narrow Message types
This commit is contained in:
parent
24a17f2b46
commit
2b66107866
|
|
@ -11,13 +11,15 @@ export async function dispatchMessage(ws: any, msg: Message) {
|
|||
console.log("<- receive", msg)
|
||||
switch (msg.type) {
|
||||
case "input":
|
||||
await inputMessage(ws, msg as InputMessage); break
|
||||
await inputMessage(ws, msg); break
|
||||
|
||||
case "save-file":
|
||||
await saveFileMessage(ws, msg as SaveFileMessage); break
|
||||
await saveFileMessage(ws, msg); break
|
||||
|
||||
case "ui:mode":
|
||||
setState("ui:mode", msg.data); break
|
||||
case "session:update":
|
||||
for (const key of Object.keys(msg.data))
|
||||
setState(key, msg.data[key]);
|
||||
break
|
||||
|
||||
default:
|
||||
send(ws, { type: "error", data: `unknown message: ${msg.type}` })
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ function closeBrowser() {
|
|||
iframe.style.pointerEvents = "none"
|
||||
iframe.tabIndex = -1
|
||||
iframe.classList.remove("fullscreen", "active")
|
||||
iframe.style.border = "2px solid var(--c64-light-blue)"
|
||||
scrollback.append(iframe)
|
||||
|
||||
controls.style.display = "none"
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export const browserCommands: Record<string, (...args: string[]) => void | Promi
|
|||
mode: (mode?: string) => {
|
||||
if (!mode) {
|
||||
mode = document.body.dataset.mode === "tall" ? "cinema" : "tall"
|
||||
send({ type: "ui:mode", data: mode })
|
||||
send({ type: "session:update", data: { "ui:mode": mode } })
|
||||
}
|
||||
|
||||
content.style.display = ""
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import type { SaveFileMessage } from "../shared/types"
|
||||
import { scrollback } from "./dom"
|
||||
import { send } from "./websocket"
|
||||
import { focusInput } from "./focus"
|
||||
|
|
@ -49,10 +50,10 @@ function keydownHandler(e: KeyboardEvent) {
|
|||
} else if ((e.ctrlKey && e.key === "s") || (e.ctrlKey && e.key === "Enter")) {
|
||||
e.preventDefault()
|
||||
send({
|
||||
id: editor.dataset.path,
|
||||
id: editor.dataset.path || "/tmp.txt",
|
||||
type: "save-file",
|
||||
data: editor.value
|
||||
})
|
||||
} as SaveFileMessage)
|
||||
} else if (e.key === "{") {
|
||||
if (editor.selectionStart !== editor.selectionEnd) {
|
||||
insertAroundSelection(editor, '{', '}')
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ function handleInputClick(e: MouseEvent) {
|
|||
|
||||
export function handleOutput(msg: Message) {
|
||||
const result = msg.data as CommandResult
|
||||
setStatus(msg.id!, result.status)
|
||||
addOutput(msg.id!, result.output)
|
||||
const id = "id" in msg ? msg.id || "" : ""
|
||||
setStatus(id, result.status)
|
||||
addOutput(id, result.output)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
////
|
||||
// The shell runs on the server and processes input, returning output.
|
||||
|
||||
import type { InputMessage } from "../shared/types"
|
||||
import { addInput, setStatus, addOutput } from "./scrollback"
|
||||
import { send } from "./websocket"
|
||||
import { randomId } from "../shared/utils"
|
||||
|
|
@ -27,7 +28,7 @@ export async function runCommand(input: string) {
|
|||
if (result) addOutput(id, result)
|
||||
setStatus(id, "ok")
|
||||
} else {
|
||||
send({ id, type: "input", data: input })
|
||||
send({ id, type: "input", data: input } as InputMessage)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
import type { Message, CommandOutput } from "@/shared/types"
|
||||
import type { StreamMessage } from "@/shared/types"
|
||||
import { addOutput, appendOutput, replaceOutput } from "./scrollback"
|
||||
|
||||
export function handleStreamStart(msg: Message) {
|
||||
const id = msg.id!
|
||||
export function handleStreamStart(msg: StreamMessage) {
|
||||
const id = msg.id
|
||||
|
||||
const status = document.querySelector(`[data-id="${id}"].input .status`)
|
||||
if (!status) return
|
||||
|
||||
addOutput(id, msg.data as CommandOutput)
|
||||
addOutput(id, msg.data)
|
||||
|
||||
status.classList.remove("yellow")
|
||||
status.classList.add("purple")
|
||||
}
|
||||
|
||||
export function handleStreamAppend(msg: Message) {
|
||||
appendOutput(msg.id!, msg.data as CommandOutput)
|
||||
export function handleStreamAppend(msg: StreamMessage) {
|
||||
appendOutput(msg.id, msg.data)
|
||||
}
|
||||
|
||||
export function handleStreamReplace(msg: Message) {
|
||||
replaceOutput(msg.id!, msg.data as CommandOutput)
|
||||
export function handleStreamReplace(msg: StreamMessage) {
|
||||
replaceOutput(msg.id, msg.data)
|
||||
}
|
||||
|
||||
export function handleStreamEnd(_msg: Message) {
|
||||
export function handleStreamEnd(_msg: StreamMessage) {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { addErrorMessage } from "./scrollback"
|
|||
const MAX_RETRIES = 5
|
||||
let retries = 0
|
||||
let connected = false
|
||||
let msgQueue: Message[] = []
|
||||
let msgQueue: Omit<Message, "session">[] = []
|
||||
|
||||
let ws: WebSocket | null = null
|
||||
|
||||
|
|
@ -30,14 +30,15 @@ export function startConnection() {
|
|||
}
|
||||
|
||||
// send any message
|
||||
export function send(msg: Message) {
|
||||
export function send(msg: Omit<Message, "session">) {
|
||||
if (!connected) {
|
||||
msgQueue.push(msg)
|
||||
startConnection()
|
||||
return
|
||||
}
|
||||
|
||||
if (!msg.session) msg.session = sessionId
|
||||
if (!(msg as any).session) (msg as any).session = sessionId
|
||||
|
||||
ws?.readyState === 1 && ws.send(JSON.stringify(msg))
|
||||
console.log("-> send", msg)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,13 @@
|
|||
export type Message = {
|
||||
session?: string
|
||||
id?: string
|
||||
type: MessageType
|
||||
data?: CommandResult | CommandOutput
|
||||
}
|
||||
export type Message =
|
||||
| ErrorMessage
|
||||
| InputMessage
|
||||
| OutputMessage
|
||||
| SaveFileMessage
|
||||
| SessionStartMessage
|
||||
| SessionUpdateMessage
|
||||
| GameStartMessage
|
||||
|
||||
export type MessageType = "error" | "input" | "output" | "commands" | "save-file"
|
||||
| "game:start"
|
||||
| "stream:start" | "stream:end" | "stream:append" | "stream:replace"
|
||||
| "ui:mode"
|
||||
| StreamMessage
|
||||
| CommandsMessage
|
||||
|
||||
export type CommandOutput = string | string[]
|
||||
| { text: string, script?: string }
|
||||
|
|
@ -26,6 +20,22 @@ export type CommandResult = {
|
|||
output: CommandOutput
|
||||
}
|
||||
|
||||
export type ErrorMessage = {
|
||||
type: "error"
|
||||
data: string
|
||||
}
|
||||
|
||||
export type CommandsMessage = {
|
||||
type: "commands"
|
||||
data: string[]
|
||||
}
|
||||
|
||||
export type OutputMessage = {
|
||||
type: "output"
|
||||
id?: string
|
||||
data: CommandResult
|
||||
}
|
||||
|
||||
export type InputMessage = {
|
||||
type: "input"
|
||||
id: string
|
||||
|
|
@ -56,6 +66,14 @@ export type SessionUpdateMessage = {
|
|||
}
|
||||
|
||||
export type GameStartMessage = {
|
||||
type: "game:start"
|
||||
id: string
|
||||
data: string
|
||||
}
|
||||
|
||||
export type StreamMessage = {
|
||||
type: "stream:start" | "stream:end" | "stream:append" | "stream:replace"
|
||||
id: string
|
||||
session: string
|
||||
data: CommandOutput
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ import { send as sendWs } from "./websocket"
|
|||
import { sessionGet } from "./session"
|
||||
import { processExecOutput } from "./shell"
|
||||
import type { Child } from "hono/jsx"
|
||||
import type { CommandOutput, Message } from "./shared/types"
|
||||
import type { CommandOutput, StreamMessage } from "./shared/types"
|
||||
|
||||
type StreamFn = (output: Child) => Promise<void>
|
||||
type StreamFns = { replace: StreamFn, append: StreamFn }
|
||||
|
|
@ -16,7 +16,7 @@ export async function stream(initOrFn: StreamParamFn | string | any, fn?: Stream
|
|||
const taskId = state.taskId
|
||||
const session = state.sessionId
|
||||
|
||||
const send = (msg: Message) => {
|
||||
const send = (msg: Omit<StreamMessage, "id" | "session">) => {
|
||||
sendWs(state.ws, { ...msg, id: taskId, session })
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user