@statewalker/cellb 0.5.2 → 0.7.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 (61) hide show
  1. package/README.md +40 -6
  2. package/dist/adapters/ltx-vfs.js +26 -4
  3. package/dist/adapters/ltx-vfs.js.map +1 -1
  4. package/dist/browser.d.ts +4 -0
  5. package/dist/browser.js +2 -0
  6. package/dist/browser.js.map +1 -1
  7. package/dist/bundle.d.ts +2 -0
  8. package/dist/bundle.js +5 -0
  9. package/dist/bundle.js.map +1 -0
  10. package/dist/core/object-host.d.ts +7 -0
  11. package/dist/core/object-host.js +40 -7
  12. package/dist/core/object-host.js.map +1 -1
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.js +1 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/ltx/files-rpc.d.ts +30 -0
  17. package/dist/ltx/files-rpc.js +129 -0
  18. package/dist/ltx/files-rpc.js.map +1 -0
  19. package/dist/ltx/ltx-host.d.ts +63 -0
  20. package/dist/ltx/ltx-host.js +46 -0
  21. package/dist/ltx/ltx-host.js.map +1 -0
  22. package/dist/ltx/ltx-page-server.d.ts +42 -1
  23. package/dist/ltx/ltx-page-server.js +101 -21
  24. package/dist/ltx/ltx-page-server.js.map +1 -1
  25. package/dist/ltx/ltx-pages.d.ts +5 -0
  26. package/dist/ltx/ltx-pages.js +32 -3
  27. package/dist/ltx/ltx-pages.js.map +1 -1
  28. package/dist/ltx/ltx-store-worker.js +35 -22
  29. package/dist/ltx/ltx-store-worker.js.map +1 -1
  30. package/dist/node-compat/browser-registry.d.ts +1 -0
  31. package/dist/node-compat/browser-registry.js +5 -0
  32. package/dist/node-compat/browser-registry.js.map +1 -1
  33. package/dist/node-compat/util-guard.d.ts +2 -0
  34. package/dist/node-compat/util-guard.js +14 -0
  35. package/dist/node-compat/util-guard.js.map +1 -0
  36. package/dist/project/browser-host.d.ts +32 -3
  37. package/dist/project/browser-host.js +47 -20
  38. package/dist/project/browser-host.js.map +1 -1
  39. package/dist/project/browser-load.d.ts +16 -4
  40. package/dist/project/browser-load.js +46 -9
  41. package/dist/project/browser-load.js.map +1 -1
  42. package/dist/project/build.js +2 -2
  43. package/dist/project/build.js.map +1 -1
  44. package/dist/project/bundle-compiler.d.ts +31 -0
  45. package/dist/project/bundle-compiler.js +73 -0
  46. package/dist/project/bundle-compiler.js.map +1 -0
  47. package/dist/project/node-project.js +3 -3
  48. package/dist/project/node-project.js.map +1 -1
  49. package/dist/project/site-compiler.d.ts +67 -0
  50. package/dist/project/site-compiler.js +134 -0
  51. package/dist/project/site-compiler.js.map +1 -0
  52. package/dist/project/source-project.d.ts +46 -0
  53. package/dist/project/source-project.js +45 -0
  54. package/dist/project/source-project.js.map +1 -0
  55. package/dist/project/wrangler.d.ts +4 -0
  56. package/dist/project/wrangler.js +7 -1
  57. package/dist/project/wrangler.js.map +1 -1
  58. package/dist/site.d.ts +2 -0
  59. package/dist/site.js +4 -3
  60. package/dist/site.js.map +1 -1
  61. package/package.json +11 -1
@@ -1,9 +1,11 @@
1
1
  /**
2
2
  * `loadProject` in a browser (`@statewalker/cellb/browser`), in a Dedicated Worker: fetches a
3
- * folder written by `cellb build` and runs it with `browserProjectRuntime`.
3
+ * folder written by `cellb build`, or compiles a source folder with the `compile` it is given,
4
+ * and runs it with `browserProjectRuntime`.
4
5
  */
5
6
  import { type BrowserBucket } from "./browser-host.js";
6
7
  import { type LoadedProject, type LoadProjectOptions, type ProjectSource } from "./built-project.js";
8
+ import { type ProjectCompiler } from "./source-project.js";
7
9
  export interface BrowserLoadProjectOptions extends LoadProjectOptions<BrowserBucket> {
8
10
  /**
9
11
  * Where loaded Workers (Worker Loader) run: the package's own isolate worker by default; a
@@ -11,12 +13,22 @@ export interface BrowserLoadProjectOptions extends LoadProjectOptions<BrowserBuc
11
13
  * realm.
12
14
  */
13
15
  isolateScript?: URL | (() => Worker) | false;
16
+ /**
17
+ * How a source folder (`wrangler.jsonc`, `main`, `package.json`, assets) becomes code, for a
18
+ * FilesApi that holds one: `bundleCompiler` (`@statewalker/cellb/bundle`: webrun-bundler and
19
+ * esbuild-wasm, one ES module) or `siteCompiler` (`@statewalker/cellb/site`: modules compiled
20
+ * one by one and served from a ServiceWorker). Without it, only `cellb build` folders load.
21
+ * A folder written by `cellb build` loads as built either way.
22
+ */
23
+ compile?: ProjectCompiler;
14
24
  }
15
25
  /**
16
- * Loads a built project and runs it in this worker.
26
+ * Loads a project and runs it in this worker.
17
27
  *
18
28
  * `source`: the URL of a `cellb build` folder (relative URLs resolve against the page or
19
- * worker), or a FilesApi holding one. `options.data` names the OPFS pool (`<data>`) and the
20
- * project's files directory (`<data>-files`); it defaults to the project's `name`.
29
+ * worker), or a FilesApi holding one — or, with `options.compile`, a FilesApi holding the
30
+ * project's sources (`wrangler.jsonc` and `main` at its root, `package.json`, assets).
31
+ * `options.data` names the OPFS pool (`<data>`) and the project's files directory
32
+ * (`<data>-files`); it defaults to the project's `name`.
21
33
  */
22
34
  export declare function loadProject(source: ProjectSource, options?: BrowserLoadProjectOptions): Promise<LoadedProject>;
@@ -1,17 +1,21 @@
1
1
  /**
2
2
  * `loadProject` in a browser (`@statewalker/cellb/browser`), in a Dedicated Worker: fetches a
3
- * folder written by `cellb build` and runs it with `browserProjectRuntime`.
3
+ * folder written by `cellb build`, or compiles a source folder with the `compile` it is given,
4
+ * and runs it with `browserProjectRuntime`.
4
5
  */
5
6
  import { browserProjectRuntime } from "./browser-host.js";
6
7
  import { BUILD_MANIFEST, filesApiReader, isFilesApi, readBuildManifest, readBuiltProject, urlReader, } from "./built-project.js";
8
+ import { hasNodeCompat, readSourceProject, WRANGLER_FILES, } from "./source-project.js";
7
9
  /** The isolate worker this package ships (bundlers follow the `new Worker(new URL(…))` form). */
8
10
  const ownIsolate = () => new Worker(new URL("../isolate/isolate-worker.js", import.meta.url), { type: "module" });
9
11
  /**
10
- * Loads a built project and runs it in this worker.
12
+ * Loads a project and runs it in this worker.
11
13
  *
12
14
  * `source`: the URL of a `cellb build` folder (relative URLs resolve against the page or
13
- * worker), or a FilesApi holding one. `options.data` names the OPFS pool (`<data>`) and the
14
- * project's files directory (`<data>-files`); it defaults to the project's `name`.
15
+ * worker), or a FilesApi holding one — or, with `options.compile`, a FilesApi holding the
16
+ * project's sources (`wrangler.jsonc` and `main` at its root, `package.json`, assets).
17
+ * `options.data` names the OPFS pool (`<data>`) and the project's files directory
18
+ * (`<data>-files`); it defaults to the project's `name`.
15
19
  */
16
20
  export async function loadProject(source, options = {}) {
17
21
  let reader;
@@ -28,15 +32,41 @@ export async function loadProject(source, options = {}) {
28
32
  where = url.href;
29
33
  }
30
34
  const manifest = await readBuildManifest(reader);
31
- if (!manifest)
32
- throw new Error(`${where} has no ${BUILD_MANIFEST}: browsers load folders written by \`cellb build\``);
33
- const built = await readBuiltProject(reader, manifest);
35
+ let built;
36
+ let compiled;
37
+ if (manifest)
38
+ built = await readBuiltProject(reader, manifest);
39
+ else if (isFilesApi(source) && options.compile) {
40
+ const project = await readSourceProject(source);
41
+ if (!project)
42
+ throw new Error(`the FilesApi has neither ${BUILD_MANIFEST} nor ${WRANGLER_FILES.join(" nor ")}`);
43
+ const { config } = project;
44
+ compiled = config.main
45
+ ? await options.compile.compile({ files: source, config, nodeCompat: hasNodeCompat(config) })
46
+ : { code: { bundle: null } };
47
+ built = { config, code: null, assets: project.assets ?? new Map() };
48
+ }
49
+ else
50
+ throw new Error(isFilesApi(source)
51
+ ? `${where} has no ${BUILD_MANIFEST}: pass \`compile\` to load a source folder, or load a folder written by \`cellb build\``
52
+ : `${where} has no ${BUILD_MANIFEST}: browsers load folders written by \`cellb build\` by URL (a source folder loads from a FilesApi, with \`compile\`)`);
53
+ try {
54
+ const close = compiled?.close?.bind(compiled);
55
+ const release = close && (() => close());
56
+ return await run(built, compiled?.code ?? { bundle: built.code }, options, release);
57
+ }
58
+ catch (err) {
59
+ await compiled?.close?.().catch(() => { });
60
+ throw err;
61
+ }
62
+ }
63
+ async function run(built, code, options, release) {
34
64
  const data = options.data ?? built.config.name ?? "cellb";
35
65
  const sqlite3 = options.sqlite3 ?? (await defaultSqlite3());
36
66
  const isolateScript = options.isolateScript === false ? undefined : (options.isolateScript ?? ownIsolate);
37
67
  const project = await browserProjectRuntime({
38
68
  config: built.config,
39
- code: { bundle: built.code },
69
+ code,
40
70
  assetFiles: built.assets,
41
71
  sqlite3,
42
72
  pool: data,
@@ -51,7 +81,14 @@ export async function loadProject(source, options = {}) {
51
81
  runtime,
52
82
  unsupported: project.unsupported,
53
83
  fetch: (req) => runtime.fetch(req),
54
- close: project.close,
84
+ close: async () => {
85
+ try {
86
+ await project.close();
87
+ }
88
+ finally {
89
+ await release?.();
90
+ }
91
+ },
55
92
  };
56
93
  }
57
94
  let sqlite3Module;
@@ -1 +1 @@
1
- {"version":3,"file":"browser-load.js","sourceRoot":"","sources":["../../src/project/browser-load.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loadProject` in a browser (`@statewalker/cellb/browser`), in a Dedicated Worker: fetches a\n * folder written by `cellb build` and runs it with `browserProjectRuntime`.\n */\n\nimport { type BrowserBucket, browserProjectRuntime } from \"./browser-host.js\";\nimport {\n BUILD_MANIFEST,\n filesApiReader,\n isFilesApi,\n type LoadedProject,\n type LoadProjectOptions,\n type ProjectSource,\n readBuildManifest,\n readBuiltProject,\n urlReader,\n} from \"./built-project.js\";\n\nexport interface BrowserLoadProjectOptions extends LoadProjectOptions<BrowserBucket> {\n /**\n * Where loaded Workers (Worker Loader) run: the package's own isolate worker by default; a\n * script URL or a function starting a Dedicated Worker instead; `false` to run them in this\n * realm.\n */\n isolateScript?: URL | (() => Worker) | false;\n}\n\n/** The isolate worker this package ships (bundlers follow the `new Worker(new URL(…))` form). */\nconst ownIsolate = () =>\n new Worker(new URL(\"../isolate/isolate-worker.ts\", import.meta.url), { type: \"module\" });\n\n/**\n * Loads a built project and runs it in this worker.\n *\n * `source`: the URL of a `cellb build` folder (relative URLs resolve against the page or\n * worker), or a FilesApi holding one. `options.data` names the OPFS pool (`<data>`) and the\n * project's files directory (`<data>-files`); it defaults to the project's `name`.\n */\nexport async function loadProject(\n source: ProjectSource,\n options: BrowserLoadProjectOptions = {},\n): Promise<LoadedProject> {\n let reader: ReturnType<typeof urlReader>;\n let where: string;\n if (isFilesApi(source)) {\n reader = filesApiReader(source);\n where = \"the FilesApi\";\n } else {\n const url = new URL(String(source), (globalThis as { location?: Location }).location?.href);\n if (!url.pathname.endsWith(\"/\")) url.pathname += \"/\";\n reader = urlReader(url);\n where = url.href;\n }\n const manifest = await readBuildManifest(reader);\n if (!manifest)\n throw new Error(\n `${where} has no ${BUILD_MANIFEST}: browsers load folders written by \\`cellb build\\``,\n );\n const built = await readBuiltProject(reader, manifest);\n const data = options.data ?? built.config.name ?? \"cellb\";\n const sqlite3 = options.sqlite3 ?? (await defaultSqlite3());\n const isolateScript =\n options.isolateScript === false ? undefined : (options.isolateScript ?? ownIsolate);\n const project = await browserProjectRuntime({\n config: built.config,\n code: { bundle: built.code },\n assetFiles: built.assets,\n sqlite3,\n pool: data,\n filesDir: `${data}-files`,\n bucket: options.bucket,\n ai: options.ai,\n isolateScript,\n });\n const { runtime } = project;\n return {\n config: built.config,\n runtime,\n unsupported: project.unsupported,\n fetch: (req) => runtime.fetch(req),\n close: project.close,\n };\n}\n\nlet sqlite3Module: Promise<unknown> | undefined;\n/** `@sqlite.org/sqlite-wasm`, initialized once per worker. */\nfunction defaultSqlite3(): Promise<unknown> {\n sqlite3Module ??= import(\"@sqlite.org/sqlite-wasm\").then(({ default: init }) =>\n (init as (o: object) => Promise<unknown>)({ print() {}, printErr() {} }),\n );\n return sqlite3Module;\n}\n"]}
1
+ {"version":3,"file":"browser-load.js","sourceRoot":"","sources":["../../src/project/browser-load.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `loadProject` in a browser (`@statewalker/cellb/browser`), in a Dedicated Worker: fetches a\n * folder written by `cellb build`, or compiles a source folder with the `compile` it is given,\n * and runs it with `browserProjectRuntime`.\n */\n\nimport { type BrowserBucket, browserProjectRuntime } from \"./browser-host.js\";\nimport {\n BUILD_MANIFEST,\n type BuiltProject,\n filesApiReader,\n isFilesApi,\n type LoadedProject,\n type LoadProjectOptions,\n type ProjectSource,\n readBuildManifest,\n readBuiltProject,\n urlReader,\n} from \"./built-project.js\";\nimport {\n type CompiledProject,\n hasNodeCompat,\n type ProjectCompiler,\n readSourceProject,\n WRANGLER_FILES,\n} from \"./source-project.js\";\n\nexport interface BrowserLoadProjectOptions extends LoadProjectOptions<BrowserBucket> {\n /**\n * Where loaded Workers (Worker Loader) run: the package's own isolate worker by default; a\n * script URL or a function starting a Dedicated Worker instead; `false` to run them in this\n * realm.\n */\n isolateScript?: URL | (() => Worker) | false;\n /**\n * How a source folder (`wrangler.jsonc`, `main`, `package.json`, assets) becomes code, for a\n * FilesApi that holds one: `bundleCompiler` (`@statewalker/cellb/bundle`: webrun-bundler and\n * esbuild-wasm, one ES module) or `siteCompiler` (`@statewalker/cellb/site`: modules compiled\n * one by one and served from a ServiceWorker). Without it, only `cellb build` folders load.\n * A folder written by `cellb build` loads as built either way.\n */\n compile?: ProjectCompiler;\n}\n\n/** The isolate worker this package ships (bundlers follow the `new Worker(new URL(…))` form). */\nconst ownIsolate = () =>\n new Worker(new URL(\"../isolate/isolate-worker.ts\", import.meta.url), { type: \"module\" });\n\n/**\n * Loads a project and runs it in this worker.\n *\n * `source`: the URL of a `cellb build` folder (relative URLs resolve against the page or\n * worker), or a FilesApi holding one — or, with `options.compile`, a FilesApi holding the\n * project's sources (`wrangler.jsonc` and `main` at its root, `package.json`, assets).\n * `options.data` names the OPFS pool (`<data>`) and the project's files directory\n * (`<data>-files`); it defaults to the project's `name`.\n */\nexport async function loadProject(\n source: ProjectSource,\n options: BrowserLoadProjectOptions = {},\n): Promise<LoadedProject> {\n let reader: ReturnType<typeof urlReader>;\n let where: string;\n if (isFilesApi(source)) {\n reader = filesApiReader(source);\n where = \"the FilesApi\";\n } else {\n const url = new URL(String(source), (globalThis as { location?: Location }).location?.href);\n if (!url.pathname.endsWith(\"/\")) url.pathname += \"/\";\n reader = urlReader(url);\n where = url.href;\n }\n const manifest = await readBuildManifest(reader);\n let built: BuiltProject;\n let compiled: CompiledProject | undefined;\n if (manifest) built = await readBuiltProject(reader, manifest);\n else if (isFilesApi(source) && options.compile) {\n const project = await readSourceProject(source);\n if (!project)\n throw new Error(\n `the FilesApi has neither ${BUILD_MANIFEST} nor ${WRANGLER_FILES.join(\" nor \")}`,\n );\n const { config } = project;\n compiled = config.main\n ? await options.compile.compile({ files: source, config, nodeCompat: hasNodeCompat(config) })\n : { code: { bundle: null } };\n built = { config, code: null, assets: project.assets ?? new Map() };\n } else\n throw new Error(\n isFilesApi(source)\n ? `${where} has no ${BUILD_MANIFEST}: pass \\`compile\\` to load a source folder, or load a folder written by \\`cellb build\\``\n : `${where} has no ${BUILD_MANIFEST}: browsers load folders written by \\`cellb build\\` by URL (a source folder loads from a FilesApi, with \\`compile\\`)`,\n );\n try {\n const close = compiled?.close?.bind(compiled);\n const release = close && (() => close());\n return await run(built, compiled?.code ?? { bundle: built.code }, options, release);\n } catch (err) {\n await compiled?.close?.().catch(() => {});\n throw err;\n }\n}\n\nasync function run(\n built: BuiltProject,\n code: CompiledProject[\"code\"],\n options: BrowserLoadProjectOptions,\n release?: () => Promise<void>,\n): Promise<LoadedProject> {\n const data = options.data ?? built.config.name ?? \"cellb\";\n const sqlite3 = options.sqlite3 ?? (await defaultSqlite3());\n const isolateScript =\n options.isolateScript === false ? undefined : (options.isolateScript ?? ownIsolate);\n const project = await browserProjectRuntime({\n config: built.config,\n code,\n assetFiles: built.assets,\n sqlite3,\n pool: data,\n filesDir: `${data}-files`,\n bucket: options.bucket,\n ai: options.ai,\n isolateScript,\n });\n const { runtime } = project;\n return {\n config: built.config,\n runtime,\n unsupported: project.unsupported,\n fetch: (req) => runtime.fetch(req),\n close: async () => {\n try {\n await project.close();\n } finally {\n await release?.();\n }\n },\n };\n}\n\nlet sqlite3Module: Promise<unknown> | undefined;\n/** `@sqlite.org/sqlite-wasm`, initialized once per worker. */\nfunction defaultSqlite3(): Promise<unknown> {\n sqlite3Module ??= import(\"@sqlite.org/sqlite-wasm\").then(({ default: init }) =>\n (init as (o: object) => Promise<unknown>)({ print() {}, printErr() {} }),\n );\n return sqlite3Module;\n}\n"]}
@@ -7,6 +7,7 @@ import { dirname, join, resolve } from "node:path";
7
7
  import { bundleWorkerForBrowser } from "./browser-bundle.js";
8
8
  import { BUILD_FORMAT, BUILD_MANIFEST, BUILT_ASSETS, BUILT_WORKER, builtConfig, } from "./built-project.js";
9
9
  import { readAssetDirectory, readWranglerConfig } from "./node-project.js";
10
+ import { hasNodeCompat } from "./wrangler.js";
10
11
  /**
11
12
  * `cellb build`: writes the project in `dir` as a folder any static host serves and
12
13
  * `loadProject` (browser or Node) loads: `wrangler.json`, `worker.js` (`main` bundled for a
@@ -18,8 +19,7 @@ export async function buildProject(dir, outDir, opts = {}) {
18
19
  const config = readWranglerConfig(dir);
19
20
  if (!config.main && !config.assets)
20
21
  throw new Error("wrangler config has neither `main` nor `assets`");
21
- const flags = config.compatibility_flags ?? [];
22
- const nodeCompat = flags.some((f) => f.startsWith("nodejs_compat"));
22
+ const nodeCompat = hasNodeCompat(config);
23
23
  const code = config.main
24
24
  ? await bundleWorkerForBrowser(resolve(dir, config.main), {
25
25
  nodeCompat,
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/project/build.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `buildProject` (`cellb build`): the build step whose output folder `loadProject` loads, in a\n * browser or on Node. Imports no SQLite: the command stays quiet and light.\n */\nimport { mkdirSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { bundleWorkerForBrowser } from \"./browser-bundle.js\";\nimport {\n BUILD_FORMAT,\n BUILD_MANIFEST,\n BUILT_ASSETS,\n BUILT_WORKER,\n type BuildManifest,\n builtConfig,\n} from \"./built-project.js\";\nimport { readAssetDirectory, readWranglerConfig } from \"./node-project.js\";\n\nexport interface BuildProjectOptions {\n /**\n * Lower `await` to generators (default: with nodejs_compat), as `bundleWorkerForBrowser`;\n * `false` for browsers with TC39 AsyncContext only.\n */\n lowerAwait?: boolean;\n}\n\n/**\n * `cellb build`: writes the project in `dir` as a folder any static host serves and\n * `loadProject` (browser or Node) loads: `wrangler.json`, `worker.js` (`main` bundled for a\n * browser realm, with nodejs_compat when the flags ask for it), `assets/` and `cellb.json`.\n */\nexport async function buildProject(\n dir: string,\n outDir: string,\n opts: BuildProjectOptions = {},\n): Promise<BuildManifest> {\n dir = resolve(dir);\n outDir = resolve(outDir);\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 = flags.some((f) => f.startsWith(\"nodejs_compat\"));\n const code = config.main\n ? await bundleWorkerForBrowser(resolve(dir, config.main), {\n nodeCompat,\n lowerAwait: opts.lowerAwait,\n })\n : null;\n const assets = config.assets?.directory\n ? readAssetDirectory(resolve(dir, config.assets.directory))\n : new Map<string, Uint8Array>();\n // A fresh folder: files of an earlier build must not linger as assets.\n for (const name of [BUILD_MANIFEST, \"wrangler.json\", BUILT_WORKER, BUILT_ASSETS])\n rmSync(join(outDir, name), { recursive: true, force: true });\n mkdirSync(outDir, { recursive: true });\n writeFileSync(join(outDir, \"wrangler.json\"), `${JSON.stringify(builtConfig(config), null, 2)}\\n`);\n if (code !== null) writeFileSync(join(outDir, BUILT_WORKER), code);\n for (const [path, bytes] of assets) {\n const out = join(outDir, BUILT_ASSETS, path);\n mkdirSync(dirname(out), { recursive: true });\n writeFileSync(out, bytes);\n }\n const manifest: BuildManifest = {\n format: BUILD_FORMAT,\n main: code !== null ? BUILT_WORKER : null,\n assets: [...assets.keys()].sort(),\n };\n // Written last: a folder with a manifest is a complete build.\n writeFileSync(join(outDir, BUILD_MANIFEST), `${JSON.stringify(manifest, null, 2)}\\n`);\n return manifest;\n}\n"]}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/project/build.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,YAAY,EAEZ,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAU9C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAW,EACX,MAAc,EACd,IAAI,GAAwB,EAAE;IAE9B,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACnB,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM;QAChC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI;QACtB,CAAC,CAAC,MAAM,sBAAsB,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE;YACtD,UAAU;YACV,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC;QACJ,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS;QACrC,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3D,CAAC,CAAC,IAAI,GAAG,EAAsB,CAAC;IAClC,uEAAuE;IACvE,KAAK,MAAM,IAAI,IAAI,CAAC,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,CAAC;QAC9E,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAClG,IAAI,IAAI,KAAK,IAAI;QAAE,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,IAAI,CAAC,CAAC;IACnE,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;QAC7C,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IACD,MAAM,QAAQ,GAAkB;QAC9B,MAAM,EAAE,YAAY;QACpB,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI;QACzC,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;KAClC,CAAC;IACF,8DAA8D;IAC9D,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACtF,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["/**\n * `buildProject` (`cellb build`): the build step whose output folder `loadProject` loads, in a\n * browser or on Node. Imports no SQLite: the command stays quiet and light.\n */\nimport { mkdirSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { bundleWorkerForBrowser } from \"./browser-bundle.js\";\nimport {\n BUILD_FORMAT,\n BUILD_MANIFEST,\n BUILT_ASSETS,\n BUILT_WORKER,\n type BuildManifest,\n builtConfig,\n} from \"./built-project.js\";\nimport { readAssetDirectory, readWranglerConfig } from \"./node-project.js\";\nimport { hasNodeCompat } from \"./wrangler.js\";\n\nexport interface BuildProjectOptions {\n /**\n * Lower `await` to generators (default: with nodejs_compat), as `bundleWorkerForBrowser`;\n * `false` for browsers with TC39 AsyncContext only.\n */\n lowerAwait?: boolean;\n}\n\n/**\n * `cellb build`: writes the project in `dir` as a folder any static host serves and\n * `loadProject` (browser or Node) loads: `wrangler.json`, `worker.js` (`main` bundled for a\n * browser realm, with nodejs_compat when the flags ask for it), `assets/` and `cellb.json`.\n */\nexport async function buildProject(\n dir: string,\n outDir: string,\n opts: BuildProjectOptions = {},\n): Promise<BuildManifest> {\n dir = resolve(dir);\n outDir = resolve(outDir);\n const config = readWranglerConfig(dir);\n if (!config.main && !config.assets)\n throw new Error(\"wrangler config has neither `main` nor `assets`\");\n const nodeCompat = hasNodeCompat(config);\n const code = config.main\n ? await bundleWorkerForBrowser(resolve(dir, config.main), {\n nodeCompat,\n lowerAwait: opts.lowerAwait,\n })\n : null;\n const assets = config.assets?.directory\n ? readAssetDirectory(resolve(dir, config.assets.directory))\n : new Map<string, Uint8Array>();\n // A fresh folder: files of an earlier build must not linger as assets.\n for (const name of [BUILD_MANIFEST, \"wrangler.json\", BUILT_WORKER, BUILT_ASSETS])\n rmSync(join(outDir, name), { recursive: true, force: true });\n mkdirSync(outDir, { recursive: true });\n writeFileSync(join(outDir, \"wrangler.json\"), `${JSON.stringify(builtConfig(config), null, 2)}\\n`);\n if (code !== null) writeFileSync(join(outDir, BUILT_WORKER), code);\n for (const [path, bytes] of assets) {\n const out = join(outDir, BUILT_ASSETS, path);\n mkdirSync(dirname(out), { recursive: true });\n writeFileSync(out, bytes);\n }\n const manifest: BuildManifest = {\n format: BUILD_FORMAT,\n main: code !== null ? BUILT_WORKER : null,\n assets: [...assets.keys()].sort(),\n };\n // Written last: a folder with a manifest is a complete build.\n writeFileSync(join(outDir, BUILD_MANIFEST), `${JSON.stringify(manifest, null, 2)}\\n`);\n return manifest;\n}\n"]}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `bundleCompiler`: a project's sources bundled in the browser by webrun-bundler on esbuild-wasm,
3
+ * into one ES module that `browserProjectRuntime({ code: { bundle } })` runs as it runs a built
4
+ * folder's `worker.js`. npm packages come from the project's `node_modules` (in its FilesApi) or
5
+ * the npm registry, at the versions its `package.json` asks for.
6
+ */
7
+ import { type BundleOptions, type PackageStore } from "@statewalker/webrun-bundler";
8
+ import type { ProjectCompiler } from "./source-project.js";
9
+ export interface BundleCompilerOptions {
10
+ /** esbuild-wasm, initialized (`await esbuild.initialize({ wasmURL })`). */
11
+ esbuild: BundleOptions["esbuild"];
12
+ /**
13
+ * Where bare specifiers go. Default: the project's own `node_modules`, then the npm registry.
14
+ * Keep one store for several compiles (`npmPackages()`) and a second build fetches nothing.
15
+ */
16
+ packages?: PackageStore;
17
+ /**
18
+ * Lower `await` to generators, so that AsyncLocalStorage stores follow them (the
19
+ * node:async_hooks polyfill rides on promise continuations). Default: with nodejs_compat, as
20
+ * `cellb build` does; a lowered bundle runs on engines with AsyncContext too.
21
+ */
22
+ lowerAwait?: boolean;
23
+ /** `package.json` `exports` conditions (default: workerd's, `["workerd", "worker", "browser"]`). */
24
+ conditions?: string[];
25
+ }
26
+ /**
27
+ * A compiler for `loadProject(files, { compile })` that bundles `main` and its packages into one
28
+ * ES module. `cloudflare:workers`, `node:*` (nodejs_compat) and the Workers globals come from
29
+ * the runtime (`cellbHostModule`), as in a folder `cellb build` writes.
30
+ */
31
+ export declare function bundleCompiler(options: BundleCompilerOptions): ProjectCompiler;
@@ -0,0 +1,73 @@
1
+ /**
2
+ * `bundleCompiler`: a project's sources bundled in the browser by webrun-bundler on esbuild-wasm,
3
+ * into one ES module that `browserProjectRuntime({ code: { bundle } })` runs as it runs a built
4
+ * folder's `worker.js`. npm packages come from the project's `node_modules` (in its FilesApi) or
5
+ * the npm registry, at the versions its `package.json` asks for.
6
+ */
7
+ import { bundle, chainPackages, nodeModulesPackages, npmPackages, } from "@statewalker/webrun-bundler";
8
+ import { CELLS_GLOBALS_MODULE, cellbHostModule } from "./host-modules.js";
9
+ /** One store per compiler: a second compile of the same project fetches nothing. */
10
+ function defaultPackages() {
11
+ return chainPackages(nodeModulesPackages(), npmPackages());
12
+ }
13
+ /**
14
+ * A compiler for `loadProject(files, { compile })` that bundles `main` and its packages into one
15
+ * ES module. `cloudflare:workers`, `node:*` (nodejs_compat) and the Workers globals come from
16
+ * the runtime (`cellbHostModule`), as in a folder `cellb build` writes.
17
+ */
18
+ export function bundleCompiler(options) {
19
+ const packages = options.packages ?? defaultPackages();
20
+ return {
21
+ kind: "bundle",
22
+ async compile({ files, config, nodeCompat }) {
23
+ if (!config.main)
24
+ return { code: { bundle: null } };
25
+ // `node:*` only with nodejs_compat, which also takes a bare built-in name ("buffer") as one
26
+ // when cellb has a polyfill for it. A `node:*` module without one is a stub that throws when
27
+ // used, as `cellb build` and wrangler's nodejs_compat do (libraries import such modules in
28
+ // code paths a Worker never takes).
29
+ const modules = (spec) => spec.startsWith("node:")
30
+ ? nodeCompat
31
+ ? (cellbHostModule(spec) ?? nodeStub(spec))
32
+ : undefined
33
+ : (cellbHostModule(spec) ??
34
+ (nodeCompat && !spec.includes(":") ? cellbHostModule(`node:${spec}`) : undefined));
35
+ const { code } = await bundle({
36
+ esbuild: options.esbuild,
37
+ files,
38
+ entry: `/${config.main.replace(/^\.?\/+/, "")}`,
39
+ packages,
40
+ modules,
41
+ inject: [CELLS_GLOBALS_MODULE], // Response, WebSocketPair… of the runtime, not the realm's
42
+ conditions: options.conditions ?? ["workerd", "worker", "browser"],
43
+ lowerAwait: options.lowerAwait ?? nodeCompat,
44
+ sourcemap: false,
45
+ // Function names are observable (the npm assert polyfill reports its caller's name as
46
+ // the operator): bundling must not rename them, as in `cellb build`.
47
+ esbuildOptions: { keepNames: true },
48
+ });
49
+ return { code: { bundle: code } };
50
+ },
51
+ };
52
+ }
53
+ /**
54
+ * A Node.js module with no browser polyfill: CommonJS, so that every import links. Its default
55
+ * export answers any member with a function that throws when called (or extended). A named import
56
+ * is undefined (esbuild copies the members of a CommonJS module, and a stub cannot list them), so
57
+ * it fails when used, not when loaded. `cellb build` lists the members from Node itself; a browser
58
+ * cannot.
59
+ */
60
+ function nodeStub(spec) {
61
+ const what = JSON.stringify(spec);
62
+ return [
63
+ `const fail = (key) => { throw new Error(${what} + "." + key + " is not available in browsers (nodejs_compat)"); };`,
64
+ "module.exports = new Proxy(Object.create(null), {",
65
+ " get(target, key) {",
66
+ ' if (typeof key === "symbol" || key === "then" || key === "__esModule") return undefined;',
67
+ " if (!(key in target)) target[key] = function () { fail(String(key)); };",
68
+ " return target[key];",
69
+ " },",
70
+ "});",
71
+ ].join("\n");
72
+ }
73
+ //# sourceMappingURL=bundle-compiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-compiler.js","sourceRoot":"","sources":["../../src/project/bundle-compiler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAEL,MAAM,EACN,aAAa,EACb,mBAAmB,EACnB,WAAW,GAEZ,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAqB1E,oFAAoF;AACpF,SAAS,eAAe;IACtB,OAAO,aAAa,CAAC,mBAAmB,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAA8B;IAC3D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,eAAe,EAAE,CAAC;IACvD,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE;YACzC,IAAI,CAAC,MAAM,CAAC,IAAI;gBAAE,OAAO,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;YACpD,4FAA4F;YAC5F,6FAA6F;YAC7F,2FAA2F;YAC3F,oCAAoC;YACpC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAC/B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBACtB,CAAC,CAAC,UAAU;oBACV,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;oBAC3C,CAAC,CAAC,SAAS;gBACb,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC;oBACtB,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YACzF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC;gBAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,KAAK;gBACL,KAAK,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE;gBAC/C,QAAQ;gBACR,OAAO;gBACP,MAAM,EAAE,CAAC,oBAAoB,CAAC,EAAE,2DAA2D;gBAC3F,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;gBAClE,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,UAAU;gBAC5C,SAAS,EAAE,KAAK;gBAChB,sFAAsF;gBACtF,qEAAqE;gBACrE,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;aACpC,CAAC,CAAC;YACH,OAAO,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;QACpC,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC,OAAO;QACL,2CAA2C,IAAI,qEAAqE;QACpH,mDAAmD;QACnD,sBAAsB;QACtB,8FAA8F;QAC9F,6EAA6E;QAC7E,yBAAyB;QACzB,MAAM;QACN,KAAK;KACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC","sourcesContent":["/**\n * `bundleCompiler`: a project's sources bundled in the browser by webrun-bundler on esbuild-wasm,\n * into one ES module that `browserProjectRuntime({ code: { bundle } })` runs as it runs a built\n * folder's `worker.js`. npm packages come from the project's `node_modules` (in its FilesApi) or\n * the npm registry, at the versions its `package.json` asks for.\n */\nimport {\n type BundleOptions,\n bundle,\n chainPackages,\n nodeModulesPackages,\n npmPackages,\n type PackageStore,\n} from \"@statewalker/webrun-bundler\";\nimport { CELLS_GLOBALS_MODULE, cellbHostModule } from \"./host-modules.js\";\nimport type { ProjectCompiler } from \"./source-project.js\";\n\nexport interface BundleCompilerOptions {\n /** esbuild-wasm, initialized (`await esbuild.initialize({ wasmURL })`). */\n esbuild: BundleOptions[\"esbuild\"];\n /**\n * Where bare specifiers go. Default: the project's own `node_modules`, then the npm registry.\n * Keep one store for several compiles (`npmPackages()`) and a second build fetches nothing.\n */\n packages?: PackageStore;\n /**\n * Lower `await` to generators, so that AsyncLocalStorage stores follow them (the\n * node:async_hooks polyfill rides on promise continuations). Default: with nodejs_compat, as\n * `cellb build` does; a lowered bundle runs on engines with AsyncContext too.\n */\n lowerAwait?: boolean;\n /** `package.json` `exports` conditions (default: workerd's, `[\"workerd\", \"worker\", \"browser\"]`). */\n conditions?: string[];\n}\n\n/** One store per compiler: a second compile of the same project fetches nothing. */\nfunction defaultPackages(): PackageStore {\n return chainPackages(nodeModulesPackages(), npmPackages());\n}\n\n/**\n * A compiler for `loadProject(files, { compile })` that bundles `main` and its packages into one\n * ES module. `cloudflare:workers`, `node:*` (nodejs_compat) and the Workers globals come from\n * the runtime (`cellbHostModule`), as in a folder `cellb build` writes.\n */\nexport function bundleCompiler(options: BundleCompilerOptions): ProjectCompiler {\n const packages = options.packages ?? defaultPackages();\n return {\n kind: \"bundle\",\n async compile({ files, config, nodeCompat }) {\n if (!config.main) return { code: { bundle: null } };\n // `node:*` only with nodejs_compat, which also takes a bare built-in name (\"buffer\") as one\n // when cellb has a polyfill for it. A `node:*` module without one is a stub that throws when\n // used, as `cellb build` and wrangler's nodejs_compat do (libraries import such modules in\n // code paths a Worker never takes).\n const modules = (spec: string) =>\n spec.startsWith(\"node:\")\n ? nodeCompat\n ? (cellbHostModule(spec) ?? nodeStub(spec))\n : undefined\n : (cellbHostModule(spec) ??\n (nodeCompat && !spec.includes(\":\") ? cellbHostModule(`node:${spec}`) : undefined));\n const { code } = await bundle({\n esbuild: options.esbuild,\n files,\n entry: `/${config.main.replace(/^\\.?\\/+/, \"\")}`,\n packages,\n modules,\n inject: [CELLS_GLOBALS_MODULE], // Response, WebSocketPair… of the runtime, not the realm's\n conditions: options.conditions ?? [\"workerd\", \"worker\", \"browser\"],\n lowerAwait: options.lowerAwait ?? nodeCompat,\n sourcemap: false,\n // Function names are observable (the npm assert polyfill reports its caller's name as\n // the operator): bundling must not rename them, as in `cellb build`.\n esbuildOptions: { keepNames: true },\n });\n return { code: { bundle: code } };\n },\n };\n}\n\n/**\n * A Node.js module with no browser polyfill: CommonJS, so that every import links. Its default\n * export answers any member with a function that throws when called (or extended). A named import\n * is undefined (esbuild copies the members of a CommonJS module, and a stub cannot list them), so\n * it fails when used, not when loaded. `cellb build` lists the members from Node itself; a browser\n * cannot.\n */\nfunction nodeStub(spec: string): string {\n const what = JSON.stringify(spec);\n return [\n `const fail = (key) => { throw new Error(${what} + \".\" + key + \" is not available in browsers (nodejs_compat)\"); };`,\n \"module.exports = new Proxy(Object.create(null), {\",\n \" get(target, key) {\",\n ' if (typeof key === \"symbol\" || key === \"then\" || key === \"__esModule\") return undefined;',\n \" if (!(key in target)) target[key] = function () { fail(String(key)); };\",\n \" return target[key];\",\n \" },\",\n \"});\",\n ].join(\"\\n\");\n}\n"]}
@@ -12,10 +12,10 @@ import * as workersClasses from "./cloudflare-workers.js";
12
12
  import { parseJsonc } from "./jsonc.js";
13
13
  import { ownModule } from "./own-module.js";
14
14
  import { workerScope } from "./worker-scope.js";
15
- import { createProjectRuntime, loadTimeEnv, } from "./wrangler.js";
15
+ import { createProjectRuntime, hasNodeCompat, loadTimeEnv, WRANGLER_FILES, } from "./wrangler.js";
16
16
  /** Reads `wrangler.jsonc` / `wrangler.json` of a project directory (celld reads the same files). */
17
17
  export function readWranglerConfig(dir) {
18
- for (const name of ["wrangler.jsonc", "wrangler.json"]) {
18
+ for (const name of WRANGLER_FILES) {
19
19
  const p = join(dir, name);
20
20
  if (existsSync(p))
21
21
  return parseJsonc(readFileSync(p, "utf8"));
@@ -203,7 +203,7 @@ export async function loadNodeProject(dir, host) {
203
203
  if (!config.main && !config.assets)
204
204
  throw new Error("wrangler config has neither `main` nor `assets`");
205
205
  const flags = config.compatibility_flags ?? [];
206
- const nodeCompat = flags.some((f) => f.startsWith("nodejs_compat"));
206
+ const nodeCompat = hasNodeCompat(config);
207
207
  const standardBinaryType = flags.includes("websocket_standard_binary_type");
208
208
  // The module reads `env` from `cloudflare:workers` while it is evaluated, before the
209
209
  // runtime exists: until then the scope holds the configuration's vars (and `ai`).
@@ -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 { ownModule } from \"./own-module.js\";\nimport { type WorkerScope, workerScope } from \"./worker-scope.js\";\nimport {\n createProjectRuntime,\n loadTimeEnv,\n type ProjectHost,\n type ProjectRuntime,\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.jsonc\", \"wrangler.json\"]) {\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: { nodeCompat?: boolean; standardBinaryType?: boolean; scope?: WorkerScope } = {},\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 ],\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 = flags.some((f) => f.startsWith(\"nodejs_compat\"));\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 })\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 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 { ownModule } from \"./own-module.js\";\nimport { type WorkerScope, workerScope } from \"./worker-scope.js\";\nimport {\n createProjectRuntime,\n hasNodeCompat,\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: { nodeCompat?: boolean; standardBinaryType?: boolean; scope?: WorkerScope } = {},\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 ],\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 })\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 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"]}
@@ -0,0 +1,67 @@
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 type { SiteHandler } from "@statewalker/webrun-site-builder";
11
+ import type { ProjectCompiler } from "./source-project.js";
12
+ /** A site, hosted: its base URL (ending in "/") and how to take it down. */
13
+ export interface HostedProjectSite {
14
+ baseUrl: string;
15
+ stop(): Promise<void>;
16
+ }
17
+ /** Hosts a site handler where this realm's code can `import()` from it. */
18
+ export type SiteHost = (handler: SiteHandler) => Promise<HostedProjectSite>;
19
+ export interface SiteCompilerOptions {
20
+ /**
21
+ * Where the site is hosted. Default: a ServiceWorker this realm registers (`HostedSiteBuilder`),
22
+ * which a page can do and a Dedicated Worker cannot; in a worker, pass `siteHostOverPort(port)`
23
+ * and call `hostSitesForWorker(port)` in the page.
24
+ */
25
+ host?: SiteHost;
26
+ /** The ServiceWorker script for the default host (default: `/sw-worker.js`). */
27
+ serviceWorkerUrl?: string;
28
+ /** `createProjectSite`'s `lowerAwait` (default: with nodejs_compat, unless AsyncContext). */
29
+ lowerAwait?: boolean;
30
+ }
31
+ /**
32
+ * A compiler for `loadProject(files, { compile })` that serves the project's modules from an
33
+ * in-browser HTTP server (`createProjectSite`): `main` and Worker Loader code are imported from
34
+ * it, so a change can rebuild one module. The site stops when the project closes.
35
+ */
36
+ export declare function siteCompiler(options?: SiteCompilerOptions): ProjectCompiler;
37
+ /**
38
+ * Where a worker and its page talk about sites: a MessagePort, the `Worker` (page side) or the
39
+ * worker's own scope (`self`). Other messages on it are left alone.
40
+ */
41
+ export interface SiteControl {
42
+ postMessage(message: unknown, transfer: Transferable[]): void;
43
+ addEventListener(type: "message", listener: (e: MessageEvent) => void): void;
44
+ removeEventListener(type: "message", listener: (e: MessageEvent) => void): void;
45
+ }
46
+ /**
47
+ * Worker side: hosts each site through the page at the other end of `control`, which runs
48
+ * `hostSitesForWorker`. The handler stays in this worker; the page's ServiceWorker forwards each
49
+ * request to it.
50
+ */
51
+ export declare function siteHostOverPort(control: SiteControl,
52
+ /**
53
+ * How long the page may take to host the site (default 30 s; a ServiceWorker's first install
54
+ * can be slow), and to confirm it stopped one (default 2 s; the worker stops serving anyway).
55
+ */
56
+ { timeoutMs, stopTimeoutMs, }?: {
57
+ timeoutMs?: number;
58
+ stopTimeoutMs?: number;
59
+ }): SiteHost;
60
+ /**
61
+ * Page side: hosts in this page's ServiceWorker the sites a worker asks for over `control`
62
+ * (`siteHostOverPort`). Returns a function that stops listening; the sites stop when the worker
63
+ * stops them.
64
+ */
65
+ export declare function hostSitesForWorker(control: SiteControl, options?: {
66
+ serviceWorkerUrl?: string;
67
+ }): () => void;