Compare commits

..

No commits in common. "2d7a5d157bb806efd3cdebbfec0e4f48e09b64b4" and "c872f6c4c4926260a70574eb6a3396bb281f361c" have entirely different histories.

8 changed files with 39 additions and 53 deletions

View File

@ -1,19 +0,0 @@
/// <reference lib="dom" />
// 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()
}

View File

@ -7,7 +7,6 @@ import { join, basename } from "path"
import { isFile } from "./utils" import { isFile } from "./utils"
import { sendAll } from "./websocket" import { sendAll } from "./websocket"
import { expectDir } from "./utils" import { expectDir } from "./utils"
import { importUrl } from "./shared/utils"
import type { Command, Commands } from "./shared/types" import type { Command, Commands } from "./shared/types"
import { projectBin, projectName } from "./project" import { projectBin, projectName } from "./project"
import { DEFAULT_PROJECT, NOSE_DIR, NOSE_ROOT_BIN, NOSE_BIN } from "./config" import { DEFAULT_PROJECT, NOSE_DIR, NOSE_ROOT_BIN, NOSE_BIN } from "./config"
@ -82,7 +81,7 @@ export async function commandSource(name: string): Promise<string> {
export async function loadCommandModule(cmd: string) { export async function loadCommandModule(cmd: string) {
const path = commandPath(cmd) const path = commandPath(cmd)
if (!path) return if (!path) return
return await importUrl(path + "?t+" + Date.now()) return await import(path + "?t+" + Date.now())
} }
let noseDirWatcher let noseDirWatcher

View File

@ -1,18 +1,32 @@
//// ////
// Keep track of all NOSE commands. // temporary hack for browser commands
import type { Commands } from "../shared/types" import type { CommandOutput, Commands } from "../shared/types"
import { runCommand } from "./shell" import { content } from "./dom"
import { focusInput } from "./focus"
import { resize } from "./resize"
import { send } from "./websocket"
export const commands: Commands = {} export const commands: Commands = {}
// TODO: convert to bin/shell "browser" commands
export const browserCommands: Record<string, (...args: string[]) => void | Promise<void> | 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) { export function cacheCommands(cmds: Commands) {
for (const key in commands) for (const key in commands)
delete commands[key] delete commands[key]
Object.assign(commands, cmds) Object.assign(commands, cmds)
} }
export async function mode(mode?: string) {
await runCommand(mode ? `mode ${mode}` : "mode", false)
}

View File

@ -2,10 +2,10 @@ import type { GameStartMessage } from "../shared/types"
import { GameContext, type InputState } from "../shared/game" import { GameContext, type InputState } from "../shared/game"
import { focusInput } from "./focus" import { focusInput } from "./focus"
import { $$ } from "./dom" import { $$ } from "./dom"
import { randomId, importUrl } from "../shared/utils" import { randomId } from "../shared/utils"
import { setStatus, addOutput, insert } from "./scrollback" import { setStatus, addOutput, insert } from "./scrollback"
import { browserCommands } from "./commands"
import { sessionId } from "./session" import { sessionId } from "./session"
import { mode } from "./commands"
const FPS = 30 const FPS = 30
const HEIGHT = 540 const HEIGHT = 540
@ -35,7 +35,7 @@ export async function handleGameStart(msg: GameStartMessage) {
let game let game
try { try {
game = await importUrl(`/source/${name}?session=${sessionId}&t=${Date.now()}`) game = await import(`/source/${name}?session=${sessionId}`)
} catch (err: any) { } catch (err: any) {
setStatus(msgId, "error") setStatus(msgId, "error")
addOutput(msgId, `Error: ${err.message ? err.message : err}`) addOutput(msgId, `Error: ${err.message ? err.message : err}`)
@ -43,7 +43,7 @@ export async function handleGameStart(msg: GameStartMessage) {
} }
if (document.body.dataset.mode === "tall") { if (document.body.dataset.mode === "tall") {
mode() browserCommands.mode?.()
oldMode = "tall" oldMode = "tall"
} }
@ -143,7 +143,7 @@ function endGame() {
window.removeEventListener("keyup", handleKeyup) window.removeEventListener("keyup", handleKeyup)
window.removeEventListener("resize", resizeCanvas) window.removeEventListener("resize", resizeCanvas)
if (oldMode === "tall") mode() if (oldMode === "tall") browserCommands.mode?.()
const main = document.querySelector("main") const main = document.querySelector("main")
main?.classList.remove("game") main?.classList.remove("game")

View File

@ -3,10 +3,10 @@
// in the same browser. // in the same browser.
import type { SessionStartMessage, SessionUpdateMessage } from "@/shared/types" import type { SessionStartMessage, SessionUpdateMessage } from "@/shared/types"
import { browserCommands } from "./commands"
import { randomId } from "../shared/utils" import { randomId } from "../shared/utils"
import { apps } from "./webapp" import { apps } from "./webapp"
import { $ } from "./dom" import { $ } from "./dom"
import { mode } from "./commands"
export const sessionId = randomId() export const sessionId = randomId()
export const projectName = $("project-name") as HTMLAnchorElement export const projectName = $("project-name") as HTMLAnchorElement
@ -25,7 +25,7 @@ export function handleSessionStart(msg: SessionStartMessage) {
sessionStore.set("hostname", msg.data.hostname) sessionStore.set("hostname", msg.data.hostname)
updateProjectName(msg.data.project) updateProjectName(msg.data.project)
updateCwd(msg.data.cwd) updateCwd(msg.data.cwd)
mode(msg.data.mode) browserCommands.mode?.(msg.data.mode)
} }
export function handleSessionUpdate(msg: SessionUpdateMessage) { export function handleSessionUpdate(msg: SessionUpdateMessage) {

View File

@ -4,11 +4,11 @@
import type { InputMessage } from "../shared/types" import type { InputMessage } from "../shared/types"
import { addInput, setStatus, addOutput } from "./scrollback" import { addInput, setStatus, addOutput } from "./scrollback"
import { send } from "./websocket" import { send } from "./websocket"
import { randomId, importUrl } from "../shared/utils" import { randomId } from "../shared/utils"
import { addToHistory } from "./history" import { addToHistory } from "./history"
import { commands } from "./commands" import { browserCommands, commands } from "./commands"
export async function runCommand(input: string, showInput = true) { export async function runCommand(input: string) {
if (!input.trim()) return if (!input.trim()) return
if (input.includes(";")) { if (input.includes(";")) {
@ -19,21 +19,19 @@ export async function runCommand(input: string, showInput = true) {
const id = randomId() const id = randomId()
addToHistory(input) addToHistory(input)
if (showInput)
addInput(id, input) addInput(id, input)
const [cmd = "", ...args] = input.split(" ") const [cmd = "", ...args] = input.split(" ")
if (commands[cmd]?.type === "browser") { if (commands[cmd]?.type === "browser") {
const mod = await importUrl(`/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) const result = mod.default(...args)
if (result) addOutput(id, result) if (result) addOutput(id, result)
setStatus(id, "ok") setStatus(id, "ok")
} else if (browserCommands[cmd]) {
const result = await browserCommands[cmd](...args)
if (result) addOutput(id, result)
setStatus(id, "ok")
} else { } else {
send({ id, type: "input", data: input } as InputMessage) send({ id, type: "input", data: input } as InputMessage)
} }

View File

@ -39,8 +39,3 @@ export function randomIndex<T>(list: T[]): number | undefined {
export function unique<T>(array: T[]): T[] { export function unique<T>(array: T[]): T[] {
return [...new Set(array)] return [...new Set(array)]
} }
export async function importUrl(url: string) {
console.log("-> import", url)
return import(url)
}

View File

@ -10,7 +10,6 @@ import { sendAll } from "./websocket"
import { expectDir } from "./utils" import { expectDir } from "./utils"
import { NOSE_DIR } from "./config" import { NOSE_DIR } from "./config"
import { isFile, isDir } from "./utils" import { isFile, isDir } from "./utils"
import { importUrl } from "./shared/utils"
export type Handler = (r: Context) => string | Child | Response | Promise<Response> export type Handler = (r: Context) => string | Child | Response | Promise<Response>
export type App = Hono | Handler export type App = Hono | Handler
@ -74,7 +73,7 @@ async function findApp(name: string): Promise<App | undefined> {
async function loadApp(path: string): Promise<App | undefined> { async function loadApp(path: string): Promise<App | undefined> {
if (!await Bun.file(path).exists()) return if (!await Bun.file(path).exists()) return
const mod = await importUrl(path + `?t=${Date.now()}`) const mod = await import(path + `?t=${Date.now()}`)
if (mod?.default) if (mod?.default)
return mod.default as App return mod.default as App
} }