@statewalker/cellb 0.8.3 → 0.8.6
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.
- package/README.md +4 -1
- package/dist/adapters/node-sqlite.d.ts +9 -3
- package/dist/adapters/node-sqlite.js +82 -5
- package/dist/adapters/node-sqlite.js.map +1 -1
- package/dist/core/object-host.js +1 -1
- package/dist/core/object-host.js.map +1 -1
- package/dist/core/sql-storage.d.ts +12 -0
- package/dist/core/sql-storage.js +22 -0
- package/dist/core/sql-storage.js.map +1 -1
- package/dist/core/storage.d.ts +12 -4
- package/dist/core/storage.js +114 -7
- package/dist/core/storage.js.map +1 -1
- package/dist/isolate/node-entry.js +3 -2
- package/dist/isolate/node-entry.js.map +1 -1
- package/dist/project/node-load.js +5 -1
- package/dist/project/node-load.js.map +1 -1
- package/dist/project/wrangler.d.ts +5 -1
- package/dist/project/wrangler.js +6 -2
- package/dist/project/wrangler.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -171,7 +171,10 @@ import { MemFilesApi } from "@statewalker/webrun-files-mem";
|
|
|
171
171
|
|
|
172
172
|
const dir = "./counter"; // wrangler.jsonc and its `main`
|
|
173
173
|
const { runtime, unsupported } = await loadNodeProject(dir, {
|
|
174
|
-
|
|
174
|
+
// Every cell starts empty and is restored from the bucket on first use. pageCapture logs each
|
|
175
|
+
// commit's pages from the WAL (O(changed pages)) instead of imaging the whole database per
|
|
176
|
+
// commit; without a directory, cells live in temporary files removed when they close.
|
|
177
|
+
openSql: nodeSqliteOpener(undefined, { pageCapture: true }),
|
|
175
178
|
files: new MemFilesApi(), // blob store for large KV values
|
|
176
179
|
storage: celldBucket(sqliteObjectStore(`${dir}/.celld/dev/objects.sqlite3`), { node: "cellb-1" }),
|
|
177
180
|
});
|
|
@@ -5,6 +5,7 @@ export declare class NodeSqliteDriver implements SyncSqlDriver {
|
|
|
5
5
|
constructor(path?: string, opts?: {
|
|
6
6
|
exclusive?: boolean;
|
|
7
7
|
pageCapture?: boolean;
|
|
8
|
+
temporary?: boolean;
|
|
8
9
|
});
|
|
9
10
|
/** The pages of the transactions committed since the previous call (WAL frames). */
|
|
10
11
|
takeDirtyPages(): {
|
|
@@ -34,10 +35,15 @@ export declare class NodeSqliteDriver implements SyncSqlDriver {
|
|
|
34
35
|
/** Replaces the database file with `image` and reopens it (an in-memory DB becomes file-backed). */
|
|
35
36
|
restore(image: Uint8Array): void;
|
|
36
37
|
}
|
|
37
|
-
/** One file per cell in `dir`, or in-memory when `dir` is omitted. */
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
39
|
+
* One file per cell in `dir`; without `dir`, each cell in memory.
|
|
40
|
+
*
|
|
41
|
+
* `pageCapture`: WAL mode, and each commit's changed pages read from the WAL (takeDirtyPages),
|
|
42
|
+
* so LTX logs (a celld bucket) cost O(changed pages) on Node as with SQLite WASM, instead of an
|
|
43
|
+
* image of the whole database (VACUUM INTO) and a page-by-page diff per commit. A WAL needs a
|
|
44
|
+
* file: without `dir`, each cell opened gets a temporary file (in a `cellb-cells-…` directory
|
|
45
|
+
* under the OS temp directory), removed when the cell closes, so it still starts empty each
|
|
46
|
+
* time as in memory (a bucket restores it).
|
|
41
47
|
*/
|
|
42
48
|
export declare function nodeSqliteOpener(dir?: string, opts?: {
|
|
43
49
|
exclusive?: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { closeSync, fstatSync, mkdtempSync, openSync, readFileSync, readSync, rmSync, writeFileSync, } from "node:fs";
|
|
1
|
+
import { closeSync, existsSync, fstatSync, mkdtempSync, openSync, readFileSync, readSync, rmdirSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
@@ -15,8 +15,11 @@ export class NodeSqliteDriver {
|
|
|
15
15
|
#path;
|
|
16
16
|
#exclusive;
|
|
17
17
|
#pageCapture;
|
|
18
|
+
/** A file of its own that close() removes (a cell "in memory" that needs a WAL). */
|
|
19
|
+
#temporary;
|
|
18
20
|
constructor(path = ":memory:", opts = {}) {
|
|
19
21
|
this.#path = path;
|
|
22
|
+
this.#temporary = !!opts.temporary && path !== ":memory:";
|
|
20
23
|
this.#exclusive = !!opts.exclusive;
|
|
21
24
|
this.#pageCapture = !!opts.pageCapture && path !== ":memory:";
|
|
22
25
|
// As celld and workerd: a double-quoted name that is no column is a string literal.
|
|
@@ -39,10 +42,16 @@ export class NodeSqliteDriver {
|
|
|
39
42
|
// instead of reading the whole file. Automatic checkpoints are off; take() checkpoints
|
|
40
43
|
// (TRUNCATE) itself once the WAL grows, and restarts from its start.
|
|
41
44
|
#walOffset = 0;
|
|
45
|
+
/** Whether anyone reads the captured pages; until then exec() keeps the WAL bounded itself. */
|
|
46
|
+
#taken = false;
|
|
47
|
+
#writes = 0;
|
|
42
48
|
#walSetup() {
|
|
43
49
|
if (!this.#pageCapture)
|
|
44
50
|
return;
|
|
45
51
|
this.#db.exec("PRAGMA journal_mode = WAL; PRAGMA wal_autocheckpoint = 0;");
|
|
52
|
+
// A temporary file is only the WAL's carrier (the bucket keeps the cell): no fsync per commit.
|
|
53
|
+
if (this.#temporary)
|
|
54
|
+
this.#db.exec("PRAGMA synchronous = OFF");
|
|
46
55
|
this.#db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
47
56
|
this.#walOffset = 0;
|
|
48
57
|
}
|
|
@@ -50,6 +59,7 @@ export class NodeSqliteDriver {
|
|
|
50
59
|
takeDirtyPages() {
|
|
51
60
|
if (!this.#pageCapture)
|
|
52
61
|
return undefined;
|
|
62
|
+
this.#taken = true;
|
|
53
63
|
const walPath = `${this.#path}-wal`;
|
|
54
64
|
let fd;
|
|
55
65
|
try {
|
|
@@ -118,6 +128,8 @@ export class NodeSqliteDriver {
|
|
|
118
128
|
last = this.#one(text, params);
|
|
119
129
|
written += last.rowsWritten;
|
|
120
130
|
}
|
|
131
|
+
if (this.#pageCapture && !this.#taken && ++this.#writes % 64 === 0)
|
|
132
|
+
this.#boundWal();
|
|
121
133
|
return { ...last, rowsWritten: written };
|
|
122
134
|
}
|
|
123
135
|
#one(sql, params) {
|
|
@@ -132,6 +144,23 @@ export class NodeSqliteDriver {
|
|
|
132
144
|
const rows = stmt.all(...args).map((row) => row.map(fromSqlite));
|
|
133
145
|
return { columnNames, rows, rowsWritten: 0 };
|
|
134
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* A database whose pages nobody takes (the runtime's own tables, a storage that logs no pages)
|
|
149
|
+
* has no one to checkpoint its WAL (automatic checkpoints are off): past 4 MiB, fold it in.
|
|
150
|
+
*/
|
|
151
|
+
#boundWal() {
|
|
152
|
+
if (this.inTransaction())
|
|
153
|
+
return;
|
|
154
|
+
try {
|
|
155
|
+
if (statSync(`${this.#path}-wal`).size <= 4 * 1024 * 1024)
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
this.#db.exec("PRAGMA wal_checkpoint(TRUNCATE)");
|
|
162
|
+
this.#walOffset = 0;
|
|
163
|
+
}
|
|
135
164
|
inTransaction() {
|
|
136
165
|
return this.#db.isTransaction;
|
|
137
166
|
}
|
|
@@ -142,6 +171,15 @@ export class NodeSqliteDriver {
|
|
|
142
171
|
}
|
|
143
172
|
close() {
|
|
144
173
|
this.#db.close();
|
|
174
|
+
if (!this.#temporary)
|
|
175
|
+
return;
|
|
176
|
+
for (const suffix of ["", "-wal", "-shm", "-journal"])
|
|
177
|
+
rmSync(this.#path + suffix, { force: true });
|
|
178
|
+
try {
|
|
179
|
+
rmdirSync(dirname(this.#path)); // the opener's directory, once its last cell is closed
|
|
180
|
+
temporaryDirs.delete(dirname(this.#path));
|
|
181
|
+
}
|
|
182
|
+
catch { }
|
|
145
183
|
}
|
|
146
184
|
// ---- change capture (session extension) for transaction logs -------------------------
|
|
147
185
|
#session;
|
|
@@ -242,12 +280,51 @@ function fromSqlite(v) {
|
|
|
242
280
|
return v.buffer.slice(v.byteOffset, v.byteOffset + v.byteLength);
|
|
243
281
|
return v;
|
|
244
282
|
}
|
|
245
|
-
/**
|
|
283
|
+
/** Temporary cell directories still present: removed if the process exits without closing them. */
|
|
284
|
+
const temporaryDirs = new Set();
|
|
285
|
+
let exitHook = false;
|
|
286
|
+
function removeAtExit(dir) {
|
|
287
|
+
temporaryDirs.add(dir);
|
|
288
|
+
if (exitHook)
|
|
289
|
+
return;
|
|
290
|
+
exitHook = true;
|
|
291
|
+
process.once("exit", () => {
|
|
292
|
+
for (const d of temporaryDirs)
|
|
293
|
+
rmSync(d, { recursive: true, force: true });
|
|
294
|
+
});
|
|
295
|
+
}
|
|
246
296
|
/**
|
|
247
|
-
*
|
|
248
|
-
*
|
|
297
|
+
* One file per cell in `dir`; without `dir`, each cell in memory.
|
|
298
|
+
*
|
|
299
|
+
* `pageCapture`: WAL mode, and each commit's changed pages read from the WAL (takeDirtyPages),
|
|
300
|
+
* so LTX logs (a celld bucket) cost O(changed pages) on Node as with SQLite WASM, instead of an
|
|
301
|
+
* image of the whole database (VACUUM INTO) and a page-by-page diff per commit. A WAL needs a
|
|
302
|
+
* file: without `dir`, each cell opened gets a temporary file (in a `cellb-cells-…` directory
|
|
303
|
+
* under the OS temp directory), removed when the cell closes, so it still starts empty each
|
|
304
|
+
* time as in memory (a bucket restores it).
|
|
249
305
|
*/
|
|
250
306
|
export function nodeSqliteOpener(dir, opts = {}) {
|
|
251
|
-
|
|
307
|
+
let temp;
|
|
308
|
+
let opened = 0;
|
|
309
|
+
return (cellKey) => {
|
|
310
|
+
const name = cellKey.replace(/[^\w.-]/g, "_");
|
|
311
|
+
// The runtime's own databases (alarms index, cron state) log no pages: never captured.
|
|
312
|
+
const capture = !!opts.pageCapture && !cellKey.startsWith("__cellb/");
|
|
313
|
+
const o = { ...opts, pageCapture: capture };
|
|
314
|
+
if (dir)
|
|
315
|
+
return new NodeSqliteDriver(`${dir}/${name}.sqlite`, o);
|
|
316
|
+
if (!capture)
|
|
317
|
+
return new NodeSqliteDriver(":memory:", o);
|
|
318
|
+
if (!temp || !existsSync(temp)) {
|
|
319
|
+
temp = mkdtempSync(join(tmpdir(), "cellb-cells-"));
|
|
320
|
+
removeAtExit(temp);
|
|
321
|
+
}
|
|
322
|
+
// A file per opening: a cell reopened while its previous database is still closing gets
|
|
323
|
+
// a fresh one, as in memory.
|
|
324
|
+
return new NodeSqliteDriver(join(temp, `${name}-${++opened}.sqlite`), {
|
|
325
|
+
...o,
|
|
326
|
+
temporary: true,
|
|
327
|
+
});
|
|
328
|
+
};
|
|
252
329
|
}
|
|
253
330
|
//# sourceMappingURL=node-sqlite.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-sqlite.js","sourceRoot":"","sources":["../../src/adapters/node-sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n closeSync,\n fstatSync,\n mkdtempSync,\n openSync,\n readFileSync,\n readSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { DatabaseSync as DatabaseSyncT } from \"node:sqlite\";\n\nimport { splitSqlStatements } from \"../core/sql-split.js\";\nimport type { OpenCellSql, SqlResult, SyncSqlDriver } from \"../ports.js\";\nimport { requireNodeSqlite } from \"./node-sqlite-module.js\";\n\nconst { DatabaseSync } = requireNodeSqlite();\n\nconst requireCjs = createRequire(import.meta.url);\nconst KNOWN_EXTENSIONS: Record<string, () => string> = {\n sqlite_vec: () => (requireCjs(\"sqlite-vec\") as { getLoadablePath(): string }).getLoadablePath(),\n};\n\n/** Server-side SyncSqlDriver over node:sqlite (Node >= 22.13). */\nexport class NodeSqliteDriver implements SyncSqlDriver {\n #db: DatabaseSyncT;\n #path: string;\n readonly #exclusive: boolean;\n readonly #pageCapture: boolean;\n constructor(path = \":memory:\", opts: { exclusive?: boolean; pageCapture?: boolean } = {}) {\n this.#path = path;\n this.#exclusive = !!opts.exclusive;\n this.#pageCapture = !!opts.pageCapture && path !== \":memory:\";\n // As celld and workerd: a double-quoted name that is no column is a string literal.\n this.#db = new DatabaseSync(path, {\n allowExtension: true,\n enableDoubleQuotedStringLiterals: true,\n });\n this.#db.enableLoadExtension(false); // only loadExtension() below may load, by name\n // EXCLUSIVE locking: the first write takes an OS lock on the file that is\n // kept until close (or process death) — a second process can neither read\n // nor write the cell. Storage-level fencing on one host, no lease needed.\n if (opts.exclusive) this.#db.exec(\"PRAGMA locking_mode = EXCLUSIVE; PRAGMA busy_timeout = 0;\");\n this.#walSetup();\n }\n\n // ---- page capture through the WAL (what the WASM driver does with its xWrite hook) ----\n // In WAL mode every commit appends its changed pages to `<db>-wal` as frames (24-byte frame\n // header + page; a commit frame carries the database size in pages). Reading the frames\n // appended since the last read gives exactly the committed transaction's pages, O(changed),\n // instead of reading the whole file. Automatic checkpoints are off; take() checkpoints\n // (TRUNCATE) itself once the WAL grows, and restarts from its start.\n #walOffset = 0;\n #walSetup(): void {\n if (!this.#pageCapture) return;\n this.#db.exec(\"PRAGMA journal_mode = WAL; PRAGMA wal_autocheckpoint = 0;\");\n this.#db.exec(\"PRAGMA wal_checkpoint(TRUNCATE)\");\n this.#walOffset = 0;\n }\n /** The pages of the transactions committed since the previous call (WAL frames). */\n takeDirtyPages():\n | { pageSize: number; pageCount: number; pages: Map<number, Uint8Array> }\n | undefined {\n if (!this.#pageCapture) return undefined;\n const walPath = `${this.#path}-wal`;\n let fd: number;\n try {\n fd = openSync(walPath, \"r\");\n } catch {\n return undefined;\n }\n try {\n const size = fstatSync(fd).size;\n if (size < 32) return undefined;\n const header = Buffer.alloc(32);\n readSync(fd, header, 0, 32, 0);\n const pageSize = header.readUInt32BE(8) === 1 ? 65536 : header.readUInt32BE(8);\n const [salt1, salt2] = [header.readUInt32BE(16), header.readUInt32BE(20)];\n const frameSize = 24 + pageSize;\n let offset = Math.max(32, this.#walOffset);\n const pending = new Map<number, Uint8Array>();\n const pages = new Map<number, Uint8Array>();\n let pageCount = 0;\n let committedTo = offset;\n const frame = Buffer.alloc(frameSize);\n while (offset + frameSize <= size) {\n readSync(fd, frame, 0, frameSize, offset);\n if (frame.readUInt32BE(8) !== salt1 || frame.readUInt32BE(12) !== salt2) break; // stale frames\n pending.set(frame.readUInt32BE(0), new Uint8Array(frame.subarray(24)));\n offset += frameSize;\n const commit = frame.readUInt32BE(4);\n if (commit) {\n for (const [p, d] of pending) pages.set(p, d);\n pending.clear();\n pageCount = commit;\n committedTo = offset;\n }\n }\n this.#walOffset = committedTo;\n if (!pageCount)\n return {\n pageSize,\n pageCount: Number(this.exec(\"PRAGMA page_count\", []).rows[0][0]),\n pages,\n };\n for (const p of [...pages.keys()]) if (p > pageCount) pages.delete(p);\n // keep the WAL bounded: fold it into the database and start over\n if (committedTo > 4 * 1024 * 1024) {\n this.#db.exec(\"PRAGMA wal_checkpoint(TRUNCATE)\");\n this.#walOffset = 0;\n }\n return { pageSize, pageCount, pages };\n } finally {\n closeSync(fd);\n }\n }\n exec(sql: string, params: unknown[]): SqlResult {\n const statements = params.length === 0 ? splitSqlStatements(sql) : [sql];\n // Several statements: the result of the last one, with the rows written by all of them.\n let last: SqlResult = { columnNames: [], rows: [], rowsWritten: 0 };\n let written = 0;\n for (const text of statements) {\n last = this.#one(text, params);\n written += last.rowsWritten;\n }\n return { ...last, rowsWritten: written };\n }\n #one(sql: string, params: unknown[]): SqlResult {\n const stmt = this.#db.prepare(sql);\n const columnNames = stmt.columns().map((c) => c.name);\n const args = params.map(toSqlite) as any[];\n if (columnNames.length === 0) {\n const r = stmt.run(...args);\n return { columnNames, rows: [], rowsWritten: Number(r.changes) };\n }\n stmt.setReturnArrays(true);\n const rows = (stmt.all(...args) as unknown as unknown[][]).map((row) => row.map(fromSqlite));\n return { columnNames, rows, rowsWritten: 0 };\n }\n inTransaction(): boolean {\n return (this.#db as unknown as { isTransaction: boolean }).isTransaction;\n }\n databaseSize(): number {\n const [pc] = this.exec(\"PRAGMA page_count\", []).rows[0] as [number];\n const [ps] = this.exec(\"PRAGMA page_size\", []).rows[0] as [number];\n return Number(pc) * Number(ps);\n }\n close(): void {\n this.#db.close();\n }\n\n // ---- change capture (session extension) for transaction logs -------------------------\n #session: { changeset(): Uint8Array; close(): void } | undefined;\n /** node:sqlite exposes no ROWID session option: PK-less tables are logged as statements. */\n readonly captureCoversRowidTables = false;\n captureStart(): void {\n this.#session?.close();\n this.#session = (\n this.#db as unknown as { createSession(): { changeset(): Uint8Array; close(): void } }\n ).createSession();\n }\n captureTake(): Uint8Array {\n const s = this.#session;\n this.#session = undefined;\n if (!s) return new Uint8Array();\n try {\n return s.changeset();\n } finally {\n s.close();\n }\n }\n captureDiscard(): void {\n this.#session?.close();\n this.#session = undefined;\n }\n applyChangeset(changeset: Uint8Array): void {\n if (!changeset.byteLength) return;\n const SQLITE_CHANGESET_REPLACE = 1;\n (this.#db as unknown as { applyChangeset(c: Uint8Array, o: unknown): boolean }).applyChangeset(\n changeset,\n {\n onConflict: () => SQLITE_CHANGESET_REPLACE,\n },\n );\n }\n\n /** Known extensions only: \"sqlite_vec\" → the sqlite-vec npm package's loadable library. */\n loadExtension(name: string): void {\n const path = KNOWN_EXTENSIONS[name]?.();\n if (!path) throw new Error(`Unknown SQLite extension \"${name}\"`);\n this.#db.enableLoadExtension(true);\n try {\n this.#db.loadExtension(path);\n } finally {\n this.#db.enableLoadExtension(false);\n }\n }\n\n /**\n * The database file as SQLite wrote it (page for page), for page-level logs; an in-memory\n * database falls back to image(). Valid between transactions (rollback journal mode).\n */\n pageImage(): Uint8Array {\n if (this.#path === \":memory:\") return this.image();\n // A database restored from celld's files is in WAL mode (litestream needs it): its last\n // commits are in the -wal file until a checkpoint moves them into the main file.\n const mode = String(this.#db.prepare(\"PRAGMA journal_mode\").get()?.journal_mode ?? \"\");\n if (mode.toLowerCase() === \"wal\") {\n this.#db.exec(\"PRAGMA wal_checkpoint(TRUNCATE)\");\n this.#walOffset = 0; // the WAL starts over\n }\n return new Uint8Array(readFileSync(this.#path));\n }\n\n /** `VACUUM INTO` a temp file: a consistent, compact image (no open transaction allowed). */\n image(): Uint8Array {\n const tmp = join(mkdtempSync(join(tmpdir(), \"cell-snap-\")), \"db.sqlite\");\n try {\n this.#db.exec(`VACUUM INTO '${tmp.replace(/'/g, \"''\")}'`);\n return new Uint8Array(readFileSync(tmp));\n } finally {\n rmSync(dirname(tmp), { recursive: true, force: true });\n }\n }\n\n /** Replaces the database file with `image` and reopens it (an in-memory DB becomes file-backed). */\n restore(image: Uint8Array): void {\n this.#db.close();\n if (this.#path === \":memory:\")\n this.#path = join(mkdtempSync(join(tmpdir(), \"cell-mem-\")), \"db.sqlite\");\n for (const suffix of [\"-wal\", \"-shm\", \"-journal\"]) rmSync(this.#path + suffix, { force: true });\n writeFileSync(this.#path, image);\n this.#db = new DatabaseSync(this.#path, { enableDoubleQuotedStringLiterals: true });\n if (this.#exclusive) this.#db.exec(\"PRAGMA locking_mode = EXCLUSIVE; PRAGMA busy_timeout = 0;\");\n this.#walSetup(); // a new file: a new WAL\n }\n}\n\nfunction toSqlite(v: unknown): unknown {\n if (v instanceof ArrayBuffer) return new Uint8Array(v);\n if (typeof v === \"boolean\") return v ? 1 : 0;\n return v === undefined ? null : v;\n}\n/** Workers return BLOBs as ArrayBuffer. */\nfunction fromSqlite(v: unknown): unknown {\n if (v instanceof Uint8Array) return v.buffer.slice(v.byteOffset, v.byteOffset + v.byteLength);\n return v;\n}\n\n/** One file per cell in `dir`, or in-memory when `dir` is omitted. */\n/**\n * `pageCapture` (file-backed only): WAL mode, and each commit's changed pages read from the WAL\n * (takeDirtyPages) — LTX logs then cost O(changed pages) on Node as with SQLite WASM.\n */\nexport function nodeSqliteOpener(\n dir?: string,\n opts: { exclusive?: boolean; pageCapture?: boolean } = {},\n): OpenCellSql {\n return (cellKey) =>\n new NodeSqliteDriver(\n dir ? `${dir}/${cellKey.replace(/[^\\w.-]/g, \"_\")}.sqlite` : \":memory:\",\n opts,\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"node-sqlite.js","sourceRoot":"","sources":["../../src/adapters/node-sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n closeSync,\n existsSync,\n fstatSync,\n mkdtempSync,\n openSync,\n readFileSync,\n readSync,\n rmdirSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { DatabaseSync as DatabaseSyncT } from \"node:sqlite\";\n\nimport { splitSqlStatements } from \"../core/sql-split.js\";\nimport type { OpenCellSql, SqlResult, SyncSqlDriver } from \"../ports.js\";\nimport { requireNodeSqlite } from \"./node-sqlite-module.js\";\n\nconst { DatabaseSync } = requireNodeSqlite();\n\nconst requireCjs = createRequire(import.meta.url);\nconst KNOWN_EXTENSIONS: Record<string, () => string> = {\n sqlite_vec: () => (requireCjs(\"sqlite-vec\") as { getLoadablePath(): string }).getLoadablePath(),\n};\n\n/** Server-side SyncSqlDriver over node:sqlite (Node >= 22.13). */\nexport class NodeSqliteDriver implements SyncSqlDriver {\n #db: DatabaseSyncT;\n #path: string;\n readonly #exclusive: boolean;\n readonly #pageCapture: boolean;\n /** A file of its own that close() removes (a cell \"in memory\" that needs a WAL). */\n readonly #temporary: boolean;\n constructor(\n path = \":memory:\",\n opts: { exclusive?: boolean; pageCapture?: boolean; temporary?: boolean } = {},\n ) {\n this.#path = path;\n this.#temporary = !!opts.temporary && path !== \":memory:\";\n this.#exclusive = !!opts.exclusive;\n this.#pageCapture = !!opts.pageCapture && path !== \":memory:\";\n // As celld and workerd: a double-quoted name that is no column is a string literal.\n this.#db = new DatabaseSync(path, {\n allowExtension: true,\n enableDoubleQuotedStringLiterals: true,\n });\n this.#db.enableLoadExtension(false); // only loadExtension() below may load, by name\n // EXCLUSIVE locking: the first write takes an OS lock on the file that is\n // kept until close (or process death) — a second process can neither read\n // nor write the cell. Storage-level fencing on one host, no lease needed.\n if (opts.exclusive) this.#db.exec(\"PRAGMA locking_mode = EXCLUSIVE; PRAGMA busy_timeout = 0;\");\n this.#walSetup();\n }\n\n // ---- page capture through the WAL (what the WASM driver does with its xWrite hook) ----\n // In WAL mode every commit appends its changed pages to `<db>-wal` as frames (24-byte frame\n // header + page; a commit frame carries the database size in pages). Reading the frames\n // appended since the last read gives exactly the committed transaction's pages, O(changed),\n // instead of reading the whole file. Automatic checkpoints are off; take() checkpoints\n // (TRUNCATE) itself once the WAL grows, and restarts from its start.\n #walOffset = 0;\n /** Whether anyone reads the captured pages; until then exec() keeps the WAL bounded itself. */\n #taken = false;\n #writes = 0;\n #walSetup(): void {\n if (!this.#pageCapture) return;\n this.#db.exec(\"PRAGMA journal_mode = WAL; PRAGMA wal_autocheckpoint = 0;\");\n // A temporary file is only the WAL's carrier (the bucket keeps the cell): no fsync per commit.\n if (this.#temporary) this.#db.exec(\"PRAGMA synchronous = OFF\");\n this.#db.exec(\"PRAGMA wal_checkpoint(TRUNCATE)\");\n this.#walOffset = 0;\n }\n /** The pages of the transactions committed since the previous call (WAL frames). */\n takeDirtyPages():\n | { pageSize: number; pageCount: number; pages: Map<number, Uint8Array> }\n | undefined {\n if (!this.#pageCapture) return undefined;\n this.#taken = true;\n const walPath = `${this.#path}-wal`;\n let fd: number;\n try {\n fd = openSync(walPath, \"r\");\n } catch {\n return undefined;\n }\n try {\n const size = fstatSync(fd).size;\n if (size < 32) return undefined;\n const header = Buffer.alloc(32);\n readSync(fd, header, 0, 32, 0);\n const pageSize = header.readUInt32BE(8) === 1 ? 65536 : header.readUInt32BE(8);\n const [salt1, salt2] = [header.readUInt32BE(16), header.readUInt32BE(20)];\n const frameSize = 24 + pageSize;\n let offset = Math.max(32, this.#walOffset);\n const pending = new Map<number, Uint8Array>();\n const pages = new Map<number, Uint8Array>();\n let pageCount = 0;\n let committedTo = offset;\n const frame = Buffer.alloc(frameSize);\n while (offset + frameSize <= size) {\n readSync(fd, frame, 0, frameSize, offset);\n if (frame.readUInt32BE(8) !== salt1 || frame.readUInt32BE(12) !== salt2) break; // stale frames\n pending.set(frame.readUInt32BE(0), new Uint8Array(frame.subarray(24)));\n offset += frameSize;\n const commit = frame.readUInt32BE(4);\n if (commit) {\n for (const [p, d] of pending) pages.set(p, d);\n pending.clear();\n pageCount = commit;\n committedTo = offset;\n }\n }\n this.#walOffset = committedTo;\n if (!pageCount)\n return {\n pageSize,\n pageCount: Number(this.exec(\"PRAGMA page_count\", []).rows[0][0]),\n pages,\n };\n for (const p of [...pages.keys()]) if (p > pageCount) pages.delete(p);\n // keep the WAL bounded: fold it into the database and start over\n if (committedTo > 4 * 1024 * 1024) {\n this.#db.exec(\"PRAGMA wal_checkpoint(TRUNCATE)\");\n this.#walOffset = 0;\n }\n return { pageSize, pageCount, pages };\n } finally {\n closeSync(fd);\n }\n }\n exec(sql: string, params: unknown[]): SqlResult {\n const statements = params.length === 0 ? splitSqlStatements(sql) : [sql];\n // Several statements: the result of the last one, with the rows written by all of them.\n let last: SqlResult = { columnNames: [], rows: [], rowsWritten: 0 };\n let written = 0;\n for (const text of statements) {\n last = this.#one(text, params);\n written += last.rowsWritten;\n }\n if (this.#pageCapture && !this.#taken && ++this.#writes % 64 === 0) this.#boundWal();\n return { ...last, rowsWritten: written };\n }\n #one(sql: string, params: unknown[]): SqlResult {\n const stmt = this.#db.prepare(sql);\n const columnNames = stmt.columns().map((c) => c.name);\n const args = params.map(toSqlite) as any[];\n if (columnNames.length === 0) {\n const r = stmt.run(...args);\n return { columnNames, rows: [], rowsWritten: Number(r.changes) };\n }\n stmt.setReturnArrays(true);\n const rows = (stmt.all(...args) as unknown as unknown[][]).map((row) => row.map(fromSqlite));\n return { columnNames, rows, rowsWritten: 0 };\n }\n /**\n * A database whose pages nobody takes (the runtime's own tables, a storage that logs no pages)\n * has no one to checkpoint its WAL (automatic checkpoints are off): past 4 MiB, fold it in.\n */\n #boundWal(): void {\n if (this.inTransaction()) return;\n try {\n if (statSync(`${this.#path}-wal`).size <= 4 * 1024 * 1024) return;\n } catch {\n return;\n }\n this.#db.exec(\"PRAGMA wal_checkpoint(TRUNCATE)\");\n this.#walOffset = 0;\n }\n inTransaction(): boolean {\n return (this.#db as unknown as { isTransaction: boolean }).isTransaction;\n }\n databaseSize(): number {\n const [pc] = this.exec(\"PRAGMA page_count\", []).rows[0] as [number];\n const [ps] = this.exec(\"PRAGMA page_size\", []).rows[0] as [number];\n return Number(pc) * Number(ps);\n }\n close(): void {\n this.#db.close();\n if (!this.#temporary) return;\n for (const suffix of [\"\", \"-wal\", \"-shm\", \"-journal\"])\n rmSync(this.#path + suffix, { force: true });\n try {\n rmdirSync(dirname(this.#path)); // the opener's directory, once its last cell is closed\n temporaryDirs.delete(dirname(this.#path));\n } catch {}\n }\n\n // ---- change capture (session extension) for transaction logs -------------------------\n #session: { changeset(): Uint8Array; close(): void } | undefined;\n /** node:sqlite exposes no ROWID session option: PK-less tables are logged as statements. */\n readonly captureCoversRowidTables = false;\n captureStart(): void {\n this.#session?.close();\n this.#session = (\n this.#db as unknown as { createSession(): { changeset(): Uint8Array; close(): void } }\n ).createSession();\n }\n captureTake(): Uint8Array {\n const s = this.#session;\n this.#session = undefined;\n if (!s) return new Uint8Array();\n try {\n return s.changeset();\n } finally {\n s.close();\n }\n }\n captureDiscard(): void {\n this.#session?.close();\n this.#session = undefined;\n }\n applyChangeset(changeset: Uint8Array): void {\n if (!changeset.byteLength) return;\n const SQLITE_CHANGESET_REPLACE = 1;\n (this.#db as unknown as { applyChangeset(c: Uint8Array, o: unknown): boolean }).applyChangeset(\n changeset,\n {\n onConflict: () => SQLITE_CHANGESET_REPLACE,\n },\n );\n }\n\n /** Known extensions only: \"sqlite_vec\" → the sqlite-vec npm package's loadable library. */\n loadExtension(name: string): void {\n const path = KNOWN_EXTENSIONS[name]?.();\n if (!path) throw new Error(`Unknown SQLite extension \"${name}\"`);\n this.#db.enableLoadExtension(true);\n try {\n this.#db.loadExtension(path);\n } finally {\n this.#db.enableLoadExtension(false);\n }\n }\n\n /**\n * The database file as SQLite wrote it (page for page), for page-level logs; an in-memory\n * database falls back to image(). Valid between transactions (rollback journal mode).\n */\n pageImage(): Uint8Array {\n if (this.#path === \":memory:\") return this.image();\n // A database restored from celld's files is in WAL mode (litestream needs it): its last\n // commits are in the -wal file until a checkpoint moves them into the main file.\n const mode = String(this.#db.prepare(\"PRAGMA journal_mode\").get()?.journal_mode ?? \"\");\n if (mode.toLowerCase() === \"wal\") {\n this.#db.exec(\"PRAGMA wal_checkpoint(TRUNCATE)\");\n this.#walOffset = 0; // the WAL starts over\n }\n return new Uint8Array(readFileSync(this.#path));\n }\n\n /** `VACUUM INTO` a temp file: a consistent, compact image (no open transaction allowed). */\n image(): Uint8Array {\n const tmp = join(mkdtempSync(join(tmpdir(), \"cell-snap-\")), \"db.sqlite\");\n try {\n this.#db.exec(`VACUUM INTO '${tmp.replace(/'/g, \"''\")}'`);\n return new Uint8Array(readFileSync(tmp));\n } finally {\n rmSync(dirname(tmp), { recursive: true, force: true });\n }\n }\n\n /** Replaces the database file with `image` and reopens it (an in-memory DB becomes file-backed). */\n restore(image: Uint8Array): void {\n this.#db.close();\n if (this.#path === \":memory:\")\n this.#path = join(mkdtempSync(join(tmpdir(), \"cell-mem-\")), \"db.sqlite\");\n for (const suffix of [\"-wal\", \"-shm\", \"-journal\"]) rmSync(this.#path + suffix, { force: true });\n writeFileSync(this.#path, image);\n this.#db = new DatabaseSync(this.#path, { enableDoubleQuotedStringLiterals: true });\n if (this.#exclusive) this.#db.exec(\"PRAGMA locking_mode = EXCLUSIVE; PRAGMA busy_timeout = 0;\");\n this.#walSetup(); // a new file: a new WAL\n }\n}\n\nfunction toSqlite(v: unknown): unknown {\n if (v instanceof ArrayBuffer) return new Uint8Array(v);\n if (typeof v === \"boolean\") return v ? 1 : 0;\n return v === undefined ? null : v;\n}\n/** Workers return BLOBs as ArrayBuffer. */\nfunction fromSqlite(v: unknown): unknown {\n if (v instanceof Uint8Array) return v.buffer.slice(v.byteOffset, v.byteOffset + v.byteLength);\n return v;\n}\n\n/** Temporary cell directories still present: removed if the process exits without closing them. */\nconst temporaryDirs = new Set<string>();\nlet exitHook = false;\nfunction removeAtExit(dir: string): void {\n temporaryDirs.add(dir);\n if (exitHook) return;\n exitHook = true;\n process.once(\"exit\", () => {\n for (const d of temporaryDirs) rmSync(d, { recursive: true, force: true });\n });\n}\n\n/**\n * One file per cell in `dir`; without `dir`, each cell in memory.\n *\n * `pageCapture`: WAL mode, and each commit's changed pages read from the WAL (takeDirtyPages),\n * so LTX logs (a celld bucket) cost O(changed pages) on Node as with SQLite WASM, instead of an\n * image of the whole database (VACUUM INTO) and a page-by-page diff per commit. A WAL needs a\n * file: without `dir`, each cell opened gets a temporary file (in a `cellb-cells-…` directory\n * under the OS temp directory), removed when the cell closes, so it still starts empty each\n * time as in memory (a bucket restores it).\n */\nexport function nodeSqliteOpener(\n dir?: string,\n opts: { exclusive?: boolean; pageCapture?: boolean } = {},\n): OpenCellSql {\n let temp: string | undefined;\n let opened = 0;\n return (cellKey) => {\n const name = cellKey.replace(/[^\\w.-]/g, \"_\");\n // The runtime's own databases (alarms index, cron state) log no pages: never captured.\n const capture = !!opts.pageCapture && !cellKey.startsWith(\"__cellb/\");\n const o = { ...opts, pageCapture: capture };\n if (dir) return new NodeSqliteDriver(`${dir}/${name}.sqlite`, o);\n if (!capture) return new NodeSqliteDriver(\":memory:\", o);\n if (!temp || !existsSync(temp)) {\n temp = mkdtempSync(join(tmpdir(), \"cellb-cells-\"));\n removeAtExit(temp);\n }\n // A file per opening: a cell reopened while its previous database is still closing gets\n // a fresh one, as in memory.\n return new NodeSqliteDriver(join(temp, `${name}-${++opened}.sqlite`), {\n ...o,\n temporary: true,\n });\n };\n}\n"]}
|
package/dist/core/object-host.js
CHANGED
|
@@ -278,7 +278,7 @@ export class ObjectHost {
|
|
|
278
278
|
let started;
|
|
279
279
|
this.#active++;
|
|
280
280
|
try {
|
|
281
|
-
started = Promise.resolve(this.#root(() => fn(this.#instance, this.state)));
|
|
281
|
+
started = Promise.resolve(this.#root(() => this.state.storage.runEvent(() => fn(this.#instance, this.state))));
|
|
282
282
|
}
|
|
283
283
|
catch (e) {
|
|
284
284
|
started = Promise.reject(e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"object-host.js","sourceRoot":"","sources":["../../src/core/object-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex } from \"@noble/hashes/utils.js\";\nimport type {\n BackupInfo,\n CellBackup,\n CellDurability,\n Lease,\n OpenCellSql,\n SyncSqlDriver,\n ValueCodec,\n} from \"../ports.js\";\nimport type { AsyncRoot } from \"./async-context.js\";\nimport { CELLD_SCHEMA, LOG_SEQ_READ, LOG_SEQ_WRITE, LOG_TABLE, scopeOf } from \"./celld-schema.js\";\nimport { InputGate, OutputGate } from \"./gates.js\";\nimport {\n asyncStub,\n type DurableObjectClass,\n type IsolatedClass,\n isClassHandle,\n} from \"./handles.js\";\nimport { type DurableObjectId, DurableObjectId as DurableObjectIdClass } from \"./id.js\";\nimport { SqlStorage } from \"./sql-storage.js\";\nimport { DurableObjectState } from \"./state.js\";\nimport { DurableObjectStorage, SyncKvStorage } from \"./storage.js\";\n\n/**\n * The request as the object sees it: its signal also aborts when the host closes (the runtime\n * shuts down), as on Cloudflare when the client goes away; a long poll or an SSE stream that\n * waits on it then ends instead of running on into a closed database.\n *\n * The request is not copied: its `signal` becomes a getter that builds the merged signal the\n * first time it is read. Copying a Request and merging two signals cost about 7 µs a request, as\n * much as a small handler's whole turn, and most handlers never read the signal. The request is\n * the caller's own object (`runtime.fetch`) or a stub's fresh copy (a Durable Object's `fetch`);\n * `cf` and the upgrade's `headers` that cellb sets on it stay as they are. A copy the handler\n * makes itself (`new Request(req)`) takes the request's own signal, without the host's.\n */\nexport function closingWith(req: Request, closing: AbortSignal): Request {\n if (closing.aborted) return req;\n const own = signalOf(req);\n let merged: AbortSignal | undefined;\n try {\n Object.defineProperty(req, \"signal\", {\n configurable: true,\n enumerable: false,\n get: () => {\n if (!merged) {\n const before = own();\n merged = before ? AbortSignal.any([before, closing]) : closing;\n }\n return merged;\n },\n });\n return req;\n } catch {\n // A request whose `signal` cannot be redefined: a copy with the merged signal, as before.\n const r = new Request(req, { signal: AbortSignal.any([req.signal, closing]) });\n for (const k of [\"cf\", \"headers\"]) {\n const d = Object.getOwnPropertyDescriptor(req, k);\n if (d) Object.defineProperty(r, k, d);\n }\n return r;\n }\n}\n\n/** Reads `req.signal` as it is now: a getter set by an earlier `closingWith`, or the Request's own. */\nfunction signalOf(req: Request): () => AbortSignal | undefined {\n for (let o: object | null = req; o; o = Object.getPrototypeOf(o)) {\n const d = Object.getOwnPropertyDescriptor(o, \"signal\");\n if (d) return d.get ? () => d.get?.call(req) : () => d.value;\n }\n return () => undefined;\n}\n\n/** The object's host was closed for good: its storage and events fail with this. */\nexport class ObjectClosedError extends Error {\n override name = \"ObjectClosedError\";\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} was closed (its runtime shut down, or it moved or was reset)`);\n }\n}\n\nexport class BrokenObjectError extends Error {\n constructor(cause: unknown, reason = \"its storage failed to commit durably\") {\n const detail = cause instanceof Error ? `: ${cause.message}` : \"\";\n super(`Durable Object reset because ${reason}${detail}`, { cause });\n this.name = \"BrokenObjectError\";\n }\n}\n\n/**\n * One live instance of one Durable Object: its SQLite, gates and dispatcher.\n * Everything that reaches the object (fetch, RPC, later alarms/WebSockets)\n * goes through `deliver()`.\n */\nexport class ObjectHost {\n readonly cellKey: string;\n readonly #gate = new InputGate();\n readonly #out = new OutputGate();\n /** The open database; `#driver` follows it, so it can be closed while idle and reopened. */\n #db!: SyncSqlDriver;\n readonly #driver: SyncSqlDriver = new Proxy({} as SyncSqlDriver, {\n get: (_t, k) => {\n // Closed for good (its runtime or shard shut down): code still running in the object\n // learns why, instead of SQLite's \"DB has been closed\".\n if (this.#closed && k !== \"close\")\n return () => {\n throw new ObjectClosedError(this.cellKey);\n };\n const v = (this.#db as unknown as Record<PropertyKey, unknown>)[k];\n return typeof v === \"function\" ? v.bind(this.#db) : v;\n },\n });\n readonly #sql: SqlStorage;\n #instance: any;\n readonly #backup?: CellBackup;\n #backedUpSeq = 0;\n #saving: Promise<void> | undefined;\n readonly state: DurableObjectState;\n #seq = 0;\n broken = false;\n #brokenCause: unknown;\n\n /** blockConcurrencyWhile() rejected (CF: the object is reset; queued events fail). */\n #breakOn(e: unknown): void {\n this.broken = true;\n this.#brokenCause = e;\n }\n\n constructor(opts: {\n cellKey: string;\n id: DurableObjectId;\n cls: DurableObjectClass;\n env: unknown;\n openSql: OpenCellSql;\n durability: CellDurability;\n codec: ValueCodec;\n waitUntil: (p: Promise<unknown>) => void;\n backup?: CellBackup;\n /** The stored alarm changed (null = cleared). */\n onAlarmChange?: (at: number | null) => void;\n /** `ctx.exports` (loopback handles of the Worker's exports). */\n exports?: Record<string, unknown>;\n /** `ctx.props` of a facet started from a class handle with `{ props }`. */\n props?: unknown;\n /** SQLite extensions to load into every cell database (e.g. \"sqlite_vec\"). */\n sqlExtensions?: string[];\n /** storage.deleteAll() keeps the alarm (`delete_all_preserves_alarm`). */\n deleteAllPreservesAlarm?: boolean;\n /**\n * Ownership: acquire the cell's lease before restoring it. No lease → the cell is owned\n * elsewhere (the host refuses events). The lease epoch fences the cell's log segments;\n * losing the lease breaks the host so it stops serving.\n */\n /** Owner epoch when no lease is taken (facets inherit their root's). */\n epoch?: number;\n /** A facet: on open its rows move to this run's scope, as celld does. */\n facet?: boolean;\n acquire?: Lease[\"tryAcquire\"];\n /** The async context events start in (`asyncRoot()`): not the caller's, as on Cloudflare. */\n asyncRoot?: AsyncRoot;\n }) {\n this.#backup = opts.backup;\n this.cellKey = opts.cellKey;\n this.#epoch = opts.epoch;\n this.#opts = opts;\n this.#open = () => {\n this.#db = opts.openSql(opts.cellKey);\n for (const ext of opts.sqlExtensions ?? []) this.#db.loadExtension(ext);\n };\n this.#open();\n this.#sql = new SqlStorage(\n this.#driver,\n (changes) => {\n if (changes && this.#epoch !== undefined) changes.epoch = this.#epoch;\n // Page-level logs (LTX): the changed pages straight from the page hook when the driver\n // has one; the image only on demand (a generation's first snapshot, or no hook).\n const d = this.#driver;\n const seq = ++this.#seq;\n const pages = opts.durability.capturePages ? d.takeDirtyPages() : undefined;\n const snap = () => d.pageImage?.() ?? d.image?.();\n // The log runs later, after the next event may have opened its transaction, and an\n // image cannot be taken inside one (VACUUM INTO). When the log will surely need it\n // (no page hook) or likely does (this host's first commit), take it now.\n const image = opts.durability.capturePages\n ? !pages || seq === 1\n ? snap()\n : snap\n : undefined;\n const durable = opts.durability.committed(this.cellKey, {\n seq,\n changes,\n image,\n pages,\n epoch: this.#epoch,\n });\n const wake = this.#wakeAfterCommit();\n return this.#out.track(wake ? durable.then(wake) : durable);\n },\n { capture: !!opts.durability.captureChanges },\n );\n // The cell's scope in celld's tables (\"Class:idhex\"), so its database is celld's format.\n const kv = new SyncKvStorage(this.#sql, opts.codec, scopeOf(opts.cellKey));\n if (!opts.facet) kv.actorName = opts.id.name;\n const storage = new DurableObjectStorage(this.#sql, kv, this.#gate, () => this.#barrier());\n if (opts.onAlarmChange) storage.onAlarmChange = opts.onAlarmChange;\n storage.deleteAllPreservesAlarm = !!opts.deleteAllPreservesAlarm;\n const state = new DurableObjectState(opts.id, storage, this.#gate, opts.waitUntil, (e) =>\n this.#breakOn(e),\n );\n this.state = state;\n state.attachDispatcher((fn) => this.deliver(fn));\n // ctx.abort(reason) (workerd, celld): the object resets — a fresh instance on the same\n // database serves the next event; the calling event fails with the reason. Writes the event\n // already made still commit (celld: celld's workflow cell aborts after its delete commit).\n (state as unknown as { abort(reason?: unknown): never }).abort = (reason?: unknown): never => {\n queueMicrotask(() => this.restart());\n throw reason ?? new Error(\"Durable Object reset because its code calls abort()\");\n };\n state.exports = opts.exports ?? {};\n state.props = opts.props;\n state.facets = createFacets(\n { ...opts, epoch: () => this.#epoch },\n (name, cls, env, id, props) => {\n const facet = new ObjectHost({\n ...opts,\n // celld's facet stream: <parent>/facets/<SHA-256(name)[0..16] hex> (engine_api.rs)\n cellKey: `${opts.cellKey}/facets/${facetSegment(name)}`,\n id,\n cls,\n env,\n props,\n onAlarmChange: undefined,\n // A facet is part of its root's cell: no lease of its own, the root's epoch.\n acquire: undefined,\n epoch: this.#epoch,\n facet: true,\n });\n this.#facets.add(facet); // closed with its root\n return facet;\n },\n );\n const root = opts.asyncRoot ?? ((fn) => fn());\n this.#root = root;\n const construct = () => root(() => (this.#instance = new opts.cls(state, opts.env)));\n this.#construct = construct;\n const load = opts.backup?.load;\n const replay = opts.backup?.replay;\n const acquire = opts.acquire;\n if (!load && !replay && !acquire) {\n this.#nameFromMetadata(state);\n construct();\n return;\n }\n // Restore-on-open: events queue behind the closed gate until the image is in.\n void this.#gate\n .runClosed(async () => {\n if (acquire) {\n const lease = await acquire(this.cellKey);\n if (!lease) throw new CellOwnedElsewhereError(this.cellKey);\n this.#epoch = lease.epoch;\n this.#release = lease.release;\n lease.lost.addEventListener(\n \"abort\",\n () => this.#breakOn(new Error(`lease of ${this.cellKey} lost`)),\n {\n once: true,\n },\n );\n }\n // Under a lease (the cell's own, or its root's for a facet) the bucket is the cell's\n // truth: a local file kept from an earlier ownership is older than what other owners\n // wrote since, and may hold commits that never became durable.\n await this.#catchUp(this.#epoch !== undefined);\n if (opts.facet) this.#rescope(scopeOf(opts.cellKey));\n else {\n this.#initWake();\n this.#scheduleRestoredAlarm(opts.onAlarmChange);\n }\n this.#nameFromMetadata(state);\n construct();\n })\n .catch((e) => this.#breakOn(e));\n }\n\n /**\n * Takes an image if the cell changed since the last successful save and hands\n * it to `backup.save`. Taken synchronously between events → a consistent image.\n * Skipped while an async transaction() holds the database or a save is running.\n */\n backupIfDirty(reason: BackupInfo[\"reason\"], now: number): Promise<void> {\n const b = this.#backup;\n if (!b || this.broken || this.#saving || this.#seq === this.#backedUpSeq)\n return this.#saving ?? Promise.resolve();\n if (!this.#driver.image)\n return Promise.reject(new Error(\"SyncSqlDriver has no image(): cannot back up\"));\n if (this.#sql.held) return Promise.resolve(); // mid-transaction: next round\n this.#sql.commit();\n const seq = this.#seq;\n let logSeq = 0;\n try {\n logSeq = Number(this.#driver.exec(LOG_SEQ_READ, []).rows[0]?.[0] ?? 0);\n } catch {\n // no _cf_LOG yet\n }\n const image = this.#driver.image();\n this.#saving = b\n .save(this.cellKey, image, { seq, takenAt: now, reason, logSeq })\n .then(\n () => {\n this.#backedUpSeq = Math.max(this.#backedUpSeq, seq);\n },\n (e) => b.onError?.(this.cellKey, e),\n )\n .finally(() => (this.#saving = undefined));\n return this.#saving;\n }\n\n /**\n * Input gate → handler → commit → output gate (durability) → result.\n *\n * Events are queued and STARTED synchronously by a pump only while the gate\n * is open: the first storage op of a handler closes the gate before the\n * next event can start (checking the gate in an `await` continuation is too\n * late — every queued continuation would see it open).\n */\n deliver<T>(fn: (instance: any, state: DurableObjectState) => T | Promise<T>): Promise<T> {\n if (this.#closed) return Promise.reject(new ObjectClosedError(this.cellKey));\n if (this.broken) return Promise.reject(new BrokenObjectError(undefined));\n return new Promise<T>((resolve, reject) => {\n this.#queue.push(() => {\n if (this.#closed) return reject(new ObjectClosedError(this.cellKey));\n if (this.broken)\n return reject(new BrokenObjectError(this.#brokenCause, \"its initialization failed\"));\n let started: Promise<T>;\n this.#active++;\n try {\n started = Promise.resolve(this.#root(() => fn(this.#instance, this.state)));\n } catch (e) {\n started = Promise.reject(e);\n }\n const done = () => {\n this.#active--;\n this.lastActive = Date.now();\n if (!this.#active && !this.#queue.length) this.#notifyIdle();\n };\n started.then(\n (r) => {\n this.#pinIfStandardWebSocket(r);\n this.#barrier().then(\n () => (done(), resolve(r)),\n (e) => (done(), reject(e)),\n );\n },\n (e) =>\n this.#barrier().then(\n () => (done(), reject(e)),\n (e2) => (done(), reject(e2)),\n ),\n );\n });\n this.#pump();\n });\n }\n\n #queue: (() => void)[] = [];\n #pumpWaiting = false;\n #pump = (): void => {\n this.#pumpWaiting = false;\n while (this.#queue.length && this.#gate.isOpen) {\n // A database closed while idle: reopen it (and catch up) before anything runs.\n if (this.#dbClosed) {\n this.#dbClosed = false;\n void this.#gate\n .runClosed(async () => {\n this.#open();\n // The lease was held throughout: a kept file is current, an empty one is restored.\n await this.#catchUp(false);\n })\n .catch((e) => this.#breakOn(e));\n continue;\n }\n // Waking from hibernation: the constructor runs again before the event (and may\n // close the gate with blockConcurrencyWhile, which the loop then respects).\n if (this.#hibernated) {\n this.#hibernated = false;\n this.#construct?.();\n continue;\n }\n this.#queue.shift()!();\n }\n if (this.#queue.length && !this.#pumpWaiting) {\n this.#pumpWaiting = true;\n this.#gate.onOpen(this.#pump);\n }\n };\n\n async #barrier(): Promise<void> {\n try {\n this.#sql.commit();\n await this.#out.barrier();\n } catch (e) {\n this.broken = true;\n try {\n this.#sql.rollback();\n } catch {}\n throw new BrokenObjectError(e);\n }\n }\n\n /**\n * Settles once no event is in flight or queued (a response body still streaming is not an\n * event: its handler has returned). The runtime waits for it, within a grace period, before\n * it closes the database on shutdown.\n */\n /** No event in flight or queued. */\n get idle(): boolean {\n return !this.#active && !this.#queue.length;\n }\n settled(): Promise<void> {\n if (!this.#active && !this.#queue.length) return Promise.resolve();\n return new Promise((resolve) => this.#idleWaiters.push(resolve));\n }\n #idleWaiters: (() => void)[] = [];\n #notifyIdle(): void {\n const waiters = this.#idleWaiters;\n this.#idleWaiters = [];\n for (const w of waiters) w();\n }\n\n /** Closed for good: storage calls throw ObjectClosedError. */\n #closed = false;\n readonly #closing = new AbortController();\n /** Aborts when the host is shutting down: the signal of the requests it is handed. */\n get closing(): AbortSignal {\n return this.#closing.signal;\n }\n /** The first step of a shutdown: requests in flight see their signal abort. */\n shutdown(): void {\n if (this.#closing.signal.aborted) return;\n this.#closing.abort(new ObjectClosedError(this.cellKey));\n for (const facet of this.#facets) facet.shutdown();\n }\n\n /** Settles once the cell lease is released (a store closed earlier would keep it held). */\n close(): Promise<void> {\n this.shutdown();\n this.#closed = true;\n for (const facet of this.#facets) void facet.close();\n this.#facets.clear();\n if (!this.#dbClosed) this.#db.close();\n // Events still queued fail (each checks #closed first); nothing more runs here.\n for (const queued of this.#queue.splice(0)) queued();\n this.#notifyIdle();\n // Hand the cell over at once instead of letting the lease expire.\n const released = this.#release?.().catch(() => {});\n this.#release = undefined;\n return released ?? Promise.resolve();\n }\n #release: (() => Promise<void>) | undefined;\n /** The hosts of this cell's facets: their databases close with the root's. */\n readonly #facets = new Set<ObjectHost>();\n\n /**\n * Brings the local database to the storage's state: restores the image, then replays the log.\n * Without `rebuild` only an empty database is restored (the local file is the primary copy);\n * with it, a non-empty one is replaced too — dropped first when the storage has no image.\n */\n async #catchUp(rebuild: boolean): Promise<void> {\n const { load, replay } = this.#backup ?? {};\n if (!load && !replay) return;\n const d = this.#driver;\n const empty = Number(d.exec(\"SELECT count(*) FROM sqlite_master\", []).rows[0][0]) === 0;\n if (!empty && !rebuild) return;\n const image = await load?.(this.cellKey);\n if (image) {\n if (!d.restore) throw new Error(\"SyncSqlDriver has no restore(): cannot restore a backup\");\n d.restore(image);\n } else if (!empty) {\n // Indexes and triggers go with their tables; sqlite_* tables cannot be dropped. Foreign\n // keys are off meanwhile, so a parent table can go before its children.\n const objects = d.exec(\n \"SELECT type, name FROM sqlite_master WHERE type IN ('view', 'table') AND name NOT LIKE 'sqlite_%'\",\n [],\n ).rows;\n const fk = Number(d.exec(\"PRAGMA foreign_keys\", []).rows[0][0]);\n d.exec(\"PRAGMA foreign_keys = OFF\", []);\n try {\n for (const [type, name] of objects)\n d.exec(`DROP ${type} IF EXISTS \"${String(name).replace(/\"/g, '\"\"')}\"`, []);\n } finally {\n d.exec(`PRAGMA foreign_keys = ${fk}`, []);\n }\n }\n // Then every logged transaction the image does not contain, in order.\n if (replay) await this.#replayLog(replay);\n }\n\n /** Applies log segments newer than the database's own log sequence (restore path). */\n async #replayLog(replay: NonNullable<CellBackup[\"replay\"]>): Promise<void> {\n const d = this.#driver;\n d.exec(LOG_TABLE, []);\n const row = d.exec(LOG_SEQ_READ, []).rows[0];\n const after = Number(row?.[0] ?? 0);\n for await (const seg of replay(this.cellKey, after)) {\n if (!d.applyChangeset)\n throw new Error(\"SyncSqlDriver cannot apply changesets: cannot replay a log\");\n d.exec(\"BEGIN\", []);\n try {\n for (const ddl of seg.ddl) d.exec(ddl, []);\n d.applyChangeset(seg.changeset);\n for (const [sql, params] of seg.statements) d.exec(sql, params);\n d.exec(LOG_SEQ_WRITE, [seg.logSeq]);\n d.exec(\"COMMIT\", []);\n } catch (e) {\n d.exec(\"ROLLBACK\", []);\n throw e;\n }\n }\n }\n\n #construct?: () => unknown;\n #root: AsyncRoot = (fn) => fn();\n readonly #open: () => void;\n #epoch: number | undefined;\n\n /**\n * celld gives each run of a facet its own scope and moves the facet database's rows to it\n * on open (storage.rs open_embedded); doing the same here reads a facet database celld\n * wrote, whatever scope it used.\n */\n /**\n * celld's alarm publication identity (storage/wake_record.rs initialize): one `_cf_WAKE`\n * row per cell carrying the writer epoch; triggers bump its sequence on every alarm change.\n */\n #initWake(): void {\n if (!this.#epoch || !this.#opts.durability.publishWake) return;\n const scope = scopeOf(this.cellKey);\n for (const ddl of CELLD_SCHEMA) this.#driver.exec(ddl, []);\n this.#driver.exec(\n `INSERT INTO _cf_WAKE(scope,epoch,sequence,at_ms)\n VALUES(?1,?2,0,(SELECT at_ms FROM _cf_ALARM WHERE scope=?1))\n ON CONFLICT(scope) DO UPDATE SET epoch=excluded.epoch WHERE excluded.epoch>_cf_WAKE.epoch`,\n [scope, this.#epoch.toString(16).padStart(16, \"0\")],\n );\n this.#wakeSeq = this.#wakeRow()?.sequence;\n }\n /**\n * A cell restored on open may carry an alarm armed by its previous owner (another node, or\n * celld). This node owns the cell now, so the alarm is its to fire: hand it to the scheduler,\n * which otherwise only hears of alarms set here (or of a later wake-index poll).\n */\n #scheduleRestoredAlarm(onAlarmChange?: (at: number) => void): void {\n let at: unknown;\n try {\n at = this.#driver.exec(\"SELECT at_ms FROM _cf_ALARM WHERE scope = ?\", [scopeOf(this.cellKey)])\n .rows[0]?.[0];\n } catch {\n return; // no alarm table: the cell never had an alarm\n }\n if (at != null) onAlarmChange?.(Number(at));\n }\n #wakeSeq: number | undefined;\n #wakeRow(): { epoch: number; sequence: number; at: number | null } | undefined {\n try {\n const r = this.#driver.exec(\"SELECT epoch, sequence, at_ms FROM _cf_WAKE WHERE scope = ?\", [\n scopeOf(this.cellKey),\n ]).rows[0];\n return r\n ? {\n epoch: Number.parseInt(String(r[0]), 16),\n sequence: Number(r[1]),\n at: r[2] == null ? null : Number(r[2]),\n }\n : undefined;\n } catch {\n return undefined;\n }\n }\n /**\n * After a commit: if it changed the alarm, a publication to run once the commit is durable\n * (celld publishes after replication).\n */\n #wakeAfterCommit(): (() => Promise<void>) | undefined {\n const publish = this.#opts.durability.publishWake;\n if (!publish || this.#opts.facet || !this.#epoch) return undefined;\n const row = this.#wakeRow();\n if (!row || row.sequence === this.#wakeSeq) return undefined;\n this.#wakeSeq = row.sequence;\n return () => publish(this.cellKey, row);\n }\n readonly #opts: { durability: CellDurability; facet?: boolean };\n\n /**\n * celld records the name an object was addressed by (`_cf_METADATA.actor_name`) and gives it\n * back as `ctx.id.name` when the object is woken by id alone (an alarm, a wake entry) —\n * celld's own queue cells rely on it. Both directions here: restore it, and record it.\n */\n #nameFromMetadata(state: { id: DurableObjectId }): void {\n if (this.#opts.facet) return;\n const scope = scopeOf(this.cellKey);\n // Reading only: no DDL or write outside a logged transaction (a changeset log replays\n // only what it captured). The name is recorded with the cell's first storage write.\n if (state.id.name !== undefined) return;\n try {\n const r = this.#driver.exec(\"SELECT actor_name FROM _cf_METADATA WHERE scope = ?\", [scope])\n .rows[0];\n if (r?.[0] != null)\n (state as { id: DurableObjectId }).id = new DurableObjectIdClass(\n state.id.toString(),\n String(r[0]),\n );\n } catch {\n // no _cf_METADATA yet\n }\n }\n\n #rescope(scope: string): void {\n for (const table of [\"_cf_KV\", \"_cf_ALARM\", \"_cf_METADATA\"])\n try {\n this.#driver.exec(`UPDATE ${table} SET scope = ? WHERE scope <> ?`, [scope, scope]);\n } catch {\n // table not created yet\n }\n }\n\n // ---- hibernation ---------------------------------------------------------------------\n #active = 0;\n #hibernated = false;\n #pinned = 0;\n /** Time of the last event's completion (the runtime's idle sweep reads it). */\n lastActive = Date.now();\n\n get hibernated(): boolean {\n return this.#hibernated;\n }\n\n /**\n * A 101 response whose server end was accepted with `accept()` (not acceptWebSocket)\n * holds a standard WebSocket: the object cannot hibernate until that socket closes —\n * as on Cloudflare, only the hibernation API lets an object sleep with open sockets.\n */\n #pinIfStandardWebSocket(r: unknown): void {\n const server = (\n r as { webSocket?: { peer?: { accepted: boolean; hibernatable: boolean } & EventTarget } }\n )?.webSocket?.peer;\n if (!server || server.hibernatable || !server.accepted) return;\n this.#pinned++;\n server.addEventListener(\"close\", () => this.#pinned--, { once: true });\n }\n\n /**\n * Drops the instance when nothing runs: no event in flight or queued, no open async\n * transaction, no standard WebSocket. Storage, alarms and hibernatable sockets stay; the\n * next event constructs the class again. Returns whether it hibernated.\n */\n hibernate(): boolean {\n if (\n this.#hibernated ||\n this.broken ||\n this.#active ||\n this.#queue.length ||\n this.#sql.held ||\n this.#pinned\n )\n return false;\n if (!this.#gate.isOpen) return false;\n this.#sql.commit();\n this.#instance = undefined;\n this.#hibernated = true;\n return true;\n }\n #dbClosed = false;\n /**\n * Closes the database of a hibernated cell (the cell lease stays); the next event reopens it.\n * A cell with changes its backup has not taken yet stays open. Returns whether it closed.\n */\n closeDatabase(): boolean {\n if (!this.#hibernated || this.#dbClosed || this.#queue.length || !this.#gate.isOpen)\n return false;\n if (this.#backup && (this.#saving || this.#seq !== this.#backedUpSeq)) return false;\n this.#db.close();\n this.#dbClosed = true;\n return true;\n }\n /** Replaces the instance with a fresh one on the SAME database (facet abort/delete). */\n restart(): void {\n if (this.#dbClosed) return; // the next event reopens it with a fresh instance\n this.#construct?.();\n }\n}\n\n/**\n * `ctx.facets` (celld docs/services/durable-object-facets.md): named child objects with a\n * SQLite database of their own (`<cellKey>/facets/<name>`), started on first call from a\n * class (or class handle) returned by the callback; the name alone selects the database.\n */\ninterface FacetTarget {\n call(method: string, args: unknown[]): Promise<unknown>;\n fetch(req: Request): Promise<Response>;\n restart(): void | Promise<void>;\n delete(): Promise<void>;\n}\n\nfunction createFacets(\n parent: { id: DurableObjectId; env: unknown; cellKey: string; epoch?: () => number | undefined },\n spawn: (\n name: string,\n cls: DurableObjectClass,\n env: unknown,\n id: DurableObjectId,\n props?: unknown,\n ) => ObjectHost,\n) {\n const running = new Map<string, Promise<FacetTarget>>();\n // abort() stops the stubs handed out so far (their calls throw the reason); a later\n // get() starts the facet again on the same database — as celld does.\n const generation = new Map<string, { n: number; reason?: unknown }>();\n const local = (h: ObjectHost): FacetTarget => ({\n call: (method, args) =>\n h.deliver((obj) => {\n const fn = obj[method];\n if (typeof fn !== \"function\") throw new TypeError(`${method} is not a function`);\n return fn.apply(obj, args);\n }),\n fetch: (req) => h.deliver((obj) => obj.fetch(closingWith(req, h.closing))),\n restart: () => h.restart(),\n delete: async () => {\n await h.deliver((_o, state) => state.storage.deleteAll());\n h.restart();\n },\n });\n /** A class of isolated loaded code: the facet's instance and SQLite live in the isolate. */\n const isolated = (iso: IsolatedClass, cellKey: string, idName?: string): FacetTarget => {\n const attached = iso.attach?.(cellKey, parent.epoch?.(), idName);\n const ready = async () => attached;\n return {\n call: async (method, args) => (await ready(), iso.call(cellKey, method, args)),\n fetch: async (req) => (await ready(), iso.fetch(cellKey, req)),\n restart: async () => (await ready(), iso.restart(cellKey)),\n delete: async () => (await ready(), iso.delete(cellKey)),\n };\n };\n\n const targetOf = (name: string, start?: () => unknown): Promise<FacetTarget> => {\n let p = running.get(name);\n if (!p) {\n if (!start) return Promise.reject(new Error(`Facet \"${name}\" is not running`));\n p = (async () => {\n const info = (await start()) as { class: unknown; id?: unknown };\n let cls: DurableObjectClass;\n let env = parent.env;\n let props: unknown;\n if (isClassHandle(info.class)) {\n const r = await info.class.resolve();\n if (\"isolated\" in r)\n return isolated(\n r.isolated,\n `${parent.cellKey}/facets/${facetSegment(name)}`,\n // The facet's own `ctx.id` (partyserver's `this.name` reads its name).\n info.id instanceof DurableObjectIdClass ? info.id.name : undefined,\n );\n ({ cls, env, props } = r);\n } else cls = info.class as DurableObjectClass;\n const id = info.id instanceof DurableObjectIdClass ? info.id : parent.id;\n return local(spawn(name, cls, env, id, props));\n })();\n p.catch(() => running.delete(name));\n running.set(name, p);\n }\n return p;\n };\n return {\n get(name: string, start: () => unknown) {\n if (new TextEncoder().encode(name).byteLength > 256)\n throw new Error(\"A facet name has a limit of 256 bytes\");\n const gen = generation.get(name)?.n ?? 0;\n const live = () => {\n const g = generation.get(name);\n if (g && g.n !== gen) throw g.reason;\n };\n return asyncStub(\n async (method, args) => (live(), await targetOf(name, start)).call(method, args),\n async (req) => (live(), await targetOf(name, start)).fetch(req),\n );\n },\n abort(name: string, reason?: unknown) {\n const n = (generation.get(name)?.n ?? 0) + 1;\n generation.set(name, { n, reason: reason ?? new Error(`Facet \"${name}\" was aborted`) });\n // The database stays: the next call on a new stub gets a fresh instance over it.\n void running.get(name)?.then((t) => t.restart());\n },\n async delete(name: string) {\n const p = running.get(name);\n generation.set(name, {\n n: (generation.get(name)?.n ?? 0) + 1,\n reason: new Error(`Facet \"${name}\" was deleted`),\n });\n if (p) await (await p).delete();\n },\n };\n}\n\n/** The cell's lease is held by another owner (route the request there, or retry later). */\nexport class CellOwnedElsewhereError extends Error {\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} is owned by another node`);\n this.name = \"CellOwnedElsewhereError\";\n }\n}\n\n/** celld's path segment for a facet name: the first 16 bytes of SHA-256(name), hex. */\nexport function facetSegment(name: string): string {\n return bytesToHex(sha256(new TextEncoder().encode(name)).subarray(0, 16));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"object-host.js","sourceRoot":"","sources":["../../src/core/object-host.ts"],"names":[],"mappings":"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","sourcesContent":["import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex } from \"@noble/hashes/utils.js\";\nimport type {\n BackupInfo,\n CellBackup,\n CellDurability,\n Lease,\n OpenCellSql,\n SyncSqlDriver,\n ValueCodec,\n} from \"../ports.js\";\nimport type { AsyncRoot } from \"./async-context.js\";\nimport { CELLD_SCHEMA, LOG_SEQ_READ, LOG_SEQ_WRITE, LOG_TABLE, scopeOf } from \"./celld-schema.js\";\nimport { InputGate, OutputGate } from \"./gates.js\";\nimport {\n asyncStub,\n type DurableObjectClass,\n type IsolatedClass,\n isClassHandle,\n} from \"./handles.js\";\nimport { type DurableObjectId, DurableObjectId as DurableObjectIdClass } from \"./id.js\";\nimport { SqlStorage } from \"./sql-storage.js\";\nimport { DurableObjectState } from \"./state.js\";\nimport { DurableObjectStorage, SyncKvStorage } from \"./storage.js\";\n\n/**\n * The request as the object sees it: its signal also aborts when the host closes (the runtime\n * shuts down), as on Cloudflare when the client goes away; a long poll or an SSE stream that\n * waits on it then ends instead of running on into a closed database.\n *\n * The request is not copied: its `signal` becomes a getter that builds the merged signal the\n * first time it is read. Copying a Request and merging two signals cost about 7 µs a request, as\n * much as a small handler's whole turn, and most handlers never read the signal. The request is\n * the caller's own object (`runtime.fetch`) or a stub's fresh copy (a Durable Object's `fetch`);\n * `cf` and the upgrade's `headers` that cellb sets on it stay as they are. A copy the handler\n * makes itself (`new Request(req)`) takes the request's own signal, without the host's.\n */\nexport function closingWith(req: Request, closing: AbortSignal): Request {\n if (closing.aborted) return req;\n const own = signalOf(req);\n let merged: AbortSignal | undefined;\n try {\n Object.defineProperty(req, \"signal\", {\n configurable: true,\n enumerable: false,\n get: () => {\n if (!merged) {\n const before = own();\n merged = before ? AbortSignal.any([before, closing]) : closing;\n }\n return merged;\n },\n });\n return req;\n } catch {\n // A request whose `signal` cannot be redefined: a copy with the merged signal, as before.\n const r = new Request(req, { signal: AbortSignal.any([req.signal, closing]) });\n for (const k of [\"cf\", \"headers\"]) {\n const d = Object.getOwnPropertyDescriptor(req, k);\n if (d) Object.defineProperty(r, k, d);\n }\n return r;\n }\n}\n\n/** Reads `req.signal` as it is now: a getter set by an earlier `closingWith`, or the Request's own. */\nfunction signalOf(req: Request): () => AbortSignal | undefined {\n for (let o: object | null = req; o; o = Object.getPrototypeOf(o)) {\n const d = Object.getOwnPropertyDescriptor(o, \"signal\");\n if (d) return d.get ? () => d.get?.call(req) : () => d.value;\n }\n return () => undefined;\n}\n\n/** The object's host was closed for good: its storage and events fail with this. */\nexport class ObjectClosedError extends Error {\n override name = \"ObjectClosedError\";\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} was closed (its runtime shut down, or it moved or was reset)`);\n }\n}\n\nexport class BrokenObjectError extends Error {\n constructor(cause: unknown, reason = \"its storage failed to commit durably\") {\n const detail = cause instanceof Error ? `: ${cause.message}` : \"\";\n super(`Durable Object reset because ${reason}${detail}`, { cause });\n this.name = \"BrokenObjectError\";\n }\n}\n\n/**\n * One live instance of one Durable Object: its SQLite, gates and dispatcher.\n * Everything that reaches the object (fetch, RPC, later alarms/WebSockets)\n * goes through `deliver()`.\n */\nexport class ObjectHost {\n readonly cellKey: string;\n readonly #gate = new InputGate();\n readonly #out = new OutputGate();\n /** The open database; `#driver` follows it, so it can be closed while idle and reopened. */\n #db!: SyncSqlDriver;\n readonly #driver: SyncSqlDriver = new Proxy({} as SyncSqlDriver, {\n get: (_t, k) => {\n // Closed for good (its runtime or shard shut down): code still running in the object\n // learns why, instead of SQLite's \"DB has been closed\".\n if (this.#closed && k !== \"close\")\n return () => {\n throw new ObjectClosedError(this.cellKey);\n };\n const v = (this.#db as unknown as Record<PropertyKey, unknown>)[k];\n return typeof v === \"function\" ? v.bind(this.#db) : v;\n },\n });\n readonly #sql: SqlStorage;\n #instance: any;\n readonly #backup?: CellBackup;\n #backedUpSeq = 0;\n #saving: Promise<void> | undefined;\n readonly state: DurableObjectState;\n #seq = 0;\n broken = false;\n #brokenCause: unknown;\n\n /** blockConcurrencyWhile() rejected (CF: the object is reset; queued events fail). */\n #breakOn(e: unknown): void {\n this.broken = true;\n this.#brokenCause = e;\n }\n\n constructor(opts: {\n cellKey: string;\n id: DurableObjectId;\n cls: DurableObjectClass;\n env: unknown;\n openSql: OpenCellSql;\n durability: CellDurability;\n codec: ValueCodec;\n waitUntil: (p: Promise<unknown>) => void;\n backup?: CellBackup;\n /** The stored alarm changed (null = cleared). */\n onAlarmChange?: (at: number | null) => void;\n /** `ctx.exports` (loopback handles of the Worker's exports). */\n exports?: Record<string, unknown>;\n /** `ctx.props` of a facet started from a class handle with `{ props }`. */\n props?: unknown;\n /** SQLite extensions to load into every cell database (e.g. \"sqlite_vec\"). */\n sqlExtensions?: string[];\n /** storage.deleteAll() keeps the alarm (`delete_all_preserves_alarm`). */\n deleteAllPreservesAlarm?: boolean;\n /**\n * Ownership: acquire the cell's lease before restoring it. No lease → the cell is owned\n * elsewhere (the host refuses events). The lease epoch fences the cell's log segments;\n * losing the lease breaks the host so it stops serving.\n */\n /** Owner epoch when no lease is taken (facets inherit their root's). */\n epoch?: number;\n /** A facet: on open its rows move to this run's scope, as celld does. */\n facet?: boolean;\n acquire?: Lease[\"tryAcquire\"];\n /** The async context events start in (`asyncRoot()`): not the caller's, as on Cloudflare. */\n asyncRoot?: AsyncRoot;\n }) {\n this.#backup = opts.backup;\n this.cellKey = opts.cellKey;\n this.#epoch = opts.epoch;\n this.#opts = opts;\n this.#open = () => {\n this.#db = opts.openSql(opts.cellKey);\n for (const ext of opts.sqlExtensions ?? []) this.#db.loadExtension(ext);\n };\n this.#open();\n this.#sql = new SqlStorage(\n this.#driver,\n (changes) => {\n if (changes && this.#epoch !== undefined) changes.epoch = this.#epoch;\n // Page-level logs (LTX): the changed pages straight from the page hook when the driver\n // has one; the image only on demand (a generation's first snapshot, or no hook).\n const d = this.#driver;\n const seq = ++this.#seq;\n const pages = opts.durability.capturePages ? d.takeDirtyPages() : undefined;\n const snap = () => d.pageImage?.() ?? d.image?.();\n // The log runs later, after the next event may have opened its transaction, and an\n // image cannot be taken inside one (VACUUM INTO). When the log will surely need it\n // (no page hook) or likely does (this host's first commit), take it now.\n const image = opts.durability.capturePages\n ? !pages || seq === 1\n ? snap()\n : snap\n : undefined;\n const durable = opts.durability.committed(this.cellKey, {\n seq,\n changes,\n image,\n pages,\n epoch: this.#epoch,\n });\n const wake = this.#wakeAfterCommit();\n return this.#out.track(wake ? durable.then(wake) : durable);\n },\n { capture: !!opts.durability.captureChanges },\n );\n // The cell's scope in celld's tables (\"Class:idhex\"), so its database is celld's format.\n const kv = new SyncKvStorage(this.#sql, opts.codec, scopeOf(opts.cellKey));\n if (!opts.facet) kv.actorName = opts.id.name;\n const storage = new DurableObjectStorage(this.#sql, kv, this.#gate, () => this.#barrier());\n if (opts.onAlarmChange) storage.onAlarmChange = opts.onAlarmChange;\n storage.deleteAllPreservesAlarm = !!opts.deleteAllPreservesAlarm;\n const state = new DurableObjectState(opts.id, storage, this.#gate, opts.waitUntil, (e) =>\n this.#breakOn(e),\n );\n this.state = state;\n state.attachDispatcher((fn) => this.deliver(fn));\n // ctx.abort(reason) (workerd, celld): the object resets — a fresh instance on the same\n // database serves the next event; the calling event fails with the reason. Writes the event\n // already made still commit (celld: celld's workflow cell aborts after its delete commit).\n (state as unknown as { abort(reason?: unknown): never }).abort = (reason?: unknown): never => {\n queueMicrotask(() => this.restart());\n throw reason ?? new Error(\"Durable Object reset because its code calls abort()\");\n };\n state.exports = opts.exports ?? {};\n state.props = opts.props;\n state.facets = createFacets(\n { ...opts, epoch: () => this.#epoch },\n (name, cls, env, id, props) => {\n const facet = new ObjectHost({\n ...opts,\n // celld's facet stream: <parent>/facets/<SHA-256(name)[0..16] hex> (engine_api.rs)\n cellKey: `${opts.cellKey}/facets/${facetSegment(name)}`,\n id,\n cls,\n env,\n props,\n onAlarmChange: undefined,\n // A facet is part of its root's cell: no lease of its own, the root's epoch.\n acquire: undefined,\n epoch: this.#epoch,\n facet: true,\n });\n this.#facets.add(facet); // closed with its root\n return facet;\n },\n );\n const root = opts.asyncRoot ?? ((fn) => fn());\n this.#root = root;\n const construct = () => root(() => (this.#instance = new opts.cls(state, opts.env)));\n this.#construct = construct;\n const load = opts.backup?.load;\n const replay = opts.backup?.replay;\n const acquire = opts.acquire;\n if (!load && !replay && !acquire) {\n this.#nameFromMetadata(state);\n construct();\n return;\n }\n // Restore-on-open: events queue behind the closed gate until the image is in.\n void this.#gate\n .runClosed(async () => {\n if (acquire) {\n const lease = await acquire(this.cellKey);\n if (!lease) throw new CellOwnedElsewhereError(this.cellKey);\n this.#epoch = lease.epoch;\n this.#release = lease.release;\n lease.lost.addEventListener(\n \"abort\",\n () => this.#breakOn(new Error(`lease of ${this.cellKey} lost`)),\n {\n once: true,\n },\n );\n }\n // Under a lease (the cell's own, or its root's for a facet) the bucket is the cell's\n // truth: a local file kept from an earlier ownership is older than what other owners\n // wrote since, and may hold commits that never became durable.\n await this.#catchUp(this.#epoch !== undefined);\n if (opts.facet) this.#rescope(scopeOf(opts.cellKey));\n else {\n this.#initWake();\n this.#scheduleRestoredAlarm(opts.onAlarmChange);\n }\n this.#nameFromMetadata(state);\n construct();\n })\n .catch((e) => this.#breakOn(e));\n }\n\n /**\n * Takes an image if the cell changed since the last successful save and hands\n * it to `backup.save`. Taken synchronously between events → a consistent image.\n * Skipped while an async transaction() holds the database or a save is running.\n */\n backupIfDirty(reason: BackupInfo[\"reason\"], now: number): Promise<void> {\n const b = this.#backup;\n if (!b || this.broken || this.#saving || this.#seq === this.#backedUpSeq)\n return this.#saving ?? Promise.resolve();\n if (!this.#driver.image)\n return Promise.reject(new Error(\"SyncSqlDriver has no image(): cannot back up\"));\n if (this.#sql.held) return Promise.resolve(); // mid-transaction: next round\n this.#sql.commit();\n const seq = this.#seq;\n let logSeq = 0;\n try {\n logSeq = Number(this.#driver.exec(LOG_SEQ_READ, []).rows[0]?.[0] ?? 0);\n } catch {\n // no _cf_LOG yet\n }\n const image = this.#driver.image();\n this.#saving = b\n .save(this.cellKey, image, { seq, takenAt: now, reason, logSeq })\n .then(\n () => {\n this.#backedUpSeq = Math.max(this.#backedUpSeq, seq);\n },\n (e) => b.onError?.(this.cellKey, e),\n )\n .finally(() => (this.#saving = undefined));\n return this.#saving;\n }\n\n /**\n * Input gate → handler → commit → output gate (durability) → result.\n *\n * Events are queued and STARTED synchronously by a pump only while the gate\n * is open: the first storage op of a handler closes the gate before the\n * next event can start (checking the gate in an `await` continuation is too\n * late — every queued continuation would see it open).\n */\n deliver<T>(fn: (instance: any, state: DurableObjectState) => T | Promise<T>): Promise<T> {\n if (this.#closed) return Promise.reject(new ObjectClosedError(this.cellKey));\n if (this.broken) return Promise.reject(new BrokenObjectError(undefined));\n return new Promise<T>((resolve, reject) => {\n this.#queue.push(() => {\n if (this.#closed) return reject(new ObjectClosedError(this.cellKey));\n if (this.broken)\n return reject(new BrokenObjectError(this.#brokenCause, \"its initialization failed\"));\n let started: Promise<T>;\n this.#active++;\n try {\n started = Promise.resolve(\n this.#root(() => this.state.storage.runEvent(() => fn(this.#instance, this.state))),\n );\n } catch (e) {\n started = Promise.reject(e);\n }\n const done = () => {\n this.#active--;\n this.lastActive = Date.now();\n if (!this.#active && !this.#queue.length) this.#notifyIdle();\n };\n started.then(\n (r) => {\n this.#pinIfStandardWebSocket(r);\n this.#barrier().then(\n () => (done(), resolve(r)),\n (e) => (done(), reject(e)),\n );\n },\n (e) =>\n this.#barrier().then(\n () => (done(), reject(e)),\n (e2) => (done(), reject(e2)),\n ),\n );\n });\n this.#pump();\n });\n }\n\n #queue: (() => void)[] = [];\n #pumpWaiting = false;\n #pump = (): void => {\n this.#pumpWaiting = false;\n while (this.#queue.length && this.#gate.isOpen) {\n // A database closed while idle: reopen it (and catch up) before anything runs.\n if (this.#dbClosed) {\n this.#dbClosed = false;\n void this.#gate\n .runClosed(async () => {\n this.#open();\n // The lease was held throughout: a kept file is current, an empty one is restored.\n await this.#catchUp(false);\n })\n .catch((e) => this.#breakOn(e));\n continue;\n }\n // Waking from hibernation: the constructor runs again before the event (and may\n // close the gate with blockConcurrencyWhile, which the loop then respects).\n if (this.#hibernated) {\n this.#hibernated = false;\n this.#construct?.();\n continue;\n }\n this.#queue.shift()!();\n }\n if (this.#queue.length && !this.#pumpWaiting) {\n this.#pumpWaiting = true;\n this.#gate.onOpen(this.#pump);\n }\n };\n\n async #barrier(): Promise<void> {\n try {\n this.#sql.commit();\n await this.#out.barrier();\n } catch (e) {\n this.broken = true;\n try {\n this.#sql.rollback();\n } catch {}\n throw new BrokenObjectError(e);\n }\n }\n\n /**\n * Settles once no event is in flight or queued (a response body still streaming is not an\n * event: its handler has returned). The runtime waits for it, within a grace period, before\n * it closes the database on shutdown.\n */\n /** No event in flight or queued. */\n get idle(): boolean {\n return !this.#active && !this.#queue.length;\n }\n settled(): Promise<void> {\n if (!this.#active && !this.#queue.length) return Promise.resolve();\n return new Promise((resolve) => this.#idleWaiters.push(resolve));\n }\n #idleWaiters: (() => void)[] = [];\n #notifyIdle(): void {\n const waiters = this.#idleWaiters;\n this.#idleWaiters = [];\n for (const w of waiters) w();\n }\n\n /** Closed for good: storage calls throw ObjectClosedError. */\n #closed = false;\n readonly #closing = new AbortController();\n /** Aborts when the host is shutting down: the signal of the requests it is handed. */\n get closing(): AbortSignal {\n return this.#closing.signal;\n }\n /** The first step of a shutdown: requests in flight see their signal abort. */\n shutdown(): void {\n if (this.#closing.signal.aborted) return;\n this.#closing.abort(new ObjectClosedError(this.cellKey));\n for (const facet of this.#facets) facet.shutdown();\n }\n\n /** Settles once the cell lease is released (a store closed earlier would keep it held). */\n close(): Promise<void> {\n this.shutdown();\n this.#closed = true;\n for (const facet of this.#facets) void facet.close();\n this.#facets.clear();\n if (!this.#dbClosed) this.#db.close();\n // Events still queued fail (each checks #closed first); nothing more runs here.\n for (const queued of this.#queue.splice(0)) queued();\n this.#notifyIdle();\n // Hand the cell over at once instead of letting the lease expire.\n const released = this.#release?.().catch(() => {});\n this.#release = undefined;\n return released ?? Promise.resolve();\n }\n #release: (() => Promise<void>) | undefined;\n /** The hosts of this cell's facets: their databases close with the root's. */\n readonly #facets = new Set<ObjectHost>();\n\n /**\n * Brings the local database to the storage's state: restores the image, then replays the log.\n * Without `rebuild` only an empty database is restored (the local file is the primary copy);\n * with it, a non-empty one is replaced too — dropped first when the storage has no image.\n */\n async #catchUp(rebuild: boolean): Promise<void> {\n const { load, replay } = this.#backup ?? {};\n if (!load && !replay) return;\n const d = this.#driver;\n const empty = Number(d.exec(\"SELECT count(*) FROM sqlite_master\", []).rows[0][0]) === 0;\n if (!empty && !rebuild) return;\n const image = await load?.(this.cellKey);\n if (image) {\n if (!d.restore) throw new Error(\"SyncSqlDriver has no restore(): cannot restore a backup\");\n d.restore(image);\n } else if (!empty) {\n // Indexes and triggers go with their tables; sqlite_* tables cannot be dropped. Foreign\n // keys are off meanwhile, so a parent table can go before its children.\n const objects = d.exec(\n \"SELECT type, name FROM sqlite_master WHERE type IN ('view', 'table') AND name NOT LIKE 'sqlite_%'\",\n [],\n ).rows;\n const fk = Number(d.exec(\"PRAGMA foreign_keys\", []).rows[0][0]);\n d.exec(\"PRAGMA foreign_keys = OFF\", []);\n try {\n for (const [type, name] of objects)\n d.exec(`DROP ${type} IF EXISTS \"${String(name).replace(/\"/g, '\"\"')}\"`, []);\n } finally {\n d.exec(`PRAGMA foreign_keys = ${fk}`, []);\n }\n }\n // Then every logged transaction the image does not contain, in order.\n if (replay) await this.#replayLog(replay);\n }\n\n /** Applies log segments newer than the database's own log sequence (restore path). */\n async #replayLog(replay: NonNullable<CellBackup[\"replay\"]>): Promise<void> {\n const d = this.#driver;\n d.exec(LOG_TABLE, []);\n const row = d.exec(LOG_SEQ_READ, []).rows[0];\n const after = Number(row?.[0] ?? 0);\n for await (const seg of replay(this.cellKey, after)) {\n if (!d.applyChangeset)\n throw new Error(\"SyncSqlDriver cannot apply changesets: cannot replay a log\");\n d.exec(\"BEGIN\", []);\n try {\n for (const ddl of seg.ddl) d.exec(ddl, []);\n d.applyChangeset(seg.changeset);\n for (const [sql, params] of seg.statements) d.exec(sql, params);\n d.exec(LOG_SEQ_WRITE, [seg.logSeq]);\n d.exec(\"COMMIT\", []);\n } catch (e) {\n d.exec(\"ROLLBACK\", []);\n throw e;\n }\n }\n }\n\n #construct?: () => unknown;\n #root: AsyncRoot = (fn) => fn();\n readonly #open: () => void;\n #epoch: number | undefined;\n\n /**\n * celld gives each run of a facet its own scope and moves the facet database's rows to it\n * on open (storage.rs open_embedded); doing the same here reads a facet database celld\n * wrote, whatever scope it used.\n */\n /**\n * celld's alarm publication identity (storage/wake_record.rs initialize): one `_cf_WAKE`\n * row per cell carrying the writer epoch; triggers bump its sequence on every alarm change.\n */\n #initWake(): void {\n if (!this.#epoch || !this.#opts.durability.publishWake) return;\n const scope = scopeOf(this.cellKey);\n for (const ddl of CELLD_SCHEMA) this.#driver.exec(ddl, []);\n this.#driver.exec(\n `INSERT INTO _cf_WAKE(scope,epoch,sequence,at_ms)\n VALUES(?1,?2,0,(SELECT at_ms FROM _cf_ALARM WHERE scope=?1))\n ON CONFLICT(scope) DO UPDATE SET epoch=excluded.epoch WHERE excluded.epoch>_cf_WAKE.epoch`,\n [scope, this.#epoch.toString(16).padStart(16, \"0\")],\n );\n this.#wakeSeq = this.#wakeRow()?.sequence;\n }\n /**\n * A cell restored on open may carry an alarm armed by its previous owner (another node, or\n * celld). This node owns the cell now, so the alarm is its to fire: hand it to the scheduler,\n * which otherwise only hears of alarms set here (or of a later wake-index poll).\n */\n #scheduleRestoredAlarm(onAlarmChange?: (at: number) => void): void {\n let at: unknown;\n try {\n at = this.#driver.exec(\"SELECT at_ms FROM _cf_ALARM WHERE scope = ?\", [scopeOf(this.cellKey)])\n .rows[0]?.[0];\n } catch {\n return; // no alarm table: the cell never had an alarm\n }\n if (at != null) onAlarmChange?.(Number(at));\n }\n #wakeSeq: number | undefined;\n #wakeRow(): { epoch: number; sequence: number; at: number | null } | undefined {\n try {\n const r = this.#driver.exec(\"SELECT epoch, sequence, at_ms FROM _cf_WAKE WHERE scope = ?\", [\n scopeOf(this.cellKey),\n ]).rows[0];\n return r\n ? {\n epoch: Number.parseInt(String(r[0]), 16),\n sequence: Number(r[1]),\n at: r[2] == null ? null : Number(r[2]),\n }\n : undefined;\n } catch {\n return undefined;\n }\n }\n /**\n * After a commit: if it changed the alarm, a publication to run once the commit is durable\n * (celld publishes after replication).\n */\n #wakeAfterCommit(): (() => Promise<void>) | undefined {\n const publish = this.#opts.durability.publishWake;\n if (!publish || this.#opts.facet || !this.#epoch) return undefined;\n const row = this.#wakeRow();\n if (!row || row.sequence === this.#wakeSeq) return undefined;\n this.#wakeSeq = row.sequence;\n return () => publish(this.cellKey, row);\n }\n readonly #opts: { durability: CellDurability; facet?: boolean };\n\n /**\n * celld records the name an object was addressed by (`_cf_METADATA.actor_name`) and gives it\n * back as `ctx.id.name` when the object is woken by id alone (an alarm, a wake entry) —\n * celld's own queue cells rely on it. Both directions here: restore it, and record it.\n */\n #nameFromMetadata(state: { id: DurableObjectId }): void {\n if (this.#opts.facet) return;\n const scope = scopeOf(this.cellKey);\n // Reading only: no DDL or write outside a logged transaction (a changeset log replays\n // only what it captured). The name is recorded with the cell's first storage write.\n if (state.id.name !== undefined) return;\n try {\n const r = this.#driver.exec(\"SELECT actor_name FROM _cf_METADATA WHERE scope = ?\", [scope])\n .rows[0];\n if (r?.[0] != null)\n (state as { id: DurableObjectId }).id = new DurableObjectIdClass(\n state.id.toString(),\n String(r[0]),\n );\n } catch {\n // no _cf_METADATA yet\n }\n }\n\n #rescope(scope: string): void {\n for (const table of [\"_cf_KV\", \"_cf_ALARM\", \"_cf_METADATA\"])\n try {\n this.#driver.exec(`UPDATE ${table} SET scope = ? WHERE scope <> ?`, [scope, scope]);\n } catch {\n // table not created yet\n }\n }\n\n // ---- hibernation ---------------------------------------------------------------------\n #active = 0;\n #hibernated = false;\n #pinned = 0;\n /** Time of the last event's completion (the runtime's idle sweep reads it). */\n lastActive = Date.now();\n\n get hibernated(): boolean {\n return this.#hibernated;\n }\n\n /**\n * A 101 response whose server end was accepted with `accept()` (not acceptWebSocket)\n * holds a standard WebSocket: the object cannot hibernate until that socket closes —\n * as on Cloudflare, only the hibernation API lets an object sleep with open sockets.\n */\n #pinIfStandardWebSocket(r: unknown): void {\n const server = (\n r as { webSocket?: { peer?: { accepted: boolean; hibernatable: boolean } & EventTarget } }\n )?.webSocket?.peer;\n if (!server || server.hibernatable || !server.accepted) return;\n this.#pinned++;\n server.addEventListener(\"close\", () => this.#pinned--, { once: true });\n }\n\n /**\n * Drops the instance when nothing runs: no event in flight or queued, no open async\n * transaction, no standard WebSocket. Storage, alarms and hibernatable sockets stay; the\n * next event constructs the class again. Returns whether it hibernated.\n */\n hibernate(): boolean {\n if (\n this.#hibernated ||\n this.broken ||\n this.#active ||\n this.#queue.length ||\n this.#sql.held ||\n this.#pinned\n )\n return false;\n if (!this.#gate.isOpen) return false;\n this.#sql.commit();\n this.#instance = undefined;\n this.#hibernated = true;\n return true;\n }\n #dbClosed = false;\n /**\n * Closes the database of a hibernated cell (the cell lease stays); the next event reopens it.\n * A cell with changes its backup has not taken yet stays open. Returns whether it closed.\n */\n closeDatabase(): boolean {\n if (!this.#hibernated || this.#dbClosed || this.#queue.length || !this.#gate.isOpen)\n return false;\n if (this.#backup && (this.#saving || this.#seq !== this.#backedUpSeq)) return false;\n this.#db.close();\n this.#dbClosed = true;\n return true;\n }\n /** Replaces the instance with a fresh one on the SAME database (facet abort/delete). */\n restart(): void {\n if (this.#dbClosed) return; // the next event reopens it with a fresh instance\n this.#construct?.();\n }\n}\n\n/**\n * `ctx.facets` (celld docs/services/durable-object-facets.md): named child objects with a\n * SQLite database of their own (`<cellKey>/facets/<name>`), started on first call from a\n * class (or class handle) returned by the callback; the name alone selects the database.\n */\ninterface FacetTarget {\n call(method: string, args: unknown[]): Promise<unknown>;\n fetch(req: Request): Promise<Response>;\n restart(): void | Promise<void>;\n delete(): Promise<void>;\n}\n\nfunction createFacets(\n parent: { id: DurableObjectId; env: unknown; cellKey: string; epoch?: () => number | undefined },\n spawn: (\n name: string,\n cls: DurableObjectClass,\n env: unknown,\n id: DurableObjectId,\n props?: unknown,\n ) => ObjectHost,\n) {\n const running = new Map<string, Promise<FacetTarget>>();\n // abort() stops the stubs handed out so far (their calls throw the reason); a later\n // get() starts the facet again on the same database — as celld does.\n const generation = new Map<string, { n: number; reason?: unknown }>();\n const local = (h: ObjectHost): FacetTarget => ({\n call: (method, args) =>\n h.deliver((obj) => {\n const fn = obj[method];\n if (typeof fn !== \"function\") throw new TypeError(`${method} is not a function`);\n return fn.apply(obj, args);\n }),\n fetch: (req) => h.deliver((obj) => obj.fetch(closingWith(req, h.closing))),\n restart: () => h.restart(),\n delete: async () => {\n await h.deliver((_o, state) => state.storage.deleteAll());\n h.restart();\n },\n });\n /** A class of isolated loaded code: the facet's instance and SQLite live in the isolate. */\n const isolated = (iso: IsolatedClass, cellKey: string, idName?: string): FacetTarget => {\n const attached = iso.attach?.(cellKey, parent.epoch?.(), idName);\n const ready = async () => attached;\n return {\n call: async (method, args) => (await ready(), iso.call(cellKey, method, args)),\n fetch: async (req) => (await ready(), iso.fetch(cellKey, req)),\n restart: async () => (await ready(), iso.restart(cellKey)),\n delete: async () => (await ready(), iso.delete(cellKey)),\n };\n };\n\n const targetOf = (name: string, start?: () => unknown): Promise<FacetTarget> => {\n let p = running.get(name);\n if (!p) {\n if (!start) return Promise.reject(new Error(`Facet \"${name}\" is not running`));\n p = (async () => {\n const info = (await start()) as { class: unknown; id?: unknown };\n let cls: DurableObjectClass;\n let env = parent.env;\n let props: unknown;\n if (isClassHandle(info.class)) {\n const r = await info.class.resolve();\n if (\"isolated\" in r)\n return isolated(\n r.isolated,\n `${parent.cellKey}/facets/${facetSegment(name)}`,\n // The facet's own `ctx.id` (partyserver's `this.name` reads its name).\n info.id instanceof DurableObjectIdClass ? info.id.name : undefined,\n );\n ({ cls, env, props } = r);\n } else cls = info.class as DurableObjectClass;\n const id = info.id instanceof DurableObjectIdClass ? info.id : parent.id;\n return local(spawn(name, cls, env, id, props));\n })();\n p.catch(() => running.delete(name));\n running.set(name, p);\n }\n return p;\n };\n return {\n get(name: string, start: () => unknown) {\n if (new TextEncoder().encode(name).byteLength > 256)\n throw new Error(\"A facet name has a limit of 256 bytes\");\n const gen = generation.get(name)?.n ?? 0;\n const live = () => {\n const g = generation.get(name);\n if (g && g.n !== gen) throw g.reason;\n };\n return asyncStub(\n async (method, args) => (live(), await targetOf(name, start)).call(method, args),\n async (req) => (live(), await targetOf(name, start)).fetch(req),\n );\n },\n abort(name: string, reason?: unknown) {\n const n = (generation.get(name)?.n ?? 0) + 1;\n generation.set(name, { n, reason: reason ?? new Error(`Facet \"${name}\" was aborted`) });\n // The database stays: the next call on a new stub gets a fresh instance over it.\n void running.get(name)?.then((t) => t.restart());\n },\n async delete(name: string) {\n const p = running.get(name);\n generation.set(name, {\n n: (generation.get(name)?.n ?? 0) + 1,\n reason: new Error(`Facet \"${name}\" was deleted`),\n });\n if (p) await (await p).delete();\n },\n };\n}\n\n/** The cell's lease is held by another owner (route the request there, or retry later). */\nexport class CellOwnedElsewhereError extends Error {\n constructor(cellKey: string) {\n super(`Durable Object ${cellKey} is owned by another node`);\n this.name = \"CellOwnedElsewhereError\";\n }\n}\n\n/** celld's path segment for a facet name: the first 16 bytes of SHA-256(name), hex. */\nexport function facetSegment(name: string): string {\n return bytesToHex(sha256(new TextEncoder().encode(name)).subarray(0, 16));\n}\n"]}
|
|
@@ -14,6 +14,11 @@ export declare class SqlStorageCursor<T = Record<string, unknown>> implements It
|
|
|
14
14
|
}
|
|
15
15
|
export declare class SqlStorage {
|
|
16
16
|
#private;
|
|
17
|
+
/**
|
|
18
|
+
* Set by `ctx.storage`: true when called from another event while an async `transaction()` is
|
|
19
|
+
* open, where async context tells them apart.
|
|
20
|
+
*/
|
|
21
|
+
outsideTransaction?: () => boolean;
|
|
17
22
|
constructor(driver: SyncSqlDriver, onCommit: (changes?: CommitChanges) => void, opts?: {
|
|
18
23
|
capture?: boolean;
|
|
19
24
|
});
|
|
@@ -35,6 +40,13 @@ export declare class SqlStorage {
|
|
|
35
40
|
statementCount: number;
|
|
36
41
|
rowsWritten: number;
|
|
37
42
|
};
|
|
43
|
+
/**
|
|
44
|
+
* A synchronous write made from another event while an async `transaction()` is open lands in
|
|
45
|
+
* that transaction's savepoint, and is undone if it rolls back. On workerd that event would not
|
|
46
|
+
* run until the transaction ends; a synchronous call cannot wait, so this warns, once per
|
|
47
|
+
* object. (Async storage calls wait for the transaction instead.)
|
|
48
|
+
*/
|
|
49
|
+
checkWrite(): void;
|
|
38
50
|
get databaseSize(): number;
|
|
39
51
|
/** Unguarded path for the runtime's own tables (_cf_KV, _cf_METADATA). */
|
|
40
52
|
internalExec(query: string, bindings?: unknown[]): SqlResult;
|