Skip to content

Commit 4be38fa

Browse files
committed
use ALS for entire process object
1 parent e7f9206 commit 4be38fa

File tree

2 files changed

+42
-46
lines changed

2 files changed

+42
-46
lines changed

packages/cloudflare/src/cli/templates/utils/create-als-proxy.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,11 @@ import type { AsyncLocalStorage } from "node:async_hooks";
55
*
66
* @param als AsyncLocalStorage instance
77
*/
8-
export function createALSProxy<T>(als: AsyncLocalStorage<T>) {
9-
return new Proxy(
10-
{},
11-
{
12-
ownKeys: () => Reflect.ownKeys(als.getStore()!),
13-
getOwnPropertyDescriptor: (_, ...args) => Reflect.getOwnPropertyDescriptor(als.getStore()!, ...args),
14-
get: (_, property) => Reflect.get(als.getStore()!, property),
15-
set: (_, property, value) => Reflect.set(als.getStore()!, property, value),
16-
}
17-
);
8+
export function createALSProxy<T extends object>(als: AsyncLocalStorage<T>) {
9+
return new Proxy({} as T, {
10+
ownKeys: () => Reflect.ownKeys(als.getStore()!),
11+
getOwnPropertyDescriptor: (_, ...args) => Reflect.getOwnPropertyDescriptor(als.getStore()!, ...args),
12+
get: (_, property) => Reflect.get(als.getStore()!, property),
13+
set: (_, property, value) => Reflect.set(als.getStore()!, property, value),
14+
});
1815
}

packages/cloudflare/src/cli/templates/worker.ts

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,14 @@ import { createALSProxy } from "./utils";
1313

1414
const NON_BODY_RESPONSES = new Set([101, 204, 205, 304]);
1515

16-
const processEnvALS = new AsyncLocalStorage<Record<string, unknown>>();
16+
const processALS = new AsyncLocalStorage<typeof process>();
1717
const cloudflareContextALS = new AsyncLocalStorage<CloudflareContext>();
1818

1919
// Note: this symbol needs to be kept in sync with the one defined in `src/api/get-cloudflare-context.ts`
2020
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2121
(globalThis as any)[Symbol.for("__cloudflare-context__")] = createALSProxy(cloudflareContextALS);
2222

23-
globalThis.process = {
24-
...globalThis.process,
25-
// @ts-expect-error - populated when we run inside the ALS context
26-
env: createALSProxy(processEnvALS),
27-
};
23+
globalThis.process = createALSProxy(processALS);
2824

2925
// Injected at build time
3026
const nextConfig: NextConfig = JSON.parse(process.env.__NEXT_PRIVATE_STANDALONE_CONFIG ?? "{}");
@@ -33,42 +29,45 @@ let requestHandler: NodeRequestHandler | null = null;
3329

3430
export default {
3531
async fetch(request, env, ctx) {
36-
return processEnvALS.run({ NODE_ENV: "production", ...env }, () => {
37-
return cloudflareContextALS.run({ env, ctx, cf: request.cf }, async () => {
38-
if (requestHandler == null) {
39-
// Note: "next/dist/server/next-server" is a cjs module so we have to `require` it not to confuse esbuild
40-
// (since esbuild can run in projects with different module resolutions)
41-
// eslint-disable-next-line @typescript-eslint/no-require-imports
42-
const NextNodeServer = require("next/dist/server/next-server")
43-
.default as typeof import("next/dist/server/next-server").default;
44-
45-
requestHandler = new NextNodeServer({
46-
conf: nextConfig,
47-
customServer: false,
48-
dev: false,
49-
dir: "",
50-
minimalMode: false,
51-
}).getRequestHandler();
52-
}
32+
return processALS.run(
33+
{ ...globalThis.process, env: { ...globalThis.process.env, NODE_ENV: "production", ...env } },
34+
() => {
35+
return cloudflareContextALS.run({ env, ctx, cf: request.cf }, async () => {
36+
if (requestHandler == null) {
37+
// Note: "next/dist/server/next-server" is a cjs module so we have to `require` it not to confuse esbuild
38+
// (since esbuild can run in projects with different module resolutions)
39+
// eslint-disable-next-line @typescript-eslint/no-require-imports
40+
const NextNodeServer = require("next/dist/server/next-server")
41+
.default as typeof import("next/dist/server/next-server").default;
42+
43+
requestHandler = new NextNodeServer({
44+
conf: nextConfig,
45+
customServer: false,
46+
dev: false,
47+
dir: "",
48+
minimalMode: false,
49+
}).getRequestHandler();
50+
}
5351

54-
const url = new URL(request.url);
52+
const url = new URL(request.url);
5553

56-
if (url.pathname === "/_next/image") {
57-
const imageUrl =
58-
url.searchParams.get("url") ?? "https://developers.cloudflare.com/_astro/logo.BU9hiExz.svg";
59-
if (imageUrl.startsWith("/")) {
60-
return env.ASSETS.fetch(new URL(imageUrl, request.url));
54+
if (url.pathname === "/_next/image") {
55+
const imageUrl =
56+
url.searchParams.get("url") ?? "https://developers.cloudflare.com/_astro/logo.BU9hiExz.svg";
57+
if (imageUrl.startsWith("/")) {
58+
return env.ASSETS.fetch(new URL(imageUrl, request.url));
59+
}
60+
return fetch(imageUrl, { cf: { cacheEverything: true } });
6161
}
62-
return fetch(imageUrl, { cf: { cacheEverything: true } });
63-
}
6462

65-
const { req, res, webResponse } = getWrappedStreams(request, ctx);
63+
const { req, res, webResponse } = getWrappedStreams(request, ctx);
6664

67-
ctx.waitUntil(Promise.resolve(requestHandler(new NodeNextRequest(req), new NodeNextResponse(res))));
65+
ctx.waitUntil(Promise.resolve(requestHandler(new NodeNextRequest(req), new NodeNextResponse(res))));
6866

69-
return await webResponse();
70-
});
71-
});
67+
return await webResponse();
68+
});
69+
}
70+
);
7271
},
7372
} as ExportedHandler<{ ASSETS: Fetcher }>;
7473

0 commit comments

Comments
 (0)