living, breathing commands
This commit is contained in:
parent
6a7f10f8d5
commit
efe4e4b447
3
nose/bin/greet.ts
Normal file
3
nose/bin/greet.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export default function (name: string): string {
|
||||||
|
return `Hi, ${name || "stranger"}!`
|
||||||
|
}
|
||||||
19
src/commands.ts
Normal file
19
src/commands.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { Glob } from "bun"
|
||||||
|
import { watch } from "fs"
|
||||||
|
import { NOSE_BIN } from "./config"
|
||||||
|
import { sendAll } from "./websocket"
|
||||||
|
|
||||||
|
const cmdWatcher = watch(NOSE_BIN, async (event, filename) => {
|
||||||
|
sendAll({ type: "commands", data: await commands() })
|
||||||
|
})
|
||||||
|
|
||||||
|
export async function commands(): Promise<string[]> {
|
||||||
|
const glob = new Glob("**/*.{ts,tsx}")
|
||||||
|
let list: string[] = []
|
||||||
|
|
||||||
|
for await (const file of glob.scan(NOSE_BIN)) {
|
||||||
|
list.push(file.replace(".ts", ""))
|
||||||
|
}
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
@ -3,11 +3,13 @@ import { serveStatic, upgradeWebSocket, websocket } from "hono/bun"
|
||||||
import { prettyJSON } from "hono/pretty-json"
|
import { prettyJSON } from "hono/pretty-json"
|
||||||
import color from "kleur"
|
import color from "kleur"
|
||||||
|
|
||||||
|
import type { Message } from "./shared/types"
|
||||||
import { NOSE_ICON, NOSE_DIR, NOSE_BIN, NOSE_WWW } from "./config"
|
import { NOSE_ICON, NOSE_DIR, NOSE_BIN, NOSE_WWW } from "./config"
|
||||||
import { transpile, isFile, tilde } from "./utils"
|
import { transpile, isFile, tilde } from "./utils"
|
||||||
import { apps, serveApp, publishDNS } from "./webapp"
|
import { apps, serveApp, publishDNS } from "./webapp"
|
||||||
import { runCommand } from "./shell"
|
import { runCommand } from "./shell"
|
||||||
import type { Message } from "./shared/types"
|
import { commands } from "./commands"
|
||||||
|
import { send, addWebsocket, removeWebsocket, closeWebsockets, websockets } from "./websocket"
|
||||||
|
|
||||||
import { Layout } from "./components/layout"
|
import { Layout } from "./components/layout"
|
||||||
import { Terminal } from "./components/terminal"
|
import { Terminal } from "./components/terminal"
|
||||||
|
|
@ -52,13 +54,11 @@ app.on("GET", ["/js/:path{.+}", "/shared/:path{.+}"], async c => {
|
||||||
// websocket
|
// websocket
|
||||||
//
|
//
|
||||||
|
|
||||||
const wsConnections: any[] = []
|
|
||||||
|
|
||||||
app.get("/ws", upgradeWebSocket(async c => {
|
app.get("/ws", upgradeWebSocket(async c => {
|
||||||
return {
|
return {
|
||||||
onOpen(_e, ws) {
|
async onOpen(_e, ws) {
|
||||||
wsConnections.push(ws)
|
addWebsocket(ws)
|
||||||
ws.send(JSON.stringify({ type: "commands", data: ["hello", "echo"] }))
|
send(ws, { type: "commands", data: await commands() })
|
||||||
},
|
},
|
||||||
async onMessage(event, ws) {
|
async onMessage(event, ws) {
|
||||||
let data: Message | undefined
|
let data: Message | undefined
|
||||||
|
|
@ -67,16 +67,18 @@ app.get("/ws", upgradeWebSocket(async c => {
|
||||||
data = JSON.parse(event.data.toString())
|
data = JSON.parse(event.data.toString())
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("JSON parsing error", e)
|
console.error("JSON parsing error", e)
|
||||||
ws.send(JSON.stringify({ type: "error", data: "json parsing error" }))
|
send(ws, { type: "error", data: "json parsing error" })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data) return
|
if (!data) return
|
||||||
|
|
||||||
const result = await runCommand(data.data as string)
|
const result = await runCommand(data.data as string)
|
||||||
ws.send(JSON.stringify({ id: data.id, type: "output", data: result }))
|
send(ws, { id: data.id, type: "output", data: result })
|
||||||
|
},
|
||||||
|
onClose: (event, ws) => {
|
||||||
|
removeWebsocket(ws)
|
||||||
},
|
},
|
||||||
onClose: () => console.log('Connection closed'),
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
@ -126,14 +128,14 @@ if (process.env.BUN_HOT) {
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
globalThis.__hot_reload_cleanup = () => {
|
globalThis.__hot_reload_cleanup = () => {
|
||||||
wsConnections.forEach(conn => conn?.close())
|
closeWebsockets()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const sig of ["SIGINT", "SIGTERM"] as const) {
|
for (const sig of ["SIGINT", "SIGTERM"] as const) {
|
||||||
process.on(sig, () => {
|
process.on(sig, () => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
globalThis.__hot_reload_cleanup?.()
|
globalThis.__hot_reload_cleanup?.()
|
||||||
process.exit()
|
process.exit(0)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
export type Message = {
|
export type Message = {
|
||||||
session?: string
|
session?: string
|
||||||
id?: string
|
id?: string
|
||||||
type: "input" | "output" | "commands"
|
type: "input" | "output" | "commands" | "error"
|
||||||
data: CommandResult | string | string[]
|
data: CommandResult | string | string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
31
src/websocket.ts
Normal file
31
src/websocket.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
////
|
||||||
|
// Manage open websockets, send messages... fun stuff like that.
|
||||||
|
|
||||||
|
import type { Message } from "./shared/types"
|
||||||
|
|
||||||
|
const wsConnections: any[] = []
|
||||||
|
|
||||||
|
export function send(ws: any, msg: Message) {
|
||||||
|
ws.send(JSON.stringify(msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sendAll(msg: Message) {
|
||||||
|
wsConnections.forEach(ws => send(ws, msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addWebsocket(ws: any) {
|
||||||
|
wsConnections.push(ws)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeWebsocket(ws: any) {
|
||||||
|
wsConnections.splice(wsConnections.indexOf(ws), 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function closeWebsockets() {
|
||||||
|
wsConnections.forEach(conn => conn.close())
|
||||||
|
wsConnections.length = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
export function websockets(): any[] {
|
||||||
|
return wsConnections
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user