@statewalker/cellb 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +46 -3
  2. package/bin/cellb.mjs +20 -0
  3. package/dist/browser.d.ts +2 -0
  4. package/dist/browser.js +1 -0
  5. package/dist/browser.js.map +1 -1
  6. package/dist/bucket/celld-cells.js +25 -3
  7. package/dist/bucket/celld-cells.js.map +1 -1
  8. package/dist/cli.d.ts +3 -0
  9. package/dist/cli.js +62 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/isolate/browser.d.ts +2 -1
  12. package/dist/isolate/browser.js +2 -1
  13. package/dist/isolate/browser.js.map +1 -1
  14. package/dist/isolate/isolate.js +5 -3
  15. package/dist/isolate/isolate.js.map +1 -1
  16. package/dist/isolate/protocol.d.ts +4 -2
  17. package/dist/isolate/protocol.js +4 -4
  18. package/dist/isolate/protocol.js.map +1 -1
  19. package/dist/node.d.ts +3 -0
  20. package/dist/node.js +2 -0
  21. package/dist/node.js.map +1 -1
  22. package/dist/project/browser-host.d.ts +6 -12
  23. package/dist/project/browser-host.js +2 -25
  24. package/dist/project/browser-host.js.map +1 -1
  25. package/dist/project/browser-load.d.ts +22 -0
  26. package/dist/project/browser-load.js +63 -0
  27. package/dist/project/browser-load.js.map +1 -0
  28. package/dist/project/browser-shards.d.ts +8 -9
  29. package/dist/project/browser-shards.js +88 -52
  30. package/dist/project/browser-shards.js.map +1 -1
  31. package/dist/project/browser-tabs.d.ts +14 -4
  32. package/dist/project/browser-tabs.js +193 -208
  33. package/dist/project/browser-tabs.js.map +1 -1
  34. package/dist/project/build.d.ts +14 -0
  35. package/dist/project/build.js +53 -0
  36. package/dist/project/build.js.map +1 -0
  37. package/dist/project/built-project.d.ts +88 -0
  38. package/dist/project/built-project.js +118 -0
  39. package/dist/project/built-project.js.map +1 -0
  40. package/dist/project/node-load.d.ts +14 -0
  41. package/dist/project/node-load.js +187 -0
  42. package/dist/project/node-load.js.map +1 -0
  43. package/dist/project/wrangler.d.ts +9 -0
  44. package/dist/project/wrangler.js +24 -0
  45. package/dist/project/wrangler.js.map +1 -1
  46. package/dist/transport/cells-http.d.ts +6 -0
  47. package/dist/transport/cells-http.js +22 -1
  48. package/dist/transport/cells-http.js.map +1 -1
  49. package/dist/transport/cells-link.d.ts +2 -0
  50. package/dist/transport/cells-link.js +5 -0
  51. package/dist/transport/cells-link.js.map +1 -1
  52. package/dist/transport/port.js +4 -0
  53. package/dist/transport/port.js.map +1 -1
  54. package/dist/ws/server.d.ts +39 -23
  55. package/dist/ws/server.js +99 -140
  56. package/dist/ws/server.js.map +1 -1
  57. package/package.json +9 -4
@@ -0,0 +1,187 @@
1
+ /**
2
+ * `loadProject` on Node (`@statewalker/cellb/node`): one call that reads a project, built or
3
+ * not, and runs it.
4
+ */
5
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
6
+ import { tmpdir } from "node:os";
7
+ import { dirname, join, resolve } from "node:path";
8
+ import { fileURLToPath, pathToFileURL } from "node:url";
9
+ import { MemFilesApi } from "@statewalker/webrun-files-mem";
10
+ import { NodeFilesApi } from "@statewalker/webrun-files-node";
11
+ import { nodeSqliteOpener } from "../adapters/node-sqlite.js";
12
+ import { BUILD_MANIFEST, BUILT_WORKER, filesApiReader, isFilesApi, readBuildManifest, readBuiltProject, urlReader, } from "./built-project.js";
13
+ import * as workersClasses from "./cloudflare-workers.js";
14
+ import { loadNodeProject, nodeIsolatedLoader, nodeModuleLoader } from "./node-project.js";
15
+ import { workerScope } from "./worker-scope.js";
16
+ import * as workersGlobals from "./workers-globals-module.js";
17
+ import { createProjectRuntime, loadTimeEnv, populatesProcessEnv, processEnvOf, } from "./wrangler.js";
18
+ /**
19
+ * Loads a project and runs it in this process.
20
+ *
21
+ * `source`: a folder with `wrangler.json(c)` (its `main` bundled with esbuild, as
22
+ * `loadNodeProject` does), a folder written by `cellb build` (its `worker.js` imported as built),
23
+ * an `http(s):` URL of a built folder, or a FilesApi holding either kind of folder.
24
+ *
25
+ * `options.data`: a directory for the cells' SQLite files and the project's files
26
+ * (`<data>/files`); without it, both are in memory.
27
+ */
28
+ export async function loadProject(source, options = {}) {
29
+ const host = nodeHost(options);
30
+ const close = async (runtime, cleanup) => {
31
+ await runtime.close();
32
+ cleanup?.();
33
+ };
34
+ // A folder on disk: read where it lies.
35
+ const dir = localDir(source);
36
+ if (dir !== undefined) {
37
+ const reader = fsReader(dir);
38
+ const manifest = await readBuildManifest(reader);
39
+ if (manifest)
40
+ return runBuilt(await readBuiltProject(reader, manifest), host);
41
+ const { runtime, unsupported, config } = await loadNodeProject(dir, host);
42
+ return {
43
+ config,
44
+ runtime,
45
+ unsupported,
46
+ fetch: (req) => runtime.fetch(req),
47
+ close: () => close(runtime),
48
+ };
49
+ }
50
+ // A FilesApi: a built folder is read from it; a source folder is copied out for esbuild.
51
+ if (isFilesApi(source)) {
52
+ const reader = filesApiReader(source);
53
+ const manifest = await readBuildManifest(reader);
54
+ if (manifest)
55
+ return runBuilt(await readBuiltProject(reader, manifest), host);
56
+ const tmp = await copyOut(source);
57
+ try {
58
+ const { runtime, unsupported, config } = await loadNodeProject(tmp, host);
59
+ return {
60
+ config,
61
+ runtime,
62
+ unsupported,
63
+ fetch: (req) => runtime.fetch(req),
64
+ close: () => close(runtime, () => rmSync(tmp, { recursive: true, force: true })),
65
+ };
66
+ }
67
+ catch (err) {
68
+ rmSync(tmp, { recursive: true, force: true });
69
+ throw err;
70
+ }
71
+ }
72
+ // A URL of a built folder.
73
+ const url = folderUrl(source);
74
+ const reader = urlReader(url);
75
+ const manifest = await readBuildManifest(reader);
76
+ if (!manifest)
77
+ throw new Error(`${url} has no ${BUILD_MANIFEST}: load a folder written by \`cellb build\``);
78
+ return runBuilt(await readBuiltProject(reader, manifest), host);
79
+ }
80
+ /** What `options` become on Node: SQLite files and a FilesApi under `data`, or memory. */
81
+ function nodeHost(options) {
82
+ let files;
83
+ if (options.data) {
84
+ const data = resolve(options.data);
85
+ mkdirSync(join(data, "files"), { recursive: true });
86
+ files = new NodeFilesApi({ rootDir: join(data, "files") });
87
+ }
88
+ else
89
+ files = new MemFilesApi();
90
+ return {
91
+ openSql: nodeSqliteOpener(options.data ? resolve(options.data) : undefined),
92
+ files,
93
+ storage: options.bucket,
94
+ ai: options.ai,
95
+ };
96
+ }
97
+ /**
98
+ * Runs a built project on Node: `worker.js` was bundled for a browser realm, so it reads the
99
+ * Workers globals and `cloudflare:workers` from the globals this sets, as in a browser worker.
100
+ * (One such project per process: the globals are the process's.)
101
+ */
102
+ async function runBuilt(built, host) {
103
+ const { config } = built;
104
+ const flags = config.compatibility_flags ?? [];
105
+ const scope = workerScope(loadTimeEnv(config, host.ai));
106
+ const g = globalThis;
107
+ g.__cellsWorkersModule = workersClasses;
108
+ g.__cellsProjectScope = scope;
109
+ g.__cellsGlobals = {
110
+ ...workersGlobals,
111
+ Request: workersGlobals.CellsRequest,
112
+ Response: workersGlobals.CellsResponse,
113
+ WebSocketPair: flags.includes("websocket_standard_binary_type")
114
+ ? workersGlobals.StandardWebSocketPair
115
+ : workersGlobals.WebSocketPair,
116
+ };
117
+ if (populatesProcessEnv(config)) {
118
+ const env = processEnvOf(config);
119
+ g.__cellsProcessEnv = env;
120
+ for (const [k, v] of Object.entries(env))
121
+ process.env[k] ??= v;
122
+ }
123
+ let module = { default: {} };
124
+ if (built.code !== null) {
125
+ const tmp = mkdtempSync(join(tmpdir(), "cellb-built-"));
126
+ const file = join(tmp, BUILT_WORKER.replace(/\.js$/, ".mjs"));
127
+ writeFileSync(file, built.code);
128
+ try {
129
+ module = (await import(/* @vite-ignore */ pathToFileURL(file).href));
130
+ }
131
+ finally {
132
+ rmSync(tmp, { recursive: true, force: true });
133
+ }
134
+ }
135
+ const project = createProjectRuntime(config, module, {
136
+ loadModules: nodeModuleLoader,
137
+ isolatedModules: nodeIsolatedLoader(() => host.storage),
138
+ assetFiles: built.assets,
139
+ ...host,
140
+ });
141
+ scope.bind(project.runtime);
142
+ const { runtime, unsupported } = project;
143
+ return {
144
+ config,
145
+ runtime,
146
+ unsupported,
147
+ fetch: (req) => runtime.fetch(req),
148
+ close: () => runtime.close(),
149
+ };
150
+ }
151
+ /** The folder a source names on this machine: a path or a `file:` URL. */
152
+ function localDir(source) {
153
+ if (typeof source === "string") {
154
+ if (/^https?:\/\//i.test(source))
155
+ return undefined;
156
+ return resolve(source.startsWith("file:") ? fileURLToPath(source) : source);
157
+ }
158
+ if (source instanceof URL && source.protocol === "file:")
159
+ return fileURLToPath(source);
160
+ return undefined;
161
+ }
162
+ function folderUrl(source) {
163
+ const url = new URL(String(source));
164
+ if (!url.pathname.endsWith("/"))
165
+ url.pathname += "/";
166
+ return url;
167
+ }
168
+ function fsReader(dir) {
169
+ return {
170
+ async bytes(path) {
171
+ const full = join(dir, path);
172
+ return existsSync(full) ? new Uint8Array(readFileSync(full)) : undefined;
173
+ },
174
+ };
175
+ }
176
+ /** Copies a FilesApi's files into a temporary folder (esbuild bundles from disk). */
177
+ async function copyOut(files) {
178
+ const tmp = mkdtempSync(join(tmpdir(), "cellb-project-"));
179
+ const reader = filesApiReader(files);
180
+ for (const path of (await reader.list?.("/")) ?? []) {
181
+ const out = join(tmp, path);
182
+ mkdirSync(dirname(out), { recursive: true });
183
+ writeFileSync(out, (await reader.bytes(path)));
184
+ }
185
+ return tmp;
186
+ }
187
+ //# sourceMappingURL=node-load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-load.js","sourceRoot":"","sources":["../../src/project/node-load.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loadProject` on Node (`@statewalker/cellb/node`): one call that reads a project, built or\n * not, and runs it.\n */\nimport { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport type { FilesApi } from \"@statewalker/webrun-files\";\nimport { MemFilesApi } from \"@statewalker/webrun-files-mem\";\nimport { NodeFilesApi } from \"@statewalker/webrun-files-node\";\nimport { nodeSqliteOpener } from \"../adapters/node-sqlite.js\";\nimport type { WorkerModule } from \"../core/runtime.js\";\nimport type { CellStorage } from \"../ports.js\";\nimport {\n BUILD_MANIFEST,\n BUILT_WORKER,\n type BuiltProject,\n filesApiReader,\n isFilesApi,\n type LoadedProject,\n type LoadProjectOptions,\n type ProjectReader,\n type ProjectSource,\n readBuildManifest,\n readBuiltProject,\n urlReader,\n} from \"./built-project.js\";\nimport * as workersClasses from \"./cloudflare-workers.js\";\nimport { loadNodeProject, nodeIsolatedLoader, nodeModuleLoader } from \"./node-project.js\";\nimport { workerScope } from \"./worker-scope.js\";\nimport * as workersGlobals from \"./workers-globals-module.js\";\nimport {\n createProjectRuntime,\n loadTimeEnv,\n type ProjectHost,\n populatesProcessEnv,\n processEnvOf,\n} from \"./wrangler.js\";\n\nexport type NodeLoadProjectOptions = LoadProjectOptions<CellStorage>;\n\n/**\n * Loads a project and runs it in this process.\n *\n * `source`: a folder with `wrangler.json(c)` (its `main` bundled with esbuild, as\n * `loadNodeProject` does), a folder written by `cellb build` (its `worker.js` imported as built),\n * an `http(s):` URL of a built folder, or a FilesApi holding either kind of folder.\n *\n * `options.data`: a directory for the cells' SQLite files and the project's files\n * (`<data>/files`); without it, both are in memory.\n */\nexport async function loadProject(\n source: ProjectSource,\n options: NodeLoadProjectOptions = {},\n): Promise<LoadedProject> {\n const host = nodeHost(options);\n const close = async (runtime: { close(): Promise<void> }, cleanup?: () => void) => {\n await runtime.close();\n cleanup?.();\n };\n // A folder on disk: read where it lies.\n const dir = localDir(source);\n if (dir !== undefined) {\n const reader = fsReader(dir);\n const manifest = await readBuildManifest(reader);\n if (manifest) return runBuilt(await readBuiltProject(reader, manifest), host);\n const { runtime, unsupported, config } = await loadNodeProject(dir, host);\n return {\n config,\n runtime,\n unsupported,\n fetch: (req) => runtime.fetch(req),\n close: () => close(runtime),\n };\n }\n // A FilesApi: a built folder is read from it; a source folder is copied out for esbuild.\n if (isFilesApi(source)) {\n const reader = filesApiReader(source);\n const manifest = await readBuildManifest(reader);\n if (manifest) return runBuilt(await readBuiltProject(reader, manifest), host);\n const tmp = await copyOut(source);\n try {\n const { runtime, unsupported, config } = await loadNodeProject(tmp, host);\n return {\n config,\n runtime,\n unsupported,\n fetch: (req) => runtime.fetch(req),\n close: () => close(runtime, () => rmSync(tmp, { recursive: true, force: true })),\n };\n } catch (err) {\n rmSync(tmp, { recursive: true, force: true });\n throw err;\n }\n }\n // A URL of a built folder.\n const url = folderUrl(source);\n const reader = urlReader(url);\n const manifest = await readBuildManifest(reader);\n if (!manifest)\n throw new Error(`${url} has no ${BUILD_MANIFEST}: load a folder written by \\`cellb build\\``);\n return runBuilt(await readBuiltProject(reader, manifest), host);\n}\n\n/** What `options` become on Node: SQLite files and a FilesApi under `data`, or memory. */\nfunction nodeHost(options: NodeLoadProjectOptions): Omit<ProjectHost, \"loadModules\"> {\n let files: FilesApi;\n if (options.data) {\n const data = resolve(options.data);\n mkdirSync(join(data, \"files\"), { recursive: true });\n files = new NodeFilesApi({ rootDir: join(data, \"files\") });\n } else files = new MemFilesApi();\n return {\n openSql: nodeSqliteOpener(options.data ? resolve(options.data) : undefined),\n files,\n storage: options.bucket,\n ai: options.ai,\n };\n}\n\n/**\n * Runs a built project on Node: `worker.js` was bundled for a browser realm, so it reads the\n * Workers globals and `cloudflare:workers` from the globals this sets, as in a browser worker.\n * (One such project per process: the globals are the process's.)\n */\nasync function runBuilt(\n built: BuiltProject,\n host: Omit<ProjectHost, \"loadModules\">,\n): Promise<LoadedProject> {\n const { config } = built;\n const flags = config.compatibility_flags ?? [];\n const scope = workerScope(loadTimeEnv(config, host.ai));\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkersModule = workersClasses;\n g.__cellsProjectScope = scope;\n g.__cellsGlobals = {\n ...workersGlobals,\n Request: workersGlobals.CellsRequest,\n Response: workersGlobals.CellsResponse,\n WebSocketPair: flags.includes(\"websocket_standard_binary_type\")\n ? workersGlobals.StandardWebSocketPair\n : workersGlobals.WebSocketPair,\n };\n if (populatesProcessEnv(config)) {\n const env = processEnvOf(config);\n g.__cellsProcessEnv = env;\n for (const [k, v] of Object.entries(env)) process.env[k] ??= v;\n }\n let module: WorkerModule = { default: {} } as WorkerModule;\n if (built.code !== null) {\n const tmp = mkdtempSync(join(tmpdir(), \"cellb-built-\"));\n const file = join(tmp, BUILT_WORKER.replace(/\\.js$/, \".mjs\"));\n writeFileSync(file, built.code);\n try {\n module = (await import(/* @vite-ignore */ pathToFileURL(file).href)) as WorkerModule;\n } finally {\n rmSync(tmp, { recursive: true, force: true });\n }\n }\n const project = createProjectRuntime(config, module, {\n loadModules: nodeModuleLoader,\n isolatedModules: nodeIsolatedLoader(() => host.storage),\n assetFiles: built.assets,\n ...host,\n });\n scope.bind(project.runtime);\n const { runtime, unsupported } = project;\n return {\n config,\n runtime,\n unsupported,\n fetch: (req) => runtime.fetch(req),\n close: () => runtime.close(),\n };\n}\n\n/** The folder a source names on this machine: a path or a `file:` URL. */\nfunction localDir(source: ProjectSource): string | undefined {\n if (typeof source === \"string\") {\n if (/^https?:\\/\\//i.test(source)) return undefined;\n return resolve(source.startsWith(\"file:\") ? fileURLToPath(source) : source);\n }\n if (source instanceof URL && source.protocol === \"file:\") return fileURLToPath(source);\n return undefined;\n}\n\nfunction folderUrl(source: ProjectSource): URL {\n const url = new URL(String(source));\n if (!url.pathname.endsWith(\"/\")) url.pathname += \"/\";\n return url;\n}\n\nfunction fsReader(dir: string): ProjectReader {\n return {\n async bytes(path) {\n const full = join(dir, path);\n return existsSync(full) ? new Uint8Array(readFileSync(full)) : undefined;\n },\n };\n}\n\n/** Copies a FilesApi's files into a temporary folder (esbuild bundles from disk). */\nasync function copyOut(files: FilesApi): Promise<string> {\n const tmp = mkdtempSync(join(tmpdir(), \"cellb-project-\"));\n const reader = filesApiReader(files);\n for (const path of (await reader.list?.(\"/\")) ?? []) {\n const out = join(tmp, path);\n mkdirSync(dirname(out), { recursive: true });\n writeFileSync(out, (await reader.bytes(path)) as Uint8Array);\n }\n return tmp;\n}\n"]}
@@ -114,3 +114,12 @@ export declare function createProjectRuntime(config: WranglerConfig, module: Wor
114
114
  * Entries with ids are kept as they are, so storage shared with celld keeps its names.
115
115
  */
116
116
  export declare function withResourceIds(config: WranglerConfig): WranglerConfig;
117
+ /**
118
+ * workerd fills `process.env` with the project's text `vars` under nodejs_compat from
119
+ * compatibility date 2025-04-01 (`nodejs_compat_populate_process_env`), unless
120
+ * `nodejs_compat_do_not_populate_process_env` is set. Frameworks read their settings there
121
+ * (EmDash's `EMDASH_SITE_URL`, for one).
122
+ */
123
+ export declare function populatesProcessEnv(config: WranglerConfig): boolean;
124
+ /** The text `vars` of a project, as `process.env` holds them. */
125
+ export declare function processEnvOf(config: WranglerConfig): Record<string, string>;
@@ -349,4 +349,28 @@ export function withResourceIds(config) {
349
349
  d1_databases: d1?.map((d) => d.database_id ? d : { ...d, database_id: d.database_name ?? d.binding }),
350
350
  };
351
351
  }
352
+ /**
353
+ * workerd fills `process.env` with the project's text `vars` under nodejs_compat from
354
+ * compatibility date 2025-04-01 (`nodejs_compat_populate_process_env`), unless
355
+ * `nodejs_compat_do_not_populate_process_env` is set. Frameworks read their settings there
356
+ * (EmDash's `EMDASH_SITE_URL`, for one).
357
+ */
358
+ export function populatesProcessEnv(config) {
359
+ const flags = config.compatibility_flags ?? [];
360
+ if (!flags.some((f) => f.startsWith("nodejs_compat")))
361
+ return false;
362
+ if (flags.includes("nodejs_compat_do_not_populate_process_env"))
363
+ return false;
364
+ if (flags.includes("nodejs_compat_populate_process_env"))
365
+ return true;
366
+ return (config.compatibility_date ?? "") >= "2025-04-01";
367
+ }
368
+ /** The text `vars` of a project, as `process.env` holds them. */
369
+ export function processEnvOf(config) {
370
+ const env = {};
371
+ for (const [k, v] of Object.entries(config.vars ?? {}))
372
+ if (typeof v === "string")
373
+ env[k] = v;
374
+ return env;
375
+ }
352
376
  //# sourceMappingURL=wrangler.js.map
@@ -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, type AssetsConfig, createAssets } from \"../bindings/assets.js\";\nimport { celldKv } from \"../bindings/celld-kv.js\";\nimport { celldQueues, type QueueConsumerConfig } from \"../bindings/celld-queues.js\";\nimport { celldWorkflows } from \"../bindings/celld-workflows.js\";\nimport { startCronTriggers } from \"../bindings/cron.js\";\nimport { r2Bucket, r2BucketOn } from \"../bindings/r2.js\";\nimport { celldR2Backend } from \"../bindings/r2-celld.js\";\nimport { type ModuleLoader, workerLoader } 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 { D1DatabaseObject, makeD1Binding } from \"../miniflare-compat/vendored.js\";\nimport { systemClock } from \"../ports.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 /** 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}\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 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<typeof celldKv> | undefined;\n if (config.kv_namespaces?.length) {\n kv = 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 = 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<typeof celldQueues> | undefined;\n if (config.queues?.producers?.length || consumers.size) {\n 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: ReturnType<typeof celldWorkflows> | undefined;\n if (config.workflows?.length) {\n 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 else\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 = 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 = createAssets(host.assetFiles ?? new Map(), config.assets, hasWorker);\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 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 for (const d1 of config.d1_databases ?? [])\n env[d1.binding] = celldExec(\n 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"]}
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, type AssetsConfig, createAssets } from \"../bindings/assets.js\";\nimport { celldKv } from \"../bindings/celld-kv.js\";\nimport { celldQueues, type QueueConsumerConfig } from \"../bindings/celld-queues.js\";\nimport { celldWorkflows } from \"../bindings/celld-workflows.js\";\nimport { startCronTriggers } from \"../bindings/cron.js\";\nimport { r2Bucket, r2BucketOn } from \"../bindings/r2.js\";\nimport { celldR2Backend } from \"../bindings/r2-celld.js\";\nimport { type ModuleLoader, workerLoader } 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 { D1DatabaseObject, makeD1Binding } from \"../miniflare-compat/vendored.js\";\nimport { systemClock } from \"../ports.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 /** 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}\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 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<typeof celldKv> | undefined;\n if (config.kv_namespaces?.length) {\n kv = 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 = 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<typeof celldQueues> | undefined;\n if (config.queues?.producers?.length || consumers.size) {\n 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: ReturnType<typeof celldWorkflows> | undefined;\n if (config.workflows?.length) {\n 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 else\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 = 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 = createAssets(host.assetFiles ?? new Map(), config.assets, hasWorker);\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 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 for (const d1 of config.d1_databases ?? [])\n env[d1.binding] = celldExec(\n 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 */\nexport function populatesProcessEnv(config: WranglerConfig): boolean {\n const flags = config.compatibility_flags ?? [];\n if (!flags.some((f) => f.startsWith(\"nodejs_compat\"))) 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"]}
@@ -10,6 +10,12 @@ export interface CellsHttpOptions {
10
10
  * upgrades cannot cross this link.
11
11
  */
12
12
  onUpgrade?: (id: string, port: MessagePort, protocol?: string) => void;
13
+ /**
14
+ * A stub.fetch answered 101 with a WebSocket, and the transport carries ports itself (a
15
+ * ServiceWorker's sockets): the 101, its `webSocket` included, is returned as it is, for the
16
+ * transport to hand the client end over.
17
+ */
18
+ passUpgrades?: boolean;
13
19
  }
14
20
  /** Server side: exposes a runtime as one HTTP handler. */
15
21
  export declare function errorResponse(e: unknown, status?: number): Response;
@@ -26,7 +26,7 @@ export function errorResponse(e, status = 500) {
26
26
  export function cellsHttpHandler(runtime, opts = {}) {
27
27
  const codec = opts.codec ?? v8Codec; // the runtime's default: V8 serialization
28
28
  return async (incoming) => {
29
- const req = await restoreScheme(incoming);
29
+ const req = await restoreScheme(await restoreRoute(incoming));
30
30
  const kind = req.headers.get(H.kind);
31
31
  if (!kind) {
32
32
  const cookie = req.headers.get(H.cookie);
@@ -59,6 +59,8 @@ export function cellsHttpHandler(runtime, opts = {}) {
59
59
  const res = (await stub.fetch(inner));
60
60
  if (res.status !== 101 || !res.webSocket)
61
61
  return res;
62
+ if (opts.passUpgrades && !wsId)
63
+ return res;
62
64
  if (!wsId || !opts.onUpgrade)
63
65
  throw new Error("WebSocket upgrade cannot cross this link (no control channel)");
64
66
  const protocol = res.headers.get("Sec-WebSocket-Protocol") ?? undefined;
@@ -106,6 +108,25 @@ export async function remoteRuntime(send, opts = {}) {
106
108
  env[binding] = new DurableObjectNamespace(keys?.[binding] ?? className, (id) => () => httpEndpoint(post, codec, binding, className, id));
107
109
  return { env, fetch: (req) => send(withScheme(req)) };
108
110
  }
111
+ /**
112
+ * The url the request was meant for, where a router changed it to route it: a call between
113
+ * shards carries its own (`H.url`), and with stripBase the router's prefix (`H.base`) comes off.
114
+ */
115
+ async function restoreRoute(req) {
116
+ const original = req.headers.get(H.url);
117
+ if (original !== null)
118
+ return keepUpgrade(req, await withUrl(req, new URL(original)));
119
+ const base = req.headers.get(H.base);
120
+ if (base === null)
121
+ return req;
122
+ const url = new URL(req.url);
123
+ if (!url.pathname.startsWith(base))
124
+ return req;
125
+ url.pathname = url.pathname.slice(base.length) || "/";
126
+ if (!url.pathname.startsWith("/"))
127
+ url.pathname = `/${url.pathname}`;
128
+ return keepUpgrade(req, await withUrl(req, url));
129
+ }
109
130
  async function restoreScheme(req) {
110
131
  const proto = req.headers.get(H.proto);
111
132
  if (!proto)
@@ -1 +1 @@
1
- {"version":3,"file":"cells-http.js","sourceRoot":"","sources":["../../src/transport/cells-http.ts"],"names":[],"mappings":"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","sourcesContent":["import { serializeError } from \"@statewalker/webrun-streams\";\nimport { toAnotherNode } from \"../core/handles.js\";\nimport { DurableObjectNamespace, type DurableObjectStub } from \"../core/namespace.js\";\nimport { withUrl } from \"../core/request-body.js\";\nimport type { CellRuntime } from \"../core/runtime.js\";\nimport type { ValueCodec } from \"../ports.js\";\nimport { v8Codec } from \"../v8/codec.js\";\nimport { type CfWebSocket, takeClientPort } from \"../ws/server.js\";\nimport { withHeaders, withUpgrade } from \"../ws/upgrade.js\";\nimport {\n control,\n H,\n httpEndpoint,\n keepUpgrade,\n postVia,\n type Send,\n withScheme,\n} from \"./cells-link.js\";\n\n/**\n * Everything a remote caller can do with a cell host is expressed as HTTP:\n * worker ingress, `stub.fetch()`, JS-RPC calls and the bindings descriptor.\n * The resulting `(Request) ⇒ Response` handler can then ride ANY webrun-wire\n * transport: a MessagePort (webrun-rpc), a WebSocket (webrun-streams-ws),\n * WebRTC / libp2p peers (httpeers) — via webrun-http-streams' Duplex seam.\n *\n * Control headers mark internal requests. TRUST MODEL: this handler is for an\n * internal link (page ⇄ worker, owner ⇄ forwarder). Public ingress must call\n * `runtime.fetch` directly, never this handler, or clients could address\n * objects without going through the Worker's own routing.\n */\nconst CT_VALUES = \"application/x-cellb-values\";\n\nexport interface CellsHttpOptions {\n codec?: ValueCodec;\n /**\n * A stub.fetch answered 101 with a WebSocket: hand the client end's port to the\n * caller out of band (the HTTP link cannot carry ports). Without it, WebSocket\n * upgrades cannot cross this link.\n */\n onUpgrade?: (id: string, port: MessagePort, protocol?: string) => void;\n}\n\n/** Server side: exposes a runtime as one HTTP handler. */\nexport function errorResponse(e: unknown, status = 500): Response {\n return Response.json(serializeError(e), { status, headers: { [H.kind]: \"error\" } });\n}\n\nexport function cellsHttpHandler(\n runtime: CellRuntime,\n opts: CellsHttpOptions = {},\n): (req: Request) => Promise<Response> {\n const codec = opts.codec ?? v8Codec; // the runtime's default: V8 serialization\n return async (incoming) => {\n const req = await restoreScheme(incoming);\n const kind = req.headers.get(H.kind);\n if (!kind) {\n const cookie = req.headers.get(H.cookie);\n if (cookie === null) return runtime.fetch(stripControl(req));\n // From a ServiceWorker: the cookies in, the Worker's Set-Cookie out, under H.cookie and\n // H.setCookie (a browser drops both headers from every Request and Response it builds).\n const inner = cookie ? withHeaders(stripControl(req), { cookie }) : stripControl(req);\n return tunnelSetCookies(await runtime.fetch(inner));\n }\n try {\n if (kind === \"describe\")\n return Response.json({\n bindings: runtime.durableObjectBindings,\n // The far side derives the same ids only with the same namespace keys.\n keys: Object.fromEntries(\n Object.keys(runtime.durableObjectBindings).map((b) => [\n b,\n (runtime.env[b] as { namespaceKey?: string }).namespaceKey,\n ]),\n ),\n });\n const stub = stubOf(\n runtime,\n req.headers.get(H.binding) ?? \"\",\n req.headers.get(H.target) ?? \"\",\n );\n if (kind === \"fetch\") {\n const wsId = req.headers.get(H.ws);\n let inner = stripControl(req);\n const upgrade = req.headers.get(H.upgrade);\n if (upgrade) {\n const offered = req.headers.get(H.wsProtocol);\n inner = withUpgrade(\n inner,\n upgrade,\n offered ? { \"Sec-WebSocket-Protocol\": offered } : undefined,\n );\n }\n const res = (await stub.fetch(inner)) as Response & { webSocket?: CfWebSocket | null };\n if (res.status !== 101 || !res.webSocket) return res;\n if (!wsId || !opts.onUpgrade)\n throw new Error(\"WebSocket upgrade cannot cross this link (no control channel)\");\n const protocol = res.headers.get(\"Sec-WebSocket-Protocol\") ?? undefined;\n opts.onUpgrade(wsId, takeClientPort(res.webSocket), protocol);\n return new Response(null, {\n status: 200,\n headers: {\n [H.wsAccepted]: wsId,\n ...(protocol ? { \"Sec-WebSocket-Protocol\": protocol } : {}),\n },\n });\n }\n if (kind === \"rpc\") {\n const args = codec.decode(new Uint8Array(await req.arrayBuffer())) as unknown[];\n const result = await stub[req.headers.get(H.method) ?? \"\"](...args);\n return new Response(codec.encode(toAnotherNode(result)) as BodyInit, {\n headers: { \"content-type\": CT_VALUES },\n });\n }\n throw new Error(`Unknown cellb request kind \"${kind}\"`);\n } catch (e) {\n return errorResponse(e);\n }\n };\n}\n\nfunction stubOf(runtime: CellRuntime, binding: string, target: string): DurableObjectStub {\n const ns = runtime.env[binding];\n if (!(ns instanceof DurableObjectNamespace))\n throw new Error(`Unknown Durable Object binding \"${binding}\"`);\n if (target.startsWith(\"name:\")) return ns.getByName(target.slice(5));\n if (target.startsWith(\"id:\")) return ns.get(ns.idFromString(target.slice(3)));\n throw new Error(`Invalid Durable Object target \"${target}\"`);\n}\n\nexport interface RemoteRuntime {\n /** Ingress into the remote Worker's default fetch handler. */\n fetch(req: Request): Promise<Response>;\n /** Namespaces whose stubs send HTTP over the link (idFromName computed locally). */\n readonly env: Record<string, DurableObjectNamespace>;\n}\n\n/** Client side over any `send` (fetchOverDuplex over a port / WebSocket / peer, or the handler itself). */\nexport async function remoteRuntime(\n send: Send,\n opts: CellsHttpOptions = {},\n): Promise<RemoteRuntime> {\n const codec = opts.codec ?? v8Codec; // the runtime's default: V8 serialization\n const post = postVia(send);\n const described = await post(control(\"describe\", {}));\n const { bindings, keys } = (await described.json()) as {\n bindings: Record<string, string>;\n keys?: Record<string, string>;\n };\n const env: Record<string, DurableObjectNamespace> = {};\n for (const [binding, className] of Object.entries(bindings))\n env[binding] = new DurableObjectNamespace(\n keys?.[binding] ?? className,\n (id) => () => httpEndpoint(post, codec, binding, className, id),\n );\n return { env, fetch: (req) => send(withScheme(req)) };\n}\n\nasync function restoreScheme(req: Request): Promise<Request> {\n const proto = req.headers.get(H.proto);\n if (!proto) return req;\n const url = new URL(req.url);\n if (url.protocol === `${proto}:`) return req;\n url.protocol = `${proto}:`;\n return keepUpgrade(req, await withUrl(req, url));\n}\n\n/** The Set-Cookie values of a response as one H.setCookie header (status 101 left as it is). */\nfunction tunnelSetCookies(res: Response): Response {\n const cookies = res.status === 101 ? [] : (res.headers.getSetCookie?.() ?? []);\n if (!cookies.length) return res;\n const headers = new Headers();\n for (const [k, v] of res.headers) if (k !== \"set-cookie\") headers.append(k, v);\n headers.set(H.setCookie, cookies.map(encodeURIComponent).join(\",\"));\n return new Response(res.body, { status: res.status, statusText: res.statusText, headers });\n}\n\nexport function stripControl(req: Request, keep: string[] = []): Request {\n const headers = new Headers(req.headers);\n let changed = false;\n for (const h of Object.values(H))\n if (headers.has(h) && !keep.includes(h)) headers.delete(h), (changed = true);\n if (!changed) return req;\n return keepUpgrade(req, new Request(req, { headers })); // keeps the body in Firefox too (addHeaders)\n}\n"]}
1
+ {"version":3,"file":"cells-http.js","sourceRoot":"","sources":["../../src/transport/cells-http.ts"],"names":[],"mappings":"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","sourcesContent":["import { serializeError } from \"@statewalker/webrun-streams\";\nimport { toAnotherNode } from \"../core/handles.js\";\nimport { DurableObjectNamespace, type DurableObjectStub } from \"../core/namespace.js\";\nimport { withUrl } from \"../core/request-body.js\";\nimport type { CellRuntime } from \"../core/runtime.js\";\nimport type { ValueCodec } from \"../ports.js\";\nimport { v8Codec } from \"../v8/codec.js\";\nimport { type CfWebSocket, takeClientPort } from \"../ws/server.js\";\nimport { withHeaders, withUpgrade } from \"../ws/upgrade.js\";\nimport {\n control,\n H,\n httpEndpoint,\n keepUpgrade,\n postVia,\n type Send,\n withScheme,\n} from \"./cells-link.js\";\n\n/**\n * Everything a remote caller can do with a cell host is expressed as HTTP:\n * worker ingress, `stub.fetch()`, JS-RPC calls and the bindings descriptor.\n * The resulting `(Request) ⇒ Response` handler can then ride ANY webrun-wire\n * transport: a MessagePort (webrun-rpc), a WebSocket (webrun-streams-ws),\n * WebRTC / libp2p peers (httpeers) — via webrun-http-streams' Duplex seam.\n *\n * Control headers mark internal requests. TRUST MODEL: this handler is for an\n * internal link (page ⇄ worker, owner ⇄ forwarder). Public ingress must call\n * `runtime.fetch` directly, never this handler, or clients could address\n * objects without going through the Worker's own routing.\n */\nconst CT_VALUES = \"application/x-cellb-values\";\n\nexport interface CellsHttpOptions {\n codec?: ValueCodec;\n /**\n * A stub.fetch answered 101 with a WebSocket: hand the client end's port to the\n * caller out of band (the HTTP link cannot carry ports). Without it, WebSocket\n * upgrades cannot cross this link.\n */\n onUpgrade?: (id: string, port: MessagePort, protocol?: string) => void;\n /**\n * A stub.fetch answered 101 with a WebSocket, and the transport carries ports itself (a\n * ServiceWorker's sockets): the 101, its `webSocket` included, is returned as it is, for the\n * transport to hand the client end over.\n */\n passUpgrades?: boolean;\n}\n\n/** Server side: exposes a runtime as one HTTP handler. */\nexport function errorResponse(e: unknown, status = 500): Response {\n return Response.json(serializeError(e), { status, headers: { [H.kind]: \"error\" } });\n}\n\nexport function cellsHttpHandler(\n runtime: CellRuntime,\n opts: CellsHttpOptions = {},\n): (req: Request) => Promise<Response> {\n const codec = opts.codec ?? v8Codec; // the runtime's default: V8 serialization\n return async (incoming) => {\n const req = await restoreScheme(await restoreRoute(incoming));\n const kind = req.headers.get(H.kind);\n if (!kind) {\n const cookie = req.headers.get(H.cookie);\n if (cookie === null) return runtime.fetch(stripControl(req));\n // From a ServiceWorker: the cookies in, the Worker's Set-Cookie out, under H.cookie and\n // H.setCookie (a browser drops both headers from every Request and Response it builds).\n const inner = cookie ? withHeaders(stripControl(req), { cookie }) : stripControl(req);\n return tunnelSetCookies(await runtime.fetch(inner));\n }\n try {\n if (kind === \"describe\")\n return Response.json({\n bindings: runtime.durableObjectBindings,\n // The far side derives the same ids only with the same namespace keys.\n keys: Object.fromEntries(\n Object.keys(runtime.durableObjectBindings).map((b) => [\n b,\n (runtime.env[b] as { namespaceKey?: string }).namespaceKey,\n ]),\n ),\n });\n const stub = stubOf(\n runtime,\n req.headers.get(H.binding) ?? \"\",\n req.headers.get(H.target) ?? \"\",\n );\n if (kind === \"fetch\") {\n const wsId = req.headers.get(H.ws);\n let inner = stripControl(req);\n const upgrade = req.headers.get(H.upgrade);\n if (upgrade) {\n const offered = req.headers.get(H.wsProtocol);\n inner = withUpgrade(\n inner,\n upgrade,\n offered ? { \"Sec-WebSocket-Protocol\": offered } : undefined,\n );\n }\n const res = (await stub.fetch(inner)) as Response & { webSocket?: CfWebSocket | null };\n if (res.status !== 101 || !res.webSocket) return res;\n if (opts.passUpgrades && !wsId) return res;\n if (!wsId || !opts.onUpgrade)\n throw new Error(\"WebSocket upgrade cannot cross this link (no control channel)\");\n const protocol = res.headers.get(\"Sec-WebSocket-Protocol\") ?? undefined;\n opts.onUpgrade(wsId, takeClientPort(res.webSocket), protocol);\n return new Response(null, {\n status: 200,\n headers: {\n [H.wsAccepted]: wsId,\n ...(protocol ? { \"Sec-WebSocket-Protocol\": protocol } : {}),\n },\n });\n }\n if (kind === \"rpc\") {\n const args = codec.decode(new Uint8Array(await req.arrayBuffer())) as unknown[];\n const result = await stub[req.headers.get(H.method) ?? \"\"](...args);\n return new Response(codec.encode(toAnotherNode(result)) as BodyInit, {\n headers: { \"content-type\": CT_VALUES },\n });\n }\n throw new Error(`Unknown cellb request kind \"${kind}\"`);\n } catch (e) {\n return errorResponse(e);\n }\n };\n}\n\nfunction stubOf(runtime: CellRuntime, binding: string, target: string): DurableObjectStub {\n const ns = runtime.env[binding];\n if (!(ns instanceof DurableObjectNamespace))\n throw new Error(`Unknown Durable Object binding \"${binding}\"`);\n if (target.startsWith(\"name:\")) return ns.getByName(target.slice(5));\n if (target.startsWith(\"id:\")) return ns.get(ns.idFromString(target.slice(3)));\n throw new Error(`Invalid Durable Object target \"${target}\"`);\n}\n\nexport interface RemoteRuntime {\n /** Ingress into the remote Worker's default fetch handler. */\n fetch(req: Request): Promise<Response>;\n /** Namespaces whose stubs send HTTP over the link (idFromName computed locally). */\n readonly env: Record<string, DurableObjectNamespace>;\n}\n\n/** Client side over any `send` (fetchOverDuplex over a port / WebSocket / peer, or the handler itself). */\nexport async function remoteRuntime(\n send: Send,\n opts: CellsHttpOptions = {},\n): Promise<RemoteRuntime> {\n const codec = opts.codec ?? v8Codec; // the runtime's default: V8 serialization\n const post = postVia(send);\n const described = await post(control(\"describe\", {}));\n const { bindings, keys } = (await described.json()) as {\n bindings: Record<string, string>;\n keys?: Record<string, string>;\n };\n const env: Record<string, DurableObjectNamespace> = {};\n for (const [binding, className] of Object.entries(bindings))\n env[binding] = new DurableObjectNamespace(\n keys?.[binding] ?? className,\n (id) => () => httpEndpoint(post, codec, binding, className, id),\n );\n return { env, fetch: (req) => send(withScheme(req)) };\n}\n\n/**\n * The url the request was meant for, where a router changed it to route it: a call between\n * shards carries its own (`H.url`), and with stripBase the router's prefix (`H.base`) comes off.\n */\nasync function restoreRoute(req: Request): Promise<Request> {\n const original = req.headers.get(H.url);\n if (original !== null) return keepUpgrade(req, await withUrl(req, new URL(original)));\n const base = req.headers.get(H.base);\n if (base === null) return req;\n const url = new URL(req.url);\n if (!url.pathname.startsWith(base)) return req;\n url.pathname = url.pathname.slice(base.length) || \"/\";\n if (!url.pathname.startsWith(\"/\")) url.pathname = `/${url.pathname}`;\n return keepUpgrade(req, await withUrl(req, url));\n}\n\nasync function restoreScheme(req: Request): Promise<Request> {\n const proto = req.headers.get(H.proto);\n if (!proto) return req;\n const url = new URL(req.url);\n if (url.protocol === `${proto}:`) return req;\n url.protocol = `${proto}:`;\n return keepUpgrade(req, await withUrl(req, url));\n}\n\n/** The Set-Cookie values of a response as one H.setCookie header (status 101 left as it is). */\nfunction tunnelSetCookies(res: Response): Response {\n const cookies = res.status === 101 ? [] : (res.headers.getSetCookie?.() ?? []);\n if (!cookies.length) return res;\n const headers = new Headers();\n for (const [k, v] of res.headers) if (k !== \"set-cookie\") headers.append(k, v);\n headers.set(H.setCookie, cookies.map(encodeURIComponent).join(\",\"));\n return new Response(res.body, { status: res.status, statusText: res.statusText, headers });\n}\n\nexport function stripControl(req: Request, keep: string[] = []): Request {\n const headers = new Headers(req.headers);\n let changed = false;\n for (const h of Object.values(H))\n if (headers.has(h) && !keep.includes(h)) headers.delete(h), (changed = true);\n if (!changed) return req;\n return keepUpgrade(req, new Request(req, { headers })); // keeps the body in Firefox too (addHeaders)\n}\n"]}
@@ -13,6 +13,8 @@ export declare const H: {
13
13
  readonly upgrade: "x-cellb-upgrade";
14
14
  readonly wsProtocol: "x-cellb-ws-protocol";
15
15
  readonly shard: "x-cellb-shard";
16
+ readonly url: "x-cellb-url";
17
+ readonly base: "x-cellb-base";
16
18
  readonly cookie: "x-cellb-cookie";
17
19
  readonly setCookie: "x-cellb-set-cookie";
18
20
  };
@@ -13,6 +13,11 @@ export const H = {
13
13
  upgrade: "x-cellb-upgrade", // `Upgrade` is hop-by-hop: dropped by the HTTP/1.1 wire, carried here
14
14
  wsProtocol: "x-cellb-ws-protocol", // `Sec-WebSocket-Protocol` is forbidden in browser Requests
15
15
  shard: "x-cellb-shard", // the shard that owns the target, as the sending shard computed it
16
+ // A call between shards through a ServiceWorker goes to `http://cellb.internal/<project>/`
17
+ // (the router's key for it): the url the caller asked for travels here.
18
+ url: "x-cellb-url",
19
+ // stripBase: the prefix the router keeps in the url (its key) for the Worker to cut off.
20
+ base: "x-cellb-base",
16
21
  // Ingress from a browser (a ServiceWorker): `Cookie` is forbidden in browser Requests and
17
22
  // `Set-Cookie` in browser Responses, so the page's cookies travel here, and the Worker's
18
23
  // Set-Cookie values come back URI-encoded and comma-separated (browser-cookies.ts).