@statewalker/cellb 0.8.1 → 0.8.3
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 -2
- package/dist/adapters/wasm-sqlite.d.ts +2 -0
- package/dist/adapters/wasm-sqlite.js +89 -31
- package/dist/adapters/wasm-sqlite.js.map +1 -1
- package/dist/project/node-project.js +4 -8
- package/dist/project/node-project.js.map +1 -1
- package/dist/project/site-compiler.js +23 -2
- package/dist/project/site-compiler.js.map +1 -1
- package/dist/project/wrangler.d.ts +4 -4
- package/dist/project/wrangler.js +9 -6
- package/dist/project/wrangler.js.map +1 -1
- package/package.json +20 -20
package/README.md
CHANGED
|
@@ -308,8 +308,10 @@ docs/ topic pages
|
|
|
308
308
|
the server end acknowledges the bytes of each message it dispatched and a client's
|
|
309
309
|
`bufferedAmount` counts the bytes not acknowledged yet: the WHATWG signal a sender throttles on.
|
|
310
310
|
workerd's server-side WebSocket has no `bufferedAmount`, and cellb's has none.
|
|
311
|
-
- **Each loaded Worker gets a realm of its own**, a thread
|
|
312
|
-
|
|
311
|
+
- **Each loaded Worker gets a realm of its own**, a worker thread in Node, or in a browser a
|
|
312
|
+
Dedicated Worker when `isolateScript` is set (the browser `loadProject` sets it;
|
|
313
|
+
`browserProjectRuntime` and the shard functions do not): as in celld's isolates, loaded code must
|
|
314
|
+
not see the host's globals or env.
|
|
313
315
|
- **`idFromName` is synchronous**, with `@noble/hashes` instead of `crypto.subtle`, which is
|
|
314
316
|
asynchronous only; Worker code relies on getting the id at once.
|
|
315
317
|
- **Ownership depends on the deployment**: a Web Lock per shard in an origin, celld's ownership
|
|
@@ -84,8 +84,10 @@ export declare function sahpoolOpener(sqlite3: {
|
|
|
84
84
|
}): Promise<{
|
|
85
85
|
OpfsSAHPoolDb: new (path: string) => Oo1Db;
|
|
86
86
|
reserveMinimumCapacity(n: number): Promise<number>;
|
|
87
|
+
addCapacity?(n: number): Promise<number>;
|
|
87
88
|
getCapacity(): number;
|
|
88
89
|
getFileCount(): number;
|
|
90
|
+
getFileNames?(): string[];
|
|
89
91
|
pauseVfs?(): unknown;
|
|
90
92
|
isPaused?(): boolean;
|
|
91
93
|
unpauseVfs?(): Promise<unknown>;
|
|
@@ -209,41 +209,80 @@ export async function sahpoolOpener(sqlite3, opts = {}) {
|
|
|
209
209
|
if (pool.isPaused?.())
|
|
210
210
|
await pool.unpauseVfs?.();
|
|
211
211
|
// A full pool fails the open (`SAH pool is full`), and opening is synchronous while growing
|
|
212
|
-
// the pool is not.
|
|
213
|
-
//
|
|
214
|
-
//
|
|
212
|
+
// the pool is not. Each new slot is an OPFS file with a sync access handle, made one at a time,
|
|
213
|
+
// and once the worker is busy each one takes seconds (about 5 s with 32 Flue conversations in
|
|
214
|
+
// one worker), so the pool grows ahead of need, in small steps:
|
|
215
|
+
// - a cell about to open reserves room first (`room`, awaited by the runtime before the cell's
|
|
216
|
+
// first event): its database, its journal and a spare, and it waits until what was needed
|
|
217
|
+
// when it asked fits, one step of 16 slots at a time (not a doubling, nor later reservations);
|
|
218
|
+
// - an open cell counts its journal until it has one (SQLite makes it at the cell's first
|
|
219
|
+
// write), so the pool grows while it still has room, not once the journals fill it;
|
|
220
|
+
// - at each open (failed ones too: a cell can reopen without `room`), the pool grows in the
|
|
221
|
+
// background until two thirds of it are free: an unused slot costs a small file, a missing
|
|
222
|
+
// one a wait of seconds per slot, so it grows while the worker is still quiet.
|
|
215
223
|
const SLOTS_PER_CELL = 3; // the database, its journal, and one spare
|
|
224
|
+
const STEP = 16; // slots per growth step, made in parallel
|
|
225
|
+
const AHEAD = 3; // the pool's size, in multiples of what it needs, kept by the background growth
|
|
216
226
|
const reserved = new Set();
|
|
227
|
+
const opened = new Map(); // the open cells' databases
|
|
217
228
|
let growing;
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
229
|
+
/**
|
|
230
|
+
* One growth step toward `target` (one at a time: a second caller joins it). SQLite makes a
|
|
231
|
+
* pool's new slots one after another, two awaited OPFS calls each, and in a busy worker each
|
|
232
|
+
* await waits seconds for the event loop: the step asks for its slots in parallel instead,
|
|
233
|
+
* one `addCapacity(1)` each, so it costs about one slot's wait.
|
|
234
|
+
*/
|
|
235
|
+
const step = (target) => {
|
|
236
|
+
const n = Math.min(target, pool.getCapacity() + STEP) - pool.getCapacity();
|
|
237
|
+
growing ??= (pool.addCapacity && n > 0
|
|
238
|
+
? Promise.all(Array.from({ length: n }, () => pool.addCapacity?.(1)))
|
|
239
|
+
: pool.reserveMinimumCapacity(pool.getCapacity() + Math.max(n, 0)))
|
|
221
240
|
.then(() => { })
|
|
222
241
|
.finally(() => {
|
|
223
242
|
growing = undefined;
|
|
224
243
|
});
|
|
225
244
|
return growing;
|
|
226
245
|
};
|
|
227
|
-
const needed = () =>
|
|
246
|
+
const needed = () => {
|
|
247
|
+
// Journals not made yet. Without the pool's file names (older SQLite WASM builds) none
|
|
248
|
+
// is counted, as before: the files that exist are.
|
|
249
|
+
let journals = 0;
|
|
250
|
+
if (pool.getFileNames) {
|
|
251
|
+
const files = new Set(pool.getFileNames());
|
|
252
|
+
for (const { path } of opened.values())
|
|
253
|
+
if (!files.has(`${path}-journal`))
|
|
254
|
+
journals++;
|
|
255
|
+
}
|
|
256
|
+
return pool.getFileCount() + journals + SLOTS_PER_CELL * reserved.size;
|
|
257
|
+
};
|
|
258
|
+
/** Grows until `target()` fits; stops when a step of its own adds nothing (the open says why). */
|
|
259
|
+
const growTo = async (target) => {
|
|
260
|
+
while (target() > pool.getCapacity()) {
|
|
261
|
+
// A step already under way may have added its slots and not ended yet: joining it says
|
|
262
|
+
// nothing about whether the pool can grow.
|
|
263
|
+
const joined = growing !== undefined;
|
|
264
|
+
const before = pool.getCapacity();
|
|
265
|
+
await step(target());
|
|
266
|
+
if (!joined && pool.getCapacity() <= before)
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
};
|
|
228
270
|
const room = (cellKey) => {
|
|
229
271
|
reserved.add(cellKey);
|
|
230
|
-
|
|
272
|
+
const target = needed();
|
|
273
|
+
if (target <= pool.getCapacity())
|
|
231
274
|
return undefined;
|
|
232
|
-
|
|
233
|
-
const fit = async () => {
|
|
234
|
-
while (needed() > pool.getCapacity()) {
|
|
235
|
-
const before = pool.getCapacity();
|
|
236
|
-
await grow(needed());
|
|
237
|
-
if (pool.getCapacity() <= before)
|
|
238
|
-
return; // it did not grow: the open will say why
|
|
239
|
-
}
|
|
240
|
-
};
|
|
241
|
-
return fit();
|
|
275
|
+
return growTo(() => target);
|
|
242
276
|
};
|
|
277
|
+
let ahead;
|
|
243
278
|
const keepRoom = () => {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
279
|
+
if (ahead || pool.getCapacity() >= AHEAD * needed())
|
|
280
|
+
return;
|
|
281
|
+
ahead = growTo(() => AHEAD * needed())
|
|
282
|
+
.catch(() => { })
|
|
283
|
+
.finally(() => {
|
|
284
|
+
ahead = undefined;
|
|
285
|
+
});
|
|
247
286
|
};
|
|
248
287
|
// The rollback journal stays in the pool between transactions (PERSIST): DELETE gives its pool
|
|
249
288
|
// slot back and takes it again on every commit, which costs a header write each time. The
|
|
@@ -257,16 +296,35 @@ export async function sahpoolOpener(sqlite3, opts = {}) {
|
|
|
257
296
|
const open = (cellKey) => {
|
|
258
297
|
const path = `/${cellKey.replace(/[^\w.-]/g, "_")}.sqlite`;
|
|
259
298
|
reserved.delete(cellKey);
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
299
|
+
// Counted from now on, with its journal until it has one; no longer once it is closed.
|
|
300
|
+
const entry = { path };
|
|
301
|
+
opened.set(cellKey, entry);
|
|
302
|
+
keepRoom();
|
|
303
|
+
let driver;
|
|
304
|
+
try {
|
|
305
|
+
driver = new WasmSqliteDriver(openDb(path), {
|
|
306
|
+
image: (db) => sqlite3.capi.sqlite3_js_db_export(db),
|
|
307
|
+
// Replace the file inside the pool, then reopen it.
|
|
308
|
+
restore(db, image) {
|
|
309
|
+
db.close();
|
|
310
|
+
pool.importDb(path, image);
|
|
311
|
+
return openDb(path);
|
|
312
|
+
},
|
|
313
|
+
}, sqlite3);
|
|
314
|
+
}
|
|
315
|
+
catch (err) {
|
|
316
|
+
if (opened.get(cellKey) === entry)
|
|
317
|
+
opened.delete(cellKey);
|
|
318
|
+
throw err;
|
|
319
|
+
}
|
|
320
|
+
const close = driver.close.bind(driver);
|
|
321
|
+
driver.close = () => {
|
|
322
|
+
// Only this driver's entry: the cell may have been opened again since.
|
|
323
|
+
if (opened.get(cellKey) === entry)
|
|
324
|
+
opened.delete(cellKey);
|
|
325
|
+
close();
|
|
326
|
+
};
|
|
327
|
+
return driver;
|
|
270
328
|
};
|
|
271
329
|
return Object.assign(open, {
|
|
272
330
|
room,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-sqlite.js","sourceRoot":"","sources":["../../src/adapters/wasm-sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import { splitSqlStatements } from \"../core/sql-split.js\";\nimport type { OpenCellSql, SqlResult, SyncSqlDriver } from \"../ports.js\";\nimport { type DirtyPages, installPageHook } from \"./wasm-page-hook.js\";\nimport { type WasmSqlite3, wasmSessionCapture } from \"./wasm-session.js\";\n\n/** Minimal slice of the @sqlite.org/sqlite-wasm `oo1.DB` API we rely on. */\nexport interface Oo1Db {\n prepare(sql: string): Oo1Stmt;\n exec(sql: string): unknown;\n changes(): number;\n close(): void;\n}\ninterface Oo1Stmt {\n bind(values: unknown[]): Oo1Stmt;\n getColumnNames(): string[];\n columnCount: number;\n step(): boolean;\n get(target: unknown[]): unknown[];\n finalize(): void;\n}\n\n/**\n * SyncSqlDriver over the official SQLite WASM build (oo1 API). Synchronous,\n * so it satisfies `ctx.storage.sql`. Works in Node (in-memory, for tests) and\n * in browsers; persistence comes from the VFS behind the DB (see sahpoolOpener).\n */\n/** Backup hooks: how to export an image of the DB and how to replace it (returns the reopened DB). */\nexport interface WasmImageHooks {\n image(db: Oo1Db): Uint8Array;\n restore(db: Oo1Db, image: Uint8Array): Oo1Db;\n}\n\nexport class WasmSqliteDriver implements SyncSqlDriver {\n captureStart?: () => void;\n captureTake?: () => Uint8Array;\n captureDiscard?: () => void;\n applyChangeset?: (changeset: Uint8Array) => void;\n captureCoversRowidTables?: boolean;\n #db: Oo1Db;\n readonly #hooks?: WasmImageHooks;\n readonly #sqlite3?: WasmSqlite3;\n readonly #capi?: { sqlite3_get_autocommit(db: number): number };\n #pageHook?: ReturnType<typeof installPageHook>;\n constructor(\n db: Oo1Db,\n hooks?: WasmImageHooks,\n sqlite3?: WasmSqlite3,\n /** SQLite's C API, for `inTransaction()` alone (when `sqlite3` is not given). */\n capi?: { sqlite3_get_autocommit(db: number): number },\n ) {\n this.#db = db;\n this.#hooks = hooks;\n this.#sqlite3 = sqlite3;\n this.#capi = capi ?? sqlite3?.capi;\n if (!this.#capi?.sqlite3_get_autocommit)\n (this as { inTransaction?: unknown }).inTransaction = undefined;\n this.#enableDqs();\n this.#hookPages();\n if (sqlite3?.capi?.sqlite3session_create) {\n // Transaction-log capture (session extension), following the current DB handle.\n Object.assign(\n this,\n wasmSessionCapture(sqlite3, () => (this.#db as unknown as { pointer: number }).pointer),\n );\n }\n if (!hooks) {\n // No image support for this driver: hide the optional port methods.\n (this as { image?: unknown }).image = undefined;\n (this as { restore?: unknown }).restore = undefined;\n }\n }\n image(): Uint8Array {\n return this.#hooks!.image(this.#db);\n }\n\n /**\n * As celld and workerd: a double-quoted name that is no column is a string literal (SQLite's\n * DQS misfeature, off in this build).\n */\n #enableDqs(): void {\n const capi = this.#sqlite3?.capi;\n if (!capi?.sqlite3_db_config) return;\n const db = (this.#db as unknown as { pointer: number }).pointer;\n capi.sqlite3_db_config(db, capi.SQLITE_DBCONFIG_DQS_DML, 1, 0);\n capi.sqlite3_db_config(db, capi.SQLITE_DBCONFIG_DQS_DDL, 1, 0);\n }\n\n /** Installs the page hook on the current main database file (see wasm-page-hook.ts). */\n #hookPages(): void {\n this.#pageHook = undefined;\n if (!this.#sqlite3?.capi?.sqlite3_file_control) return;\n try {\n this.#pageHook = installPageHook(\n this.#sqlite3,\n (this.#db as unknown as { pointer: number }).pointer,\n );\n } catch {\n this.#pageHook = undefined;\n }\n }\n /** Pages written since the previous call — a committed transaction's changed pages. */\n takeDirtyPages(): DirtyPages | undefined {\n if (!this.#pageHook) return undefined;\n const pageSize = Number(this.exec(\"PRAGMA page_size\", []).rows[0][0]);\n const pageCount = Number(this.exec(\"PRAGMA page_count\", []).rows[0][0]);\n return this.#pageHook.take(pageSize, pageCount);\n }\n discardDirtyPages(): void {\n this.#pageHook?.discard();\n }\n /**\n * WASM builds cannot load extensions at run time; an extension must be compiled into the\n * build (e.g. the `sqlite-vec-wasm-demo` package for \"sqlite_vec\"). This only checks it is.\n */\n loadExtension(name: string): void {\n const probe: Record<string, string> = { sqlite_vec: \"SELECT vec_version()\" };\n if (!probe[name]) throw new Error(`Unknown SQLite extension \"${name}\"`);\n try {\n this.exec(probe[name], []);\n } catch {\n throw new Error(`SQLite extension \"${name}\" is not compiled into this SQLite WASM build`);\n }\n }\n restore(image: Uint8Array): void {\n // celld's databases are in WAL mode (header bytes 18–19 = 2); the WASM VFSes (memdb,\n // opfs-sahpool) have no shared memory for WAL and refuse to open such a file. The pages\n // are the same in rollback-journal mode: switch the header to 1 (celld sets WAL again\n // when it opens the database).\n if (image.length > 19 && image[18] === 2 && image[19] === 2) {\n image = image.slice();\n image[18] = 1;\n image[19] = 1;\n }\n this.#db = this.#hooks!.restore(this.#db, image);\n this.#enableDqs();\n this.#hookPages(); // a new database file behind the connection\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 st = this.#db.prepare(sql);\n try {\n if (params.length) st.bind(params.map(toSqlite));\n const columnNames = st.columnCount ? st.getColumnNames() : [];\n const rows: unknown[][] = [];\n while (st.step()) if (columnNames.length) rows.push(st.get([]).map(fromSqlite));\n return { columnNames, rows, rowsWritten: columnNames.length ? 0 : this.#db.changes() };\n } finally {\n st.finalize();\n }\n }\n inTransaction(): boolean {\n const pointer = (this.#db as unknown as { pointer: number }).pointer;\n return this.#capi!.sqlite3_get_autocommit(pointer) === 0;\n }\n databaseSize(): number {\n const pc = this.exec(\"PRAGMA page_count\", []).rows[0][0];\n const ps = this.exec(\"PRAGMA page_size\", []).rows[0][0];\n return Number(pc) * Number(ps);\n }\n close(): void {\n this.#db.close();\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}\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/** In-memory WASM databases (tests, ephemeral cells). `sqlite3` = await sqlite3InitModule(). */\n/** Image hooks for an in-memory DB: `sqlite3_js_db_export` / `sqlite3_deserialize`. */\nexport function memoryImageHooks(sqlite3: any): WasmImageHooks {\n const { capi, wasm } = sqlite3;\n return {\n image: (db) => sqlite3.capi.sqlite3_js_db_export(db),\n restore(db, image) {\n const p = wasm.allocFromTypedArray(image);\n const rc = capi.sqlite3_deserialize(\n (db as any).pointer,\n \"main\",\n p,\n image.byteLength,\n image.byteLength,\n capi.SQLITE_DESERIALIZE_FREEONCLOSE | capi.SQLITE_DESERIALIZE_RESIZEABLE,\n );\n if (rc) throw new Error(`sqlite3_deserialize failed: ${capi.sqlite3_js_rc_str?.(rc) ?? rc}`);\n return db;\n },\n };\n}\n\n/**\n * Sets up a new SQLite WASM connection for a cell. One worker holds many small cells, and SQLite\n * WASM's heap is capped at 2 GiB and never shrinks, so each connection's fixed memory decides how\n * many cells can be open at once:\n * - no lookaside: SQLite's per-connection allocator of small blocks, about 45 KiB each;\n * - 4 KiB pages for a database that is still empty (celld's page size: SQLite's native default;\n * the WASM build's is 8 KiB). The page cache starts with a block of pages, so the page size\n * sets most of a connection's memory. A database that already holds data keeps its page size.\n * Together they bring a connection with one small table from about 258 KiB to about 120 KiB.\n */\nexport function tuneCellConnection(sqlite3: unknown, db: Oo1Db): void {\n const capi = (sqlite3 as { capi?: Record<string, any> }).capi;\n const pointer = (db as unknown as { pointer?: number }).pointer;\n // Before the connection runs any statement: SQLite refuses (SQLITE_BUSY) while lookaside is used.\n if (capi?.sqlite3_db_config && pointer) {\n capi.sqlite3_db_config(pointer, capi.SQLITE_DBCONFIG_LOOKASIDE, 0, 0, 0);\n }\n db.exec(\"PRAGMA page_size=4096\");\n}\n\nlet memdbCounter = 0;\nexport function wasmMemoryOpener(sqlite3: {\n oo1: { DB: new (path: string, mode?: string) => Oo1Db };\n}): OpenCellSql {\n return () => {\n // memdb (not \":memory:\"): an in-memory database that IS a VFS file, so the page hook works.\n const db = new sqlite3.oo1.DB(`file:/cells-mem-${++memdbCounter}?vfs=memdb`, \"c\");\n tuneCellConnection(sqlite3, db);\n return new WasmSqliteDriver(db, memoryImageHooks(sqlite3), sqlite3 as never);\n };\n}\n\n/**\n * Browser persistence: one OPFS \"SyncAccessHandle pool\" database per cell.\n * Must run in a Dedicated Worker; needs neither COOP/COEP nor SharedArrayBuffer.\n * Not runnable in Node (installOpfsSAHPoolVfs is browser-only) — covered by P04's Playwright spec.\n */\nexport async function sahpoolOpener(\n sqlite3: {\n installOpfsSAHPoolVfs(opts: { name?: string; initialCapacity?: number }): Promise<{\n OpfsSAHPoolDb: new (path: string) => Oo1Db;\n reserveMinimumCapacity(n: number): Promise<number>;\n getCapacity(): number;\n getFileCount(): number;\n // Not in older SQLite WASM builds (sqlite-vec's): there `release()` does nothing.\n pauseVfs?(): unknown;\n isPaused?(): boolean;\n unpauseVfs?(): Promise<unknown>;\n }>;\n },\n opts: { name?: string; initialCapacity?: number } = {},\n): Promise<OpenCellSql & { reserve(n: number): Promise<number>; release(): void }> {\n const pool = await sqlite3.installOpfsSAHPoolVfs({\n name: opts.name ?? \"cellb\",\n initialCapacity: opts.initialCapacity ?? 16,\n });\n // The same pool again in this worker (SQLite WASM keeps one per name), after a `release()`.\n if (pool.isPaused?.()) await pool.unpauseVfs?.();\n // A full pool fails the open (`SAH pool is full`), and opening is synchronous while growing\n // the pool is not. A cell about to open reserves room first (`room`, awaited by the runtime\n // before the cell's first event); the pool grows when the reservations would not fit, and in\n // the background whenever less than half of it is free.\n const SLOTS_PER_CELL = 3; // the database, its journal, and one spare\n const reserved = new Set<string>();\n let growing: Promise<void> | undefined;\n const grow = (min: number): Promise<void> => {\n growing ??= pool\n .reserveMinimumCapacity(Math.max(min, pool.getCapacity() * 2))\n .then(() => {})\n .finally(() => {\n growing = undefined;\n });\n return growing;\n };\n const needed = () => pool.getFileCount() + SLOTS_PER_CELL * reserved.size;\n const room = (cellKey: string): Promise<void> | undefined => {\n reserved.add(cellKey);\n if (needed() <= pool.getCapacity()) return undefined;\n // Grow until this reservation (and every other one) fits; the open fails visibly if not.\n const fit = async (): Promise<void> => {\n while (needed() > pool.getCapacity()) {\n const before = pool.getCapacity();\n await grow(needed());\n if (pool.getCapacity() <= before) return; // it did not grow: the open will say why\n }\n };\n return fit();\n };\n const keepRoom = () => {\n const capacity = pool.getCapacity();\n if (!growing && capacity - needed() < capacity / 2) grow(capacity * 2).catch(() => {});\n };\n // The rollback journal stays in the pool between transactions (PERSIST): DELETE gives its pool\n // slot back and takes it again on every commit, which costs a header write each time. The\n // database file is the same in both modes (only WAL marks it).\n const openDb = (path: string) => {\n const db = new pool.OpfsSAHPoolDb(path);\n tuneCellConnection(sqlite3, db);\n db.exec(\"PRAGMA journal_mode=PERSIST\");\n return db;\n };\n const open: OpenCellSql = (cellKey) => {\n const path = `/${cellKey.replace(/[^\\w.-]/g, \"_\")}.sqlite`;\n reserved.delete(cellKey);\n queueMicrotask(keepRoom); // after this open (and its first slot) is counted\n return new WasmSqliteDriver(\n openDb(path),\n {\n image: (db) => (sqlite3 as any).capi.sqlite3_js_db_export(db),\n // Replace the file inside the pool, then reopen it.\n restore(db, image) {\n db.close();\n (pool as any).importDb(path, image);\n return openDb(path);\n },\n },\n sqlite3 as never,\n );\n };\n return Object.assign(open, {\n room,\n reserve: (n: number) => pool.reserveMinimumCapacity(n),\n /**\n * Gives the pool's OPFS files back once every database is closed, so that another worker\n * (another tab's) can open the pool at once instead of when this worker is gone.\n */\n release: () => void pool.pauseVfs?.(),\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"wasm-sqlite.js","sourceRoot":"","sources":["../../src/adapters/wasm-sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import { splitSqlStatements } from \"../core/sql-split.js\";\nimport type { OpenCellSql, SqlResult, SyncSqlDriver } from \"../ports.js\";\nimport { type DirtyPages, installPageHook } from \"./wasm-page-hook.js\";\nimport { type WasmSqlite3, wasmSessionCapture } from \"./wasm-session.js\";\n\n/** Minimal slice of the @sqlite.org/sqlite-wasm `oo1.DB` API we rely on. */\nexport interface Oo1Db {\n prepare(sql: string): Oo1Stmt;\n exec(sql: string): unknown;\n changes(): number;\n close(): void;\n}\ninterface Oo1Stmt {\n bind(values: unknown[]): Oo1Stmt;\n getColumnNames(): string[];\n columnCount: number;\n step(): boolean;\n get(target: unknown[]): unknown[];\n finalize(): void;\n}\n\n/**\n * SyncSqlDriver over the official SQLite WASM build (oo1 API). Synchronous,\n * so it satisfies `ctx.storage.sql`. Works in Node (in-memory, for tests) and\n * in browsers; persistence comes from the VFS behind the DB (see sahpoolOpener).\n */\n/** Backup hooks: how to export an image of the DB and how to replace it (returns the reopened DB). */\nexport interface WasmImageHooks {\n image(db: Oo1Db): Uint8Array;\n restore(db: Oo1Db, image: Uint8Array): Oo1Db;\n}\n\nexport class WasmSqliteDriver implements SyncSqlDriver {\n captureStart?: () => void;\n captureTake?: () => Uint8Array;\n captureDiscard?: () => void;\n applyChangeset?: (changeset: Uint8Array) => void;\n captureCoversRowidTables?: boolean;\n #db: Oo1Db;\n readonly #hooks?: WasmImageHooks;\n readonly #sqlite3?: WasmSqlite3;\n readonly #capi?: { sqlite3_get_autocommit(db: number): number };\n #pageHook?: ReturnType<typeof installPageHook>;\n constructor(\n db: Oo1Db,\n hooks?: WasmImageHooks,\n sqlite3?: WasmSqlite3,\n /** SQLite's C API, for `inTransaction()` alone (when `sqlite3` is not given). */\n capi?: { sqlite3_get_autocommit(db: number): number },\n ) {\n this.#db = db;\n this.#hooks = hooks;\n this.#sqlite3 = sqlite3;\n this.#capi = capi ?? sqlite3?.capi;\n if (!this.#capi?.sqlite3_get_autocommit)\n (this as { inTransaction?: unknown }).inTransaction = undefined;\n this.#enableDqs();\n this.#hookPages();\n if (sqlite3?.capi?.sqlite3session_create) {\n // Transaction-log capture (session extension), following the current DB handle.\n Object.assign(\n this,\n wasmSessionCapture(sqlite3, () => (this.#db as unknown as { pointer: number }).pointer),\n );\n }\n if (!hooks) {\n // No image support for this driver: hide the optional port methods.\n (this as { image?: unknown }).image = undefined;\n (this as { restore?: unknown }).restore = undefined;\n }\n }\n image(): Uint8Array {\n return this.#hooks!.image(this.#db);\n }\n\n /**\n * As celld and workerd: a double-quoted name that is no column is a string literal (SQLite's\n * DQS misfeature, off in this build).\n */\n #enableDqs(): void {\n const capi = this.#sqlite3?.capi;\n if (!capi?.sqlite3_db_config) return;\n const db = (this.#db as unknown as { pointer: number }).pointer;\n capi.sqlite3_db_config(db, capi.SQLITE_DBCONFIG_DQS_DML, 1, 0);\n capi.sqlite3_db_config(db, capi.SQLITE_DBCONFIG_DQS_DDL, 1, 0);\n }\n\n /** Installs the page hook on the current main database file (see wasm-page-hook.ts). */\n #hookPages(): void {\n this.#pageHook = undefined;\n if (!this.#sqlite3?.capi?.sqlite3_file_control) return;\n try {\n this.#pageHook = installPageHook(\n this.#sqlite3,\n (this.#db as unknown as { pointer: number }).pointer,\n );\n } catch {\n this.#pageHook = undefined;\n }\n }\n /** Pages written since the previous call — a committed transaction's changed pages. */\n takeDirtyPages(): DirtyPages | undefined {\n if (!this.#pageHook) return undefined;\n const pageSize = Number(this.exec(\"PRAGMA page_size\", []).rows[0][0]);\n const pageCount = Number(this.exec(\"PRAGMA page_count\", []).rows[0][0]);\n return this.#pageHook.take(pageSize, pageCount);\n }\n discardDirtyPages(): void {\n this.#pageHook?.discard();\n }\n /**\n * WASM builds cannot load extensions at run time; an extension must be compiled into the\n * build (e.g. the `sqlite-vec-wasm-demo` package for \"sqlite_vec\"). This only checks it is.\n */\n loadExtension(name: string): void {\n const probe: Record<string, string> = { sqlite_vec: \"SELECT vec_version()\" };\n if (!probe[name]) throw new Error(`Unknown SQLite extension \"${name}\"`);\n try {\n this.exec(probe[name], []);\n } catch {\n throw new Error(`SQLite extension \"${name}\" is not compiled into this SQLite WASM build`);\n }\n }\n restore(image: Uint8Array): void {\n // celld's databases are in WAL mode (header bytes 18–19 = 2); the WASM VFSes (memdb,\n // opfs-sahpool) have no shared memory for WAL and refuse to open such a file. The pages\n // are the same in rollback-journal mode: switch the header to 1 (celld sets WAL again\n // when it opens the database).\n if (image.length > 19 && image[18] === 2 && image[19] === 2) {\n image = image.slice();\n image[18] = 1;\n image[19] = 1;\n }\n this.#db = this.#hooks!.restore(this.#db, image);\n this.#enableDqs();\n this.#hookPages(); // a new database file behind the connection\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 st = this.#db.prepare(sql);\n try {\n if (params.length) st.bind(params.map(toSqlite));\n const columnNames = st.columnCount ? st.getColumnNames() : [];\n const rows: unknown[][] = [];\n while (st.step()) if (columnNames.length) rows.push(st.get([]).map(fromSqlite));\n return { columnNames, rows, rowsWritten: columnNames.length ? 0 : this.#db.changes() };\n } finally {\n st.finalize();\n }\n }\n inTransaction(): boolean {\n const pointer = (this.#db as unknown as { pointer: number }).pointer;\n return this.#capi!.sqlite3_get_autocommit(pointer) === 0;\n }\n databaseSize(): number {\n const pc = this.exec(\"PRAGMA page_count\", []).rows[0][0];\n const ps = this.exec(\"PRAGMA page_size\", []).rows[0][0];\n return Number(pc) * Number(ps);\n }\n close(): void {\n this.#db.close();\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}\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/** In-memory WASM databases (tests, ephemeral cells). `sqlite3` = await sqlite3InitModule(). */\n/** Image hooks for an in-memory DB: `sqlite3_js_db_export` / `sqlite3_deserialize`. */\nexport function memoryImageHooks(sqlite3: any): WasmImageHooks {\n const { capi, wasm } = sqlite3;\n return {\n image: (db) => sqlite3.capi.sqlite3_js_db_export(db),\n restore(db, image) {\n const p = wasm.allocFromTypedArray(image);\n const rc = capi.sqlite3_deserialize(\n (db as any).pointer,\n \"main\",\n p,\n image.byteLength,\n image.byteLength,\n capi.SQLITE_DESERIALIZE_FREEONCLOSE | capi.SQLITE_DESERIALIZE_RESIZEABLE,\n );\n if (rc) throw new Error(`sqlite3_deserialize failed: ${capi.sqlite3_js_rc_str?.(rc) ?? rc}`);\n return db;\n },\n };\n}\n\n/**\n * Sets up a new SQLite WASM connection for a cell. One worker holds many small cells, and SQLite\n * WASM's heap is capped at 2 GiB and never shrinks, so each connection's fixed memory decides how\n * many cells can be open at once:\n * - no lookaside: SQLite's per-connection allocator of small blocks, about 45 KiB each;\n * - 4 KiB pages for a database that is still empty (celld's page size: SQLite's native default;\n * the WASM build's is 8 KiB). The page cache starts with a block of pages, so the page size\n * sets most of a connection's memory. A database that already holds data keeps its page size.\n * Together they bring a connection with one small table from about 258 KiB to about 120 KiB.\n */\nexport function tuneCellConnection(sqlite3: unknown, db: Oo1Db): void {\n const capi = (sqlite3 as { capi?: Record<string, any> }).capi;\n const pointer = (db as unknown as { pointer?: number }).pointer;\n // Before the connection runs any statement: SQLite refuses (SQLITE_BUSY) while lookaside is used.\n if (capi?.sqlite3_db_config && pointer) {\n capi.sqlite3_db_config(pointer, capi.SQLITE_DBCONFIG_LOOKASIDE, 0, 0, 0);\n }\n db.exec(\"PRAGMA page_size=4096\");\n}\n\nlet memdbCounter = 0;\nexport function wasmMemoryOpener(sqlite3: {\n oo1: { DB: new (path: string, mode?: string) => Oo1Db };\n}): OpenCellSql {\n return () => {\n // memdb (not \":memory:\"): an in-memory database that IS a VFS file, so the page hook works.\n const db = new sqlite3.oo1.DB(`file:/cells-mem-${++memdbCounter}?vfs=memdb`, \"c\");\n tuneCellConnection(sqlite3, db);\n return new WasmSqliteDriver(db, memoryImageHooks(sqlite3), sqlite3 as never);\n };\n}\n\n/**\n * Browser persistence: one OPFS \"SyncAccessHandle pool\" database per cell.\n * Must run in a Dedicated Worker; needs neither COOP/COEP nor SharedArrayBuffer.\n * Not runnable in Node (installOpfsSAHPoolVfs is browser-only) — covered by P04's Playwright spec.\n */\nexport async function sahpoolOpener(\n sqlite3: {\n installOpfsSAHPoolVfs(opts: { name?: string; initialCapacity?: number }): Promise<{\n OpfsSAHPoolDb: new (path: string) => Oo1Db;\n reserveMinimumCapacity(n: number): Promise<number>;\n addCapacity?(n: number): Promise<number>;\n getCapacity(): number;\n getFileCount(): number;\n getFileNames?(): string[];\n // Not in older SQLite WASM builds (sqlite-vec's): there `release()` does nothing.\n pauseVfs?(): unknown;\n isPaused?(): boolean;\n unpauseVfs?(): Promise<unknown>;\n }>;\n },\n opts: { name?: string; initialCapacity?: number } = {},\n): Promise<OpenCellSql & { reserve(n: number): Promise<number>; release(): void }> {\n const pool = await sqlite3.installOpfsSAHPoolVfs({\n name: opts.name ?? \"cellb\",\n initialCapacity: opts.initialCapacity ?? 16,\n });\n // The same pool again in this worker (SQLite WASM keeps one per name), after a `release()`.\n if (pool.isPaused?.()) await pool.unpauseVfs?.();\n // A full pool fails the open (`SAH pool is full`), and opening is synchronous while growing\n // the pool is not. Each new slot is an OPFS file with a sync access handle, made one at a time,\n // and once the worker is busy each one takes seconds (about 5 s with 32 Flue conversations in\n // one worker), so the pool grows ahead of need, in small steps:\n // - a cell about to open reserves room first (`room`, awaited by the runtime before the cell's\n // first event): its database, its journal and a spare, and it waits until what was needed\n // when it asked fits, one step of 16 slots at a time (not a doubling, nor later reservations);\n // - an open cell counts its journal until it has one (SQLite makes it at the cell's first\n // write), so the pool grows while it still has room, not once the journals fill it;\n // - at each open (failed ones too: a cell can reopen without `room`), the pool grows in the\n // background until two thirds of it are free: an unused slot costs a small file, a missing\n // one a wait of seconds per slot, so it grows while the worker is still quiet.\n const SLOTS_PER_CELL = 3; // the database, its journal, and one spare\n const STEP = 16; // slots per growth step, made in parallel\n const AHEAD = 3; // the pool's size, in multiples of what it needs, kept by the background growth\n const reserved = new Set<string>();\n const opened = new Map<string, { path: string }>(); // the open cells' databases\n let growing: Promise<void> | undefined;\n /**\n * One growth step toward `target` (one at a time: a second caller joins it). SQLite makes a\n * pool's new slots one after another, two awaited OPFS calls each, and in a busy worker each\n * await waits seconds for the event loop: the step asks for its slots in parallel instead,\n * one `addCapacity(1)` each, so it costs about one slot's wait.\n */\n const step = (target: number): Promise<void> => {\n const n = Math.min(target, pool.getCapacity() + STEP) - pool.getCapacity();\n growing ??= (\n pool.addCapacity && n > 0\n ? Promise.all(Array.from({ length: n }, () => pool.addCapacity?.(1)))\n : pool.reserveMinimumCapacity(pool.getCapacity() + Math.max(n, 0))\n )\n .then(() => {})\n .finally(() => {\n growing = undefined;\n });\n return growing;\n };\n const needed = () => {\n // Journals not made yet. Without the pool's file names (older SQLite WASM builds) none\n // is counted, as before: the files that exist are.\n let journals = 0;\n if (pool.getFileNames) {\n const files = new Set(pool.getFileNames());\n for (const { path } of opened.values()) if (!files.has(`${path}-journal`)) journals++;\n }\n return pool.getFileCount() + journals + SLOTS_PER_CELL * reserved.size;\n };\n /** Grows until `target()` fits; stops when a step of its own adds nothing (the open says why). */\n const growTo = async (target: () => number): Promise<void> => {\n while (target() > pool.getCapacity()) {\n // A step already under way may have added its slots and not ended yet: joining it says\n // nothing about whether the pool can grow.\n const joined = growing !== undefined;\n const before = pool.getCapacity();\n await step(target());\n if (!joined && pool.getCapacity() <= before) return;\n }\n };\n const room = (cellKey: string): Promise<void> | undefined => {\n reserved.add(cellKey);\n const target = needed();\n if (target <= pool.getCapacity()) return undefined;\n return growTo(() => target);\n };\n let ahead: Promise<void> | undefined;\n const keepRoom = () => {\n if (ahead || pool.getCapacity() >= AHEAD * needed()) return;\n ahead = growTo(() => AHEAD * needed())\n .catch(() => {})\n .finally(() => {\n ahead = undefined;\n });\n };\n // The rollback journal stays in the pool between transactions (PERSIST): DELETE gives its pool\n // slot back and takes it again on every commit, which costs a header write each time. The\n // database file is the same in both modes (only WAL marks it).\n const openDb = (path: string) => {\n const db = new pool.OpfsSAHPoolDb(path);\n tuneCellConnection(sqlite3, db);\n db.exec(\"PRAGMA journal_mode=PERSIST\");\n return db;\n };\n const open: OpenCellSql = (cellKey) => {\n const path = `/${cellKey.replace(/[^\\w.-]/g, \"_\")}.sqlite`;\n reserved.delete(cellKey);\n // Counted from now on, with its journal until it has one; no longer once it is closed.\n const entry = { path };\n opened.set(cellKey, entry);\n keepRoom();\n let driver: WasmSqliteDriver;\n try {\n driver = new WasmSqliteDriver(\n openDb(path),\n {\n image: (db) => (sqlite3 as any).capi.sqlite3_js_db_export(db),\n // Replace the file inside the pool, then reopen it.\n restore(db, image) {\n db.close();\n (pool as any).importDb(path, image);\n return openDb(path);\n },\n },\n sqlite3 as never,\n );\n } catch (err) {\n if (opened.get(cellKey) === entry) opened.delete(cellKey);\n throw err;\n }\n const close = driver.close.bind(driver);\n driver.close = () => {\n // Only this driver's entry: the cell may have been opened again since.\n if (opened.get(cellKey) === entry) opened.delete(cellKey);\n close();\n };\n return driver;\n };\n return Object.assign(open, {\n room,\n reserve: (n: number) => pool.reserveMinimumCapacity(n),\n /**\n * Gives the pool's OPFS files back once every database is closed, so that another worker\n * (another tab's) can open the pool at once instead of when this worker is gone.\n */\n release: () => void pool.pauseVfs?.(),\n });\n}\n"]}
|
|
@@ -13,7 +13,7 @@ import { parseJsonc } from "./jsonc.js";
|
|
|
13
13
|
import { moduleRulesPlugin } from "./module-rules.js";
|
|
14
14
|
import { ownModule } from "./own-module.js";
|
|
15
15
|
import { workerScope } from "./worker-scope.js";
|
|
16
|
-
import { createProjectRuntime, hasNodeCompat, loadProjectBindings, loadTimeEnv, WRANGLER_FILES, } from "./wrangler.js";
|
|
16
|
+
import { createProjectRuntime, hasNodeCompat, loadProjectBindings, loadTimeEnv, populatesProcessEnv, processEnvOf, WRANGLER_FILES, } from "./wrangler.js";
|
|
17
17
|
/** Reads `wrangler.jsonc` / `wrangler.json` of a project directory (celld reads the same files). */
|
|
18
18
|
export function readWranglerConfig(dir) {
|
|
19
19
|
for (const name of WRANGLER_FILES) {
|
|
@@ -216,13 +216,9 @@ export async function loadNodeProject(dir, host) {
|
|
|
216
216
|
installHostModuleGlobals(scope);
|
|
217
217
|
// As the browser host: nodejs_compat fills process.env with the text vars (from compatibility
|
|
218
218
|
// date 2025-04-01). Node shares its real process with the Worker, so they land there.
|
|
219
|
-
if (
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
(config.compatibility_date ?? "") >= "2025-04-01"))
|
|
223
|
-
for (const [k, v] of Object.entries(config.vars ?? {}))
|
|
224
|
-
if (typeof v === "string")
|
|
225
|
-
process.env[k] ??= v;
|
|
219
|
+
if (populatesProcessEnv(config))
|
|
220
|
+
for (const [k, v] of Object.entries(processEnvOf(config)))
|
|
221
|
+
process.env[k] ??= v;
|
|
226
222
|
const module = config.main
|
|
227
223
|
? await bundleWorker({ path: resolve(dir, config.main) }, undefined, undefined, {
|
|
228
224
|
nodeCompat,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-project.js","sourceRoot":"","sources":["../../src/project/node-project.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n existsSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { builtinModules, createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { Worker as NodeWorker } from \"node:worker_threads\";\nimport { build } from \"esbuild\";\nimport { applyD1Migrations } from \"../bindings/d1-migrations.js\";\nimport {\n type LogSink,\n type ModuleLoader,\n moduleText,\n outboundFetch,\n} from \"../bindings/worker-loader.js\";\nimport { ctxExports } from \"../core/handles.js\";\nimport type { WorkerModule } from \"../core/runtime.js\";\nimport { isolatedModuleLoader } from \"../isolate/host.js\";\nimport type { PortLike } from \"../isolate/protocol.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport * as workersClasses from \"./cloudflare-workers.js\";\nimport { parseJsonc } from \"./jsonc.js\";\nimport { type ModuleRule, moduleRulesPlugin } from \"./module-rules.js\";\nimport { ownModule } from \"./own-module.js\";\nimport { type WorkerScope, workerScope } from \"./worker-scope.js\";\nimport {\n createProjectRuntime,\n hasNodeCompat,\n loadProjectBindings,\n loadTimeEnv,\n type ProjectHost,\n type ProjectRuntime,\n WRANGLER_FILES,\n type WranglerConfig,\n} from \"./wrangler.js\";\n\n/** Reads `wrangler.jsonc` / `wrangler.json` of a project directory (celld reads the same files). */\nexport function readWranglerConfig(dir: string): WranglerConfig {\n for (const name of WRANGLER_FILES) {\n const p = join(dir, name);\n if (existsSync(p)) return parseJsonc(readFileSync(p, \"utf8\")) as WranglerConfig;\n }\n throw new Error(`no wrangler.jsonc or wrangler.json in ${dir}`);\n}\n\n/** A bare Node.js built-in specifier (\"path\", \"fs/promises\"), not one of a package. */\nconst nodeBuiltinName = new RegExp(\n `^(${builtinModules\n .filter((m) => !m.startsWith(\"_\") && !m.includes(\":\"))\n .map((m) => m.replace(/[/]/g, \"\\\\/\"))\n .join(\"|\")})$`,\n);\n\n/**\n * Node host: bundles `main` with esbuild (as `celld deploy` does) and builds the runtime.\n * `cloudflare:workers` resolves to cellb's module so user classes extend the\n * runtime's own DurableObject / WorkerEntrypoint.\n */\n/** Bundles Worker code (a file, or in-memory modules) with the runtime's module mappings, then imports it. */\nexport async function bundleWorker(\n entry: { path: string } | { modules: Record<string, string>; main: string },\n logs?: LogSink,\n outbound?: typeof fetch,\n opts: {\n nodeCompat?: boolean;\n standardBinaryType?: boolean;\n scope?: WorkerScope;\n /** wrangler `rules` for non-JS imports (the defaults: `.wasm`, `.bin`, `.txt`…, as wrangler). */\n rules?: ModuleRule[];\n } = {},\n): Promise<WorkerModule> {\n // `env` and `exports` of `cloudflare:workers` belong to one Worker: the bundle reads them\n // from its own scope (empty objects for code that has none).\n const scopeKey = opts.scope ? `s${Math.random().toString(36).slice(2)}` : \"\";\n if (opts.scope) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkerScopes ??= {};\n (g.__cellsWorkerScopes as Record<string, unknown>)[scopeKey] = opts.scope;\n }\n // Loaded code gets a bundle-local `fetch` (globalOutbound policy)…\n const outboundKey = outbound ? `o${Math.random().toString(36).slice(2)}` : \"\";\n if (outbound) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsOutbound ??= {};\n (g.__cellsOutbound as Record<string, unknown>)[outboundKey] = outbound;\n }\n // …and a bundle-local `console` that also feeds its Tail Workers.\n const consoleKey = logs ? `c${Math.random().toString(36).slice(2)}` : \"\";\n if (logs) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsConsoles ??= {};\n const registry = g.__cellsConsoles as Record<string, unknown>;\n const real = globalThis.console;\n const wrap =\n (level: \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\") =>\n (...args: unknown[]) => {\n logs(level, args);\n real[level](...args);\n };\n registry[consoleKey] = Object.assign(Object.create(real), {\n log: wrap(\"log\"),\n info: wrap(\"info\"),\n warn: wrap(\"warn\"),\n error: wrap(\"error\"),\n debug: wrap(\"debug\"),\n });\n }\n const outDir = mkdtempSync(join(tmpdir(), \"cells-worker-\"));\n const out = join(outDir, \"worker.mjs\");\n const cfWorkers = ownModule(import.meta.dirname, \"cloudflare-workers\");\n // This bundle's `cloudflare:workers`: the runtime's classes plus its own `env` and `exports`.\n // A file of its own, kept out of the bundle so it adds no names to the Worker's scope.\n const workersModule = join(outDir, \"cloudflare-workers.mjs\");\n writeFileSync(\n workersModule,\n [\n `export * from ${JSON.stringify(cfWorkers)};`,\n `const scope = globalThis.__cellsWorkerScopes?.[${JSON.stringify(scopeKey)}];`,\n \"export const env = scope ? scope.env : {};\",\n \"export const exports = scope ? scope.exports : {};\",\n \"export const waitUntil = (p) => scope?.waitUntil(p);\",\n ].join(\"\\n\"),\n );\n const memory = \"modules\" in entry ? entry.modules : undefined;\n await build({\n entryPoints: [\n memory ? `memory:${(entry as { main: string }).main}` : (entry as { path: string }).path,\n ],\n outfile: out,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n // As `celld deploy` resolves packages: workerd's conditions, then `module` and `main` (the\n // neutral platform has no main fields, so a package with only `main` would not resolve).\n conditions: [\"workerd\", \"worker\", \"browser\"],\n mainFields: [\"module\", \"main\"],\n target: \"es2022\",\n logLevel: \"silent\",\n // nodejs_compat: CommonJS dependencies `require()` Node's built-ins (mime-types requires\n // node:path), as they may under workerd's nodejs_compat. In an ES module bundle esbuild's\n // require shim needs a `require` in scope: vitest's module runner provides one, plain Node\n // does not.\n ...(opts.nodeCompat\n ? {\n banner: {\n js: 'import { createRequire as __cellbCreateRequire } from \"node:module\";\\nconst require = __cellbCreateRequire(import.meta.url);',\n },\n }\n : {}),\n inject: [\n ownModule(import.meta.dirname, \"workers-globals\"),\n ...(logs ? [\"cellb:console\"] : []),\n ...(outbound ? [\"cellb:fetch\"] : []),\n ],\n plugins: [\n {\n name: \"cells-modules\",\n setup(b) {\n b.onResolve({ filter: /^cellb:console$/ }, () => ({\n path: \"console\",\n namespace: \"cells-console\",\n }));\n // nodejs_compat on a Node host: `node:*` are the real Node.js modules.\n if (opts.nodeCompat) {\n b.onResolve({ filter: /^node:/ }, (a) => ({ path: a.path, external: true }));\n // workerd's nodejs_compat also takes the bare names (\"path\", \"fs/promises\").\n b.onResolve({ filter: nodeBuiltinName }, (a) => ({\n path: `node:${a.path}`,\n external: true,\n }));\n }\n b.onResolve({ filter: /^cellb:compat$/ }, () => ({\n path: \"compat\",\n namespace: \"cells-compat\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-compat\" }, () => ({\n contents: `export const standardBinaryType = ${!!opts.standardBinaryType};`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cellb:fetch$/ }, () => ({\n path: \"fetch\",\n namespace: \"cells-fetch\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-fetch\" }, () => ({\n contents: `export const fetch = globalThis.__cellsOutbound[${JSON.stringify(outboundKey)}];`,\n loader: \"js\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-console\" }, () => ({\n contents: `export const console = globalThis.__cellsConsoles[${JSON.stringify(consoleKey)}];`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: workersModule,\n external: true,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n external: true,\n }));\n b.onResolve({ filter: /^cellb:ws$/ }, () => ({\n path: ownModule(import.meta.dirname, \"workers-globals-module\"),\n external: true,\n }));\n if (!memory) return;\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) =>\n a.namespace === \"memory\"\n ? {\n path: new URL(a.path, `file:///${a.importer}`).pathname.slice(1),\n namespace: \"memory\",\n }\n : undefined,\n );\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: memory[a.path],\n loader: \"js\",\n }));\n },\n },\n moduleRulesPlugin(opts.rules),\n ],\n });\n return (await import(/* @vite-ignore */ out)) as WorkerModule;\n}\n\n/** Worker Loader on Node: compiles `WorkerCode.modules` with esbuild (as celld compiles loaded code). */\nexport const nodeModuleLoader: ModuleLoader = async (_id, code, logs) => {\n const outbound = outboundFetch(code);\n const modules: Record<string, string> = {};\n for (const [name, m] of Object.entries(code.modules)) modules[name] = moduleText(m);\n // `env` and `exports` of the loaded code's `cloudflare:workers` are its own (WorkerCode.env).\n const env = code.env ?? {};\n const scope = workerScope(env);\n const module = (await bundleWorker({ modules, main: code.mainModule }, logs, outbound, {\n scope,\n })) as Record<string, unknown>;\n scope.bind({ env, exports: ctxExports(module, env) });\n return module;\n};\n\nexport async function loadNodeProject(\n dir: string,\n host: Omit<ProjectHost, \"loadModules\"> & Partial<Pick<ProjectHost, \"loadModules\">>,\n): Promise<ProjectRuntime & { config: WranglerConfig }> {\n const config = readWranglerConfig(dir);\n if (!config.main && !config.assets)\n throw new Error(\"wrangler config has neither `main` nor `assets`\");\n const flags = config.compatibility_flags ?? [];\n const nodeCompat = hasNodeCompat(config);\n const standardBinaryType = flags.includes(\"websocket_standard_binary_type\");\n // The module reads `env` from `cloudflare:workers` while it is evaluated, before the\n // runtime exists: until then the scope holds the configuration's vars (and `ai`).\n const scope = workerScope(loadTimeEnv(config, host.ai));\n // A bundle built elsewhere for cellb (cellbHostModule: webrun-bundler in a browser, say) reads\n // the runtime from globals, as in the browser realm: set them here too, so the same bundle\n // runs on Node. (One such project per process: the globals are the process's.)\n installHostModuleGlobals(scope);\n // As the browser host: nodejs_compat fills process.env with the text vars (from compatibility\n // date 2025-04-01). Node shares its real process with the Worker, so they land there.\n if (\n nodeCompat &&\n !flags.includes(\"nodejs_compat_do_not_populate_process_env\") &&\n (flags.includes(\"nodejs_compat_populate_process_env\") ||\n (config.compatibility_date ?? \"\") >= \"2025-04-01\")\n )\n for (const [k, v] of Object.entries(config.vars ?? {}))\n if (typeof v === \"string\") process.env[k] ??= v;\n const module = config.main\n ? await bundleWorker({ path: resolve(dir, config.main) }, undefined, undefined, {\n nodeCompat,\n standardBinaryType,\n scope,\n rules: config.rules,\n })\n : ({ default: {} } as WorkerModule);\n const assetFiles = config.assets?.directory\n ? readAssetDirectory(resolve(dir, config.assets.directory))\n : undefined;\n const project = createProjectRuntime(config, module, {\n bindings: await loadProjectBindings(config),\n loadModules: nodeModuleLoader,\n // own realm, as celld; facets logged like the root's\n isolatedModules: nodeIsolatedLoader(() => host.storage),\n assetFiles,\n ...host,\n });\n scope.bind(project.runtime);\n return { ...project, config };\n}\n\n/** Reads an assets directory into \"/path\" → bytes (what `celld deploy` uploads). */\nexport function readAssetDirectory(root: string): Map<string, Uint8Array> {\n const files = new Map<string, Uint8Array>();\n const walk = (dir: string, prefix: string) => {\n for (const name of readdirSync(dir)) {\n const full = join(dir, name);\n if (statSync(full).isDirectory()) walk(full, `${prefix}${name}/`);\n else files.set(`${prefix}${name}`, new Uint8Array(readFileSync(full)));\n }\n };\n walk(root, \"/\");\n return files;\n}\n\n/**\n * `celld d1 migrations apply DATABASE` for a Node-hosted project: reads\n * `migrations_dir` (default \"migrations\") of the `d1_databases` entry and applies what is new.\n */\nexport async function applyNodeD1Migrations(\n dir: string,\n runtime: { env: Record<string, unknown> },\n database: string,\n) {\n const config = readWranglerConfig(dir);\n const d1 = config.d1_databases?.find(\n (d) => d.database_name === database || d.binding === database,\n );\n if (!d1) throw new Error(`no d1_databases entry named ${database}`);\n const mdir = resolve(dir, (d1 as { migrations_dir?: string }).migrations_dir ?? \"migrations\");\n const files: [string, string][] = existsSync(mdir)\n ? readdirSync(mdir).map((f) => [f, readFileSync(join(mdir, f), \"utf8\")])\n : [];\n return applyD1Migrations(\n runtime.env[d1.binding] as never,\n files,\n (d1 as { migrations_table?: string }).migrations_table ?? \"d1_migrations\",\n );\n}\n\n/**\n * Loaded Workers in worker threads (one realm each), like celld's isolates. The code is\n * bundled with esbuild (cloudflare:workers bundled in) and imported in the thread from a\n * data: URL; Durable Object classes for facets still load in this realm.\n */\nlet isolateEntry: Promise<string> | undefined;\nexport function nodeIsolatedLoader(storage?: () => CellStorage | undefined): ModuleLoader {\n return isolatedModuleLoader({\n storage,\n spawn: () => {\n const port = new NodeWorker(new URL(`file://${isolateEntryPathSync()}`));\n port.unref(); // an idle isolate never keeps the process alive\n return { port: port as unknown as PortLike, terminate: () => void port.terminate() };\n },\n prepare: async (_id, code) => {\n isolateEntry ??= buildIsolateEntry();\n await isolateEntry;\n const modules: Record<string, string> = {};\n for (const [name, m] of Object.entries(code.modules)) modules[name] = moduleText(m);\n const out = await build({\n entryPoints: [`memory:${code.mainModule}`],\n write: false,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n target: \"es2022\",\n logLevel: \"silent\",\n plugins: [\n {\n name: \"isolate-modules\",\n setup(b) {\n // The loaded Worker is its thread's own: `env` and `exports` are the scope\n // serveIsolate keeps for it.\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: \"cloudflare:workers\",\n namespace: \"isolate-workers\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"isolate-workers\" }, () => ({\n contents: [\n // cloudflare-workers.js in the published package (dist/), .ts in the sources.\n `export * from ${JSON.stringify(ownModule(import.meta.dirname, \"cloudflare-workers\"))};`,\n \"export const env = globalThis.__cellsProjectScope.env, exports = globalThis.__cellsProjectScope.exports, waitUntil = (p) => globalThis.__cellsProjectScope.waitUntil(p);\",\n ].join(\"\\n\"),\n loader: \"js\",\n resolveDir: import.meta.dirname,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n }));\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) =>\n a.namespace === \"memory\"\n ? {\n path: new URL(a.path, `file:///${a.importer}`).pathname.slice(1),\n namespace: \"memory\",\n }\n : undefined,\n );\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: modules[a.path],\n loader: \"js\",\n }));\n },\n },\n ],\n });\n return { source: out.outputFiles[0].text };\n },\n });\n}\n\nlet isolateEntryFile = \"\";\nfunction isolateEntryPathSync(): string {\n if (!isolateEntryFile) throw new Error(\"isolate entry not built yet\");\n return isolateEntryFile;\n}\nasync function buildIsolateEntry(): Promise<string> {\n isolateEntryFile = join(mkdtempSync(join(tmpdir(), \"cells-isolate-\")), \"isolate.mjs\");\n await build({\n entryPoints: [ownModule(import.meta.dirname, \"../isolate/node-entry\")],\n outfile: isolateEntryFile,\n bundle: true,\n format: \"esm\",\n platform: \"node\",\n target: \"node22\",\n logLevel: \"silent\",\n });\n return isolateEntryFile;\n}\n\n/** The globals `@statewalker/cellb/host-modules` bundles read (see host-modules.ts). */\nfunction installHostModuleGlobals(scope: WorkerScope): void {\n const g = globalThis as Record<string, unknown>;\n g.__cellsProjectScope = scope;\n g.__cellsWorkersModule ??= workersClasses;\n // node:* from Node itself (the browser realm gives cellb's polyfills).\n g.__cellsNodeModules ??= new Proxy(\n {},\n { get: (_t, k) => (typeof k === \"string\" ? requireBuiltin(k) : undefined) },\n );\n}\nconst requireBuiltin = createRequire(import.meta.url);\n"]}
|
|
1
|
+
{"version":3,"file":"node-project.js","sourceRoot":"","sources":["../../src/project/node-project.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n existsSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { builtinModules, createRequire } from \"node:module\";\nimport { tmpdir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport { Worker as NodeWorker } from \"node:worker_threads\";\nimport { build } from \"esbuild\";\nimport { applyD1Migrations } from \"../bindings/d1-migrations.js\";\nimport {\n type LogSink,\n type ModuleLoader,\n moduleText,\n outboundFetch,\n} from \"../bindings/worker-loader.js\";\nimport { ctxExports } from \"../core/handles.js\";\nimport type { WorkerModule } from \"../core/runtime.js\";\nimport { isolatedModuleLoader } from \"../isolate/host.js\";\nimport type { PortLike } from \"../isolate/protocol.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport * as workersClasses from \"./cloudflare-workers.js\";\nimport { parseJsonc } from \"./jsonc.js\";\nimport { type ModuleRule, moduleRulesPlugin } from \"./module-rules.js\";\nimport { ownModule } from \"./own-module.js\";\nimport { type WorkerScope, workerScope } from \"./worker-scope.js\";\nimport {\n createProjectRuntime,\n hasNodeCompat,\n loadProjectBindings,\n loadTimeEnv,\n type ProjectHost,\n type ProjectRuntime,\n populatesProcessEnv,\n processEnvOf,\n WRANGLER_FILES,\n type WranglerConfig,\n} from \"./wrangler.js\";\n\n/** Reads `wrangler.jsonc` / `wrangler.json` of a project directory (celld reads the same files). */\nexport function readWranglerConfig(dir: string): WranglerConfig {\n for (const name of WRANGLER_FILES) {\n const p = join(dir, name);\n if (existsSync(p)) return parseJsonc(readFileSync(p, \"utf8\")) as WranglerConfig;\n }\n throw new Error(`no wrangler.jsonc or wrangler.json in ${dir}`);\n}\n\n/** A bare Node.js built-in specifier (\"path\", \"fs/promises\"), not one of a package. */\nconst nodeBuiltinName = new RegExp(\n `^(${builtinModules\n .filter((m) => !m.startsWith(\"_\") && !m.includes(\":\"))\n .map((m) => m.replace(/[/]/g, \"\\\\/\"))\n .join(\"|\")})$`,\n);\n\n/**\n * Node host: bundles `main` with esbuild (as `celld deploy` does) and builds the runtime.\n * `cloudflare:workers` resolves to cellb's module so user classes extend the\n * runtime's own DurableObject / WorkerEntrypoint.\n */\n/** Bundles Worker code (a file, or in-memory modules) with the runtime's module mappings, then imports it. */\nexport async function bundleWorker(\n entry: { path: string } | { modules: Record<string, string>; main: string },\n logs?: LogSink,\n outbound?: typeof fetch,\n opts: {\n nodeCompat?: boolean;\n standardBinaryType?: boolean;\n scope?: WorkerScope;\n /** wrangler `rules` for non-JS imports (the defaults: `.wasm`, `.bin`, `.txt`…, as wrangler). */\n rules?: ModuleRule[];\n } = {},\n): Promise<WorkerModule> {\n // `env` and `exports` of `cloudflare:workers` belong to one Worker: the bundle reads them\n // from its own scope (empty objects for code that has none).\n const scopeKey = opts.scope ? `s${Math.random().toString(36).slice(2)}` : \"\";\n if (opts.scope) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkerScopes ??= {};\n (g.__cellsWorkerScopes as Record<string, unknown>)[scopeKey] = opts.scope;\n }\n // Loaded code gets a bundle-local `fetch` (globalOutbound policy)…\n const outboundKey = outbound ? `o${Math.random().toString(36).slice(2)}` : \"\";\n if (outbound) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsOutbound ??= {};\n (g.__cellsOutbound as Record<string, unknown>)[outboundKey] = outbound;\n }\n // …and a bundle-local `console` that also feeds its Tail Workers.\n const consoleKey = logs ? `c${Math.random().toString(36).slice(2)}` : \"\";\n if (logs) {\n const g = globalThis as Record<string, unknown>;\n g.__cellsConsoles ??= {};\n const registry = g.__cellsConsoles as Record<string, unknown>;\n const real = globalThis.console;\n const wrap =\n (level: \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\") =>\n (...args: unknown[]) => {\n logs(level, args);\n real[level](...args);\n };\n registry[consoleKey] = Object.assign(Object.create(real), {\n log: wrap(\"log\"),\n info: wrap(\"info\"),\n warn: wrap(\"warn\"),\n error: wrap(\"error\"),\n debug: wrap(\"debug\"),\n });\n }\n const outDir = mkdtempSync(join(tmpdir(), \"cells-worker-\"));\n const out = join(outDir, \"worker.mjs\");\n const cfWorkers = ownModule(import.meta.dirname, \"cloudflare-workers\");\n // This bundle's `cloudflare:workers`: the runtime's classes plus its own `env` and `exports`.\n // A file of its own, kept out of the bundle so it adds no names to the Worker's scope.\n const workersModule = join(outDir, \"cloudflare-workers.mjs\");\n writeFileSync(\n workersModule,\n [\n `export * from ${JSON.stringify(cfWorkers)};`,\n `const scope = globalThis.__cellsWorkerScopes?.[${JSON.stringify(scopeKey)}];`,\n \"export const env = scope ? scope.env : {};\",\n \"export const exports = scope ? scope.exports : {};\",\n \"export const waitUntil = (p) => scope?.waitUntil(p);\",\n ].join(\"\\n\"),\n );\n const memory = \"modules\" in entry ? entry.modules : undefined;\n await build({\n entryPoints: [\n memory ? `memory:${(entry as { main: string }).main}` : (entry as { path: string }).path,\n ],\n outfile: out,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n // As `celld deploy` resolves packages: workerd's conditions, then `module` and `main` (the\n // neutral platform has no main fields, so a package with only `main` would not resolve).\n conditions: [\"workerd\", \"worker\", \"browser\"],\n mainFields: [\"module\", \"main\"],\n target: \"es2022\",\n logLevel: \"silent\",\n // nodejs_compat: CommonJS dependencies `require()` Node's built-ins (mime-types requires\n // node:path), as they may under workerd's nodejs_compat. In an ES module bundle esbuild's\n // require shim needs a `require` in scope: vitest's module runner provides one, plain Node\n // does not.\n ...(opts.nodeCompat\n ? {\n banner: {\n js: 'import { createRequire as __cellbCreateRequire } from \"node:module\";\\nconst require = __cellbCreateRequire(import.meta.url);',\n },\n }\n : {}),\n inject: [\n ownModule(import.meta.dirname, \"workers-globals\"),\n ...(logs ? [\"cellb:console\"] : []),\n ...(outbound ? [\"cellb:fetch\"] : []),\n ],\n plugins: [\n {\n name: \"cells-modules\",\n setup(b) {\n b.onResolve({ filter: /^cellb:console$/ }, () => ({\n path: \"console\",\n namespace: \"cells-console\",\n }));\n // nodejs_compat on a Node host: `node:*` are the real Node.js modules.\n if (opts.nodeCompat) {\n b.onResolve({ filter: /^node:/ }, (a) => ({ path: a.path, external: true }));\n // workerd's nodejs_compat also takes the bare names (\"path\", \"fs/promises\").\n b.onResolve({ filter: nodeBuiltinName }, (a) => ({\n path: `node:${a.path}`,\n external: true,\n }));\n }\n b.onResolve({ filter: /^cellb:compat$/ }, () => ({\n path: \"compat\",\n namespace: \"cells-compat\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-compat\" }, () => ({\n contents: `export const standardBinaryType = ${!!opts.standardBinaryType};`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cellb:fetch$/ }, () => ({\n path: \"fetch\",\n namespace: \"cells-fetch\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-fetch\" }, () => ({\n contents: `export const fetch = globalThis.__cellsOutbound[${JSON.stringify(outboundKey)}];`,\n loader: \"js\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"cells-console\" }, () => ({\n contents: `export const console = globalThis.__cellsConsoles[${JSON.stringify(consoleKey)}];`,\n loader: \"js\",\n }));\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: workersModule,\n external: true,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n external: true,\n }));\n b.onResolve({ filter: /^cellb:ws$/ }, () => ({\n path: ownModule(import.meta.dirname, \"workers-globals-module\"),\n external: true,\n }));\n if (!memory) return;\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) =>\n a.namespace === \"memory\"\n ? {\n path: new URL(a.path, `file:///${a.importer}`).pathname.slice(1),\n namespace: \"memory\",\n }\n : undefined,\n );\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: memory[a.path],\n loader: \"js\",\n }));\n },\n },\n moduleRulesPlugin(opts.rules),\n ],\n });\n return (await import(/* @vite-ignore */ out)) as WorkerModule;\n}\n\n/** Worker Loader on Node: compiles `WorkerCode.modules` with esbuild (as celld compiles loaded code). */\nexport const nodeModuleLoader: ModuleLoader = async (_id, code, logs) => {\n const outbound = outboundFetch(code);\n const modules: Record<string, string> = {};\n for (const [name, m] of Object.entries(code.modules)) modules[name] = moduleText(m);\n // `env` and `exports` of the loaded code's `cloudflare:workers` are its own (WorkerCode.env).\n const env = code.env ?? {};\n const scope = workerScope(env);\n const module = (await bundleWorker({ modules, main: code.mainModule }, logs, outbound, {\n scope,\n })) as Record<string, unknown>;\n scope.bind({ env, exports: ctxExports(module, env) });\n return module;\n};\n\nexport async function loadNodeProject(\n dir: string,\n host: Omit<ProjectHost, \"loadModules\"> & Partial<Pick<ProjectHost, \"loadModules\">>,\n): Promise<ProjectRuntime & { config: WranglerConfig }> {\n const config = readWranglerConfig(dir);\n if (!config.main && !config.assets)\n throw new Error(\"wrangler config has neither `main` nor `assets`\");\n const flags = config.compatibility_flags ?? [];\n const nodeCompat = hasNodeCompat(config);\n const standardBinaryType = flags.includes(\"websocket_standard_binary_type\");\n // The module reads `env` from `cloudflare:workers` while it is evaluated, before the\n // runtime exists: until then the scope holds the configuration's vars (and `ai`).\n const scope = workerScope(loadTimeEnv(config, host.ai));\n // A bundle built elsewhere for cellb (cellbHostModule: webrun-bundler in a browser, say) reads\n // the runtime from globals, as in the browser realm: set them here too, so the same bundle\n // runs on Node. (One such project per process: the globals are the process's.)\n installHostModuleGlobals(scope);\n // As the browser host: nodejs_compat fills process.env with the text vars (from compatibility\n // date 2025-04-01). Node shares its real process with the Worker, so they land there.\n if (populatesProcessEnv(config))\n for (const [k, v] of Object.entries(processEnvOf(config))) process.env[k] ??= v;\n const module = config.main\n ? await bundleWorker({ path: resolve(dir, config.main) }, undefined, undefined, {\n nodeCompat,\n standardBinaryType,\n scope,\n rules: config.rules,\n })\n : ({ default: {} } as WorkerModule);\n const assetFiles = config.assets?.directory\n ? readAssetDirectory(resolve(dir, config.assets.directory))\n : undefined;\n const project = createProjectRuntime(config, module, {\n bindings: await loadProjectBindings(config),\n loadModules: nodeModuleLoader,\n // own realm, as celld; facets logged like the root's\n isolatedModules: nodeIsolatedLoader(() => host.storage),\n assetFiles,\n ...host,\n });\n scope.bind(project.runtime);\n return { ...project, config };\n}\n\n/** Reads an assets directory into \"/path\" → bytes (what `celld deploy` uploads). */\nexport function readAssetDirectory(root: string): Map<string, Uint8Array> {\n const files = new Map<string, Uint8Array>();\n const walk = (dir: string, prefix: string) => {\n for (const name of readdirSync(dir)) {\n const full = join(dir, name);\n if (statSync(full).isDirectory()) walk(full, `${prefix}${name}/`);\n else files.set(`${prefix}${name}`, new Uint8Array(readFileSync(full)));\n }\n };\n walk(root, \"/\");\n return files;\n}\n\n/**\n * `celld d1 migrations apply DATABASE` for a Node-hosted project: reads\n * `migrations_dir` (default \"migrations\") of the `d1_databases` entry and applies what is new.\n */\nexport async function applyNodeD1Migrations(\n dir: string,\n runtime: { env: Record<string, unknown> },\n database: string,\n) {\n const config = readWranglerConfig(dir);\n const d1 = config.d1_databases?.find(\n (d) => d.database_name === database || d.binding === database,\n );\n if (!d1) throw new Error(`no d1_databases entry named ${database}`);\n const mdir = resolve(dir, (d1 as { migrations_dir?: string }).migrations_dir ?? \"migrations\");\n const files: [string, string][] = existsSync(mdir)\n ? readdirSync(mdir).map((f) => [f, readFileSync(join(mdir, f), \"utf8\")])\n : [];\n return applyD1Migrations(\n runtime.env[d1.binding] as never,\n files,\n (d1 as { migrations_table?: string }).migrations_table ?? \"d1_migrations\",\n );\n}\n\n/**\n * Loaded Workers in worker threads (one realm each), like celld's isolates. The code is\n * bundled with esbuild (cloudflare:workers bundled in) and imported in the thread from a\n * data: URL; Durable Object classes for facets still load in this realm.\n */\nlet isolateEntry: Promise<string> | undefined;\nexport function nodeIsolatedLoader(storage?: () => CellStorage | undefined): ModuleLoader {\n return isolatedModuleLoader({\n storage,\n spawn: () => {\n const port = new NodeWorker(new URL(`file://${isolateEntryPathSync()}`));\n port.unref(); // an idle isolate never keeps the process alive\n return { port: port as unknown as PortLike, terminate: () => void port.terminate() };\n },\n prepare: async (_id, code) => {\n isolateEntry ??= buildIsolateEntry();\n await isolateEntry;\n const modules: Record<string, string> = {};\n for (const [name, m] of Object.entries(code.modules)) modules[name] = moduleText(m);\n const out = await build({\n entryPoints: [`memory:${code.mainModule}`],\n write: false,\n bundle: true,\n format: \"esm\",\n platform: \"neutral\",\n target: \"es2022\",\n logLevel: \"silent\",\n plugins: [\n {\n name: \"isolate-modules\",\n setup(b) {\n // The loaded Worker is its thread's own: `env` and `exports` are the scope\n // serveIsolate keeps for it.\n b.onResolve({ filter: /^cloudflare:workers$/ }, () => ({\n path: \"cloudflare:workers\",\n namespace: \"isolate-workers\",\n }));\n b.onLoad({ filter: /.*/, namespace: \"isolate-workers\" }, () => ({\n contents: [\n // cloudflare-workers.js in the published package (dist/), .ts in the sources.\n `export * from ${JSON.stringify(ownModule(import.meta.dirname, \"cloudflare-workers\"))};`,\n \"export const env = globalThis.__cellsProjectScope.env, exports = globalThis.__cellsProjectScope.exports, waitUntil = (p) => globalThis.__cellsProjectScope.waitUntil(p);\",\n ].join(\"\\n\"),\n loader: \"js\",\n resolveDir: import.meta.dirname,\n }));\n b.onResolve({ filter: /^cloudflare:email$/ }, () => ({\n path: ownModule(import.meta.dirname, \"cloudflare-email\"),\n }));\n b.onResolve({ filter: /^memory:/ }, (a) => ({\n path: a.path.slice(7),\n namespace: \"memory\",\n }));\n b.onResolve({ filter: /^\\.{1,2}\\// }, (a) =>\n a.namespace === \"memory\"\n ? {\n path: new URL(a.path, `file:///${a.importer}`).pathname.slice(1),\n namespace: \"memory\",\n }\n : undefined,\n );\n b.onLoad({ filter: /.*/, namespace: \"memory\" }, (a) => ({\n contents: modules[a.path],\n loader: \"js\",\n }));\n },\n },\n ],\n });\n return { source: out.outputFiles[0].text };\n },\n });\n}\n\nlet isolateEntryFile = \"\";\nfunction isolateEntryPathSync(): string {\n if (!isolateEntryFile) throw new Error(\"isolate entry not built yet\");\n return isolateEntryFile;\n}\nasync function buildIsolateEntry(): Promise<string> {\n isolateEntryFile = join(mkdtempSync(join(tmpdir(), \"cells-isolate-\")), \"isolate.mjs\");\n await build({\n entryPoints: [ownModule(import.meta.dirname, \"../isolate/node-entry\")],\n outfile: isolateEntryFile,\n bundle: true,\n format: \"esm\",\n platform: \"node\",\n target: \"node22\",\n logLevel: \"silent\",\n });\n return isolateEntryFile;\n}\n\n/** The globals `@statewalker/cellb/host-modules` bundles read (see host-modules.ts). */\nfunction installHostModuleGlobals(scope: WorkerScope): void {\n const g = globalThis as Record<string, unknown>;\n g.__cellsProjectScope = scope;\n g.__cellsWorkersModule ??= workersClasses;\n // node:* from Node itself (the browser realm gives cellb's polyfills).\n g.__cellsNodeModules ??= new Proxy(\n {},\n { get: (_t, k) => (typeof k === \"string\" ? requireBuiltin(k) : undefined) },\n );\n}\nconst requireBuiltin = createRequire(import.meta.url);\n"]}
|
|
@@ -1,13 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `siteCompiler`: a project's sources served by an in-browser HTTP server (`createProjectSite`,
|
|
3
|
+
* hosted in a ServiceWorker by webrun-site-host), for `loadProject(files, { compile })`. Modules
|
|
4
|
+
* are compiled one by one as the browser imports them; nothing is bundled.
|
|
5
|
+
*
|
|
6
|
+
* `loadProject` runs in a Dedicated Worker, which cannot register a ServiceWorker: the site is
|
|
7
|
+
* hosted by a page. `siteHostOverPort` (worker) and `hostSitesForWorker` (page) do that over a
|
|
8
|
+
* MessagePort: the worker serves the site's handler, the page mounts it in its ServiceWorker.
|
|
9
|
+
*/
|
|
10
|
+
import { SwHttpAdapter } from "@statewalker/webrun-http-browser";
|
|
1
11
|
import { HostedSiteBuilder } from "@statewalker/webrun-site-host";
|
|
2
12
|
import { linkOverPort, serveHandlerOverPort } from "../transport/port.js";
|
|
3
13
|
import { createProjectSite } from "./site.js";
|
|
14
|
+
/**
|
|
15
|
+
* A `HostedSiteBuilder` whose page side is this package's webrun-http-browser (`SwHttpAdapter`),
|
|
16
|
+
* not the older one webrun-site-host depends on (^0.7). From 0.12.5 it rebuilds a request's url at
|
|
17
|
+
* the page's scheme, so a site hosted on an https page answers; and its version is the one whose
|
|
18
|
+
* ServiceWorker (`sw-worker.js`) hosts serve.
|
|
19
|
+
*/
|
|
20
|
+
function newHostedSiteBuilder() {
|
|
21
|
+
return new HostedSiteBuilder({
|
|
22
|
+
adapterFactory: ({ key, serviceWorkerUrl }) => new SwHttpAdapter({ key, serviceWorkerUrl }),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
4
25
|
/** The default host: a ServiceWorker registered from this realm. */
|
|
5
26
|
function serviceWorkerHost(serviceWorkerUrl) {
|
|
6
27
|
return async (handler) => {
|
|
7
28
|
if (!globalThis.navigator?.serviceWorker)
|
|
8
29
|
throw new Error("siteCompiler: this realm cannot register a ServiceWorker (a Dedicated Worker cannot): " +
|
|
9
30
|
"pass `host: siteHostOverPort(port)` and call `hostSitesForWorker(port)` in the page");
|
|
10
|
-
const builder =
|
|
31
|
+
const builder = newHostedSiteBuilder().setHandler(handler);
|
|
11
32
|
if (serviceWorkerUrl)
|
|
12
33
|
builder.setServiceWorkerUrl(serviceWorkerUrl);
|
|
13
34
|
const site = await builder.build();
|
|
@@ -108,7 +129,7 @@ export function hostSitesForWorker(control, options = {}) {
|
|
|
108
129
|
// The worker may give up waiting (`timeoutMs`) and ask to stop before the site is up: the
|
|
109
130
|
// stop then waits on `reply` until the handler below reads it.
|
|
110
131
|
const link = await linkOverPort(req.link);
|
|
111
|
-
const builder =
|
|
132
|
+
const builder = newHostedSiteBuilder().setHandler(link.send);
|
|
112
133
|
if (options.serviceWorkerUrl)
|
|
113
134
|
builder.setServiceWorkerUrl(options.serviceWorkerUrl);
|
|
114
135
|
const site = await builder.build();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-compiler.js","sourceRoot":"","sources":["../../src/project/site-compiler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `siteCompiler`: a project's sources served by an in-browser HTTP server (`createProjectSite`,\n * hosted in a ServiceWorker by webrun-site-host), for `loadProject(files, { compile })`. Modules\n * are compiled one by one as the browser imports them; nothing is bundled.\n *\n * `loadProject` runs in a Dedicated Worker, which cannot register a ServiceWorker: the site is\n * hosted by a page. `siteHostOverPort` (worker) and `hostSitesForWorker` (page) do that over a\n * MessagePort: the worker serves the site's handler, the page mounts it in its ServiceWorker.\n */\nimport type { SiteHandler } from \"@statewalker/webrun-site-builder\";\nimport { HostedSiteBuilder } from \"@statewalker/webrun-site-host\";\nimport { linkOverPort, serveHandlerOverPort } from \"../transport/port.js\";\nimport { createProjectSite } from \"./site.js\";\nimport type { ProjectCompiler } from \"./source-project.js\";\n\n/** A site, hosted: its base URL (ending in \"/\") and how to take it down. */\nexport interface HostedProjectSite {\n baseUrl: string;\n stop(): Promise<void>;\n}\n\n/** Hosts a site handler where this realm's code can `import()` from it. */\nexport type SiteHost = (handler: SiteHandler) => Promise<HostedProjectSite>;\n\nexport interface SiteCompilerOptions {\n /**\n * Where the site is hosted. Default: a ServiceWorker this realm registers (`HostedSiteBuilder`),\n * which a page can do and a Dedicated Worker cannot; in a worker, pass `siteHostOverPort(port)`\n * and call `hostSitesForWorker(port)` in the page.\n */\n host?: SiteHost;\n /** The ServiceWorker script for the default host (default: `/sw-worker.js`). */\n serviceWorkerUrl?: string;\n /** `createProjectSite`'s `lowerAwait` (default: with nodejs_compat, unless AsyncContext). */\n lowerAwait?: boolean;\n}\n\n/** The default host: a ServiceWorker registered from this realm. */\nfunction serviceWorkerHost(serviceWorkerUrl?: string): SiteHost {\n return async (handler) => {\n if (!(globalThis as { navigator?: { serviceWorker?: unknown } }).navigator?.serviceWorker)\n throw new Error(\n \"siteCompiler: this realm cannot register a ServiceWorker (a Dedicated Worker cannot): \" +\n \"pass `host: siteHostOverPort(port)` and call `hostSitesForWorker(port)` in the page\",\n );\n const builder = new HostedSiteBuilder().setHandler(handler);\n if (serviceWorkerUrl) builder.setServiceWorkerUrl(serviceWorkerUrl);\n const site = await builder.build();\n return { baseUrl: site.baseUrl, stop: () => site.stop() };\n };\n}\n\n/**\n * A compiler for `loadProject(files, { compile })` that serves the project's modules from an\n * in-browser HTTP server (`createProjectSite`): `main` and Worker Loader code are imported from\n * it, so a change can rebuild one module. The site stops when the project closes.\n */\nexport function siteCompiler(options: SiteCompilerOptions = {}): ProjectCompiler {\n const host = options.host ?? serviceWorkerHost(options.serviceWorkerUrl);\n return {\n kind: \"site\",\n async compile({ files, nodeCompat }) {\n let nodeModules: Record<string, unknown> | undefined;\n if (nodeCompat) {\n // The served `node:*` proxies take their export names from the registry entries, which\n // the browser host binds in this realm; the npm `util` polyfill reads `process` when it\n // is imported.\n (await import(\"../node-compat/install.js\")).installNodeGlobals();\n nodeModules = (await import(\"../node-compat/browser-registry.js\")).nodeRegistryEntries;\n }\n const handler = createProjectSite({\n projectFiles: files,\n nodeCompat,\n nodeModules,\n lowerAwait: options.lowerAwait,\n });\n const site = await host(handler);\n const baseUrl = site.baseUrl.endsWith(\"/\") ? site.baseUrl : `${site.baseUrl}/`;\n return { code: { site: baseUrl }, close: () => site.stop() };\n },\n };\n}\n\nconst HOST_SITE = \"cellb:host-site\";\nconst STOP_SITE = \"cellb:stop-site\";\n\n/**\n * Where a worker and its page talk about sites: a MessagePort, the `Worker` (page side) or the\n * worker's own scope (`self`). Other messages on it are left alone.\n */\nexport interface SiteControl {\n postMessage(message: unknown, transfer: Transferable[]): void;\n addEventListener(type: \"message\", listener: (e: MessageEvent) => void): void;\n removeEventListener(type: \"message\", listener: (e: MessageEvent) => void): void;\n}\n\n/** What a worker asks its page for, on the control port. */\ninterface HostSiteRequest {\n type: typeof HOST_SITE;\n /** The worker serves the site's handler on this port's other end. */\n link: MessagePort;\n /** The page answers here, and the worker asks to stop here. */\n reply: MessagePort;\n}\n\n/** The next message on `port`, or `{ error }` after `timeoutMs` (a page that never answers). */\nconst once = (port: MessagePort, timeoutMs: number) =>\n new Promise<{ baseUrl?: string; error?: string }>((resolve) => {\n const timer = setTimeout(\n () =>\n resolve({ error: `no answer in ${timeoutMs} ms (does the page run hostSitesForWorker?)` }),\n timeoutMs,\n );\n port.onmessage = (e) => {\n clearTimeout(timer);\n resolve(e.data);\n };\n });\n\n/**\n * Worker side: hosts each site through the page at the other end of `control`, which runs\n * `hostSitesForWorker`. The handler stays in this worker; the page's ServiceWorker forwards each\n * request to it.\n */\nexport function siteHostOverPort(\n control: SiteControl,\n /**\n * How long the page may take to host the site (default 30 s; a ServiceWorker's first install\n * can be slow), and to confirm it stopped one (default 2 s; the worker stops serving anyway).\n */\n {\n timeoutMs = 30_000,\n stopTimeoutMs = 2_000,\n }: { timeoutMs?: number; stopTimeoutMs?: number } = {},\n): SiteHost {\n return async (handler) => {\n const link = new MessageChannel();\n const reply = new MessageChannel();\n const stopServing = await serveHandlerOverPort(link.port1, handler);\n const answered = once(reply.port1, timeoutMs);\n const request: HostSiteRequest = { type: HOST_SITE, link: link.port2, reply: reply.port2 };\n control.postMessage(request, [link.port2, reply.port2]);\n const { baseUrl, error } = await answered;\n if (!baseUrl) {\n // A page that hosts the site after all finds this stop waiting for it, and takes the site\n // down (its port stays open for that).\n reply.port1.onmessage = null;\n reply.port1.postMessage({ type: STOP_SITE });\n await stopServing();\n throw new Error(`the page did not host the site: ${error}`);\n }\n return {\n baseUrl,\n stop: async () => {\n // A page that does not answer stops nothing: the worker stops serving all the same.\n const stopped = once(reply.port1, stopTimeoutMs);\n reply.port1.postMessage({ type: STOP_SITE });\n await stopped;\n reply.port1.close();\n await stopServing();\n },\n };\n };\n}\n\n/**\n * Page side: hosts in this page's ServiceWorker the sites a worker asks for over `control`\n * (`siteHostOverPort`). Returns a function that stops listening; the sites stop when the worker\n * stops them.\n */\nexport function hostSitesForWorker(\n control: SiteControl,\n options: { serviceWorkerUrl?: string } = {},\n): () => void {\n const listener = async (e: MessageEvent) => {\n const req = e.data as HostSiteRequest | undefined;\n if (req?.type !== HOST_SITE) return;\n try {\n // The worker may give up waiting (`timeoutMs`) and ask to stop before the site is up: the\n // stop then waits on `reply` until the handler below reads it.\n const link = await linkOverPort(req.link);\n const builder = new HostedSiteBuilder().setHandler(link.send);\n if (options.serviceWorkerUrl) builder.setServiceWorkerUrl(options.serviceWorkerUrl);\n const site = await builder.build();\n req.reply.onmessage = async (m) => {\n if ((m.data as { type?: string })?.type !== STOP_SITE) return;\n await site.stop().catch(() => {});\n await link.close().catch(() => {});\n req.reply.postMessage({ stopped: true });\n req.reply.close();\n };\n req.reply.postMessage({ baseUrl: site.baseUrl });\n } catch (err) {\n req.reply.postMessage({ error: String((err as Error)?.message ?? err) });\n req.reply.close();\n }\n };\n control.addEventListener(\"message\", listener);\n (control as { start?: () => void }).start?.();\n return () => control.removeEventListener(\"message\", listener);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"site-compiler.js","sourceRoot":"","sources":["../../src/project/site-compiler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `siteCompiler`: a project's sources served by an in-browser HTTP server (`createProjectSite`,\n * hosted in a ServiceWorker by webrun-site-host), for `loadProject(files, { compile })`. Modules\n * are compiled one by one as the browser imports them; nothing is bundled.\n *\n * `loadProject` runs in a Dedicated Worker, which cannot register a ServiceWorker: the site is\n * hosted by a page. `siteHostOverPort` (worker) and `hostSitesForWorker` (page) do that over a\n * MessagePort: the worker serves the site's handler, the page mounts it in its ServiceWorker.\n */\n\nimport { SwHttpAdapter } from \"@statewalker/webrun-http-browser\";\nimport type { SiteHandler } from \"@statewalker/webrun-site-builder\";\nimport { HostedSiteBuilder } from \"@statewalker/webrun-site-host\";\nimport { linkOverPort, serveHandlerOverPort } from \"../transport/port.js\";\nimport { createProjectSite } from \"./site.js\";\nimport type { ProjectCompiler } from \"./source-project.js\";\n\n/**\n * A `HostedSiteBuilder` whose page side is this package's webrun-http-browser (`SwHttpAdapter`),\n * not the older one webrun-site-host depends on (^0.7). From 0.12.5 it rebuilds a request's url at\n * the page's scheme, so a site hosted on an https page answers; and its version is the one whose\n * ServiceWorker (`sw-worker.js`) hosts serve.\n */\nfunction newHostedSiteBuilder(): HostedSiteBuilder {\n return new HostedSiteBuilder({\n adapterFactory: ({ key, serviceWorkerUrl }) => new SwHttpAdapter({ key, serviceWorkerUrl }),\n });\n}\n\n/** A site, hosted: its base URL (ending in \"/\") and how to take it down. */\nexport interface HostedProjectSite {\n baseUrl: string;\n stop(): Promise<void>;\n}\n\n/** Hosts a site handler where this realm's code can `import()` from it. */\nexport type SiteHost = (handler: SiteHandler) => Promise<HostedProjectSite>;\n\nexport interface SiteCompilerOptions {\n /**\n * Where the site is hosted. Default: a ServiceWorker this realm registers (`HostedSiteBuilder`),\n * which a page can do and a Dedicated Worker cannot; in a worker, pass `siteHostOverPort(port)`\n * and call `hostSitesForWorker(port)` in the page.\n */\n host?: SiteHost;\n /** The ServiceWorker script for the default host (default: `/sw-worker.js`). */\n serviceWorkerUrl?: string;\n /** `createProjectSite`'s `lowerAwait` (default: with nodejs_compat, unless AsyncContext). */\n lowerAwait?: boolean;\n}\n\n/** The default host: a ServiceWorker registered from this realm. */\nfunction serviceWorkerHost(serviceWorkerUrl?: string): SiteHost {\n return async (handler) => {\n if (!(globalThis as { navigator?: { serviceWorker?: unknown } }).navigator?.serviceWorker)\n throw new Error(\n \"siteCompiler: this realm cannot register a ServiceWorker (a Dedicated Worker cannot): \" +\n \"pass `host: siteHostOverPort(port)` and call `hostSitesForWorker(port)` in the page\",\n );\n const builder = newHostedSiteBuilder().setHandler(handler);\n if (serviceWorkerUrl) builder.setServiceWorkerUrl(serviceWorkerUrl);\n const site = await builder.build();\n return { baseUrl: site.baseUrl, stop: () => site.stop() };\n };\n}\n\n/**\n * A compiler for `loadProject(files, { compile })` that serves the project's modules from an\n * in-browser HTTP server (`createProjectSite`): `main` and Worker Loader code are imported from\n * it, so a change can rebuild one module. The site stops when the project closes.\n */\nexport function siteCompiler(options: SiteCompilerOptions = {}): ProjectCompiler {\n const host = options.host ?? serviceWorkerHost(options.serviceWorkerUrl);\n return {\n kind: \"site\",\n async compile({ files, nodeCompat }) {\n let nodeModules: Record<string, unknown> | undefined;\n if (nodeCompat) {\n // The served `node:*` proxies take their export names from the registry entries, which\n // the browser host binds in this realm; the npm `util` polyfill reads `process` when it\n // is imported.\n (await import(\"../node-compat/install.js\")).installNodeGlobals();\n nodeModules = (await import(\"../node-compat/browser-registry.js\")).nodeRegistryEntries;\n }\n const handler = createProjectSite({\n projectFiles: files,\n nodeCompat,\n nodeModules,\n lowerAwait: options.lowerAwait,\n });\n const site = await host(handler);\n const baseUrl = site.baseUrl.endsWith(\"/\") ? site.baseUrl : `${site.baseUrl}/`;\n return { code: { site: baseUrl }, close: () => site.stop() };\n },\n };\n}\n\nconst HOST_SITE = \"cellb:host-site\";\nconst STOP_SITE = \"cellb:stop-site\";\n\n/**\n * Where a worker and its page talk about sites: a MessagePort, the `Worker` (page side) or the\n * worker's own scope (`self`). Other messages on it are left alone.\n */\nexport interface SiteControl {\n postMessage(message: unknown, transfer: Transferable[]): void;\n addEventListener(type: \"message\", listener: (e: MessageEvent) => void): void;\n removeEventListener(type: \"message\", listener: (e: MessageEvent) => void): void;\n}\n\n/** What a worker asks its page for, on the control port. */\ninterface HostSiteRequest {\n type: typeof HOST_SITE;\n /** The worker serves the site's handler on this port's other end. */\n link: MessagePort;\n /** The page answers here, and the worker asks to stop here. */\n reply: MessagePort;\n}\n\n/** The next message on `port`, or `{ error }` after `timeoutMs` (a page that never answers). */\nconst once = (port: MessagePort, timeoutMs: number) =>\n new Promise<{ baseUrl?: string; error?: string }>((resolve) => {\n const timer = setTimeout(\n () =>\n resolve({ error: `no answer in ${timeoutMs} ms (does the page run hostSitesForWorker?)` }),\n timeoutMs,\n );\n port.onmessage = (e) => {\n clearTimeout(timer);\n resolve(e.data);\n };\n });\n\n/**\n * Worker side: hosts each site through the page at the other end of `control`, which runs\n * `hostSitesForWorker`. The handler stays in this worker; the page's ServiceWorker forwards each\n * request to it.\n */\nexport function siteHostOverPort(\n control: SiteControl,\n /**\n * How long the page may take to host the site (default 30 s; a ServiceWorker's first install\n * can be slow), and to confirm it stopped one (default 2 s; the worker stops serving anyway).\n */\n {\n timeoutMs = 30_000,\n stopTimeoutMs = 2_000,\n }: { timeoutMs?: number; stopTimeoutMs?: number } = {},\n): SiteHost {\n return async (handler) => {\n const link = new MessageChannel();\n const reply = new MessageChannel();\n const stopServing = await serveHandlerOverPort(link.port1, handler);\n const answered = once(reply.port1, timeoutMs);\n const request: HostSiteRequest = { type: HOST_SITE, link: link.port2, reply: reply.port2 };\n control.postMessage(request, [link.port2, reply.port2]);\n const { baseUrl, error } = await answered;\n if (!baseUrl) {\n // A page that hosts the site after all finds this stop waiting for it, and takes the site\n // down (its port stays open for that).\n reply.port1.onmessage = null;\n reply.port1.postMessage({ type: STOP_SITE });\n await stopServing();\n throw new Error(`the page did not host the site: ${error}`);\n }\n return {\n baseUrl,\n stop: async () => {\n // A page that does not answer stops nothing: the worker stops serving all the same.\n const stopped = once(reply.port1, stopTimeoutMs);\n reply.port1.postMessage({ type: STOP_SITE });\n await stopped;\n reply.port1.close();\n await stopServing();\n },\n };\n };\n}\n\n/**\n * Page side: hosts in this page's ServiceWorker the sites a worker asks for over `control`\n * (`siteHostOverPort`). Returns a function that stops listening; the sites stop when the worker\n * stops them.\n */\nexport function hostSitesForWorker(\n control: SiteControl,\n options: { serviceWorkerUrl?: string } = {},\n): () => void {\n const listener = async (e: MessageEvent) => {\n const req = e.data as HostSiteRequest | undefined;\n if (req?.type !== HOST_SITE) return;\n try {\n // The worker may give up waiting (`timeoutMs`) and ask to stop before the site is up: the\n // stop then waits on `reply` until the handler below reads it.\n const link = await linkOverPort(req.link);\n const builder = newHostedSiteBuilder().setHandler(link.send);\n if (options.serviceWorkerUrl) builder.setServiceWorkerUrl(options.serviceWorkerUrl);\n const site = await builder.build();\n req.reply.onmessage = async (m) => {\n if ((m.data as { type?: string })?.type !== STOP_SITE) return;\n await site.stop().catch(() => {});\n await link.close().catch(() => {});\n req.reply.postMessage({ stopped: true });\n req.reply.close();\n };\n req.reply.postMessage({ baseUrl: site.baseUrl });\n } catch (err) {\n req.reply.postMessage({ error: String((err as Error)?.message ?? err) });\n req.reply.close();\n }\n };\n control.addEventListener(\"message\", listener);\n (control as { start?: () => void }).start?.();\n return () => control.removeEventListener(\"message\", listener);\n}\n"]}
|
|
@@ -138,16 +138,16 @@ export declare function createProjectRuntime(config: WranglerConfig, module: Wor
|
|
|
138
138
|
* Entries with ids are kept as they are, so storage shared with celld keeps its names.
|
|
139
139
|
*/
|
|
140
140
|
export declare function withResourceIds(config: WranglerConfig): WranglerConfig;
|
|
141
|
+
/** Whether `config` asks for nodejs_compat (the flag, or a `nodejs_compat_*` one). */
|
|
142
|
+
export declare function hasNodeCompat(config: WranglerConfig): boolean;
|
|
143
|
+
/** The configuration files of a project folder, in the order celld reads them. */
|
|
144
|
+
export declare const WRANGLER_FILES: string[];
|
|
141
145
|
/**
|
|
142
146
|
* workerd fills `process.env` with the project's text `vars` under nodejs_compat from
|
|
143
147
|
* compatibility date 2025-04-01 (`nodejs_compat_populate_process_env`), unless
|
|
144
148
|
* `nodejs_compat_do_not_populate_process_env` is set. Frameworks read their settings there
|
|
145
149
|
* (EmDash's `EMDASH_SITE_URL`, for one).
|
|
146
150
|
*/
|
|
147
|
-
/** Whether `config` asks for nodejs_compat (the flag, or a `nodejs_compat_*` one). */
|
|
148
|
-
export declare function hasNodeCompat(config: WranglerConfig): boolean;
|
|
149
|
-
/** The configuration files of a project folder, in the order celld reads them. */
|
|
150
|
-
export declare const WRANGLER_FILES: string[];
|
|
151
151
|
export declare function populatesProcessEnv(config: WranglerConfig): boolean;
|
|
152
152
|
/** The text `vars` of a project, as `process.env` holds them. */
|
|
153
153
|
export declare function processEnvOf(config: WranglerConfig): Record<string, string>;
|
package/dist/project/wrangler.js
CHANGED
|
@@ -131,6 +131,9 @@ export function createProjectRuntime(config, module, host) {
|
|
|
131
131
|
continue; // the host's bundler maps node:*
|
|
132
132
|
else if (f === "websocket_standard_binary_type")
|
|
133
133
|
continue; // the host picks the project's WebSocketPair
|
|
134
|
+
else if (f === "nodejs_compat_populate_process_env" ||
|
|
135
|
+
f === "nodejs_compat_do_not_populate_process_env")
|
|
136
|
+
continue; // the host fills process.env or not (populatesProcessEnv)
|
|
134
137
|
else
|
|
135
138
|
unsupported.push(`compatibility_flags: ${f}`);
|
|
136
139
|
}
|
|
@@ -372,18 +375,18 @@ export function withResourceIds(config) {
|
|
|
372
375
|
d1_databases: d1?.map((d) => d.database_id ? d : { ...d, database_id: d.database_name ?? d.binding }),
|
|
373
376
|
};
|
|
374
377
|
}
|
|
375
|
-
/**
|
|
376
|
-
* workerd fills `process.env` with the project's text `vars` under nodejs_compat from
|
|
377
|
-
* compatibility date 2025-04-01 (`nodejs_compat_populate_process_env`), unless
|
|
378
|
-
* `nodejs_compat_do_not_populate_process_env` is set. Frameworks read their settings there
|
|
379
|
-
* (EmDash's `EMDASH_SITE_URL`, for one).
|
|
380
|
-
*/
|
|
381
378
|
/** Whether `config` asks for nodejs_compat (the flag, or a `nodejs_compat_*` one). */
|
|
382
379
|
export function hasNodeCompat(config) {
|
|
383
380
|
return (config.compatibility_flags ?? []).some((f) => f.startsWith("nodejs_compat"));
|
|
384
381
|
}
|
|
385
382
|
/** The configuration files of a project folder, in the order celld reads them. */
|
|
386
383
|
export const WRANGLER_FILES = ["wrangler.jsonc", "wrangler.json"];
|
|
384
|
+
/**
|
|
385
|
+
* workerd fills `process.env` with the project's text `vars` under nodejs_compat from
|
|
386
|
+
* compatibility date 2025-04-01 (`nodejs_compat_populate_process_env`), unless
|
|
387
|
+
* `nodejs_compat_do_not_populate_process_env` is set. Frameworks read their settings there
|
|
388
|
+
* (EmDash's `EMDASH_SITE_URL`, for one).
|
|
389
|
+
*/
|
|
387
390
|
export function populatesProcessEnv(config) {
|
|
388
391
|
const flags = config.compatibility_flags ?? [];
|
|
389
392
|
if (!hasNodeCompat(config))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrangler.js","sourceRoot":"","sources":["../../src/project/wrangler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FilesApi } from \"@statewalker/webrun-files\";\nimport type { AssetFiles, AssetsConfig } from \"../bindings/assets.js\";\nimport type { QueueConsumerConfig } from \"../bindings/celld-queues.js\";\nimport type { ModuleLoader } from \"../bindings/worker-loader.js\";\nimport { type WorkersAiOptions, workersAi } from \"../bindings/workers-ai.js\";\nimport { entrypointStub } from \"../core/handles.js\";\nimport type { DurableObjectNamespace } from \"../core/namespace.js\";\nimport {\n type CellRuntime,\n type CellRuntimeOptions,\n createCellRuntime,\n type WorkerModule,\n} from \"../core/runtime.js\";\nimport { splitSqlStatements } from \"../core/sql-split.js\";\nimport { filesApiBlobService } from \"../miniflare-compat/blob-service.js\";\nimport { simulatorFetcher } from \"../miniflare-compat/simulator-fetcher.js\";\nimport { systemClock } from \"../ports.js\";\nimport type { ModuleRule } from \"./module-rules.js\";\n\n/** The subset of wrangler.json(c) that celld deploys (and cellb reads). */\nexport interface WranglerConfig {\n name?: string;\n main?: string;\n compatibility_date?: string;\n compatibility_flags?: string[];\n vars?: Record<string, unknown>;\n durable_objects?: { bindings?: { name: string; class_name: string; script_name?: string }[] };\n migrations?: {\n tag: string;\n new_sqlite_classes?: string[];\n new_classes?: string[];\n renamed_classes?: { from: string; to: string }[];\n deleted_classes?: string[];\n }[];\n kv_namespaces?: { binding: string; id?: string }[];\n d1_databases?: { binding: string; database_name?: string; database_id?: string }[];\n r2_buckets?: { binding: string; bucket_name: string }[];\n queues?: {\n producers?: { binding: string; queue: string; delivery_delay?: number }[];\n consumers?: QueueConsumerConfig[];\n };\n workflows?: WorkflowConfig[];\n triggers?: { crons?: string[] };\n assets?: AssetsConfig;\n services?: { binding: string; service: string; entrypoint?: string; props?: unknown }[];\n worker_loaders?: { binding: string }[];\n /** Workers AI: served by the host's OpenAI-compatible endpoint (`ProjectHost.ai`), if any. */\n ai?: { binding: string };\n /** Module rules: how imports of non-JS files load (`CompiledWasm`, `Data`, `Text`). */\n rules?: ModuleRule[];\n /** Containers (celld runs them with Docker or Podman): not supported, reported. */\n containers?: { class_name: string; image?: string }[];\n}\n\n/** wrangler `workflows` entries. */\nexport interface WorkflowConfig {\n binding: string;\n name: string;\n class_name: string;\n}\n\n/** Runs the Worker's `queue(batch, env, ctx)` handler for a batch celld's queue cell leased. */\ninterface QueueDispatcher {\n deliver(batch: unknown): Promise<void>;\n}\n\nexport interface ProjectHost\n extends Pick<CellRuntimeOptions, \"openSql\" | \"storage\" | \"clock\" | \"peers\" | \"route\"> {\n /** Files of `assets.directory` (path \"/a/b.html\" → bytes), loaded by the host. */\n assetFiles?: AssetFiles;\n /** Runs each loaded Worker in its own realm (celld isolates); classes still use `loadModules`. */\n isolatedModules?: ModuleLoader;\n /** Compiles code given to a Worker Loader binding (esbuild on Node, webrun-modules in browsers). */\n loadModules?: ModuleLoader;\n /** Blob store of the KV simulator (large values): OPFS in a browser, a directory or S3 on a server. */\n files: FilesApi;\n /** The OpenAI-compatible endpoint behind the `ai` binding; without it the binding is unsupported. */\n ai?: WorkersAiOptions;\n /** The binding implementations the config needs: `await loadProjectBindings(config)`. */\n bindings?: ProjectBindings;\n}\n\n/**\n * The implementations of the bindings a project declares, loaded on demand: a project with\n * Durable Objects only loads none of them (Miniflare's D1 simulator, celld's KV, queue and\n * workflow code, R2, assets, cron and Worker Loaders), and a browser bundle keeps them in chunks\n * of their own.\n */\nexport interface ProjectBindings {\n kv?: typeof import(\"../bindings/celld-kv.js\");\n d1?: typeof import(\"../miniflare-compat/vendored.js\");\n queues?: typeof import(\"../bindings/celld-queues.js\");\n workflows?: typeof import(\"../bindings/celld-workflows.js\");\n r2?: typeof import(\"../bindings/r2.js\");\n r2Celld?: typeof import(\"../bindings/r2-celld.js\");\n cron?: typeof import(\"../bindings/cron.js\");\n assets?: typeof import(\"../bindings/assets.js\");\n workerLoader?: typeof import(\"../bindings/worker-loader.js\");\n}\n\n/** Loads the binding implementations `config` declares, for `createProjectRuntime`'s host. */\nexport async function loadProjectBindings(config: WranglerConfig): Promise<ProjectBindings> {\n const when = <T>(cond: unknown, load: () => Promise<T>) =>\n cond ? load() : Promise.resolve(undefined);\n const [kv, d1, queues, workflows, r2, r2Celld, cron, assets, workerLoader] = await Promise.all([\n when(config.kv_namespaces?.length, () => import(\"../bindings/celld-kv.js\")),\n when(config.d1_databases?.length, () => import(\"../miniflare-compat/vendored.js\")),\n when(\n config.queues?.producers?.length || config.queues?.consumers?.length,\n () => import(\"../bindings/celld-queues.js\"),\n ),\n when(config.workflows?.length, () => import(\"../bindings/celld-workflows.js\")),\n when(config.r2_buckets?.length, () => import(\"../bindings/r2.js\")),\n when(config.r2_buckets?.length, () => import(\"../bindings/r2-celld.js\")),\n when(config.triggers?.crons?.length, () => import(\"../bindings/cron.js\")),\n when(config.assets, () => import(\"../bindings/assets.js\")),\n when(config.worker_loaders?.length, () => import(\"../bindings/worker-loader.js\")),\n ]);\n return { kv, d1, queues, workflows, r2, r2Celld, cron, assets, workerLoader };\n}\n\n/** The loaded implementation of a binding the config declares, or an error saying how to load it. */\nfunction binding<K extends keyof ProjectBindings>(\n host: ProjectHost,\n key: K,\n what: string,\n): NonNullable<ProjectBindings[K]> {\n const m = host.bindings?.[key];\n if (!m)\n throw new Error(\n `${what}: the host has no implementation loaded; pass \\`bindings: await loadProjectBindings(config)\\``,\n );\n return m as NonNullable<ProjectBindings[K]>;\n}\n\nexport interface ProjectRuntime {\n runtime: CellRuntime;\n /** Configuration entries cellb does not support yet (reported, not silently ignored). */\n unsupported: string[];\n}\n\n/**\n * What `env` of `cloudflare:workers` holds while the Worker's module is evaluated, before the\n * runtime exists: the vars, and the bindings that need no runtime (`ai`; Flue's entry reads\n * `env.AI` at load).\n */\nexport function loadTimeEnv(\n config: WranglerConfig,\n ai?: WorkersAiOptions,\n): Record<string, unknown> {\n const env: Record<string, unknown> = { ...config.vars };\n if (config.ai && ai) env[config.ai.binding] = workersAi(ai);\n return env;\n}\n\n// Internal bindings carrying the runtime-supplied objects behind KV and D1.\nconst KV_OBJECTS = \"__CELLS_KV_OBJECTS\";\nconst D1_OBJECTS = \"__CELLS_D1_OBJECTS\";\nconst QUEUE_OBJECTS = \"__CELLS_QUEUE_OBJECTS\";\nconst WORKFLOW_OBJECTS = \"__CELLS_WORKFLOW_OBJECTS\";\n\n/**\n * Builds a runtime from a wrangler config and the Worker's module namespace — the same\n * inputs celld deploys. Hosts differ only in `host` (storage) and in how they load `main`.\n */\nexport function createProjectRuntime(\n config: WranglerConfig,\n module: WorkerModule,\n host: ProjectHost,\n): ProjectRuntime {\n config = withResourceIds(config);\n const unsupported: string[] = [];\n const durableObjects: NonNullable<CellRuntimeOptions[\"durableObjects\"]> = {};\n const sqliteClasses = new Set<string>();\n for (const m of config.migrations ?? []) {\n for (const c of m.new_sqlite_classes ?? []) sqliteClasses.add(c);\n for (const c of m.new_classes ?? []) sqliteClasses.add(c); // KV-backed on Cloudflare; SQLite here (superset)\n for (const r of m.renamed_classes ?? [])\n unsupported.push(`migrations.renamed_classes (${r.from} → ${r.to})`);\n }\n // wrangler's module rule types: the bundles apply CompiledWasm, Data and Text (module-rules.ts)\n for (const [i, r] of (config.rules ?? []).entries())\n if (![\"ESModule\", \"CommonJS\", \"CompiledWasm\", \"Data\", \"Text\"].includes(r.type))\n unsupported.push(`rules[${i}].type \"${r.type}\"`);\n for (const c of config.containers ?? [])\n unsupported.push(`containers[${c.class_name}] (cellb runs no containers)`);\n for (const b of config.durable_objects?.bindings ?? []) {\n if (b.script_name) unsupported.push(`durable_objects.bindings[${b.name}].script_name`);\n durableObjects[b.name] = { className: b.class_name };\n }\n const worker: WorkerModule = { ...module };\n let kv: ReturnType<NonNullable<ProjectBindings[\"kv\"]>[\"celldKv\"]> | undefined;\n if (config.kv_namespaces?.length) {\n kv = binding(host, \"kv\", \"kv_namespaces\").celldKv(host.files);\n worker.__KvNamespace = kv.KvNamespaceCell as never;\n durableObjects[KV_OBJECTS] = { className: \"__KvNamespace\" };\n }\n if (config.d1_databases?.length) {\n worker.__D1Database = binding(host, \"d1\", \"d1_databases\").D1DatabaseObject;\n durableObjects[D1_OBJECTS] = { className: \"__D1Database\" };\n }\n // Queues: every queue is a cell of a runtime-supplied class (as on celld).\n const consumers = new Map((config.queues?.consumers ?? []).map((c) => [c.queue, c]));\n // celld's own queue code (vendor/celld/queues.js): its queue cell, producer and consumer\n // batch, so a queue's cell (and pending messages) is celld's format.\n let queueDispatcher: QueueDispatcher | undefined;\n let queues: ReturnType<NonNullable<ProjectBindings[\"queues\"]>[\"celldQueues\"]> | undefined;\n if (config.queues?.producers?.length || consumers.size) {\n queues = binding(host, \"queues\", \"queues\").celldQueues({\n namespace: () => runtime.env[QUEUE_OBJECTS] as never,\n consumers: [...consumers.values()],\n compatibilityDate: config.compatibility_date,\n runConsumer: (batch) => queueDispatcher!.deliver(batch as never),\n });\n worker.__Queue = queues.QueueCell as never;\n durableObjects[QUEUE_OBJECTS] = { className: \"__Queue\" };\n }\n // Workflows: every instance is a cell of a runtime-supplied class (as on celld).\n // celld's own workflow code (vendor/celld/workflows.js): its instance cell and binding.\n let workflows:\n | ReturnType<NonNullable<ProjectBindings[\"workflows\"]>[\"celldWorkflows\"]>\n | undefined;\n if (config.workflows?.length) {\n workflows = binding(host, \"workflows\", \"workflows\").celldWorkflows({\n script: config.name ?? \"worker\",\n workflows: Object.fromEntries(config.workflows.map((w) => [w.name, w.class_name])),\n exports: () => module as Record<string, unknown>,\n env: () => runtime.env,\n namespace: () => runtime.env[WORKFLOW_OBJECTS],\n });\n worker[workflows.className] = workflows.WorkflowCell as never;\n durableObjects[WORKFLOW_OBJECTS] = { className: workflows.className };\n }\n if (config.ai && !host.ai)\n unsupported.push(\n `ai[${config.ai.binding}] (Workers AI: give the host an OpenAI-compatible \\`ai\\`)`,\n );\n for (const s of config.services ?? [])\n if (s.service !== config.name)\n unsupported.push(\n `services[${s.binding}] → \"${s.service}\" (only this script's own entrypoints)`,\n );\n const sqlExtensions: string[] = [];\n let deleteAllPreservesAlarm = false;\n for (const f of config.compatibility_flags ?? []) {\n if (f === \"delete_all_preserves_alarm\") deleteAllPreservesAlarm = true;\n else if (f === \"delete_all_deletes_alarm\")\n continue; // the default\n else if (f === \"sqlite_vec\")\n sqlExtensions.push(\"sqlite_vec\"); // vec0 virtual tables, as on celld\n else if (f === \"nodejs_compat\" || f === \"nodejs_compat_v2\")\n continue; // the host's bundler maps node:*\n else if (f === \"websocket_standard_binary_type\")\n continue; // the host picks the project's WebSocketPair\n else unsupported.push(`compatibility_flags: ${f}`);\n }\n\n const runtime = createCellRuntime({\n worker,\n durableObjects,\n vars: { ...config.vars, MINIFLARE_BLOBS: filesApiBlobService(host.files) },\n openSql: host.openSql,\n sqlExtensions,\n deleteAllPreservesAlarm,\n scriptName: config.name ?? \"worker\",\n // celld's fleet-wide namespaces for the resources several scripts can share.\n namespaceKeys: {\n __KvNamespace: \"cells:v1:kv:__KvNamespace\",\n __D1Database: \"cells:v1:d1:__D1Database\",\n __Queue: \"cells:v1:queue:__Queue\",\n },\n storage: host.storage,\n clock: host.clock,\n peers: host.peers,\n route: host.route,\n });\n const env = runtime.env as Record<string, unknown>;\n if (config.ai && host.ai) env[config.ai.binding] = workersAi(host.ai);\n // KV: celld's own client against celld's own namespace cell (cell name \"<id>/<shard>\").\n for (const ns of config.kv_namespaces ?? [])\n env[ns.binding] = new kv!.KvNamespace(() => env[KV_OBJECTS], `${ns.id}/0`);\n for (const p of config.queues?.producers ?? [])\n env[p.binding] = queues!.producer(p.queue, p.delivery_delay ?? 0);\n if (consumers.size) {\n const handler = (module.default as { queue?: (b: unknown, e: unknown, c: unknown) => unknown })\n .queue;\n if (typeof handler !== \"function\")\n unsupported.push(\"queues.consumers without a queue() handler\");\n queueDispatcher = {\n deliver: async (batch) => {\n const pending: Promise<unknown>[] = [];\n await handler?.call(module.default, batch, env, {\n waitUntil: (p: Promise<unknown>) => pending.push(p),\n passThroughOnException() {},\n });\n await Promise.allSettled(pending);\n },\n };\n }\n // The isolates of loaded Workers end with the runtime (on Node, a worker thread's port would\n // keep the process alive; in a browser, a Dedicated Worker would outlive the runtime).\n const isolated = host.isolatedModules as\n | (ModuleLoader & { close?(): void | Promise<void> })\n | undefined;\n if (config.worker_loaders?.length && isolated?.close) {\n const close = runtime.close.bind(runtime);\n runtime.close = async () => {\n await close();\n await isolated.close?.();\n };\n }\n for (const l of config.worker_loaders ?? []) {\n if (!host.loadModules) {\n unsupported.push(`worker_loaders[${l.binding}] (the host provides no module loader)`);\n continue;\n }\n const { workerLoader } = binding(host, \"workerLoader\", \"worker_loaders\");\n env[l.binding] = host.isolatedModules\n ? workerLoader(host.isolatedModules) // facets of loaded code run in the isolate as well\n : workerLoader(host.loadModules);\n }\n // Cron Triggers (validated at load time like `celld deploy` does).\n const crons = config.triggers?.crons ?? [];\n if (crons.length) {\n const scheduled = (\n module.default as { scheduled?: (c: unknown, e: unknown, x: unknown) => unknown }\n ).scheduled;\n if (typeof scheduled !== \"function\")\n unsupported.push(\"triggers.crons without a scheduled() handler\");\n else {\n const db = host.openSql(\"__cellb/cron\");\n const stop = binding(host, \"cron\", \"triggers.crons\").startCronTriggers(\n crons,\n (c, x) => runtime.runEvent(() => scheduled.call(module.default, c, env, x)),\n host.clock ?? systemClock,\n cronState(db),\n );\n const close = runtime.close.bind(runtime);\n runtime.close = async () => {\n stop();\n db.close();\n await close();\n };\n }\n }\n // Static assets: routed before the Worker; `assets.binding` exposes env.ASSETS.\n if (config.assets) {\n const hasWorker = typeof (module.default as { fetch?: unknown })?.fetch === \"function\";\n if (host.assetFiles?.has(\"/.assetsignore\"))\n throw new Error(\n `${config.assets.directory ?? \"assets\"}/.assetsignore is not supported by celld; remove it`,\n );\n const assets = binding(host, \"assets\", \"assets\").createAssets(\n host.assetFiles ?? new Map(),\n config.assets,\n hasWorker,\n );\n if (config.assets.binding) env[config.assets.binding] = assets.binding;\n const workerFetch = runtime.fetch.bind(runtime);\n runtime.fetch = async (req) =>\n assets.route(req) ??\n (hasWorker ? workerFetch(req) : new Response(\"Not found\", { status: 404 }));\n }\n for (const w of config.workflows ?? []) env[w.binding] = workflows!.binding(w.name);\n // Service bindings to this script's own entrypoints (a celld fleet runs one application):\n // default export or a named WorkerEntrypoint, with fetch() and JS RPC.\n for (const s of config.services ?? []) {\n if (s.service !== config.name) continue;\n const target = s.entrypoint ? module[s.entrypoint] : module.default;\n if (!target)\n unsupported.push(`services[${s.binding}].entrypoint \"${s.entrypoint}\" is not exported`);\n else env[s.binding] = entrypointStub(target, env, s.props);\n }\n // R2 objects live directly in the host's store, as celld keeps them in the fleet bucket.\n // With a celld fleet bucket, R2 objects live in it as celld keeps them; else in the FilesApi.\n for (const r2 of config.r2_buckets ?? []) {\n const { r2Bucket, r2BucketOn } = binding(host, \"r2\", \"r2_buckets\");\n const { celldR2Backend } = binding(host, \"r2Celld\", \"r2_buckets\");\n env[r2.binding] = host.storage?.objects\n ? r2BucketOn(celldR2Backend(host.storage.objects, r2.bucket_name), r2.binding)\n : r2Bucket(host.files, `/r2/${r2.bucket_name}`, r2.binding);\n }\n for (const d1 of config.d1_databases ?? [])\n env[d1.binding] = celldExec(\n binding(host, \"d1\", \"d1_databases\").makeD1Binding({\n fetcher: simulatorFetcher(\n env[D1_OBJECTS] as DurableObjectNamespace,\n d1.database_id as string, // set by withResourceIds\n ) as never,\n }) as D1Like,\n );\n for (const name of [...sqliteClasses])\n if (!Object.values(durableObjects).some((d) => d.className === name)) {\n // A migrated class without a binding is fine (reachable through other code paths only).\n }\n return { runtime, unsupported };\n}\n\ninterface D1Like {\n exec(sql: string): Promise<{ count: number; duration: number }>;\n prepare(sql: string): { run(): Promise<unknown> };\n}\n\n/**\n * `D1Database#exec` as celld implements it: statements are split by SQL syntax.\n * workerd's d1-api.ts splits on NEWLINES (Cloudflare's documented behaviour), so a\n * multi-line `CREATE TABLE` fails there but works on celld — and celld is the\n * reference here (verified on celld 0.6.2 by the d1 example in conformance/).\n */\nfunction celldExec<T extends D1Like>(db: T): T {\n const exec = async (sql: string) => {\n const t0 = Date.now();\n const statements = splitSqlStatements(sql).filter((s) => s.trim());\n for (const statement of statements) {\n if (/^\\s*BEGIN\\b/i.test(statement))\n throw new Error(\n \"D1_EXEC_ERROR: the SQL ends in an incomplete statement, which did not run: terminate the last statement with a semicolon\",\n );\n guard(statement);\n await db.prepare(statement).run();\n }\n return { count: statements.length, duration: Date.now() - t0 };\n };\n return celldD1(db, exec) as T;\n}\n\n/**\n * celld's D1 rules on top of workerd's client (celld docs/services/d1.md, checked by the\n * d1-details project): ATTACH/DETACH and TEMP objects are \"not authorized\", VACUUM is\n * \"authorization denied\"; there is one primary and no replica, so sessions return the\n * bookmark \"celld:primary\" and every result reports served_by_primary/served_by_region\n * \"local\"; a read-only statement reports last_row_id and changes as 0.\n */\nfunction guard(sql: string): void {\n if (/^\\s*(ATTACH|DETACH)\\b/i.test(sql) || /^\\s*CREATE\\s+(TEMP|TEMPORARY)\\b/i.test(sql))\n throw new Error(\"D1_ERROR: not authorized\");\n if (/^\\s*VACUUM\\b/i.test(sql)) throw new Error(\"D1_ERROR: authorization denied\");\n}\n\nfunction celldMeta(r: any): any {\n if (!r?.meta) return r;\n r.meta.served_by_primary = true;\n r.meta.served_by_region = \"local\";\n if (r.meta.changed_db === false) {\n r.meta.last_row_id = 0;\n r.meta.changes = 0;\n }\n return r;\n}\n\nfunction celldStatement(stmt: any): any {\n return new Proxy(stmt, {\n get(t, p, r) {\n const v = Reflect.get(t, p, r);\n if (p === \"bind\") return (...a: unknown[]) => celldStatement(v.apply(t, a));\n if (p === \"run\" || p === \"all\")\n return async (...a: unknown[]) => celldMeta(await v.apply(t, a));\n return typeof v === \"function\" ? v.bind(t) : v;\n },\n });\n}\n\nfunction celldD1(db: any, exec?: (sql: string) => Promise<unknown>): any {\n return new Proxy(db, {\n get(t, p, r) {\n if (p === \"exec\" && exec) return exec;\n const v = Reflect.get(t, p, r);\n if (p === \"prepare\")\n return (sql: string) => {\n guard(sql);\n return celldStatement(v.call(t, sql));\n };\n if (p === \"batch\")\n return async (stmts: unknown[], ...a: unknown[]) =>\n ((await v.call(t, stmts, ...a)) as unknown[]).map(celldMeta);\n if (p === \"withSession\")\n return () => {\n const session = celldD1(t);\n return new Proxy(session, {\n get: (s, q, rr) =>\n q === \"getBookmark\" ? () => \"celld:primary\" : Reflect.get(s, q, rr),\n });\n };\n if (p === \"getBookmark\") return () => \"celld:primary\";\n return typeof v === \"function\" ? v.bind(t) : v;\n },\n });\n}\n\n/** Last fired occurrence per cron expression, in a small SQLite database of the host. */\nfunction cronState(db: ReturnType<ProjectHost[\"openSql\"]>) {\n db.exec(\n \"CREATE TABLE IF NOT EXISTS cron_state (expression TEXT PRIMARY KEY, scheduled_time INTEGER)\",\n [],\n );\n return {\n get: (e: string) => {\n const row = db.exec(\"SELECT scheduled_time FROM cron_state WHERE expression = ?\", [e])\n .rows[0];\n return row ? Number(row[0]) : undefined;\n },\n set: (e: string, t: number) =>\n void db.exec(\"INSERT OR REPLACE INTO cron_state (expression, scheduled_time) VALUES (?, ?)\", [\n e,\n t,\n ]),\n };\n}\n\n/**\n * KV namespaces and D1 databases may omit their ids: wrangler provisions them on deploy, and\n * framework builds (Astro's Cloudflare adapter, for one) emit such entries. A KV namespace\n * then takes its binding name as id; a D1 database its `database_name`, else its binding name.\n * Entries with ids are kept as they are, so storage shared with celld keeps its names.\n */\nexport function withResourceIds(config: WranglerConfig): WranglerConfig {\n const kv = config.kv_namespaces;\n const d1 = config.d1_databases;\n if (!kv?.some((n) => !n.id) && !d1?.some((d) => !d.database_id)) return config;\n return {\n ...config,\n kv_namespaces: kv?.map((n) => (n.id ? n : { ...n, id: n.binding })),\n d1_databases: d1?.map((d) =>\n d.database_id ? d : { ...d, database_id: d.database_name ?? d.binding },\n ),\n };\n}\n\n/**\n * workerd fills `process.env` with the project's text `vars` under nodejs_compat from\n * compatibility date 2025-04-01 (`nodejs_compat_populate_process_env`), unless\n * `nodejs_compat_do_not_populate_process_env` is set. Frameworks read their settings there\n * (EmDash's `EMDASH_SITE_URL`, for one).\n */\n/** Whether `config` asks for nodejs_compat (the flag, or a `nodejs_compat_*` one). */\nexport function hasNodeCompat(config: WranglerConfig): boolean {\n return (config.compatibility_flags ?? []).some((f) => f.startsWith(\"nodejs_compat\"));\n}\n\n/** The configuration files of a project folder, in the order celld reads them. */\nexport const WRANGLER_FILES = [\"wrangler.jsonc\", \"wrangler.json\"];\n\nexport function populatesProcessEnv(config: WranglerConfig): boolean {\n const flags = config.compatibility_flags ?? [];\n if (!hasNodeCompat(config)) return false;\n if (flags.includes(\"nodejs_compat_do_not_populate_process_env\")) return false;\n if (flags.includes(\"nodejs_compat_populate_process_env\")) return true;\n return (config.compatibility_date ?? \"\") >= \"2025-04-01\";\n}\n\n/** The text `vars` of a project, as `process.env` holds them. */\nexport function processEnvOf(config: WranglerConfig): Record<string, string> {\n const env: Record<string, string> = {};\n for (const [k, v] of Object.entries(config.vars ?? {})) if (typeof v === \"string\") env[k] = v;\n return env;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"wrangler.js","sourceRoot":"","sources":["../../src/project/wrangler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FilesApi } from \"@statewalker/webrun-files\";\nimport type { AssetFiles, AssetsConfig } from \"../bindings/assets.js\";\nimport type { QueueConsumerConfig } from \"../bindings/celld-queues.js\";\nimport type { ModuleLoader } from \"../bindings/worker-loader.js\";\nimport { type WorkersAiOptions, workersAi } from \"../bindings/workers-ai.js\";\nimport { entrypointStub } from \"../core/handles.js\";\nimport type { DurableObjectNamespace } from \"../core/namespace.js\";\nimport {\n type CellRuntime,\n type CellRuntimeOptions,\n createCellRuntime,\n type WorkerModule,\n} from \"../core/runtime.js\";\nimport { splitSqlStatements } from \"../core/sql-split.js\";\nimport { filesApiBlobService } from \"../miniflare-compat/blob-service.js\";\nimport { simulatorFetcher } from \"../miniflare-compat/simulator-fetcher.js\";\nimport { systemClock } from \"../ports.js\";\nimport type { ModuleRule } from \"./module-rules.js\";\n\n/** The subset of wrangler.json(c) that celld deploys (and cellb reads). */\nexport interface WranglerConfig {\n name?: string;\n main?: string;\n compatibility_date?: string;\n compatibility_flags?: string[];\n vars?: Record<string, unknown>;\n durable_objects?: { bindings?: { name: string; class_name: string; script_name?: string }[] };\n migrations?: {\n tag: string;\n new_sqlite_classes?: string[];\n new_classes?: string[];\n renamed_classes?: { from: string; to: string }[];\n deleted_classes?: string[];\n }[];\n kv_namespaces?: { binding: string; id?: string }[];\n d1_databases?: { binding: string; database_name?: string; database_id?: string }[];\n r2_buckets?: { binding: string; bucket_name: string }[];\n queues?: {\n producers?: { binding: string; queue: string; delivery_delay?: number }[];\n consumers?: QueueConsumerConfig[];\n };\n workflows?: WorkflowConfig[];\n triggers?: { crons?: string[] };\n assets?: AssetsConfig;\n services?: { binding: string; service: string; entrypoint?: string; props?: unknown }[];\n worker_loaders?: { binding: string }[];\n /** Workers AI: served by the host's OpenAI-compatible endpoint (`ProjectHost.ai`), if any. */\n ai?: { binding: string };\n /** Module rules: how imports of non-JS files load (`CompiledWasm`, `Data`, `Text`). */\n rules?: ModuleRule[];\n /** Containers (celld runs them with Docker or Podman): not supported, reported. */\n containers?: { class_name: string; image?: string }[];\n}\n\n/** wrangler `workflows` entries. */\nexport interface WorkflowConfig {\n binding: string;\n name: string;\n class_name: string;\n}\n\n/** Runs the Worker's `queue(batch, env, ctx)` handler for a batch celld's queue cell leased. */\ninterface QueueDispatcher {\n deliver(batch: unknown): Promise<void>;\n}\n\nexport interface ProjectHost\n extends Pick<CellRuntimeOptions, \"openSql\" | \"storage\" | \"clock\" | \"peers\" | \"route\"> {\n /** Files of `assets.directory` (path \"/a/b.html\" → bytes), loaded by the host. */\n assetFiles?: AssetFiles;\n /** Runs each loaded Worker in its own realm (celld isolates); classes still use `loadModules`. */\n isolatedModules?: ModuleLoader;\n /** Compiles code given to a Worker Loader binding (esbuild on Node, webrun-modules in browsers). */\n loadModules?: ModuleLoader;\n /** Blob store of the KV simulator (large values): OPFS in a browser, a directory or S3 on a server. */\n files: FilesApi;\n /** The OpenAI-compatible endpoint behind the `ai` binding; without it the binding is unsupported. */\n ai?: WorkersAiOptions;\n /** The binding implementations the config needs: `await loadProjectBindings(config)`. */\n bindings?: ProjectBindings;\n}\n\n/**\n * The implementations of the bindings a project declares, loaded on demand: a project with\n * Durable Objects only loads none of them (Miniflare's D1 simulator, celld's KV, queue and\n * workflow code, R2, assets, cron and Worker Loaders), and a browser bundle keeps them in chunks\n * of their own.\n */\nexport interface ProjectBindings {\n kv?: typeof import(\"../bindings/celld-kv.js\");\n d1?: typeof import(\"../miniflare-compat/vendored.js\");\n queues?: typeof import(\"../bindings/celld-queues.js\");\n workflows?: typeof import(\"../bindings/celld-workflows.js\");\n r2?: typeof import(\"../bindings/r2.js\");\n r2Celld?: typeof import(\"../bindings/r2-celld.js\");\n cron?: typeof import(\"../bindings/cron.js\");\n assets?: typeof import(\"../bindings/assets.js\");\n workerLoader?: typeof import(\"../bindings/worker-loader.js\");\n}\n\n/** Loads the binding implementations `config` declares, for `createProjectRuntime`'s host. */\nexport async function loadProjectBindings(config: WranglerConfig): Promise<ProjectBindings> {\n const when = <T>(cond: unknown, load: () => Promise<T>) =>\n cond ? load() : Promise.resolve(undefined);\n const [kv, d1, queues, workflows, r2, r2Celld, cron, assets, workerLoader] = await Promise.all([\n when(config.kv_namespaces?.length, () => import(\"../bindings/celld-kv.js\")),\n when(config.d1_databases?.length, () => import(\"../miniflare-compat/vendored.js\")),\n when(\n config.queues?.producers?.length || config.queues?.consumers?.length,\n () => import(\"../bindings/celld-queues.js\"),\n ),\n when(config.workflows?.length, () => import(\"../bindings/celld-workflows.js\")),\n when(config.r2_buckets?.length, () => import(\"../bindings/r2.js\")),\n when(config.r2_buckets?.length, () => import(\"../bindings/r2-celld.js\")),\n when(config.triggers?.crons?.length, () => import(\"../bindings/cron.js\")),\n when(config.assets, () => import(\"../bindings/assets.js\")),\n when(config.worker_loaders?.length, () => import(\"../bindings/worker-loader.js\")),\n ]);\n return { kv, d1, queues, workflows, r2, r2Celld, cron, assets, workerLoader };\n}\n\n/** The loaded implementation of a binding the config declares, or an error saying how to load it. */\nfunction binding<K extends keyof ProjectBindings>(\n host: ProjectHost,\n key: K,\n what: string,\n): NonNullable<ProjectBindings[K]> {\n const m = host.bindings?.[key];\n if (!m)\n throw new Error(\n `${what}: the host has no implementation loaded; pass \\`bindings: await loadProjectBindings(config)\\``,\n );\n return m as NonNullable<ProjectBindings[K]>;\n}\n\nexport interface ProjectRuntime {\n runtime: CellRuntime;\n /** Configuration entries cellb does not support yet (reported, not silently ignored). */\n unsupported: string[];\n}\n\n/**\n * What `env` of `cloudflare:workers` holds while the Worker's module is evaluated, before the\n * runtime exists: the vars, and the bindings that need no runtime (`ai`; Flue's entry reads\n * `env.AI` at load).\n */\nexport function loadTimeEnv(\n config: WranglerConfig,\n ai?: WorkersAiOptions,\n): Record<string, unknown> {\n const env: Record<string, unknown> = { ...config.vars };\n if (config.ai && ai) env[config.ai.binding] = workersAi(ai);\n return env;\n}\n\n// Internal bindings carrying the runtime-supplied objects behind KV and D1.\nconst KV_OBJECTS = \"__CELLS_KV_OBJECTS\";\nconst D1_OBJECTS = \"__CELLS_D1_OBJECTS\";\nconst QUEUE_OBJECTS = \"__CELLS_QUEUE_OBJECTS\";\nconst WORKFLOW_OBJECTS = \"__CELLS_WORKFLOW_OBJECTS\";\n\n/**\n * Builds a runtime from a wrangler config and the Worker's module namespace — the same\n * inputs celld deploys. Hosts differ only in `host` (storage) and in how they load `main`.\n */\nexport function createProjectRuntime(\n config: WranglerConfig,\n module: WorkerModule,\n host: ProjectHost,\n): ProjectRuntime {\n config = withResourceIds(config);\n const unsupported: string[] = [];\n const durableObjects: NonNullable<CellRuntimeOptions[\"durableObjects\"]> = {};\n const sqliteClasses = new Set<string>();\n for (const m of config.migrations ?? []) {\n for (const c of m.new_sqlite_classes ?? []) sqliteClasses.add(c);\n for (const c of m.new_classes ?? []) sqliteClasses.add(c); // KV-backed on Cloudflare; SQLite here (superset)\n for (const r of m.renamed_classes ?? [])\n unsupported.push(`migrations.renamed_classes (${r.from} → ${r.to})`);\n }\n // wrangler's module rule types: the bundles apply CompiledWasm, Data and Text (module-rules.ts)\n for (const [i, r] of (config.rules ?? []).entries())\n if (![\"ESModule\", \"CommonJS\", \"CompiledWasm\", \"Data\", \"Text\"].includes(r.type))\n unsupported.push(`rules[${i}].type \"${r.type}\"`);\n for (const c of config.containers ?? [])\n unsupported.push(`containers[${c.class_name}] (cellb runs no containers)`);\n for (const b of config.durable_objects?.bindings ?? []) {\n if (b.script_name) unsupported.push(`durable_objects.bindings[${b.name}].script_name`);\n durableObjects[b.name] = { className: b.class_name };\n }\n const worker: WorkerModule = { ...module };\n let kv: ReturnType<NonNullable<ProjectBindings[\"kv\"]>[\"celldKv\"]> | undefined;\n if (config.kv_namespaces?.length) {\n kv = binding(host, \"kv\", \"kv_namespaces\").celldKv(host.files);\n worker.__KvNamespace = kv.KvNamespaceCell as never;\n durableObjects[KV_OBJECTS] = { className: \"__KvNamespace\" };\n }\n if (config.d1_databases?.length) {\n worker.__D1Database = binding(host, \"d1\", \"d1_databases\").D1DatabaseObject;\n durableObjects[D1_OBJECTS] = { className: \"__D1Database\" };\n }\n // Queues: every queue is a cell of a runtime-supplied class (as on celld).\n const consumers = new Map((config.queues?.consumers ?? []).map((c) => [c.queue, c]));\n // celld's own queue code (vendor/celld/queues.js): its queue cell, producer and consumer\n // batch, so a queue's cell (and pending messages) is celld's format.\n let queueDispatcher: QueueDispatcher | undefined;\n let queues: ReturnType<NonNullable<ProjectBindings[\"queues\"]>[\"celldQueues\"]> | undefined;\n if (config.queues?.producers?.length || consumers.size) {\n queues = binding(host, \"queues\", \"queues\").celldQueues({\n namespace: () => runtime.env[QUEUE_OBJECTS] as never,\n consumers: [...consumers.values()],\n compatibilityDate: config.compatibility_date,\n runConsumer: (batch) => queueDispatcher!.deliver(batch as never),\n });\n worker.__Queue = queues.QueueCell as never;\n durableObjects[QUEUE_OBJECTS] = { className: \"__Queue\" };\n }\n // Workflows: every instance is a cell of a runtime-supplied class (as on celld).\n // celld's own workflow code (vendor/celld/workflows.js): its instance cell and binding.\n let workflows:\n | ReturnType<NonNullable<ProjectBindings[\"workflows\"]>[\"celldWorkflows\"]>\n | undefined;\n if (config.workflows?.length) {\n workflows = binding(host, \"workflows\", \"workflows\").celldWorkflows({\n script: config.name ?? \"worker\",\n workflows: Object.fromEntries(config.workflows.map((w) => [w.name, w.class_name])),\n exports: () => module as Record<string, unknown>,\n env: () => runtime.env,\n namespace: () => runtime.env[WORKFLOW_OBJECTS],\n });\n worker[workflows.className] = workflows.WorkflowCell as never;\n durableObjects[WORKFLOW_OBJECTS] = { className: workflows.className };\n }\n if (config.ai && !host.ai)\n unsupported.push(\n `ai[${config.ai.binding}] (Workers AI: give the host an OpenAI-compatible \\`ai\\`)`,\n );\n for (const s of config.services ?? [])\n if (s.service !== config.name)\n unsupported.push(\n `services[${s.binding}] → \"${s.service}\" (only this script's own entrypoints)`,\n );\n const sqlExtensions: string[] = [];\n let deleteAllPreservesAlarm = false;\n for (const f of config.compatibility_flags ?? []) {\n if (f === \"delete_all_preserves_alarm\") deleteAllPreservesAlarm = true;\n else if (f === \"delete_all_deletes_alarm\")\n continue; // the default\n else if (f === \"sqlite_vec\")\n sqlExtensions.push(\"sqlite_vec\"); // vec0 virtual tables, as on celld\n else if (f === \"nodejs_compat\" || f === \"nodejs_compat_v2\")\n continue; // the host's bundler maps node:*\n else if (f === \"websocket_standard_binary_type\")\n continue; // the host picks the project's WebSocketPair\n else if (\n f === \"nodejs_compat_populate_process_env\" ||\n f === \"nodejs_compat_do_not_populate_process_env\"\n )\n continue; // the host fills process.env or not (populatesProcessEnv)\n else unsupported.push(`compatibility_flags: ${f}`);\n }\n\n const runtime = createCellRuntime({\n worker,\n durableObjects,\n vars: { ...config.vars, MINIFLARE_BLOBS: filesApiBlobService(host.files) },\n openSql: host.openSql,\n sqlExtensions,\n deleteAllPreservesAlarm,\n scriptName: config.name ?? \"worker\",\n // celld's fleet-wide namespaces for the resources several scripts can share.\n namespaceKeys: {\n __KvNamespace: \"cells:v1:kv:__KvNamespace\",\n __D1Database: \"cells:v1:d1:__D1Database\",\n __Queue: \"cells:v1:queue:__Queue\",\n },\n storage: host.storage,\n clock: host.clock,\n peers: host.peers,\n route: host.route,\n });\n const env = runtime.env as Record<string, unknown>;\n if (config.ai && host.ai) env[config.ai.binding] = workersAi(host.ai);\n // KV: celld's own client against celld's own namespace cell (cell name \"<id>/<shard>\").\n for (const ns of config.kv_namespaces ?? [])\n env[ns.binding] = new kv!.KvNamespace(() => env[KV_OBJECTS], `${ns.id}/0`);\n for (const p of config.queues?.producers ?? [])\n env[p.binding] = queues!.producer(p.queue, p.delivery_delay ?? 0);\n if (consumers.size) {\n const handler = (module.default as { queue?: (b: unknown, e: unknown, c: unknown) => unknown })\n .queue;\n if (typeof handler !== \"function\")\n unsupported.push(\"queues.consumers without a queue() handler\");\n queueDispatcher = {\n deliver: async (batch) => {\n const pending: Promise<unknown>[] = [];\n await handler?.call(module.default, batch, env, {\n waitUntil: (p: Promise<unknown>) => pending.push(p),\n passThroughOnException() {},\n });\n await Promise.allSettled(pending);\n },\n };\n }\n // The isolates of loaded Workers end with the runtime (on Node, a worker thread's port would\n // keep the process alive; in a browser, a Dedicated Worker would outlive the runtime).\n const isolated = host.isolatedModules as\n | (ModuleLoader & { close?(): void | Promise<void> })\n | undefined;\n if (config.worker_loaders?.length && isolated?.close) {\n const close = runtime.close.bind(runtime);\n runtime.close = async () => {\n await close();\n await isolated.close?.();\n };\n }\n for (const l of config.worker_loaders ?? []) {\n if (!host.loadModules) {\n unsupported.push(`worker_loaders[${l.binding}] (the host provides no module loader)`);\n continue;\n }\n const { workerLoader } = binding(host, \"workerLoader\", \"worker_loaders\");\n env[l.binding] = host.isolatedModules\n ? workerLoader(host.isolatedModules) // facets of loaded code run in the isolate as well\n : workerLoader(host.loadModules);\n }\n // Cron Triggers (validated at load time like `celld deploy` does).\n const crons = config.triggers?.crons ?? [];\n if (crons.length) {\n const scheduled = (\n module.default as { scheduled?: (c: unknown, e: unknown, x: unknown) => unknown }\n ).scheduled;\n if (typeof scheduled !== \"function\")\n unsupported.push(\"triggers.crons without a scheduled() handler\");\n else {\n const db = host.openSql(\"__cellb/cron\");\n const stop = binding(host, \"cron\", \"triggers.crons\").startCronTriggers(\n crons,\n (c, x) => runtime.runEvent(() => scheduled.call(module.default, c, env, x)),\n host.clock ?? systemClock,\n cronState(db),\n );\n const close = runtime.close.bind(runtime);\n runtime.close = async () => {\n stop();\n db.close();\n await close();\n };\n }\n }\n // Static assets: routed before the Worker; `assets.binding` exposes env.ASSETS.\n if (config.assets) {\n const hasWorker = typeof (module.default as { fetch?: unknown })?.fetch === \"function\";\n if (host.assetFiles?.has(\"/.assetsignore\"))\n throw new Error(\n `${config.assets.directory ?? \"assets\"}/.assetsignore is not supported by celld; remove it`,\n );\n const assets = binding(host, \"assets\", \"assets\").createAssets(\n host.assetFiles ?? new Map(),\n config.assets,\n hasWorker,\n );\n if (config.assets.binding) env[config.assets.binding] = assets.binding;\n const workerFetch = runtime.fetch.bind(runtime);\n runtime.fetch = async (req) =>\n assets.route(req) ??\n (hasWorker ? workerFetch(req) : new Response(\"Not found\", { status: 404 }));\n }\n for (const w of config.workflows ?? []) env[w.binding] = workflows!.binding(w.name);\n // Service bindings to this script's own entrypoints (a celld fleet runs one application):\n // default export or a named WorkerEntrypoint, with fetch() and JS RPC.\n for (const s of config.services ?? []) {\n if (s.service !== config.name) continue;\n const target = s.entrypoint ? module[s.entrypoint] : module.default;\n if (!target)\n unsupported.push(`services[${s.binding}].entrypoint \"${s.entrypoint}\" is not exported`);\n else env[s.binding] = entrypointStub(target, env, s.props);\n }\n // R2 objects live directly in the host's store, as celld keeps them in the fleet bucket.\n // With a celld fleet bucket, R2 objects live in it as celld keeps them; else in the FilesApi.\n for (const r2 of config.r2_buckets ?? []) {\n const { r2Bucket, r2BucketOn } = binding(host, \"r2\", \"r2_buckets\");\n const { celldR2Backend } = binding(host, \"r2Celld\", \"r2_buckets\");\n env[r2.binding] = host.storage?.objects\n ? r2BucketOn(celldR2Backend(host.storage.objects, r2.bucket_name), r2.binding)\n : r2Bucket(host.files, `/r2/${r2.bucket_name}`, r2.binding);\n }\n for (const d1 of config.d1_databases ?? [])\n env[d1.binding] = celldExec(\n binding(host, \"d1\", \"d1_databases\").makeD1Binding({\n fetcher: simulatorFetcher(\n env[D1_OBJECTS] as DurableObjectNamespace,\n d1.database_id as string, // set by withResourceIds\n ) as never,\n }) as D1Like,\n );\n for (const name of [...sqliteClasses])\n if (!Object.values(durableObjects).some((d) => d.className === name)) {\n // A migrated class without a binding is fine (reachable through other code paths only).\n }\n return { runtime, unsupported };\n}\n\ninterface D1Like {\n exec(sql: string): Promise<{ count: number; duration: number }>;\n prepare(sql: string): { run(): Promise<unknown> };\n}\n\n/**\n * `D1Database#exec` as celld implements it: statements are split by SQL syntax.\n * workerd's d1-api.ts splits on NEWLINES (Cloudflare's documented behaviour), so a\n * multi-line `CREATE TABLE` fails there but works on celld — and celld is the\n * reference here (verified on celld 0.6.2 by the d1 example in conformance/).\n */\nfunction celldExec<T extends D1Like>(db: T): T {\n const exec = async (sql: string) => {\n const t0 = Date.now();\n const statements = splitSqlStatements(sql).filter((s) => s.trim());\n for (const statement of statements) {\n if (/^\\s*BEGIN\\b/i.test(statement))\n throw new Error(\n \"D1_EXEC_ERROR: the SQL ends in an incomplete statement, which did not run: terminate the last statement with a semicolon\",\n );\n guard(statement);\n await db.prepare(statement).run();\n }\n return { count: statements.length, duration: Date.now() - t0 };\n };\n return celldD1(db, exec) as T;\n}\n\n/**\n * celld's D1 rules on top of workerd's client (celld docs/services/d1.md, checked by the\n * d1-details project): ATTACH/DETACH and TEMP objects are \"not authorized\", VACUUM is\n * \"authorization denied\"; there is one primary and no replica, so sessions return the\n * bookmark \"celld:primary\" and every result reports served_by_primary/served_by_region\n * \"local\"; a read-only statement reports last_row_id and changes as 0.\n */\nfunction guard(sql: string): void {\n if (/^\\s*(ATTACH|DETACH)\\b/i.test(sql) || /^\\s*CREATE\\s+(TEMP|TEMPORARY)\\b/i.test(sql))\n throw new Error(\"D1_ERROR: not authorized\");\n if (/^\\s*VACUUM\\b/i.test(sql)) throw new Error(\"D1_ERROR: authorization denied\");\n}\n\nfunction celldMeta(r: any): any {\n if (!r?.meta) return r;\n r.meta.served_by_primary = true;\n r.meta.served_by_region = \"local\";\n if (r.meta.changed_db === false) {\n r.meta.last_row_id = 0;\n r.meta.changes = 0;\n }\n return r;\n}\n\nfunction celldStatement(stmt: any): any {\n return new Proxy(stmt, {\n get(t, p, r) {\n const v = Reflect.get(t, p, r);\n if (p === \"bind\") return (...a: unknown[]) => celldStatement(v.apply(t, a));\n if (p === \"run\" || p === \"all\")\n return async (...a: unknown[]) => celldMeta(await v.apply(t, a));\n return typeof v === \"function\" ? v.bind(t) : v;\n },\n });\n}\n\nfunction celldD1(db: any, exec?: (sql: string) => Promise<unknown>): any {\n return new Proxy(db, {\n get(t, p, r) {\n if (p === \"exec\" && exec) return exec;\n const v = Reflect.get(t, p, r);\n if (p === \"prepare\")\n return (sql: string) => {\n guard(sql);\n return celldStatement(v.call(t, sql));\n };\n if (p === \"batch\")\n return async (stmts: unknown[], ...a: unknown[]) =>\n ((await v.call(t, stmts, ...a)) as unknown[]).map(celldMeta);\n if (p === \"withSession\")\n return () => {\n const session = celldD1(t);\n return new Proxy(session, {\n get: (s, q, rr) =>\n q === \"getBookmark\" ? () => \"celld:primary\" : Reflect.get(s, q, rr),\n });\n };\n if (p === \"getBookmark\") return () => \"celld:primary\";\n return typeof v === \"function\" ? v.bind(t) : v;\n },\n });\n}\n\n/** Last fired occurrence per cron expression, in a small SQLite database of the host. */\nfunction cronState(db: ReturnType<ProjectHost[\"openSql\"]>) {\n db.exec(\n \"CREATE TABLE IF NOT EXISTS cron_state (expression TEXT PRIMARY KEY, scheduled_time INTEGER)\",\n [],\n );\n return {\n get: (e: string) => {\n const row = db.exec(\"SELECT scheduled_time FROM cron_state WHERE expression = ?\", [e])\n .rows[0];\n return row ? Number(row[0]) : undefined;\n },\n set: (e: string, t: number) =>\n void db.exec(\"INSERT OR REPLACE INTO cron_state (expression, scheduled_time) VALUES (?, ?)\", [\n e,\n t,\n ]),\n };\n}\n\n/**\n * KV namespaces and D1 databases may omit their ids: wrangler provisions them on deploy, and\n * framework builds (Astro's Cloudflare adapter, for one) emit such entries. A KV namespace\n * then takes its binding name as id; a D1 database its `database_name`, else its binding name.\n * Entries with ids are kept as they are, so storage shared with celld keeps its names.\n */\nexport function withResourceIds(config: WranglerConfig): WranglerConfig {\n const kv = config.kv_namespaces;\n const d1 = config.d1_databases;\n if (!kv?.some((n) => !n.id) && !d1?.some((d) => !d.database_id)) return config;\n return {\n ...config,\n kv_namespaces: kv?.map((n) => (n.id ? n : { ...n, id: n.binding })),\n d1_databases: d1?.map((d) =>\n d.database_id ? d : { ...d, database_id: d.database_name ?? d.binding },\n ),\n };\n}\n\n/** Whether `config` asks for nodejs_compat (the flag, or a `nodejs_compat_*` one). */\nexport function hasNodeCompat(config: WranglerConfig): boolean {\n return (config.compatibility_flags ?? []).some((f) => f.startsWith(\"nodejs_compat\"));\n}\n\n/** The configuration files of a project folder, in the order celld reads them. */\nexport const WRANGLER_FILES = [\"wrangler.jsonc\", \"wrangler.json\"];\n\n/**\n * workerd fills `process.env` with the project's text `vars` under nodejs_compat from\n * compatibility date 2025-04-01 (`nodejs_compat_populate_process_env`), unless\n * `nodejs_compat_do_not_populate_process_env` is set. Frameworks read their settings there\n * (EmDash's `EMDASH_SITE_URL`, for one).\n */\nexport function populatesProcessEnv(config: WranglerConfig): boolean {\n const flags = config.compatibility_flags ?? [];\n if (!hasNodeCompat(config)) return false;\n if (flags.includes(\"nodejs_compat_do_not_populate_process_env\")) return false;\n if (flags.includes(\"nodejs_compat_populate_process_env\")) return true;\n return (config.compatibility_date ?? \"\") >= \"2025-04-01\";\n}\n\n/** The text `vars` of a project, as `process.env` holds them. */\nexport function processEnvOf(config: WranglerConfig): Record<string, string> {\n const env: Record<string, string> = {};\n for (const [k, v] of Object.entries(config.vars ?? {})) if (typeof v === \"string\") env[k] = v;\n return env;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@statewalker/cellb",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "cellb: isomorphic Durable Objects runtime (celld/Cloudflare-compatible surface) for browsers and servers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -62,29 +62,29 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@noble/hashes": "^2.4.0",
|
|
65
|
-
"@sqlite.org/sqlite-wasm": "^3.
|
|
66
|
-
"@statewalker/webrun-files": "^0.10.
|
|
67
|
-
"@statewalker/webrun-files-browser": "^0.10.
|
|
68
|
-
"@statewalker/webrun-files-mem": "^0.10.
|
|
65
|
+
"@sqlite.org/sqlite-wasm": "^3.54.1-build1",
|
|
66
|
+
"@statewalker/webrun-files": "^0.10.3",
|
|
67
|
+
"@statewalker/webrun-files-browser": "^0.10.2",
|
|
68
|
+
"@statewalker/webrun-files-mem": "^0.10.3",
|
|
69
69
|
"@statewalker/webrun-files-node": "^0.10.3",
|
|
70
|
-
"@statewalker/webrun-http-browser": "^0.12.
|
|
71
|
-
"@statewalker/webrun-http-streams": "^0.4.
|
|
72
|
-
"@statewalker/webrun-rpc": "^0.10.
|
|
70
|
+
"@statewalker/webrun-http-browser": "^0.12.5",
|
|
71
|
+
"@statewalker/webrun-http-streams": "^0.4.2",
|
|
72
|
+
"@statewalker/webrun-rpc": "^0.10.2",
|
|
73
73
|
"@statewalker/webrun-streams": "^0.2.3",
|
|
74
74
|
"acorn": "^8.19.0",
|
|
75
75
|
"assert": "^2.1.0",
|
|
76
76
|
"buffer": "^6.0.3",
|
|
77
77
|
"events": "^3.3.0",
|
|
78
78
|
"path-browserify": "^1.0.1",
|
|
79
|
-
"sqlite-vec": "^0.1.
|
|
79
|
+
"sqlite-vec": "^0.1.9",
|
|
80
80
|
"util": "^0.12.5",
|
|
81
|
-
"worker-timers": "^8.0.
|
|
82
|
-
"ws": "^8.22.
|
|
81
|
+
"worker-timers": "^8.0.34",
|
|
82
|
+
"ws": "^8.22.2"
|
|
83
83
|
},
|
|
84
84
|
"peerDependencies": {
|
|
85
85
|
"@statewalker/webrun-bundler": "^0.1.1",
|
|
86
|
-
"@statewalker/webrun-modules": "^0.3.
|
|
87
|
-
"@statewalker/webrun-site-builder": "^0.2.
|
|
86
|
+
"@statewalker/webrun-modules": "^0.3.6",
|
|
87
|
+
"@statewalker/webrun-site-builder": "^0.2.2",
|
|
88
88
|
"@statewalker/webrun-site-host": "^0.3.0",
|
|
89
89
|
"esbuild": ">=0.25"
|
|
90
90
|
},
|
|
@@ -106,15 +106,15 @@
|
|
|
106
106
|
}
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
109
|
-
"@playwright/test": "^1.
|
|
109
|
+
"@playwright/test": "^1.65.0",
|
|
110
110
|
"@sparticuz/chromium": "^153.0.0",
|
|
111
111
|
"@statewalker/webrun-bundler": "^0.1.1",
|
|
112
|
-
"@statewalker/webrun-modules": "^0.3.
|
|
113
|
-
"@statewalker/webrun-site-builder": "^0.2.
|
|
112
|
+
"@statewalker/webrun-modules": "^0.3.6",
|
|
113
|
+
"@statewalker/webrun-site-builder": "^0.2.2",
|
|
114
114
|
"@statewalker/webrun-site-host": "^0.3.0",
|
|
115
|
-
"@types/node": "^26.6.
|
|
115
|
+
"@types/node": "^26.6.6",
|
|
116
116
|
"@types/ws": "^8.18.2",
|
|
117
|
-
"esbuild": "^0.28.
|
|
117
|
+
"esbuild": "^0.28.2",
|
|
118
118
|
"esbuild-wasm": "0.28.2",
|
|
119
119
|
"html-rewriter-wasm": "^0.4.1",
|
|
120
120
|
"miniflare": "4.20260730.0",
|
|
@@ -122,8 +122,8 @@
|
|
|
122
122
|
"partywhen": "0.1.5",
|
|
123
123
|
"sqlite-vec-wasm-demo": "0.1.6",
|
|
124
124
|
"typescript": "^7.0.2",
|
|
125
|
-
"vite": "^8.3.
|
|
126
|
-
"vitest": "^5.0
|
|
125
|
+
"vite": "^8.3.8",
|
|
126
|
+
"vitest": "^5.1.0",
|
|
127
127
|
"zod": "^3.25.0"
|
|
128
128
|
},
|
|
129
129
|
"scripts": {
|