@takazudo/zfb-adapter-cloudflare 3.1.0 → 4.0.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.
package/dist/build.d.ts CHANGED
@@ -49,7 +49,7 @@ export interface EmitWorkerOutput {
49
49
  * more copied Wasm assets in `outdir`):
50
50
  *
51
51
  * _worker.js — Worker entry point (`main` in wrangler.toml)
52
- * _zfb_inner.mjs — the input bundle, copied verbatim
52
+ * _zfb_inner.mjs — the input bundle, minus any trailing external `sourceMappingURL` comment
53
53
  * <asset>.wasm — each bundle-relative Wasm input, copied by basename
54
54
  * .assetsignore — excludes every generated JavaScript and Wasm basename
55
55
  * from the asset upload so they are only reachable
package/dist/build.js CHANGED
@@ -27,7 +27,7 @@ export const WORKER_WRAPPER_SOURCE = _wrapper;
27
27
  * more copied Wasm assets in `outdir`):
28
28
  *
29
29
  * _worker.js — Worker entry point (`main` in wrangler.toml)
30
- * _zfb_inner.mjs — the input bundle, copied verbatim
30
+ * _zfb_inner.mjs — the input bundle, minus any trailing external `sourceMappingURL` comment
31
31
  * <asset>.wasm — each bundle-relative Wasm input, copied by basename
32
32
  * .assetsignore — excludes every generated JavaScript and Wasm basename
33
33
  * from the asset upload so they are only reachable
package/dist/build.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,0EAA0E;AAC1E,kEAAkE;AAClE,sEAAsE;AACtE,+DAA+D;AAC/D,EAAE;AACF,yEAAyE;AACzE,mEAAmE;AAEnE,0EAA0E;AAC1E,sCAAsC;AACtC,OAAO,EAAE,qBAAqB,IAAI,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACzE,uEAAuE;AACvE,gEAAgE;AAChE,OAAO,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAW,QAAkB,CAAC;AAyChE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAsB;IACrD,OAAO,WAAW,CAAC;QACjB,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,mBAAmB,EAAE,qBAAqB;KAC3C,CAA8B,CAAC;AAClC,CAAC","sourcesContent":["// `@takazudo/zfb-adapter-cloudflare/build` — Node-only build helpers.\n//\n// This sub-entry is intentionally **not** imported by the Workers-runtime\n// entry (`./`). Code in this module may freely use Node built-ins\n// (`node:fs`, `node:path`, …) because it only ever runs in a Node 22+\n// build environment, never inside a Cloudflare Worker isolate.\n//\n// The `./` entry (`src/index.ts`) exports only Workers-runtime-safe code\n// (AsyncLocalStorage helpers) that can be bundled into the worker.\n\n// @ts-expect-error worker-wrapper.mjs has no declaration file; the export\n// shape is narrowed explicitly below.\nimport { WORKER_WRAPPER_SOURCE as _wrapper } from \"./worker-wrapper.mjs\";\n// @ts-expect-error emit-worker.mjs has no declaration file; the export\n// shape is narrowed via EmitWorkerInput/EmitWorkerOutput below.\nimport { emitWorker as _emitWorker } from \"./emit-worker.mjs\";\n\n/**\n * The wrapper source written to `_worker.js`. Imported from the single\n * canonical `.mjs` file so `src/build.ts` and `bin/cli.mjs` always stay\n * in sync without any duplication.\n */\nexport const WORKER_WRAPPER_SOURCE: string = _wrapper as string;\n\n/**\n * Inputs to [`emitWorker`].\n */\nexport interface EmitWorkerInput {\n /**\n * Absolute path to the input ESM bundle produced by `zfb-build`. The\n * bundle must export a Workers-shaped `default { fetch: (request) =>\n * Promise<Response> }` (this is the contract `zfb_build::bundler`\n * pins). The file is copied verbatim next to the emitted wrapper so\n * relative imports inside it keep resolving.\n */\n readonly inputBundlePath: string;\n /**\n * Absolute path to the output directory. The emitter creates it if\n * missing and writes `_worker.js`, `_zfb_inner.mjs` (the copied input\n * bundle), copied Wasm assets, and `.assetsignore` into it. The ignore\n * file protects every generated JavaScript and Wasm basename from the\n * public asset upload.\n */\n readonly outdir: string;\n /**\n * Wasm modules emitted beside the input bundle. Relative paths resolve from\n * the input bundle's directory and each module is copied into the Worker\n * package under its basename, then added to `.assetsignore` so it remains a\n * Worker module rather than a public static asset.\n */\n readonly assets?: readonly string[];\n}\n\n/**\n * Output paths the emitter produced. Returned for callers that want to\n * log them (the Rust orchestrator surfaces them in build output).\n */\nexport interface EmitWorkerOutput {\n readonly workerPath: string;\n readonly innerBundlePath: string;\n readonly assetsIgnorePath: string;\n}\n\n/**\n * Emit a Cloudflare Workers Static Assets `_worker.js` that wraps the zfb\n * input bundle. Cloudflare Pages advanced mode is unverified.\n *\n * Output shape (two generated JavaScript files, `.assetsignore`, and zero or\n * more copied Wasm assets in `outdir`):\n *\n * _worker.js — Worker entry point (`main` in wrangler.toml)\n * _zfb_inner.mjs — the input bundle, copied verbatim\n * <asset>.wasm — each bundle-relative Wasm input, copied by basename\n * .assetsignore — excludes every generated JavaScript and Wasm basename\n * from the asset upload so they are only reachable\n * through the Worker's module graph\n *\n * The wrapper imports the inner bundle via the relative path\n * `./_zfb_inner.mjs`. Workerd's Module loader resolves relative ESM\n * imports inside the `_worker.js` directory, so this layout works\n * without re-bundling.\n *\n * Why two bundle files instead of one: re-bundling here would require a\n * second esbuild pass and would force the adapter to ship its own\n * esbuild binary slot. The two-file layout keeps the adapter\n * dependency-free at runtime — it is just `node:fs` glue.\n */\nexport async function emitWorker(input: EmitWorkerInput): Promise<EmitWorkerOutput> {\n return _emitWorker({\n inputBundlePath: input.inputBundlePath,\n outdir: input.outdir,\n assets: input.assets,\n workerWrapperSource: WORKER_WRAPPER_SOURCE,\n }) as Promise<EmitWorkerOutput>;\n}\n"]}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,0EAA0E;AAC1E,kEAAkE;AAClE,sEAAsE;AACtE,+DAA+D;AAC/D,EAAE;AACF,yEAAyE;AACzE,mEAAmE;AAEnE,0EAA0E;AAC1E,sCAAsC;AACtC,OAAO,EAAE,qBAAqB,IAAI,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACzE,uEAAuE;AACvE,gEAAgE;AAChE,OAAO,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAW,QAAkB,CAAC;AAyChE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAsB;IACrD,OAAO,WAAW,CAAC;QACjB,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,mBAAmB,EAAE,qBAAqB;KAC3C,CAA8B,CAAC;AAClC,CAAC","sourcesContent":["// `@takazudo/zfb-adapter-cloudflare/build` — Node-only build helpers.\n//\n// This sub-entry is intentionally **not** imported by the Workers-runtime\n// entry (`./`). Code in this module may freely use Node built-ins\n// (`node:fs`, `node:path`, …) because it only ever runs in a Node 22+\n// build environment, never inside a Cloudflare Worker isolate.\n//\n// The `./` entry (`src/index.ts`) exports only Workers-runtime-safe code\n// (AsyncLocalStorage helpers) that can be bundled into the worker.\n\n// @ts-expect-error worker-wrapper.mjs has no declaration file; the export\n// shape is narrowed explicitly below.\nimport { WORKER_WRAPPER_SOURCE as _wrapper } from \"./worker-wrapper.mjs\";\n// @ts-expect-error emit-worker.mjs has no declaration file; the export\n// shape is narrowed via EmitWorkerInput/EmitWorkerOutput below.\nimport { emitWorker as _emitWorker } from \"./emit-worker.mjs\";\n\n/**\n * The wrapper source written to `_worker.js`. Imported from the single\n * canonical `.mjs` file so `src/build.ts` and `bin/cli.mjs` always stay\n * in sync without any duplication.\n */\nexport const WORKER_WRAPPER_SOURCE: string = _wrapper as string;\n\n/**\n * Inputs to [`emitWorker`].\n */\nexport interface EmitWorkerInput {\n /**\n * Absolute path to the input ESM bundle produced by `zfb-build`. The\n * bundle must export a Workers-shaped `default { fetch: (request) =>\n * Promise<Response> }` (this is the contract `zfb_build::bundler`\n * pins). The file is copied verbatim next to the emitted wrapper so\n * relative imports inside it keep resolving.\n */\n readonly inputBundlePath: string;\n /**\n * Absolute path to the output directory. The emitter creates it if\n * missing and writes `_worker.js`, `_zfb_inner.mjs` (the copied input\n * bundle), copied Wasm assets, and `.assetsignore` into it. The ignore\n * file protects every generated JavaScript and Wasm basename from the\n * public asset upload.\n */\n readonly outdir: string;\n /**\n * Wasm modules emitted beside the input bundle. Relative paths resolve from\n * the input bundle's directory and each module is copied into the Worker\n * package under its basename, then added to `.assetsignore` so it remains a\n * Worker module rather than a public static asset.\n */\n readonly assets?: readonly string[];\n}\n\n/**\n * Output paths the emitter produced. Returned for callers that want to\n * log them (the Rust orchestrator surfaces them in build output).\n */\nexport interface EmitWorkerOutput {\n readonly workerPath: string;\n readonly innerBundlePath: string;\n readonly assetsIgnorePath: string;\n}\n\n/**\n * Emit a Cloudflare Workers Static Assets `_worker.js` that wraps the zfb\n * input bundle. Cloudflare Pages advanced mode is unverified.\n *\n * Output shape (two generated JavaScript files, `.assetsignore`, and zero or\n * more copied Wasm assets in `outdir`):\n *\n * _worker.js — Worker entry point (`main` in wrangler.toml)\n * _zfb_inner.mjs — the input bundle, minus any trailing external `sourceMappingURL` comment\n * <asset>.wasm — each bundle-relative Wasm input, copied by basename\n * .assetsignore — excludes every generated JavaScript and Wasm basename\n * from the asset upload so they are only reachable\n * through the Worker's module graph\n *\n * The wrapper imports the inner bundle via the relative path\n * `./_zfb_inner.mjs`. Workerd's Module loader resolves relative ESM\n * imports inside the `_worker.js` directory, so this layout works\n * without re-bundling.\n *\n * Why two bundle files instead of one: re-bundling here would require a\n * second esbuild pass and would force the adapter to ship its own\n * esbuild binary slot. The two-file layout keeps the adapter\n * dependency-free at runtime — it is just `node:fs` glue.\n */\nexport async function emitWorker(input: EmitWorkerInput): Promise<EmitWorkerOutput> {\n return _emitWorker({\n inputBundlePath: input.inputBundlePath,\n outdir: input.outdir,\n assets: input.assets,\n workerWrapperSource: WORKER_WRAPPER_SOURCE,\n }) as Promise<EmitWorkerOutput>;\n}\n"]}
@@ -70,6 +70,21 @@ async function resolveAssets(inputBundlePath, assetPaths) {
70
70
  return resolvedAssets;
71
71
  }
72
72
 
73
+ // The adapter never emits source maps (they are not published and would leak
74
+ // local source paths), so a trailing external `sourceMappingURL` reference in
75
+ // the copied bundle would dangle and make source-map-aware tools (Vite Workers
76
+ // integration) fail with ENOENT. Inline `data:` maps are self-contained and kept.
77
+ const TRAILING_EXTERNAL_SOURCE_MAP =
78
+ /(?:\r?\n)?[ \t]*\/\/[#@][ \t]*sourceMappingURL=(?!data:)\S*\s*$/;
79
+
80
+ export function stripDanglingSourceMapReference(source) {
81
+ const stripped = source.replace(TRAILING_EXTERNAL_SOURCE_MAP, "");
82
+ if (stripped === source) {
83
+ return source;
84
+ }
85
+ return stripped.endsWith("\n") || stripped.length === 0 ? stripped : stripped + "\n";
86
+ }
87
+
73
88
  async function pathExists(path) {
74
89
  try {
75
90
  await lstat(path);
@@ -112,7 +127,8 @@ function mergeAssetsIgnore(existing, requiredEntries) {
112
127
  * more copied Wasm assets in `outdir`):
113
128
  *
114
129
  * _worker.js — Worker entry point (`main` in wrangler.toml)
115
- * _zfb_inner.mjs — the input bundle, copied verbatim
130
+ * _zfb_inner.mjs — the input bundle, copied with any trailing external
131
+ * `sourceMappingURL` comment removed (no map is emitted)
116
132
  * <asset>.wasm — each bundle-relative Wasm input, copied by basename
117
133
  * .assetsignore — excludes every generated JavaScript and Wasm basename
118
134
  * from the asset upload
@@ -136,7 +152,8 @@ export async function emitWorker({ inputBundlePath, outdir, assets = [], workerW
136
152
  }
137
153
 
138
154
  const innerBundlePath = join(outdirAbs, "_zfb_inner.mjs");
139
- await copyFile(inputAbs, innerBundlePath);
155
+ const inputSource = await readFile(inputAbs, "utf8");
156
+ await writeFile(innerBundlePath, stripDanglingSourceMapReference(inputSource), "utf8");
140
157
 
141
158
  const workerPath = join(outdirAbs, "_worker.js");
142
159
  await writeFile(workerPath, workerWrapperSource, "utf8");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@takazudo/zfb-adapter-cloudflare",
3
- "version": "3.1.0",
3
+ "version": "4.0.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Content-site engine on the web's Request/Response model — prerender to static HTML, serve on Cloudflare Workers, or run as a local content server inside your app. One Rust binary. Cloudflare adapter: Workers Static Assets (Pages-compatible).",
@@ -59,14 +59,16 @@
59
59
  },
60
60
  "devDependencies": {
61
61
  "@types/node": "^22.0.0",
62
- "typescript": "^5.9.0",
63
- "vitest": "^2.1.9"
62
+ "typescript": "7.0.2",
63
+ "typescript-5.9": "npm:typescript@5.9.3",
64
+ "typescript-6.0": "npm:typescript@6.0.3",
65
+ "vite-plus": "1.0.0"
64
66
  },
65
67
  "scripts": {
66
68
  "build": "tsc && cp src/worker-wrapper.mjs dist/worker-wrapper.mjs && cp src/emit-worker.mjs dist/emit-worker.mjs",
67
- "test": "pnpm typecheck:consumer && vitest run && pnpm test:packed-types",
69
+ "test": "pnpm typecheck:consumer && vp test run && pnpm test:packed-types",
68
70
  "test:packed-types": "pnpm build && node scripts/check-packed-types.mjs",
69
- "test:watch": "vitest",
71
+ "test:watch": "vp test",
70
72
  "typecheck": "tsc --noEmit && pnpm typecheck:consumer",
71
73
  "typecheck:consumer": "tsc --project tsconfig.consumer.json --noEmit"
72
74
  }
@@ -70,6 +70,21 @@ async function resolveAssets(inputBundlePath, assetPaths) {
70
70
  return resolvedAssets;
71
71
  }
72
72
 
73
+ // The adapter never emits source maps (they are not published and would leak
74
+ // local source paths), so a trailing external `sourceMappingURL` reference in
75
+ // the copied bundle would dangle and make source-map-aware tools (Vite Workers
76
+ // integration) fail with ENOENT. Inline `data:` maps are self-contained and kept.
77
+ const TRAILING_EXTERNAL_SOURCE_MAP =
78
+ /(?:\r?\n)?[ \t]*\/\/[#@][ \t]*sourceMappingURL=(?!data:)\S*\s*$/;
79
+
80
+ export function stripDanglingSourceMapReference(source) {
81
+ const stripped = source.replace(TRAILING_EXTERNAL_SOURCE_MAP, "");
82
+ if (stripped === source) {
83
+ return source;
84
+ }
85
+ return stripped.endsWith("\n") || stripped.length === 0 ? stripped : stripped + "\n";
86
+ }
87
+
73
88
  async function pathExists(path) {
74
89
  try {
75
90
  await lstat(path);
@@ -112,7 +127,8 @@ function mergeAssetsIgnore(existing, requiredEntries) {
112
127
  * more copied Wasm assets in `outdir`):
113
128
  *
114
129
  * _worker.js — Worker entry point (`main` in wrangler.toml)
115
- * _zfb_inner.mjs — the input bundle, copied verbatim
130
+ * _zfb_inner.mjs — the input bundle, copied with any trailing external
131
+ * `sourceMappingURL` comment removed (no map is emitted)
116
132
  * <asset>.wasm — each bundle-relative Wasm input, copied by basename
117
133
  * .assetsignore — excludes every generated JavaScript and Wasm basename
118
134
  * from the asset upload
@@ -136,7 +152,8 @@ export async function emitWorker({ inputBundlePath, outdir, assets = [], workerW
136
152
  }
137
153
 
138
154
  const innerBundlePath = join(outdirAbs, "_zfb_inner.mjs");
139
- await copyFile(inputAbs, innerBundlePath);
155
+ const inputSource = await readFile(inputAbs, "utf8");
156
+ await writeFile(innerBundlePath, stripDanglingSourceMapReference(inputSource), "utf8");
140
157
 
141
158
  const workerPath = join(outdirAbs, "_worker.js");
142
159
  await writeFile(workerPath, workerWrapperSource, "utf8");