@bleedingdev/modern-js-runtime 3.2.0-ultramodern.11 → 3.2.0-ultramodern.110
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.
- package/dist/cjs/boundary-debugger/index.js +303 -0
- package/dist/cjs/cache/index.js +9 -5
- package/dist/cjs/cli/alias.js +9 -5
- package/dist/cjs/cli/code.js +9 -5
- package/dist/cjs/cli/constants.js +20 -16
- package/dist/cjs/cli/entry.js +9 -5
- package/dist/cjs/cli/index.js +9 -5
- package/dist/cjs/cli/ssr/index.js +14 -20
- package/dist/cjs/cli/ssr/loadable-bundler-plugin.js +9 -5
- package/dist/cjs/cli/ssr/mode.js +12 -8
- package/dist/cjs/cli/template.js +9 -5
- package/dist/cjs/cli/template.server.js +10 -5
- package/dist/cjs/common.js +14 -10
- package/dist/cjs/core/browser/hydrate.js +9 -5
- package/dist/cjs/core/browser/index.js +9 -5
- package/dist/cjs/core/browser/withCallback.js +9 -5
- package/dist/cjs/core/compat/hooks.js +14 -10
- package/dist/cjs/core/compat/index.js +9 -5
- package/dist/cjs/core/compat/requestContext.js +13 -9
- package/dist/cjs/core/config.js +12 -8
- package/dist/cjs/core/constants.js +15 -10
- package/dist/cjs/core/context/index.js +9 -5
- package/dist/cjs/core/context/monitors/default.js +12 -8
- package/dist/cjs/core/context/monitors/index.js +9 -5
- package/dist/cjs/core/context/monitors/index.server.js +9 -5
- package/dist/cjs/core/context/request/index.js +12 -8
- package/dist/cjs/core/context/request/index.server.js +9 -5
- package/dist/cjs/core/context/response/index.js +15 -11
- package/dist/cjs/core/context/response/index.server.js +9 -5
- package/dist/cjs/core/context/runtime.js +9 -5
- package/dist/cjs/core/context/serverPayload/index.js +13 -9
- package/dist/cjs/core/context/serverPayload/index.server.js +9 -5
- package/dist/cjs/core/index.js +9 -5
- package/dist/cjs/core/plugin/index.js +9 -5
- package/dist/cjs/core/react/index.js +9 -5
- package/dist/cjs/core/react/wrapper.js +18 -8
- package/dist/cjs/core/server/constants.js +15 -11
- package/dist/cjs/core/server/federatedCss.js +51 -0
- package/dist/cjs/core/server/helmet.js +17 -7
- package/dist/cjs/core/server/index.js +9 -5
- package/dist/cjs/core/server/react/index.js +9 -5
- package/dist/cjs/core/server/react/no-ssr-cache/index.js +9 -5
- package/dist/cjs/core/server/react/nossr/index.js +9 -5
- package/dist/cjs/core/server/requestHandler.js +9 -5
- package/dist/cjs/core/server/scriptOrder.js +63 -0
- package/dist/cjs/core/server/server.js +9 -5
- package/dist/cjs/core/server/shared.js +12 -8
- package/dist/cjs/core/server/stream/afterTemplate.js +22 -10
- package/dist/cjs/core/server/stream/beforeTemplate.js +22 -25
- package/dist/cjs/core/server/stream/beforeTemplate.worker.js +102 -0
- package/dist/cjs/core/server/stream/createReadableStream.js +16 -7
- package/dist/cjs/core/server/stream/createReadableStream.worker.js +13 -7
- package/dist/cjs/core/server/stream/deferredScript.js +9 -5
- package/dist/cjs/core/server/stream/index.js +9 -5
- package/dist/cjs/core/server/stream/shared.js +12 -6
- package/dist/cjs/core/server/stream/template.js +9 -5
- package/dist/cjs/core/server/string/index.js +25 -14
- package/dist/cjs/core/server/string/loadable.js +83 -15
- package/dist/cjs/core/server/string/ssrData.js +9 -5
- package/dist/cjs/core/server/tracer.js +13 -9
- package/dist/cjs/core/server/utils.js +9 -5
- package/dist/cjs/document/Body.js +9 -5
- package/dist/cjs/document/Comment.js +9 -5
- package/dist/cjs/document/DocumentContext.js +9 -5
- package/dist/cjs/document/DocumentStructureContext.js +9 -5
- package/dist/cjs/document/Head.js +9 -5
- package/dist/cjs/document/Html.js +9 -5
- package/dist/cjs/document/Links.js +9 -5
- package/dist/cjs/document/Root.js +9 -5
- package/dist/cjs/document/Script.js +9 -5
- package/dist/cjs/document/Scripts.js +9 -5
- package/dist/cjs/document/Style.js +9 -5
- package/dist/cjs/document/Title.js +9 -5
- package/dist/cjs/document/cli/index.js +12 -6
- package/dist/cjs/document/constants.js +9 -5
- package/dist/cjs/document/index.js +9 -5
- package/dist/cjs/exports/config-routes.js +12 -8
- package/dist/cjs/exports/head.js +209 -10
- package/dist/cjs/exports/loadable.js +51 -12
- package/dist/cjs/exports/tanstack-router.js +320 -59
- package/dist/cjs/index.js +9 -5
- package/dist/cjs/internal.js +9 -5
- package/dist/cjs/react-server.js +9 -5
- package/dist/cjs/router/cli/code/getClientRoutes/getRoutes.js +9 -5
- package/dist/cjs/router/cli/code/getClientRoutes/index.js +9 -5
- package/dist/cjs/router/cli/code/getClientRoutes/utils.js +9 -5
- package/dist/cjs/router/cli/code/index.js +9 -5
- package/dist/cjs/router/cli/code/inspect.js +9 -5
- package/dist/cjs/router/cli/code/makeLegalIdentifier.js +12 -8
- package/dist/cjs/router/cli/code/nestedRoutes.js +9 -5
- package/dist/cjs/router/cli/code/tanstackTypes.js +125 -56
- package/dist/cjs/router/cli/code/templates.js +24 -14
- package/dist/cjs/router/cli/code/utils.js +9 -5
- package/dist/cjs/router/cli/config-routes/converter.js +9 -5
- package/dist/cjs/router/cli/config-routes/parseRouteConfig.js +9 -5
- package/dist/cjs/router/cli/constants.js +23 -19
- package/dist/cjs/router/cli/entry.js +9 -5
- package/dist/cjs/router/cli/handler.js +9 -5
- package/dist/cjs/router/cli/index.js +9 -5
- package/dist/cjs/router/index.js +9 -5
- package/dist/cjs/router/internal.js +12 -8
- package/dist/cjs/router/runtime/CSSLinks.js +9 -5
- package/dist/cjs/router/runtime/DefaultNotFound.js +9 -5
- package/dist/cjs/router/runtime/DeferredDataScripts.js +12 -8
- package/dist/cjs/router/runtime/DeferredDataScripts.node.js +9 -5
- package/dist/cjs/router/runtime/PrefetchLink.js +162 -26
- package/dist/cjs/router/runtime/constants.js +9 -5
- package/dist/cjs/router/runtime/hooks.js +9 -5
- package/dist/cjs/router/runtime/index.js +15 -10
- package/dist/cjs/router/runtime/internal.js +9 -5
- package/dist/cjs/router/runtime/lifecycle.js +18 -14
- package/dist/cjs/router/runtime/plugin.js +9 -5
- package/dist/cjs/router/runtime/plugin.node.js +9 -5
- package/dist/cjs/router/runtime/routerHelper.js +9 -5
- package/dist/cjs/router/runtime/rsc-router.js +9 -5
- package/dist/cjs/router/runtime/rsc.js +9 -5
- package/dist/cjs/router/runtime/server.js +9 -5
- package/dist/cjs/router/runtime/tanstack/basepathRewrite.js +12 -8
- package/dist/cjs/router/runtime/tanstack/dataMutation.js +9 -5
- package/dist/cjs/router/runtime/tanstack/hydrationBoundary.js +48 -0
- package/dist/cjs/router/runtime/tanstack/outlet.js +58 -0
- package/dist/cjs/router/runtime/tanstack/plugin.js +199 -96
- package/dist/cjs/router/runtime/tanstack/plugin.node.js +13 -19
- package/dist/cjs/router/runtime/tanstack/prefetchLink.js +10 -6
- package/dist/cjs/router/runtime/tanstack/routeTree.js +73 -17
- package/dist/cjs/router/runtime/tanstack/rsc/ClientSlot.js +9 -5
- package/dist/cjs/router/runtime/tanstack/rsc/CompositeComponent.js +9 -5
- package/dist/cjs/router/runtime/tanstack/rsc/ReplayableStream.js +14 -9
- package/dist/cjs/router/runtime/tanstack/rsc/RscNodeRenderer.js +9 -5
- package/dist/cjs/router/runtime/tanstack/rsc/SlotContext.js +9 -5
- package/dist/cjs/router/runtime/tanstack/rsc/client.js +9 -5
- package/dist/cjs/router/runtime/tanstack/rsc/createRscProxy.js +9 -5
- package/dist/cjs/router/runtime/tanstack/rsc/index.js +9 -5
- package/dist/cjs/router/runtime/tanstack/rsc/server.js +9 -5
- package/dist/cjs/router/runtime/tanstack/rsc/slotUsageSanitizer.js +9 -5
- package/dist/cjs/router/runtime/tanstack/rsc/symbols.js +20 -15
- package/dist/cjs/router/runtime/utils.js +9 -5
- package/dist/cjs/router/runtime/withRouter.js +9 -5
- package/dist/cjs/rsc/client.js +12 -8
- package/dist/cjs/rsc/server.js +9 -5
- package/dist/cjs/rsc/server.worker.js +62 -0
- package/dist/cjs/ssr/index.node.js +13 -9
- package/dist/cjs/ssr/serverRender/renderToStream/buildTemplate.after.js +9 -5
- package/dist/cjs/ssr/serverRender/renderToString/entry.js +18 -13
- package/dist/cjs/ssr/serverRender/types.js +9 -5
- package/dist/esm/boundary-debugger/index.mjs +263 -0
- package/dist/esm/cli/ssr/index.mjs +5 -15
- package/dist/esm/cli/template.server.mjs +1 -0
- package/dist/esm/core/react/wrapper.mjs +9 -3
- package/dist/esm/core/server/federatedCss.mjs +13 -0
- package/dist/esm/core/server/helmet.mjs +5 -2
- package/dist/esm/core/server/scriptOrder.mjs +25 -0
- package/dist/esm/core/server/stream/afterTemplate.mjs +14 -6
- package/dist/esm/core/server/stream/beforeTemplate.mjs +14 -11
- package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +64 -0
- package/dist/esm/core/server/stream/createReadableStream.mjs +7 -2
- package/dist/esm/core/server/stream/createReadableStream.worker.mjs +4 -2
- package/dist/esm/core/server/stream/shared.mjs +3 -1
- package/dist/esm/core/server/string/index.mjs +17 -9
- package/dist/esm/core/server/string/loadable.mjs +70 -9
- package/dist/esm/document/cli/index.mjs +3 -1
- package/dist/esm/exports/head.mjs +193 -4
- package/dist/esm/exports/loadable.mjs +26 -3
- package/dist/esm/exports/tanstack-router.mjs +2 -1
- package/dist/esm/router/cli/code/tanstackTypes.mjs +116 -51
- package/dist/esm/router/cli/code/templates.mjs +15 -9
- package/dist/esm/router/runtime/PrefetchLink.mjs +153 -21
- package/dist/esm/router/runtime/tanstack/hydrationBoundary.mjs +10 -0
- package/dist/esm/router/runtime/tanstack/outlet.mjs +17 -0
- package/dist/esm/router/runtime/tanstack/plugin.mjs +193 -94
- package/dist/esm/router/runtime/tanstack/plugin.node.mjs +5 -15
- package/dist/esm/router/runtime/tanstack/prefetchLink.mjs +1 -1
- package/dist/esm/router/runtime/tanstack/routeTree.mjs +65 -13
- package/dist/esm/rsc/server.worker.mjs +1 -0
- package/dist/esm/ssr/serverRender/renderToString/entry.mjs +9 -6
- package/dist/esm-node/boundary-debugger/index.mjs +264 -0
- package/dist/esm-node/cli/ssr/index.mjs +5 -15
- package/dist/esm-node/cli/template.server.mjs +1 -0
- package/dist/esm-node/core/react/wrapper.mjs +9 -3
- package/dist/esm-node/core/server/federatedCss.mjs +14 -0
- package/dist/esm-node/core/server/helmet.mjs +5 -2
- package/dist/esm-node/core/server/scriptOrder.mjs +26 -0
- package/dist/esm-node/core/server/stream/afterTemplate.mjs +14 -6
- package/dist/esm-node/core/server/stream/beforeTemplate.mjs +14 -11
- package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +65 -0
- package/dist/esm-node/core/server/stream/createReadableStream.mjs +7 -2
- package/dist/esm-node/core/server/stream/createReadableStream.worker.mjs +4 -2
- package/dist/esm-node/core/server/stream/shared.mjs +3 -1
- package/dist/esm-node/core/server/string/index.mjs +17 -9
- package/dist/esm-node/core/server/string/loadable.mjs +70 -9
- package/dist/esm-node/document/cli/index.mjs +3 -1
- package/dist/esm-node/exports/head.mjs +193 -4
- package/dist/esm-node/exports/loadable.mjs +26 -3
- package/dist/esm-node/exports/tanstack-router.mjs +2 -1
- package/dist/esm-node/router/cli/code/tanstackTypes.mjs +116 -51
- package/dist/esm-node/router/cli/code/templates.mjs +15 -9
- package/dist/esm-node/router/runtime/PrefetchLink.mjs +153 -21
- package/dist/esm-node/router/runtime/tanstack/hydrationBoundary.mjs +11 -0
- package/dist/esm-node/router/runtime/tanstack/outlet.mjs +18 -0
- package/dist/esm-node/router/runtime/tanstack/plugin.mjs +193 -94
- package/dist/esm-node/router/runtime/tanstack/plugin.node.mjs +5 -15
- package/dist/esm-node/router/runtime/tanstack/prefetchLink.mjs +1 -1
- package/dist/esm-node/router/runtime/tanstack/routeTree.mjs +65 -13
- package/dist/esm-node/rsc/server.worker.mjs +2 -0
- package/dist/esm-node/ssr/serverRender/renderToString/entry.mjs +9 -6
- package/dist/types/boundary-debugger/index.d.ts +28 -0
- package/dist/types/cli/entry.d.ts +2 -2
- package/dist/types/core/context/response/index.server.d.ts +4 -1
- package/dist/types/core/context/runtime.d.ts +4 -0
- package/dist/types/core/plugin/index.d.ts +1 -1
- package/dist/types/core/server/federatedCss.d.ts +5 -0
- package/dist/types/core/server/helmet.d.ts +5 -3
- package/dist/types/core/server/scriptOrder.d.ts +1 -0
- package/dist/types/core/server/stream/beforeTemplate.d.ts +1 -0
- package/dist/types/core/server/stream/beforeTemplate.worker.d.ts +10 -0
- package/dist/types/core/server/stream/shared.d.ts +8 -0
- package/dist/types/core/server/string/loadable.d.ts +11 -0
- package/dist/types/core/server/utils.d.ts +11 -1
- package/dist/types/document/constants.d.ts +3 -1
- package/dist/types/exports/head.d.ts +10 -3
- package/dist/types/exports/loadable.d.ts +8 -1
- package/dist/types/exports/tanstack-router.d.ts +3 -1
- package/dist/types/router/cli/code/utils.d.ts +1 -1
- package/dist/types/router/cli/entry.d.ts +1 -1
- package/dist/types/router/runtime/PrefetchLink.d.ts +5 -1
- package/dist/types/router/runtime/tanstack/hydrationBoundary.d.ts +2 -0
- package/dist/types/router/runtime/tanstack/outlet.d.ts +2 -0
- package/dist/types/rsc/server.worker.d.ts +1 -0
- package/package.json +31 -25
|
@@ -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
|
-
|
|
15
|
-
|
|
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)
|
|
96
|
+
if ('intent' === prefetch || 'intent' === preload) setMaybeWarmup(true);
|
|
25
97
|
};
|
|
26
98
|
const cancelIntent = ()=>{
|
|
27
|
-
if ('intent' === prefetch) {
|
|
28
|
-
|
|
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 (
|
|
106
|
+
if (maybeWarmup) {
|
|
34
107
|
const id = setTimeout(()=>{
|
|
35
|
-
setShouldPrefetch(true);
|
|
36
|
-
|
|
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
|
-
|
|
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
|
|
93
|
-
|
|
94
|
-
|
|
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
|
|
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
|
|
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:
|
|
271
|
+
ref: setAnchorRef,
|
|
141
272
|
to: to,
|
|
142
273
|
...props,
|
|
143
274
|
...prefetchHandlers
|
|
144
275
|
}),
|
|
145
|
-
shouldPrefetch
|
|
146
|
-
path: resolvedPath
|
|
276
|
+
(shouldPrefetch || shouldPreload) && !isAbsolute ? /*#__PURE__*/ jsx(PrefetchPageLinks, {
|
|
277
|
+
path: resolvedPath,
|
|
278
|
+
includeData: shouldPrefetch
|
|
147
279
|
}) : null
|
|
148
280
|
]
|
|
149
281
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Suspense } from "react";
|
|
4
|
+
function wrapTanstackSsrHydrationBoundary(routerContent, shouldWrap) {
|
|
5
|
+
if (shouldWrap) return /*#__PURE__*/ jsx(Suspense, {
|
|
6
|
+
fallback: null,
|
|
7
|
+
children: routerContent
|
|
8
|
+
});
|
|
9
|
+
return routerContent;
|
|
10
|
+
}
|
|
11
|
+
export { wrapTanstackSsrHydrationBoundary };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Outlet } from "@tanstack/react-router";
|
|
4
|
+
import { createElement, memo } from "react";
|
|
5
|
+
const outlet_Outlet = /*#__PURE__*/ memo(function() {
|
|
6
|
+
return /*#__PURE__*/ jsx(Outlet, {});
|
|
7
|
+
});
|
|
8
|
+
function withModernRouteMatchContext(component, _routeId) {
|
|
9
|
+
if (null == component) return component;
|
|
10
|
+
const Component = component;
|
|
11
|
+
const WrappedRouteComponent = (props)=>/*#__PURE__*/ createElement(Component, props);
|
|
12
|
+
const preloadable = component;
|
|
13
|
+
if ('function' == typeof preloadable.load) WrappedRouteComponent.load = preloadable.load.bind(preloadable);
|
|
14
|
+
if ('function' == typeof preloadable.preload) WrappedRouteComponent.preload = preloadable.preload.bind(preloadable);
|
|
15
|
+
else if ('function' == typeof preloadable.load) WrappedRouteComponent.preload = WrappedRouteComponent.load;
|
|
16
|
+
return WrappedRouteComponent;
|
|
17
|
+
}
|
|
18
|
+
export { outlet_Outlet as Outlet, withModernRouteMatchContext };
|
|
@@ -3,15 +3,18 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { merge } from "@modern-js/runtime-utils/merge";
|
|
4
4
|
import { normalizePathname } from "@modern-js/runtime-utils/url";
|
|
5
5
|
import { RouterProvider, createBrowserHistory, createHashHistory, createRouter, useLocation, useMatches, useNavigate, useRouter } from "@tanstack/react-router";
|
|
6
|
-
import {
|
|
6
|
+
import { hydrate } from "@tanstack/react-router/ssr/client";
|
|
7
|
+
import { useContext, useMemo } from "react";
|
|
7
8
|
import { InternalRuntimeContext, getGlobalEnableRsc, getGlobalLayoutApp, getGlobalRoutes } from "../../../core/context/index.mjs";
|
|
8
9
|
import { onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeHydrateRouter } from "../hooks.mjs";
|
|
9
10
|
import { applyRouterRuntimeState } from "../lifecycle.mjs";
|
|
10
11
|
import { createRouteObjectsFromConfig, urlJoin } from "../utils.mjs";
|
|
11
12
|
import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
|
|
13
|
+
import { wrapTanstackSsrHydrationBoundary } from "./hydrationBoundary.mjs";
|
|
14
|
+
import { withModernRouteMatchContext } from "./outlet.mjs";
|
|
15
|
+
import { Link } from "./prefetchLink.mjs";
|
|
12
16
|
import { createRouteTreeFromRouteObjects } from "./routeTree.mjs";
|
|
13
17
|
import { getTanstackRscSerializationAdapters } from "./rsc/client.mjs";
|
|
14
|
-
import * as __rspack_external_react from "react";
|
|
15
18
|
const BLOCKING_SUBSCRIBE_SYMBOL = Symbol.for('@modern-js/plugin-runtime:tanstack-blocking-subscribe');
|
|
16
19
|
const BLOCKING_STATE_SYMBOL = Symbol.for('@modern-js/plugin-runtime:tanstack-blocking-state');
|
|
17
20
|
function normalizeBase(b) {
|
|
@@ -39,6 +42,82 @@ function wrapRouterSubscribeWithBlockState(router, getBlockNavState) {
|
|
|
39
42
|
};
|
|
40
43
|
target[BLOCKING_SUBSCRIBE_SYMBOL] = true;
|
|
41
44
|
}
|
|
45
|
+
const routerHydrationRecords = new WeakMap();
|
|
46
|
+
const routeModulesKey = '_routeModules';
|
|
47
|
+
function pickRouteModuleComponent(routeModule, seen = new Set()) {
|
|
48
|
+
if ('function' == typeof routeModule || routeModule && 'object' == typeof routeModule && '$$typeof' in routeModule) return routeModule;
|
|
49
|
+
if (!routeModule || 'object' != typeof routeModule) return;
|
|
50
|
+
if (seen.has(routeModule)) return;
|
|
51
|
+
seen.add(routeModule);
|
|
52
|
+
const module = routeModule;
|
|
53
|
+
for (const candidate of [
|
|
54
|
+
module.default,
|
|
55
|
+
module.Component
|
|
56
|
+
]){
|
|
57
|
+
const component = pickRouteModuleComponent(candidate, seen);
|
|
58
|
+
if (component) return component;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function getCachedRouteModule(routeId) {
|
|
62
|
+
if ("u" < typeof window) return;
|
|
63
|
+
return window[routeModulesKey]?.[routeId];
|
|
64
|
+
}
|
|
65
|
+
function preloadHydratedRouteComponents(router) {
|
|
66
|
+
const preloadableRouter = router;
|
|
67
|
+
const routesById = preloadableRouter.routesById || {};
|
|
68
|
+
const matches = preloadableRouter.stores.matches.get();
|
|
69
|
+
return Promise.all(matches.map((match)=>{
|
|
70
|
+
if (void 0 === match.routeId || '' === match.routeId) return;
|
|
71
|
+
const route = routesById[match.routeId];
|
|
72
|
+
const component = route?.options?.component;
|
|
73
|
+
const preload = component?.load || component?.preload;
|
|
74
|
+
if ('function' != typeof preload) return;
|
|
75
|
+
return Promise.resolve(preload.call(component)).then((routeModule)=>{
|
|
76
|
+
const modernRouteId = route?.options?.staticData?.modernRouteId;
|
|
77
|
+
const cachedRouteModule = 'string' == typeof modernRouteId && '' !== modernRouteId ? getCachedRouteModule(modernRouteId) : void 0;
|
|
78
|
+
const resolvedComponent = pickRouteModuleComponent(cachedRouteModule ?? routeModule);
|
|
79
|
+
if (void 0 !== resolvedComponent && 'string' == typeof modernRouteId && '' !== modernRouteId) route.options.component = withModernRouteMatchContext(resolvedComponent, modernRouteId);
|
|
80
|
+
});
|
|
81
|
+
})).then(()=>void 0);
|
|
82
|
+
}
|
|
83
|
+
function getTanstackSsrHydrationRecord(router) {
|
|
84
|
+
const existingHydrationRecord = routerHydrationRecords.get(router);
|
|
85
|
+
if (void 0 !== existingHydrationRecord) return existingHydrationRecord;
|
|
86
|
+
const hydrationRecord = {
|
|
87
|
+
promise: Promise.resolve(),
|
|
88
|
+
status: 'pending'
|
|
89
|
+
};
|
|
90
|
+
routerHydrationRecords.set(router, hydrationRecord);
|
|
91
|
+
try {
|
|
92
|
+
hydrationRecord.promise = hydrate(router).then((value)=>preloadHydratedRouteComponents(router).then(()=>value)).then((value)=>{
|
|
93
|
+
hydrationRecord.status = 'fulfilled';
|
|
94
|
+
return value;
|
|
95
|
+
}, (error)=>{
|
|
96
|
+
hydrationRecord.status = 'rejected';
|
|
97
|
+
hydrationRecord.error = error;
|
|
98
|
+
throw error;
|
|
99
|
+
});
|
|
100
|
+
} catch (error) {
|
|
101
|
+
hydrationRecord.status = 'rejected';
|
|
102
|
+
hydrationRecord.error = error;
|
|
103
|
+
hydrationRecord.promise = Promise.reject(error);
|
|
104
|
+
hydrationRecord.promise.catch(()=>{});
|
|
105
|
+
}
|
|
106
|
+
return hydrationRecord;
|
|
107
|
+
}
|
|
108
|
+
function getTanstackSsrHydrationPromise(router) {
|
|
109
|
+
return getTanstackSsrHydrationRecord(router).promise;
|
|
110
|
+
}
|
|
111
|
+
function hasTanstackSsrHydrationRecord(router) {
|
|
112
|
+
return routerHydrationRecords.has(router);
|
|
113
|
+
}
|
|
114
|
+
function ModernRouterClient({ router }) {
|
|
115
|
+
const hydrationRecord = getTanstackSsrHydrationRecord(router);
|
|
116
|
+
if ('rejected' === hydrationRecord.status) throw hydrationRecord.error;
|
|
117
|
+
return /*#__PURE__*/ jsx(RouterProvider, {
|
|
118
|
+
router: router
|
|
119
|
+
});
|
|
120
|
+
}
|
|
42
121
|
function stripSyntheticNotFoundRoute(routes) {
|
|
43
122
|
return routes.filter((route)=>!('*' === route.path && !route.id && !route.loader)).map((route)=>{
|
|
44
123
|
if (!route.children?.length) return route;
|
|
@@ -57,110 +136,131 @@ const tanstackRouterPlugin = (userConfig = {})=>({
|
|
|
57
136
|
onBeforeHydrateRouter: onBeforeHydrateRouter
|
|
58
137
|
},
|
|
59
138
|
setup: (api)=>{
|
|
60
|
-
api.
|
|
139
|
+
const hooks = api.getHooks();
|
|
140
|
+
let cachedRouteObjects;
|
|
141
|
+
let cachedRouteTree = null;
|
|
142
|
+
let cachedRouter = null;
|
|
143
|
+
let cachedRouterBasepath = null;
|
|
144
|
+
const getMergedConfig = ()=>{
|
|
61
145
|
const pluginConfig = api.getRuntimeConfig();
|
|
62
|
-
|
|
63
|
-
|
|
146
|
+
return merge(pluginConfig.router || {}, userConfig);
|
|
147
|
+
};
|
|
148
|
+
const getRouteObjects = ()=>{
|
|
149
|
+
if (void 0 !== cachedRouteObjects) return cachedRouteObjects;
|
|
150
|
+
const mergedConfig = getMergedConfig();
|
|
151
|
+
const { routesConfig, createRoutes } = mergedConfig;
|
|
152
|
+
const finalRouteConfig = {
|
|
153
|
+
routes: getGlobalRoutes(),
|
|
154
|
+
globalApp: getGlobalLayoutApp(),
|
|
155
|
+
...routesConfig
|
|
156
|
+
};
|
|
157
|
+
const routeObjects = createRoutes ? createRoutes() : createRouteObjectsFromConfig({
|
|
158
|
+
routesConfig: finalRouteConfig
|
|
159
|
+
}) || [];
|
|
160
|
+
const normalizedRouteObjects = createRoutes ? routeObjects : stripSyntheticNotFoundRoute(routeObjects);
|
|
161
|
+
cachedRouteObjects = hooks.modifyRoutes.call(normalizedRouteObjects);
|
|
162
|
+
return cachedRouteObjects;
|
|
163
|
+
};
|
|
164
|
+
const getRouteTree = ()=>{
|
|
165
|
+
if (cachedRouteTree) return cachedRouteTree;
|
|
166
|
+
const routeObjects = getRouteObjects();
|
|
167
|
+
if (!routeObjects.length) return null;
|
|
168
|
+
cachedRouteTree = createRouteTreeFromRouteObjects(routeObjects);
|
|
169
|
+
return cachedRouteTree;
|
|
170
|
+
};
|
|
171
|
+
const selectBasePath = (pathname)=>{
|
|
172
|
+
const { serverBase = [] } = getMergedConfig();
|
|
173
|
+
const match = serverBase.find((baseUrl)=>isSegmentPrefix(pathname, baseUrl));
|
|
174
|
+
return match || '/';
|
|
175
|
+
};
|
|
176
|
+
const getClientBasename = (runtimeContext)=>{
|
|
177
|
+
const { basename = '' } = getMergedConfig();
|
|
178
|
+
const baseUrl = selectBasePath(location.pathname).replace(/^\/*/, '/');
|
|
179
|
+
return '/' === baseUrl ? urlJoin(baseUrl, runtimeContext._internalRouterBaseName || basename || '') : baseUrl;
|
|
180
|
+
};
|
|
181
|
+
const getRouter = (runtimeContext, _basename)=>{
|
|
182
|
+
const routeTree = getRouteTree();
|
|
183
|
+
if (!routeTree) return null;
|
|
184
|
+
const lifecycleContext = {
|
|
185
|
+
framework: 'tanstack',
|
|
186
|
+
phase: 'client-create',
|
|
187
|
+
routes: getRouteObjects(),
|
|
188
|
+
runtimeContext,
|
|
189
|
+
basename: _basename
|
|
190
|
+
};
|
|
191
|
+
hooks.onBeforeCreateRouter.call(lifecycleContext);
|
|
192
|
+
if (cachedRouter && cachedRouterBasepath === _basename) {
|
|
193
|
+
wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
|
|
194
|
+
hooks.onAfterCreateRouter.call({
|
|
195
|
+
...lifecycleContext,
|
|
196
|
+
router: cachedRouter,
|
|
197
|
+
runtimeContext
|
|
198
|
+
});
|
|
199
|
+
return cachedRouter;
|
|
200
|
+
}
|
|
201
|
+
const mergedConfig = getMergedConfig();
|
|
202
|
+
const { supportHtml5History = true } = mergedConfig;
|
|
203
|
+
const history = supportHtml5History ? createBrowserHistory() : createHashHistory();
|
|
204
|
+
const rewrite = createModernBasepathRewrite(_basename);
|
|
205
|
+
const serializationAdapters = getGlobalEnableRsc() ? getTanstackRscSerializationAdapters() : void 0;
|
|
206
|
+
cachedRouter = createRouter({
|
|
207
|
+
routeTree,
|
|
208
|
+
basepath: '/',
|
|
209
|
+
rewrite,
|
|
210
|
+
history,
|
|
211
|
+
context: {},
|
|
212
|
+
...serializationAdapters ? {
|
|
213
|
+
serializationAdapters
|
|
214
|
+
} : {}
|
|
215
|
+
});
|
|
216
|
+
cachedRouterBasepath = _basename;
|
|
217
|
+
wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
|
|
218
|
+
hooks.onAfterCreateRouter.call({
|
|
219
|
+
...lifecycleContext,
|
|
220
|
+
router: cachedRouter,
|
|
221
|
+
runtimeContext
|
|
222
|
+
});
|
|
223
|
+
return cachedRouter;
|
|
224
|
+
};
|
|
225
|
+
api.onBeforeRender((context)=>{
|
|
226
|
+
const mergedConfig = getMergedConfig();
|
|
227
|
+
if ("u" > typeof window && void 0 !== window._SSR_DATA && mergedConfig.unstable_reloadOnURLMismatch) {
|
|
64
228
|
const { ssrContext } = context;
|
|
65
229
|
const currentPathname = normalizePathname(window.location.pathname);
|
|
66
|
-
const initialPathname = ssrContext?.request?.pathname
|
|
67
|
-
if (initialPathname && initialPathname !== currentPathname) {
|
|
230
|
+
const initialPathname = 'string' == typeof ssrContext?.request?.pathname ? normalizePathname(ssrContext.request.pathname) : void 0;
|
|
231
|
+
if (void 0 !== initialPathname && '' !== initialPathname && initialPathname !== currentPathname) {
|
|
68
232
|
const errorMsg = `The initial URL ${initialPathname} and the URL ${currentPathname} to be hydrated do not match, reload.`;
|
|
69
233
|
console.error(errorMsg);
|
|
70
234
|
window.location.reload();
|
|
71
235
|
}
|
|
72
236
|
}
|
|
73
237
|
context.router = {
|
|
238
|
+
Link: Link,
|
|
74
239
|
useMatches: useMatches,
|
|
75
240
|
useLocation: useLocation,
|
|
76
241
|
useNavigate: useNavigate,
|
|
77
242
|
useRouter: useRouter
|
|
78
243
|
};
|
|
244
|
+
const hasSSRBootstrap = "u" > typeof window && Boolean(window.$_TSR);
|
|
245
|
+
if (hasSSRBootstrap && getRouteObjects().length > 0) {
|
|
246
|
+
const runtimeContext = context;
|
|
247
|
+
const router = getRouter(runtimeContext, getClientBasename(runtimeContext));
|
|
248
|
+
if (null != router) return getTanstackSsrHydrationPromise(router).then(()=>void 0);
|
|
249
|
+
}
|
|
79
250
|
});
|
|
80
251
|
api.wrapRoot((App)=>{
|
|
81
|
-
|
|
82
|
-
const { serverBase = [], supportHtml5History = true, basename = '', routesConfig, createRoutes } = mergedConfig;
|
|
83
|
-
const finalRouteConfig = {
|
|
84
|
-
routes: getGlobalRoutes(),
|
|
85
|
-
globalApp: getGlobalLayoutApp(),
|
|
86
|
-
...routesConfig
|
|
87
|
-
};
|
|
88
|
-
if (!finalRouteConfig.routes && !createRoutes) return App;
|
|
89
|
-
const hooks = api.getHooks();
|
|
90
|
-
let cachedRouteObjects;
|
|
91
|
-
const getRouteObjects = ()=>{
|
|
92
|
-
if (void 0 !== cachedRouteObjects) return cachedRouteObjects;
|
|
93
|
-
const routeObjects = createRoutes ? createRoutes() : createRouteObjectsFromConfig({
|
|
94
|
-
routesConfig: finalRouteConfig
|
|
95
|
-
}) || [];
|
|
96
|
-
const normalizedRouteObjects = createRoutes ? routeObjects : stripSyntheticNotFoundRoute(routeObjects);
|
|
97
|
-
cachedRouteObjects = hooks.modifyRoutes.call(normalizedRouteObjects);
|
|
98
|
-
return cachedRouteObjects;
|
|
99
|
-
};
|
|
100
|
-
const selectBasePath = (pathname)=>{
|
|
101
|
-
const match = serverBase.find((baseUrl)=>isSegmentPrefix(pathname, baseUrl));
|
|
102
|
-
return match || '/';
|
|
103
|
-
};
|
|
104
|
-
let cachedRouteTree = null;
|
|
105
|
-
let cachedRouter = null;
|
|
106
|
-
let cachedRouterBasepath = null;
|
|
252
|
+
if (0 === getRouteObjects().length) return App;
|
|
107
253
|
const RouterWrapper = ()=>{
|
|
108
|
-
const runtimeContext =
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
const routeTree = (0, __rspack_external_react.useMemo)(()=>{
|
|
112
|
-
if (cachedRouteTree) return cachedRouteTree;
|
|
113
|
-
const routeObjects = getRouteObjects();
|
|
114
|
-
if (!routeObjects.length) return null;
|
|
115
|
-
cachedRouteTree = createRouteTreeFromRouteObjects(routeObjects);
|
|
116
|
-
return cachedRouteTree;
|
|
117
|
-
}, []);
|
|
254
|
+
const runtimeContext = useContext(InternalRuntimeContext);
|
|
255
|
+
const _basename = getClientBasename(runtimeContext);
|
|
256
|
+
const routeTree = useMemo(()=>getRouteTree(), []);
|
|
118
257
|
if (!routeTree) return App ? /*#__PURE__*/ jsx(App, {}) : null;
|
|
119
|
-
const router =
|
|
120
|
-
const lifecycleContext = {
|
|
121
|
-
framework: 'tanstack',
|
|
122
|
-
phase: 'client-create',
|
|
123
|
-
routes: getRouteObjects(),
|
|
124
|
-
runtimeContext,
|
|
125
|
-
basename: _basename
|
|
126
|
-
};
|
|
127
|
-
hooks.onBeforeCreateRouter.call(lifecycleContext);
|
|
128
|
-
if (cachedRouter && cachedRouterBasepath === _basename) {
|
|
129
|
-
wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
|
|
130
|
-
hooks.onAfterCreateRouter.call({
|
|
131
|
-
...lifecycleContext,
|
|
132
|
-
router: cachedRouter,
|
|
133
|
-
runtimeContext
|
|
134
|
-
});
|
|
135
|
-
return cachedRouter;
|
|
136
|
-
}
|
|
137
|
-
const history = supportHtml5History ? createBrowserHistory() : createHashHistory();
|
|
138
|
-
const rewrite = createModernBasepathRewrite(_basename);
|
|
139
|
-
const serializationAdapters = getGlobalEnableRsc() ? getTanstackRscSerializationAdapters() : void 0;
|
|
140
|
-
cachedRouter = createRouter({
|
|
141
|
-
routeTree,
|
|
142
|
-
basepath: '/',
|
|
143
|
-
rewrite,
|
|
144
|
-
history,
|
|
145
|
-
context: {},
|
|
146
|
-
...serializationAdapters ? {
|
|
147
|
-
serializationAdapters
|
|
148
|
-
} : {}
|
|
149
|
-
});
|
|
150
|
-
cachedRouterBasepath = _basename;
|
|
151
|
-
wrapRouterSubscribeWithBlockState(cachedRouter, runtimeContext.unstable_getBlockNavState);
|
|
152
|
-
hooks.onAfterCreateRouter.call({
|
|
153
|
-
...lifecycleContext,
|
|
154
|
-
router: cachedRouter,
|
|
155
|
-
runtimeContext
|
|
156
|
-
});
|
|
157
|
-
return cachedRouter;
|
|
158
|
-
}, [
|
|
258
|
+
const router = useMemo(()=>getRouter(runtimeContext, _basename), [
|
|
159
259
|
_basename,
|
|
160
260
|
routeTree,
|
|
161
|
-
supportHtml5History,
|
|
162
261
|
runtimeContext
|
|
163
262
|
]);
|
|
263
|
+
if (!router) return App ? /*#__PURE__*/ jsx(App, {}) : null;
|
|
164
264
|
const runtimeState = applyRouterRuntimeState(runtimeContext, {
|
|
165
265
|
framework: 'tanstack',
|
|
166
266
|
basename: _basename,
|
|
@@ -174,30 +274,29 @@ const tanstackRouterPlugin = (userConfig = {})=>({
|
|
|
174
274
|
basename: _basename,
|
|
175
275
|
router
|
|
176
276
|
};
|
|
177
|
-
const hasSSRBootstrap = "u" > typeof window && Boolean(window.$_TSR);
|
|
178
|
-
|
|
277
|
+
const hasSSRBootstrap = "u" > typeof window && (Boolean(window.$_TSR) || hasTanstackSsrHydrationRecord(router));
|
|
278
|
+
const needsRouterClient = hasSSRBootstrap;
|
|
279
|
+
if (needsRouterClient) hooks.onBeforeHydrateRouter.call({
|
|
179
280
|
...lifecycleContext,
|
|
180
281
|
phase: 'hydrate',
|
|
181
282
|
router,
|
|
182
283
|
runtimeContext: runtimeState
|
|
183
284
|
});
|
|
184
|
-
const RouterContent =
|
|
185
|
-
|
|
186
|
-
children: /*#__PURE__*/ jsx(RouterClient, {
|
|
187
|
-
router: router
|
|
188
|
-
})
|
|
285
|
+
const RouterContent = needsRouterClient ? /*#__PURE__*/ jsx(ModernRouterClient, {
|
|
286
|
+
router: router
|
|
189
287
|
}) : /*#__PURE__*/ jsx(RouterProvider, {
|
|
190
288
|
router: router
|
|
191
289
|
});
|
|
192
|
-
|
|
290
|
+
const HydratableRouterContent = wrapTanstackSsrHydrationBoundary(RouterContent, hasSSRBootstrap);
|
|
291
|
+
if (needsRouterClient) hooks.onAfterHydrateRouter.call({
|
|
193
292
|
...lifecycleContext,
|
|
194
293
|
phase: 'hydrate',
|
|
195
294
|
router,
|
|
196
295
|
runtimeContext: runtimeState
|
|
197
296
|
});
|
|
198
297
|
return App ? /*#__PURE__*/ jsx(App, {
|
|
199
|
-
children:
|
|
200
|
-
}) :
|
|
298
|
+
children: HydratableRouterContent
|
|
299
|
+
}) : HydratableRouterContent;
|
|
201
300
|
};
|
|
202
301
|
return RouterWrapper;
|
|
203
302
|
});
|