@bleedingdev/modern-js-runtime 3.9.0-ultramodern.1 → 3.9.0-ultramodern.11

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 (166) hide show
  1. package/dist/cjs/cli/code.js +3 -1
  2. package/dist/cjs/cli/ssr/index.js +2 -74
  3. package/dist/cjs/core/browser/hydrate.js +6 -1
  4. package/dist/cjs/core/context/index.js +4 -43
  5. package/dist/cjs/core/context/public.js +4 -7
  6. package/dist/cjs/core/context/runtime.js +17 -5
  7. package/dist/cjs/core/react/wrapper.js +22 -65
  8. package/dist/cjs/core/server/helmet.js +5 -4
  9. package/dist/cjs/core/server/requestResponse.js +4 -4
  10. package/dist/cjs/core/server/routerCleanup.js +2 -2
  11. package/dist/cjs/core/server/shared.js +171 -4
  12. package/dist/cjs/core/server/stream/afterTemplate.js +21 -16
  13. package/dist/cjs/core/server/stream/beforeTemplate.js +34 -25
  14. package/dist/cjs/core/server/stream/beforeTemplate.worker.js +28 -21
  15. package/dist/cjs/core/server/stream/createReadableStream.js +208 -123
  16. package/dist/cjs/core/server/stream/createReadableStream.worker.js +159 -90
  17. package/dist/cjs/core/server/stream/deferredScript.js +3 -3
  18. package/dist/cjs/core/server/stream/shared.js +2 -2
  19. package/dist/cjs/core/server/string/index.js +100 -64
  20. package/dist/cjs/core/server/string/loadable.js +34 -19
  21. package/dist/cjs/core/server/string/ssrData.js +5 -12
  22. package/dist/cjs/core/server/utils.js +1 -2
  23. package/dist/cjs/exports/head.js +7 -14
  24. package/dist/cjs/router/runtime/PrefetchLink.js +67 -123
  25. package/dist/cjs/router/runtime/hooks.js +13 -2
  26. package/dist/cjs/router/runtime/internal.js +7 -45
  27. package/dist/cjs/router/runtime/plugin.js +2 -8
  28. package/dist/cjs/router/runtime/plugin.node.js +2 -30
  29. package/dist/cjs/router/runtime/redirect.js +1 -1
  30. package/dist/esm/cli/code.mjs +3 -1
  31. package/dist/esm/cli/ssr/index.mjs +3 -72
  32. package/dist/esm/core/browser/hydrate.mjs +7 -2
  33. package/dist/esm/core/context/index.mjs +2 -5
  34. package/dist/esm/core/context/public.mjs +1 -5
  35. package/dist/esm/core/context/runtime.mjs +13 -4
  36. package/dist/esm/core/react/wrapper.mjs +21 -67
  37. package/dist/esm/core/server/helmet.mjs +5 -4
  38. package/dist/esm/core/server/requestResponse.mjs +3 -3
  39. package/dist/esm/core/server/routerCleanup.mjs +1 -1
  40. package/dist/esm/core/server/shared.mjs +153 -1
  41. package/dist/esm/core/server/stream/afterTemplate.mjs +23 -18
  42. package/dist/esm/core/server/stream/beforeTemplate.mjs +37 -28
  43. package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +31 -24
  44. package/dist/esm/core/server/stream/createReadableStream.mjs +207 -122
  45. package/dist/esm/core/server/stream/createReadableStream.worker.mjs +149 -90
  46. package/dist/esm/core/server/stream/deferredScript.mjs +3 -3
  47. package/dist/esm/core/server/stream/shared.mjs +2 -2
  48. package/dist/esm/core/server/string/index.mjs +104 -68
  49. package/dist/esm/core/server/string/loadable.mjs +34 -19
  50. package/dist/esm/core/server/string/ssrData.mjs +5 -12
  51. package/dist/esm/core/server/utils.mjs +1 -2
  52. package/dist/esm/exports/head.mjs +7 -14
  53. package/dist/esm/router/runtime/PrefetchLink.mjs +67 -123
  54. package/dist/esm/router/runtime/hooks.mjs +9 -1
  55. package/dist/esm/router/runtime/internal.mjs +2 -33
  56. package/dist/esm/router/runtime/plugin.mjs +1 -7
  57. package/dist/esm/router/runtime/plugin.node.mjs +1 -29
  58. package/dist/esm/router/runtime/redirect.mjs +1 -1
  59. package/dist/esm-node/cli/code.mjs +3 -1
  60. package/dist/esm-node/cli/ssr/index.mjs +3 -72
  61. package/dist/esm-node/core/browser/hydrate.mjs +7 -2
  62. package/dist/esm-node/core/context/index.mjs +2 -5
  63. package/dist/esm-node/core/context/public.mjs +1 -5
  64. package/dist/esm-node/core/context/runtime.mjs +13 -4
  65. package/dist/esm-node/core/react/wrapper.mjs +21 -67
  66. package/dist/esm-node/core/server/helmet.mjs +5 -4
  67. package/dist/esm-node/core/server/requestResponse.mjs +3 -3
  68. package/dist/esm-node/core/server/routerCleanup.mjs +1 -1
  69. package/dist/esm-node/core/server/shared.mjs +153 -1
  70. package/dist/esm-node/core/server/stream/afterTemplate.mjs +23 -18
  71. package/dist/esm-node/core/server/stream/beforeTemplate.mjs +37 -28
  72. package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +31 -24
  73. package/dist/esm-node/core/server/stream/createReadableStream.mjs +207 -122
  74. package/dist/esm-node/core/server/stream/createReadableStream.worker.mjs +149 -90
  75. package/dist/esm-node/core/server/stream/deferredScript.mjs +3 -3
  76. package/dist/esm-node/core/server/stream/shared.mjs +2 -2
  77. package/dist/esm-node/core/server/string/index.mjs +104 -68
  78. package/dist/esm-node/core/server/string/loadable.mjs +34 -19
  79. package/dist/esm-node/core/server/string/ssrData.mjs +5 -12
  80. package/dist/esm-node/core/server/utils.mjs +1 -2
  81. package/dist/esm-node/exports/head.mjs +7 -14
  82. package/dist/esm-node/router/runtime/PrefetchLink.mjs +67 -123
  83. package/dist/esm-node/router/runtime/hooks.mjs +9 -1
  84. package/dist/esm-node/router/runtime/internal.mjs +2 -33
  85. package/dist/esm-node/router/runtime/plugin.mjs +1 -7
  86. package/dist/esm-node/router/runtime/plugin.node.mjs +1 -29
  87. package/dist/esm-node/router/runtime/redirect.mjs +1 -1
  88. package/dist/types/cli/ssr/index.d.ts +0 -3
  89. package/dist/types/core/context/index.d.ts +4 -6
  90. package/dist/types/core/context/public.d.ts +1 -23
  91. package/dist/types/core/context/runtime.d.ts +26 -2
  92. package/dist/types/core/react/wrapper.d.ts +6 -0
  93. package/dist/types/core/server/helmet.d.ts +4 -5
  94. package/dist/types/core/server/requestHandler.d.ts +2 -2
  95. package/dist/types/core/server/requestResponse.d.ts +1 -1
  96. package/dist/types/core/server/routerCleanup.d.ts +1 -1
  97. package/dist/types/core/server/shared.d.ts +24 -1
  98. package/dist/types/core/server/stream/afterTemplate.d.ts +2 -1
  99. package/dist/types/core/server/stream/beforeTemplate.d.ts +4 -1
  100. package/dist/types/core/server/stream/beforeTemplate.worker.d.ts +4 -1
  101. package/dist/types/core/server/stream/shared.d.ts +2 -2
  102. package/dist/types/core/server/string/loadable.d.ts +6 -3
  103. package/dist/types/core/server/string/ssrData.d.ts +2 -1
  104. package/dist/types/core/server/string/types.d.ts +1 -5
  105. package/dist/types/core/server/tracer.d.ts +1 -1
  106. package/dist/types/core/server/utils.d.ts +1 -1
  107. package/dist/types/core/types.d.ts +1 -2
  108. package/dist/types/exports/head.d.ts +2 -2
  109. package/dist/types/router/runtime/PrefetchLink.d.ts +27 -2
  110. package/dist/types/router/runtime/hooks.d.ts +19 -2
  111. package/dist/types/router/runtime/internal.d.ts +4 -21
  112. package/dist/types/router/runtime/types.d.ts +2 -43
  113. package/package.json +18 -46
  114. package/rstest.config.mts +32 -2
  115. package/dist/cjs/boundary-debugger/index.js +0 -317
  116. package/dist/cjs/core/context/extensions.js +0 -74
  117. package/dist/cjs/core/context/helmetContext.js +0 -54
  118. package/dist/cjs/core/server/federatedCss.js +0 -58
  119. package/dist/cjs/core/server/scriptOrder.js +0 -140
  120. package/dist/cjs/module-federation/consume-surface.js +0 -199
  121. package/dist/cjs/module-federation/distributed-ssr.js +0 -135
  122. package/dist/cjs/module-federation/index.js +0 -316
  123. package/dist/cjs/module-federation/last-known-good.js +0 -157
  124. package/dist/cjs/module-federation/manifest-recovery-runtime-plugin.js +0 -129
  125. package/dist/cjs/module-federation/surface-resolution-types.js +0 -61
  126. package/dist/cjs/router/runtime/lifecycle.js +0 -167
  127. package/dist/cjs/router/runtime/provider.js +0 -153
  128. package/dist/esm/boundary-debugger/index.mjs +0 -277
  129. package/dist/esm/core/context/extensions.mjs +0 -33
  130. package/dist/esm/core/context/helmetContext.mjs +0 -13
  131. package/dist/esm/core/server/federatedCss.mjs +0 -20
  132. package/dist/esm/core/server/scriptOrder.mjs +0 -90
  133. package/dist/esm/module-federation/consume-surface.mjs +0 -158
  134. package/dist/esm/module-federation/distributed-ssr.mjs +0 -82
  135. package/dist/esm/module-federation/index.mjs +0 -115
  136. package/dist/esm/module-federation/last-known-good.mjs +0 -113
  137. package/dist/esm/module-federation/manifest-recovery-runtime-plugin.mjs +0 -89
  138. package/dist/esm/module-federation/surface-resolution-types.mjs +0 -8
  139. package/dist/esm/router/runtime/lifecycle.mjs +0 -105
  140. package/dist/esm/router/runtime/provider.mjs +0 -100
  141. package/dist/esm-node/boundary-debugger/index.mjs +0 -278
  142. package/dist/esm-node/core/context/extensions.mjs +0 -34
  143. package/dist/esm-node/core/context/helmetContext.mjs +0 -14
  144. package/dist/esm-node/core/server/federatedCss.mjs +0 -21
  145. package/dist/esm-node/core/server/scriptOrder.mjs +0 -91
  146. package/dist/esm-node/module-federation/consume-surface.mjs +0 -159
  147. package/dist/esm-node/module-federation/distributed-ssr.mjs +0 -83
  148. package/dist/esm-node/module-federation/index.mjs +0 -116
  149. package/dist/esm-node/module-federation/last-known-good.mjs +0 -114
  150. package/dist/esm-node/module-federation/manifest-recovery-runtime-plugin.mjs +0 -90
  151. package/dist/esm-node/module-federation/surface-resolution-types.mjs +0 -9
  152. package/dist/esm-node/router/runtime/lifecycle.mjs +0 -106
  153. package/dist/esm-node/router/runtime/provider.mjs +0 -101
  154. package/dist/types/boundary-debugger/index.d.ts +0 -28
  155. package/dist/types/core/context/extensions.d.ts +0 -35
  156. package/dist/types/core/context/helmetContext.d.ts +0 -10
  157. package/dist/types/core/server/federatedCss.d.ts +0 -5
  158. package/dist/types/core/server/scriptOrder.d.ts +0 -25
  159. package/dist/types/module-federation/consume-surface.d.ts +0 -104
  160. package/dist/types/module-federation/distributed-ssr.d.ts +0 -61
  161. package/dist/types/module-federation/index.d.ts +0 -71
  162. package/dist/types/module-federation/last-known-good.d.ts +0 -52
  163. package/dist/types/module-federation/manifest-recovery-runtime-plugin.d.ts +0 -25
  164. package/dist/types/module-federation/surface-resolution-types.d.ts +0 -23
  165. package/dist/types/router/runtime/lifecycle.d.ts +0 -27
  166. package/dist/types/router/runtime/provider.d.ts +0 -78
@@ -1,7 +1,6 @@
1
1
  import "node:module";
2
2
  "use client";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
- import { getNavigationWarmupCacheKey } from "@modern-js/runtime-extensions";
5
4
  import { Link as router_Link, NavLink, matchRoutes, useHref, useMatches, useResolvedPath } from "@modern-js/runtime-utils/router";
6
5
  import react, { useContext, useMemo } from "react";
7
6
  import { InternalRuntimeContext } from "../../core/context/index.mjs";
@@ -21,62 +20,6 @@ function composeEventHandlers(theirHandler, ourHandler) {
21
20
  };
22
21
  }
23
22
  const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
24
- const DEFAULT_PREFETCH_BEHAVIOR = 'render';
25
- const INTENT_DELAY = 100;
26
- const VIEWPORT_ROOT_MARGIN = '200px';
27
- const MAX_CONCURRENT_WARMUPS = 4;
28
- const WARMUP_TTL = 30000;
29
- const SLOW_EFFECTIVE_TYPES = new Set([
30
- 'slow-2g',
31
- '2g'
32
- ]);
33
- const warmupCache = new Map();
34
- const warmupQueue = [];
35
- let activeWarmups = 0;
36
- const getWarmupTimestamp = ()=>performance.now();
37
- const getConnection = ()=>{
38
- const nav = globalThis.navigator;
39
- return nav?.connection || nav?.mozConnection || nav?.webkitConnection;
40
- };
41
- const shouldWarmupOnCurrentNetwork = ()=>{
42
- const connection = getConnection();
43
- if (connection?.saveData) return false;
44
- if ('string' == typeof connection?.effectiveType && SLOW_EFFECTIVE_TYPES.has(connection.effectiveType)) return false;
45
- return true;
46
- };
47
- const pruneWarmupCache = (now = getWarmupTimestamp())=>{
48
- for (const [key, timestamp] of warmupCache)if (now - timestamp > WARMUP_TTL) warmupCache.delete(key);
49
- };
50
- const runNextWarmup = ()=>{
51
- while(activeWarmups < MAX_CONCURRENT_WARMUPS && warmupQueue.length > 0){
52
- const task = warmupQueue.shift();
53
- if (task.cancelled) continue;
54
- activeWarmups += 1;
55
- task.run().catch(()=>{
56
- warmupCache.delete(task.key);
57
- }).finally(()=>{
58
- activeWarmups -= 1;
59
- runNextWarmup();
60
- });
61
- }
62
- };
63
- const scheduleWarmup = (key, run)=>{
64
- if (!shouldWarmupOnCurrentNetwork()) return ()=>{};
65
- pruneWarmupCache();
66
- if (warmupCache.has(key)) return ()=>{};
67
- warmupCache.set(key, getWarmupTimestamp());
68
- const task = {
69
- key,
70
- run,
71
- cancelled: false
72
- };
73
- warmupQueue.push(task);
74
- runNextWarmup();
75
- return ()=>{
76
- task.cancelled = true;
77
- if (warmupQueue.includes(task)) warmupCache.delete(task.key);
78
- };
79
- };
80
23
  const setRef = (ref, value)=>{
81
24
  if (!ref) return;
82
25
  if ('function' == typeof ref) return void ref(value);
@@ -84,70 +27,65 @@ const setRef = (ref, value)=>{
84
27
  ref.current = value;
85
28
  } catch {}
86
29
  };
87
- const isDataWarmupEnabled = (route)=>{
88
- const handle = route.handle;
89
- return handle?.navigationWarmup?.data !== false;
90
- };
91
- function usePrefetchBehavior(prefetch, preload, theirElementProps) {
92
- const [maybeWarmup, setMaybeWarmup] = react.useState(false);
93
- const [shouldPrefetch, setShouldPrefetch] = react.useState(false);
94
- const [shouldPreload, setShouldPreload] = react.useState(false);
95
- const [viewportElement, setViewportElement] = react.useState(null);
30
+ function usePrefetchBehavior(prefetch, preload, theirElementProps, policy) {
31
+ const [maybePrefetch, setMaybePrefetch] = react.useState(false);
32
+ const [state, setState] = react.useState({
33
+ code: false,
34
+ data: false
35
+ });
36
+ const [element, setElement] = react.useState(null);
37
+ const observerRef = react.useRef(void 0);
96
38
  const { onFocus, onBlur, onMouseEnter, onMouseLeave, onTouchStart } = theirElementProps;
97
39
  react.useEffect(()=>{
98
- if ('render' === prefetch) setShouldPrefetch(true);
99
- if ('render' === preload) setShouldPreload(true);
40
+ if (!policy) return void setState({
41
+ code: 'render' === prefetch,
42
+ data: 'render' === prefetch
43
+ });
44
+ const observer = policy.observe({
45
+ element,
46
+ prefetch,
47
+ preload,
48
+ notify: (next)=>setState((previous)=>previous.code === next.code && previous.data === next.data ? previous : next)
49
+ });
50
+ observerRef.current = observer;
51
+ return ()=>{
52
+ observerRef.current = void 0;
53
+ observer.dispose();
54
+ };
100
55
  }, [
56
+ policy,
101
57
  prefetch,
102
- preload
58
+ preload,
59
+ element
60
+ ]);
61
+ react.useEffect(()=>{
62
+ if (policy || !maybePrefetch) return;
63
+ const timer = setTimeout(()=>setState({
64
+ code: true,
65
+ data: true
66
+ }), 100);
67
+ return ()=>clearTimeout(timer);
68
+ }, [
69
+ policy,
70
+ maybePrefetch
103
71
  ]);
104
72
  const setIntent = ()=>{
105
- if ('intent' === prefetch || 'intent' === preload) setMaybeWarmup(true);
73
+ if (policy) observerRef.current?.onIntent();
74
+ else if ('intent' === prefetch) setMaybePrefetch(true);
106
75
  };
107
76
  const cancelIntent = ()=>{
108
- if ('intent' === prefetch || 'intent' === preload) {
109
- setMaybeWarmup(false);
110
- setShouldPrefetch(false);
111
- setShouldPreload(false);
77
+ if (policy) observerRef.current?.onCancel();
78
+ else if ('intent' === prefetch) {
79
+ setMaybePrefetch(false);
80
+ setState({
81
+ code: false,
82
+ data: false
83
+ });
112
84
  }
113
85
  };
114
- react.useEffect(()=>{
115
- if (maybeWarmup) {
116
- const id = setTimeout(()=>{
117
- if ('intent' === prefetch) setShouldPrefetch(true);
118
- if ('intent' === preload) setShouldPreload(true);
119
- }, INTENT_DELAY);
120
- return ()=>{
121
- clearTimeout(id);
122
- };
123
- }
124
- }, [
125
- maybeWarmup,
126
- prefetch,
127
- preload
128
- ]);
129
- react.useEffect(()=>{
130
- if (!viewportElement || 'viewport' !== prefetch && 'viewport' !== preload || "u" < typeof IntersectionObserver) return;
131
- const observer = new IntersectionObserver((entries)=>{
132
- if (!entries.some((entry)=>entry.isIntersecting)) return;
133
- if ('viewport' === prefetch) setShouldPrefetch(true);
134
- if ('viewport' === preload) setShouldPreload(true);
135
- observer.disconnect();
136
- }, {
137
- rootMargin: VIEWPORT_ROOT_MARGIN
138
- });
139
- observer.observe(viewportElement);
140
- return ()=>{
141
- observer.disconnect();
142
- };
143
- }, [
144
- prefetch,
145
- preload,
146
- viewportElement
147
- ]);
148
86
  return [
149
- shouldPrefetch,
150
- shouldPreload,
87
+ state.data,
88
+ state.code,
151
89
  {
152
90
  onFocus: composeEventHandlers(onFocus, setIntent),
153
91
  onBlur: composeEventHandlers(onBlur, cancelIntent),
@@ -155,7 +93,7 @@ function usePrefetchBehavior(prefetch, preload, theirElementProps) {
155
93
  onMouseLeave: composeEventHandlers(onMouseLeave, cancelIntent),
156
94
  onTouchStart: composeEventHandlers(onTouchStart, setIntent)
157
95
  },
158
- setViewportElement
96
+ setElement
159
97
  ];
160
98
  }
161
99
  async function loadRouteModule(route, routeAssets, chunkLoader) {
@@ -196,7 +134,8 @@ const PrefetchPageLinks = ({ path, includeData })=>{
196
134
  const context = useContext(InternalRuntimeContext);
197
135
  const { routeManifest, routes } = context;
198
136
  const { routeAssets } = routeManifest || {};
199
- const allowNetworkWarmup = shouldWarmupOnCurrentNetwork();
137
+ const policy = context.linkPrefetchPolicy;
138
+ const allowNetworkWarmup = policy?.canWarmup() ?? true;
200
139
  const matches = useMemo(()=>Array.isArray(routes) ? matchRoutes(routes, pathname) : [], [
201
140
  pathname,
202
141
  routes
@@ -216,7 +155,16 @@ const PrefetchPageLinks = ({ path, includeData })=>{
216
155
  const routeAsset = routeId ? routeAssets[routeId] : void 0;
217
156
  const chunkIds = routeAsset?.chunkIds;
218
157
  if (!routeId || !Array.isArray(chunkIds) || 0 === chunkIds.length) return ()=>{};
219
- return scheduleWarmup(getNavigationWarmupCacheKey(context, chunkLoader, getWebpackPublicPath(), `route-module:${routeId}:${chunkIds.join(',')}`), ()=>loadRouteModule(match.route, routeAssets, chunkLoader));
158
+ const run = ()=>loadRouteModule(match.route, routeAssets, chunkLoader);
159
+ if (policy) return policy.schedule({
160
+ runtimeContext: context,
161
+ chunkLoader,
162
+ publicPath: getWebpackPublicPath(),
163
+ key: `route-module:${routeId}:${chunkIds.join(',')}`,
164
+ run
165
+ });
166
+ run().catch(()=>{});
167
+ return ()=>{};
220
168
  });
221
169
  return ()=>{
222
170
  cancellations.forEach((cancel)=>cancel());
@@ -225,6 +173,7 @@ const PrefetchPageLinks = ({ path, includeData })=>{
225
173
  allowNetworkWarmup,
226
174
  chunkLoader,
227
175
  context,
176
+ policy,
228
177
  routeAssetGeneration
229
178
  ]);
230
179
  if (!allowNetworkWarmup || !includeData || !window._SSR_DATA) return null;
@@ -236,10 +185,11 @@ const PrefetchPageLinks = ({ path, includeData })=>{
236
185
  };
237
186
  const PrefetchDataLinks = ({ matches, path, routeManifest })=>{
238
187
  const { pathname, search, hash } = path;
188
+ const policy = useContext(InternalRuntimeContext).linkPrefetchPolicy;
239
189
  const currentMatches = useMatches();
240
190
  const basename = useHref('/');
241
191
  const dataHrefs = useMemo(()=>matches?.filter((match, index)=>{
242
- if (!isDataWarmupEnabled(match.route) || !match.route.loader || 'function' != typeof match.route.loader || 0 === match.route.loader.length) return false;
192
+ if (policy?.allowData(match.route) === false || !match.route.loader || 'function' != typeof match.route.loader || 0 === match.route.loader.length) return false;
243
193
  if (match.route.shouldRevalidate) {
244
194
  const currentUrl = new URL(location.pathname + location.search + location.hash, window.origin);
245
195
  const nextUrl = new URL(pathname + search + hash, window.origin);
@@ -266,16 +216,10 @@ const PrefetchDataLinks = ({ matches, path, routeManifest })=>{
266
216
  children: dataHrefs
267
217
  });
268
218
  };
269
- const normalizePreloadBehavior = (preload, prefetch)=>{
270
- if (false === preload || 'none' === preload) return 'none';
271
- if (void 0 !== preload) return preload;
272
- if ('none' === prefetch) return 'none';
273
- return prefetch;
274
- };
275
- const createPrefetchLink = (Link)=>/*#__PURE__*/ react.forwardRef(({ to, prefetch = DEFAULT_PREFETCH_BEHAVIOR, preload, ...props }, forwardedRef)=>{
219
+ const createPrefetchLink = (Link)=>/*#__PURE__*/ react.forwardRef(({ to, prefetch, preload, ...props }, forwardedRef)=>{
276
220
  const isAbsolute = 'string' == typeof to && ABSOLUTE_URL_REGEX.test(to);
277
- const resolvedPreload = normalizePreloadBehavior(preload, prefetch);
278
- const [shouldPrefetch, shouldPreload, prefetchHandlers, setViewportElement] = usePrefetchBehavior(prefetch, resolvedPreload, props);
221
+ const policy = useContext(InternalRuntimeContext).linkPrefetchPolicy;
222
+ const [shouldPrefetch, shouldPreload, prefetchHandlers, setViewportElement] = usePrefetchBehavior(prefetch, preload, props, policy);
279
223
  const setAnchorRef = react.useCallback((element)=>{
280
224
  setViewportElement(element);
281
225
  setRef(forwardedRef, element);
@@ -7,4 +7,12 @@ const onBeforeCreateRouter = createRouterSyncHook();
7
7
  const onAfterCreateRouter = createRouterSyncHook();
8
8
  const onBeforeHydrateRouter = createRouterSyncHook();
9
9
  const onAfterHydrateRouter = createRouterSyncHook();
10
- export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter };
10
+ const routerProviderRegistryHooks = {
11
+ modifyRoutes: modifyRoutes,
12
+ onBeforeCreateRoutes: onBeforeCreateRoutes,
13
+ onBeforeCreateRouter: onBeforeCreateRouter,
14
+ onAfterCreateRouter: onAfterCreateRouter,
15
+ onBeforeHydrateRouter: onBeforeHydrateRouter,
16
+ onAfterHydrateRouter: onAfterHydrateRouter
17
+ };
18
+ export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter, routerProviderRegistryHooks };
@@ -1,35 +1,4 @@
1
1
  import "node:module";
2
- import { merge } from "@modern-js/runtime-utils/merge";
3
- import { modifyRoutes, routerPlugin } from "./plugin.mjs";
4
- import { createRouterProviderRealm, registerRouterProvider, reportUnsupportedProviderRegistryHooks, resolveRouterProvider, routerProviderRegistryHooks } from "./provider.mjs";
5
- registerRouterProvider('react-router', routerPlugin, {
6
- isDefault: true
7
- });
8
- const createRouterPlugin = (localProviders = [])=>{
9
- const providerRealm = createRouterProviderRealm([
10
- {
11
- name: 'react-router',
12
- factory: routerPlugin,
13
- isDefault: true
14
- },
15
- ...localProviders
16
- ]);
17
- return (userConfig = {})=>({
18
- name: '@modern-js/plugin-router',
19
- registryHooks: routerProviderRegistryHooks,
20
- setup: (api)=>{
21
- const mergedConfig = merge(api.getRuntimeConfig().router || {}, userConfig);
22
- const pluginFactory = resolveRouterProvider(mergedConfig.framework, {
23
- realm: providerRealm
24
- });
25
- const providerPlugin = pluginFactory(userConfig);
26
- reportUnsupportedProviderRegistryHooks(providerPlugin);
27
- providerPlugin.setup?.(api);
28
- }
29
- });
30
- };
31
- const internal_routerPlugin = createRouterPlugin();
32
- const internal = internal_routerPlugin;
2
+ export { routerProviderRegistryHooks } from "./hooks.mjs";
3
+ export { modifyRoutes, routerPlugin as default, routerPlugin } from "./plugin.mjs";
33
4
  export { renderRoutes } from "./utils.mjs";
34
- export default internal;
35
- export { createRouterPlugin, createRouterProviderRealm, internal_routerPlugin as routerPlugin, modifyRoutes, registerRouterProvider, resolveRouterProvider };
@@ -5,9 +5,8 @@ import { RouterProvider, createBrowserRouter, createHashRouter, createRoutesFrom
5
5
  import { normalizePathname } from "@modern-js/runtime-utils/url";
6
6
  import * as __rspack_external_react from "react";
7
7
  import { InternalRuntimeContext, getGlobalEnableRsc, getGlobalIsRscClient, getGlobalLayoutApp, getGlobalRoutes } from "../../core/context/index.mjs";
8
- import { applyRouterRuntimeState } from "./lifecycle.mjs";
8
+ import { routerProviderRegistryHooks } from "./hooks.mjs";
9
9
  import { Link } from "./PrefetchLink.mjs";
10
- import { routerProviderRegistryHooks } from "./provider.mjs";
11
10
  import { createClientRouterFromPayload } from "./rsc-router.mjs";
12
11
  import { createRouteObjectsFromConfig, deserializeErrors, renderRoutes, urlJoin } from "./utils.mjs";
13
12
  let finalRouteConfig = {
@@ -169,11 +168,6 @@ function useRouterCreation(props, options) {
169
168
  basename: _basename,
170
169
  hydrationData
171
170
  });
172
- applyRouterRuntimeState(runtimeContext, {
173
- framework: 'react-router',
174
- basename: _basename,
175
- instance: router
176
- });
177
171
  hooks.onAfterCreateRouter.call({
178
172
  ...routerLifecycleContext,
179
173
  router,
@@ -9,9 +9,8 @@ import { useContext } from "react";
9
9
  import { InternalRuntimeContext, getGlobalEnableRsc, getGlobalLayoutApp, getGlobalRoutes } from "../../core/context/index.mjs";
10
10
  import { setServerPayload } from "../../core/context/serverPayload/index.server.mjs";
11
11
  import DeferredDataScripts_node from "./DeferredDataScripts.node.mjs";
12
- import { applyRouterRuntimeState, createRouterServerSnapshot } from "./lifecycle.mjs";
12
+ import { routerProviderRegistryHooks } from "./hooks.mjs";
13
13
  import { Link } from "./PrefetchLink.mjs";
14
- import { routerProviderRegistryHooks } from "./provider.mjs";
15
14
  import { RSCStaticRouter, createServerPayload, handleRSCRedirect, prepareRSCRoutes } from "./rsc-router.mjs";
16
15
  import { createRouteObjectsFromConfig, renderRoutes, urlJoin } from "./utils.mjs";
17
16
  function createRemixRequest(request) {
@@ -24,24 +23,6 @@ function createRemixRequest(request) {
24
23
  signal: controller.signal
25
24
  });
26
25
  }
27
- function createReactRouterServerSnapshot(routerContext, basename) {
28
- return createRouterServerSnapshot({
29
- framework: 'react-router',
30
- basename,
31
- statusCode: routerContext.statusCode,
32
- errors: routerContext.errors,
33
- routerData: {
34
- loaderData: routerContext.loaderData,
35
- errors: routerContext.errors
36
- },
37
- matches: routerContext.matches.map((match)=>{
38
- const routeId = match.route.id;
39
- return 'string' == typeof routeId ? {
40
- routeId
41
- } : void 0;
42
- }).filter((match)=>void 0 !== match)
43
- });
44
- }
45
26
  const routerPlugin = (userConfig = {})=>({
46
27
  name: '@modern-js/plugin-router',
47
28
  registryHooks: routerProviderRegistryHooks,
@@ -108,18 +89,9 @@ const routerPlugin = (userConfig = {})=>({
108
89
  throw errors[0];
109
90
  }
110
91
  context.routerContext = routerContext;
111
- const routerServerSnapshot = createReactRouterServerSnapshot(routerContext, _basename);
112
- applyRouterRuntimeState(context, {
113
- framework: 'react-router',
114
- basename: _basename,
115
- instance: routerContext,
116
- matchedRouteIds: routerServerSnapshot.matchedRouteIds,
117
- serverSnapshot: routerServerSnapshot
118
- });
119
92
  hooks.onAfterCreateRouter.call({
120
93
  ...routerLifecycleContext,
121
94
  router: routerContext,
122
- serverSnapshot: routerServerSnapshot,
123
95
  runtimeContext: context
124
96
  });
125
97
  let payload;
@@ -2,7 +2,7 @@ import "node:module";
2
2
  const handleRSCRedirect = (headers, basename, status)=>{
3
3
  const newHeaders = new Headers(headers);
4
4
  let redirectUrl = headers.get('Location');
5
- if (!redirectUrl || ![
5
+ if (null === redirectUrl || '' === redirectUrl || ![
6
6
  301,
7
7
  302,
8
8
  303,
@@ -1,6 +1,3 @@
1
1
  import type { AppTools, CliPlugin } from '@modern-js/app-tools';
2
- import type { MergedEnvironmentConfig } from '@rsbuild/core';
3
- type EnvironmentConfigLike = Partial<Pick<MergedEnvironmentConfig, 'output' | 'source' | 'tools'>>;
4
- export declare const shouldUseModuleFederationNodeOutput: (config: EnvironmentConfigLike) => boolean;
5
2
  export declare const ssrPlugin: () => CliPlugin<AppTools>;
6
3
  export default ssrPlugin;
@@ -20,12 +20,10 @@ type InternalRuntimeContextLike = {
20
20
  [key: string]: any;
21
21
  };
22
22
  export { DefaultNotFound } from '../../router/runtime/DefaultNotFound.js';
23
- export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter, type RouterExtendsHooks, } from '../../router/runtime/hooks.js';
24
- export { applyRouterRuntimeState, applyRouterServerPrepareResult, cleanupRouterRuntimeState, createRouterRuntimeState, createRouterServerSnapshot, getRouterHydrationScripts, getRouterMatchedRouteIds, getRouterRuntimeState, getRouterServerSnapshot, type RouterLifecycleContext, type RouterLifecyclePhase, } from '../../router/runtime/lifecycle.js';
25
- export { createRouterProviderRealm, type RouterProviderFactory, type RouterProviderPlugin, type RouterProviderRealm, type RouterProviderRegistration, registerRouterProvider, resolveRouterProvider, routerProviderRegistryHooks, } from '../../router/runtime/provider.js';
26
- export type { BuiltInRouterFramework, InternalRouterRuntimeState, InternalRouterServerSnapshot, LoaderFunction, LoaderFunctionArgs, ModernRoute, RouterFramework, RouterRouteMatchSnapshot, RouterServerPrepareResult, } from '../../router/runtime/types.js';
27
- export { createRuntimeContextExtension, type RuntimeContextExtension, } from './extensions.js';
28
- export { getInitialContext, InternalRuntimeContext, RuntimeContext, type TInternalRuntimeContext, type TRuntimeContext, } from './runtime.js';
23
+ export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter, type RouterExtendsHooks, type RouterLifecycleContext, routerProviderRegistryHooks, } from '../../router/runtime/hooks.js';
24
+ export type { LinkPrefetchPolicy } from '../../router/runtime/PrefetchLink.js';
25
+ export type { LoaderFunction, LoaderFunctionArgs, ModernRoute, } from '../../router/runtime/types.js';
26
+ export { getInitialContext, InternalRuntimeContext, RuntimeComponentResolverContext, RuntimeContext, type TInternalRuntimeContext, type TRuntimeContext, } from './runtime.js';
29
27
  export type { PayloadRoute, ServerPayload } from './serverPayload/index.js';
30
28
  interface GlobalContext {
31
29
  entryName?: string;
@@ -1,23 +1 @@
1
- import type { RouteObject } from '@modern-js/runtime-utils/router';
2
- import type { RequestContext } from '../types.js';
3
- export type { RequestContext };
4
- export interface TRuntimeContext {
5
- initialData?: Record<string, unknown>;
6
- isBrowser: boolean;
7
- routes?: RouteObject[];
8
- requestContext: RequestContext;
9
- /**
10
- * @deprecated Use `requestContext` instead
11
- */
12
- context: RequestContext;
13
- [key: string]: unknown;
14
- }
15
- export declare const RuntimeContext: import("react").Context<TRuntimeContext>;
16
- /**
17
- * deprecated, use RuntimeContext instead
18
- */
19
- export declare const ReactRuntimeContext: import("react").Context<TRuntimeContext>;
20
- /**
21
- * @deprecated use use(RuntimeContext) instead
22
- */
23
- export declare const useRuntimeContext: () => TRuntimeContext;
1
+ export { ReactRuntimeContext, type RequestContext, RuntimeContext, type TRuntimeContext, useRuntimeContext, } from './runtime.js';
@@ -1,7 +1,10 @@
1
+ import type { ResolveComponentFn } from '@modern-js/plugin/runtime';
1
2
  import type { RouteObject, StaticHandlerContext } from '@modern-js/runtime-utils/router';
2
3
  import type { BaseSSRServerContext } from '@modern-js/types';
4
+ import type { LinkPrefetchPolicy } from '../../router/runtime/PrefetchLink.js';
3
5
  import type { RouteManifest } from '../../router/runtime/types.js';
4
- import { type TRuntimeContext } from './public.js';
6
+ import type { RequestContext } from '../types.js';
7
+ export type { RequestContext };
5
8
  export type InternalSSRContext = {
6
9
  request: BaseSSRServerContext['request'] & {
7
10
  raw?: Request;
@@ -9,12 +12,23 @@ export type InternalSSRContext = {
9
12
  response: BaseSSRServerContext['response'];
10
13
  [key: string]: any;
11
14
  };
12
- export { ReactRuntimeContext, RuntimeContext, type TRuntimeContext, useRuntimeContext, } from './public.js';
15
+ export interface TRuntimeContext {
16
+ initialData?: Record<string, unknown>;
17
+ isBrowser: boolean;
18
+ routes?: RouteObject[];
19
+ requestContext: RequestContext;
20
+ /**
21
+ * @deprecated Use `requestContext` instead
22
+ */
23
+ context: RequestContext;
24
+ [key: string]: unknown;
25
+ }
13
26
  /**
14
27
  * InternalRuntimeContext used internally and by plugins
15
28
  */
16
29
  export interface TInternalRuntimeContext extends TRuntimeContext {
17
30
  routeManifest?: RouteManifest;
31
+ linkPrefetchPolicy?: LinkPrefetchPolicy;
18
32
  routes?: RouteObject[];
19
33
  routerContext?: StaticHandlerContext;
20
34
  unstable_getBlockNavState?: () => boolean;
@@ -23,4 +37,14 @@ export interface TInternalRuntimeContext extends TRuntimeContext {
23
37
  _internalRouterBaseName?: any;
24
38
  }
25
39
  export declare const InternalRuntimeContext: import("react").Context<TInternalRuntimeContext>;
40
+ export declare const RuntimeContext: import("react").Context<TRuntimeContext>;
41
+ export declare const RuntimeComponentResolverContext: import("react").Context<ResolveComponentFn | undefined>;
42
+ /**
43
+ * deprecated, use RuntimeContext instead
44
+ */
45
+ export declare const ReactRuntimeContext: import("react").Context<TRuntimeContext>;
46
+ /**
47
+ * @deprecated use use(RuntimeContext) instead
48
+ */
49
+ export declare const useRuntimeContext: () => TRuntimeContext;
26
50
  export declare const getInitialContext: (isBrowser?: boolean, routeManifest?: RouteManifest) => TInternalRuntimeContext;
@@ -1,3 +1,9 @@
1
+ import type { ResolveComponentFn } from '@modern-js/plugin/runtime';
1
2
  import type React from 'react';
2
3
  import { type TRuntimeContext } from '../context/index.js';
4
+ export declare function wrapRuntimeComponentResolver(root: React.ReactNode, hooks?: {
5
+ resolveComponent?: {
6
+ call: ResolveComponentFn;
7
+ };
8
+ } | undefined): React.ReactElement;
3
9
  export declare function wrapRuntimeContextProvider(App: React.ReactElement, contextValue: TRuntimeContext): React.JSX.Element;
@@ -1,5 +1,4 @@
1
- import type { HelmetServerState } from 'react-helmet-async';
2
- import type { TInternalRuntimeContext } from '../context/index.js';
3
- export declare function getHelmetData(runtimeContext: TInternalRuntimeContext): HelmetServerState | undefined;
4
- export declare function createReplaceHelemt(helmetData?: HelmetServerState): (template: string) => string;
5
- export declare function helmetReplace(content: string, helmetData: HelmetServerState): string;
1
+ import type { SSRHeadData, SSRRenderLifecycle } from '@modern-js/plugin/runtime';
2
+ export declare function getHelmetData(providers: readonly SSRRenderLifecycle[]): SSRHeadData | undefined;
3
+ export declare function createReplaceHelemt(helmetData?: SSRHeadData): (template: string) => string;
4
+ export declare function helmetReplace(content: string, helmetData: SSRHeadData): string;
@@ -1,7 +1,7 @@
1
- import type { RequestHandler, RequestHandlerOptions } from '@modern-js/app-tools';
1
+ import type { RequestHandler, RequestHandlerOptions } from '@modern-js/server-core';
2
2
  import React from 'react';
3
3
  import { type TInternalRuntimeContext } from '../context/index.js';
4
- export type { RequestHandlerConfig as HandleRequestConfig } from '@modern-js/app-tools';
4
+ export type { RequestHandlerConfig as HandleRequestConfig } from '@modern-js/server-core';
5
5
  export type HandleRequestOptions = Exclude<RequestHandlerOptions, 'staticGenerate'> & {
6
6
  runtimeContext: TInternalRuntimeContext;
7
7
  };
@@ -1,4 +1,4 @@
1
- import type { OnError } from '@modern-js/app-tools';
1
+ import type { OnError } from '@modern-js/types';
2
2
  import type { TInternalRuntimeContext } from '../context/index.js';
3
3
  import type { RouterCleanup } from './routerCleanup.js';
4
4
  export type ResponseProxy = {
@@ -9,7 +9,7 @@
9
9
  * failures are reported through the request's `onError` instead of being
10
10
  * swallowed.
11
11
  */
12
- import type { OnError } from '@modern-js/app-tools';
12
+ import type { OnError } from '@modern-js/types';
13
13
  import type { TInternalRuntimeContext } from '../context/index.js';
14
14
  export declare const ROUTER_CLEANUP_ERROR = "An error occurs during router runtime cleanup";
15
15
  export type RouterCleanup = {
@@ -1,4 +1,5 @@
1
- import type { ServerUserConfig } from '@modern-js/app-tools';
1
+ import type { SSRAssetGroup, SSRAssetTransformInfo, SSRRenderAsset, SSRRenderLifecycle, SSRRenderTerminal, SSRRouterData, SSRTemplateChunk, StreamSSRExtender } from '@modern-js/plugin/runtime';
2
+ import type { ServerUserConfig } from '@modern-js/server-core';
2
3
  import type { HandleRequestOptions } from './requestHandler.js';
3
4
  export type RenderOptions = HandleRequestOptions;
4
5
  export type SSRConfig = NonNullable<ServerUserConfig['ssr']>;
@@ -6,3 +7,25 @@ export type RenderStreaming = (request: Request, serverRoot: React.ReactElement,
6
7
  export type RenderString = (request: Request, serverRoot: React.ReactElement, optinos: RenderOptions) => Promise<string>;
7
8
  export type BuildHtmlCb = (template: string) => string | Promise<string>;
8
9
  export declare function buildHtml(template: string, callbacks: BuildHtmlCb[]): Promise<string>;
10
+ export declare function createSSRRenderLifecycle(observers: SSRRenderLifecycle[]): {
11
+ transformAssets<T extends SSRRenderAsset>(groups: readonly SSRAssetGroup<T>[], info: Omit<SSRAssetTransformInfo<T>, 'groups'>): readonly T[];
12
+ transformTemplateChunk(chunk: SSRTemplateChunk): SSRTemplateChunk;
13
+ getRouterData(): SSRRouterData | undefined;
14
+ readonly terminal: SSRRenderTerminal | undefined;
15
+ beforeReact(): void;
16
+ completedBody(html: string, phase: 'complete' | 'shell'): string;
17
+ finish(result: SSRRenderTerminal): void;
18
+ };
19
+ export declare function replaceSSRTemplateChunk(chunk: SSRTemplateChunk, lifecycle?: ReturnType<typeof createSSRRenderLifecycle>, options?: {
20
+ preserveEmpty?: boolean;
21
+ }): string;
22
+ export declare function orderSSRStreamTransforms(extenders: StreamSSRExtender[]): StreamSSRExtender[];
23
+ export declare function createSSRStreamErrorReporter(onError: (error: unknown) => void): (error: unknown) => void;
24
+ /** Observe the delivered body, rather than declaring completion at allReady. */
25
+ export declare function observeSSRStream(source: ReadableStream<Uint8Array>, options: {
26
+ lifecycle: ReturnType<typeof createSSRRenderLifecycle>;
27
+ onError: (error: unknown) => void | Promise<void>;
28
+ signal: AbortSignal;
29
+ onCancel?: (reason: unknown) => void | Promise<void>;
30
+ onComplete?: () => void | Promise<void>;
31
+ }): ReadableStream<Uint8Array>;
@@ -1,7 +1,7 @@
1
1
  import { type RenderLevel } from '../../constants.js';
2
2
  import type { TInternalRuntimeContext } from '../../context/index.js';
3
3
  import type { HandleRequestConfig } from '../requestHandler.js';
4
- import { type SSRConfig } from '../shared.js';
4
+ import { type createSSRRenderLifecycle, type SSRConfig } from '../shared.js';
5
5
  export type BuildShellAfterTemplateOptions = {
6
6
  runtimeContext: TInternalRuntimeContext;
7
7
  renderLevel: RenderLevel;
@@ -9,5 +9,6 @@ export type BuildShellAfterTemplateOptions = {
9
9
  request: Request;
10
10
  entryName: string;
11
11
  config: HandleRequestConfig;
12
+ lifecycle?: ReturnType<typeof createSSRRenderLifecycle>;
12
13
  };
13
14
  export declare function buildShellAfterTemplate(afterAppTemplate: string, options: BuildShellAfterTemplateOptions): Promise<string>;
@@ -1,10 +1,13 @@
1
+ import type { SSRHeadData } from '@modern-js/plugin/runtime';
1
2
  import type { TInternalRuntimeContext } from '../../context/index.js';
2
3
  import type { HandleRequestConfig } from '../requestHandler.js';
4
+ import { type createSSRRenderLifecycle } from '../shared.js';
3
5
  export interface BuildShellBeforeTemplateOptions {
4
6
  runtimeContext: TInternalRuntimeContext;
5
7
  entryName: string;
6
8
  config: HandleRequestConfig;
7
9
  styledComponentsStyleTags?: string;
8
- moduleFederationCssAssets?: string[];
10
+ lifecycle?: ReturnType<typeof createSSRRenderLifecycle>;
11
+ helmetData?: SSRHeadData;
9
12
  }
10
13
  export declare function buildShellBeforeTemplate(beforeAppTemplate: string, options: BuildShellBeforeTemplateOptions): Promise<string>;
@@ -1,10 +1,13 @@
1
+ import type { SSRHeadData } from '@modern-js/plugin/runtime';
1
2
  import type { TInternalRuntimeContext } from '../../context/index.js';
2
3
  import type { HandleRequestConfig } from '../requestHandler.js';
4
+ import { type createSSRRenderLifecycle } from '../shared.js';
3
5
  export interface BuildShellBeforeTemplateOptions {
4
6
  runtimeContext: TInternalRuntimeContext;
5
7
  entryName: string;
6
8
  config: HandleRequestConfig;
7
9
  styledComponentsStyleTags?: string;
8
- moduleFederationCssAssets?: string[];
10
+ lifecycle?: ReturnType<typeof createSSRRenderLifecycle>;
11
+ helmetData?: SSRHeadData;
9
12
  }
10
13
  export declare function buildShellBeforeTemplate(beforeAppTemplate: string, options: BuildShellBeforeTemplateOptions): Promise<string>;