browser commands are now real commands! (again)
This commit is contained in:
parent
6d05b6888f
commit
c872f6c4c4
16
bin/browse.ts
Normal file
16
bin/browse.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
/// <reference lib="dom" />
|
||||||
|
// Open a URL (or the current project) in the NOSEbrowser.
|
||||||
|
|
||||||
|
import { openBrowser } from "@/js/browser"
|
||||||
|
import { setStatus, latestId } from "@/js/scrollback"
|
||||||
|
import { currentAppUrl } from "@/js/webapp"
|
||||||
|
|
||||||
|
export default function (url?: string) {
|
||||||
|
const currentUrl = url ?? currentAppUrl()
|
||||||
|
if (currentUrl) {
|
||||||
|
openBrowser(currentUrl, "command")
|
||||||
|
} else {
|
||||||
|
setTimeout(() => setStatus(latestId()!, "error"), 0)
|
||||||
|
return "usage: browse <url>"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
bin/browser-session.ts
Normal file
6
bin/browser-session.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
/// <reference lib="dom" />
|
||||||
|
// Print the browser's session ID
|
||||||
|
|
||||||
|
import { sessionId } from "@/js/session"
|
||||||
|
|
||||||
|
export default () => sessionId
|
||||||
8
bin/clear.ts
Normal file
8
bin/clear.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference lib="dom" />
|
||||||
|
// Clear the scrollback history.
|
||||||
|
|
||||||
|
import { scrollback } from "@/js/dom"
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
scrollback.innerHTML = ""
|
||||||
|
}
|
||||||
8
bin/commands.ts
Normal file
8
bin/commands.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference lib="dom" />
|
||||||
|
// Print all the commands.
|
||||||
|
|
||||||
|
import { commands } from "@/js/commands"
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
return { html: "<div>" + Object.keys(commands).map(cmd => `<a href="#help ${cmd}">${cmd}</a>`).join("") + "</div>" }
|
||||||
|
}
|
||||||
4
bin/fullscreen.ts
Normal file
4
bin/fullscreen.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
/// <reference lib="dom" />
|
||||||
|
// Toggle fullscreen mode.
|
||||||
|
|
||||||
|
export default () => { document.body.requestFullscreen() }
|
||||||
4
bin/reload.ts
Normal file
4
bin/reload.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
/// <reference lib="dom" />
|
||||||
|
// Reload the browser window.
|
||||||
|
|
||||||
|
export default () => { window.location.reload() }
|
||||||
6
bin/status.ts
Normal file
6
bin/status.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
/// <reference lib="dom" />
|
||||||
|
// Display a status message in the status bar.
|
||||||
|
|
||||||
|
import { status } from "@/js/statusbar"
|
||||||
|
|
||||||
|
export default (msg: string) => { status(msg) }
|
||||||
|
|
@ -43,7 +43,7 @@ export async function findCommands(path: string): Promise<Commands> {
|
||||||
function describeCommand(path: string): Command {
|
function describeCommand(path: string): Command {
|
||||||
const code = readFileSync(path, "utf8")
|
const code = readFileSync(path, "utf8")
|
||||||
let game = /^export const game = true$/mg.test(code)
|
let game = /^export const game = true$/mg.test(code)
|
||||||
let browser = /^\/\/\/ ?<reference lib=['"]dom['"]\s*\/mg>$/.test(code)
|
let browser = /^\/\/\/ ?<reference lib=['"]dom['"]\s*\/>$/mg.test(code)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: basename(path).replace(/\.tsx?$/, ""),
|
name: basename(path).replace(/\.tsx?$/, ""),
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,16 @@
|
||||||
////
|
////
|
||||||
// temporary hack for browser commands
|
// temporary hack for browser commands
|
||||||
|
|
||||||
import type { CommandOutput, Commands, Command } from "../shared/types"
|
import type { CommandOutput, Commands } from "../shared/types"
|
||||||
import { openBrowser } from "./browser"
|
import { content } from "./dom"
|
||||||
import { scrollback, content } from "./dom"
|
|
||||||
import { focusInput } from "./focus"
|
import { focusInput } from "./focus"
|
||||||
import { resize } from "./resize"
|
import { resize } from "./resize"
|
||||||
import { sessionId } from "./session"
|
|
||||||
import { send } from "./websocket"
|
import { send } from "./websocket"
|
||||||
import { status } from "./statusbar"
|
|
||||||
import { setStatus, latestId } from "./scrollback"
|
|
||||||
import { currentAppUrl } from "./webapp"
|
|
||||||
|
|
||||||
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> = {
|
export const browserCommands: Record<string, (...args: string[]) => void | Promise<void> | CommandOutput> = {
|
||||||
browse: (url?: string) => {
|
|
||||||
const currentUrl = url ?? currentAppUrl()
|
|
||||||
if (currentUrl) {
|
|
||||||
openBrowser(currentUrl, "command")
|
|
||||||
} else {
|
|
||||||
setTimeout(() => setStatus(latestId()!, "error"), 0)
|
|
||||||
return "usage: browse <url>"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"browser-session": () => sessionId,
|
|
||||||
clear: () => scrollback.innerHTML = "",
|
|
||||||
commands: () => {
|
|
||||||
return { html: "<div>" + Object.keys(commands).map(cmd => `<a href="#help ${cmd}">${cmd}</a>`).join("") + "</div>" }
|
|
||||||
},
|
|
||||||
fullscreen: () => document.body.requestFullscreen(),
|
|
||||||
mode: (mode?: string) => {
|
mode: (mode?: string) => {
|
||||||
if (!mode) {
|
if (!mode) {
|
||||||
mode = document.body.dataset.mode === "tall" ? "cinema" : "tall"
|
mode = document.body.dataset.mode === "tall" ? "cinema" : "tall"
|
||||||
|
|
@ -41,8 +22,6 @@ export const browserCommands: Record<string, (...args: string[]) => void | Promi
|
||||||
resize()
|
resize()
|
||||||
focusInput()
|
focusInput()
|
||||||
},
|
},
|
||||||
status: (msg: string) => status(msg),
|
|
||||||
reload: () => window.location.reload(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cacheCommands(cmds: Commands) {
|
export function cacheCommands(cmds: Commands) {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import { addInput, setStatus, addOutput } from "./scrollback"
|
||||||
import { send } from "./websocket"
|
import { send } from "./websocket"
|
||||||
import { randomId } from "../shared/utils"
|
import { randomId } from "../shared/utils"
|
||||||
import { addToHistory } from "./history"
|
import { addToHistory } from "./history"
|
||||||
import { browserCommands } from "./commands"
|
import { browserCommands, commands } from "./commands"
|
||||||
|
|
||||||
export async function runCommand(input: string) {
|
export async function runCommand(input: string) {
|
||||||
if (!input.trim()) return
|
if (!input.trim()) return
|
||||||
|
|
@ -23,7 +23,12 @@ export async function runCommand(input: string) {
|
||||||
|
|
||||||
const [cmd = "", ...args] = input.split(" ")
|
const [cmd = "", ...args] = input.split(" ")
|
||||||
|
|
||||||
if (browserCommands[cmd]) {
|
if (commands[cmd]?.type === "browser") {
|
||||||
|
const mod = await import(`/source/${cmd}?t=${Date.now()}`)
|
||||||
|
const result = mod.default(...args)
|
||||||
|
if (result) addOutput(id, result)
|
||||||
|
setStatus(id, "ok")
|
||||||
|
} else if (browserCommands[cmd]) {
|
||||||
const result = await browserCommands[cmd](...args)
|
const result = await browserCommands[cmd](...args)
|
||||||
if (result) addOutput(id, result)
|
if (result) addOutput(id, result)
|
||||||
setStatus(id, "ok")
|
setStatus(id, "ok")
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,12 @@ app.get("/source/:name", async c => {
|
||||||
const sessionId = c.req.query("session") || "0"
|
const sessionId = c.req.query("session") || "0"
|
||||||
const path = await sessionRun(sessionId, () => commandPath(name))
|
const path = await sessionRun(sessionId, () => commandPath(name))
|
||||||
if (!path) return c.text("Command not found", 404)
|
if (!path) return c.text("Command not found", 404)
|
||||||
return new Response(await transpile(path), {
|
|
||||||
|
let code = await transpile(path)
|
||||||
|
// rewrite imports so they work on the server and in the browser
|
||||||
|
code = code.replace(/from (["'])@\/js\//g, "from $1../js/")
|
||||||
|
|
||||||
|
return new Response(code, {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "text/javascript"
|
"Content-Type": "text/javascript"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user