diff --git a/packages/next/package.json b/packages/next/package.json index d57fedd7033ff8..be5da70812d07f 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -304,6 +304,7 @@ "querystring-es3": "0.2.1", "raw-body": "2.4.1", "react-refresh": "0.12.0", + "recast": "0.23.11", "regenerator-runtime": "0.13.4", "sass-loader": "15.0.0", "schema-utils2": "npm:schema-utils@2.7.1", diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js index 01da5da5d6bf46..0990d97633b0bb 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js @@ -35,6 +35,15 @@ "use strict"; "production" !== process.env.NODE_ENV && (function () { + // This is a patch added by Next.js + const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); function styleReplacer(match, prefix, s, suffix) { return "" + prefix + ("s" === s ? "\\73 " : "\\53 ") + suffix; } @@ -4903,7 +4912,7 @@ }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createSuspenseBoundary( request, @@ -8473,7 +8482,7 @@ request ) : enqueueEarlyPreloadsAfterInitialWork(request)); - }, 0); + }); } function enqueueEarlyPreloadsAfterInitialWork(request) { safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); @@ -8488,7 +8497,7 @@ destination ? flushCompletedQueues(request, destination) : (request.flushScheduled = !1); - }, 0)); + })); } function startFlowing(request, destination) { if (13 === request.status) @@ -10392,16 +10401,5 @@ startWork(request); }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.version = "19.2.0-experimental-197d6a04-20250424"; })(); diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js index 117b5dd7753bdd..8d3fe9168ca2dc 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js @@ -1,3 +1,12 @@ +// This is a patch added by Next.js +const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); /** * @license React * react-dom-server.edge.production.js @@ -4411,7 +4420,7 @@ function pingTask(request, task) { }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createSuspenseBoundary( request, @@ -6936,7 +6945,7 @@ function startWork(request) { request ) : enqueueEarlyPreloadsAfterInitialWork(request)); - }, 0); + }); } function enqueueEarlyPreloadsAfterInitialWork(request) { safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); @@ -6951,7 +6960,7 @@ function enqueueFlush(request) { destination ? flushCompletedQueues(request, destination) : (request.flushScheduled = !1); - }, 0)); + })); } function startFlowing(request, destination) { if (13 === request.status) @@ -7305,15 +7314,4 @@ exports.resumeAndPrerender = function (children, postponedState, options) { startWork(request); }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.version = "19.2.0-experimental-197d6a04-20250424"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js index 444136a74fb135..14ab76a2105865 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js @@ -35,6 +35,15 @@ "use strict"; "production" !== process.env.NODE_ENV && (function () { + // This is a patch added by Next.js + const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); function styleReplacer(match, prefix, s, suffix) { return "" + prefix + ("s" === s ? "\\73 " : "\\53 ") + suffix; } @@ -4565,7 +4574,7 @@ }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createSuspenseBoundary( request, @@ -7704,7 +7713,7 @@ request ) : enqueueEarlyPreloadsAfterInitialWork(request)); - }, 0); + }); } function enqueueEarlyPreloadsAfterInitialWork(request) { safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); @@ -7719,7 +7728,7 @@ destination ? flushCompletedQueues(request, destination) : (request.flushScheduled = !1); - }, 0)); + })); } function startFlowing(request, destination) { if (13 === request.status) @@ -9439,16 +9448,5 @@ startWork(request); }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.version = "19.2.0-canary-197d6a04-20250424"; })(); diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js index 1c0ddceb106740..9a68913b21de90 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js @@ -1,3 +1,12 @@ +// This is a patch added by Next.js +const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); /** * @license React * react-dom-server.edge.production.js @@ -4078,7 +4087,7 @@ function pingTask(request, task) { }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createSuspenseBoundary( request, @@ -6262,7 +6271,7 @@ function startWork(request) { request ) : enqueueEarlyPreloadsAfterInitialWork(request)); - }, 0); + }); } function enqueueEarlyPreloadsAfterInitialWork(request) { safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); @@ -6277,7 +6286,7 @@ function enqueueFlush(request) { destination ? flushCompletedQueues(request, destination) : (request.flushScheduled = !1); - }, 0)); + })); } function startFlowing(request, destination) { if (13 === request.status) @@ -6468,15 +6477,4 @@ exports.renderToReadableStream = function (children, options) { startWork(request); }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.version = "19.2.0-canary-197d6a04-20250424"; diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.development.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.development.js index ad8c0650ffbaf0..8b8739ab0e141e 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.development.js @@ -11,6 +11,15 @@ "use strict"; "production" !== process.env.NODE_ENV && (function () { + // This is a patch added by Next.js + const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); function voidHandler() {} function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) @@ -1445,7 +1454,7 @@ }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createTask( request, @@ -2826,7 +2835,7 @@ }); setTimeoutOrImmediate(function () { request.status === OPENING && (request.status = 11); - }, 0); + }); } function enqueueFlush(request) { !1 === request.flushScheduled && @@ -2837,7 +2846,7 @@ request.flushScheduled = !1; var destination = request.destination; destination && flushCompletedChunks(request, destination); - }, 0)); + })); } function callOnAllReadyIfReady(request) { if ( @@ -4303,17 +4312,6 @@ bind: { value: bind, configurable: !0 } }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.renderToReadableStream = function (model, turbopackMap, options) { var request = createRequest( model, diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.production.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.production.js index 4ca23bd6c40d6e..620dc0df307c04 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.production.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.production.js @@ -1,3 +1,12 @@ +// This is a patch added by Next.js +const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); /** * @license React * react-server-dom-turbopack-server.edge.production.js @@ -1144,7 +1153,7 @@ function pingTask(request, task) { }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1949,7 +1958,7 @@ function startWork(request) { }); setTimeoutOrImmediate(function () { 10 === request.status && (request.status = 11); - }, 0); + }); } function enqueueFlush(request) { !1 === request.flushScheduled && @@ -1960,7 +1969,7 @@ function enqueueFlush(request) { request.flushScheduled = !1; var destination = request.destination; destination && flushCompletedChunks(request, destination); - }, 0)); + })); } function callOnAllReadyIfReady(request) { if (0 === request.abortableTasks.size && 0 === request.abortListeners.size) @@ -2881,17 +2890,6 @@ exports.registerServerReference = function (reference, id, exportName) { bind: { value: bind, configurable: !0 } }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.renderToReadableStream = function (model, turbopackMap, options) { var request = new RequestInstance( 20, diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js index 51d557f2add18f..04a09df7a494c6 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js @@ -11,6 +11,15 @@ "use strict"; "production" !== process.env.NODE_ENV && (function () { + // This is a patch added by Next.js + const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); function voidHandler() {} function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) @@ -1415,7 +1424,7 @@ }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createTask( request, @@ -2667,7 +2676,7 @@ }); setTimeoutOrImmediate(function () { request.status === OPENING && (request.status = 11); - }, 0); + }); } function enqueueFlush(request) { !1 === request.flushScheduled && @@ -2678,7 +2687,7 @@ request.flushScheduled = !1; var destination = request.destination; destination && flushCompletedChunks(request, destination); - }, 0)); + })); } function callOnAllReadyIfReady(request) { if ( @@ -4102,17 +4111,6 @@ bind: { value: bind, configurable: !0 } }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.renderToReadableStream = function (model, turbopackMap, options) { var request = createRequest( model, diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.js index de7961ef413a44..feec70823829e9 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.js @@ -1,3 +1,12 @@ +// This is a patch added by Next.js +const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); /** * @license React * react-server-dom-turbopack-server.edge.production.js @@ -1112,7 +1121,7 @@ function pingTask(request, task) { }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1840,7 +1849,7 @@ function startWork(request) { }); setTimeoutOrImmediate(function () { 10 === request.status && (request.status = 11); - }, 0); + }); } function enqueueFlush(request) { !1 === request.flushScheduled && @@ -1851,7 +1860,7 @@ function enqueueFlush(request) { request.flushScheduled = !1; var destination = request.destination; destination && flushCompletedChunks(request, destination); - }, 0)); + })); } function callOnAllReadyIfReady(request) { if (0 === request.abortableTasks.size && 0 === request.abortListeners.size) @@ -2754,17 +2763,6 @@ exports.registerServerReference = function (reference, id, exportName) { bind: { value: bind, configurable: !0 } }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.renderToReadableStream = function (model, turbopackMap, options) { var request = new RequestInstance( 20, diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.development.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.development.js index 6d49aff71eb049..54989fa74bfdbe 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.development.js @@ -11,6 +11,15 @@ "use strict"; "production" !== process.env.NODE_ENV && (function () { + // This is a patch added by Next.js + const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); function voidHandler() {} function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) @@ -1445,7 +1454,7 @@ }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createTask( request, @@ -2826,7 +2835,7 @@ }); setTimeoutOrImmediate(function () { request.status === OPENING && (request.status = 11); - }, 0); + }); } function enqueueFlush(request) { !1 === request.flushScheduled && @@ -2837,7 +2846,7 @@ request.flushScheduled = !1; var destination = request.destination; destination && flushCompletedChunks(request, destination); - }, 0)); + })); } function callOnAllReadyIfReady(request) { if ( @@ -4306,17 +4315,6 @@ bind: { value: bind, configurable: !0 } }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.renderToReadableStream = function (model, webpackMap, options) { var request = createRequest( model, diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.production.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.production.js index be86d67e390119..c917a9c618b983 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.production.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.production.js @@ -1,3 +1,12 @@ +// This is a patch added by Next.js +const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); /** * @license React * react-server-dom-webpack-server.edge.production.js @@ -1144,7 +1153,7 @@ function pingTask(request, task) { }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1949,7 +1958,7 @@ function startWork(request) { }); setTimeoutOrImmediate(function () { 10 === request.status && (request.status = 11); - }, 0); + }); } function enqueueFlush(request) { !1 === request.flushScheduled && @@ -1960,7 +1969,7 @@ function enqueueFlush(request) { request.flushScheduled = !1; var destination = request.destination; destination && flushCompletedChunks(request, destination); - }, 0)); + })); } function callOnAllReadyIfReady(request) { if (0 === request.abortableTasks.size && 0 === request.abortListeners.size) @@ -2884,17 +2893,6 @@ exports.registerServerReference = function (reference, id, exportName) { bind: { value: bind, configurable: !0 } }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.renderToReadableStream = function (model, webpackMap, options) { var request = new RequestInstance( 20, diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js index 5c6a6514b9d9d8..08c37d2f1cb686 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js @@ -11,6 +11,15 @@ "use strict"; "production" !== process.env.NODE_ENV && (function () { + // This is a patch added by Next.js + const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); function voidHandler() {} function getIteratorFn(maybeIterable) { if (null === maybeIterable || "object" !== typeof maybeIterable) @@ -1415,7 +1424,7 @@ }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createTask( request, @@ -2667,7 +2676,7 @@ }); setTimeoutOrImmediate(function () { request.status === OPENING && (request.status = 11); - }, 0); + }); } function enqueueFlush(request) { !1 === request.flushScheduled && @@ -2678,7 +2687,7 @@ request.flushScheduled = !1; var destination = request.destination; destination && flushCompletedChunks(request, destination); - }, 0)); + })); } function callOnAllReadyIfReady(request) { if ( @@ -4105,17 +4114,6 @@ bind: { value: bind, configurable: !0 } }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.renderToReadableStream = function (model, webpackMap, options) { var request = createRequest( model, diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js index 0aa53bfb1f096b..6470f6ba70bd52 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js @@ -1,3 +1,12 @@ +// This is a patch added by Next.js +const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); /** * @license React * react-server-dom-webpack-server.edge.production.js @@ -1112,7 +1121,7 @@ function pingTask(request, task) { }) : setTimeoutOrImmediate(function () { return performWork(request); - }, 0)); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1840,7 +1849,7 @@ function startWork(request) { }); setTimeoutOrImmediate(function () { 10 === request.status && (request.status = 11); - }, 0); + }); } function enqueueFlush(request) { !1 === request.flushScheduled && @@ -1851,7 +1860,7 @@ function enqueueFlush(request) { request.flushScheduled = !1; var destination = request.destination; destination && flushCompletedChunks(request, destination); - }, 0)); + })); } function callOnAllReadyIfReady(request) { if (0 === request.abortableTasks.size && 0 === request.abortListeners.size) @@ -2757,17 +2766,6 @@ exports.registerServerReference = function (reference, id, exportName) { bind: { value: bind, configurable: !0 } }); }; - -// This is a patch added by Next.js -const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - exports.renderToReadableStream = function (model, webpackMap, options) { var request = new RequestInstance( 20, diff --git a/packages/next/taskfile.js b/packages/next/taskfile.js index 5bffe545402694..90cdbb3de2b4f8 100644 --- a/packages/next/taskfile.js +++ b/packages/next/taskfile.js @@ -8,6 +8,7 @@ const fs = require('fs/promises') const resolveFrom = require('resolve-from') const execa = require('execa') const process = require('process') +const recast = require('recast') export async function next__polyfill_nomodule(task, opts) { await task @@ -1633,11 +1634,11 @@ export async function copy_vendor_react(task_) { filepath ) ) { - newSource = replaceSetTimeout({ - code: newSource, - file: filepath, - insertBefore: /\n\s*exports\.version =/, + const ast = parseFile(newSource, { + sourceFileName: filepath, }) + replaceSetTimeoutInAst(ast, filepath) + newSource = recast.print(ast).code } file.data = newSource @@ -1647,11 +1648,10 @@ export async function copy_vendor_react(task_) { }) .target(`src/compiled/react-dom${packageSuffix}/cjs`) - function replaceSetTimeout({ - code, - file, - insertBefore: insertBeforePattern, - }) { + function replaceSetTimeoutInAst( + /** @type {recast.types.namedTypes.File} */ ast, + /** @type {string} */ filepath + ) { // FIXME: we need this hack until we can use the Node build of 'react-dom/server' // // We're currently using the Edge builds of 'react-dom/server' and 'react-server-dom-{webpack,turbopack}' everywhere. @@ -1665,41 +1665,166 @@ export async function copy_vendor_react(task_) { // setTimeout(() => ..., 0) // into this: // setImmediate(() => ...) - // - // ReactDOM only ever calls `setTimeout` with `0` (and no further arguments), - // so we can just naively replace `setTimeout` with `setImmediate`. - // Technically the `0` will then be passed to the callback as an argument, - // but the callbacks will always ignore it anyway. - // NOTE: we have to replace these before inserting the definition of `setTimeoutOrImmediate`, - // otherwise we'd break it! - code = code.replaceAll(`setTimeout`, `setTimeoutOrImmediate`) + recast.types.namedTypes.File.assert(ast) + const definitionStr = outdent` + // This is a patch added by Next.js + const setTimeoutOrImmediate = + typeof globalThis["set" + "Immediate"] === "function" && + // edge runtime sandbox defines a stub for setImmediate + // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) + // but it's made non-enumerable, so we can detect it + globalThis.propertyIsEnumerable("setImmediate") + ? globalThis["set" + "Immediate"] + : (callback, ...args) => setTimeout(callback, 0, ...args); + + ` + const getDefinitionStmt = () => { + const fileAst = /** @type {recast.types.namedTypes.File} */ ( + recast.parse(definitionStr) + ) + return fileAst.program.body[0] + } + + let needsDefinition = false + recast.visit(ast, { + visitCallExpression(path) { + const { callee, arguments: args } = path.node + + if (callee.type === 'Identifier' && callee.name === 'setTimeout') { + const durationArg = args.length >= 2 ? args[1] : undefined + if ( + // `setTimeout(fn)` + !durationArg || + // `setTimeout(fn, 0, ...)` + (durationArg.type === 'Literal' && durationArg.value === 0) || + // `setTimeout(fn, undefined, ...)` + (durationArg.type === 'Identifier' && + durationArg.name === 'undefined') + ) { + needsDefinition = true + // setTimeout(fn, 0, ...) -> + // setTimeoutOrImmediate(fn, ...) + callee.name = 'setTimeoutOrImmediate' + path.node.arguments = [args[0], ...args.slice(2)] + } + } + this.traverse(path) + }, + }) + + if (!needsDefinition) { + return + } - const insertionPoint = code.search(insertBeforePattern) - if (insertionPoint === -1) { + let didInsertDefinition = false + recast.visit(ast, { + visitAssignmentExpression(path) { + // we should only insert the definition of `setTimeoutOrImmediate` once. + if (didInsertDefinition) { + return false + } + + // Find the first `exports.NAME = ...` assignment + const { left: target } = path.node + if ( + target.type === 'MemberExpression' && + target.object.type === 'Identifier' && + target.object.name === 'exports' && + // we don't care about which export is being assigned. + target.property.type === 'Identifier' + ) { + didInsertDefinition = true + // We expect `exports` assignments to happen: + // - at the top level for prod builds of react + // - inside an IIFE for dev builds of react + // In either case, we now need find an ancestor node we can insert the definition into. + const blocklikeAncestor = findBlocklikeAncestor( + /** @type {recast.types.NodePath} */ (path) + ) + if (!blocklikeAncestor) { + throw new Error('Could not find a block to insert definition') + } + blocklikeAncestor.insertAt(0, getDefinitionStmt()) + } + + // we don't care about any assignment expressions that might happen in the RHS, + // React doesn't do that + return false + }, + }) + if (!didInsertDefinition) { throw new Error( - `Cannot find insertion point for setTimeoutOrImmediate in ${file}` + `Failed to find an insertion point for \`setTimeout\` replacement in '${filepath}'` ) } - const toInsert = - '\n\n' + - outdent` - // This is a patch added by Next.js - const setTimeoutOrImmediate = - typeof globalThis['set' + 'Immediate'] === 'function' && - // edge runtime sandbox defines a stub for setImmediate - // (see 'addStub' in packages/next/src/server/web/sandbox/context.ts) - // but it's made non-enumerable, so we can detect it - globalThis.propertyIsEnumerable('setImmediate') - ? globalThis['set' + 'Immediate'] - : setTimeout; - ` + - '\n' - - return ( - code.slice(0, insertionPoint) + toInsert + code.slice(insertionPoint) - ) + function findBlocklikeAncestor( + /** @type {recast.types.NodePath} */ path + ) { + /** @type {recast.types.NodePath | null} */ + let current = path + while (current) { + if ( + recast.types.namedTypes.BlockStatement.check(current.node) || + recast.types.namedTypes.Program.check(current.node) + ) { + break + } else { + current = current.parentPath + } + } + return current + } + } + + function replaceIdentifiersInAst( + /** @type {recast.types.namedTypes.File} */ ast, + /** @type {Map} */ replacements + ) { + recast.types.namedTypes.File.assert(ast) + recast.visit(ast, { + visitIdentifier(path) { + const replacement = replacements.get(path.node.name) + if (replacement !== undefined) { + path.replace(replacement) + } + this.traverse(path) + }, + }) + } + + function parseFile( + /** @type {string} */ code, + /** @type {recast.Options} */ opts + ) { + /** @type {recast.types.namedTypes.File} */ + const file = recast.parse(code, { + parser: { + parse(source, options) { + return require('recast/parsers/acorn').parse(source, { + ...options, + // allow `import()` in `react-server-dom-{webpack,turbopack}-client.node.unbundled.development.js` + ecmaVersion: 'latest', + sourceType: 'script', + }) + }, + }, + ...opts, + }) + return file + } + + /** @typedef {ReturnType} ExpressionKind */ + + function parseExpression(/** @type {string} */ exprCode) { + /** @type {recast.types.namedTypes.File} */ + const ast = recast.parse(`(${exprCode});`) + const statement = + /** @type {recast.types.namedTypes.ExpressionStatement} */ ( + ast.program.body[0] + ) + return statement.expression } // Remove unused files @@ -1753,19 +1878,22 @@ export async function copy_vendor_react(task_) { (file.base.startsWith('react-server-dom-webpack-server') && !file.base.startsWith('react-server-dom-webpack-server.browser')) ) { + const filepath = file.dir + '/' + file.base const source = file.data.toString() - let newSource = source.replace( - /__webpack_require__/g, - 'globalThis.__next_require__' + const ast = parseFile(source, { sourceFileName: filepath }) + replaceIdentifiersInAst( + ast, + new Map([ + [ + '__webpack_require__', + parseExpression('globalThis.__next_require__'), + ], + ]) ) if (file.base.startsWith('react-server-dom-webpack-server.edge')) { - newSource = replaceSetTimeout({ - code: newSource, - file: file.base, - insertBefore: /\n\s*exports\.renderToReadableStream =/, - }) + replaceSetTimeoutInAst(ast, filepath) } - file.data = newSource + file.data = recast.print(ast).code } else if (file.base === 'package.json') { file.data = overridePackageName(file.data) } @@ -1803,31 +1931,41 @@ export async function copy_vendor_react(task_) { if (file.base.startsWith('react-server-dom-turbopack-client.browser')) { const source = file.data.toString() - let newSource = source.replace( - /__turbopack_load__/g, - '__turbopack_load_by_url__' + const filepath = file.dir + '/' + file.base + const ast = parseFile(source, { sourceFileName: filepath }) + replaceIdentifiersInAst( + ast, + new Map([['__turbopack_load__', '__turbopack_load_by_url__']]) ) - - file.data = newSource + file.data = recast.print(ast).code } else if ( file.base.startsWith('react-server-dom-turbopack-client') || (file.base.startsWith('react-server-dom-turbopack-server') && !file.base.startsWith('react-server-dom-turbopack-server.browser')) ) { const source = file.data.toString() - let newSource = source - .replace(/__turbopack_load__/g, 'globalThis.__next_chunk_load__') - .replace(/__turbopack_require__/g, 'globalThis.__next_require__') + const filepath = file.dir + '/' + file.base + const ast = parseFile(source, { sourceFileName: filepath }) + + replaceIdentifiersInAst( + ast, + new Map([ + [ + '__turbopack_load__', + parseExpression('globalThis.__next_chunk_load__'), + ], + [ + '__turbopack_require__', + parseExpression('globalThis.__next_require__'), + ], + ]) + ) if (file.base.startsWith('react-server-dom-turbopack-server.edge')) { - newSource = replaceSetTimeout({ - code: newSource, - file: file.base, - insertBefore: /\n\s*exports\.renderToReadableStream =/, - }) + replaceSetTimeoutInAst(ast, filepath) } - file.data = newSource + file.data = recast.print(ast).code } else if (file.base === 'package.json') { file.data = overridePackageName(file.data) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aaa5d31f7e9727..65453c038abfb6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1432,6 +1432,9 @@ importers: react-refresh: specifier: 0.12.0 version: 0.12.0 + recast: + specifier: 0.23.11 + version: 0.23.11 regenerator-runtime: specifier: 0.13.4 version: 0.13.4 @@ -13692,6 +13695,7 @@ packages: engines: {node: '>=0.6.0', teleport: '>=0.2.0'} deprecated: |- You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other. + (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) qs@6.11.0: @@ -14000,6 +14004,10 @@ packages: resolution: {integrity: sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==} engines: {node: '>= 4'} + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + engines: {node: '>= 4'} + recast@0.23.9: resolution: {integrity: sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==} engines: {node: '>= 4'} @@ -20404,7 +20412,7 @@ snapshots: esbuild-register: 3.6.0(esbuild@0.24.2) jsdoc-type-pratt-parser: 4.0.0 process: 0.11.10 - recast: 0.23.9 + recast: 0.23.11 semver: 7.6.3 util: 0.12.5 ws: 8.2.3 @@ -31887,6 +31895,14 @@ snapshots: source-map: 0.6.1 tslib: 2.8.1 + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + recast@0.23.9: dependencies: ast-types: 0.16.1