next 15.3.1-canary.4 → 15.3.1-canary.5

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.

Potentially problematic release.


This version of next might be problematic. Click here for more details.

Files changed (35) hide show
  1. package/dist/bin/next +1 -1
  2. package/dist/build/index.js +2 -2
  3. package/dist/build/swc/index.js +1 -1
  4. package/dist/build/webpack-config.js +2 -2
  5. package/dist/client/app-bootstrap.js +1 -1
  6. package/dist/client/components/bfcache.d.ts +27 -0
  7. package/dist/client/components/bfcache.js +90 -0
  8. package/dist/client/components/bfcache.js.map +1 -0
  9. package/dist/client/components/layout-router.d.ts +1 -1
  10. package/dist/client/components/layout-router.js +83 -61
  11. package/dist/client/components/layout-router.js.map +1 -1
  12. package/dist/client/index.js +1 -1
  13. package/dist/esm/build/index.js +2 -2
  14. package/dist/esm/build/swc/index.js +1 -1
  15. package/dist/esm/build/webpack-config.js +2 -2
  16. package/dist/esm/client/app-bootstrap.js +1 -1
  17. package/dist/esm/client/components/bfcache.js +93 -0
  18. package/dist/esm/client/components/bfcache.js.map +1 -0
  19. package/dist/esm/client/components/layout-router.js +83 -61
  20. package/dist/esm/client/components/layout-router.js.map +1 -1
  21. package/dist/esm/client/index.js +1 -1
  22. package/dist/esm/server/dev/hot-reloader-turbopack.js +1 -1
  23. package/dist/esm/server/dev/hot-reloader-webpack.js +1 -1
  24. package/dist/esm/server/lib/app-info-log.js +1 -1
  25. package/dist/esm/server/lib/start-server.js +1 -1
  26. package/dist/esm/shared/lib/canary-only.js +1 -1
  27. package/dist/server/dev/hot-reloader-turbopack.js +1 -1
  28. package/dist/server/dev/hot-reloader-webpack.js +1 -1
  29. package/dist/server/lib/app-info-log.js +1 -1
  30. package/dist/server/lib/start-server.js +1 -1
  31. package/dist/shared/lib/canary-only.js +1 -1
  32. package/dist/telemetry/anonymous-meta.js +1 -1
  33. package/dist/telemetry/events/session-stopped.js +2 -2
  34. package/dist/telemetry/events/version.js +2 -2
  35. package/package.json +15 -15
package/dist/bin/next CHANGED
@@ -79,7 +79,7 @@ const program = new NextRootCommand();
79
79
  program.name('next').description('The Next.js CLI allows you to develop, build, start your application, and more.').configureHelp({
80
80
  formatHelp: (cmd, helper)=>(0, _formatclihelpoutput.formatCliHelpOutput)(cmd, helper),
81
81
  subcommandTerm: (cmd)=>`${cmd.name()} ${cmd.usage()}`
82
- }).helpCommand(false).helpOption('-h, --help', 'Displays this message.').version(`Next.js v${"15.3.1-canary.4"}`, '-v, --version', 'Outputs the Next.js version.');
82
+ }).helpCommand(false).helpOption('-h, --help', 'Displays this message.').version(`Next.js v${"15.3.1-canary.5"}`, '-v, --version', 'Outputs the Next.js version.');
83
83
  program.command('build').description('Creates an optimized production build of your application. The output displays information about each route.').argument('[directory]', `A directory on which to build the application. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).option('-d, --debug', 'Enables a more verbose build output.').option('--no-lint', 'Disables linting.').option('--no-mangling', 'Disables mangling.').option('--profile', 'Enables production profiling for React.').option('--experimental-app-only', 'Builds only App Router routes.').option('--turbo', 'Starts development mode using Turbopack.').option('--turbopack', 'Starts development mode using Turbopack.').addOption(new _commander.Option('--experimental-build-mode [mode]', 'Uses an experimental build mode.').choices([
84
84
  'compile',
85
85
  'generate',
@@ -375,7 +375,7 @@ async function build(dir, reactProductionProfiling = false, debugOutput = false,
375
375
  const nextBuildSpan = (0, _trace.trace)('next-build', undefined, {
376
376
  buildMode: experimentalBuildMode,
377
377
  isTurboBuild: String(isTurbopack),
378
- version: "15.3.1-canary.4"
378
+ version: "15.3.1-canary.5"
379
379
  });
380
380
  _buildcontext.NextBuildContext.nextBuildSpan = nextBuildSpan;
381
381
  _buildcontext.NextBuildContext.dir = dir;
@@ -756,7 +756,7 @@ async function build(dir, reactProductionProfiling = false, debugOutput = false,
756
756
  // Files outside of the distDir can be "type": "module"
757
757
  await writeFileUtf8(_path.default.join(distDir, 'package.json'), '{"type": "commonjs"}');
758
758
  // These are written to distDir, so they need to come after creating and cleaning distDr.
759
- await (0, _builddiagnostics.recordFrameworkVersion)("15.3.1-canary.4");
759
+ await (0, _builddiagnostics.recordFrameworkVersion)("15.3.1-canary.5");
760
760
  await (0, _builddiagnostics.updateBuildDiagnostics)({
761
761
  buildStage: 'start'
762
762
  });
@@ -119,7 +119,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
119
119
  }
120
120
  return newObj;
121
121
  }
122
- const nextVersion = "15.3.1-canary.4";
122
+ const nextVersion = "15.3.1-canary.5";
123
123
  const ArchName = (0, _os.arch)();
124
124
  const PlatformName = (0, _os.platform)();
125
125
  function infoLog(...args) {
@@ -1650,7 +1650,7 @@ async function getBaseWebpackConfig(dir, { buildId, encryptionKey, config, compi
1650
1650
  isClient && new _copyfileplugin.CopyFilePlugin({
1651
1651
  // file path to build output of `@next/polyfill-nomodule`
1652
1652
  filePath: require.resolve('./polyfills/polyfill-nomodule'),
1653
- cacheKey: "15.3.1-canary.4",
1653
+ cacheKey: "15.3.1-canary.5",
1654
1654
  name: `static/chunks/polyfills${dev ? '' : '-[hash]'}.js`,
1655
1655
  minimize: false,
1656
1656
  info: {
@@ -1827,7 +1827,7 @@ async function getBaseWebpackConfig(dir, { buildId, encryptionKey, config, compi
1827
1827
  // - Next.js location on disk (some loaders use absolute paths and some resolve options depend on absolute paths)
1828
1828
  // - Next.js version
1829
1829
  // - next.config.js keys that affect compilation
1830
- version: `${__dirname}|${"15.3.1-canary.4"}|${configVars}`,
1830
+ version: `${__dirname}|${"15.3.1-canary.5"}|${configVars}`,
1831
1831
  cacheDirectory: _path.default.join(distDir, 'cache', 'webpack'),
1832
1832
  // For production builds, it's more efficient to compress all cache files together instead of compression each one individually.
1833
1833
  // So we disable compression here and allow the build runner to take care of compressing the cache as a whole.
@@ -13,7 +13,7 @@ Object.defineProperty(exports, "appBootstrap", {
13
13
  return appBootstrap;
14
14
  }
15
15
  });
16
- const version = "15.3.1-canary.4";
16
+ const version = "15.3.1-canary.5";
17
17
  window.next = {
18
18
  version,
19
19
  appDir: true
@@ -0,0 +1,27 @@
1
+ import type { FlightRouterState } from '../../server/app-render/types';
2
+ export type RouterBFCacheEntry = {
3
+ tree: FlightRouterState;
4
+ stateKey: string;
5
+ next: RouterBFCacheEntry | null;
6
+ };
7
+ /**
8
+ * Keeps track of the most recent N trees (FlightRouterStates) that were active
9
+ * at a certain segment level. E.g. for a segment "/a/b/[param]", this hook
10
+ * tracks the last N param values that the router rendered for N.
11
+ *
12
+ * The result of this hook precisely determines the number and order of
13
+ * trees that are rendered in parallel at their segment level.
14
+ *
15
+ * The purpose of this cache is to we can preserve the React and DOM state of
16
+ * some number of inactive trees, by rendering them in an <Activity> boundary.
17
+ * That means it would not make sense for the the lifetime of the cache to be
18
+ * any longer than the lifetime of the React tree; e.g. if the hook were
19
+ * unmounted, then the React tree would be, too. So, we use React state to
20
+ * manage it.
21
+ *
22
+ * Note that we don't store the RSC data for the cache entries in this hook —
23
+ * the data for inactive segments is stored in the parent CacheNode, which
24
+ * *does* have a longer lifetime than the React tree. This hook only determines
25
+ * which of those trees should have their *state* preserved, by <Activity>.
26
+ */
27
+ export declare function useRouterBFCache(activeTree: FlightRouterState, activeStateKey: string): RouterBFCacheEntry;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "useRouterBFCache", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return useRouterBFCache;
9
+ }
10
+ });
11
+ const _react = require("react");
12
+ // When the flag is disabled, only track the currently active tree
13
+ const MAX_BF_CACHE_ENTRIES = process.env.__NEXT_ROUTER_BF_CACHE ? 3 : 1;
14
+ function useRouterBFCache(activeTree, activeStateKey) {
15
+ // The currently active entry. The entries form a linked list, sorted in
16
+ // order of most recently active. This allows us to reuse parts of the list
17
+ // without cloning, unless there's a reordering or removal.
18
+ // TODO: Once we start tracking back/forward history at each route level,
19
+ // we should use the history order instead. In other words, when traversing
20
+ // to an existing entry as a result of a popstate event, we should maintain
21
+ // the existing order instead of moving it to the front of the list. I think
22
+ // an initial implementation of this could be to pass an incrementing id
23
+ // to history.pushState/replaceState, then use that here for ordering.
24
+ const [prevActiveEntry, setPrevActiveEntry] = (0, _react.useState)(()=>{
25
+ const initialEntry = {
26
+ tree: activeTree,
27
+ stateKey: activeStateKey,
28
+ next: null
29
+ };
30
+ return initialEntry;
31
+ });
32
+ if (prevActiveEntry.tree === activeTree) {
33
+ // Fast path. The active tree hasn't changed, so we can reuse the
34
+ // existing state.
35
+ return prevActiveEntry;
36
+ }
37
+ // The route tree changed. Note that this doesn't mean that the tree changed
38
+ // *at this level* — the change may be due to a child route. Either way, we
39
+ // need to either add or update the router tree in the bfcache.
40
+ //
41
+ // The rest of the code looks more complicated than it actually is because we
42
+ // can't mutate the state in place; we have to copy-on-write.
43
+ // Create a new entry for the active cache key. This is the head of the new
44
+ // linked list.
45
+ const newActiveEntry = {
46
+ tree: activeTree,
47
+ stateKey: activeStateKey,
48
+ next: null
49
+ };
50
+ // We need to append the old list onto the new list. If the head of the new
51
+ // list was already present in the cache, then we'll need to clone everything
52
+ // that came before it. Then we can reuse the rest.
53
+ let n = 1;
54
+ let oldEntry = prevActiveEntry;
55
+ let clonedEntry = newActiveEntry;
56
+ while(oldEntry !== null && n < MAX_BF_CACHE_ENTRIES){
57
+ if (oldEntry.stateKey === activeStateKey) {
58
+ // Fast path. This entry in the old list that corresponds to the key that
59
+ // is now active. We've already placed a clone of this entry at the front
60
+ // of the new list. We can reuse the rest of the old list without cloning.
61
+ // NOTE: We don't need to worry about eviction in this case because we
62
+ // haven't increased the size of the cache, and we assume the max size
63
+ // is constant across renders. If we were to change it to a dynamic limit,
64
+ // then the implementation would need to account for that.
65
+ clonedEntry.next = oldEntry.next;
66
+ break;
67
+ } else {
68
+ // Clone the entry and append it to the list.
69
+ n++;
70
+ const entry = {
71
+ tree: oldEntry.tree,
72
+ stateKey: oldEntry.stateKey,
73
+ next: null
74
+ };
75
+ clonedEntry.next = entry;
76
+ clonedEntry = entry;
77
+ }
78
+ oldEntry = oldEntry.next;
79
+ }
80
+ setPrevActiveEntry(newActiveEntry);
81
+ return newActiveEntry;
82
+ }
83
+
84
+ if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
85
+ Object.defineProperty(exports.default, '__esModule', { value: true });
86
+ Object.assign(exports.default, exports);
87
+ module.exports = exports.default;
88
+ }
89
+
90
+ //# sourceMappingURL=bfcache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/client/components/bfcache.ts"],"sourcesContent":["import type { FlightRouterState } from '../../server/app-render/types'\nimport { useState } from 'react'\n\n// When the flag is disabled, only track the currently active tree\nconst MAX_BF_CACHE_ENTRIES = process.env.__NEXT_ROUTER_BF_CACHE ? 3 : 1\n\nexport type RouterBFCacheEntry = {\n tree: FlightRouterState\n stateKey: string\n // The entries form a linked list, sorted in order of most recently active.\n next: RouterBFCacheEntry | null\n}\n\n/**\n * Keeps track of the most recent N trees (FlightRouterStates) that were active\n * at a certain segment level. E.g. for a segment \"/a/b/[param]\", this hook\n * tracks the last N param values that the router rendered for N.\n *\n * The result of this hook precisely determines the number and order of\n * trees that are rendered in parallel at their segment level.\n *\n * The purpose of this cache is to we can preserve the React and DOM state of\n * some number of inactive trees, by rendering them in an <Activity> boundary.\n * That means it would not make sense for the the lifetime of the cache to be\n * any longer than the lifetime of the React tree; e.g. if the hook were\n * unmounted, then the React tree would be, too. So, we use React state to\n * manage it.\n *\n * Note that we don't store the RSC data for the cache entries in this hook —\n * the data for inactive segments is stored in the parent CacheNode, which\n * *does* have a longer lifetime than the React tree. This hook only determines\n * which of those trees should have their *state* preserved, by <Activity>.\n */\nexport function useRouterBFCache(\n activeTree: FlightRouterState,\n activeStateKey: string\n): RouterBFCacheEntry {\n // The currently active entry. The entries form a linked list, sorted in\n // order of most recently active. This allows us to reuse parts of the list\n // without cloning, unless there's a reordering or removal.\n // TODO: Once we start tracking back/forward history at each route level,\n // we should use the history order instead. In other words, when traversing\n // to an existing entry as a result of a popstate event, we should maintain\n // the existing order instead of moving it to the front of the list. I think\n // an initial implementation of this could be to pass an incrementing id\n // to history.pushState/replaceState, then use that here for ordering.\n const [prevActiveEntry, setPrevActiveEntry] = useState<RouterBFCacheEntry>(\n () => {\n const initialEntry: RouterBFCacheEntry = {\n tree: activeTree,\n stateKey: activeStateKey,\n next: null,\n }\n return initialEntry\n }\n )\n\n if (prevActiveEntry.tree === activeTree) {\n // Fast path. The active tree hasn't changed, so we can reuse the\n // existing state.\n return prevActiveEntry\n }\n\n // The route tree changed. Note that this doesn't mean that the tree changed\n // *at this level* — the change may be due to a child route. Either way, we\n // need to either add or update the router tree in the bfcache.\n //\n // The rest of the code looks more complicated than it actually is because we\n // can't mutate the state in place; we have to copy-on-write.\n\n // Create a new entry for the active cache key. This is the head of the new\n // linked list.\n const newActiveEntry: RouterBFCacheEntry = {\n tree: activeTree,\n stateKey: activeStateKey,\n next: null,\n }\n\n // We need to append the old list onto the new list. If the head of the new\n // list was already present in the cache, then we'll need to clone everything\n // that came before it. Then we can reuse the rest.\n let n = 1\n let oldEntry: RouterBFCacheEntry | null = prevActiveEntry\n let clonedEntry: RouterBFCacheEntry = newActiveEntry\n while (oldEntry !== null && n < MAX_BF_CACHE_ENTRIES) {\n if (oldEntry.stateKey === activeStateKey) {\n // Fast path. This entry in the old list that corresponds to the key that\n // is now active. We've already placed a clone of this entry at the front\n // of the new list. We can reuse the rest of the old list without cloning.\n // NOTE: We don't need to worry about eviction in this case because we\n // haven't increased the size of the cache, and we assume the max size\n // is constant across renders. If we were to change it to a dynamic limit,\n // then the implementation would need to account for that.\n clonedEntry.next = oldEntry.next\n break\n } else {\n // Clone the entry and append it to the list.\n n++\n const entry: RouterBFCacheEntry = {\n tree: oldEntry.tree,\n stateKey: oldEntry.stateKey,\n next: null,\n }\n clonedEntry.next = entry\n clonedEntry = entry\n }\n oldEntry = oldEntry.next\n }\n\n setPrevActiveEntry(newActiveEntry)\n return newActiveEntry\n}\n"],"names":["useRouterBFCache","MAX_BF_CACHE_ENTRIES","process","env","__NEXT_ROUTER_BF_CACHE","activeTree","activeStateKey","prevActiveEntry","setPrevActiveEntry","useState","initialEntry","tree","stateKey","next","newActiveEntry","n","oldEntry","clonedEntry","entry"],"mappings":";;;;+BAiCgBA;;;eAAAA;;;uBAhCS;AAEzB,kEAAkE;AAClE,MAAMC,uBAAuBC,QAAQC,GAAG,CAACC,sBAAsB,GAAG,IAAI;AA6B/D,SAASJ,iBACdK,UAA6B,EAC7BC,cAAsB;IAEtB,wEAAwE;IACxE,2EAA2E;IAC3E,2DAA2D;IAC3D,yEAAyE;IACzE,2EAA2E;IAC3E,2EAA2E;IAC3E,4EAA4E;IAC5E,wEAAwE;IACxE,sEAAsE;IACtE,MAAM,CAACC,iBAAiBC,mBAAmB,GAAGC,IAAAA,eAAQ,EACpD;QACE,MAAMC,eAAmC;YACvCC,MAAMN;YACNO,UAAUN;YACVO,MAAM;QACR;QACA,OAAOH;IACT;IAGF,IAAIH,gBAAgBI,IAAI,KAAKN,YAAY;QACvC,iEAAiE;QACjE,kBAAkB;QAClB,OAAOE;IACT;IAEA,4EAA4E;IAC5E,2EAA2E;IAC3E,+DAA+D;IAC/D,EAAE;IACF,6EAA6E;IAC7E,6DAA6D;IAE7D,2EAA2E;IAC3E,eAAe;IACf,MAAMO,iBAAqC;QACzCH,MAAMN;QACNO,UAAUN;QACVO,MAAM;IACR;IAEA,2EAA2E;IAC3E,6EAA6E;IAC7E,mDAAmD;IACnD,IAAIE,IAAI;IACR,IAAIC,WAAsCT;IAC1C,IAAIU,cAAkCH;IACtC,MAAOE,aAAa,QAAQD,IAAId,qBAAsB;QACpD,IAAIe,SAASJ,QAAQ,KAAKN,gBAAgB;YACxC,yEAAyE;YACzE,yEAAyE;YACzE,0EAA0E;YAC1E,sEAAsE;YACtE,sEAAsE;YACtE,0EAA0E;YAC1E,0DAA0D;YAC1DW,YAAYJ,IAAI,GAAGG,SAASH,IAAI;YAChC;QACF,OAAO;YACL,6CAA6C;YAC7CE;YACA,MAAMG,QAA4B;gBAChCP,MAAMK,SAASL,IAAI;gBACnBC,UAAUI,SAASJ,QAAQ;gBAC3BC,MAAM;YACR;YACAI,YAAYJ,IAAI,GAAGK;YACnBD,cAAcC;QAChB;QACAF,WAAWA,SAASH,IAAI;IAC1B;IAEAL,mBAAmBM;IACnB,OAAOA;AACT"}
@@ -15,4 +15,4 @@ export default function OuterLayoutRouter({ parallelRouterKey, error, errorStyle
15
15
  notFound: React.ReactNode | undefined;
16
16
  forbidden: React.ReactNode | undefined;
17
17
  unauthorized: React.ReactNode | undefined;
18
- }): import("react/jsx-runtime").JSX.Element;
18
+ }): React.ReactNode[];
@@ -29,6 +29,8 @@ const _errorboundary1 = require("./http-access-fallback/error-boundary");
29
29
  const _createroutercachekey = require("./router-reducer/create-router-cache-key");
30
30
  const _hasinterceptionrouteincurrenttree = require("./router-reducer/reducers/has-interception-route-in-current-tree");
31
31
  const _useactionqueue = require("./use-action-queue");
32
+ const _bfcache = require("./bfcache");
33
+ const Activity = process.env.__NEXT_ROUTER_BF_CACHE ? require('react').unstable_Activity : null;
32
34
  /**
33
35
  * Add refetch marker to router state at the point of the current layout segment.
34
36
  * This ensures the response returned is not further down than the current layout segment.
@@ -383,11 +385,7 @@ function OuterLayoutRouter(param) {
383
385
  segmentMap = new Map();
384
386
  parentParallelRoutes.set(parallelRouterKey, segmentMap);
385
387
  }
386
- // Get the active segment in the tree
387
- // The reason arrays are used in the data format is that these are transferred from the server to the browser so it's optimized to save bytes.
388
388
  const parentTreeSegment = parentTree[0];
389
- const tree = parentTree[1][parallelRouterKey];
390
- const treeSegment = tree[0];
391
389
  const segmentPath = parentSegmentPath === null ? // path. This has led to a bunch of special cases scattered throughout
392
390
  // the code. We should clean this up.
393
391
  [
@@ -406,29 +404,43 @@ function OuterLayoutRouter(param) {
406
404
  // it's possible that the segment accessed the search params on the server.
407
405
  // (This only applies to page segments; layout segments cannot access search
408
406
  // params on the server.)
409
- const cacheKey = (0, _createroutercachekey.createRouterCacheKey)(treeSegment);
410
- const stateKey = (0, _createroutercachekey.createRouterCacheKey)(treeSegment, true) // no search params
407
+ const activeTree = parentTree[1][parallelRouterKey];
408
+ const activeSegment = activeTree[0];
409
+ const activeStateKey = (0, _createroutercachekey.createRouterCacheKey)(activeSegment, true) // no search params
411
410
  ;
412
- // Read segment path from the parallel router cache node.
413
- let cacheNode = segmentMap.get(cacheKey);
414
- if (cacheNode === undefined) {
415
- // When data is not available during rendering client-side we need to fetch
416
- // it from the server.
417
- const newLazyCacheNode = {
418
- lazyData: null,
419
- rsc: null,
420
- prefetchRsc: null,
421
- head: null,
422
- prefetchHead: null,
423
- parallelRoutes: new Map(),
424
- loading: null,
425
- navigatedAt: -1
426
- };
427
- // Flight data fetch kicked off during render and put into the cache.
428
- cacheNode = newLazyCacheNode;
429
- segmentMap.set(cacheKey, newLazyCacheNode);
430
- }
431
- /*
411
+ // At each level of the route tree, not only do we render the currently
412
+ // active segment — we also render the last N segments that were active at
413
+ // this level inside a hidden <Activity> boundary, to preserve their state
414
+ // if or when the user navigates to them again.
415
+ //
416
+ // bfcacheEntry is a linked list of FlightRouterStates.
417
+ let bfcacheEntry = (0, _bfcache.useRouterBFCache)(activeTree, activeStateKey);
418
+ let children = [];
419
+ do {
420
+ const tree = bfcacheEntry.tree;
421
+ const stateKey = bfcacheEntry.stateKey;
422
+ const segment = tree[0];
423
+ const cacheKey = (0, _createroutercachekey.createRouterCacheKey)(segment);
424
+ // Read segment path from the parallel router cache node.
425
+ let cacheNode = segmentMap.get(cacheKey);
426
+ if (cacheNode === undefined) {
427
+ // When data is not available during rendering client-side we need to fetch
428
+ // it from the server.
429
+ const newLazyCacheNode = {
430
+ lazyData: null,
431
+ rsc: null,
432
+ prefetchRsc: null,
433
+ head: null,
434
+ prefetchHead: null,
435
+ parallelRoutes: new Map(),
436
+ loading: null,
437
+ navigatedAt: -1
438
+ };
439
+ // Flight data fetch kicked off during render and put into the cache.
440
+ cacheNode = newLazyCacheNode;
441
+ segmentMap.set(cacheKey, newLazyCacheNode);
442
+ }
443
+ /*
432
444
  - Error boundary
433
445
  - Only renders error boundary if error component is provided.
434
446
  - Rendered for each segment to ensure they have their own error state.
@@ -437,45 +449,55 @@ function OuterLayoutRouter(param) {
437
449
  - Rendered for each segment to ensure they have their own loading state.
438
450
  - Passed to the router during rendering to ensure it can be immediately rendered when suspending on a Flight fetch.
439
451
  */ // TODO: The loading module data for a segment is stored on the parent, then
440
- // applied to each of that parent segment's parallel route slots. In the
441
- // simple case where there's only one parallel route (the `children` slot),
442
- // this is no different from if the loading module data where stored on the
443
- // child directly. But I'm not sure this actually makes sense when there are
444
- // multiple parallel routes. It's not a huge issue because you always have
445
- // the option to define a narrower loading boundary for a particular slot. But
446
- // this sort of smells like an implementation accident to me.
447
- const loadingModuleData = parentCacheNode.loading;
448
- return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_approutercontextsharedruntime.TemplateContext.Provider, {
449
- value: /*#__PURE__*/ (0, _jsxruntime.jsx)(ScrollAndFocusHandler, {
450
- segmentPath: segmentPath,
451
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_errorboundary.ErrorBoundary, {
452
- errorComponent: error,
453
- errorStyles: errorStyles,
454
- errorScripts: errorScripts,
455
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(LoadingBoundary, {
456
- loading: loadingModuleData,
457
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_errorboundary1.HTTPAccessFallbackBoundary, {
458
- notFound: notFound,
459
- forbidden: forbidden,
460
- unauthorized: unauthorized,
461
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_redirectboundary.RedirectBoundary, {
462
- children: /*#__PURE__*/ (0, _jsxruntime.jsx)(InnerLayoutRouter, {
463
- url: url,
464
- tree: tree,
465
- cacheNode: cacheNode,
466
- segmentPath: segmentPath
452
+ // applied to each of that parent segment's parallel route slots. In the
453
+ // simple case where there's only one parallel route (the `children` slot),
454
+ // this is no different from if the loading module data where stored on the
455
+ // child directly. But I'm not sure this actually makes sense when there are
456
+ // multiple parallel routes. It's not a huge issue because you always have
457
+ // the option to define a narrower loading boundary for a particular slot. But
458
+ // this sort of smells like an implementation accident to me.
459
+ const loadingModuleData = parentCacheNode.loading;
460
+ let child = /*#__PURE__*/ (0, _jsxruntime.jsxs)(_approutercontextsharedruntime.TemplateContext.Provider, {
461
+ value: /*#__PURE__*/ (0, _jsxruntime.jsx)(ScrollAndFocusHandler, {
462
+ segmentPath: segmentPath,
463
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_errorboundary.ErrorBoundary, {
464
+ errorComponent: error,
465
+ errorStyles: errorStyles,
466
+ errorScripts: errorScripts,
467
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(LoadingBoundary, {
468
+ loading: loadingModuleData,
469
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_errorboundary1.HTTPAccessFallbackBoundary, {
470
+ notFound: notFound,
471
+ forbidden: forbidden,
472
+ unauthorized: unauthorized,
473
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_redirectboundary.RedirectBoundary, {
474
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(InnerLayoutRouter, {
475
+ url: url,
476
+ tree: tree,
477
+ cacheNode: cacheNode,
478
+ segmentPath: segmentPath
479
+ })
467
480
  })
468
481
  })
469
482
  })
470
483
  })
471
- })
472
- }),
473
- children: [
474
- templateStyles,
475
- templateScripts,
476
- template
477
- ]
478
- }, stateKey);
484
+ }),
485
+ children: [
486
+ templateStyles,
487
+ templateScripts,
488
+ template
489
+ ]
490
+ }, stateKey);
491
+ if (process.env.__NEXT_ROUTER_BF_CACHE) {
492
+ child = /*#__PURE__*/ (0, _jsxruntime.jsx)(Activity, {
493
+ mode: stateKey === activeStateKey ? 'visible' : 'hidden',
494
+ children: child
495
+ }, stateKey);
496
+ }
497
+ children.push(child);
498
+ bfcacheEntry = bfcacheEntry.next;
499
+ }while (bfcacheEntry !== null);
500
+ return children;
479
501
  }
480
502
 
481
503
  if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/client/components/layout-router.tsx"],"sourcesContent":["'use client'\n\nimport type {\n CacheNode,\n LazyCacheNode,\n LoadingModuleData,\n} from '../../shared/lib/app-router-context.shared-runtime'\nimport type {\n FlightRouterState,\n FlightSegmentPath,\n} from '../../server/app-render/types'\nimport type { ErrorComponent } from './error-boundary'\nimport {\n ACTION_SERVER_PATCH,\n type FocusAndScrollRef,\n} from './router-reducer/router-reducer-types'\n\nimport React, {\n useContext,\n use,\n startTransition,\n Suspense,\n useDeferredValue,\n type JSX,\n} from 'react'\nimport ReactDOM from 'react-dom'\nimport {\n LayoutRouterContext,\n GlobalLayoutRouterContext,\n TemplateContext,\n} from '../../shared/lib/app-router-context.shared-runtime'\nimport { fetchServerResponse } from './router-reducer/fetch-server-response'\nimport { unresolvedThenable } from './unresolved-thenable'\nimport { ErrorBoundary } from './error-boundary'\nimport { matchSegment } from './match-segments'\nimport { handleSmoothScroll } from '../../shared/lib/router/utils/handle-smooth-scroll'\nimport { RedirectBoundary } from './redirect-boundary'\nimport { HTTPAccessFallbackBoundary } from './http-access-fallback/error-boundary'\nimport { createRouterCacheKey } from './router-reducer/create-router-cache-key'\nimport { hasInterceptionRouteInCurrentTree } from './router-reducer/reducers/has-interception-route-in-current-tree'\nimport { dispatchAppRouterAction } from './use-action-queue'\n\n/**\n * Add refetch marker to router state at the point of the current layout segment.\n * This ensures the response returned is not further down than the current layout segment.\n */\nfunction walkAddRefetch(\n segmentPathToWalk: FlightSegmentPath | undefined,\n treeToRecreate: FlightRouterState\n): FlightRouterState {\n if (segmentPathToWalk) {\n const [segment, parallelRouteKey] = segmentPathToWalk\n const isLast = segmentPathToWalk.length === 2\n\n if (matchSegment(treeToRecreate[0], segment)) {\n if (treeToRecreate[1].hasOwnProperty(parallelRouteKey)) {\n if (isLast) {\n const subTree = walkAddRefetch(\n undefined,\n treeToRecreate[1][parallelRouteKey]\n )\n return [\n treeToRecreate[0],\n {\n ...treeToRecreate[1],\n [parallelRouteKey]: [\n subTree[0],\n subTree[1],\n subTree[2],\n 'refetch',\n ],\n },\n ]\n }\n\n return [\n treeToRecreate[0],\n {\n ...treeToRecreate[1],\n [parallelRouteKey]: walkAddRefetch(\n segmentPathToWalk.slice(2),\n treeToRecreate[1][parallelRouteKey]\n ),\n },\n ]\n }\n }\n }\n\n return treeToRecreate\n}\n\nconst __DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = (\n ReactDOM as any\n).__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE\n\n// TODO-APP: Replace with new React API for finding dom nodes without a `ref` when available\n/**\n * Wraps ReactDOM.findDOMNode with additional logic to hide React Strict Mode warning\n */\nfunction findDOMNode(\n instance: React.ReactInstance | null | undefined\n): Element | Text | null {\n // Tree-shake for server bundle\n if (typeof window === 'undefined') return null\n\n // __DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE.findDOMNode is null during module init.\n // We need to lazily reference it.\n const internal_reactDOMfindDOMNode =\n __DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE.findDOMNode\n return internal_reactDOMfindDOMNode(instance)\n}\n\nconst rectProperties = [\n 'bottom',\n 'height',\n 'left',\n 'right',\n 'top',\n 'width',\n 'x',\n 'y',\n] as const\n/**\n * Check if a HTMLElement is hidden or fixed/sticky position\n */\nfunction shouldSkipElement(element: HTMLElement) {\n // we ignore fixed or sticky positioned elements since they'll likely pass the \"in-viewport\" check\n // and will result in a situation we bail on scroll because of something like a fixed nav,\n // even though the actual page content is offscreen\n if (['sticky', 'fixed'].includes(getComputedStyle(element).position)) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n 'Skipping auto-scroll behavior due to `position: sticky` or `position: fixed` on element:',\n element\n )\n }\n return true\n }\n\n // Uses `getBoundingClientRect` to check if the element is hidden instead of `offsetParent`\n // because `offsetParent` doesn't consider document/body\n const rect = element.getBoundingClientRect()\n return rectProperties.every((item) => rect[item] === 0)\n}\n\n/**\n * Check if the top corner of the HTMLElement is in the viewport.\n */\nfunction topOfElementInViewport(element: HTMLElement, viewportHeight: number) {\n const rect = element.getBoundingClientRect()\n return rect.top >= 0 && rect.top <= viewportHeight\n}\n\n/**\n * Find the DOM node for a hash fragment.\n * If `top` the page has to scroll to the top of the page. This mirrors the browser's behavior.\n * If the hash fragment is an id, the page has to scroll to the element with that id.\n * If the hash fragment is a name, the page has to scroll to the first element with that name.\n */\nfunction getHashFragmentDomNode(hashFragment: string) {\n // If the hash fragment is `top` the page has to scroll to the top of the page.\n if (hashFragment === 'top') {\n return document.body\n }\n\n // If the hash fragment is an id, the page has to scroll to the element with that id.\n return (\n document.getElementById(hashFragment) ??\n // If the hash fragment is a name, the page has to scroll to the first element with that name.\n document.getElementsByName(hashFragment)[0]\n )\n}\ninterface ScrollAndFocusHandlerProps {\n focusAndScrollRef: FocusAndScrollRef\n children: React.ReactNode\n segmentPath: FlightSegmentPath\n}\nclass InnerScrollAndFocusHandler extends React.Component<ScrollAndFocusHandlerProps> {\n handlePotentialScroll = () => {\n // Handle scroll and focus, it's only applied once in the first useEffect that triggers that changed.\n const { focusAndScrollRef, segmentPath } = this.props\n\n if (focusAndScrollRef.apply) {\n // segmentPaths is an array of segment paths that should be scrolled to\n // if the current segment path is not in the array, the scroll is not applied\n // unless the array is empty, in which case the scroll is always applied\n if (\n focusAndScrollRef.segmentPaths.length !== 0 &&\n !focusAndScrollRef.segmentPaths.some((scrollRefSegmentPath) =>\n segmentPath.every((segment, index) =>\n matchSegment(segment, scrollRefSegmentPath[index])\n )\n )\n ) {\n return\n }\n\n let domNode:\n | ReturnType<typeof getHashFragmentDomNode>\n | ReturnType<typeof findDOMNode> = null\n const hashFragment = focusAndScrollRef.hashFragment\n\n if (hashFragment) {\n domNode = getHashFragmentDomNode(hashFragment)\n }\n\n // `findDOMNode` is tricky because it returns just the first child if the component is a fragment.\n // This already caused a bug where the first child was a <link/> in head.\n if (!domNode) {\n domNode = findDOMNode(this)\n }\n\n // If there is no DOM node this layout-router level is skipped. It'll be handled higher-up in the tree.\n if (!(domNode instanceof Element)) {\n return\n }\n\n // Verify if the element is a HTMLElement and if we want to consider it for scroll behavior.\n // If the element is skipped, try to select the next sibling and try again.\n while (!(domNode instanceof HTMLElement) || shouldSkipElement(domNode)) {\n if (process.env.NODE_ENV !== 'production') {\n if (domNode.parentElement?.localName === 'head') {\n // TODO: We enter this state when metadata was rendered as part of the page or via Next.js.\n // This is always a bug in Next.js and caused by React hoisting metadata.\n // We need to replace `findDOMNode` in favor of Fragment Refs (when available) so that we can skip over metadata.\n }\n }\n\n // No siblings found that match the criteria are found, so handle scroll higher up in the tree instead.\n if (domNode.nextElementSibling === null) {\n return\n }\n domNode = domNode.nextElementSibling\n }\n\n // State is mutated to ensure that the focus and scroll is applied only once.\n focusAndScrollRef.apply = false\n focusAndScrollRef.hashFragment = null\n focusAndScrollRef.segmentPaths = []\n\n handleSmoothScroll(\n () => {\n // In case of hash scroll, we only need to scroll the element into view\n if (hashFragment) {\n ;(domNode as HTMLElement).scrollIntoView()\n\n return\n }\n // Store the current viewport height because reading `clientHeight` causes a reflow,\n // and it won't change during this function.\n const htmlElement = document.documentElement\n const viewportHeight = htmlElement.clientHeight\n\n // If the element's top edge is already in the viewport, exit early.\n if (topOfElementInViewport(domNode as HTMLElement, viewportHeight)) {\n return\n }\n\n // Otherwise, try scrolling go the top of the document to be backward compatible with pages\n // scrollIntoView() called on `<html/>` element scrolls horizontally on chrome and firefox (that shouldn't happen)\n // We could use it to scroll horizontally following RTL but that also seems to be broken - it will always scroll left\n // scrollLeft = 0 also seems to ignore RTL and manually checking for RTL is too much hassle so we will scroll just vertically\n htmlElement.scrollTop = 0\n\n // Scroll to domNode if domNode is not in viewport when scrolled to top of document\n if (!topOfElementInViewport(domNode as HTMLElement, viewportHeight)) {\n // Scroll into view doesn't scroll horizontally by default when not needed\n ;(domNode as HTMLElement).scrollIntoView()\n }\n },\n {\n // We will force layout by querying domNode position\n dontForceLayout: true,\n onlyHashChange: focusAndScrollRef.onlyHashChange,\n }\n )\n\n // Mutate after scrolling so that it can be read by `handleSmoothScroll`\n focusAndScrollRef.onlyHashChange = false\n\n // Set focus on the element\n domNode.focus()\n }\n }\n\n componentDidMount() {\n this.handlePotentialScroll()\n }\n\n componentDidUpdate() {\n // Because this property is overwritten in handlePotentialScroll it's fine to always run it when true as it'll be set to false for subsequent renders.\n if (this.props.focusAndScrollRef.apply) {\n this.handlePotentialScroll()\n }\n }\n\n render() {\n return this.props.children\n }\n}\n\nfunction ScrollAndFocusHandler({\n segmentPath,\n children,\n}: {\n segmentPath: FlightSegmentPath\n children: React.ReactNode\n}) {\n const context = useContext(GlobalLayoutRouterContext)\n if (!context) {\n throw new Error('invariant global layout router not mounted')\n }\n\n return (\n <InnerScrollAndFocusHandler\n segmentPath={segmentPath}\n focusAndScrollRef={context.focusAndScrollRef}\n >\n {children}\n </InnerScrollAndFocusHandler>\n )\n}\n\n/**\n * InnerLayoutRouter handles rendering the provided segment based on the cache.\n */\nfunction InnerLayoutRouter({\n tree,\n segmentPath,\n cacheNode,\n url,\n}: {\n tree: FlightRouterState\n segmentPath: FlightSegmentPath\n cacheNode: CacheNode\n url: string\n}) {\n const context = useContext(GlobalLayoutRouterContext)\n if (!context) {\n throw new Error('invariant global layout router not mounted')\n }\n\n const { tree: fullTree } = context\n\n // `rsc` represents the renderable node for this segment.\n\n // If this segment has a `prefetchRsc`, it's the statically prefetched data.\n // We should use that on initial render instead of `rsc`. Then we'll switch\n // to `rsc` when the dynamic response streams in.\n //\n // If no prefetch data is available, then we go straight to rendering `rsc`.\n const resolvedPrefetchRsc =\n cacheNode.prefetchRsc !== null ? cacheNode.prefetchRsc : cacheNode.rsc\n\n // We use `useDeferredValue` to handle switching between the prefetched and\n // final values. The second argument is returned on initial render, then it\n // re-renders with the first argument.\n const rsc: any = useDeferredValue(cacheNode.rsc, resolvedPrefetchRsc)\n\n // `rsc` is either a React node or a promise for a React node, except we\n // special case `null` to represent that this segment's data is missing. If\n // it's a promise, we need to unwrap it so we can determine whether or not the\n // data is missing.\n const resolvedRsc: React.ReactNode =\n typeof rsc === 'object' && rsc !== null && typeof rsc.then === 'function'\n ? use(rsc)\n : rsc\n\n if (!resolvedRsc) {\n // The data for this segment is not available, and there's no pending\n // navigation that will be able to fulfill it. We need to fetch more from\n // the server and patch the cache.\n\n // Check if there's already a pending request.\n let lazyData = cacheNode.lazyData\n if (lazyData === null) {\n /**\n * Router state with refetch marker added\n */\n // TODO-APP: remove ''\n const refetchTree = walkAddRefetch(['', ...segmentPath], fullTree)\n const includeNextUrl = hasInterceptionRouteInCurrentTree(fullTree)\n const navigatedAt = Date.now()\n cacheNode.lazyData = lazyData = fetchServerResponse(\n new URL(url, location.origin),\n {\n flightRouterState: refetchTree,\n nextUrl: includeNextUrl ? context.nextUrl : null,\n }\n ).then((serverResponse) => {\n startTransition(() => {\n dispatchAppRouterAction({\n type: ACTION_SERVER_PATCH,\n previousTree: fullTree,\n serverResponse,\n navigatedAt,\n })\n })\n\n return serverResponse\n })\n\n // Suspend while waiting for lazyData to resolve\n use(lazyData)\n }\n // Suspend infinitely as `changeByServerResponse` will cause a different part of the tree to be rendered.\n // A falsey `resolvedRsc` indicates missing data -- we should not commit that branch, and we need to wait for the data to arrive.\n use(unresolvedThenable) as never\n }\n\n // If we get to this point, then we know we have something we can render.\n const subtree = (\n // The layout router context narrows down tree and childNodes at each level.\n <LayoutRouterContext.Provider\n value={{\n parentTree: tree,\n parentCacheNode: cacheNode,\n parentSegmentPath: segmentPath,\n\n // TODO-APP: overriding of url for parallel routes\n url: url,\n }}\n >\n {resolvedRsc}\n </LayoutRouterContext.Provider>\n )\n // Ensure root layout is not wrapped in a div as the root layout renders `<html>`\n return subtree\n}\n\n/**\n * Renders suspense boundary with the provided \"loading\" property as the fallback.\n * If no loading property is provided it renders the children without a suspense boundary.\n */\nfunction LoadingBoundary({\n loading,\n children,\n}: {\n loading: LoadingModuleData | Promise<LoadingModuleData>\n children: React.ReactNode\n}): JSX.Element {\n // If loading is a promise, unwrap it. This happens in cases where we haven't\n // yet received the loading data from the server — which includes whether or\n // not this layout has a loading component at all.\n //\n // It's OK to suspend here instead of inside the fallback because this\n // promise will resolve simultaneously with the data for the segment itself.\n // So it will never suspend for longer than it would have if we didn't use\n // a Suspense fallback at all.\n let loadingModuleData\n if (\n typeof loading === 'object' &&\n loading !== null &&\n typeof (loading as any).then === 'function'\n ) {\n const promiseForLoading = loading as Promise<LoadingModuleData>\n loadingModuleData = use(promiseForLoading)\n } else {\n loadingModuleData = loading as LoadingModuleData\n }\n\n if (loadingModuleData) {\n const loadingRsc = loadingModuleData[0]\n const loadingStyles = loadingModuleData[1]\n const loadingScripts = loadingModuleData[2]\n return (\n <Suspense\n fallback={\n <>\n {loadingStyles}\n {loadingScripts}\n {loadingRsc}\n </>\n }\n >\n {children}\n </Suspense>\n )\n }\n\n return <>{children}</>\n}\n\n/**\n * OuterLayoutRouter handles the current segment as well as <Offscreen> rendering of other segments.\n * It can be rendered next to each other with a different `parallelRouterKey`, allowing for Parallel routes.\n */\nexport default function OuterLayoutRouter({\n parallelRouterKey,\n error,\n errorStyles,\n errorScripts,\n templateStyles,\n templateScripts,\n template,\n notFound,\n forbidden,\n unauthorized,\n}: {\n parallelRouterKey: string\n error: ErrorComponent | undefined\n errorStyles: React.ReactNode | undefined\n errorScripts: React.ReactNode | undefined\n templateStyles: React.ReactNode | undefined\n templateScripts: React.ReactNode | undefined\n template: React.ReactNode\n notFound: React.ReactNode | undefined\n forbidden: React.ReactNode | undefined\n unauthorized: React.ReactNode | undefined\n}) {\n const context = useContext(LayoutRouterContext)\n if (!context) {\n throw new Error('invariant expected layout router to be mounted')\n }\n\n const { parentTree, parentCacheNode, parentSegmentPath, url } = context\n\n // Get the CacheNode for this segment by reading it from the parent segment's\n // child map.\n const parentParallelRoutes = parentCacheNode.parallelRoutes\n let segmentMap = parentParallelRoutes.get(parallelRouterKey)\n // If the parallel router cache node does not exist yet, create it.\n // This writes to the cache when there is no item in the cache yet. It never *overwrites* existing cache items which is why it's safe in concurrent mode.\n if (!segmentMap) {\n segmentMap = new Map()\n parentParallelRoutes.set(parallelRouterKey, segmentMap)\n }\n\n // Get the active segment in the tree\n // The reason arrays are used in the data format is that these are transferred from the server to the browser so it's optimized to save bytes.\n const parentTreeSegment = parentTree[0]\n const tree = parentTree[1][parallelRouterKey]\n const treeSegment = tree[0]\n\n const segmentPath =\n parentSegmentPath === null\n ? // TODO: The root segment value is currently omitted from the segment\n // path. This has led to a bunch of special cases scattered throughout\n // the code. We should clean this up.\n [parallelRouterKey]\n : parentSegmentPath.concat([parentTreeSegment, parallelRouterKey])\n\n // The \"state\" key of a segment is the one passed to React — it represents the\n // identity of the UI tree. Whenever the state key changes, the tree is\n // recreated and the state is reset. In the App Router model, search params do\n // not cause state to be lost, so two segments with the same segment path but\n // different search params should have the same state key.\n //\n // The \"cache\" key of a segment, however, *does* include the search params, if\n // it's possible that the segment accessed the search params on the server.\n // (This only applies to page segments; layout segments cannot access search\n // params on the server.)\n const cacheKey = createRouterCacheKey(treeSegment)\n const stateKey = createRouterCacheKey(treeSegment, true) // no search params\n\n // Read segment path from the parallel router cache node.\n let cacheNode = segmentMap.get(cacheKey)\n if (cacheNode === undefined) {\n // When data is not available during rendering client-side we need to fetch\n // it from the server.\n const newLazyCacheNode: LazyCacheNode = {\n lazyData: null,\n rsc: null,\n prefetchRsc: null,\n head: null,\n prefetchHead: null,\n parallelRoutes: new Map(),\n loading: null,\n navigatedAt: -1,\n }\n\n // Flight data fetch kicked off during render and put into the cache.\n cacheNode = newLazyCacheNode\n segmentMap.set(cacheKey, newLazyCacheNode)\n }\n\n /*\n - Error boundary\n - Only renders error boundary if error component is provided.\n - Rendered for each segment to ensure they have their own error state.\n - Loading boundary\n - Only renders suspense boundary if loading components is provided.\n - Rendered for each segment to ensure they have their own loading state.\n - Passed to the router during rendering to ensure it can be immediately rendered when suspending on a Flight fetch.\n */\n\n // TODO: The loading module data for a segment is stored on the parent, then\n // applied to each of that parent segment's parallel route slots. In the\n // simple case where there's only one parallel route (the `children` slot),\n // this is no different from if the loading module data where stored on the\n // child directly. But I'm not sure this actually makes sense when there are\n // multiple parallel routes. It's not a huge issue because you always have\n // the option to define a narrower loading boundary for a particular slot. But\n // this sort of smells like an implementation accident to me.\n const loadingModuleData = parentCacheNode.loading\n\n return (\n <TemplateContext.Provider\n key={stateKey}\n value={\n <ScrollAndFocusHandler segmentPath={segmentPath}>\n <ErrorBoundary\n errorComponent={error}\n errorStyles={errorStyles}\n errorScripts={errorScripts}\n >\n <LoadingBoundary loading={loadingModuleData}>\n <HTTPAccessFallbackBoundary\n notFound={notFound}\n forbidden={forbidden}\n unauthorized={unauthorized}\n >\n <RedirectBoundary>\n <InnerLayoutRouter\n url={url}\n tree={tree}\n cacheNode={cacheNode}\n segmentPath={segmentPath}\n />\n </RedirectBoundary>\n </HTTPAccessFallbackBoundary>\n </LoadingBoundary>\n </ErrorBoundary>\n </ScrollAndFocusHandler>\n }\n >\n {templateStyles}\n {templateScripts}\n {template}\n </TemplateContext.Provider>\n )\n}\n"],"names":["OuterLayoutRouter","walkAddRefetch","segmentPathToWalk","treeToRecreate","segment","parallelRouteKey","isLast","length","matchSegment","hasOwnProperty","subTree","undefined","slice","__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE","ReactDOM","findDOMNode","instance","window","internal_reactDOMfindDOMNode","rectProperties","shouldSkipElement","element","includes","getComputedStyle","position","process","env","NODE_ENV","console","warn","rect","getBoundingClientRect","every","item","topOfElementInViewport","viewportHeight","top","getHashFragmentDomNode","hashFragment","document","body","getElementById","getElementsByName","InnerScrollAndFocusHandler","React","Component","componentDidMount","handlePotentialScroll","componentDidUpdate","props","focusAndScrollRef","apply","render","children","segmentPath","segmentPaths","some","scrollRefSegmentPath","index","domNode","Element","HTMLElement","parentElement","localName","nextElementSibling","handleSmoothScroll","scrollIntoView","htmlElement","documentElement","clientHeight","scrollTop","dontForceLayout","onlyHashChange","focus","ScrollAndFocusHandler","context","useContext","GlobalLayoutRouterContext","Error","InnerLayoutRouter","tree","cacheNode","url","fullTree","resolvedPrefetchRsc","prefetchRsc","rsc","useDeferredValue","resolvedRsc","then","use","lazyData","refetchTree","includeNextUrl","hasInterceptionRouteInCurrentTree","navigatedAt","Date","now","fetchServerResponse","URL","location","origin","flightRouterState","nextUrl","serverResponse","startTransition","dispatchAppRouterAction","type","ACTION_SERVER_PATCH","previousTree","unresolvedThenable","subtree","LayoutRouterContext","Provider","value","parentTree","parentCacheNode","parentSegmentPath","LoadingBoundary","loading","loadingModuleData","promiseForLoading","loadingRsc","loadingStyles","loadingScripts","Suspense","fallback","parallelRouterKey","error","errorStyles","errorScripts","templateStyles","templateScripts","template","notFound","forbidden","unauthorized","parentParallelRoutes","parallelRoutes","segmentMap","get","Map","set","parentTreeSegment","treeSegment","concat","cacheKey","createRouterCacheKey","stateKey","newLazyCacheNode","head","prefetchHead","TemplateContext","ErrorBoundary","errorComponent","HTTPAccessFallbackBoundary","RedirectBoundary"],"mappings":"AAAA;;;;;+BAoeA;;;CAGC,GACD;;;eAAwBA;;;;;;oCAzdjB;iEASA;mEACc;+CAKd;qCAC6B;oCACD;+BACL;+BACD;oCACM;kCACF;gCACU;sCACN;mDACa;gCACV;AAExC;;;CAGC,GACD,SAASC,eACPC,iBAAgD,EAChDC,cAAiC;IAEjC,IAAID,mBAAmB;QACrB,MAAM,CAACE,SAASC,iBAAiB,GAAGH;QACpC,MAAMI,SAASJ,kBAAkBK,MAAM,KAAK;QAE5C,IAAIC,IAAAA,2BAAY,EAACL,cAAc,CAAC,EAAE,EAAEC,UAAU;YAC5C,IAAID,cAAc,CAAC,EAAE,CAACM,cAAc,CAACJ,mBAAmB;gBACtD,IAAIC,QAAQ;oBACV,MAAMI,UAAUT,eACdU,WACAR,cAAc,CAAC,EAAE,CAACE,iBAAiB;oBAErC,OAAO;wBACLF,cAAc,CAAC,EAAE;wBACjB;4BACE,GAAGA,cAAc,CAAC,EAAE;4BACpB,CAACE,iBAAiB,EAAE;gCAClBK,OAAO,CAAC,EAAE;gCACVA,OAAO,CAAC,EAAE;gCACVA,OAAO,CAAC,EAAE;gCACV;6BACD;wBACH;qBACD;gBACH;gBAEA,OAAO;oBACLP,cAAc,CAAC,EAAE;oBACjB;wBACE,GAAGA,cAAc,CAAC,EAAE;wBACpB,CAACE,iBAAiB,EAAEJ,eAClBC,kBAAkBU,KAAK,CAAC,IACxBT,cAAc,CAAC,EAAE,CAACE,iBAAiB;oBAEvC;iBACD;YACH;QACF;IACF;IAEA,OAAOF;AACT;AAEA,MAAMU,+DAA+D,AACnEC,iBAAQ,CACRD,4DAA4D;AAE9D,4FAA4F;AAC5F;;CAEC,GACD,SAASE,YACPC,QAAgD;IAEhD,+BAA+B;IAC/B,IAAI,OAAOC,WAAW,aAAa,OAAO;IAE1C,uGAAuG;IACvG,kCAAkC;IAClC,MAAMC,+BACJL,6DAA6DE,WAAW;IAC1E,OAAOG,6BAA6BF;AACtC;AAEA,MAAMG,iBAAiB;IACrB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;CACD;AACD;;CAEC,GACD,SAASC,kBAAkBC,OAAoB;IAC7C,kGAAkG;IAClG,0FAA0F;IAC1F,mDAAmD;IACnD,IAAI;QAAC;QAAU;KAAQ,CAACC,QAAQ,CAACC,iBAAiBF,SAASG,QAAQ,GAAG;QACpE,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;YAC1CC,QAAQC,IAAI,CACV,4FACAR;QAEJ;QACA,OAAO;IACT;IAEA,2FAA2F;IAC3F,wDAAwD;IACxD,MAAMS,OAAOT,QAAQU,qBAAqB;IAC1C,OAAOZ,eAAea,KAAK,CAAC,CAACC,OAASH,IAAI,CAACG,KAAK,KAAK;AACvD;AAEA;;CAEC,GACD,SAASC,uBAAuBb,OAAoB,EAAEc,cAAsB;IAC1E,MAAML,OAAOT,QAAQU,qBAAqB;IAC1C,OAAOD,KAAKM,GAAG,IAAI,KAAKN,KAAKM,GAAG,IAAID;AACtC;AAEA;;;;;CAKC,GACD,SAASE,uBAAuBC,YAAoB;IAClD,+EAA+E;IAC/E,IAAIA,iBAAiB,OAAO;QAC1B,OAAOC,SAASC,IAAI;IACtB;QAIED;IAFF,qFAAqF;IACrF,OACEA,CAAAA,2BAAAA,SAASE,cAAc,CAACH,yBAAxBC,2BACA,8FAA8F;IAC9FA,SAASG,iBAAiB,CAACJ,aAAa,CAAC,EAAE;AAE/C;AAMA,MAAMK,mCAAmCC,cAAK,CAACC,SAAS;IA4GtDC,oBAAoB;QAClB,IAAI,CAACC,qBAAqB;IAC5B;IAEAC,qBAAqB;QACnB,sJAAsJ;QACtJ,IAAI,IAAI,CAACC,KAAK,CAACC,iBAAiB,CAACC,KAAK,EAAE;YACtC,IAAI,CAACJ,qBAAqB;QAC5B;IACF;IAEAK,SAAS;QACP,OAAO,IAAI,CAACH,KAAK,CAACI,QAAQ;IAC5B;;QAzHF,qBACEN,wBAAwB;YACtB,qGAAqG;YACrG,MAAM,EAAEG,iBAAiB,EAAEI,WAAW,EAAE,GAAG,IAAI,CAACL,KAAK;YAErD,IAAIC,kBAAkBC,KAAK,EAAE;gBAC3B,uEAAuE;gBACvE,6EAA6E;gBAC7E,wEAAwE;gBACxE,IACED,kBAAkBK,YAAY,CAAChD,MAAM,KAAK,KAC1C,CAAC2C,kBAAkBK,YAAY,CAACC,IAAI,CAAC,CAACC,uBACpCH,YAAYtB,KAAK,CAAC,CAAC5B,SAASsD,QAC1BlD,IAAAA,2BAAY,EAACJ,SAASqD,oBAAoB,CAACC,MAAM,KAGrD;oBACA;gBACF;gBAEA,IAAIC,UAEiC;gBACrC,MAAMrB,eAAeY,kBAAkBZ,YAAY;gBAEnD,IAAIA,cAAc;oBAChBqB,UAAUtB,uBAAuBC;gBACnC;gBAEA,kGAAkG;gBAClG,yEAAyE;gBACzE,IAAI,CAACqB,SAAS;oBACZA,UAAU5C,YAAY,IAAI;gBAC5B;gBAEA,uGAAuG;gBACvG,IAAI,CAAE4C,CAAAA,mBAAmBC,OAAM,GAAI;oBACjC;gBACF;gBAEA,4FAA4F;gBAC5F,2EAA2E;gBAC3E,MAAO,CAAED,CAAAA,mBAAmBE,WAAU,KAAMzC,kBAAkBuC,SAAU;oBACtE,IAAIlC,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;4BACrCgC;wBAAJ,IAAIA,EAAAA,yBAAAA,QAAQG,aAAa,qBAArBH,uBAAuBI,SAAS,MAAK,QAAQ;wBAC/C,2FAA2F;wBAC3F,yEAAyE;wBACzE,iHAAiH;wBACnH;oBACF;oBAEA,uGAAuG;oBACvG,IAAIJ,QAAQK,kBAAkB,KAAK,MAAM;wBACvC;oBACF;oBACAL,UAAUA,QAAQK,kBAAkB;gBACtC;gBAEA,6EAA6E;gBAC7Ed,kBAAkBC,KAAK,GAAG;gBAC1BD,kBAAkBZ,YAAY,GAAG;gBACjCY,kBAAkBK,YAAY,GAAG,EAAE;gBAEnCU,IAAAA,sCAAkB,EAChB;oBACE,uEAAuE;oBACvE,IAAI3B,cAAc;;wBACdqB,QAAwBO,cAAc;wBAExC;oBACF;oBACA,oFAAoF;oBACpF,4CAA4C;oBAC5C,MAAMC,cAAc5B,SAAS6B,eAAe;oBAC5C,MAAMjC,iBAAiBgC,YAAYE,YAAY;oBAE/C,oEAAoE;oBACpE,IAAInC,uBAAuByB,SAAwBxB,iBAAiB;wBAClE;oBACF;oBAEA,2FAA2F;oBAC3F,kHAAkH;oBAClH,qHAAqH;oBACrH,6HAA6H;oBAC7HgC,YAAYG,SAAS,GAAG;oBAExB,mFAAmF;oBACnF,IAAI,CAACpC,uBAAuByB,SAAwBxB,iBAAiB;wBACnE,0EAA0E;;wBACxEwB,QAAwBO,cAAc;oBAC1C;gBACF,GACA;oBACE,oDAAoD;oBACpDK,iBAAiB;oBACjBC,gBAAgBtB,kBAAkBsB,cAAc;gBAClD;gBAGF,wEAAwE;gBACxEtB,kBAAkBsB,cAAc,GAAG;gBAEnC,2BAA2B;gBAC3Bb,QAAQc,KAAK;YACf;QACF;;AAgBF;AAEA,SAASC,sBAAsB,KAM9B;IAN8B,IAAA,EAC7BpB,WAAW,EACXD,QAAQ,EAIT,GAN8B;IAO7B,MAAMsB,UAAUC,IAAAA,iBAAU,EAACC,wDAAyB;IACpD,IAAI,CAACF,SAAS;QACZ,MAAM,qBAAuD,CAAvD,IAAIG,MAAM,+CAAV,qBAAA;mBAAA;wBAAA;0BAAA;QAAsD;IAC9D;IAEA,qBACE,qBAACnC;QACCW,aAAaA;QACbJ,mBAAmByB,QAAQzB,iBAAiB;kBAE3CG;;AAGP;AAEA;;CAEC,GACD,SAAS0B,kBAAkB,KAU1B;IAV0B,IAAA,EACzBC,IAAI,EACJ1B,WAAW,EACX2B,SAAS,EACTC,GAAG,EAMJ,GAV0B;IAWzB,MAAMP,UAAUC,IAAAA,iBAAU,EAACC,wDAAyB;IACpD,IAAI,CAACF,SAAS;QACZ,MAAM,qBAAuD,CAAvD,IAAIG,MAAM,+CAAV,qBAAA;mBAAA;wBAAA;0BAAA;QAAsD;IAC9D;IAEA,MAAM,EAAEE,MAAMG,QAAQ,EAAE,GAAGR;IAE3B,yDAAyD;IAEzD,4EAA4E;IAC5E,2EAA2E;IAC3E,iDAAiD;IACjD,EAAE;IACF,4EAA4E;IAC5E,MAAMS,sBACJH,UAAUI,WAAW,KAAK,OAAOJ,UAAUI,WAAW,GAAGJ,UAAUK,GAAG;IAExE,2EAA2E;IAC3E,2EAA2E;IAC3E,sCAAsC;IACtC,MAAMA,MAAWC,IAAAA,uBAAgB,EAACN,UAAUK,GAAG,EAAEF;IAEjD,wEAAwE;IACxE,2EAA2E;IAC3E,8EAA8E;IAC9E,mBAAmB;IACnB,MAAMI,cACJ,OAAOF,QAAQ,YAAYA,QAAQ,QAAQ,OAAOA,IAAIG,IAAI,KAAK,aAC3DC,IAAAA,UAAG,EAACJ,OACJA;IAEN,IAAI,CAACE,aAAa;QAChB,qEAAqE;QACrE,yEAAyE;QACzE,kCAAkC;QAElC,8CAA8C;QAC9C,IAAIG,WAAWV,UAAUU,QAAQ;QACjC,IAAIA,aAAa,MAAM;YACrB;;OAEC,GACD,sBAAsB;YACtB,MAAMC,cAAc3F,eAAe;gBAAC;mBAAOqD;aAAY,EAAE6B;YACzD,MAAMU,iBAAiBC,IAAAA,oEAAiC,EAACX;YACzD,MAAMY,cAAcC,KAAKC,GAAG;YAC5BhB,UAAUU,QAAQ,GAAGA,WAAWO,IAAAA,wCAAmB,EACjD,IAAIC,IAAIjB,KAAKkB,SAASC,MAAM,GAC5B;gBACEC,mBAAmBV;gBACnBW,SAASV,iBAAiBlB,QAAQ4B,OAAO,GAAG;YAC9C,GACAd,IAAI,CAAC,CAACe;gBACNC,IAAAA,sBAAe,EAAC;oBACdC,IAAAA,uCAAuB,EAAC;wBACtBC,MAAMC,uCAAmB;wBACzBC,cAAc1B;wBACdqB;wBACAT;oBACF;gBACF;gBAEA,OAAOS;YACT;YAEA,gDAAgD;YAChDd,IAAAA,UAAG,EAACC;QACN;QACA,yGAAyG;QACzG,iIAAiI;QACjID,IAAAA,UAAG,EAACoB,sCAAkB;IACxB;IAEA,yEAAyE;IACzE,MAAMC,UACJ,4EAA4E;kBAC5E,qBAACC,kDAAmB,CAACC,QAAQ;QAC3BC,OAAO;YACLC,YAAYnC;YACZoC,iBAAiBnC;YACjBoC,mBAAmB/D;YAEnB,kDAAkD;YAClD4B,KAAKA;QACP;kBAECM;;IAGL,iFAAiF;IACjF,OAAOuB;AACT;AAEA;;;CAGC,GACD,SAASO,gBAAgB,KAMxB;IANwB,IAAA,EACvBC,OAAO,EACPlE,QAAQ,EAIT,GANwB;IAOvB,6EAA6E;IAC7E,4EAA4E;IAC5E,kDAAkD;IAClD,EAAE;IACF,sEAAsE;IACtE,4EAA4E;IAC5E,0EAA0E;IAC1E,8BAA8B;IAC9B,IAAImE;IACJ,IACE,OAAOD,YAAY,YACnBA,YAAY,QACZ,OAAO,AAACA,QAAgB9B,IAAI,KAAK,YACjC;QACA,MAAMgC,oBAAoBF;QAC1BC,oBAAoB9B,IAAAA,UAAG,EAAC+B;IAC1B,OAAO;QACLD,oBAAoBD;IACtB;IAEA,IAAIC,mBAAmB;QACrB,MAAME,aAAaF,iBAAiB,CAAC,EAAE;QACvC,MAAMG,gBAAgBH,iBAAiB,CAAC,EAAE;QAC1C,MAAMI,iBAAiBJ,iBAAiB,CAAC,EAAE;QAC3C,qBACE,qBAACK,eAAQ;YACPC,wBACE;;oBACGH;oBACAC;oBACAF;;;sBAIJrE;;IAGP;IAEA,qBAAO;kBAAGA;;AACZ;AAMe,SAASrD,kBAAkB,KAsBzC;IAtByC,IAAA,EACxC+H,iBAAiB,EACjBC,KAAK,EACLC,WAAW,EACXC,YAAY,EACZC,cAAc,EACdC,eAAe,EACfC,QAAQ,EACRC,QAAQ,EACRC,SAAS,EACTC,YAAY,EAYb,GAtByC;IAuBxC,MAAM7D,UAAUC,IAAAA,iBAAU,EAACoC,kDAAmB;IAC9C,IAAI,CAACrC,SAAS;QACZ,MAAM,qBAA2D,CAA3D,IAAIG,MAAM,mDAAV,qBAAA;mBAAA;wBAAA;0BAAA;QAA0D;IAClE;IAEA,MAAM,EAAEqC,UAAU,EAAEC,eAAe,EAAEC,iBAAiB,EAAEnC,GAAG,EAAE,GAAGP;IAEhE,6EAA6E;IAC7E,aAAa;IACb,MAAM8D,uBAAuBrB,gBAAgBsB,cAAc;IAC3D,IAAIC,aAAaF,qBAAqBG,GAAG,CAACb;IAC1C,mEAAmE;IACnE,yJAAyJ;IACzJ,IAAI,CAACY,YAAY;QACfA,aAAa,IAAIE;QACjBJ,qBAAqBK,GAAG,CAACf,mBAAmBY;IAC9C;IAEA,qCAAqC;IACrC,8IAA8I;IAC9I,MAAMI,oBAAoB5B,UAAU,CAAC,EAAE;IACvC,MAAMnC,OAAOmC,UAAU,CAAC,EAAE,CAACY,kBAAkB;IAC7C,MAAMiB,cAAchE,IAAI,CAAC,EAAE;IAE3B,MAAM1B,cACJ+D,sBAAsB,OAElB,sEAAsE;IACtE,qCAAqC;IACrC;QAACU;KAAkB,GACnBV,kBAAkB4B,MAAM,CAAC;QAACF;QAAmBhB;KAAkB;IAErE,8EAA8E;IAC9E,uEAAuE;IACvE,8EAA8E;IAC9E,6EAA6E;IAC7E,0DAA0D;IAC1D,EAAE;IACF,8EAA8E;IAC9E,2EAA2E;IAC3E,4EAA4E;IAC5E,yBAAyB;IACzB,MAAMmB,WAAWC,IAAAA,0CAAoB,EAACH;IACtC,MAAMI,WAAWD,IAAAA,0CAAoB,EAACH,aAAa,MAAM,mBAAmB;;IAE5E,yDAAyD;IACzD,IAAI/D,YAAY0D,WAAWC,GAAG,CAACM;IAC/B,IAAIjE,cAActE,WAAW;QAC3B,2EAA2E;QAC3E,sBAAsB;QACtB,MAAM0I,mBAAkC;YACtC1D,UAAU;YACVL,KAAK;YACLD,aAAa;YACbiE,MAAM;YACNC,cAAc;YACdb,gBAAgB,IAAIG;YACpBtB,SAAS;YACTxB,aAAa,CAAC;QAChB;QAEA,qEAAqE;QACrEd,YAAYoE;QACZV,WAAWG,GAAG,CAACI,UAAUG;IAC3B;IAEA;;;;;;;;EAQA,GAEA,4EAA4E;IAC5E,wEAAwE;IACxE,2EAA2E;IAC3E,2EAA2E;IAC3E,4EAA4E;IAC5E,0EAA0E;IAC1E,8EAA8E;IAC9E,6DAA6D;IAC7D,MAAM7B,oBAAoBJ,gBAAgBG,OAAO;IAEjD,qBACE,sBAACiC,8CAAe,CAACvC,QAAQ;QAEvBC,qBACE,qBAACxC;YAAsBpB,aAAaA;sBAClC,cAAA,qBAACmG,4BAAa;gBACZC,gBAAgB1B;gBAChBC,aAAaA;gBACbC,cAAcA;0BAEd,cAAA,qBAACZ;oBAAgBC,SAASC;8BACxB,cAAA,qBAACmC,0CAA0B;wBACzBrB,UAAUA;wBACVC,WAAWA;wBACXC,cAAcA;kCAEd,cAAA,qBAACoB,kCAAgB;sCACf,cAAA,qBAAC7E;gCACCG,KAAKA;gCACLF,MAAMA;gCACNC,WAAWA;gCACX3B,aAAaA;;;;;;;;YAS1B6E;YACAC;YACAC;;OA9BIe;AAiCX"}
1
+ {"version":3,"sources":["../../../src/client/components/layout-router.tsx"],"sourcesContent":["'use client'\n\nimport type {\n CacheNode,\n LazyCacheNode,\n LoadingModuleData,\n} from '../../shared/lib/app-router-context.shared-runtime'\nimport type {\n FlightRouterState,\n FlightSegmentPath,\n} from '../../server/app-render/types'\nimport type { ErrorComponent } from './error-boundary'\nimport {\n ACTION_SERVER_PATCH,\n type FocusAndScrollRef,\n} from './router-reducer/router-reducer-types'\n\nimport React, {\n useContext,\n use,\n startTransition,\n Suspense,\n useDeferredValue,\n type JSX,\n} from 'react'\nimport ReactDOM from 'react-dom'\nimport {\n LayoutRouterContext,\n GlobalLayoutRouterContext,\n TemplateContext,\n} from '../../shared/lib/app-router-context.shared-runtime'\nimport { fetchServerResponse } from './router-reducer/fetch-server-response'\nimport { unresolvedThenable } from './unresolved-thenable'\nimport { ErrorBoundary } from './error-boundary'\nimport { matchSegment } from './match-segments'\nimport { handleSmoothScroll } from '../../shared/lib/router/utils/handle-smooth-scroll'\nimport { RedirectBoundary } from './redirect-boundary'\nimport { HTTPAccessFallbackBoundary } from './http-access-fallback/error-boundary'\nimport { createRouterCacheKey } from './router-reducer/create-router-cache-key'\nimport { hasInterceptionRouteInCurrentTree } from './router-reducer/reducers/has-interception-route-in-current-tree'\nimport { dispatchAppRouterAction } from './use-action-queue'\nimport { useRouterBFCache, type RouterBFCacheEntry } from './bfcache'\n\nconst Activity = process.env.__NEXT_ROUTER_BF_CACHE\n ? require('react').unstable_Activity\n : null\n\n/**\n * Add refetch marker to router state at the point of the current layout segment.\n * This ensures the response returned is not further down than the current layout segment.\n */\nfunction walkAddRefetch(\n segmentPathToWalk: FlightSegmentPath | undefined,\n treeToRecreate: FlightRouterState\n): FlightRouterState {\n if (segmentPathToWalk) {\n const [segment, parallelRouteKey] = segmentPathToWalk\n const isLast = segmentPathToWalk.length === 2\n\n if (matchSegment(treeToRecreate[0], segment)) {\n if (treeToRecreate[1].hasOwnProperty(parallelRouteKey)) {\n if (isLast) {\n const subTree = walkAddRefetch(\n undefined,\n treeToRecreate[1][parallelRouteKey]\n )\n return [\n treeToRecreate[0],\n {\n ...treeToRecreate[1],\n [parallelRouteKey]: [\n subTree[0],\n subTree[1],\n subTree[2],\n 'refetch',\n ],\n },\n ]\n }\n\n return [\n treeToRecreate[0],\n {\n ...treeToRecreate[1],\n [parallelRouteKey]: walkAddRefetch(\n segmentPathToWalk.slice(2),\n treeToRecreate[1][parallelRouteKey]\n ),\n },\n ]\n }\n }\n }\n\n return treeToRecreate\n}\n\nconst __DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE = (\n ReactDOM as any\n).__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE\n\n// TODO-APP: Replace with new React API for finding dom nodes without a `ref` when available\n/**\n * Wraps ReactDOM.findDOMNode with additional logic to hide React Strict Mode warning\n */\nfunction findDOMNode(\n instance: React.ReactInstance | null | undefined\n): Element | Text | null {\n // Tree-shake for server bundle\n if (typeof window === 'undefined') return null\n\n // __DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE.findDOMNode is null during module init.\n // We need to lazily reference it.\n const internal_reactDOMfindDOMNode =\n __DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE.findDOMNode\n return internal_reactDOMfindDOMNode(instance)\n}\n\nconst rectProperties = [\n 'bottom',\n 'height',\n 'left',\n 'right',\n 'top',\n 'width',\n 'x',\n 'y',\n] as const\n/**\n * Check if a HTMLElement is hidden or fixed/sticky position\n */\nfunction shouldSkipElement(element: HTMLElement) {\n // we ignore fixed or sticky positioned elements since they'll likely pass the \"in-viewport\" check\n // and will result in a situation we bail on scroll because of something like a fixed nav,\n // even though the actual page content is offscreen\n if (['sticky', 'fixed'].includes(getComputedStyle(element).position)) {\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n 'Skipping auto-scroll behavior due to `position: sticky` or `position: fixed` on element:',\n element\n )\n }\n return true\n }\n\n // Uses `getBoundingClientRect` to check if the element is hidden instead of `offsetParent`\n // because `offsetParent` doesn't consider document/body\n const rect = element.getBoundingClientRect()\n return rectProperties.every((item) => rect[item] === 0)\n}\n\n/**\n * Check if the top corner of the HTMLElement is in the viewport.\n */\nfunction topOfElementInViewport(element: HTMLElement, viewportHeight: number) {\n const rect = element.getBoundingClientRect()\n return rect.top >= 0 && rect.top <= viewportHeight\n}\n\n/**\n * Find the DOM node for a hash fragment.\n * If `top` the page has to scroll to the top of the page. This mirrors the browser's behavior.\n * If the hash fragment is an id, the page has to scroll to the element with that id.\n * If the hash fragment is a name, the page has to scroll to the first element with that name.\n */\nfunction getHashFragmentDomNode(hashFragment: string) {\n // If the hash fragment is `top` the page has to scroll to the top of the page.\n if (hashFragment === 'top') {\n return document.body\n }\n\n // If the hash fragment is an id, the page has to scroll to the element with that id.\n return (\n document.getElementById(hashFragment) ??\n // If the hash fragment is a name, the page has to scroll to the first element with that name.\n document.getElementsByName(hashFragment)[0]\n )\n}\ninterface ScrollAndFocusHandlerProps {\n focusAndScrollRef: FocusAndScrollRef\n children: React.ReactNode\n segmentPath: FlightSegmentPath\n}\nclass InnerScrollAndFocusHandler extends React.Component<ScrollAndFocusHandlerProps> {\n handlePotentialScroll = () => {\n // Handle scroll and focus, it's only applied once in the first useEffect that triggers that changed.\n const { focusAndScrollRef, segmentPath } = this.props\n\n if (focusAndScrollRef.apply) {\n // segmentPaths is an array of segment paths that should be scrolled to\n // if the current segment path is not in the array, the scroll is not applied\n // unless the array is empty, in which case the scroll is always applied\n if (\n focusAndScrollRef.segmentPaths.length !== 0 &&\n !focusAndScrollRef.segmentPaths.some((scrollRefSegmentPath) =>\n segmentPath.every((segment, index) =>\n matchSegment(segment, scrollRefSegmentPath[index])\n )\n )\n ) {\n return\n }\n\n let domNode:\n | ReturnType<typeof getHashFragmentDomNode>\n | ReturnType<typeof findDOMNode> = null\n const hashFragment = focusAndScrollRef.hashFragment\n\n if (hashFragment) {\n domNode = getHashFragmentDomNode(hashFragment)\n }\n\n // `findDOMNode` is tricky because it returns just the first child if the component is a fragment.\n // This already caused a bug where the first child was a <link/> in head.\n if (!domNode) {\n domNode = findDOMNode(this)\n }\n\n // If there is no DOM node this layout-router level is skipped. It'll be handled higher-up in the tree.\n if (!(domNode instanceof Element)) {\n return\n }\n\n // Verify if the element is a HTMLElement and if we want to consider it for scroll behavior.\n // If the element is skipped, try to select the next sibling and try again.\n while (!(domNode instanceof HTMLElement) || shouldSkipElement(domNode)) {\n if (process.env.NODE_ENV !== 'production') {\n if (domNode.parentElement?.localName === 'head') {\n // TODO: We enter this state when metadata was rendered as part of the page or via Next.js.\n // This is always a bug in Next.js and caused by React hoisting metadata.\n // We need to replace `findDOMNode` in favor of Fragment Refs (when available) so that we can skip over metadata.\n }\n }\n\n // No siblings found that match the criteria are found, so handle scroll higher up in the tree instead.\n if (domNode.nextElementSibling === null) {\n return\n }\n domNode = domNode.nextElementSibling\n }\n\n // State is mutated to ensure that the focus and scroll is applied only once.\n focusAndScrollRef.apply = false\n focusAndScrollRef.hashFragment = null\n focusAndScrollRef.segmentPaths = []\n\n handleSmoothScroll(\n () => {\n // In case of hash scroll, we only need to scroll the element into view\n if (hashFragment) {\n ;(domNode as HTMLElement).scrollIntoView()\n\n return\n }\n // Store the current viewport height because reading `clientHeight` causes a reflow,\n // and it won't change during this function.\n const htmlElement = document.documentElement\n const viewportHeight = htmlElement.clientHeight\n\n // If the element's top edge is already in the viewport, exit early.\n if (topOfElementInViewport(domNode as HTMLElement, viewportHeight)) {\n return\n }\n\n // Otherwise, try scrolling go the top of the document to be backward compatible with pages\n // scrollIntoView() called on `<html/>` element scrolls horizontally on chrome and firefox (that shouldn't happen)\n // We could use it to scroll horizontally following RTL but that also seems to be broken - it will always scroll left\n // scrollLeft = 0 also seems to ignore RTL and manually checking for RTL is too much hassle so we will scroll just vertically\n htmlElement.scrollTop = 0\n\n // Scroll to domNode if domNode is not in viewport when scrolled to top of document\n if (!topOfElementInViewport(domNode as HTMLElement, viewportHeight)) {\n // Scroll into view doesn't scroll horizontally by default when not needed\n ;(domNode as HTMLElement).scrollIntoView()\n }\n },\n {\n // We will force layout by querying domNode position\n dontForceLayout: true,\n onlyHashChange: focusAndScrollRef.onlyHashChange,\n }\n )\n\n // Mutate after scrolling so that it can be read by `handleSmoothScroll`\n focusAndScrollRef.onlyHashChange = false\n\n // Set focus on the element\n domNode.focus()\n }\n }\n\n componentDidMount() {\n this.handlePotentialScroll()\n }\n\n componentDidUpdate() {\n // Because this property is overwritten in handlePotentialScroll it's fine to always run it when true as it'll be set to false for subsequent renders.\n if (this.props.focusAndScrollRef.apply) {\n this.handlePotentialScroll()\n }\n }\n\n render() {\n return this.props.children\n }\n}\n\nfunction ScrollAndFocusHandler({\n segmentPath,\n children,\n}: {\n segmentPath: FlightSegmentPath\n children: React.ReactNode\n}) {\n const context = useContext(GlobalLayoutRouterContext)\n if (!context) {\n throw new Error('invariant global layout router not mounted')\n }\n\n return (\n <InnerScrollAndFocusHandler\n segmentPath={segmentPath}\n focusAndScrollRef={context.focusAndScrollRef}\n >\n {children}\n </InnerScrollAndFocusHandler>\n )\n}\n\n/**\n * InnerLayoutRouter handles rendering the provided segment based on the cache.\n */\nfunction InnerLayoutRouter({\n tree,\n segmentPath,\n cacheNode,\n url,\n}: {\n tree: FlightRouterState\n segmentPath: FlightSegmentPath\n cacheNode: CacheNode\n url: string\n}) {\n const context = useContext(GlobalLayoutRouterContext)\n if (!context) {\n throw new Error('invariant global layout router not mounted')\n }\n\n const { tree: fullTree } = context\n\n // `rsc` represents the renderable node for this segment.\n\n // If this segment has a `prefetchRsc`, it's the statically prefetched data.\n // We should use that on initial render instead of `rsc`. Then we'll switch\n // to `rsc` when the dynamic response streams in.\n //\n // If no prefetch data is available, then we go straight to rendering `rsc`.\n const resolvedPrefetchRsc =\n cacheNode.prefetchRsc !== null ? cacheNode.prefetchRsc : cacheNode.rsc\n\n // We use `useDeferredValue` to handle switching between the prefetched and\n // final values. The second argument is returned on initial render, then it\n // re-renders with the first argument.\n const rsc: any = useDeferredValue(cacheNode.rsc, resolvedPrefetchRsc)\n\n // `rsc` is either a React node or a promise for a React node, except we\n // special case `null` to represent that this segment's data is missing. If\n // it's a promise, we need to unwrap it so we can determine whether or not the\n // data is missing.\n const resolvedRsc: React.ReactNode =\n typeof rsc === 'object' && rsc !== null && typeof rsc.then === 'function'\n ? use(rsc)\n : rsc\n\n if (!resolvedRsc) {\n // The data for this segment is not available, and there's no pending\n // navigation that will be able to fulfill it. We need to fetch more from\n // the server and patch the cache.\n\n // Check if there's already a pending request.\n let lazyData = cacheNode.lazyData\n if (lazyData === null) {\n /**\n * Router state with refetch marker added\n */\n // TODO-APP: remove ''\n const refetchTree = walkAddRefetch(['', ...segmentPath], fullTree)\n const includeNextUrl = hasInterceptionRouteInCurrentTree(fullTree)\n const navigatedAt = Date.now()\n cacheNode.lazyData = lazyData = fetchServerResponse(\n new URL(url, location.origin),\n {\n flightRouterState: refetchTree,\n nextUrl: includeNextUrl ? context.nextUrl : null,\n }\n ).then((serverResponse) => {\n startTransition(() => {\n dispatchAppRouterAction({\n type: ACTION_SERVER_PATCH,\n previousTree: fullTree,\n serverResponse,\n navigatedAt,\n })\n })\n\n return serverResponse\n })\n\n // Suspend while waiting for lazyData to resolve\n use(lazyData)\n }\n // Suspend infinitely as `changeByServerResponse` will cause a different part of the tree to be rendered.\n // A falsey `resolvedRsc` indicates missing data -- we should not commit that branch, and we need to wait for the data to arrive.\n use(unresolvedThenable) as never\n }\n\n // If we get to this point, then we know we have something we can render.\n const subtree = (\n // The layout router context narrows down tree and childNodes at each level.\n <LayoutRouterContext.Provider\n value={{\n parentTree: tree,\n parentCacheNode: cacheNode,\n parentSegmentPath: segmentPath,\n\n // TODO-APP: overriding of url for parallel routes\n url: url,\n }}\n >\n {resolvedRsc}\n </LayoutRouterContext.Provider>\n )\n // Ensure root layout is not wrapped in a div as the root layout renders `<html>`\n return subtree\n}\n\n/**\n * Renders suspense boundary with the provided \"loading\" property as the fallback.\n * If no loading property is provided it renders the children without a suspense boundary.\n */\nfunction LoadingBoundary({\n loading,\n children,\n}: {\n loading: LoadingModuleData | Promise<LoadingModuleData>\n children: React.ReactNode\n}): JSX.Element {\n // If loading is a promise, unwrap it. This happens in cases where we haven't\n // yet received the loading data from the server — which includes whether or\n // not this layout has a loading component at all.\n //\n // It's OK to suspend here instead of inside the fallback because this\n // promise will resolve simultaneously with the data for the segment itself.\n // So it will never suspend for longer than it would have if we didn't use\n // a Suspense fallback at all.\n let loadingModuleData\n if (\n typeof loading === 'object' &&\n loading !== null &&\n typeof (loading as any).then === 'function'\n ) {\n const promiseForLoading = loading as Promise<LoadingModuleData>\n loadingModuleData = use(promiseForLoading)\n } else {\n loadingModuleData = loading as LoadingModuleData\n }\n\n if (loadingModuleData) {\n const loadingRsc = loadingModuleData[0]\n const loadingStyles = loadingModuleData[1]\n const loadingScripts = loadingModuleData[2]\n return (\n <Suspense\n fallback={\n <>\n {loadingStyles}\n {loadingScripts}\n {loadingRsc}\n </>\n }\n >\n {children}\n </Suspense>\n )\n }\n\n return <>{children}</>\n}\n\n/**\n * OuterLayoutRouter handles the current segment as well as <Offscreen> rendering of other segments.\n * It can be rendered next to each other with a different `parallelRouterKey`, allowing for Parallel routes.\n */\nexport default function OuterLayoutRouter({\n parallelRouterKey,\n error,\n errorStyles,\n errorScripts,\n templateStyles,\n templateScripts,\n template,\n notFound,\n forbidden,\n unauthorized,\n}: {\n parallelRouterKey: string\n error: ErrorComponent | undefined\n errorStyles: React.ReactNode | undefined\n errorScripts: React.ReactNode | undefined\n templateStyles: React.ReactNode | undefined\n templateScripts: React.ReactNode | undefined\n template: React.ReactNode\n notFound: React.ReactNode | undefined\n forbidden: React.ReactNode | undefined\n unauthorized: React.ReactNode | undefined\n}) {\n const context = useContext(LayoutRouterContext)\n if (!context) {\n throw new Error('invariant expected layout router to be mounted')\n }\n\n const { parentTree, parentCacheNode, parentSegmentPath, url } = context\n\n // Get the CacheNode for this segment by reading it from the parent segment's\n // child map.\n const parentParallelRoutes = parentCacheNode.parallelRoutes\n let segmentMap = parentParallelRoutes.get(parallelRouterKey)\n // If the parallel router cache node does not exist yet, create it.\n // This writes to the cache when there is no item in the cache yet. It never *overwrites* existing cache items which is why it's safe in concurrent mode.\n if (!segmentMap) {\n segmentMap = new Map()\n parentParallelRoutes.set(parallelRouterKey, segmentMap)\n }\n const parentTreeSegment = parentTree[0]\n const segmentPath =\n parentSegmentPath === null\n ? // TODO: The root segment value is currently omitted from the segment\n // path. This has led to a bunch of special cases scattered throughout\n // the code. We should clean this up.\n [parallelRouterKey]\n : parentSegmentPath.concat([parentTreeSegment, parallelRouterKey])\n\n // The \"state\" key of a segment is the one passed to React — it represents the\n // identity of the UI tree. Whenever the state key changes, the tree is\n // recreated and the state is reset. In the App Router model, search params do\n // not cause state to be lost, so two segments with the same segment path but\n // different search params should have the same state key.\n //\n // The \"cache\" key of a segment, however, *does* include the search params, if\n // it's possible that the segment accessed the search params on the server.\n // (This only applies to page segments; layout segments cannot access search\n // params on the server.)\n const activeTree = parentTree[1][parallelRouterKey]\n const activeSegment = activeTree[0]\n const activeStateKey = createRouterCacheKey(activeSegment, true) // no search params\n\n // At each level of the route tree, not only do we render the currently\n // active segment — we also render the last N segments that were active at\n // this level inside a hidden <Activity> boundary, to preserve their state\n // if or when the user navigates to them again.\n //\n // bfcacheEntry is a linked list of FlightRouterStates.\n let bfcacheEntry: RouterBFCacheEntry | null = useRouterBFCache(\n activeTree,\n activeStateKey\n )\n let children: Array<React.ReactNode> = []\n do {\n const tree = bfcacheEntry.tree\n const stateKey = bfcacheEntry.stateKey\n const segment = tree[0]\n const cacheKey = createRouterCacheKey(segment)\n\n // Read segment path from the parallel router cache node.\n let cacheNode = segmentMap.get(cacheKey)\n if (cacheNode === undefined) {\n // When data is not available during rendering client-side we need to fetch\n // it from the server.\n const newLazyCacheNode: LazyCacheNode = {\n lazyData: null,\n rsc: null,\n prefetchRsc: null,\n head: null,\n prefetchHead: null,\n parallelRoutes: new Map(),\n loading: null,\n navigatedAt: -1,\n }\n\n // Flight data fetch kicked off during render and put into the cache.\n cacheNode = newLazyCacheNode\n segmentMap.set(cacheKey, newLazyCacheNode)\n }\n\n /*\n - Error boundary\n - Only renders error boundary if error component is provided.\n - Rendered for each segment to ensure they have their own error state.\n - Loading boundary\n - Only renders suspense boundary if loading components is provided.\n - Rendered for each segment to ensure they have their own loading state.\n - Passed to the router during rendering to ensure it can be immediately rendered when suspending on a Flight fetch.\n */\n\n // TODO: The loading module data for a segment is stored on the parent, then\n // applied to each of that parent segment's parallel route slots. In the\n // simple case where there's only one parallel route (the `children` slot),\n // this is no different from if the loading module data where stored on the\n // child directly. But I'm not sure this actually makes sense when there are\n // multiple parallel routes. It's not a huge issue because you always have\n // the option to define a narrower loading boundary for a particular slot. But\n // this sort of smells like an implementation accident to me.\n const loadingModuleData = parentCacheNode.loading\n let child = (\n <TemplateContext.Provider\n key={stateKey}\n value={\n <ScrollAndFocusHandler segmentPath={segmentPath}>\n <ErrorBoundary\n errorComponent={error}\n errorStyles={errorStyles}\n errorScripts={errorScripts}\n >\n <LoadingBoundary loading={loadingModuleData}>\n <HTTPAccessFallbackBoundary\n notFound={notFound}\n forbidden={forbidden}\n unauthorized={unauthorized}\n >\n <RedirectBoundary>\n <InnerLayoutRouter\n url={url}\n tree={tree}\n cacheNode={cacheNode}\n segmentPath={segmentPath}\n />\n </RedirectBoundary>\n </HTTPAccessFallbackBoundary>\n </LoadingBoundary>\n </ErrorBoundary>\n </ScrollAndFocusHandler>\n }\n >\n {templateStyles}\n {templateScripts}\n {template}\n </TemplateContext.Provider>\n )\n\n if (process.env.__NEXT_ROUTER_BF_CACHE) {\n child = (\n <Activity\n key={stateKey}\n mode={stateKey === activeStateKey ? 'visible' : 'hidden'}\n >\n {child}\n </Activity>\n )\n }\n\n children.push(child)\n\n bfcacheEntry = bfcacheEntry.next\n } while (bfcacheEntry !== null)\n\n return children\n}\n"],"names":["OuterLayoutRouter","Activity","process","env","__NEXT_ROUTER_BF_CACHE","require","unstable_Activity","walkAddRefetch","segmentPathToWalk","treeToRecreate","segment","parallelRouteKey","isLast","length","matchSegment","hasOwnProperty","subTree","undefined","slice","__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE","ReactDOM","findDOMNode","instance","window","internal_reactDOMfindDOMNode","rectProperties","shouldSkipElement","element","includes","getComputedStyle","position","NODE_ENV","console","warn","rect","getBoundingClientRect","every","item","topOfElementInViewport","viewportHeight","top","getHashFragmentDomNode","hashFragment","document","body","getElementById","getElementsByName","InnerScrollAndFocusHandler","React","Component","componentDidMount","handlePotentialScroll","componentDidUpdate","props","focusAndScrollRef","apply","render","children","segmentPath","segmentPaths","some","scrollRefSegmentPath","index","domNode","Element","HTMLElement","parentElement","localName","nextElementSibling","handleSmoothScroll","scrollIntoView","htmlElement","documentElement","clientHeight","scrollTop","dontForceLayout","onlyHashChange","focus","ScrollAndFocusHandler","context","useContext","GlobalLayoutRouterContext","Error","InnerLayoutRouter","tree","cacheNode","url","fullTree","resolvedPrefetchRsc","prefetchRsc","rsc","useDeferredValue","resolvedRsc","then","use","lazyData","refetchTree","includeNextUrl","hasInterceptionRouteInCurrentTree","navigatedAt","Date","now","fetchServerResponse","URL","location","origin","flightRouterState","nextUrl","serverResponse","startTransition","dispatchAppRouterAction","type","ACTION_SERVER_PATCH","previousTree","unresolvedThenable","subtree","LayoutRouterContext","Provider","value","parentTree","parentCacheNode","parentSegmentPath","LoadingBoundary","loading","loadingModuleData","promiseForLoading","loadingRsc","loadingStyles","loadingScripts","Suspense","fallback","parallelRouterKey","error","errorStyles","errorScripts","templateStyles","templateScripts","template","notFound","forbidden","unauthorized","parentParallelRoutes","parallelRoutes","segmentMap","get","Map","set","parentTreeSegment","concat","activeTree","activeSegment","activeStateKey","createRouterCacheKey","bfcacheEntry","useRouterBFCache","stateKey","cacheKey","newLazyCacheNode","head","prefetchHead","child","TemplateContext","ErrorBoundary","errorComponent","HTTPAccessFallbackBoundary","RedirectBoundary","mode","push","next"],"mappings":"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"}
@@ -61,7 +61,7 @@ const _hooksclientcontextsharedruntime = require("../shared/lib/hooks-client-con
61
61
  const _onrecoverableerror = require("./react-client-callbacks/on-recoverable-error");
62
62
  const _tracer = /*#__PURE__*/ _interop_require_default._(require("./tracing/tracer"));
63
63
  const _isnextroutererror = require("./components/is-next-router-error");
64
- const version = "15.3.1-canary.4";
64
+ const version = "15.3.1-canary.5";
65
65
  let router;
66
66
  const emitter = (0, _mitt.default)();
67
67
  const looseToArray = (input)=>[].slice.call(input);
@@ -307,7 +307,7 @@ export default async function build(dir, reactProductionProfiling = false, debug
307
307
  const nextBuildSpan = trace('next-build', undefined, {
308
308
  buildMode: experimentalBuildMode,
309
309
  isTurboBuild: String(isTurbopack),
310
- version: "15.3.1-canary.4"
310
+ version: "15.3.1-canary.5"
311
311
  });
312
312
  NextBuildContext.nextBuildSpan = nextBuildSpan;
313
313
  NextBuildContext.dir = dir;
@@ -688,7 +688,7 @@ export default async function build(dir, reactProductionProfiling = false, debug
688
688
  // Files outside of the distDir can be "type": "module"
689
689
  await writeFileUtf8(path.join(distDir, 'package.json'), '{"type": "commonjs"}');
690
690
  // These are written to distDir, so they need to come after creating and cleaning distDr.
691
- await recordFrameworkVersion("15.3.1-canary.4");
691
+ await recordFrameworkVersion("15.3.1-canary.5");
692
692
  await updateBuildDiagnostics({
693
693
  buildStage: 'start'
694
694
  });
@@ -11,7 +11,7 @@ import { isDeepStrictEqual } from 'util';
11
11
  import { getDefineEnv } from '../webpack/plugins/define-env-plugin';
12
12
  import { getReactCompilerLoader } from '../get-babel-loader-config';
13
13
  import { TurbopackInternalError } from '../../shared/lib/turbopack/utils';
14
- const nextVersion = "15.3.1-canary.4";
14
+ const nextVersion = "15.3.1-canary.5";
15
15
  const ArchName = arch();
16
16
  const PlatformName = platform();
17
17
  function infoLog(...args) {