diff --git a/bin/mode.ts b/bin/mode.ts
new file mode 100644
index 0000000..9fe7625
--- /dev/null
+++ b/bin/mode.ts
@@ -0,0 +1,19 @@
+///
+// Swap UI between cinema mode (fix 16:9) and 100% height.
+
+import { content } from "@/js/dom"
+import { focusInput } from "@/js/focus"
+import { resize } from "@/js/resize"
+import { send } from "@/js/websocket"
+
+export default function (mode?: string) {
+ if (!mode) {
+ mode = document.body.dataset.mode === "tall" ? "cinema" : "tall"
+ send({ type: "session:update", data: { "ui:mode": mode } })
+ }
+
+ content.style.display = ""
+ document.body.dataset.mode = mode
+ resize()
+ focusInput()
+}
\ No newline at end of file
diff --git a/src/commands.ts b/src/commands.ts
index ed6fced..3ed3b99 100644
--- a/src/commands.ts
+++ b/src/commands.ts
@@ -81,6 +81,7 @@ export async function commandSource(name: string): Promise {
export async function loadCommandModule(cmd: string) {
const path = commandPath(cmd)
if (!path) return
+ console.log("-> import", path + "?t+" + Date.now())
return await import(path + "?t+" + Date.now())
}
diff --git a/src/js/commands.ts b/src/js/commands.ts
index 87249b1..1105058 100644
--- a/src/js/commands.ts
+++ b/src/js/commands.ts
@@ -1,32 +1,18 @@
////
-// temporary hack for browser commands
+// Keep track of all NOSE commands.
-import type { CommandOutput, Commands } from "../shared/types"
-import { content } from "./dom"
-import { focusInput } from "./focus"
-import { resize } from "./resize"
-import { send } from "./websocket"
+import type { Commands } from "../shared/types"
+import { runCommand } from "./shell"
export const commands: Commands = {}
-// TODO: convert to bin/shell "browser" commands
-export const browserCommands: Record void | Promise | CommandOutput> = {
- mode: (mode?: string) => {
- if (!mode) {
- mode = document.body.dataset.mode === "tall" ? "cinema" : "tall"
- send({ type: "session:update", data: { "ui:mode": mode } })
- }
-
- content.style.display = ""
- document.body.dataset.mode = mode
- resize()
- focusInput()
- },
-}
-
export function cacheCommands(cmds: Commands) {
for (const key in commands)
delete commands[key]
Object.assign(commands, cmds)
+}
+
+export async function mode(mode?: string) {
+ await runCommand(mode ? `mode ${mode}` : "mode")
}
\ No newline at end of file
diff --git a/src/js/game.ts b/src/js/game.ts
index 847869a..9ef1434 100644
--- a/src/js/game.ts
+++ b/src/js/game.ts
@@ -4,8 +4,8 @@ import { focusInput } from "./focus"
import { $$ } from "./dom"
import { randomId } from "../shared/utils"
import { setStatus, addOutput, insert } from "./scrollback"
-import { browserCommands } from "./commands"
import { sessionId } from "./session"
+import { mode } from "./commands"
const FPS = 30
const HEIGHT = 540
@@ -35,7 +35,8 @@ export async function handleGameStart(msg: GameStartMessage) {
let game
try {
- game = await import(`/source/${name}?session=${sessionId}`)
+ console.log("-> import", `/source/${name}?session=${sessionId}&t=${Date.now()}`)
+ game = await import(`/source/${name}?session=${sessionId}&t=${Date.now()}`)
} catch (err: any) {
setStatus(msgId, "error")
addOutput(msgId, `Error: ${err.message ? err.message : err}`)
@@ -43,7 +44,7 @@ export async function handleGameStart(msg: GameStartMessage) {
}
if (document.body.dataset.mode === "tall") {
- browserCommands.mode?.()
+ mode()
oldMode = "tall"
}
@@ -143,7 +144,7 @@ function endGame() {
window.removeEventListener("keyup", handleKeyup)
window.removeEventListener("resize", resizeCanvas)
- if (oldMode === "tall") browserCommands.mode?.()
+ if (oldMode === "tall") mode()
const main = document.querySelector("main")
main?.classList.remove("game")
diff --git a/src/js/session.ts b/src/js/session.ts
index b9e86cb..55b03aa 100644
--- a/src/js/session.ts
+++ b/src/js/session.ts
@@ -3,10 +3,10 @@
// in the same browser.
import type { SessionStartMessage, SessionUpdateMessage } from "@/shared/types"
-import { browserCommands } from "./commands"
import { randomId } from "../shared/utils"
import { apps } from "./webapp"
import { $ } from "./dom"
+import { mode } from "./commands"
export const sessionId = randomId()
export const projectName = $("project-name") as HTMLAnchorElement
@@ -25,7 +25,7 @@ export function handleSessionStart(msg: SessionStartMessage) {
sessionStore.set("hostname", msg.data.hostname)
updateProjectName(msg.data.project)
updateCwd(msg.data.cwd)
- browserCommands.mode?.(msg.data.mode)
+ mode(msg.data.mode)
}
export function handleSessionUpdate(msg: SessionUpdateMessage) {
diff --git a/src/js/shell.ts b/src/js/shell.ts
index 0764a7d..2889536 100644
--- a/src/js/shell.ts
+++ b/src/js/shell.ts
@@ -6,7 +6,7 @@ import { addInput, setStatus, addOutput } from "./scrollback"
import { send } from "./websocket"
import { randomId } from "../shared/utils"
import { addToHistory } from "./history"
-import { browserCommands, commands } from "./commands"
+import { commands } from "./commands"
export async function runCommand(input: string) {
if (!input.trim()) return
@@ -24,14 +24,16 @@ export async function runCommand(input: string) {
const [cmd = "", ...args] = input.split(" ")
if (commands[cmd]?.type === "browser") {
+ console.log("-> import", `/source/${cmd}?t=${Date.now()}`)
const mod = await import(`/source/${cmd}?t=${Date.now()}`)
+ if (!mod.default) {
+ addOutput(id, `no default export in ${cmd}`)
+ setStatus(id, "error")
+ return
+ }
const result = mod.default(...args)
if (result) addOutput(id, result)
setStatus(id, "ok")
- } else if (browserCommands[cmd]) {
- const result = await browserCommands[cmd](...args)
- if (result) addOutput(id, result)
- setStatus(id, "ok")
} else {
send({ id, type: "input", data: input } as InputMessage)
}
diff --git a/src/webapp.ts b/src/webapp.ts
index 8ef2635..af346f7 100644
--- a/src/webapp.ts
+++ b/src/webapp.ts
@@ -73,6 +73,7 @@ async function findApp(name: string): Promise {
async function loadApp(path: string): Promise {
if (!await Bun.file(path).exists()) return
+ console.log("-> import", path + `?t+${Date.now()}`)
const mod = await import(path + `?t=${Date.now()}`)
if (mod?.default)
return mod.default as App