@bleedingdev/modern-js-runtime 3.2.0-ultramodern.120 → 3.2.0-ultramodern.122

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 (203) hide show
  1. package/dist/cjs/boundary-debugger/index.js +4 -0
  2. package/dist/cjs/cli/index.js +11 -0
  3. package/dist/cjs/{router/runtime/tanstack/rsc/ClientSlot.js → core/context/extensions.js} +33 -21
  4. package/dist/cjs/{router/runtime/tanstack/rsc/SlotContext.js → core/context/helmetContext.js} +16 -20
  5. package/dist/cjs/core/context/index.js +65 -0
  6. package/dist/cjs/core/react/wrapper.js +6 -4
  7. package/dist/cjs/core/server/helmet.js +2 -1
  8. package/dist/cjs/core/server/requestHandler.js +42 -29
  9. package/dist/cjs/core/server/routerCleanup.js +110 -0
  10. package/dist/cjs/core/server/scriptOrder.js +75 -4
  11. package/dist/cjs/core/server/stream/afterTemplate.js +6 -18
  12. package/dist/cjs/core/server/stream/deferredScript.js +4 -1
  13. package/dist/cjs/core/server/string/index.js +1 -7
  14. package/dist/cjs/core/server/string/loadable.js +13 -40
  15. package/dist/cjs/core/server/string/ssrData.js +1 -1
  16. package/dist/cjs/core/server/utils.js +31 -8
  17. package/dist/cjs/exports/head.js +135 -74
  18. package/dist/cjs/exports/tanstack-router.js +36 -305
  19. package/dist/cjs/module-federation/index.js +178 -0
  20. package/dist/cjs/router/cli/code/index.js +1 -47
  21. package/dist/cjs/router/cli/code/templates.js +1 -14
  22. package/dist/cjs/router/cli/handler.js +1 -1
  23. package/dist/cjs/router/cli/index.js +2 -23
  24. package/dist/cjs/router/runtime/DeferredDataScripts.node.js +16 -4
  25. package/dist/cjs/router/runtime/PrefetchLink.js +2 -3
  26. package/dist/cjs/router/runtime/internal.js +20 -13
  27. package/dist/cjs/router/runtime/lifecycle.js +37 -22
  28. package/dist/cjs/router/runtime/plugin.js +2 -9
  29. package/dist/cjs/router/runtime/plugin.node.js +2 -7
  30. package/dist/cjs/router/runtime/provider.js +107 -0
  31. package/dist/cjs/router/runtime/utils.js +35 -9
  32. package/dist/esm/boundary-debugger/index.mjs +4 -0
  33. package/dist/esm/cli/index.mjs +4 -2
  34. package/dist/esm/core/context/extensions.mjs +28 -0
  35. package/dist/esm/core/context/helmetContext.mjs +13 -0
  36. package/dist/esm/core/context/index.mjs +5 -0
  37. package/dist/esm/core/react/wrapper.mjs +6 -4
  38. package/dist/esm/core/server/helmet.mjs +2 -1
  39. package/dist/esm/core/server/requestHandler.mjs +43 -30
  40. package/dist/esm/core/server/routerCleanup.mjs +66 -0
  41. package/dist/esm/core/server/scriptOrder.mjs +60 -1
  42. package/dist/esm/core/server/stream/afterTemplate.mjs +8 -20
  43. package/dist/esm/core/server/stream/deferredScript.mjs +4 -1
  44. package/dist/esm/core/server/string/index.mjs +3 -9
  45. package/dist/esm/core/server/string/loadable.mjs +11 -38
  46. package/dist/esm/core/server/string/ssrData.mjs +2 -2
  47. package/dist/esm/core/server/utils.mjs +31 -8
  48. package/dist/esm/exports/head.mjs +135 -74
  49. package/dist/esm/exports/tanstack-router.mjs +30 -4
  50. package/dist/esm/module-federation/index.mjs +109 -0
  51. package/dist/esm/router/cli/code/index.mjs +1 -47
  52. package/dist/esm/router/cli/code/templates.mjs +1 -14
  53. package/dist/esm/router/cli/handler.mjs +1 -1
  54. package/dist/esm/router/cli/index.mjs +3 -24
  55. package/dist/esm/router/runtime/DeferredDataScripts.node.mjs +16 -4
  56. package/dist/esm/router/runtime/PrefetchLink.mjs +2 -3
  57. package/dist/esm/router/runtime/internal.mjs +16 -15
  58. package/dist/esm/router/runtime/lifecycle.mjs +22 -13
  59. package/dist/esm/router/runtime/plugin.mjs +4 -11
  60. package/dist/esm/router/runtime/plugin.node.mjs +4 -9
  61. package/dist/esm/router/runtime/provider.mjs +57 -0
  62. package/dist/esm/router/runtime/utils.mjs +35 -9
  63. package/dist/esm-node/boundary-debugger/index.mjs +4 -0
  64. package/dist/esm-node/cli/index.mjs +4 -2
  65. package/dist/esm-node/core/context/extensions.mjs +29 -0
  66. package/dist/esm-node/core/context/helmetContext.mjs +14 -0
  67. package/dist/esm-node/core/context/index.mjs +5 -0
  68. package/dist/esm-node/core/react/wrapper.mjs +6 -4
  69. package/dist/esm-node/core/server/helmet.mjs +2 -1
  70. package/dist/esm-node/core/server/requestHandler.mjs +43 -30
  71. package/dist/esm-node/core/server/routerCleanup.mjs +67 -0
  72. package/dist/esm-node/core/server/scriptOrder.mjs +60 -1
  73. package/dist/esm-node/core/server/stream/afterTemplate.mjs +8 -20
  74. package/dist/esm-node/core/server/stream/deferredScript.mjs +4 -1
  75. package/dist/esm-node/core/server/string/index.mjs +3 -9
  76. package/dist/esm-node/core/server/string/loadable.mjs +11 -38
  77. package/dist/esm-node/core/server/string/ssrData.mjs +2 -2
  78. package/dist/esm-node/core/server/utils.mjs +31 -8
  79. package/dist/esm-node/exports/head.mjs +135 -74
  80. package/dist/esm-node/exports/tanstack-router.mjs +30 -4
  81. package/dist/esm-node/module-federation/index.mjs +110 -0
  82. package/dist/esm-node/router/cli/code/index.mjs +1 -47
  83. package/dist/esm-node/router/cli/code/templates.mjs +1 -14
  84. package/dist/esm-node/router/cli/handler.mjs +1 -1
  85. package/dist/esm-node/router/cli/index.mjs +3 -24
  86. package/dist/esm-node/router/runtime/DeferredDataScripts.node.mjs +16 -4
  87. package/dist/esm-node/router/runtime/PrefetchLink.mjs +2 -3
  88. package/dist/esm-node/router/runtime/internal.mjs +16 -15
  89. package/dist/esm-node/router/runtime/lifecycle.mjs +22 -13
  90. package/dist/esm-node/router/runtime/plugin.mjs +4 -11
  91. package/dist/esm-node/router/runtime/plugin.node.mjs +4 -9
  92. package/dist/esm-node/router/runtime/provider.mjs +58 -0
  93. package/dist/esm-node/router/runtime/utils.mjs +35 -9
  94. package/dist/types/cli/index.d.ts +3 -1
  95. package/dist/types/core/context/extensions.d.ts +37 -0
  96. package/dist/types/core/context/helmetContext.d.ts +10 -0
  97. package/dist/types/core/context/index.d.ts +6 -0
  98. package/dist/types/core/context/runtime.d.ts +1 -11
  99. package/dist/types/core/server/routerCleanup.d.ts +28 -0
  100. package/dist/types/core/server/scriptOrder.d.ts +24 -0
  101. package/dist/types/core/server/string/loadable.d.ts +1 -7
  102. package/dist/types/core/server/utils.d.ts +1 -0
  103. package/dist/types/exports/tanstack-router.d.ts +88 -7
  104. package/dist/types/module-federation/index.d.ts +65 -0
  105. package/dist/types/router/cli/code/index.d.ts +1 -3
  106. package/dist/types/router/cli/handler.d.ts +0 -3
  107. package/dist/types/router/runtime/internal.d.ts +1 -0
  108. package/dist/types/router/runtime/lifecycle.d.ts +2 -0
  109. package/dist/types/router/runtime/plugin.d.ts +1 -1
  110. package/dist/types/router/runtime/plugin.node.d.ts +1 -1
  111. package/dist/types/router/runtime/provider.d.ts +61 -0
  112. package/package.json +16 -12
  113. package/rstest.config.mts +2 -4
  114. package/dist/cjs/router/cli/code/tanstackTypes.js +0 -447
  115. package/dist/cjs/router/runtime/tanstack/basepathRewrite.js +0 -66
  116. package/dist/cjs/router/runtime/tanstack/dataMutation.js +0 -349
  117. package/dist/cjs/router/runtime/tanstack/hydrationBoundary.js +0 -48
  118. package/dist/cjs/router/runtime/tanstack/outlet.js +0 -58
  119. package/dist/cjs/router/runtime/tanstack/plugin.js +0 -342
  120. package/dist/cjs/router/runtime/tanstack/plugin.node.js +0 -272
  121. package/dist/cjs/router/runtime/tanstack/prefetchLink.js +0 -59
  122. package/dist/cjs/router/runtime/tanstack/routeTree.js +0 -525
  123. package/dist/cjs/router/runtime/tanstack/rsc/CompositeComponent.js +0 -79
  124. package/dist/cjs/router/runtime/tanstack/rsc/ReplayableStream.js +0 -146
  125. package/dist/cjs/router/runtime/tanstack/rsc/RscNodeRenderer.js +0 -69
  126. package/dist/cjs/router/runtime/tanstack/rsc/client.js +0 -97
  127. package/dist/cjs/router/runtime/tanstack/rsc/createRscProxy.js +0 -145
  128. package/dist/cjs/router/runtime/tanstack/rsc/index.js +0 -46
  129. package/dist/cjs/router/runtime/tanstack/rsc/server.js +0 -250
  130. package/dist/cjs/router/runtime/tanstack/rsc/slotUsageSanitizer.js +0 -69
  131. package/dist/cjs/router/runtime/tanstack/rsc/symbols.js +0 -77
  132. package/dist/cjs/ssr/index.node.js +0 -125
  133. package/dist/cjs/ssr/serverRender/renderToStream/buildTemplate.after.js +0 -88
  134. package/dist/cjs/ssr/serverRender/renderToString/entry.js +0 -200
  135. package/dist/cjs/ssr/serverRender/types.js +0 -40
  136. package/dist/esm/router/cli/code/tanstackTypes.mjs +0 -396
  137. package/dist/esm/router/runtime/tanstack/basepathRewrite.mjs +0 -28
  138. package/dist/esm/router/runtime/tanstack/dataMutation.mjs +0 -305
  139. package/dist/esm/router/runtime/tanstack/hydrationBoundary.mjs +0 -10
  140. package/dist/esm/router/runtime/tanstack/outlet.mjs +0 -17
  141. package/dist/esm/router/runtime/tanstack/plugin.mjs +0 -304
  142. package/dist/esm/router/runtime/tanstack/plugin.node.mjs +0 -234
  143. package/dist/esm/router/runtime/tanstack/prefetchLink.mjs +0 -18
  144. package/dist/esm/router/runtime/tanstack/routeTree.mjs +0 -481
  145. package/dist/esm/router/runtime/tanstack/rsc/ClientSlot.mjs +0 -19
  146. package/dist/esm/router/runtime/tanstack/rsc/CompositeComponent.mjs +0 -41
  147. package/dist/esm/router/runtime/tanstack/rsc/ReplayableStream.mjs +0 -104
  148. package/dist/esm/router/runtime/tanstack/rsc/RscNodeRenderer.mjs +0 -31
  149. package/dist/esm/router/runtime/tanstack/rsc/SlotContext.mjs +0 -17
  150. package/dist/esm/router/runtime/tanstack/rsc/client.mjs +0 -53
  151. package/dist/esm/router/runtime/tanstack/rsc/createRscProxy.mjs +0 -107
  152. package/dist/esm/router/runtime/tanstack/rsc/index.mjs +0 -1
  153. package/dist/esm/router/runtime/tanstack/rsc/server.mjs +0 -200
  154. package/dist/esm/router/runtime/tanstack/rsc/slotUsageSanitizer.mjs +0 -31
  155. package/dist/esm/router/runtime/tanstack/rsc/symbols.mjs +0 -17
  156. package/dist/esm/ssr/index.node.mjs +0 -44
  157. package/dist/esm/ssr/serverRender/renderToStream/buildTemplate.after.mjs +0 -50
  158. package/dist/esm/ssr/serverRender/renderToString/entry.mjs +0 -151
  159. package/dist/esm/ssr/serverRender/types.mjs +0 -1
  160. package/dist/esm-node/router/cli/code/tanstackTypes.mjs +0 -397
  161. package/dist/esm-node/router/runtime/tanstack/basepathRewrite.mjs +0 -29
  162. package/dist/esm-node/router/runtime/tanstack/dataMutation.mjs +0 -306
  163. package/dist/esm-node/router/runtime/tanstack/hydrationBoundary.mjs +0 -11
  164. package/dist/esm-node/router/runtime/tanstack/outlet.mjs +0 -18
  165. package/dist/esm-node/router/runtime/tanstack/plugin.mjs +0 -305
  166. package/dist/esm-node/router/runtime/tanstack/plugin.node.mjs +0 -235
  167. package/dist/esm-node/router/runtime/tanstack/prefetchLink.mjs +0 -19
  168. package/dist/esm-node/router/runtime/tanstack/routeTree.mjs +0 -482
  169. package/dist/esm-node/router/runtime/tanstack/rsc/ClientSlot.mjs +0 -20
  170. package/dist/esm-node/router/runtime/tanstack/rsc/CompositeComponent.mjs +0 -42
  171. package/dist/esm-node/router/runtime/tanstack/rsc/ReplayableStream.mjs +0 -105
  172. package/dist/esm-node/router/runtime/tanstack/rsc/RscNodeRenderer.mjs +0 -32
  173. package/dist/esm-node/router/runtime/tanstack/rsc/SlotContext.mjs +0 -18
  174. package/dist/esm-node/router/runtime/tanstack/rsc/client.mjs +0 -54
  175. package/dist/esm-node/router/runtime/tanstack/rsc/createRscProxy.mjs +0 -108
  176. package/dist/esm-node/router/runtime/tanstack/rsc/index.mjs +0 -2
  177. package/dist/esm-node/router/runtime/tanstack/rsc/server.mjs +0 -201
  178. package/dist/esm-node/router/runtime/tanstack/rsc/slotUsageSanitizer.mjs +0 -32
  179. package/dist/esm-node/router/runtime/tanstack/rsc/symbols.mjs +0 -18
  180. package/dist/esm-node/ssr/index.node.mjs +0 -45
  181. package/dist/esm-node/ssr/serverRender/renderToStream/buildTemplate.after.mjs +0 -51
  182. package/dist/esm-node/ssr/serverRender/renderToString/entry.mjs +0 -152
  183. package/dist/esm-node/ssr/serverRender/types.mjs +0 -2
  184. package/dist/types/router/cli/code/tanstackTypes.d.ts +0 -10
  185. package/dist/types/router/runtime/tanstack/basepathRewrite.d.ts +0 -8
  186. package/dist/types/router/runtime/tanstack/dataMutation.d.ts +0 -29
  187. package/dist/types/router/runtime/tanstack/hydrationBoundary.d.ts +0 -2
  188. package/dist/types/router/runtime/tanstack/outlet.d.ts +0 -2
  189. package/dist/types/router/runtime/tanstack/plugin.d.ts +0 -6
  190. package/dist/types/router/runtime/tanstack/plugin.node.d.ts +0 -6
  191. package/dist/types/router/runtime/tanstack/prefetchLink.d.ts +0 -11
  192. package/dist/types/router/runtime/tanstack/routeTree.d.ts +0 -8
  193. package/dist/types/router/runtime/tanstack/rsc/ClientSlot.d.ts +0 -5
  194. package/dist/types/router/runtime/tanstack/rsc/CompositeComponent.d.ts +0 -3
  195. package/dist/types/router/runtime/tanstack/rsc/ReplayableStream.d.ts +0 -24
  196. package/dist/types/router/runtime/tanstack/rsc/RscNodeRenderer.d.ts +0 -5
  197. package/dist/types/router/runtime/tanstack/rsc/SlotContext.d.ts +0 -11
  198. package/dist/types/router/runtime/tanstack/rsc/client.d.ts +0 -11
  199. package/dist/types/router/runtime/tanstack/rsc/createRscProxy.d.ts +0 -7
  200. package/dist/types/router/runtime/tanstack/rsc/index.d.ts +0 -2
  201. package/dist/types/router/runtime/tanstack/rsc/server.d.ts +0 -14
  202. package/dist/types/router/runtime/tanstack/rsc/slotUsageSanitizer.d.ts +0 -2
  203. package/dist/types/router/runtime/tanstack/rsc/symbols.d.ts +0 -46
@@ -2,6 +2,7 @@
2
2
  import react from "react";
3
3
  import { Helmet, HelmetData, HelmetProvider } from "react-helmet-async";
4
4
  import { InternalRuntimeContext } from "../core/context/index.mjs";
5
+ import { ensureHelmetContext } from "../core/context/helmetContext.mjs";
5
6
  const ATTRIBUTE_NAME_MAP = {
6
7
  charSet: 'charset',
7
8
  className: 'class',
@@ -11,6 +12,10 @@ const ATTRIBUTE_NAME_MAP = {
11
12
  itemProp: 'itemprop',
12
13
  tabIndex: 'tabindex'
13
14
  };
15
+ const CONTENT_PROPERTIES = new Set([
16
+ 'innerHTML',
17
+ 'cssText'
18
+ ]);
14
19
  const escapeHtml = (value)=>String(value).replaceAll('&', '&amp;').replaceAll('"', '&quot;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
15
20
  const toHtmlAttributeName = (name)=>ATTRIBUTE_NAME_MAP[name] ?? name;
16
21
  const attributesToString = (attributes, includeHelmetAttribute = false)=>{
@@ -18,6 +23,7 @@ const attributesToString = (attributes, includeHelmetAttribute = false)=>{
18
23
  if (includeHelmetAttribute) pairs.push('data-rh="true"');
19
24
  for (const [name, value] of Object.entries(attributes ?? {})){
20
25
  if (false === value || null == value) continue;
26
+ if (CONTENT_PROPERTIES.has(name)) continue;
21
27
  const htmlName = toHtmlAttributeName(name);
22
28
  if (true === value) pairs.push(htmlName);
23
29
  else pairs.push(`${htmlName}="${escapeHtml(value)}"`);
@@ -46,18 +52,6 @@ const createTitleDatum = (title, attributes)=>({
46
52
  return `<title ${attrs}>${escapeHtml(title)}</title>`;
47
53
  }
48
54
  });
49
- const createEmptyHelmetState = ()=>({
50
- base: createDatum('base', []),
51
- bodyAttributes: createAttributeDatum({}),
52
- htmlAttributes: createAttributeDatum({}),
53
- link: createDatum('link', []),
54
- meta: createDatum('meta', []),
55
- noscript: createDatum("noscript", []),
56
- priority: createDatum('meta', []),
57
- script: createDatum("script", []),
58
- style: createDatum('style', []),
59
- title: createTitleDatum(void 0, {})
60
- });
61
55
  const normalizeHelmetTitle = (title)=>{
62
56
  if ('string' == typeof title) return title;
63
57
  if (Array.isArray(title)) return title.map((part)=>String(part)).join('');
@@ -77,7 +71,14 @@ const collectChildren = (children, draft)=>{
77
71
  draft.titleAttributes = mergeAttributes(draft.titleAttributes, props);
78
72
  return;
79
73
  }
80
- if ('html' === child.type || 'body' === child.type) return;
74
+ if ('html' === child.type) {
75
+ draft.htmlAttributes = mergeAttributes(draft.htmlAttributes ?? {}, props);
76
+ return;
77
+ }
78
+ if ('body' === child.type) {
79
+ draft.bodyAttributes = mergeAttributes(draft.bodyAttributes ?? {}, props);
80
+ return;
81
+ }
81
82
  if ('base' === child.type || 'link' === child.type || 'meta' === child.type || "noscript" === child.type || "script" === child.type || 'style' === child.type) {
82
83
  const tag = {
83
84
  ...props
@@ -87,8 +88,7 @@ const collectChildren = (children, draft)=>{
87
88
  }
88
89
  });
89
90
  };
90
- const collectHelmetProps = (current, props)=>{
91
- const baseState = current ?? createEmptyHelmetState();
91
+ const createHelmetRecord = (props)=>{
92
92
  const draft = {
93
93
  base: [
94
94
  ...void 0 !== props.base ? [
@@ -116,71 +116,132 @@ const collectHelmetProps = (current, props)=>{
116
116
  titleAttributes: props.titleAttributes ?? {}
117
117
  };
118
118
  collectChildren(props.children, draft);
119
- const title = void 0 !== draft.title && '' !== draft.title && void 0 !== props.titleTemplate ? props.titleTemplate.replaceAll('%s', draft.title) : draft.title ?? props.defaultTitle;
120
119
  return {
121
- base: createDatum('base', [
122
- ...baseState.__baseTags ?? [],
123
- ...draft.base
124
- ]),
125
- bodyAttributes: createAttributeDatum(mergeAttributes(baseState.__bodyAttributes ?? {}, draft.bodyAttributes)),
126
- htmlAttributes: createAttributeDatum(mergeAttributes(baseState.__htmlAttributes ?? {}, draft.htmlAttributes)),
127
- link: createDatum('link', [
128
- ...baseState.__linkTags ?? [],
129
- ...draft.link
130
- ]),
131
- meta: createDatum('meta', [
132
- ...baseState.__metaTags ?? [],
133
- ...draft.meta
134
- ]),
135
- noscript: createDatum("noscript", [
136
- ...baseState.__noscriptTags ?? [],
137
- ...draft.noscript
138
- ]),
139
- priority: createDatum('meta', []),
140
- script: createDatum("script", [
141
- ...baseState.__scriptTags ?? [],
142
- ...draft.script
143
- ]),
144
- style: createDatum('style', [
145
- ...baseState.__styleTags ?? [],
146
- ...draft.style
147
- ]),
148
- title: createTitleDatum(title ?? baseState.__title, mergeAttributes(baseState.__titleAttributes ?? {}, draft.titleAttributes)),
149
- __baseTags: [
150
- ...baseState.__baseTags ?? [],
151
- ...draft.base
152
- ],
153
- __bodyAttributes: mergeAttributes(baseState.__bodyAttributes ?? {}, draft.bodyAttributes),
154
- __htmlAttributes: mergeAttributes(baseState.__htmlAttributes ?? {}, draft.htmlAttributes),
155
- __linkTags: [
156
- ...baseState.__linkTags ?? [],
157
- ...draft.link
158
- ],
159
- __metaTags: [
160
- ...baseState.__metaTags ?? [],
161
- ...draft.meta
162
- ],
163
- __noscriptTags: [
164
- ...baseState.__noscriptTags ?? [],
165
- ...draft.noscript
166
- ],
167
- __scriptTags: [
168
- ...baseState.__scriptTags ?? [],
169
- ...draft.script
170
- ],
171
- __styleTags: [
172
- ...baseState.__styleTags ?? [],
173
- ...draft.style
174
- ],
175
- __title: title ?? baseState.__title,
176
- __titleAttributes: mergeAttributes(baseState.__titleAttributes ?? {}, draft.titleAttributes)
120
+ ...draft,
121
+ titleTemplate: props.titleTemplate,
122
+ defaultTitle: props.defaultTitle
123
+ };
124
+ };
125
+ const getInnermostDefined = (records, pick)=>{
126
+ for(let i = records.length - 1; i >= 0; i -= 1){
127
+ const value = pick(records[i]);
128
+ if (void 0 !== value) return value;
129
+ }
130
+ };
131
+ const deriveTitle = (records)=>{
132
+ const innermostTitle = getInnermostDefined(records, (record)=>record.title);
133
+ const innermostTemplate = getInnermostDefined(records, (record)=>record.titleTemplate);
134
+ if (innermostTemplate && innermostTitle) return innermostTemplate.replaceAll('%s', innermostTitle);
135
+ return innermostTitle || getInnermostDefined(records, (record)=>record.defaultTitle);
136
+ };
137
+ const mergeRecordAttributes = (records, pick)=>records.reduce((merged, record)=>mergeAttributes(merged, pick(record)), {});
138
+ const deriveBaseTags = (records)=>{
139
+ for(let i = records.length - 1; i >= 0; i -= 1){
140
+ const tags = records[i].base;
141
+ for(let j = tags.length - 1; j >= 0; j -= 1)if (tags[j].href) return [
142
+ tags[j]
143
+ ];
144
+ }
145
+ return [];
146
+ };
147
+ const TAG_PRIMARY_ATTRIBUTES = {
148
+ link: [
149
+ 'rel',
150
+ 'href'
151
+ ],
152
+ meta: [
153
+ 'name',
154
+ 'charset',
155
+ 'http-equiv',
156
+ 'property',
157
+ 'itemprop'
158
+ ],
159
+ noscript: [
160
+ 'innerHTML'
161
+ ],
162
+ script: [
163
+ 'src',
164
+ 'innerHTML'
165
+ ],
166
+ style: [
167
+ 'cssText'
168
+ ]
169
+ };
170
+ const getPrimaryAttribute = (tagName, tag)=>{
171
+ const candidates = TAG_PRIMARY_ATTRIBUTES[tagName];
172
+ let selectedKey;
173
+ let selectedValue;
174
+ for (const [key, value] of Object.entries(tag)){
175
+ const normalizedKey = CONTENT_PROPERTIES.has(key) ? key : toHtmlAttributeName(key).toLowerCase();
176
+ if (candidates.includes(normalizedKey)) {
177
+ if ('rel' !== selectedKey || 'canonical' !== String(selectedValue).toLowerCase()) {
178
+ if ('rel' !== normalizedKey || 'stylesheet' !== String(value).toLowerCase()) {
179
+ selectedKey = normalizedKey;
180
+ selectedValue = value;
181
+ }
182
+ }
183
+ }
184
+ }
185
+ if (void 0 === selectedKey || !selectedValue) return;
186
+ return {
187
+ key: selectedKey,
188
+ value: String(selectedValue).toLowerCase()
177
189
  };
178
190
  };
191
+ const dedupeTags = (tagName, records)=>{
192
+ const approvedValues = new Map();
193
+ const approved = [];
194
+ for(let i = records.length - 1; i >= 0; i -= 1){
195
+ const instanceValues = new Map();
196
+ const kept = [];
197
+ for (const tag of records[i][tagName]){
198
+ const primary = getPrimaryAttribute(tagName, tag);
199
+ if (void 0 === primary) continue;
200
+ if (approvedValues.get(primary.key)?.has(primary.value)) continue;
201
+ let seen = instanceValues.get(primary.key);
202
+ if (void 0 === seen) {
203
+ seen = new Set();
204
+ instanceValues.set(primary.key, seen);
205
+ }
206
+ seen.add(primary.value);
207
+ kept.push(tag);
208
+ }
209
+ approved.unshift(...kept);
210
+ for (const [key, values] of instanceValues){
211
+ const target = approvedValues.get(key);
212
+ if (void 0 === target) approvedValues.set(key, values);
213
+ else for (const value of values)target.add(value);
214
+ }
215
+ }
216
+ return approved;
217
+ };
218
+ const deriveHelmetServerState = (records)=>({
219
+ base: createDatum('base', deriveBaseTags(records)),
220
+ bodyAttributes: createAttributeDatum(mergeRecordAttributes(records, (record)=>record.bodyAttributes)),
221
+ htmlAttributes: createAttributeDatum(mergeRecordAttributes(records, (record)=>record.htmlAttributes)),
222
+ link: createDatum('link', dedupeTags('link', records)),
223
+ meta: createDatum('meta', dedupeTags('meta', records)),
224
+ noscript: createDatum("noscript", dedupeTags("noscript", records)),
225
+ priority: createDatum('meta', []),
226
+ script: createDatum("script", dedupeTags("script", records)),
227
+ style: createDatum('style', dedupeTags('style', records)),
228
+ title: createTitleDatum(deriveTitle(records), mergeRecordAttributes(records, (record)=>record.titleAttributes))
229
+ });
230
+ const serverHelmetRecords = new WeakMap();
231
+ const collectServerHelmet = (runtimeContext, props)=>{
232
+ const helmetContext = ensureHelmetContext(runtimeContext);
233
+ let records = serverHelmetRecords.get(helmetContext);
234
+ if (void 0 === records) {
235
+ records = [];
236
+ serverHelmetRecords.set(helmetContext, records);
237
+ }
238
+ records.push(createHelmetRecord(props));
239
+ helmetContext.helmet = deriveHelmetServerState(records);
240
+ };
179
241
  const head_Helmet = (props)=>{
180
242
  const runtimeContext = react.useContext(InternalRuntimeContext);
181
243
  if (null !== runtimeContext && false === runtimeContext.isBrowser) {
182
- runtimeContext._helmetContext ??= {};
183
- runtimeContext._helmetContext.helmet = collectHelmetProps(runtimeContext._helmetContext.helmet ?? void 0, props);
244
+ collectServerHelmet(runtimeContext, props);
184
245
  return null;
185
246
  }
186
247
  return react.createElement(Helmet, props);
@@ -1,4 +1,30 @@
1
- export { Asset, Await, Block, CatchBoundary, CatchNotFound, ClientOnly, DEFAULT_PROTOCOL_ALLOWLIST, DefaultGlobalNotFound, ErrorComponent, FileRoute, FileRouteLoader, HeadContent, LazyRoute, Match, MatchRoute, Matches, Navigate, NotFoundRoute, RootRoute, Route, RouteApi, Router, RouterContextProvider, RouterProvider, ScriptOnce, Scripts, ScrollRestoration, SearchParamError, cleanPath, composeRewrites, createBrowserHistory, createControlledPromise, createFileRoute, createHashHistory, createHistory, createLazyFileRoute, createLazyRoute, createLink, createMemoryHistory, createRootRoute, createRootRouteWithContext, createRoute, createRouteMask, createRouter, createRouterConfig, createSerializationAdapter, deepEqual, defaultParseSearch, defaultStringifySearch, defer, functionalUpdate, getRouteApi, interpolatePath, isMatch, isNotFound, isPlainArray, isPlainObject, isRedirect, joinPaths, lazyFn, lazyRouteComponent, linkOptions, notFound, parseSearchWith, reactUse, redirect, replaceEqualDeep, resolvePath, retainSearchParams, rootRouteId, rootRouteWithContext, stringifySearchWith, stripSearchParams, trimPath, trimPathLeft, trimPathRight, useAwaited, useBlocker, useCanGoBack, useChildMatches, useElementScrollRestoration, useHydrated, useLayoutEffect, useLinkProps, useLoaderData, useLoaderDeps, useLocation, useMatch, useMatchRoute, useMatches, useNavigate, useParams, useParentMatches, useRouteContext, useRouter, useRouterState, useSearch, useTags } from "@tanstack/react-router";
2
- export { Form, RouteActionResponseError, useFetcher } from "../router/runtime/tanstack/dataMutation.mjs";
3
- export { Outlet } from "../router/runtime/tanstack/outlet.mjs";
4
- export { Link, NavLink } from "../router/runtime/tanstack/prefetchLink.mjs";
1
+ import { createElement } from "react";
2
+ const COMPAT_BINDINGS_SLOT = Symbol.for('@modern-js/plugin-tanstack:runtime-compat-bindings');
3
+ function readCompatBindings() {
4
+ return globalThis[COMPAT_BINDINGS_SLOT];
5
+ }
6
+ function resolveCompatBindings(exportName) {
7
+ const bindings = readCompatBindings();
8
+ if (void 0 === bindings) throw new Error(`[@modern-js/runtime] '${exportName}' from the deprecated '@modern-js/runtime/tanstack-router' alias is provided by @modern-js/plugin-tanstack. Install @modern-js/plugin-tanstack, add \`tanstackRouterPlugin()\` to the \`plugins\` array in modern.config.ts, and make sure '@modern-js/plugin-tanstack/runtime' is imported (e.g. in modern.runtime.ts) before '${exportName}' is used. Prefer importing '${exportName}' from '@modern-js/plugin-tanstack/runtime' directly.`);
9
+ return bindings;
10
+ }
11
+ const Link = (props)=>createElement(resolveCompatBindings('Link').Link, props);
12
+ const NavLink = (props)=>createElement(resolveCompatBindings('NavLink').NavLink, props);
13
+ const Outlet = ()=>createElement(resolveCompatBindings('Outlet').Outlet);
14
+ const Form = (props)=>createElement(resolveCompatBindings('Form').Form, props);
15
+ function useFetcher() {
16
+ return resolveCompatBindings('useFetcher').useFetcher();
17
+ }
18
+ function RouteActionResponseErrorPlaceholder() {}
19
+ const RouteActionResponseError = new Proxy(RouteActionResponseErrorPlaceholder, {
20
+ construct (_target, args) {
21
+ const RealError = resolveCompatBindings('RouteActionResponseError').RouteActionResponseError;
22
+ return new RealError(...args);
23
+ },
24
+ get (target, property, receiver) {
25
+ const RealError = readCompatBindings()?.RouteActionResponseError;
26
+ if (void 0 !== RealError) return Reflect.get(RealError, property);
27
+ return Reflect.get(target, property, receiver);
28
+ }
29
+ });
30
+ export { Form, Link, NavLink, Outlet, RouteActionResponseError, useFetcher };
@@ -0,0 +1,109 @@
1
+ const MODULE_FEDERATION_FALLBACK_SIGNAL_EVENT = 'modernjs:mf-runtime-fallback';
2
+ const MODULE_FEDERATION_RECOVERY_SIGNAL_EVENT = 'modernjs:mf-runtime-recovery';
3
+ const DEFAULT_RUNTIME_FALLBACK_SIGNAL_ENDPOINT = '/_modern/contract-gates/runtime-fallback';
4
+ const DEFAULT_RUNTIME_FALLBACK_SIGNAL_AUTH_HEADER = 'x-modernjs-runtime-signal-token';
5
+ class ModuleFederationRemoteLoadTimeoutError extends Error {
6
+ constructor(remote, timeoutMs){
7
+ super(`Loading remote "${remote}" timed out after ${timeoutMs}ms`);
8
+ this.name = 'ModuleFederationRemoteLoadTimeoutError';
9
+ }
10
+ }
11
+ class ModuleFederationRemoteLoadError extends Error {
12
+ constructor(remote, attempts, causeError){
13
+ super(`Unable to load remote "${remote}" after ${attempts} attempt${attempts > 1 ? 's' : ''}: ${causeError.message}`);
14
+ this.name = 'ModuleFederationRemoteLoadError';
15
+ this.remote = remote;
16
+ this.attempts = attempts;
17
+ this.causeError = causeError;
18
+ }
19
+ }
20
+ class ModuleFederationRemoteComponentContractError extends Error {
21
+ constructor(remote, exportName){
22
+ super(`Remote "${remote}" export "${exportName}" is not a valid React component`);
23
+ this.name = 'ModuleFederationRemoteComponentContractError';
24
+ }
25
+ }
26
+ function toError(error) {
27
+ if (error instanceof Error) return error;
28
+ return new Error('string' == typeof error ? error : 'Unknown remote load error');
29
+ }
30
+ function classifyModuleFederationFallback(error) {
31
+ const normalizedError = toError(error);
32
+ if (normalizedError instanceof ModuleFederationRemoteLoadError) return classifyModuleFederationFallback(normalizedError.causeError);
33
+ if (normalizedError instanceof ModuleFederationRemoteLoadTimeoutError) return 'timeout';
34
+ if (normalizedError instanceof ModuleFederationRemoteComponentContractError) return 'contract';
35
+ const message = normalizedError.message;
36
+ if (/version|requiredVersion|singleton|share scope|shared module/i.test(message)) return 'version-skew';
37
+ if (/network|fetch|script|timeout|chunk|loading/i.test(message)) return 'network';
38
+ return 'remote-unavailable';
39
+ }
40
+ function createModuleFederationFallbackTelemetry(input) {
41
+ const error = void 0 !== input.error ? toError(input.error) : void 0;
42
+ const status = input.status ?? 'degraded';
43
+ const eventName = input.eventName ?? ('recovered' === status ? MODULE_FEDERATION_RECOVERY_SIGNAL_EVENT : MODULE_FEDERATION_FALLBACK_SIGNAL_EVENT);
44
+ const metadata = {
45
+ ...input.metadata ?? {},
46
+ classification: input.classification,
47
+ remote: input.remote,
48
+ status
49
+ };
50
+ if (void 0 !== input.exportName) metadata.exportName = input.exportName;
51
+ if (void 0 !== input.runtimeDigest) metadata.runtimeDigest = input.runtimeDigest;
52
+ if (void 0 !== error) {
53
+ metadata.errorName = error.name;
54
+ metadata.errorMessage = error.message;
55
+ }
56
+ const payload = {
57
+ appName: input.appName,
58
+ eventName,
59
+ metadata,
60
+ phase: input.phase,
61
+ reason: input.classification,
62
+ schemaVersion: 1
63
+ };
64
+ if (void 0 !== input.entry) payload.entry = input.entry;
65
+ if (void 0 !== input.runtimeDigest) payload.runtimeDigest = input.runtimeDigest;
66
+ return payload;
67
+ }
68
+ function toModuleFederationFallbackAttributes(payload) {
69
+ return {
70
+ 'data-mf-fallback-app': payload.appName,
71
+ 'data-mf-fallback-classification': payload.reason,
72
+ 'data-mf-fallback-phase': payload.phase,
73
+ 'data-mf-fallback-remote': String(payload.metadata.remote),
74
+ 'data-mf-fallback-status': String(payload.metadata.status),
75
+ 'data-mf-telemetry-event': payload.eventName
76
+ };
77
+ }
78
+ async function emitModuleFederationFallbackTelemetry(input, options = {}) {
79
+ const payload = createModuleFederationFallbackTelemetry(input);
80
+ if ("u" > typeof window && 'function' == typeof window.dispatchEvent && "u" > typeof CustomEvent) window.dispatchEvent(new CustomEvent(payload.eventName, {
81
+ detail: payload
82
+ }));
83
+ const shouldPost = true === options.postSignal || Boolean(options.endpoint);
84
+ if (!shouldPost) return {
85
+ dispatched: true,
86
+ posted: false
87
+ };
88
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
89
+ if ('function' != typeof fetchImpl) return {
90
+ dispatched: true,
91
+ posted: false
92
+ };
93
+ const headers = new Headers({
94
+ 'content-type': 'application/json'
95
+ });
96
+ if (void 0 !== options.authToken && options.authToken.length > 0) headers.set(options.authHeaderName ?? DEFAULT_RUNTIME_FALLBACK_SIGNAL_AUTH_HEADER, options.authToken);
97
+ const response = await fetchImpl(options.endpoint ?? DEFAULT_RUNTIME_FALLBACK_SIGNAL_ENDPOINT, {
98
+ body: JSON.stringify(payload),
99
+ headers,
100
+ method: 'POST',
101
+ keepalive: true
102
+ });
103
+ return {
104
+ dispatched: true,
105
+ posted: true,
106
+ postStatus: response.status
107
+ };
108
+ }
109
+ export { DEFAULT_RUNTIME_FALLBACK_SIGNAL_AUTH_HEADER, DEFAULT_RUNTIME_FALLBACK_SIGNAL_ENDPOINT, MODULE_FEDERATION_FALLBACK_SIGNAL_EVENT, MODULE_FEDERATION_RECOVERY_SIGNAL_EVENT, ModuleFederationRemoteComponentContractError, ModuleFederationRemoteLoadError, ModuleFederationRemoteLoadTimeoutError, classifyModuleFederationFallback, createModuleFederationFallbackTelemetry, emitModuleFederationFallbackTelemetry, toModuleFederationFallbackAttributes };
@@ -5,7 +5,6 @@ import { ENTRY_POINT_RUNTIME_GLOBAL_CONTEXT_FILE_NAME } from "../../../cli/const
5
5
  import { resolveSSRMode } from "../../../cli/ssr/mode.mjs";
6
6
  import { FILE_SYSTEM_ROUTES_FILE_NAME } from "../constants.mjs";
7
7
  import { walk } from "./nestedRoutes.mjs";
8
- import { generateTanstackRouterTypesSourceForEntry, isTanstackRouterFrameworkEnabled } from "./tanstackTypes.mjs";
9
8
  import { getServerCombinedModuleFile, getServerLoadersFile } from "./utils.mjs";
10
9
  import * as __rspack_external__templates_mjs_4da4c6c8 from "./templates.mjs";
11
10
  async function generateRoutesForEntry(entrypoint, appContext) {
@@ -40,42 +39,11 @@ async function generateRoutesForEntry(entrypoint, appContext) {
40
39
  }
41
40
  return routes;
42
41
  }
43
- const generateCode = async (appContext, config, entrypoints, api, options)=>{
42
+ const generateCode = async (appContext, config, entrypoints, api)=>{
44
43
  const { internalDirectory, srcDirectory, internalSrcAlias, packageName } = appContext;
45
44
  const hooks = api.getHooks();
46
- const enableTanstackTypes = options?.enableTanstackTypes ?? await isTanstackRouterFrameworkEnabled(appContext);
47
45
  const generatedRoutesByEntry = {};
48
46
  await Promise.all(entrypoints.map(generateEntryCode));
49
- if (enableTanstackTypes) {
50
- const allEntries = Array.from(new Set(entrypoints.map((e)=>e.entryName).filter(Boolean)));
51
- const mainEntry = entrypoints.find((e)=>e.isMainEntry)?.entryName;
52
- const registerEntries = allEntries.sort((a, b)=>{
53
- if (mainEntry && a === mainEntry) return -1;
54
- if (mainEntry && b === mainEntry) return 1;
55
- return a.localeCompare(b);
56
- });
57
- if (registerEntries.length > 0) {
58
- const registerDtsPath = path.join(srcDirectory, 'modern-tanstack', 'register.gen.d.ts');
59
- const importStatements = registerEntries.map((entryName, index)=>`import type { router as router${index} } from './${entryName}/router.gen';`).join('\n');
60
- const routerUnionType = registerEntries.map((_, index)=>`typeof router${index}`).join(' | ');
61
- const registerContent = `// This file is auto-generated by Modern.js. Do not edit manually.
62
-
63
- ${importStatements}
64
-
65
- declare module '@modern-js/runtime/tanstack-router' {
66
- interface Register {
67
- router: ${routerUnionType};
68
- }
69
- }
70
- `;
71
- try {
72
- const prev = await fs.pathExists(registerDtsPath) ? await fs.readFile(registerDtsPath, 'utf-8') : null;
73
- if (prev !== registerContent) await fs.outputFile(registerDtsPath, registerContent, 'utf-8');
74
- } catch {
75
- await fs.outputFile(registerDtsPath, registerContent, 'utf-8');
76
- }
77
- }
78
- }
79
47
  async function generateEntryCode(entrypoint) {
80
48
  const { entryName, isMainEntry, isAutoMount, pageRoutesEntry, nestedRoutesEntry } = entrypoint;
81
49
  const { metaName } = api.getAppContext();
@@ -157,20 +125,6 @@ declare module '@modern-js/runtime/tanstack-router' {
157
125
  await fs.outputFile(serverLoaderFile, serverLoaderCombined);
158
126
  }
159
127
  await fs.outputFile(path.resolve(internalDirectory, `./${entryName}/${FILE_SYSTEM_ROUTES_FILE_NAME}`), code, 'utf8');
160
- if (enableTanstackTypes) {
161
- const { routerGenTs } = await generateTanstackRouterTypesSourceForEntry({
162
- appContext,
163
- entryName,
164
- routes: routes
165
- });
166
- const outPath = path.join(srcDirectory, 'modern-tanstack', entryName, 'router.gen.ts');
167
- try {
168
- const prev = await fs.pathExists(outPath) ? await fs.readFile(outPath, 'utf-8') : null;
169
- if (prev !== routerGenTs) await fs.outputFile(outPath, routerGenTs, 'utf-8');
170
- } catch {
171
- await fs.outputFile(outPath, routerGenTs, 'utf-8');
172
- }
173
- }
174
128
  }
175
129
  }
176
130
  }
@@ -100,20 +100,7 @@ const fileSystemRoutes = async ({ metaName, routes, ssrMode, nestedRoutesEntry,
100
100
  const loadersMapFile = path.join(internalDirectory, entryName, TEMP_LOADERS_DIR, 'map.json');
101
101
  const importLazyCode = `
102
102
  import { lazy } from "react";
103
- import * as loadableModule from "@${metaName}/runtime/loadable"
104
-
105
- const resolveLoadableExport = module => {
106
- const candidates = [module, module.default, module.default?.default];
107
- const loadable = candidates.find(candidate => typeof candidate === 'function');
108
-
109
- if (!loadable) {
110
- throw new TypeError('Modern.js runtime loadable export must resolve to a function');
111
- }
112
-
113
- return loadable;
114
- };
115
- const loadable = resolveLoadableExport(loadableModule);
116
- const loadableLazy = loadableModule.lazy || loadableModule.default?.lazy || loadable.lazy;
103
+ import loadable, { lazy as loadableLazy } from "@${metaName}/runtime/loadable"
117
104
  `;
118
105
  let rootLayoutCode = "";
119
106
  const getDataLoaderPath = ({ loaderId, clientData, action, inline, routeId, inValidSSRRoute })=>{
@@ -20,7 +20,7 @@ async function handleGeneratorEntryCode(api, entrypoints, options = {}) {
20
20
  const { generatorRegisterCode, generateCode, generatorServerRegisterCode } = await import("./code/index.mjs");
21
21
  originEntrypointsByKey.set(entrypointsKey, cloneDeep(entrypoints));
22
22
  const enableRsc = resolvedConfig?.server?.rsc;
23
- const routesByEntry = await generateCode(appContext, resolvedConfig, entrypoints, api, normalizedOptions.generateCodeOptions);
23
+ const routesByEntry = await generateCode(appContext, resolvedConfig, entrypoints, api);
24
24
  await Promise.all(entrypoints.map(async (entrypoint)=>{
25
25
  if (entrypoint.nestedRoutesEntry || entrypoint.pageRoutesEntry) {
26
26
  const route = appContext.serverRoutes.find((r)=>r.entryName === entrypoint.entryName);
@@ -1,28 +1,8 @@
1
1
  import node_path from "node:path";
2
- import { NESTED_ROUTE_SPEC_FILE, filterRoutesForServer, findExists, fs } from "@modern-js/utils";
2
+ import { NESTED_ROUTE_SPEC_FILE, filterRoutesForServer, fs } from "@modern-js/utils";
3
3
  import { NESTED_ROUTES_DIR } from "./constants.mjs";
4
4
  import { BUILT_IN_ROUTES_OWNER, getEntrypointRoutesDir, getEntrypointRoutesOwner, isRouteEntry } from "./entry.mjs";
5
5
  import { handleFileChange, handleGeneratorEntryCode, handleModifyEntrypoints } from "./handler.mjs";
6
- const JS_OR_TS_EXTS = [
7
- '.js',
8
- '.jsx',
9
- '.ts',
10
- '.tsx',
11
- '.mjs',
12
- '.mts',
13
- '.cjs',
14
- '.cts'
15
- ];
16
- function hasRouterConfigInRuntimeFile(runtimeConfigBase) {
17
- const runtimeConfigFile = findExists(JS_OR_TS_EXTS.map((ext)=>`${runtimeConfigBase}${ext}`));
18
- if (!runtimeConfigFile) return false;
19
- try {
20
- const content = fs.readFileSync(runtimeConfigFile, 'utf-8');
21
- return /router\s*:/.test(content);
22
- } catch {
23
- return false;
24
- }
25
- }
26
6
  function isBuiltInRouteEntrypoint(entrypoint) {
27
7
  const entrypointRoutesOwner = getEntrypointRoutesOwner(entrypoint);
28
8
  if (entrypointRoutesOwner) return entrypointRoutesOwner === BUILT_IN_ROUTES_OWNER;
@@ -52,12 +32,11 @@ const routerPlugin = ()=>({
52
32
  });
53
33
  });
54
34
  api._internalRuntimePlugins(({ entrypoint, plugins })=>{
55
- const { serverRoutes, metaName, srcDirectory, runtimeConfigFile } = api.getAppContext();
35
+ const { serverRoutes, metaName } = api.getAppContext();
56
36
  const normalizedConfig = api.getNormalizedConfig();
57
37
  const hasUserRouterConfig = normalizedConfig.router && Object.keys(normalizedConfig.router).length > 0;
58
- const hasRuntimeRouterConfig = hasRouterConfigInRuntimeFile(node_path.join(srcDirectory, runtimeConfigFile));
59
38
  const serverBase = serverRoutes.filter((route)=>route.entryName === entrypoint.entryName).map((route)=>route.urlPath).sort((a, b)=>a.length - b.length > 0 ? -1 : 1);
60
- const shouldInstallBuiltInRouter = isBuiltInRouteEntrypoint(entrypoint) || !isPluginOwnedRouteEntrypoint(entrypoint) && (hasUserRouterConfig || hasRuntimeRouterConfig);
39
+ const shouldInstallBuiltInRouter = isBuiltInRouteEntrypoint(entrypoint) || !isPluginOwnedRouteEntrypoint(entrypoint) && hasUserRouterConfig;
61
40
  if (shouldInstallBuiltInRouter) plugins.push({
62
41
  name: 'router',
63
42
  path: `@${metaName}/runtime/router/internal`,
@@ -4,6 +4,21 @@ import { useEffect, useMemo, useRef } from "react";
4
4
  import { ROUTER_DATA_JSON_ID } from "../../core/constants.mjs";
5
5
  import { modernInline, runWindowFnStr } from "./constants.mjs";
6
6
  import { serializeErrors } from "./utils.mjs";
7
+ function toDeferredErrorInfo(error) {
8
+ if ('production' === process.env.NODE_ENV) return {
9
+ message: 'Unexpected Server Error'
10
+ };
11
+ if (error && 'object' == typeof error) {
12
+ const maybeMessage = error.message;
13
+ return {
14
+ message: 'string' == typeof maybeMessage ? maybeMessage : String(maybeMessage ?? error),
15
+ stack: error.stack
16
+ };
17
+ }
18
+ return {
19
+ message: String(error)
20
+ };
21
+ }
7
22
  const DeferredDataScripts = (props)=>{
8
23
  const staticContext = props?.context;
9
24
  const useJsonScript = props?.useJsonScript;
@@ -39,10 +54,7 @@ const DeferredDataScripts = (props)=>{
39
54
  {
40
55
  const trackedPromise = deferredData.data[key];
41
56
  if (void 0 !== trackedPromise._error) {
42
- const error = {
43
- message: trackedPromise._error.message,
44
- stack: 'production' !== process.env.NODE_ENV ? trackedPromise._error.stack : void 0
45
- };
57
+ const error = toDeferredErrorInfo(trackedPromise._error);
46
58
  return {
47
59
  key,
48
60
  routerDataFnName: 'p',
@@ -11,7 +11,6 @@ function composeEventHandlers(theirHandler, ourHandler) {
11
11
  }
12
12
  const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
13
13
  const DEFAULT_PREFETCH_BEHAVIOR = 'render';
14
- const DEFAULT_PRELOAD_BEHAVIOR = 'viewport';
15
14
  const INTENT_DELAY = 100;
16
15
  const VIEWPORT_ROOT_MARGIN = '200px';
17
16
  const MAX_CONCURRENT_WARMUPS = 4;
@@ -76,7 +75,7 @@ const setRef = (ref, value)=>{
76
75
  };
77
76
  const isDataWarmupEnabled = (route)=>{
78
77
  const handle = route.handle;
79
- return handle?.navigationWarmup?.data === true;
78
+ return handle?.navigationWarmup?.data !== false;
80
79
  };
81
80
  function usePrefetchBehavior(prefetch, preload, theirElementProps) {
82
81
  const [maybeWarmup, setMaybeWarmup] = react.useState(false);
@@ -250,7 +249,7 @@ const normalizePreloadBehavior = (preload, prefetch)=>{
250
249
  if (false === preload || 'none' === preload) return 'none';
251
250
  if (void 0 !== preload) return preload;
252
251
  if ('none' === prefetch) return 'none';
253
- return DEFAULT_PRELOAD_BEHAVIOR;
252
+ return prefetch;
254
253
  };
255
254
  const createPrefetchLink = (Link)=>/*#__PURE__*/ react.forwardRef(({ to, prefetch = DEFAULT_PREFETCH_BEHAVIOR, preload, ...props }, forwardedRef)=>{
256
255
  const isAbsolute = 'string' == typeof to && ABSOLUTE_URL_REGEX.test(to);