pi-straw-boss 0.10.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/gui.ts +10 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-straw-boss",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
4
4
  "description": "Straw Boss coordination for pi in Herdr: sessions join a tab's net by choice, the first joiner is its main agent, a workspace tower opens on demand with a live monitoring dashboard, and boss_broadcast reaches the rest",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/gui.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { execFile } from "node:child_process";
2
2
  import { randomBytes } from "node:crypto";
3
- import { createReadStream, mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
3
+ import { mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
4
4
  import { createServer, type IncomingMessage, request, type ServerResponse } from "node:http";
5
5
  import type { AddressInfo } from "node:net";
6
- import { extname, join, resolve, sep } from "node:path";
6
+ import { extname, join } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { waitsForSecret } from "./ask.ts";
9
9
  import { createControl, type Reply } from "./control.ts";
@@ -49,7 +49,9 @@ export async function startGui({ read, net, call, hub, dir = BUNDLE, port = 0, t
49
49
  } catch {
50
50
  throw new Error(`The GUI bundle is missing (${dir}); build it with npm run gui:build`);
51
51
  }
52
- const page = readFileSync(join(dir, "index.html"), "utf8").replace("<head>", `<head>\n<base href="/${token}/">\n<meta name="sb-csrf" content="${csrf}">`);
52
+ // The whole bundle is read once: a package update replaces dist/gui under a running server, whose page names the old assets.
53
+ const bundle = new Map(readdirSync(dir, { recursive: true, encoding: "utf8" }).filter((f) => statSync(join(dir, f)).isFile()).map((f) => [f.split("\\").join("/"), readFileSync(join(dir, f))]));
54
+ const page = bundle.get("index.html")!.toString("utf8").replace("<head>", `<head>\n<base href="/${token}/">\n<meta name="sb-csrf" content="${csrf}">`);
53
55
  const files: Files = { lookup: (key) => net?.lookup(key), workspace: (id) => net?.workspace(id) ?? [], readers: readers() };
54
56
  // Turning remote access off ends the streams of remote pages; their next request finds the cookie void.
55
57
  const clients = new Map<ServerResponse, Watch | undefined>(), remotes = new Set<ServerResponse>(), access = createAccess(token, () => remotes.forEach((c) => c.end()));
@@ -130,14 +132,14 @@ export async function startGui({ read, net, call, hub, dir = BUNDLE, port = 0, t
130
132
  if (path[0] === "w") return void res.writeHead(200, { ...HEADERS, "content-type": TYPES[".html"] }).end(page);
131
133
  let file: string;
132
134
  try {
133
- file = resolve(dir, decodeURIComponent(path.join("/")) || "index.html");
134
- if (!file.startsWith(resolve(dir) + sep) || !statSync(file).isFile()) throw new Error();
135
+ file = decodeURIComponent(path.join("/")) || "index.html";
135
136
  } catch {
136
137
  return void fail(404);
137
138
  }
138
- if (file === join(resolve(dir), "index.html")) return void res.writeHead(200, { ...HEADERS, "content-type": TYPES[".html"] }).end(page);
139
- res.writeHead(200, { ...HEADERS, "content-type": TYPES[extname(file)] ?? "application/octet-stream" });
140
- createReadStream(file).pipe(res);
139
+ if (file === "index.html") return void res.writeHead(200, { ...HEADERS, "content-type": TYPES[".html"] }).end(page);
140
+ const body = bundle.get(file);
141
+ if (!body) return void fail(404);
142
+ res.writeHead(200, { ...HEADERS, "content-type": TYPES[extname(file)] ?? "application/octet-stream" }).end(body);
141
143
  });
142
144
  try {
143
145
  await listen(port);