Skip to content

Commit 0e339a1

Browse files
committed
next/after support
1 parent 0a341db commit 0e339a1

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed

packages/open-next/src/adapters/edge-adapter.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import type { ReadableStream } from "node:stream/web";
22

33
import type { InternalEvent, InternalResult } from "types/open-next";
4-
import { awaitAllDetachedPromise } from "utils/promise";
4+
import {
5+
awaitAllDetachedPromise,
6+
provideNextAfterProvider,
7+
} from "utils/promise";
58
import { emptyReadableStream } from "utils/stream";
69

710
// We import it like that so that the edge plugin can replace it
@@ -27,6 +30,7 @@ const defaultHandler = async (
2730
return globalThis.__als.run(
2831
{ requestId, pendingPromiseRunner, isISRRevalidation },
2932
async () => {
33+
provideNextAfterProvider();
3034
const host = internalEvent.headers.host
3135
? `https://${internalEvent.headers.host}`
3236
: "http://localhost:3000";

packages/open-next/src/adapters/middleware.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import type { InternalEvent, Origin } from "types/open-next";
2-
import { awaitAllDetachedPromise } from "utils/promise";
2+
import {
3+
awaitAllDetachedPromise,
4+
provideNextAfterProvider,
5+
} from "utils/promise";
36

47
import { debug } from "../adapters/logger";
58
import { createGenericHandler } from "../core/createGenericHandler";
@@ -45,6 +48,7 @@ const defaultHandler = async (internalEvent: InternalEvent) => {
4548
isISRRevalidation,
4649
},
4750
async () => {
51+
provideNextAfterProvider();
4852
const result = await routingHandler(internalEvent);
4953
if ("internalEvent" in result) {
5054
debug("Middleware intercepted event", internalEvent);

packages/open-next/src/core/requestHandler.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { AsyncLocalStorage } from "node:async_hooks";
33
import type { OpenNextNodeResponse, StreamCreator } from "http/index.js";
44
import { IncomingMessage } from "http/index.js";
55
import type { InternalEvent, InternalResult } from "types/open-next";
6-
import { awaitAllDetachedPromise } from "utils/promise";
6+
import {
7+
awaitAllDetachedPromise,
8+
provideNextAfterProvider,
9+
} from "utils/promise";
710

811
import { debug, error, warn } from "../adapters/logger";
912
import { generateOpenNextRequestContext } from "../adapters/util";
@@ -40,6 +43,7 @@ export async function openNextHandler(
4043
internalEvent.headers.host = internalEvent.headers["x-forwarded-host"];
4144
}
4245
debug("internalEvent", internalEvent);
46+
provideNextAfterProvider();
4347

4448
let preprocessResult: InternalResult | MiddlewareOutputEvent = {
4549
internalEvent: internalEvent,

packages/open-next/src/utils/promise.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,34 @@ export async function awaitAllDetachedPromise() {
6969
}
7070
await promisesToAwait;
7171
}
72+
73+
export function provideNextAfterProvider() {
74+
/** This should be considered unstable until `unstable_after` is stablized. */
75+
const NEXT_REQUEST_CONTEXT_SYMBOL = Symbol.for("@next/request-context");
76+
77+
// This is needed by some lib that relies on the vercel request context to properly await stuff.
78+
// Remove this when vercel builder is updated to provide '@next/request-context'.
79+
const VERCEL_REQUEST_CONTEXT_SYMBOL = Symbol.for("@vercel/request-context");
80+
81+
const openNextStoreContext = globalThis.__als.getStore();
82+
83+
const awaiter =
84+
globalThis.openNextWaitUntil ??
85+
((promise: Promise<unknown>) =>
86+
openNextStoreContext?.pendingPromiseRunner.add(promise));
87+
88+
const nextAfterContext = {
89+
get: () => ({
90+
waitUntil: awaiter,
91+
}),
92+
};
93+
94+
//@ts-expect-error
95+
globalThis[NEXT_REQUEST_CONTEXT_SYMBOL] = nextAfterContext;
96+
// We probably want to avoid providing this everytime since some lib may incorrectly think they are running in Vercel
97+
// It may break stuff, but at the same time it will allow libs like `@vercel/otel` to work as expected
98+
if (process.env.EMULATE_VERCEL_REQUEST_CONTEXT) {
99+
//@ts-expect-error
100+
globalThis[VERCEL_REQUEST_CONTEXT_SYMBOL] = nextAfterContext;
101+
}
102+
}

0 commit comments

Comments
 (0)