diff --git a/src/js/commands.ts b/src/js/commands.ts index 9f213e3..c7e779e 100644 --- a/src/js/commands.ts +++ b/src/js/commands.ts @@ -3,7 +3,17 @@ import { scrollback } from "./dom.js" -export const commands: Record void> = { +export const commands: string[] = [] + +export const browserCommands: Record any> = { fullscreen: () => document.body.requestFullscreen(), clear: () => scrollback.innerHTML = "", + commands: () => commands.join(" ") +} + +export function cacheCommands(cmds: string[]) { + commands.length = 0 + commands.push(...cmds) + commands.push(...Object.keys(browserCommands)) + commands.sort() } \ No newline at end of file diff --git a/src/js/shell.ts b/src/js/shell.ts index 68e5412..d70b12c 100644 --- a/src/js/shell.ts +++ b/src/js/shell.ts @@ -1,12 +1,12 @@ //// // The shell runs on the server and processes input, returning output. +import type { Message, CommandResult } from "../shared/types.js" import { addInput, setStatus, addOutput } from "./scrollback.js" import { send } from "./websocket.js" import { randomID } from "../shared/utils.js" -import type { Message, CommandResult } from "../shared/types.js" import { addToHistory } from "./history.js" -import { commands } from "./commands.js" +import { browserCommands, cacheCommands } from "./commands.js" export function runCommand(input: string) { const id = randomID() @@ -16,8 +16,9 @@ export function runCommand(input: string) { const [cmd = "", ...args] = input.split(" ") - if (commands[cmd]) { - commands[cmd]() + if (browserCommands[cmd]) { + const result = browserCommands[cmd]() + if (result) addOutput(id, result) setStatus(id, "ok") } else { send({ id, type: "input", data: input }) @@ -25,16 +26,18 @@ export function runCommand(input: string) { } // message received from server -export function handleMessage(data: Message) { - if (data.type === "output") { - handleOutput(data) +export function handleMessage(msg: Message) { + if (msg.type === "output") { + handleOutput(msg) + } else if (msg.type === "commands") { + cacheCommands(msg.data as string[]) } else { - console.error("unknown message type", data) + console.error("unknown message type", msg) } } function handleOutput(msg: Message) { const result = msg.data as CommandResult - setStatus(msg.id, result.status) - addOutput(msg.id, result.output) + setStatus(msg.id!, result.status) + addOutput(msg.id!, result.output) } diff --git a/src/server.tsx b/src/server.tsx index 85f611f..900b000 100644 --- a/src/server.tsx +++ b/src/server.tsx @@ -58,6 +58,7 @@ app.get("/ws", upgradeWebSocket(async c => { return { onOpen(_e, ws) { wsConnections.push(ws) + ws.send(JSON.stringify({ type: "commands", data: ["hello", "echo"] })) }, async onMessage(event, ws) { let data: Message | undefined diff --git a/src/shared/types.ts b/src/shared/types.ts index 3d83a3c..c39505b 100644 --- a/src/shared/types.ts +++ b/src/shared/types.ts @@ -1,8 +1,8 @@ export type Message = { session?: string - id: string - type: "input" | "output" - data: string | CommandResult + id?: string + type: "input" | "output" | "commands" + data: CommandResult | string | string[] } export type CommandResult = {