feat: embed daemon JS in binary, eliminate npm install of camoufox-browser

The daemon JS files (daemon.js, server.js, browser.js, protocol.js,
snapshot.js, ipc.js) are now EMBEDDED in the compiled Rust binary via
include_dir! and extracted to ~/.gyandoot/daemon/ on first run.

This eliminates the need to npm install -g camoufox-browser@0.1.0,
which bundles an incompatible camoufox-js@0.9.3 that caused:
- 'Cannot open database' errors
- Re-downloading 298MB browser on every navigation
- Circular install/remove/install loops

Now the daemon imports camoufox-js from the global npm install (v0.11.0)
which is installed by install.sh. Clean, no bundled deps, no conflicts.

Also removed: is_npm_package_installed(), install_npm_package(),
find_daemon_js() — all replaced by gyandoot_browser::daemon::extract_daemon()
This commit is contained in:
2026-06-13 23:22:15 +05:30
parent 57308e7805
commit d5cab65099
12 changed files with 2063 additions and 197 deletions

View File

@@ -0,0 +1,46 @@
import { z } from "zod";
const commandSchema = z
.object({
id: z.string(),
action: z.string()
})
.passthrough();
export function parseCommand(input) {
let json;
try {
json = JSON.parse(input);
}
catch {
return { success: false, error: "Invalid JSON" };
}
const id = typeof json === "object" && json !== null && "id" in json
? String(json.id)
: undefined;
const result = commandSchema.safeParse(json);
if (!result.success) {
const errors = result.error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ");
return { success: false, error: `Validation error: ${errors}`, id };
}
return { success: true, command: result.data };
}
export function successResponse(id, data) {
return { id, success: true, data };
}
export function errorResponse(id, error) {
return { id, success: false, error };
}
/**
* Serialize a response to JSON string.
* Replaces lone Unicode surrogates with U+FFFD to avoid serde_json parse errors.
*/
function sanitizeUtf16(input) {
// Fast path: most strings contain no surrogate code units.
if (!/[\uD800-\uDFFF]/.test(input))
return input;
// Replace lone high/low surrogates. Valid surrogate pairs are preserved.
// Ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toWellFormed
return input.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "\uFFFD");
}
export function serializeResponse(response) {
return JSON.stringify(response, (_key, value) => typeof value === "string" ? sanitizeUtf16(value) : value);
}