@astrojs/cloudflare 13.0.0-beta.5 → 13.0.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -83,7 +83,7 @@ function serverStart({
83
83
  host,
84
84
  base
85
85
  }) {
86
- const version = "13.0.0-beta.5";
86
+ const version = "13.0.0-beta.6";
87
87
  const localPrefix = `${colors.dim("\u2503")} Local `;
88
88
  const networkPrefix = `${colors.dim("\u2503")} Network `;
89
89
  const emptyPrefix = " ".repeat(11);
package/dist/index.d.ts CHANGED
@@ -28,14 +28,6 @@ export type Options = {
28
28
  }[];
29
29
  };
30
30
  };
31
- /**
32
- * Allow bundling cloudflare worker specific file types as importable modules. Defaults to true.
33
- * When enabled, allows imports of '.wasm', '.bin', and '.txt' file types
34
- *
35
- * See https://developers.cloudflare.com/pages/functions/module-support/
36
- * for reference on how these file types are exported
37
- */
38
- cloudflareModules?: boolean;
39
31
  /**
40
32
  * By default, Astro will be configured to use Cloudflare KV to store session data. The KV namespace
41
33
  * will be automatically provisioned when you deploy.
package/dist/index.js CHANGED
@@ -4,7 +4,6 @@ import { createInterface } from "node:readline/promises";
4
4
  import { removeLeadingForwardSlash } from "@astrojs/internal-helpers/path";
5
5
  import { createRedirectsFromAstroRoutes, printAsRedirects } from "@astrojs/underscore-redirects";
6
6
  import { cloudflare as cfVitePlugin } from "@cloudflare/vite-plugin";
7
- import { cloudflareModuleLoader } from "./utils/cloudflare-module-loader.js";
8
7
  import { createRoutesFile, getParts } from "./utils/generate-routes-json.js";
9
8
  import { setImageConfig } from "./utils/image-config.js";
10
9
  import { createConfigPlugin } from "./vite-plugin-config.js";
@@ -13,14 +12,12 @@ import {
13
12
  DEFAULT_SESSION_KV_BINDING_NAME,
14
13
  DEFAULT_IMAGES_BINDING_NAME
15
14
  } from "./wrangler.js";
16
- import { parse } from "dotenv";
15
+ import { parseEnv } from "node:util";
17
16
  import { sessionDrivers } from "astro/config";
17
+ import { createCloudflarePrerenderer } from "./prerenderer.js";
18
18
  function createIntegration(args) {
19
19
  let _config;
20
20
  let finalBuildOutput;
21
- const cloudflareModulePlugin = cloudflareModuleLoader(
22
- args?.cloudflareModules ?? true
23
- );
24
21
  let _routes;
25
22
  const sessionKVBindingName = args?.sessionKVBindingName ?? DEFAULT_SESSION_KV_BINDING_NAME;
26
23
  const imagesBindingName = args?.imagesBindingName ?? DEFAULT_IMAGES_BINDING_NAME;
@@ -51,7 +48,18 @@ function createIntegration(args) {
51
48
  config: cloudflareConfigCustomizer({
52
49
  sessionKVBindingName: args?.sessionKVBindingName,
53
50
  imagesBindingName: args?.imageService === "cloudflare-binding" ? args?.imagesBindingName : false
54
- })
51
+ }),
52
+ experimental: {
53
+ prerenderWorker: {
54
+ config(_, { entryWorkerConfig }) {
55
+ return {
56
+ ...entryWorkerConfig,
57
+ // This is the Vite environment name used for prerendering
58
+ name: "prerender"
59
+ };
60
+ }
61
+ }
62
+ }
55
63
  };
56
64
  updateConfig({
57
65
  build: {
@@ -64,9 +72,6 @@ function createIntegration(args) {
64
72
  vite: {
65
73
  plugins: [
66
74
  cfVitePlugin(cfPluginConfig),
67
- // https://developers.cloudflare.com/pages/functions/module-support/
68
- // Allows imports of '.wasm', '.bin', and '.txt' file types
69
- cloudflareModulePlugin,
70
75
  {
71
76
  name: "@astrojs/cloudflare:cf-imports",
72
77
  enforce: "pre",
@@ -82,8 +87,10 @@ function createIntegration(args) {
82
87
  {
83
88
  name: "@astrojs/cloudflare:environment",
84
89
  configEnvironment(environmentName, _options) {
85
- const isServerEnvironment = ["ssr", "prerender"].includes(environmentName);
86
- if (isServerEnvironment && _options.optimizeDeps?.noDiscovery === false) {
90
+ const isServerEnvironment = ["astro", "ssr", "prerender"].includes(
91
+ environmentName
92
+ );
93
+ if (isServerEnvironment && !_options.optimizeDeps?.noDiscovery) {
87
94
  return {
88
95
  optimizeDeps: {
89
96
  include: [
@@ -175,10 +182,9 @@ function createIntegration(args) {
175
182
  i18nDomains: "experimental",
176
183
  sharpImageService: {
177
184
  support: "limited",
178
- message: 'Cloudflare does not support sharp at runtime. However, you can configure `imageService: "compile"` to optimize images with sharp on prerendered pages during build time.',
179
- // For explicitly set image services, we suppress the warning about sharp not being supported at runtime,
180
- // inferring the user is aware of the limitations.
181
- suppress: args?.imageService ? "all" : "default"
185
+ message: "When using a custom image service, ensure it is compatible with the Cloudflare Workers runtime.",
186
+ // Only 'custom' could potentially use sharp at runtime.
187
+ suppress: args?.imageService === "custom" ? "default" : "all"
182
188
  },
183
189
  envGetSecret: "stable"
184
190
  }
@@ -187,7 +193,7 @@ function createIntegration(args) {
187
193
  if (existsSync(devVarsPath)) {
188
194
  try {
189
195
  const data = readFileSync(devVarsPath, "utf-8");
190
- const parsed = parse(data);
196
+ const parsed = parseEnv(data);
191
197
  Object.assign(process.env, parsed);
192
198
  } catch {
193
199
  logger.error(
@@ -196,6 +202,17 @@ function createIntegration(args) {
196
202
  }
197
203
  }
198
204
  },
205
+ "astro:build:start": ({ setPrerenderer }) => {
206
+ setPrerenderer(
207
+ createCloudflarePrerenderer({
208
+ root: _config.root,
209
+ serverDir: _config.build.server,
210
+ clientDir: _config.build.client,
211
+ base: _config.base,
212
+ trailingSlash: _config.trailingSlash
213
+ })
214
+ );
215
+ },
199
216
  "astro:build:setup": ({ vite, target }) => {
200
217
  if (target === "server") {
201
218
  vite.resolve ||= {};
@@ -284,6 +301,7 @@ function createIntegration(args) {
284
301
  logger.error("Failed to write _redirects file");
285
302
  }
286
303
  }
304
+ delete process.env.CLOUDFLARE_VITE_BUILD;
287
305
  }
288
306
  }
289
307
  };
@@ -0,0 +1,22 @@
1
+ import type { SerializedRouteData } from 'astro/app/manifest';
2
+ /**
3
+ * A pathname with its serialized route data, used for prerendering over HTTP.
4
+ */
5
+ interface SerializedPathWithRoute {
6
+ pathname: string;
7
+ route: SerializedRouteData;
8
+ }
9
+ /**
10
+ * Response from the /__astro_static_paths endpoint.
11
+ */
12
+ export interface StaticPathsResponse {
13
+ paths: SerializedPathWithRoute[];
14
+ }
15
+ /**
16
+ * Request body for the /__astro_prerender endpoint.
17
+ */
18
+ export interface PrerenderRequest {
19
+ url: string;
20
+ routeData: SerializedRouteData;
21
+ }
22
+ export {};
File without changes
@@ -0,0 +1,14 @@
1
+ import type { AstroConfig, AstroPrerenderer } from 'astro';
2
+ interface CloudflarePrerendererOptions {
3
+ root: AstroConfig['root'];
4
+ serverDir: AstroConfig['build']['server'];
5
+ clientDir: AstroConfig['build']['client'];
6
+ base: AstroConfig['base'];
7
+ trailingSlash: AstroConfig['trailingSlash'];
8
+ }
9
+ /**
10
+ * Creates a prerenderer that uses Cloudflare's workerd runtime via a preview server.
11
+ * This allows prerendering to happen in the same runtime that will serve the pages.
12
+ */
13
+ export declare function createCloudflarePrerenderer({ root, serverDir, clientDir, base, trailingSlash, }: CloudflarePrerendererOptions): AstroPrerenderer;
14
+ export {};
@@ -0,0 +1,88 @@
1
+ import { preview } from "vite";
2
+ import { fileURLToPath } from "node:url";
3
+ import { mkdir } from "node:fs/promises";
4
+ import { cloudflare as cfVitePlugin } from "@cloudflare/vite-plugin";
5
+ import { cloudflareConfigCustomizer } from "./wrangler.js";
6
+ import { serializeRouteData, deserializeRouteData } from "astro/app/manifest";
7
+ import { STATIC_PATHS_ENDPOINT, PRERENDER_ENDPOINT } from "./utils/prerender-constants.js";
8
+ function createCloudflarePrerenderer({
9
+ root,
10
+ serverDir,
11
+ clientDir,
12
+ base,
13
+ trailingSlash
14
+ }) {
15
+ let previewServer;
16
+ let serverUrl;
17
+ return {
18
+ name: "@astrojs/cloudflare:prerenderer",
19
+ async setup() {
20
+ await mkdir(clientDir, { recursive: true });
21
+ const cfPluginConfig = {
22
+ viteEnvironment: { name: "prerender" },
23
+ config: cloudflareConfigCustomizer()
24
+ };
25
+ previewServer = await preview({
26
+ configFile: false,
27
+ base,
28
+ appType: "mpa",
29
+ build: {
30
+ outDir: fileURLToPath(serverDir)
31
+ },
32
+ root: fileURLToPath(root),
33
+ preview: {
34
+ host: "localhost",
35
+ port: 0,
36
+ // Let the OS pick a free port
37
+ open: false
38
+ },
39
+ plugins: [cfVitePlugin(cfPluginConfig)]
40
+ });
41
+ const address = previewServer.httpServer.address();
42
+ if (address && typeof address === "object") {
43
+ serverUrl = `http://localhost:${address.port}`;
44
+ } else {
45
+ throw new Error(
46
+ "Failed to start the Cloudflare prerender server. The preview server did not return a valid address. This is likely a bug in @astrojs/cloudflare. Please file an issue at https://github.com/withastro/astro/issues"
47
+ );
48
+ }
49
+ },
50
+ async getStaticPaths() {
51
+ const response = await fetch(`${serverUrl}${STATIC_PATHS_ENDPOINT}`, {
52
+ method: "POST",
53
+ headers: { "Content-Type": "application/json" }
54
+ });
55
+ if (!response.ok) {
56
+ throw new Error(
57
+ `Failed to get static paths from the Cloudflare prerender server (${response.status}: ${response.statusText}). This is likely a bug in @astrojs/cloudflare. Please file an issue at https://github.com/withastro/astro/issues`
58
+ );
59
+ }
60
+ const data = await response.json();
61
+ return data.paths.map(({ pathname, route }) => ({
62
+ pathname,
63
+ route: deserializeRouteData(route)
64
+ }));
65
+ },
66
+ async render(request, { routeData }) {
67
+ const body = {
68
+ url: request.url,
69
+ routeData: serializeRouteData(routeData, trailingSlash)
70
+ };
71
+ const response = await fetch(`${serverUrl}${PRERENDER_ENDPOINT}`, {
72
+ method: "POST",
73
+ headers: { "Content-Type": "application/json" },
74
+ body: JSON.stringify(body)
75
+ });
76
+ return response;
77
+ },
78
+ async teardown() {
79
+ if (previewServer) {
80
+ await previewServer.close();
81
+ previewServer = void 0;
82
+ }
83
+ }
84
+ };
85
+ }
86
+ export {
87
+ createCloudflarePrerenderer
88
+ };
@@ -1,19 +1,33 @@
1
1
  import { env as globalEnv } from "cloudflare:workers";
2
- import { sessionKVBindingName } from "virtual:astro-cloudflare:config";
2
+ import { sessionKVBindingName, isPrerender } from "virtual:astro-cloudflare:config";
3
3
  import { createApp } from "astro/app/entrypoint";
4
4
  import { setGetEnv } from "astro/env/setup";
5
5
  import { createGetEnv } from "../utils/env.js";
6
+ import {
7
+ isStaticPathsRequest,
8
+ isPrerenderRequest,
9
+ handleStaticPathsRequest,
10
+ handlePrerenderRequest
11
+ } from "./prerender.js";
6
12
  setGetEnv(createGetEnv(globalEnv));
13
+ const app = createApp();
7
14
  async function handle(request, env, context) {
8
- const app = createApp(import.meta.env.DEV);
9
- const { pathname } = new URL(request.url);
15
+ if (isPrerender) {
16
+ if (isStaticPathsRequest(request)) {
17
+ return handleStaticPathsRequest(app);
18
+ }
19
+ if (isPrerenderRequest(request)) {
20
+ return handlePrerenderRequest(app, request);
21
+ }
22
+ }
23
+ const { pathname: requestPathname } = new URL(request.url);
10
24
  if (env[sessionKVBindingName]) {
11
25
  const sessionConfigOptions = app.manifest.sessionConfig?.options ?? {};
12
26
  Object.assign(sessionConfigOptions, {
13
27
  binding: env[sessionKVBindingName]
14
28
  });
15
29
  }
16
- if (app.manifest.assets.has(pathname)) {
30
+ if (app.manifest.assets.has(requestPathname)) {
17
31
  return env.ASSETS.fetch(request.url.replace(/\.html$/, ""));
18
32
  }
19
33
  let routeData = void 0;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Constants for prerender endpoints used by Cloudflare adapter
3
+ */
4
+ /** Internal endpoint for fetching all static paths during prerendering */
5
+ export declare const STATIC_PATHS_ENDPOINT = "/__astro_static_paths";
6
+ /** Internal endpoint for rendering a specific page during prerendering */
7
+ export declare const PRERENDER_ENDPOINT = "/__astro_prerender";
@@ -0,0 +1,6 @@
1
+ const STATIC_PATHS_ENDPOINT = "/__astro_static_paths";
2
+ const PRERENDER_ENDPOINT = "/__astro_prerender";
3
+ export {
4
+ PRERENDER_ENDPOINT,
5
+ STATIC_PATHS_ENDPOINT
6
+ };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Prerender utilities for Cloudflare adapter
3
+ *
4
+ * During the build process, Astro prerenders pages by making requests to internal endpoints
5
+ * served by the Cloudflare worker running in workerd. These endpoints are:
6
+ *
7
+ * - `/__astro_static_paths`: Returns all static paths that need to be prerendered.
8
+ * The prerenderer calls this to discover which routes/pages need to be generated.
9
+ *
10
+ * - `/__astro_prerender`: Renders a specific page given its URL and route data.
11
+ * The prerenderer calls this for each path to generate the static HTML.
12
+ *
13
+ * These endpoints are only active during the prerender build phase and are not
14
+ * available in production or development.
15
+ */
16
+ import type { BaseApp } from 'astro/app';
17
+ /**
18
+ * Checks if the request is for the static paths prerender endpoint.
19
+ * This endpoint returns all paths that need to be prerendered.
20
+ */
21
+ export declare function isStaticPathsRequest(request: Request): boolean;
22
+ /**
23
+ * Checks if the request is for the prerender endpoint.
24
+ * This endpoint renders a specific page during the prerender phase.
25
+ */
26
+ export declare function isPrerenderRequest(request: Request): boolean;
27
+ /**
28
+ * Handles the static paths request, returning all paths that need prerendering.
29
+ */
30
+ export declare function handleStaticPathsRequest(app: BaseApp): Promise<Response>;
31
+ /**
32
+ * Handles a prerender request, rendering the specified page.
33
+ */
34
+ export declare function handlePrerenderRequest(app: BaseApp, request: Request): Promise<Response>;
@@ -0,0 +1,43 @@
1
+ import { serializeRouteData, deserializeRouteData } from "astro/app/manifest";
2
+ import { StaticPaths } from "astro:static-paths";
3
+ import { STATIC_PATHS_ENDPOINT, PRERENDER_ENDPOINT } from "./prerender-constants.js";
4
+ function isStaticPathsRequest(request) {
5
+ const { pathname } = new URL(request.url);
6
+ return pathname === STATIC_PATHS_ENDPOINT && request.method === "POST";
7
+ }
8
+ function isPrerenderRequest(request) {
9
+ const { pathname } = new URL(request.url);
10
+ return pathname === PRERENDER_ENDPOINT && request.method === "POST";
11
+ }
12
+ async function handleStaticPathsRequest(app) {
13
+ const staticPaths = new StaticPaths(app);
14
+ const paths = await staticPaths.getAll();
15
+ const response = {
16
+ paths: paths.map(({ pathname, route }) => ({
17
+ pathname,
18
+ route: serializeRouteData(route, app.manifest.trailingSlash)
19
+ }))
20
+ };
21
+ return new Response(JSON.stringify(response), {
22
+ headers: { "Content-Type": "application/json" }
23
+ });
24
+ }
25
+ async function handlePrerenderRequest(app, request) {
26
+ const headers = new Headers();
27
+ for (const [key, value] of request.headers.entries()) {
28
+ headers.append(key, value);
29
+ }
30
+ const body = await request.json();
31
+ const routeData = deserializeRouteData(body.routeData);
32
+ const prerenderRequest = new Request(body.url, {
33
+ method: "GET",
34
+ headers
35
+ });
36
+ return app.render(prerenderRequest, { routeData });
37
+ }
38
+ export {
39
+ handlePrerenderRequest,
40
+ handleStaticPathsRequest,
41
+ isPrerenderRequest,
42
+ isStaticPathsRequest
43
+ };
@@ -1,6 +1,6 @@
1
1
  import type { PluginOption } from 'vite';
2
- interface CloudflareConfig {
2
+ export interface Config {
3
3
  sessionKVBindingName: string;
4
+ isPrerender: boolean;
4
5
  }
5
- export declare function createConfigPlugin(config: CloudflareConfig): PluginOption;
6
- export {};
6
+ export declare function createConfigPlugin(config: Omit<Config, 'isPrerender'>): PluginOption;
@@ -2,7 +2,7 @@ const VIRTUAL_CONFIG_ID = "virtual:astro-cloudflare:config";
2
2
  const RESOLVED_VIRTUAL_CONFIG_ID = "\0" + VIRTUAL_CONFIG_ID;
3
3
  function createConfigPlugin(config) {
4
4
  return {
5
- name: "vite:astro-cloudflare-config",
5
+ name: VIRTUAL_CONFIG_ID,
6
6
  resolveId: {
7
7
  filter: {
8
8
  id: new RegExp(`^${VIRTUAL_CONFIG_ID}$`)
@@ -16,7 +16,10 @@ function createConfigPlugin(config) {
16
16
  id: new RegExp(`^${RESOLVED_VIRTUAL_CONFIG_ID}$`)
17
17
  },
18
18
  handler() {
19
- return `export const sessionKVBindingName = ${JSON.stringify(config.sessionKVBindingName)};`;
19
+ return [
20
+ ...Object.entries(config).map(([k, v]) => `export const ${k} = ${JSON.stringify(v)};`),
21
+ `export const isPrerender = ${this.environment?.name === "prerender"};`
22
+ ].join("\n");
20
23
  }
21
24
  }
22
25
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@astrojs/cloudflare",
3
3
  "description": "Deploy your site to Cloudflare Workers/Pages",
4
- "version": "13.0.0-beta.5",
4
+ "version": "13.0.0-beta.6",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "author": "withastro",
@@ -35,12 +35,11 @@
35
35
  "types.d.ts"
36
36
  ],
37
37
  "dependencies": {
38
- "@cloudflare/vite-plugin": "^1.22.1",
39
- "dotenv": "^17.2.3",
38
+ "@cloudflare/vite-plugin": "^1.23.0",
40
39
  "piccolore": "^0.1.3",
41
40
  "tinyglobby": "^0.2.15",
42
41
  "vite": "^7.3.1",
43
- "@astrojs/internal-helpers": "0.8.0-beta.0",
42
+ "@astrojs/internal-helpers": "0.8.0-beta.1",
44
43
  "@astrojs/underscore-redirects": "1.0.0"
45
44
  },
46
45
  "peerDependencies": {
@@ -49,10 +48,10 @@
49
48
  },
50
49
  "devDependencies": {
51
50
  "@cloudflare/workers-types": "^4.20260131.0",
51
+ "@types/node": "^25.2.2",
52
52
  "cheerio": "1.2.0",
53
53
  "devalue": "^5.6.2",
54
- "rollup": "^4.57.1",
55
- "astro": "6.0.0-beta.9",
54
+ "astro": "6.0.0-beta.10",
56
55
  "astro-scripts": "0.0.14"
57
56
  },
58
57
  "publishConfig": {
@@ -1,16 +0,0 @@
1
- import type { PluginOption } from 'vite';
2
- /**
3
- * Enables support for various non-standard extensions in module imports that cloudflare workers supports.
4
- *
5
- * See https://developers.cloudflare.com/pages/functions/module-support/ for reference
6
- *
7
- * This adds supports for imports in the following formats:
8
- * - .wasm
9
- * - .wasm?module
10
- * - .bin
11
- * - .txt
12
- *
13
- * @param enabled - if true, will load all cloudflare pages supported types
14
- * @returns Vite plugin with additional extension method to hook into astro build
15
- */
16
- export declare function cloudflareModuleLoader(enabled: boolean): PluginOption;
@@ -1,152 +0,0 @@
1
- import * as fs from "node:fs/promises";
2
- import * as path from "node:path";
3
- function cloudflareModuleLoader(enabled) {
4
- const adaptersByExtension = enabled ? { ...defaultAdapters } : {};
5
- const extensions = Object.keys(adaptersByExtension);
6
- let isDev = false;
7
- const MAGIC_STRING = "__CLOUDFLARE_ASSET__";
8
- const replacements = [];
9
- return {
10
- name: "vite:cf-module-loader",
11
- enforce: "pre",
12
- applyToEnvironment(environment) {
13
- return environment.name === "ssr" || environment.name === "client";
14
- },
15
- configResolved(config) {
16
- isDev = config.command === "serve";
17
- },
18
- config(_, __) {
19
- return {
20
- assetsInclude: extensions.map((x) => `**/*${x}`),
21
- build: {
22
- rollupOptions: {
23
- // mark the wasm files as external so that they are not bundled and instead are loaded from the files
24
- external: extensions.map(
25
- (x) => new RegExp(`^${MAGIC_STRING}.+${escapeRegExp(x)}$`, "i")
26
- )
27
- }
28
- }
29
- };
30
- },
31
- load: {
32
- filter: {
33
- // Escape the dot in the regex
34
- id: new RegExp(`.(${extensions.map((ext) => ext.slice(1)).join("|")})$`)
35
- },
36
- async handler(id, _) {
37
- const maybeExtension = extensions.find((x) => id.endsWith(x));
38
- const moduleType = adaptersByExtension[maybeExtension];
39
- if (!enabled) {
40
- throw new Error(
41
- `Cloudflare module loading is experimental. The ${maybeExtension} module cannot be loaded unless you add \`cloudflareModules: true\` to your astro config.`
42
- );
43
- }
44
- const moduleLoader = renderers[moduleType];
45
- const filePath = id.replace(/\?\w+$/, "");
46
- const extension = maybeExtension.replace(/\?\w+$/, "");
47
- const data = await fs.readFile(filePath);
48
- const base64 = data.toString("base64");
49
- const inlineModule = moduleLoader(data);
50
- if (isDev) {
51
- return inlineModule;
52
- }
53
- const hash = hashString(base64);
54
- const assetName = `${path.basename(filePath).split(".")[0]}.${hash}${extension}`;
55
- this.emitFile({
56
- type: "asset",
57
- // emit the data explicitly as an asset with `fileName` rather than `name` so that
58
- // vite doesn't give it a random hash-id in its name--We need to be able to easily rewrite from
59
- // the loader and the actual asset later in the build for the worker
60
- fileName: assetName,
61
- source: data
62
- });
63
- const chunkId = this.emitFile({
64
- type: "prebuilt-chunk",
65
- fileName: assetName,
66
- code: inlineModule
67
- });
68
- return `import module from "${MAGIC_STRING}${chunkId}${extension}";export default module;`;
69
- }
70
- },
71
- // output original wasm file relative to the chunk now that chunking has been achieved
72
- renderChunk(code, chunk, _) {
73
- if (isDev) return;
74
- if (!code.includes(MAGIC_STRING)) return;
75
- let replaced = code;
76
- for (const ext of extensions) {
77
- const extension = ext.replace(/\?\w+$/, "");
78
- replaced = replaced.replaceAll(
79
- new RegExp(`${MAGIC_STRING}([^\\s]+?)${escapeRegExp(extension)}`, "g"),
80
- (_s, assetId) => {
81
- const fileName = this.getFileName(assetId);
82
- const relativePath = path.relative(path.dirname(chunk.fileName), fileName).replaceAll("\\", "/");
83
- replacements.push({
84
- chunkName: chunk.name,
85
- cloudflareImport: relativePath,
86
- nodejsImport: relativePath
87
- });
88
- return `./${relativePath}`;
89
- }
90
- );
91
- }
92
- return { code: replaced };
93
- },
94
- generateBundle(_, bundle) {
95
- const replacementsByChunkName = /* @__PURE__ */ new Map();
96
- for (const replacement of replacements) {
97
- const repls = replacementsByChunkName.get(replacement.chunkName) || [];
98
- if (!repls.length) {
99
- replacementsByChunkName.set(replacement.chunkName, repls);
100
- }
101
- repls.push(replacement);
102
- }
103
- for (const chunk of Object.values(bundle)) {
104
- const repls = chunk.name && replacementsByChunkName.get(chunk.name);
105
- for (const replacement of repls || []) {
106
- if (!replacement.fileName) {
107
- replacement.fileName = [];
108
- }
109
- replacement.fileName.push(chunk.fileName);
110
- }
111
- }
112
- }
113
- };
114
- }
115
- const renderers = {
116
- CompiledWasm(fileContents) {
117
- const base64 = fileContents.toString("base64");
118
- return `const wasmModule = new WebAssembly.Module(Uint8Array.from(atob("${base64}"), c => c.charCodeAt(0)));export default wasmModule;`;
119
- },
120
- Data(fileContents) {
121
- const base64 = fileContents.toString("base64");
122
- return `const binModule = Uint8Array.from(atob("${base64}"), c => c.charCodeAt(0)).buffer;export default binModule;`;
123
- },
124
- Text(fileContents) {
125
- const escaped = JSON.stringify(fileContents.toString("utf-8"));
126
- return `const stringModule = ${escaped};export default stringModule;`;
127
- }
128
- };
129
- const defaultAdapters = {
130
- // Loads '*.wasm?module' imports as WebAssembly modules, which is the only way to load WASM in cloudflare workers.
131
- // Current proposal for WASM modules: https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration
132
- ".wasm?module": "CompiledWasm",
133
- // treats the module as a WASM module
134
- ".wasm": "CompiledWasm",
135
- ".bin": "Data",
136
- ".txt": "Text"
137
- };
138
- function hashString(str) {
139
- let hash = 0;
140
- for (let i = 0; i < str.length; i++) {
141
- const char = str.charCodeAt(i);
142
- hash = (hash << 5) - hash + char;
143
- hash &= hash;
144
- }
145
- return new Uint32Array([hash])[0].toString(36);
146
- }
147
- function escapeRegExp(string) {
148
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
149
- }
150
- export {
151
- cloudflareModuleLoader
152
- };