@bleedingdev/modern-js-runtime 3.2.0-ultramodern.102 → 3.2.0-ultramodern.104

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.
Files changed (179) hide show
  1. package/dist/cjs/boundary-debugger/index.js +15 -11
  2. package/dist/cjs/cache/index.js +9 -5
  3. package/dist/cjs/cli/alias.js +9 -5
  4. package/dist/cjs/cli/code.js +9 -5
  5. package/dist/cjs/cli/constants.js +20 -16
  6. package/dist/cjs/cli/entry.js +9 -5
  7. package/dist/cjs/cli/index.js +9 -5
  8. package/dist/cjs/cli/ssr/index.js +9 -5
  9. package/dist/cjs/cli/ssr/loadable-bundler-plugin.js +9 -5
  10. package/dist/cjs/cli/ssr/mode.js +12 -8
  11. package/dist/cjs/cli/template.js +9 -5
  12. package/dist/cjs/cli/template.server.js +9 -5
  13. package/dist/cjs/common.js +14 -10
  14. package/dist/cjs/core/browser/hydrate.js +9 -5
  15. package/dist/cjs/core/browser/index.js +9 -5
  16. package/dist/cjs/core/browser/withCallback.js +9 -5
  17. package/dist/cjs/core/compat/hooks.js +14 -10
  18. package/dist/cjs/core/compat/index.js +9 -5
  19. package/dist/cjs/core/compat/requestContext.js +13 -9
  20. package/dist/cjs/core/config.js +12 -8
  21. package/dist/cjs/core/constants.js +15 -10
  22. package/dist/cjs/core/context/index.js +9 -5
  23. package/dist/cjs/core/context/monitors/default.js +12 -8
  24. package/dist/cjs/core/context/monitors/index.js +9 -5
  25. package/dist/cjs/core/context/monitors/index.server.js +9 -5
  26. package/dist/cjs/core/context/request/index.js +12 -8
  27. package/dist/cjs/core/context/request/index.server.js +9 -5
  28. package/dist/cjs/core/context/response/index.js +15 -11
  29. package/dist/cjs/core/context/response/index.server.js +9 -5
  30. package/dist/cjs/core/context/runtime.js +9 -5
  31. package/dist/cjs/core/context/serverPayload/index.js +13 -9
  32. package/dist/cjs/core/context/serverPayload/index.server.js +9 -5
  33. package/dist/cjs/core/index.js +9 -5
  34. package/dist/cjs/core/plugin/index.js +9 -5
  35. package/dist/cjs/core/react/index.js +9 -5
  36. package/dist/cjs/core/react/wrapper.js +9 -5
  37. package/dist/cjs/core/server/constants.js +15 -11
  38. package/dist/cjs/core/server/federatedCss.js +11 -7
  39. package/dist/cjs/core/server/helmet.js +9 -5
  40. package/dist/cjs/core/server/index.js +9 -5
  41. package/dist/cjs/core/server/react/index.js +9 -5
  42. package/dist/cjs/core/server/react/no-ssr-cache/index.js +9 -5
  43. package/dist/cjs/core/server/react/nossr/index.js +9 -5
  44. package/dist/cjs/core/server/requestHandler.js +9 -5
  45. package/dist/cjs/core/server/scriptOrder.js +14 -10
  46. package/dist/cjs/core/server/server.js +9 -5
  47. package/dist/cjs/core/server/shared.js +12 -8
  48. package/dist/cjs/core/server/stream/afterTemplate.js +9 -5
  49. package/dist/cjs/core/server/stream/beforeTemplate.js +10 -6
  50. package/dist/cjs/core/server/stream/beforeTemplate.worker.js +10 -6
  51. package/dist/cjs/core/server/stream/createReadableStream.js +9 -5
  52. package/dist/cjs/core/server/stream/createReadableStream.worker.js +9 -5
  53. package/dist/cjs/core/server/stream/deferredScript.js +9 -5
  54. package/dist/cjs/core/server/stream/index.js +9 -5
  55. package/dist/cjs/core/server/stream/shared.js +9 -5
  56. package/dist/cjs/core/server/stream/template.js +9 -5
  57. package/dist/cjs/core/server/string/index.js +9 -5
  58. package/dist/cjs/core/server/string/loadable.js +9 -5
  59. package/dist/cjs/core/server/string/ssrData.js +9 -5
  60. package/dist/cjs/core/server/tracer.js +13 -9
  61. package/dist/cjs/core/server/utils.js +9 -5
  62. package/dist/cjs/document/Body.js +9 -5
  63. package/dist/cjs/document/Comment.js +9 -5
  64. package/dist/cjs/document/DocumentContext.js +9 -5
  65. package/dist/cjs/document/DocumentStructureContext.js +9 -5
  66. package/dist/cjs/document/Head.js +9 -5
  67. package/dist/cjs/document/Html.js +9 -5
  68. package/dist/cjs/document/Links.js +9 -5
  69. package/dist/cjs/document/Root.js +9 -5
  70. package/dist/cjs/document/Script.js +9 -5
  71. package/dist/cjs/document/Scripts.js +9 -5
  72. package/dist/cjs/document/Style.js +9 -5
  73. package/dist/cjs/document/Title.js +9 -5
  74. package/dist/cjs/document/cli/index.js +12 -6
  75. package/dist/cjs/document/constants.js +9 -5
  76. package/dist/cjs/document/index.js +9 -5
  77. package/dist/cjs/exports/config-routes.js +12 -8
  78. package/dist/cjs/exports/head.js +18 -10
  79. package/dist/cjs/exports/loadable.js +27 -18
  80. package/dist/cjs/exports/tanstack-router.js +9 -5
  81. package/dist/cjs/index.js +9 -5
  82. package/dist/cjs/internal.js +9 -5
  83. package/dist/cjs/react-server.js +9 -5
  84. package/dist/cjs/router/cli/code/getClientRoutes/getRoutes.js +9 -5
  85. package/dist/cjs/router/cli/code/getClientRoutes/index.js +9 -5
  86. package/dist/cjs/router/cli/code/getClientRoutes/utils.js +9 -5
  87. package/dist/cjs/router/cli/code/index.js +9 -5
  88. package/dist/cjs/router/cli/code/inspect.js +9 -5
  89. package/dist/cjs/router/cli/code/makeLegalIdentifier.js +12 -8
  90. package/dist/cjs/router/cli/code/nestedRoutes.js +9 -5
  91. package/dist/cjs/router/cli/code/tanstackTypes.js +9 -5
  92. package/dist/cjs/router/cli/code/templates.js +9 -5
  93. package/dist/cjs/router/cli/code/utils.js +9 -5
  94. package/dist/cjs/router/cli/config-routes/converter.js +9 -5
  95. package/dist/cjs/router/cli/config-routes/parseRouteConfig.js +9 -5
  96. package/dist/cjs/router/cli/constants.js +23 -19
  97. package/dist/cjs/router/cli/entry.js +9 -5
  98. package/dist/cjs/router/cli/handler.js +9 -5
  99. package/dist/cjs/router/cli/index.js +9 -5
  100. package/dist/cjs/router/index.js +9 -5
  101. package/dist/cjs/router/internal.js +12 -8
  102. package/dist/cjs/router/runtime/CSSLinks.js +9 -5
  103. package/dist/cjs/router/runtime/DefaultNotFound.js +9 -5
  104. package/dist/cjs/router/runtime/DeferredDataScripts.js +12 -8
  105. package/dist/cjs/router/runtime/DeferredDataScripts.node.js +9 -5
  106. package/dist/cjs/router/runtime/PrefetchLink.js +162 -26
  107. package/dist/cjs/router/runtime/constants.js +9 -5
  108. package/dist/cjs/router/runtime/hooks.js +9 -5
  109. package/dist/cjs/router/runtime/index.js +15 -10
  110. package/dist/cjs/router/runtime/internal.js +9 -5
  111. package/dist/cjs/router/runtime/lifecycle.js +18 -14
  112. package/dist/cjs/router/runtime/plugin.js +9 -5
  113. package/dist/cjs/router/runtime/plugin.node.js +9 -5
  114. package/dist/cjs/router/runtime/routerHelper.js +9 -5
  115. package/dist/cjs/router/runtime/rsc-router.js +9 -5
  116. package/dist/cjs/router/runtime/rsc.js +9 -5
  117. package/dist/cjs/router/runtime/server.js +9 -5
  118. package/dist/cjs/router/runtime/tanstack/basepathRewrite.js +12 -8
  119. package/dist/cjs/router/runtime/tanstack/dataMutation.js +9 -5
  120. package/dist/cjs/router/runtime/tanstack/hydrationBoundary.js +9 -5
  121. package/dist/cjs/router/runtime/tanstack/outlet.js +10 -6
  122. package/dist/cjs/router/runtime/tanstack/plugin.js +42 -41
  123. package/dist/cjs/router/runtime/tanstack/plugin.node.js +9 -5
  124. package/dist/cjs/router/runtime/tanstack/prefetchLink.js +10 -6
  125. package/dist/cjs/router/runtime/tanstack/routeTree.js +9 -5
  126. package/dist/cjs/router/runtime/tanstack/rsc/ClientSlot.js +9 -5
  127. package/dist/cjs/router/runtime/tanstack/rsc/CompositeComponent.js +9 -5
  128. package/dist/cjs/router/runtime/tanstack/rsc/ReplayableStream.js +14 -9
  129. package/dist/cjs/router/runtime/tanstack/rsc/RscNodeRenderer.js +9 -5
  130. package/dist/cjs/router/runtime/tanstack/rsc/SlotContext.js +9 -5
  131. package/dist/cjs/router/runtime/tanstack/rsc/client.js +9 -5
  132. package/dist/cjs/router/runtime/tanstack/rsc/createRscProxy.js +9 -5
  133. package/dist/cjs/router/runtime/tanstack/rsc/index.js +9 -5
  134. package/dist/cjs/router/runtime/tanstack/rsc/server.js +9 -5
  135. package/dist/cjs/router/runtime/tanstack/rsc/slotUsageSanitizer.js +9 -5
  136. package/dist/cjs/router/runtime/tanstack/rsc/symbols.js +20 -15
  137. package/dist/cjs/router/runtime/utils.js +9 -5
  138. package/dist/cjs/router/runtime/withRouter.js +9 -5
  139. package/dist/cjs/rsc/client.js +12 -8
  140. package/dist/cjs/rsc/server.js +9 -5
  141. package/dist/cjs/rsc/server.worker.js +9 -5
  142. package/dist/cjs/ssr/index.node.js +13 -9
  143. package/dist/cjs/ssr/serverRender/renderToStream/buildTemplate.after.js +9 -5
  144. package/dist/cjs/ssr/serverRender/renderToString/entry.js +9 -5
  145. package/dist/cjs/ssr/serverRender/types.js +9 -5
  146. package/dist/esm/boundary-debugger/index.mjs +6 -6
  147. package/dist/esm/core/server/federatedCss.mjs +2 -2
  148. package/dist/esm/core/server/scriptOrder.mjs +2 -2
  149. package/dist/esm/core/server/stream/beforeTemplate.mjs +1 -1
  150. package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +1 -1
  151. package/dist/esm/document/cli/index.mjs +3 -1
  152. package/dist/esm/exports/head.mjs +9 -5
  153. package/dist/esm/exports/loadable.mjs +12 -6
  154. package/dist/esm/router/runtime/PrefetchLink.mjs +153 -21
  155. package/dist/esm/router/runtime/tanstack/outlet.mjs +1 -1
  156. package/dist/esm/router/runtime/tanstack/plugin.mjs +33 -36
  157. package/dist/esm/router/runtime/tanstack/prefetchLink.mjs +1 -1
  158. package/dist/esm-node/boundary-debugger/index.mjs +6 -6
  159. package/dist/esm-node/core/server/federatedCss.mjs +2 -2
  160. package/dist/esm-node/core/server/scriptOrder.mjs +2 -2
  161. package/dist/esm-node/core/server/stream/beforeTemplate.mjs +1 -1
  162. package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +1 -1
  163. package/dist/esm-node/document/cli/index.mjs +3 -1
  164. package/dist/esm-node/exports/head.mjs +9 -5
  165. package/dist/esm-node/exports/loadable.mjs +12 -6
  166. package/dist/esm-node/router/runtime/PrefetchLink.mjs +153 -21
  167. package/dist/esm-node/router/runtime/tanstack/outlet.mjs +1 -1
  168. package/dist/esm-node/router/runtime/tanstack/plugin.mjs +33 -36
  169. package/dist/esm-node/router/runtime/tanstack/prefetchLink.mjs +1 -1
  170. package/dist/types/cli/entry.d.ts +2 -2
  171. package/dist/types/core/context/response/index.server.d.ts +4 -1
  172. package/dist/types/core/plugin/index.d.ts +1 -1
  173. package/dist/types/core/server/utils.d.ts +11 -1
  174. package/dist/types/exports/head.d.ts +4 -4
  175. package/dist/types/exports/loadable.d.ts +1 -1
  176. package/dist/types/router/cli/code/utils.d.ts +1 -1
  177. package/dist/types/router/cli/entry.d.ts +1 -1
  178. package/dist/types/router/runtime/PrefetchLink.d.ts +5 -1
  179. package/package.json +10 -10
@@ -61,49 +61,46 @@ function getCachedRouteModule(routeId) {
61
61
  if ("u" < typeof window) return;
62
62
  return window[routeModulesKey]?.[routeId];
63
63
  }
64
- async function preloadHydratedRouteComponents(router) {
64
+ function preloadHydratedRouteComponents(router) {
65
65
  const preloadableRouter = router;
66
66
  const routesById = preloadableRouter.routesById || {};
67
67
  const matches = preloadableRouter.stores.matches.get();
68
- await Promise.all(matches.map((match)=>{
69
- if (!match.routeId) return;
68
+ return Promise.all(matches.map((match)=>{
69
+ if (void 0 === match.routeId || '' === match.routeId) return;
70
70
  const route = routesById[match.routeId];
71
71
  const component = route?.options?.component;
72
72
  const preload = component?.load || component?.preload;
73
73
  if ('function' != typeof preload) return;
74
74
  return Promise.resolve(preload.call(component)).then((routeModule)=>{
75
75
  const modernRouteId = route?.options?.staticData?.modernRouteId;
76
- const resolvedComponent = pickRouteModuleComponent(modernRouteId && getCachedRouteModule(modernRouteId) || routeModule);
77
- if (resolvedComponent && modernRouteId) route.options.component = withModernRouteMatchContext(resolvedComponent, modernRouteId);
76
+ const cachedRouteModule = 'string' == typeof modernRouteId && '' !== modernRouteId ? getCachedRouteModule(modernRouteId) : void 0;
77
+ const resolvedComponent = pickRouteModuleComponent(cachedRouteModule ?? routeModule);
78
+ if (void 0 !== resolvedComponent && 'string' == typeof modernRouteId && '' !== modernRouteId) route.options.component = withModernRouteMatchContext(resolvedComponent, modernRouteId);
78
79
  });
79
- }));
80
+ })).then(()=>void 0);
80
81
  }
81
82
  function getTanstackSsrHydrationRecord(router) {
82
- let hydrationRecord = routerHydrationRecords.get(router);
83
- if (!hydrationRecord) {
84
- hydrationRecord = {
85
- promise: Promise.resolve(),
86
- status: 'pending'
87
- };
88
- routerHydrationRecords.set(router, hydrationRecord);
89
- try {
90
- hydrationRecord.promise = hydrate(router).then(async (value)=>{
91
- await preloadHydratedRouteComponents(router);
92
- return value;
93
- }).then((value)=>{
94
- hydrationRecord.status = 'fulfilled';
95
- return value;
96
- }, (error)=>{
97
- hydrationRecord.status = 'rejected';
98
- hydrationRecord.error = error;
99
- throw error;
100
- });
101
- } catch (error) {
83
+ const existingHydrationRecord = routerHydrationRecords.get(router);
84
+ if (void 0 !== existingHydrationRecord) return existingHydrationRecord;
85
+ const hydrationRecord = {
86
+ promise: Promise.resolve(),
87
+ status: 'pending'
88
+ };
89
+ routerHydrationRecords.set(router, hydrationRecord);
90
+ try {
91
+ hydrationRecord.promise = hydrate(router).then((value)=>preloadHydratedRouteComponents(router).then(()=>value)).then((value)=>{
92
+ hydrationRecord.status = 'fulfilled';
93
+ return value;
94
+ }, (error)=>{
102
95
  hydrationRecord.status = 'rejected';
103
96
  hydrationRecord.error = error;
104
- hydrationRecord.promise = Promise.reject(error);
105
- hydrationRecord.promise.catch(()=>{});
106
- }
97
+ throw error;
98
+ });
99
+ } catch (error) {
100
+ hydrationRecord.status = 'rejected';
101
+ hydrationRecord.error = error;
102
+ hydrationRecord.promise = Promise.reject(error);
103
+ hydrationRecord.promise.catch(()=>{});
107
104
  }
108
105
  return hydrationRecord;
109
106
  }
@@ -224,13 +221,13 @@ const tanstackRouterPlugin = (userConfig = {})=>({
224
221
  });
225
222
  return cachedRouter;
226
223
  };
227
- api.onBeforeRender(async (context)=>{
224
+ api.onBeforeRender((context)=>{
228
225
  const mergedConfig = getMergedConfig();
229
- if ("u" > typeof window && window._SSR_DATA && mergedConfig.unstable_reloadOnURLMismatch) {
226
+ if ("u" > typeof window && void 0 !== window._SSR_DATA && mergedConfig.unstable_reloadOnURLMismatch) {
230
227
  const { ssrContext } = context;
231
228
  const currentPathname = normalizePathname(window.location.pathname);
232
- const initialPathname = ssrContext?.request?.pathname && normalizePathname(ssrContext.request.pathname);
233
- if (initialPathname && initialPathname !== currentPathname) {
229
+ const initialPathname = 'string' == typeof ssrContext?.request?.pathname ? normalizePathname(ssrContext.request.pathname) : void 0;
230
+ if (void 0 !== initialPathname && '' !== initialPathname && initialPathname !== currentPathname) {
234
231
  const errorMsg = `The initial URL ${initialPathname} and the URL ${currentPathname} to be hydrated do not match, reload.`;
235
232
  console.error(errorMsg);
236
233
  window.location.reload();
@@ -244,14 +241,14 @@ const tanstackRouterPlugin = (userConfig = {})=>({
244
241
  useRouter: useRouter
245
242
  };
246
243
  const hasSSRBootstrap = "u" > typeof window && Boolean(window.$_TSR);
247
- if (hasSSRBootstrap && getRouteObjects().length) {
244
+ if (hasSSRBootstrap && getRouteObjects().length > 0) {
248
245
  const runtimeContext = context;
249
246
  const router = getRouter(runtimeContext, getClientBasename(runtimeContext));
250
- if (router) await getTanstackSsrHydrationPromise(router);
247
+ if (null != router) return getTanstackSsrHydrationPromise(router).then(()=>void 0);
251
248
  }
252
249
  });
253
250
  api.wrapRoot((App)=>{
254
- if (!getRouteObjects().length) return App;
251
+ if (0 === getRouteObjects().length) return App;
255
252
  const RouterWrapper = ()=>{
256
253
  const runtimeContext = useContext(InternalRuntimeContext);
257
254
  const _basename = getClientBasename(runtimeContext);
@@ -4,7 +4,7 @@ function resolvePreloadFromPrefetch(prefetch, preload) {
4
4
  if (void 0 !== preload) return preload;
5
5
  if ('none' === prefetch) return false;
6
6
  if ('intent' === prefetch || 'render' === prefetch || 'viewport' === prefetch) return prefetch;
7
- return preload;
7
+ return 'viewport';
8
8
  }
9
9
  const LinkComponentImpl = (props)=>{
10
10
  const { prefetch, preload, ...rest } = props;
@@ -51,7 +51,7 @@ const readQueryEnabledOverride = ()=>{
51
51
  const detectLanguage = ()=>{
52
52
  if ("u" < typeof document) return 'en';
53
53
  const htmlLanguage = document.documentElement.lang;
54
- if (htmlLanguage) return htmlLanguage.split('-')[0] || 'en';
54
+ if ('' !== htmlLanguage) return htmlLanguage.split('-')[0] || 'en';
55
55
  if ("u" < typeof window) return 'en';
56
56
  return window.location.pathname.split('/').filter(Boolean)[0] || 'en';
57
57
  };
@@ -70,7 +70,7 @@ const getBoundaryId = (element)=>element.dataset.modernBoundaryId ?? element.dat
70
70
  const collectBoundaryElements = (legacySelector)=>{
71
71
  const elements = new Set();
72
72
  for (const element of document.querySelectorAll(boundarySelector))elements.add(element);
73
- if (!legacySelector) return Array.from(elements);
73
+ if (void 0 === legacySelector || '' === legacySelector) return Array.from(elements);
74
74
  try {
75
75
  for (const element of document.querySelectorAll(legacySelector))elements.add(element);
76
76
  } catch {}
@@ -114,7 +114,7 @@ function BoundaryDebugger({ controlMode = 'visible', enabledByDefault = false, l
114
114
  const seenBoxes = new Set();
115
115
  const nextBoxes = collectBoundaryElements(legacySelector).map((element)=>{
116
116
  const boundaryId = getBoundaryId(element);
117
- if (!boundaryId) return;
117
+ if (void 0 === boundaryId || '' === boundaryId) return;
118
118
  const rect = element.getBoundingClientRect();
119
119
  if (rect.width <= 0 || rect.height <= 0) return;
120
120
  const rectKey = formatRectKey(rect);
@@ -125,7 +125,7 @@ function BoundaryDebugger({ controlMode = 'visible', enabledByDefault = false, l
125
125
  const color = boundary?.color ?? palette[hashBoundaryId(boundaryId) % palette.length];
126
126
  const label = boundary?.label ?? boundary?.appId ?? boundaryId;
127
127
  const expose = element.dataset.modernMfExpose;
128
- const detail = expose && expose !== label && expose !== boundaryId ? expose : void 0;
128
+ const detail = void 0 !== expose && '' !== expose && expose !== label && expose !== boundaryId ? expose : void 0;
129
129
  const box = {
130
130
  color,
131
131
  height: rect.height,
@@ -135,7 +135,7 @@ function BoundaryDebugger({ controlMode = 'visible', enabledByDefault = false, l
135
135
  top: rect.top,
136
136
  width: rect.width
137
137
  };
138
- if (detail) box.detail = detail;
138
+ if (void 0 !== detail) box.detail = detail;
139
139
  return box;
140
140
  }).filter((box)=>void 0 !== box);
141
141
  setBoxes(nextBoxes);
@@ -228,7 +228,7 @@ function BoundaryDebugger({ controlMode = 'visible', enabledByDefault = false, l
228
228
  /*#__PURE__*/ jsx("span", {
229
229
  children: box.label
230
230
  }),
231
- box.detail ? /*#__PURE__*/ jsx("span", {
231
+ void 0 !== box.detail && '' !== box.detail ? /*#__PURE__*/ jsx("span", {
232
232
  style: {
233
233
  font: '700 10px/1.1 system-ui, sans-serif',
234
234
  opacity: 0.82,
@@ -1,11 +1,11 @@
1
1
  import "node:module";
2
2
  import { attributesToString } from "./utils.mjs";
3
3
  const createFederatedCssLinks = (assets, options)=>{
4
- if (!assets?.length) return '';
4
+ if (void 0 === assets || 0 === assets.length) return '';
5
5
  const seen = new Set(options.existingAssets || []);
6
6
  const attributes = attributesToString(options.attributes || {});
7
7
  const links = [];
8
- for (const asset of assets)if (!(!asset || seen.has(asset) || options.template.includes(asset))) {
8
+ for (const asset of assets)if (!('' === asset || seen.has(asset) || options.template.includes(asset))) {
9
9
  seen.add(asset);
10
10
  links.push(`<link${attributes} href="${asset}" rel="stylesheet" />`);
11
11
  }
@@ -17,10 +17,10 @@ function isEntryScript(src, entryName, asyncEntry) {
17
17
  return basename === `${prefix}.js` || basename.startsWith(`${prefix}.`) || basename.startsWith(`${prefix}-`);
18
18
  }
19
19
  function injectBeforeHydrationEntryScript(template, scripts, entryName = 'index') {
20
- if (!scripts) return template;
20
+ if ('' === scripts) return template;
21
21
  const scriptTags = getScriptTags(template);
22
22
  const target = scriptTags.find((match)=>isEntryScript(match.src, entryName, false)) ?? scriptTags.find((match)=>isEntryScript(match.src, entryName, true));
23
- if (!target) return template;
23
+ if (void 0 === target) return template;
24
24
  return `${template.slice(0, target.index)}${scripts}${template.slice(target.index)}`;
25
25
  }
26
26
  export { injectBeforeHydrationEntryScript };
@@ -49,7 +49,7 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
49
49
  if (!index) return;
50
50
  const routeId = match.route.id;
51
51
  if (routeId) return routeAssets[routeId];
52
- }).filter(Boolean) ?? [];
52
+ }).filter((routeManifest)=>void 0 !== routeManifest) ?? [];
53
53
  }
54
54
  const asyncEntry = routeAssets[`async-${entryName}`];
55
55
  if (asyncEntry) matchedRouteManifests.push(asyncEntry);
@@ -40,7 +40,7 @@ async function buildShellBeforeTemplate(beforeAppTemplate, options) {
40
40
  if (!index) return;
41
41
  const routeId = match.route.id;
42
42
  if (routeId) return routeAssets[routeId];
43
- }).filter(Boolean) ?? [];
43
+ }).filter((routeManifest)=>void 0 !== routeManifest) ?? [];
44
44
  }
45
45
  const asyncEntry = routeAssets[`async-${entryName}`];
46
46
  if (asyncEntry) matchedRouteManifests.push(asyncEntry);
@@ -301,7 +301,7 @@ const documentPlugin = ()=>({
301
301
  const { entrypoints, internalDirectory, appDirectory } = api.getAppContext();
302
302
  const documentFilePath = getDocumentByEntryName(entrypoints, entryName, appDirectory);
303
303
  if (!documentFilePath) return null;
304
- return async ({ htmlPlugin })=>{
304
+ return async (templateData)=>{
305
305
  const config = api.getNormalizedConfig();
306
306
  const documentParams = getDocParams({
307
307
  config: config,
@@ -320,6 +320,8 @@ const documentPlugin = ()=>({
320
320
  debug("entry %s's document jsx rendered html: %o", entryName, html);
321
321
  const { partialsByEntrypoint } = api.getAppContext();
322
322
  html = processPartials(html, entryName, partialsByEntrypoint || {});
323
+ const htmlPlugin = templateData.htmlPlugin || templateData.htmlWebpackPlugin || templateData.htmlRspackPlugin;
324
+ if (!htmlPlugin) throw new Error('Failed to get HTML plugin tags from template parameters.');
323
325
  const { scripts, links, metas, titles } = extractHtmlTags(htmlPlugin, templateParameters);
324
326
  return processPlaceholders(html, config, scripts, links, metas, titles);
325
327
  };
@@ -41,7 +41,7 @@ const createAttributeDatum = (attributes)=>({
41
41
  const createTitleDatum = (title, attributes)=>({
42
42
  toComponent: ()=>[],
43
43
  toString: ()=>{
44
- if (!title) return '';
44
+ if (void 0 === title || '' === title) return '';
45
45
  const attrs = attributesToString(attributes, true);
46
46
  return `<title ${attrs}>${escapeHtml(title)}</title>`;
47
47
  }
@@ -58,6 +58,10 @@ const createEmptyHelmetState = ()=>({
58
58
  style: createDatum('style', []),
59
59
  title: createTitleDatum(void 0, {})
60
60
  });
61
+ const normalizeHelmetTitle = (title)=>{
62
+ if ('string' == typeof title) return title;
63
+ if (Array.isArray(title)) return title.map((part)=>String(part)).join('');
64
+ };
61
65
  const mergeAttributes = (current, next)=>({
62
66
  ...current,
63
67
  ...next ?? {}
@@ -87,7 +91,7 @@ const collectHelmetProps = (current, props)=>{
87
91
  const baseState = current ?? createEmptyHelmetState();
88
92
  const draft = {
89
93
  base: [
90
- ...props.base ? [
94
+ ...void 0 !== props.base ? [
91
95
  props.base
92
96
  ] : []
93
97
  ],
@@ -108,11 +112,11 @@ const collectHelmetProps = (current, props)=>{
108
112
  style: [
109
113
  ...props.style ?? []
110
114
  ],
111
- title: 'string' == typeof props.title ? props.title : Array.isArray(props.title) ? props.title.join('') : void 0,
115
+ title: normalizeHelmetTitle(props.title),
112
116
  titleAttributes: props.titleAttributes ?? {}
113
117
  };
114
118
  collectChildren(props.children, draft);
115
- const title = draft.title && props.titleTemplate ? props.titleTemplate.replaceAll('%s', draft.title) : draft.title ?? props.defaultTitle;
119
+ const title = void 0 !== draft.title && '' !== draft.title && void 0 !== props.titleTemplate ? props.titleTemplate.replaceAll('%s', draft.title) : draft.title ?? props.defaultTitle;
116
120
  return {
117
121
  base: createDatum('base', [
118
122
  ...baseState.__baseTags ?? [],
@@ -174,7 +178,7 @@ const collectHelmetProps = (current, props)=>{
174
178
  };
175
179
  const head_Helmet = (props)=>{
176
180
  const runtimeContext = react.useContext(InternalRuntimeContext);
177
- if (runtimeContext && !runtimeContext.isBrowser) {
181
+ if (null !== runtimeContext && false === runtimeContext.isBrowser) {
178
182
  runtimeContext._helmetContext ??= {};
179
183
  runtimeContext._helmetContext.helmet = collectHelmetProps(runtimeContext._helmetContext.helmet ?? void 0, props);
180
184
  return null;
@@ -1,22 +1,28 @@
1
1
  import "node:module";
2
2
  import * as __rspack_external__loadable_component_0aaae075 from "@loadable/component";
3
3
  export * from "@loadable/component";
4
+ function asLoadableNamespace(value) {
5
+ return 'object' == typeof value && null !== value ? value : {};
6
+ }
4
7
  function resolveLoadable(module) {
5
- const namespace = module;
6
- const defaultExport = namespace.default;
8
+ const namespace = asLoadableNamespace(module);
9
+ const defaultExport = asLoadableNamespace(namespace.default);
7
10
  const candidates = [
8
11
  module,
9
12
  namespace.default,
10
13
  defaultExport?.default
11
14
  ];
12
15
  const loadable = candidates.find((candidate)=>'function' == typeof candidate);
13
- if (!loadable) throw new TypeError('Modern.js runtime loadable export must resolve to a function');
16
+ if ('function' != typeof loadable) throw new TypeError('Modern.js runtime loadable export must resolve to a function');
14
17
  return loadable;
15
18
  }
16
19
  const loadable_loadable = resolveLoadable(__rspack_external__loadable_component_0aaae075);
17
- const lazy = __rspack_external__loadable_component_0aaae075.lazy ?? __rspack_external__loadable_component_0aaae075["default"]?.lazy ?? loadable_loadable.lazy;
18
- const loadableReady = __rspack_external__loadable_component_0aaae075.loadableReady ?? __rspack_external__loadable_component_0aaae075["default"]?.loadableReady ?? loadable_loadable.loadableReady;
19
- const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = __rspack_external__loadable_component_0aaae075.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? __rspack_external__loadable_component_0aaae075["default"]?.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? loadable_loadable.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
20
+ const loadableNamespace = asLoadableNamespace(__rspack_external__loadable_component_0aaae075);
21
+ const loadableDefaultNamespace = asLoadableNamespace(loadableNamespace.default);
22
+ const callableLoadableNamespace = asLoadableNamespace(loadable_loadable);
23
+ const lazy = loadableNamespace.lazy ?? loadableDefaultNamespace.lazy ?? callableLoadableNamespace.lazy;
24
+ const loadableReady = loadableNamespace.loadableReady ?? loadableDefaultNamespace.loadableReady ?? callableLoadableNamespace.loadableReady;
25
+ const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = loadableNamespace.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? loadableDefaultNamespace.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED ?? callableLoadableNamespace.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
20
26
  const exports_loadable = loadable_loadable;
21
27
  export default exports_loadable;
22
28
  export { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, lazy, loadableReady };
@@ -11,45 +11,142 @@ function composeEventHandlers(theirHandler, ourHandler) {
11
11
  };
12
12
  }
13
13
  const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
14
- function usePrefetchBehavior(prefetch, theirElementProps) {
15
- const [maybePrefetch, setMaybePrefetch] = react.useState(false);
14
+ const DEFAULT_PREFETCH_BEHAVIOR = 'render';
15
+ const DEFAULT_PRELOAD_BEHAVIOR = 'viewport';
16
+ const INTENT_DELAY = 100;
17
+ const VIEWPORT_ROOT_MARGIN = '200px';
18
+ const MAX_CONCURRENT_WARMUPS = 4;
19
+ const WARMUP_TTL = 30000;
20
+ const SLOW_EFFECTIVE_TYPES = new Set([
21
+ 'slow-2g',
22
+ '2g'
23
+ ]);
24
+ const warmupCache = new Map();
25
+ const warmupQueue = [];
26
+ let activeWarmups = 0;
27
+ const getWarmupTimestamp = ()=>performance.now();
28
+ const getConnection = ()=>{
29
+ const nav = globalThis.navigator;
30
+ return nav?.connection || nav?.mozConnection || nav?.webkitConnection;
31
+ };
32
+ const shouldWarmupOnCurrentNetwork = ()=>{
33
+ const connection = getConnection();
34
+ if (connection?.saveData) return false;
35
+ if ('string' == typeof connection?.effectiveType && SLOW_EFFECTIVE_TYPES.has(connection.effectiveType)) return false;
36
+ return true;
37
+ };
38
+ const pruneWarmupCache = (now = getWarmupTimestamp())=>{
39
+ for (const [key, timestamp] of warmupCache)if (now - timestamp > WARMUP_TTL) warmupCache.delete(key);
40
+ };
41
+ const runNextWarmup = ()=>{
42
+ while(activeWarmups < MAX_CONCURRENT_WARMUPS && warmupQueue.length > 0){
43
+ const task = warmupQueue.shift();
44
+ if (task.cancelled) continue;
45
+ activeWarmups += 1;
46
+ task.run().catch((error)=>{
47
+ console.error(error);
48
+ warmupCache.delete(task.key);
49
+ }).finally(()=>{
50
+ activeWarmups -= 1;
51
+ runNextWarmup();
52
+ });
53
+ }
54
+ };
55
+ const scheduleWarmup = (key, run)=>{
56
+ if (!shouldWarmupOnCurrentNetwork()) return ()=>{};
57
+ pruneWarmupCache();
58
+ if (warmupCache.has(key)) return ()=>{};
59
+ warmupCache.set(key, getWarmupTimestamp());
60
+ const task = {
61
+ key,
62
+ run,
63
+ cancelled: false
64
+ };
65
+ warmupQueue.push(task);
66
+ runNextWarmup();
67
+ return ()=>{
68
+ task.cancelled = true;
69
+ };
70
+ };
71
+ const setRef = (ref, value)=>{
72
+ if (!ref) return;
73
+ if ('function' == typeof ref) return void ref(value);
74
+ try {
75
+ ref.current = value;
76
+ } catch {}
77
+ };
78
+ const isDataWarmupEnabled = (route)=>{
79
+ const handle = route.handle;
80
+ return handle?.navigationWarmup?.data === true;
81
+ };
82
+ function usePrefetchBehavior(prefetch, preload, theirElementProps) {
83
+ const [maybeWarmup, setMaybeWarmup] = react.useState(false);
16
84
  const [shouldPrefetch, setShouldPrefetch] = react.useState(false);
85
+ const [shouldPreload, setShouldPreload] = react.useState(false);
86
+ const [viewportElement, setViewportElement] = react.useState(null);
17
87
  const { onFocus, onBlur, onMouseEnter, onMouseLeave, onTouchStart } = theirElementProps;
18
88
  react.useEffect(()=>{
19
89
  if ('render' === prefetch) setShouldPrefetch(true);
90
+ if ('render' === preload) setShouldPreload(true);
20
91
  }, [
21
- prefetch
92
+ prefetch,
93
+ preload
22
94
  ]);
23
95
  const setIntent = ()=>{
24
- if ('intent' === prefetch) setMaybePrefetch(true);
96
+ if ('intent' === prefetch || 'intent' === preload) setMaybeWarmup(true);
25
97
  };
26
98
  const cancelIntent = ()=>{
27
- if ('intent' === prefetch) {
28
- setMaybePrefetch(false);
99
+ if ('intent' === prefetch || 'intent' === preload) {
100
+ setMaybeWarmup(false);
29
101
  setShouldPrefetch(false);
102
+ setShouldPreload(false);
30
103
  }
31
104
  };
32
105
  react.useEffect(()=>{
33
- if (maybePrefetch) {
106
+ if (maybeWarmup) {
34
107
  const id = setTimeout(()=>{
35
- setShouldPrefetch(true);
36
- }, 100);
108
+ if ('intent' === prefetch) setShouldPrefetch(true);
109
+ if ('intent' === preload) setShouldPreload(true);
110
+ }, INTENT_DELAY);
37
111
  return ()=>{
38
112
  clearTimeout(id);
39
113
  };
40
114
  }
41
115
  }, [
42
- maybePrefetch
116
+ maybeWarmup,
117
+ prefetch,
118
+ preload
119
+ ]);
120
+ react.useEffect(()=>{
121
+ if (!viewportElement || 'viewport' !== prefetch && 'viewport' !== preload || "u" < typeof IntersectionObserver) return;
122
+ const observer = new IntersectionObserver((entries)=>{
123
+ if (!entries.some((entry)=>entry.isIntersecting)) return;
124
+ if ('viewport' === prefetch) setShouldPrefetch(true);
125
+ if ('viewport' === preload) setShouldPreload(true);
126
+ observer.disconnect();
127
+ }, {
128
+ rootMargin: VIEWPORT_ROOT_MARGIN
129
+ });
130
+ observer.observe(viewportElement);
131
+ return ()=>{
132
+ observer.disconnect();
133
+ };
134
+ }, [
135
+ prefetch,
136
+ preload,
137
+ viewportElement
43
138
  ]);
44
139
  return [
45
140
  shouldPrefetch,
141
+ shouldPreload,
46
142
  {
47
143
  onFocus: composeEventHandlers(onFocus, setIntent),
48
144
  onBlur: composeEventHandlers(onBlur, cancelIntent),
49
145
  onMouseEnter: composeEventHandlers(onMouseEnter, setIntent),
50
146
  onMouseLeave: composeEventHandlers(onMouseLeave, cancelIntent),
51
147
  onTouchStart: composeEventHandlers(onTouchStart, setIntent)
52
- }
148
+ },
149
+ setViewportElement
53
150
  ];
54
151
  }
55
152
  async function loadRouteModule(route, routeAssets) {
@@ -84,14 +181,34 @@ const getDataHref = (route, pathname, basename)=>{
84
181
  const url = getRequestUrl(path, id);
85
182
  return createDataHref(url.toString());
86
183
  };
87
- const PrefetchPageLinks = ({ path })=>{
184
+ const PrefetchPageLinks = ({ path, includeData })=>{
88
185
  const { pathname } = path;
89
186
  const context = useContext(InternalRuntimeContext);
90
187
  const { routeManifest, routes } = context;
91
188
  const { routeAssets } = routeManifest || {};
92
- const matches = Array.isArray(routes) ? matchRoutes(routes, pathname) : [];
93
- if (Array.isArray(matches) && routeAssets) matches?.forEach((match)=>loadRouteModule(match.route, routeAssets));
94
- if (!window._SSR_DATA) return null;
189
+ const allowNetworkWarmup = shouldWarmupOnCurrentNetwork();
190
+ const matches = useMemo(()=>Array.isArray(routes) ? matchRoutes(routes, pathname) : [], [
191
+ pathname,
192
+ routes
193
+ ]);
194
+ react.useEffect(()=>{
195
+ if (!allowNetworkWarmup || !Array.isArray(matches) || !routeAssets || !__webpack_chunk_load__) return;
196
+ const cancellations = matches.map((match)=>{
197
+ const routeId = match.route.id;
198
+ const routeAsset = routeId ? routeAssets[routeId] : void 0;
199
+ const chunkIds = routeAsset?.chunkIds;
200
+ if (!routeId || !Array.isArray(chunkIds) || 0 === chunkIds.length) return ()=>{};
201
+ return scheduleWarmup(`route-module:${routeId}:${chunkIds.join(',')}`, ()=>loadRouteModule(match.route, routeAssets));
202
+ });
203
+ return ()=>{
204
+ cancellations.forEach((cancel)=>cancel());
205
+ };
206
+ }, [
207
+ allowNetworkWarmup,
208
+ matches,
209
+ routeAssets
210
+ ]);
211
+ if (!allowNetworkWarmup || !includeData || !window._SSR_DATA) return null;
95
212
  return /*#__PURE__*/ jsx(PrefetchDataLinks, {
96
213
  matches: matches,
97
214
  path: path,
@@ -103,7 +220,7 @@ const PrefetchDataLinks = ({ matches, path, routeManifest })=>{
103
220
  const currentMatches = useMatches();
104
221
  const basename = useHref('/');
105
222
  const dataHrefs = useMemo(()=>matches?.filter((match, index)=>{
106
- if (!match.route.loader || 'function' != typeof match.route.loader || 0 === match.route.loader.length) return false;
223
+ if (!isDataWarmupEnabled(match.route) || !match.route.loader || 'function' != typeof match.route.loader || 0 === match.route.loader.length) return false;
107
224
  if (match.route.shouldRevalidate) {
108
225
  const currentUrl = new URL(location.pathname + location.search + location.hash, window.origin);
109
226
  const nextUrl = new URL(pathname + search + hash, window.origin);
@@ -130,20 +247,35 @@ const PrefetchDataLinks = ({ matches, path, routeManifest })=>{
130
247
  children: dataHrefs
131
248
  });
132
249
  };
133
- const createPrefetchLink = (Link)=>/*#__PURE__*/ react.forwardRef(({ to, prefetch = 'none', ...props }, forwardedRef)=>{
250
+ const normalizePreloadBehavior = (preload, prefetch)=>{
251
+ if (false === preload || 'none' === preload) return 'none';
252
+ if (void 0 !== preload) return preload;
253
+ if ('none' === prefetch) return 'none';
254
+ return DEFAULT_PRELOAD_BEHAVIOR;
255
+ };
256
+ const createPrefetchLink = (Link)=>/*#__PURE__*/ react.forwardRef(({ to, prefetch = DEFAULT_PREFETCH_BEHAVIOR, preload, ...props }, forwardedRef)=>{
134
257
  const isAbsolute = 'string' == typeof to && ABSOLUTE_URL_REGEX.test(to);
135
- const [shouldPrefetch, prefetchHandlers] = usePrefetchBehavior(prefetch, props);
258
+ const resolvedPreload = normalizePreloadBehavior(preload, prefetch);
259
+ const [shouldPrefetch, shouldPreload, prefetchHandlers, setViewportElement] = usePrefetchBehavior(prefetch, resolvedPreload, props);
260
+ const setAnchorRef = react.useCallback((element)=>{
261
+ setViewportElement(element);
262
+ setRef(forwardedRef, element);
263
+ }, [
264
+ forwardedRef,
265
+ setViewportElement
266
+ ]);
136
267
  const resolvedPath = useResolvedPath(to);
137
268
  return /*#__PURE__*/ jsxs(Fragment, {
138
269
  children: [
139
270
  /*#__PURE__*/ jsx(Link, {
140
- ref: forwardedRef,
271
+ ref: setAnchorRef,
141
272
  to: to,
142
273
  ...props,
143
274
  ...prefetchHandlers
144
275
  }),
145
- shouldPrefetch && __webpack_chunk_load__ && !isAbsolute ? /*#__PURE__*/ jsx(PrefetchPageLinks, {
146
- path: resolvedPath
276
+ (shouldPrefetch || shouldPreload) && !isAbsolute ? /*#__PURE__*/ jsx(PrefetchPageLinks, {
277
+ path: resolvedPath,
278
+ includeData: shouldPrefetch
147
279
  }) : null
148
280
  ]
149
281
  });
@@ -6,7 +6,7 @@ const outlet_Outlet = /*#__PURE__*/ memo(function() {
6
6
  return /*#__PURE__*/ jsx(Outlet, {});
7
7
  });
8
8
  function withModernRouteMatchContext(component, _routeId) {
9
- if (!component) return component;
9
+ if (null == component) return component;
10
10
  const Component = component;
11
11
  const WrappedRouteComponent = (props)=>/*#__PURE__*/ createElement(Component, props);
12
12
  const preloadable = component;