Run the desktop's model layer in the browser (#557)

This commit is contained in:
Gregory Schier
2026-08-16 07:34:48 -07:00
committed by GitHub
parent 32e92d484b
commit 6f91f76064
36 changed files with 3266 additions and 24 deletions
+47
View File
@@ -0,0 +1,47 @@
/**
* The messages that cross between a tab and the worker that owns the database.
*
* Declared once and imported from both sides, so a change to the shape is a
* type error in whichever side forgot. Kept deliberately small: commands in,
* results or errors out, and events pushed the other way — the same envelope
* the desktop's IPC uses, because that is what the frontend is written against.
*/
/** Tab → worker */
export type ToWorker =
| { type: "rpc"; id: number; cmd: string; payload: unknown; label: string }
| { type: "blob_get"; id: number; blobId: string }
| { type: "blob_put"; id: number; blobId: string; bytes: ArrayBuffer }
| { type: "blob_delete"; id: number; blobId: string }
/** The tab is going away; the worker can forget its port. */
| { type: "goodbye" };
/** Worker → tab */
export type FromWorker =
/**
* Sent synchronously the moment a port connects, before anything else. Its
* only job is to prove the worker is alive: a tab that connects during a
* shared worker's teardown gets a port that is accepted and then never
* serviced, and this is how it tells that apart from a slow boot.
*/
| { type: "hello" }
/** The database is open. Sent to each port once boot has finished. */
| { type: "ready" }
/** The database could not be opened; every command will fail with this. */
| { type: "boot_error"; message: string }
| { type: "result"; id: number; result: unknown }
| { type: "error"; id: number; message: string }
/** A backend event for the app — today only `model_writes`. Sent to every port. */
| { type: "event"; event: string; payload: unknown };
/** What the worker registers itself under. Tabs on one origin share it. */
export const WORKER_NAME = "yaak-db";
/**
* The Web Lock the worker takes before opening the database.
*
* The browser already guarantees one SharedWorker per origin for this name.
* The lock covers the one overlap it doesn't rule out: a tab reloading itself,
* whose old worker may still be letting go while the new one comes up.
*/
export const DB_LOCK_NAME = "yaak-db";