This commit is contained in:
Kismet Hasanaj
2026-05-02 20:07:02 +02:00
parent ce8672e283
commit 34dc9aec52
9428 changed files with 1733330 additions and 0 deletions
@@ -0,0 +1,53 @@
import { InvariantError } from '../../../shared/lib/invariant-error';
import { isThenable } from '../../../shared/lib/is-thenable';
import { trackPendingImport } from './track-module-loading.external';
/**
* in CacheComponents, `import(...)` will be transformed into `trackDynamicImport(import(...))`.
* A dynamic import is essentially a cached async function, except it's cached by the module system.
*
* The promises are tracked globally regardless of if the `import()` happens inside a render or outside of it.
* When rendering, we can make the `cacheSignal` wait for all pending promises via `trackPendingModules`.
* */ export function trackDynamicImport(modulePromise) {
if (process.env.NEXT_RUNTIME === 'edge') {
throw Object.defineProperty(new InvariantError("Dynamic imports should not be instrumented in the edge runtime, because `cacheComponents` doesn't support it"), "__NEXT_ERROR_CODE", {
value: "E687",
enumerable: false,
configurable: true
});
}
if (!isThenable(modulePromise)) {
// We're expecting `import()` to always return a promise. If it's not, something's very wrong.
throw Object.defineProperty(new InvariantError('`trackDynamicImport` should always receive a promise. Something went wrong in the dynamic imports transform.'), "__NEXT_ERROR_CODE", {
value: "E677",
enumerable: false,
configurable: true
});
}
// Even if we're inside a prerender and have `workUnitStore.cacheSignal`, we always track the promise globally.
// (i.e. via the global `moduleLoadingSignal` that `trackPendingImport` uses internally).
//
// We do this because the `import()` promise might be cached in userspace:
// (which is quite common for e.g. lazy initialization in libraries)
//
// let promise;
// function doDynamicImportOnce() {
// if (!promise) {
// promise = import("...");
// // transformed into:
// // promise = trackDynamicImport(import("..."));
// }
// return promise;
// }
//
// If multiple prerenders (e.g. multiple pages) depend on `doDynamicImportOnce`,
// we have to wait for the import *in all of them*.
// If we only tracked it using `workUnitStore.cacheSignal.trackRead()`,
// then only the first prerender to call `doDynamicImportOnce` would wait --
// Subsequent prerenders would re-use the existing `promise`,
// and `trackDynamicImport` wouldn't be called again in their scope,
// so their respective CacheSignals wouldn't wait for the promise.
trackPendingImport(modulePromise);
return modulePromise;
}
//# sourceMappingURL=track-dynamic-import.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/server/app-render/module-loading/track-dynamic-import.ts"],"sourcesContent":["import { InvariantError } from '../../../shared/lib/invariant-error'\nimport { isThenable } from '../../../shared/lib/is-thenable'\nimport { trackPendingImport } from './track-module-loading.external'\n\n/**\n * in CacheComponents, `import(...)` will be transformed into `trackDynamicImport(import(...))`.\n * A dynamic import is essentially a cached async function, except it's cached by the module system.\n *\n * The promises are tracked globally regardless of if the `import()` happens inside a render or outside of it.\n * When rendering, we can make the `cacheSignal` wait for all pending promises via `trackPendingModules`.\n * */\nexport function trackDynamicImport<TExports extends Record<string, any>>(\n modulePromise: Promise<TExports>\n): Promise<TExports> {\n if (process.env.NEXT_RUNTIME === 'edge') {\n throw new InvariantError(\n \"Dynamic imports should not be instrumented in the edge runtime, because `cacheComponents` doesn't support it\"\n )\n }\n\n if (!isThenable(modulePromise)) {\n // We're expecting `import()` to always return a promise. If it's not, something's very wrong.\n throw new InvariantError(\n '`trackDynamicImport` should always receive a promise. Something went wrong in the dynamic imports transform.'\n )\n }\n\n // Even if we're inside a prerender and have `workUnitStore.cacheSignal`, we always track the promise globally.\n // (i.e. via the global `moduleLoadingSignal` that `trackPendingImport` uses internally).\n //\n // We do this because the `import()` promise might be cached in userspace:\n // (which is quite common for e.g. lazy initialization in libraries)\n //\n // let promise;\n // function doDynamicImportOnce() {\n // if (!promise) {\n // promise = import(\"...\");\n // // transformed into:\n // // promise = trackDynamicImport(import(\"...\"));\n // }\n // return promise;\n // }\n //\n // If multiple prerenders (e.g. multiple pages) depend on `doDynamicImportOnce`,\n // we have to wait for the import *in all of them*.\n // If we only tracked it using `workUnitStore.cacheSignal.trackRead()`,\n // then only the first prerender to call `doDynamicImportOnce` would wait --\n // Subsequent prerenders would re-use the existing `promise`,\n // and `trackDynamicImport` wouldn't be called again in their scope,\n // so their respective CacheSignals wouldn't wait for the promise.\n trackPendingImport(modulePromise)\n\n return modulePromise\n}\n"],"names":["InvariantError","isThenable","trackPendingImport","trackDynamicImport","modulePromise","process","env","NEXT_RUNTIME"],"mappings":"AAAA,SAASA,cAAc,QAAQ,sCAAqC;AACpE,SAASC,UAAU,QAAQ,kCAAiC;AAC5D,SAASC,kBAAkB,QAAQ,kCAAiC;AAEpE;;;;;;GAMG,GACH,OAAO,SAASC,mBACdC,aAAgC;IAEhC,IAAIC,QAAQC,GAAG,CAACC,YAAY,KAAK,QAAQ;QACvC,MAAM,qBAEL,CAFK,IAAIP,eACR,iHADI,qBAAA;mBAAA;wBAAA;0BAAA;QAEN;IACF;IAEA,IAAI,CAACC,WAAWG,gBAAgB;QAC9B,8FAA8F;QAC9F,MAAM,qBAEL,CAFK,IAAIJ,eACR,iHADI,qBAAA;mBAAA;wBAAA;0BAAA;QAEN;IACF;IAEA,+GAA+G;IAC/G,yFAAyF;IACzF,EAAE;IACF,0EAA0E;IAC1E,oEAAoE;IACpE,EAAE;IACF,iBAAiB;IACjB,qCAAqC;IACrC,sBAAsB;IACtB,iCAAiC;IACjC,6BAA6B;IAC7B,wDAAwD;IACxD,QAAQ;IACR,sBAAsB;IACtB,MAAM;IACN,EAAE;IACF,gFAAgF;IAChF,mDAAmD;IACnD,uEAAuE;IACvE,4EAA4E;IAC5E,6DAA6D;IAC7D,oEAAoE;IACpE,kEAAkE;IAClEE,mBAAmBE;IAEnB,OAAOA;AACT","ignoreList":[0]}
@@ -0,0 +1,9 @@
// NOTE: this is marked as shared/external because it's stateful
// and the state needs to be shared between app-render (which waits for pending imports)
// and helpers used in transformed page code (which register pending imports)
import { trackPendingChunkLoad, trackPendingImport, trackPendingModules } from './track-module-loading.instance' with {
'turbopack-transition': 'next-shared'
};
export { trackPendingChunkLoad, trackPendingImport, trackPendingModules };
//# sourceMappingURL=track-module-loading.external.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/server/app-render/module-loading/track-module-loading.external.ts"],"sourcesContent":["// NOTE: this is marked as shared/external because it's stateful\n// and the state needs to be shared between app-render (which waits for pending imports)\n// and helpers used in transformed page code (which register pending imports)\n\nimport {\n trackPendingChunkLoad,\n trackPendingImport,\n trackPendingModules,\n} from './track-module-loading.instance' with { 'turbopack-transition': 'next-shared' }\n\nexport { trackPendingChunkLoad, trackPendingImport, trackPendingModules }\n"],"names":["trackPendingChunkLoad","trackPendingImport","trackPendingModules"],"mappings":"AAAA,gEAAgE;AAChE,wFAAwF;AACxF,6EAA6E;AAE7E,SACEA,qBAAqB,EACrBC,kBAAkB,EAClBC,mBAAmB,QACd,uCAAuC;IAAE,wBAAwB;AAAc,EAAC;AAEvF,SAASF,qBAAqB,EAAEC,kBAAkB,EAAEC,mBAAmB,GAAE","ignoreList":[0]}
@@ -0,0 +1,47 @@
import { CacheSignal } from '../cache-signal';
import { isThenable } from '../../../shared/lib/is-thenable';
/**
* Tracks all in-flight async imports and chunk loads.
* Initialized lazily, because we don't want this to error in case it gets pulled into an edge runtime module.
*/ let _moduleLoadingSignal;
function getModuleLoadingSignal() {
if (!_moduleLoadingSignal) {
_moduleLoadingSignal = new CacheSignal();
}
return _moduleLoadingSignal;
}
export function trackPendingChunkLoad(promise) {
const moduleLoadingSignal = getModuleLoadingSignal();
moduleLoadingSignal.trackRead(promise);
}
export function trackPendingImport(exportsOrPromise) {
const moduleLoadingSignal = getModuleLoadingSignal();
// requiring an async module returns a promise.
// if it's sync, there's nothing to track.
if (isThenable(exportsOrPromise)) {
// A client reference proxy might look like a promise, but we can only call `.then()` on it, not e.g. `.finally()`.
// Turn it into a real promise to avoid issues elsewhere.
const promise = Promise.resolve(exportsOrPromise);
moduleLoadingSignal.trackRead(promise);
}
}
/**
* A top-level dynamic import (or chunk load):
*
* 1. delays a prerender (potentially for a task or longer)
* 2. may reveal more caches that need be filled
*
* So if we see one, we want to extend the duration of `cacheSignal` at least until the import/chunk-load is done.
*/ export function trackPendingModules(cacheSignal) {
const moduleLoadingSignal = getModuleLoadingSignal();
// We can't just use `cacheSignal.trackRead(moduleLoadingSignal.cacheReady())`,
// because we might start and finish multiple batches of module loads while waiting for caches,
// and `moduleLoadingSignal.cacheReady()` would resolve after the first batch.
// Instead, we'll keep notifying `cacheSignal` of each import/chunk-load.
const unsubscribe = moduleLoadingSignal.subscribeToReads(cacheSignal);
// Later, when `cacheSignal` is no longer waiting for any caches (or imports that we've notified it of),
// we can unsubscribe it.
cacheSignal.cacheReady().then(unsubscribe);
}
//# sourceMappingURL=track-module-loading.instance.js.map
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../../src/server/app-render/module-loading/track-module-loading.instance.ts"],"sourcesContent":["import { CacheSignal } from '../cache-signal'\nimport { isThenable } from '../../../shared/lib/is-thenable'\n\n/**\n * Tracks all in-flight async imports and chunk loads.\n * Initialized lazily, because we don't want this to error in case it gets pulled into an edge runtime module.\n */\nlet _moduleLoadingSignal: CacheSignal | null\nfunction getModuleLoadingSignal() {\n if (!_moduleLoadingSignal) {\n _moduleLoadingSignal = new CacheSignal()\n }\n return _moduleLoadingSignal\n}\n\nexport function trackPendingChunkLoad(promise: Promise<unknown>) {\n const moduleLoadingSignal = getModuleLoadingSignal()\n moduleLoadingSignal.trackRead(promise)\n}\n\nexport function trackPendingImport(exportsOrPromise: unknown) {\n const moduleLoadingSignal = getModuleLoadingSignal()\n\n // requiring an async module returns a promise.\n // if it's sync, there's nothing to track.\n if (isThenable(exportsOrPromise)) {\n // A client reference proxy might look like a promise, but we can only call `.then()` on it, not e.g. `.finally()`.\n // Turn it into a real promise to avoid issues elsewhere.\n const promise = Promise.resolve(exportsOrPromise)\n moduleLoadingSignal.trackRead(promise)\n }\n}\n\n/**\n * A top-level dynamic import (or chunk load):\n *\n * 1. delays a prerender (potentially for a task or longer)\n * 2. may reveal more caches that need be filled\n *\n * So if we see one, we want to extend the duration of `cacheSignal` at least until the import/chunk-load is done.\n */\nexport function trackPendingModules(cacheSignal: CacheSignal): void {\n const moduleLoadingSignal = getModuleLoadingSignal()\n\n // We can't just use `cacheSignal.trackRead(moduleLoadingSignal.cacheReady())`,\n // because we might start and finish multiple batches of module loads while waiting for caches,\n // and `moduleLoadingSignal.cacheReady()` would resolve after the first batch.\n // Instead, we'll keep notifying `cacheSignal` of each import/chunk-load.\n const unsubscribe = moduleLoadingSignal.subscribeToReads(cacheSignal)\n\n // Later, when `cacheSignal` is no longer waiting for any caches (or imports that we've notified it of),\n // we can unsubscribe it.\n cacheSignal.cacheReady().then(unsubscribe)\n}\n"],"names":["CacheSignal","isThenable","_moduleLoadingSignal","getModuleLoadingSignal","trackPendingChunkLoad","promise","moduleLoadingSignal","trackRead","trackPendingImport","exportsOrPromise","Promise","resolve","trackPendingModules","cacheSignal","unsubscribe","subscribeToReads","cacheReady","then"],"mappings":"AAAA,SAASA,WAAW,QAAQ,kBAAiB;AAC7C,SAASC,UAAU,QAAQ,kCAAiC;AAE5D;;;CAGC,GACD,IAAIC;AACJ,SAASC;IACP,IAAI,CAACD,sBAAsB;QACzBA,uBAAuB,IAAIF;IAC7B;IACA,OAAOE;AACT;AAEA,OAAO,SAASE,sBAAsBC,OAAyB;IAC7D,MAAMC,sBAAsBH;IAC5BG,oBAAoBC,SAAS,CAACF;AAChC;AAEA,OAAO,SAASG,mBAAmBC,gBAAyB;IAC1D,MAAMH,sBAAsBH;IAE5B,+CAA+C;IAC/C,0CAA0C;IAC1C,IAAIF,WAAWQ,mBAAmB;QAChC,mHAAmH;QACnH,yDAAyD;QACzD,MAAMJ,UAAUK,QAAQC,OAAO,CAACF;QAChCH,oBAAoBC,SAAS,CAACF;IAChC;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,SAASO,oBAAoBC,WAAwB;IAC1D,MAAMP,sBAAsBH;IAE5B,+EAA+E;IAC/E,+FAA+F;IAC/F,8EAA8E;IAC9E,yEAAyE;IACzE,MAAMW,cAAcR,oBAAoBS,gBAAgB,CAACF;IAEzD,wGAAwG;IACxG,yBAAyB;IACzBA,YAAYG,UAAU,GAAGC,IAAI,CAACH;AAChC","ignoreList":[0]}