@bleedingdev/modern-js-plugin-tanstack 3.9.0-ultramodern.9 → 3.9.3-ultramodern.1
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/cli/artifacts.js +15 -1
- package/dist/cjs/cli/index.js +13 -2
- package/dist/cjs/cli/routeMetadata.js +131 -0
- package/dist/cjs/cli/rscRouteLayer.js +86 -0
- package/dist/cjs/cli/tanstackTypes/canonicalRoutes.js +7 -7
- package/dist/cjs/cli/tanstackTypes/shared.js +0 -14
- package/dist/cjs/cli/tanstackTypes/source.js +28 -63
- package/dist/cjs/runtime/lifecycle.js +0 -3
- package/dist/cjs/runtime/loaderBridge.js +10 -4
- package/dist/cjs/runtime/navigation.js +102 -0
- package/dist/cjs/runtime/plugin.js +10 -1
- package/dist/cjs/runtime/plugin.node.js +89 -64
- package/dist/cjs/runtime/routeTree/construction.js +19 -61
- package/dist/cjs/runtime/routeTree/loaders.js +1 -1
- package/dist/cjs/runtime/routeTree/paths.js +0 -6
- package/dist/cjs/runtime/ssrManagedTags.js +2 -12
- package/dist/cjs/runtime/utils.js +1 -0
- package/dist/cjs/shared/routeDescriptor.js +60 -0
- package/dist/esm/cli/artifacts.mjs +13 -2
- package/dist/esm/cli/index.mjs +13 -11
- package/dist/esm/cli/routeMetadata.mjs +71 -0
- package/dist/esm/cli/rscRouteLayer.mjs +35 -0
- package/dist/esm/cli/tanstackTypes/canonicalRoutes.mjs +7 -7
- package/dist/esm/cli/tanstackTypes/shared.mjs +1 -9
- package/dist/esm/cli/tanstackTypes/source.mjs +29 -64
- package/dist/esm/runtime/lifecycle.mjs +1 -1
- package/dist/esm/runtime/loaderBridge.mjs +8 -5
- package/dist/esm/runtime/navigation.mjs +64 -0
- package/dist/esm/runtime/plugin.mjs +10 -1
- package/dist/esm/runtime/plugin.node.mjs +91 -66
- package/dist/esm/runtime/routeTree/construction.mjs +19 -61
- package/dist/esm/runtime/routeTree/loaders.mjs +2 -2
- package/dist/esm/runtime/routeTree/paths.mjs +1 -4
- package/dist/esm/runtime/ssrManagedTags.mjs +1 -8
- package/dist/esm/runtime/utils.mjs +1 -0
- package/dist/esm/shared/routeDescriptor.mjs +22 -0
- package/dist/esm-node/cli/artifacts.mjs +13 -2
- package/dist/esm-node/cli/index.mjs +13 -11
- package/dist/esm-node/cli/routeMetadata.mjs +72 -0
- package/dist/esm-node/cli/rscRouteLayer.mjs +36 -0
- package/dist/esm-node/cli/tanstackTypes/canonicalRoutes.mjs +7 -7
- package/dist/esm-node/cli/tanstackTypes/shared.mjs +1 -9
- package/dist/esm-node/cli/tanstackTypes/source.mjs +29 -64
- package/dist/esm-node/runtime/lifecycle.mjs +1 -1
- package/dist/esm-node/runtime/loaderBridge.mjs +8 -5
- package/dist/esm-node/runtime/navigation.mjs +65 -0
- package/dist/esm-node/runtime/plugin.mjs +10 -1
- package/dist/esm-node/runtime/plugin.node.mjs +91 -66
- package/dist/esm-node/runtime/routeTree/construction.mjs +19 -61
- package/dist/esm-node/runtime/routeTree/loaders.mjs +2 -2
- package/dist/esm-node/runtime/routeTree/paths.mjs +1 -4
- package/dist/esm-node/runtime/ssrManagedTags.mjs +1 -8
- package/dist/esm-node/runtime/utils.mjs +1 -0
- package/dist/esm-node/shared/routeDescriptor.mjs +23 -0
- package/dist/types/cli/artifacts.d.ts +16 -7
- package/dist/types/cli/index.d.ts +1 -1
- package/dist/types/cli/routeMetadata.d.ts +18 -0
- package/dist/types/cli/rscRouteLayer.d.ts +11 -0
- package/dist/types/cli/tanstackTypes/shared.d.ts +0 -2
- package/dist/types/cli/tanstackTypes/source.d.ts +3 -2
- package/dist/types/runtime/lifecycle.d.ts +1 -1
- package/dist/types/runtime/loaderBridge.d.ts +1 -0
- package/dist/types/runtime/navigation.d.ts +4 -0
- package/dist/types/runtime/pluginShared.d.ts +5 -0
- package/dist/types/runtime/routeTree/paths.d.ts +0 -2
- package/dist/types/runtime/ssrManagedTags.d.ts +0 -1
- package/dist/types/runtime/ssrTypes.d.ts +0 -7
- package/dist/types/shared/routeDescriptor.d.ts +26 -0
- package/package.json +32 -26
- package/src/cli/artifacts.ts +59 -8
- package/src/cli/index.ts +17 -4
- package/src/cli/routeMetadata.ts +121 -0
- package/src/cli/rscRouteLayer.ts +93 -0
- package/src/cli/tanstackTypes/canonicalRoutes.ts +17 -12
- package/src/cli/tanstackTypes/shared.ts +0 -14
- package/src/cli/tanstackTypes/source.ts +48 -120
- package/src/runtime/lifecycle.ts +0 -1
- package/src/runtime/loaderBridge.ts +9 -9
- package/src/runtime/navigation.ts +78 -0
- package/src/runtime/plugin.node.tsx +121 -91
- package/src/runtime/plugin.tsx +10 -0
- package/src/runtime/pluginShared.ts +12 -0
- package/src/runtime/routeTree/construction.ts +32 -112
- package/src/runtime/routeTree/loaders.ts +2 -4
- package/src/runtime/routeTree/paths.ts +0 -6
- package/src/runtime/ssrManagedTags.ts +0 -17
- package/src/runtime/ssrTypes.ts +0 -7
- package/src/runtime/utils.tsx +1 -0
- package/src/shared/routeDescriptor.ts +46 -0
- package/dist/esm/rslib-runtime~1.mjs +0 -18
- package/dist/esm-node/rslib-runtime~0.mjs +0 -19
- package/rslib.config.mts +0 -4
- package/rstest.config.mts +0 -53
- package/tests/router/cli.test.ts +0 -420
- package/tests/router/clientHydration.test.tsx +0 -200
- package/tests/router/dataMutation.test.tsx +0 -428
- package/tests/router/fixtures/router-gen.oxlint.json +0 -5
- package/tests/router/flightSerialization.roundtrip.test.tsx +0 -140
- package/tests/router/generateRouteArtifacts.test.ts +0 -146
- package/tests/router/loaderBridge.test.ts +0 -207
- package/tests/router/localisedIdentity.test.tsx +0 -95
- package/tests/router/prefetchLink.test.tsx +0 -122
- package/tests/router/prefetchLinkPreload.test.tsx +0 -65
- package/tests/router/routeHooks.test.ts +0 -49
- package/tests/router/routeTree.test.ts +0 -240
- package/tests/router/rsc.test.tsx +0 -480
- package/tests/router/serverPlugin.test.ts +0 -157
- package/tests/router/slotUsageSanitizer.test.ts +0 -23
- package/tests/router/ssrPreload.test.ts +0 -30
- package/tests/router/tanstackTypes.test.ts +0 -384
- package/tsconfig.json +0 -12
- package/tsconfig.tsgo.json +0 -6
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { InternalRuntimeContext, getGlobalEnableRsc } from "@modern-js/runtime/context";
|
|
3
|
+
import { createRouterStatePlugin } from "@modern-js/runtime-extensions/router-state-plugin";
|
|
3
4
|
import { createRequestContext } from "@modern-js/runtime-utils/node";
|
|
4
5
|
import { time } from "@modern-js/runtime-utils/time";
|
|
5
6
|
import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
|
|
@@ -8,13 +9,14 @@ import { useContext } from "react";
|
|
|
8
9
|
import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
|
|
9
10
|
import { routerProviderRegistryHooks } from "./hooks.mjs";
|
|
10
11
|
import { wrapTanstackSsrHydrationBoundary } from "./hydrationBoundary.mjs";
|
|
11
|
-
import {
|
|
12
|
+
import { applyRouterRuntimeState, applyRouterServerPrepareResult, getRouterRuntimeState, getRouterServerSnapshot } from "./lifecycle.mjs";
|
|
13
|
+
import { createTanstackNavigation } from "./navigation.mjs";
|
|
12
14
|
import { createTanstackRouteObjects, getTanstackRouteConfig, joinBasename } from "./pluginShared.mjs";
|
|
13
15
|
import { Link } from "./prefetchLink.mjs";
|
|
14
16
|
import { createRouteTreeFromRouteObjects, getModernRouteIdsFromMatches } from "./routeTree/index.mjs";
|
|
15
17
|
import { createTanstackRscServerPayload, handleTanstackRscRedirect } from "./rsc/payloadRouter.mjs";
|
|
16
18
|
import { getTanstackRscRouter, setTanstackRscRouter, setTanstackRscServerPayload } from "./rsc/payloadStorage.mjs";
|
|
17
|
-
import { attachServerSsrUtils, collectRouterErrors, createGetSsrHref, routerManagedTagsToHtml
|
|
19
|
+
import { attachServerSsrUtils, collectRouterErrors, createGetSsrHref, routerManagedTagsToHtml } from "./ssrManagedTags.mjs";
|
|
18
20
|
import { preloadMatchedRouteComponents } from "./ssrPreload.mjs";
|
|
19
21
|
import { getModernTanstackRouterFastDefaults } from "./types.mjs";
|
|
20
22
|
const tanstackRouterPlugin = (userConfig = {})=>{
|
|
@@ -22,6 +24,9 @@ const tanstackRouterPlugin = (userConfig = {})=>{
|
|
|
22
24
|
name: '@modern-js/plugin-router-tanstack',
|
|
23
25
|
registryHooks: routerProviderRegistryHooks,
|
|
24
26
|
setup: (api)=>{
|
|
27
|
+
createRouterStatePlugin({
|
|
28
|
+
registryHooks: routerProviderRegistryHooks
|
|
29
|
+
}).setup(api);
|
|
25
30
|
api.onBeforeRender(async (context, interrupt)=>{
|
|
26
31
|
const routeConfig = getTanstackRouteConfig(api, userConfig);
|
|
27
32
|
const { mergedConfig } = routeConfig;
|
|
@@ -87,76 +92,96 @@ const tanstackRouterPlugin = (userConfig = {})=>{
|
|
|
87
92
|
});
|
|
88
93
|
const serverRouter = tanstackRouter;
|
|
89
94
|
if (enableRsc) setTanstackRscRouter(serverRouter);
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (!serverLoadResult) {
|
|
102
|
-
try {
|
|
103
|
-
serverRouter.serverSsr?.cleanup?.();
|
|
104
|
-
} catch {}
|
|
105
|
-
throw new Error('TanStack Router completed an SSR load without a server result.');
|
|
106
|
-
}
|
|
107
|
-
if ('redirect' === serverLoadResult.type) {
|
|
108
|
-
const { redirect } = serverLoadResult;
|
|
109
|
-
try {
|
|
110
|
-
serverRouter.serverSsr?.cleanup?.();
|
|
111
|
-
} catch {}
|
|
112
|
-
return interrupt(isRSCNavigation ? handleTanstackRscRedirect(redirect.headers, _basename, redirect.status) : redirect);
|
|
113
|
-
}
|
|
114
|
-
const routerErrors = collectRouterErrors(tanstackRouter);
|
|
115
|
-
if (routerErrors && 'clientRender' === loaderFailureMode) {
|
|
116
|
-
context.ssrContext?.response?.status(200);
|
|
117
|
-
try {
|
|
118
|
-
serverRouter.serverSsr?.cleanup?.();
|
|
119
|
-
} catch {}
|
|
120
|
-
throw Object.values(routerErrors)[0];
|
|
121
|
-
}
|
|
122
|
-
await preloadMatchedRouteComponents(serverRouter);
|
|
123
|
-
context.ssrContext?.response?.status(serverLoadResult.status);
|
|
124
|
-
await serverRouter.serverSsr?.dehydrate?.();
|
|
125
|
-
if (enableRsc) {
|
|
126
|
-
if (isRSCNavigation) await waitForRouterSerialization(serverRouter);
|
|
127
|
-
setTanstackRscServerPayload(createTanstackRscServerPayload(serverRouter, {
|
|
128
|
-
omitClientLoaderData: isRSCNavigation
|
|
129
|
-
}));
|
|
130
|
-
}
|
|
131
|
-
const ssrScriptTags = serverRouter.serverSsr?.takeBufferedScripts?.();
|
|
132
|
-
const hydrationScripts = routerManagedTagsToHtml(ssrScriptTags);
|
|
133
|
-
const matchedRouteIds = getModernRouteIdsFromMatches(serverRouter);
|
|
134
|
-
const routerServerSnapshot = createRouterServerSnapshot({
|
|
95
|
+
let disposed = false;
|
|
96
|
+
let prepared = false;
|
|
97
|
+
const onAbort = ()=>controller.abort(rawRequest.signal.reason);
|
|
98
|
+
const cleanup = ()=>{
|
|
99
|
+
if (disposed) return;
|
|
100
|
+
disposed = true;
|
|
101
|
+
rawRequest.signal.removeEventListener('abort', onAbort);
|
|
102
|
+
controller.abort();
|
|
103
|
+
serverRouter.serverSsr?.cleanup();
|
|
104
|
+
};
|
|
105
|
+
applyRouterRuntimeState(context, {
|
|
135
106
|
framework: 'tanstack',
|
|
136
107
|
basename: _basename,
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
108
|
+
instance: serverRouter,
|
|
109
|
+
cleanup
|
|
110
|
+
});
|
|
111
|
+
rawRequest.signal.addEventListener('abort', onAbort, {
|
|
112
|
+
once: true
|
|
141
113
|
});
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
114
|
+
try {
|
|
115
|
+
rawRequest.signal.throwIfAborted();
|
|
116
|
+
await attachServerSsrUtils(serverRouter);
|
|
117
|
+
rawRequest.signal.throwIfAborted();
|
|
118
|
+
const end = time();
|
|
119
|
+
try {
|
|
120
|
+
await tanstackRouter.load({
|
|
121
|
+
sync: true
|
|
122
|
+
});
|
|
123
|
+
} finally{
|
|
124
|
+
const cost = end();
|
|
125
|
+
context.ssrContext?.onTiming?.(LOADER_REPORTER_NAME, cost);
|
|
126
|
+
}
|
|
127
|
+
rawRequest.signal.throwIfAborted();
|
|
128
|
+
const serverLoadResult = serverRouter._serverResult;
|
|
129
|
+
if (!serverLoadResult) throw new Error('TanStack Router completed an SSR load without a server result.');
|
|
130
|
+
if ('redirect' === serverLoadResult.type) {
|
|
131
|
+
const { redirect } = serverLoadResult;
|
|
132
|
+
return interrupt(isRSCNavigation ? handleTanstackRscRedirect(redirect.headers, _basename, redirect.status) : redirect);
|
|
133
|
+
}
|
|
134
|
+
const routerErrors = collectRouterErrors(tanstackRouter);
|
|
135
|
+
if (routerErrors && 'clientRender' === loaderFailureMode) {
|
|
136
|
+
context.ssrContext?.response?.status(200);
|
|
137
|
+
throw Object.values(routerErrors)[0];
|
|
138
|
+
}
|
|
139
|
+
await preloadMatchedRouteComponents(serverRouter);
|
|
140
|
+
context.ssrContext?.response?.status(serverLoadResult.status);
|
|
141
|
+
await serverRouter.serverSsr?.dehydrate();
|
|
142
|
+
if (enableRsc) {
|
|
143
|
+
setTanstackRscServerPayload(createTanstackRscServerPayload(serverRouter, {
|
|
144
|
+
omitClientLoaderData: isRSCNavigation
|
|
145
|
+
}));
|
|
146
|
+
if (isRSCNavigation) context.ssrContext.response.setHeader('Content-Type', 'text/x-component');
|
|
147
|
+
}
|
|
148
|
+
const initialScriptTags = serverRouter.serverSsr?.takeInitialHydrationScriptTags();
|
|
149
|
+
const hydrationScripts = initialScriptTags ? routerManagedTagsToHtml([
|
|
150
|
+
...initialScriptTags.before,
|
|
151
|
+
initialScriptTags.boundary
|
|
152
|
+
]) : [];
|
|
153
|
+
const matchedRouteIds = getModernRouteIdsFromMatches(serverRouter);
|
|
154
|
+
const routerServerSnapshot = {
|
|
146
155
|
framework: 'tanstack',
|
|
147
156
|
basename: _basename,
|
|
148
|
-
|
|
149
|
-
|
|
157
|
+
statusCode: serverLoadResult.status,
|
|
158
|
+
errors: routerErrors,
|
|
150
159
|
matchedRouteIds,
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
+
hydrationScripts
|
|
161
|
+
};
|
|
162
|
+
const runtimeContext = applyRouterServerPrepareResult(context, {
|
|
163
|
+
snapshot: routerServerSnapshot,
|
|
164
|
+
cleanup,
|
|
165
|
+
state: {
|
|
166
|
+
framework: 'tanstack',
|
|
167
|
+
basename: _basename,
|
|
168
|
+
instance: serverRouter,
|
|
169
|
+
navigation: createTanstackNavigation(tanstackRouter)
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
rawRequest.signal.throwIfAborted();
|
|
173
|
+
hooks.onAfterCreateRouter.call({
|
|
174
|
+
...routerLifecycleContext,
|
|
175
|
+
router: serverRouter,
|
|
176
|
+
serverSnapshot: getRouterServerSnapshot(runtimeContext),
|
|
177
|
+
runtimeContext
|
|
178
|
+
});
|
|
179
|
+
prepared = true;
|
|
180
|
+
} finally{
|
|
181
|
+
if (!prepared) try {
|
|
182
|
+
cleanup();
|
|
183
|
+
} catch {}
|
|
184
|
+
}
|
|
160
185
|
});
|
|
161
186
|
api.wrapRoot((App)=>{
|
|
162
187
|
const getRouteApp = ()=>{
|
|
@@ -1,23 +1,19 @@
|
|
|
1
|
-
import { canonicaliseLocalisedRoutes } from "@modern-js/i18n-runtime-extensions";
|
|
2
1
|
import { DefaultNotFound } from "@modern-js/runtime/context";
|
|
3
2
|
import { rootRouteId } from "@tanstack/react-router";
|
|
3
|
+
import { describeRouteTree } from "../../shared/routeDescriptor.mjs";
|
|
4
4
|
import { createRouteStaticData } from "../../shared/routeStaticData.mjs";
|
|
5
5
|
import { withModernRouteMatchContext } from "../outlet.mjs";
|
|
6
6
|
import { toErrorComponent, toPendingComponent, toRouteComponent } from "./components.mjs";
|
|
7
7
|
import { createModernShouldReload, wrapRouteObjectLoader } from "./loaders.mjs";
|
|
8
|
-
import { isRouteObjectPathlessLayout, toTanstackPath } from "./paths.mjs";
|
|
9
8
|
import { mergeModernRouteHandle } from "./staticData.mjs";
|
|
10
9
|
import { createTanstackRootRoute, createTanstackRoute, wrapRouteComponentWithModernContext } from "./tanstackRoutes.mjs";
|
|
11
|
-
function
|
|
12
|
-
const { options = {}, parent, pathlessFallbackId = 'pathless', routeObject } = opts;
|
|
10
|
+
function createRouteOptions(routeObject, options) {
|
|
13
11
|
const modernRouteObject = routeObject;
|
|
14
12
|
const revalidationState = {};
|
|
15
13
|
const shouldRevalidate = modernRouteObject.shouldRevalidate;
|
|
16
14
|
const shouldReload = createModernShouldReload(shouldRevalidate, revalidationState);
|
|
17
|
-
const stableFallbackId = routeObject.id || modernRouteObject.file || pathlessFallbackId;
|
|
18
15
|
const component = toRouteComponent(routeObject);
|
|
19
16
|
const base = {
|
|
20
|
-
getParentRoute: ()=>parent,
|
|
21
17
|
component,
|
|
22
18
|
pendingComponent: toPendingComponent(routeObject),
|
|
23
19
|
errorComponent: toErrorComponent(routeObject),
|
|
@@ -38,67 +34,29 @@ function createRouteFromRouteObject(opts) {
|
|
|
38
34
|
};
|
|
39
35
|
if (modernRouteObject.inValidSSRRoute) base.ssr = false;
|
|
40
36
|
if (shouldReload) base.shouldReload = shouldReload;
|
|
41
|
-
|
|
42
|
-
else base.path = routeObject.index ? '/' : toTanstackPath(routeObject.path || '');
|
|
43
|
-
const route = createTanstackRoute(base);
|
|
44
|
-
wrapRouteComponentWithModernContext(route, component, routeObject.id);
|
|
45
|
-
const children = routeObject.children;
|
|
46
|
-
if (children && children.length > 0) {
|
|
47
|
-
const childRoutes = children.map((child, index)=>createRouteFromRouteObject({
|
|
48
|
-
options,
|
|
49
|
-
parent: route,
|
|
50
|
-
pathlessFallbackId: `pathless-${index}`,
|
|
51
|
-
routeObject: child
|
|
52
|
-
}));
|
|
53
|
-
route.addChildren(childRoutes);
|
|
54
|
-
}
|
|
55
|
-
return route;
|
|
37
|
+
return base;
|
|
56
38
|
}
|
|
57
|
-
function
|
|
58
|
-
|
|
39
|
+
function createRouteFromDescriptor(descriptor, parent, options) {
|
|
40
|
+
const { source, location, children } = descriptor;
|
|
41
|
+
const routeOptions = createRouteOptions(source, options);
|
|
42
|
+
const route = createTanstackRoute({
|
|
43
|
+
...routeOptions,
|
|
44
|
+
...location,
|
|
45
|
+
getParentRoute: ()=>parent
|
|
46
|
+
});
|
|
47
|
+
wrapRouteComponentWithModernContext(route, routeOptions.component, source.id);
|
|
48
|
+
if (children.length) route.addChildren(children.map((child)=>createRouteFromDescriptor(child, route, options)));
|
|
49
|
+
return route;
|
|
59
50
|
}
|
|
60
51
|
function createRouteTreeFromRouteObjects(routes, options = {}) {
|
|
61
|
-
|
|
62
|
-
const rootLikeRoute = getRootLikeRouteObject(routes);
|
|
63
|
-
const rootRevalidationState = {};
|
|
64
|
-
const rootShouldRevalidate = rootLikeRoute?.shouldRevalidate;
|
|
65
|
-
const rootShouldReload = createModernShouldReload(rootShouldRevalidate, rootRevalidationState);
|
|
66
|
-
const rootComponent = rootLikeRoute ? toRouteComponent(rootLikeRoute) : void 0;
|
|
52
|
+
const { root, children } = describeRouteTree(routes);
|
|
67
53
|
const rootRouteOptions = {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
errorComponent: rootLikeRoute ? toErrorComponent(rootLikeRoute) : void 0,
|
|
71
|
-
validateSearch: rootLikeRoute?.validateSearch,
|
|
72
|
-
loaderDeps: rootLikeRoute?.loaderDeps,
|
|
73
|
-
notFoundComponent: DefaultNotFound,
|
|
74
|
-
staticData: createRouteStaticData({
|
|
75
|
-
modernRouteId: rootLikeRoute?.id,
|
|
76
|
-
modernRouteAction: rootLikeRoute?.action,
|
|
77
|
-
modernRouteHandle: rootLikeRoute ? mergeModernRouteHandle(rootLikeRoute) : void 0,
|
|
78
|
-
modernRouteHasAction: rootLikeRoute?.hasAction || Boolean(rootLikeRoute?.action),
|
|
79
|
-
modernRouteHasClientLoader: rootLikeRoute?.hasClientLoader || void 0 !== rootLikeRoute?.clientData,
|
|
80
|
-
modernRouteHasLoader: rootLikeRoute?.hasLoader || 'function' == typeof rootLikeRoute?.loader,
|
|
81
|
-
modernRouteIsClientComponent: rootLikeRoute?.isClientComponent,
|
|
82
|
-
modernRouteLoader: rootLikeRoute?.loader,
|
|
83
|
-
modernRouteShouldRevalidate: rootShouldRevalidate
|
|
84
|
-
}),
|
|
85
|
-
loader: rootLikeRoute ? wrapRouteObjectLoader(rootLikeRoute, rootRevalidationState, options) : void 0
|
|
54
|
+
...root ? createRouteOptions(root, options) : {},
|
|
55
|
+
notFoundComponent: DefaultNotFound
|
|
86
56
|
};
|
|
87
|
-
if (rootShouldReload) rootRouteOptions.shouldReload = rootShouldReload;
|
|
88
|
-
if (rootLikeRoute?.inValidSSRRoute) rootRouteOptions.ssr = false;
|
|
89
57
|
const rootRoute = createTanstackRootRoute(rootRouteOptions);
|
|
90
|
-
if (
|
|
91
|
-
|
|
92
|
-
...rootLikeRoute.children || [],
|
|
93
|
-
...routes.filter((route)=>route !== rootLikeRoute)
|
|
94
|
-
] : routes;
|
|
95
|
-
const childRoutes = topLevel.map((routeObject, index)=>createRouteFromRouteObject({
|
|
96
|
-
options,
|
|
97
|
-
parent: rootRoute,
|
|
98
|
-
pathlessFallbackId: `pathless-${index}`,
|
|
99
|
-
routeObject
|
|
100
|
-
}));
|
|
101
|
-
rootRoute.addChildren(childRoutes);
|
|
58
|
+
if (rootRouteOptions.component) rootRoute.options.component = withModernRouteMatchContext(rootRouteOptions.component, rootRouteId);
|
|
59
|
+
rootRoute.addChildren(children.map((child)=>createRouteFromDescriptor(child, rootRoute, options)));
|
|
102
60
|
return rootRoute;
|
|
103
61
|
}
|
|
104
62
|
function getModernRouteIdsFromMatches(router) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getLoaderHref, handleModernLoaderError, handleModernLoaderResult, mapSplatParamsForModernLoader } from "../loaderBridge.mjs";
|
|
1
|
+
import { getLoaderHref, getLoaderSignal, handleModernLoaderError, handleModernLoaderResult, mapSplatParamsForModernLoader } from "../loaderBridge.mjs";
|
|
2
2
|
import { isTanstackRscPayloadNavigationEnabled, loadTanstackRscRouteData } from "../rsc/payloadRouter.mjs";
|
|
3
3
|
function isModernDeferredData(value) {
|
|
4
4
|
if (!value || 'object' != typeof value) return false;
|
|
@@ -49,7 +49,7 @@ function wrapRouteObjectLoader(route, revalidationState, options = {}) {
|
|
|
49
49
|
if ('function' == typeof modernRoute.lazyImport) try {
|
|
50
50
|
await modernRoute.lazyImport();
|
|
51
51
|
} catch {}
|
|
52
|
-
const signal = ctx
|
|
52
|
+
const signal = getLoaderSignal(ctx);
|
|
53
53
|
const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
|
|
54
54
|
const href = getLoaderHref(ctx);
|
|
55
55
|
const request = void 0 !== baseRequest ? new Request(baseRequest, {
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
async function waitForRouterSerialization(tanstackRouter) {
|
|
2
|
-
const serverSsr = tanstackRouter.serverSsr;
|
|
3
|
-
if (!serverSsr || 'function' != typeof serverSsr.onSerializationFinished || serverSsr.isSerializationFinished?.()) return;
|
|
4
|
-
await new Promise((resolve)=>{
|
|
5
|
-
serverSsr.onSerializationFinished?.(resolve);
|
|
6
|
-
});
|
|
7
|
-
}
|
|
8
1
|
function htmlEscapeAttr(value) {
|
|
9
2
|
return value.replace(/&/g, '&').replace(/"/g, '"');
|
|
10
3
|
}
|
|
@@ -50,4 +43,4 @@ async function attachServerSsrUtils(router) {
|
|
|
50
43
|
manifest: void 0
|
|
51
44
|
});
|
|
52
45
|
}
|
|
53
|
-
export { attachServerSsrUtils, collectRouterErrors, createGetSsrHref, routerManagedTagsToHtml
|
|
46
|
+
export { attachServerSsrUtils, collectRouterErrors, createGetSsrHref, routerManagedTagsToHtml };
|
|
@@ -14,6 +14,7 @@ function withGlobalLayout(Component, globalApp) {
|
|
|
14
14
|
function toTanstackRouteObject(route, globalApp) {
|
|
15
15
|
if ('nested' === route.type) return {
|
|
16
16
|
modernLocalisedRoute: Reflect.get(route, 'modernLocalisedRoute'),
|
|
17
|
+
isRoot: Reflect.get(route, 'isRoot'),
|
|
17
18
|
path: route.path,
|
|
18
19
|
id: route.id,
|
|
19
20
|
loader: route.loader,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { toTanstackPath } from "../runtime/routeTree/paths.mjs";
|
|
2
|
+
function describeRouteTree(routes) {
|
|
3
|
+
const root = routes.find((route)=>true === route.isRoot || '/' === route.path && true !== route.index);
|
|
4
|
+
const describe = (route, index)=>({
|
|
5
|
+
source: route,
|
|
6
|
+
location: 0 === (route.path ?? '').length && true !== route.index ? {
|
|
7
|
+
id: route.id || route.file || `pathless-${index}`
|
|
8
|
+
} : {
|
|
9
|
+
path: true === route.index ? '/' : toTanstackPath(route.path || '')
|
|
10
|
+
},
|
|
11
|
+
hasSplat: Boolean(route.path?.includes('*')),
|
|
12
|
+
children: (route.children ?? []).map(describe)
|
|
13
|
+
});
|
|
14
|
+
return {
|
|
15
|
+
root,
|
|
16
|
+
children: (void 0 !== root ? [
|
|
17
|
+
...root.children ?? [],
|
|
18
|
+
...routes.filter((route)=>route !== root)
|
|
19
|
+
] : routes).map(describe)
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export { describeRouteTree };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import node_path from "node:path";
|
|
3
3
|
import { fs } from "@modern-js/utils";
|
|
4
|
+
import { ROUTE_METADATA_MANIFEST_FILE_NAME, ROUTE_METADATA_MANIFEST_HEADER, findRouteMetaFiles, renderRouteMetadataManifest } from "./routeMetadata.mjs";
|
|
4
5
|
import { collectCanonicalRoutesForEntry, generateTanstackRouterTypesSourceForEntry } from "./tanstackTypes.mjs";
|
|
5
6
|
const DEFAULT_GENERATED_DIR_NAME = 'modern-tanstack';
|
|
6
7
|
async function writeFileIfChanged(filePath, content) {
|
|
@@ -78,7 +79,16 @@ async function writeTanstackRouterTypesForEntries(opts) {
|
|
|
78
79
|
canonicalRoutes
|
|
79
80
|
});
|
|
80
81
|
}
|
|
82
|
+
async function writeRouteMetadataManifest(opts) {
|
|
83
|
+
const routesDirectory = node_path.join(opts.appDirectory, 'src', 'routes');
|
|
84
|
+
const manifestPath = node_path.join(routesDirectory, ROUTE_METADATA_MANIFEST_FILE_NAME);
|
|
85
|
+
const manifest = renderRouteMetadataManifest(await findRouteMetaFiles(routesDirectory));
|
|
86
|
+
if (null !== manifest) return void await writeFileIfChanged(manifestPath, manifest);
|
|
87
|
+
const previous = await fs.pathExists(manifestPath) ? await fs.readFile(manifestPath, 'utf-8') : null;
|
|
88
|
+
if (previous?.startsWith(`${ROUTE_METADATA_MANIFEST_HEADER}\n`)) throw new Error(`[plugin-tanstack] ${manifestPath} is generated from route.meta.ts files, but none remain below ${routesDirectory}. Restore at least one route.meta.ts that exports routeMeta, or delete the manifest together with its imports.`);
|
|
89
|
+
}
|
|
81
90
|
async function generateTanstackRouteArtifacts(opts) {
|
|
91
|
+
await writeRouteMetadataManifest(opts);
|
|
82
92
|
const [{ createRunOptions }, { cli }, utils] = await Promise.all([
|
|
83
93
|
import("@modern-js/app-tools/cli/run"),
|
|
84
94
|
import("@modern-js/plugin/cli"),
|
|
@@ -96,9 +106,10 @@ async function generateTanstackRouteArtifacts(opts) {
|
|
|
96
106
|
version: opts.version || process.env.MODERN_JS_VERSION || '0.0.0-routes-generate',
|
|
97
107
|
internalPlugins: utils.INTERNAL_RUNTIME_PLUGINS
|
|
98
108
|
});
|
|
99
|
-
await cli.init({
|
|
109
|
+
const { appContext } = await cli.init({
|
|
100
110
|
...runOptions,
|
|
101
111
|
command: 'build'
|
|
102
112
|
});
|
|
113
|
+
await appContext.hooks.onBeforeExit.call();
|
|
103
114
|
}
|
|
104
|
-
export { generateTanstackRouteArtifacts, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries };
|
|
115
|
+
export { generateTanstackRouteArtifacts, writeRouteMetadataManifest, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries };
|
|
@@ -1,26 +1,21 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import node_path from "node:path";
|
|
3
3
|
import { NESTED_ROUTE_SPEC_FILE, filterRoutesForServer } from "@modern-js/utils";
|
|
4
|
-
import { generateTanstackRouteArtifacts, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries } from "./artifacts.mjs";
|
|
4
|
+
import { generateTanstackRouteArtifacts, writeRouteMetadataManifest, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries } from "./artifacts.mjs";
|
|
5
5
|
import { createTanstackRsbuildRouteSplittingProfile, resolveTanstackRouteCodeSplittingEnabled } from "./routeSplitting.mjs";
|
|
6
|
-
import {
|
|
6
|
+
import { TANSTACK_SERVER_ROUTES_FILE, createTanstackRscRouteLayerPlugin } from "./rscRouteLayer.mjs";
|
|
7
7
|
import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
|
|
8
8
|
import { dirname as __rspack_dirname } from "node:path";
|
|
9
9
|
var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
|
|
10
10
|
import { createRequire as __rspack_createRequire } from "node:module";
|
|
11
11
|
const __rspack_createRequire_require = __rspack_createRequire(import.meta.url);
|
|
12
|
-
__webpack_require__.add({
|
|
13
|
-
"@modern-js/runtime/cli?667f" (module) {
|
|
14
|
-
module.exports = __rspack_createRequire_require("@modern-js/runtime/cli");
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
12
|
const DEFAULT_ROUTES_DIR = 'routes';
|
|
18
13
|
const DEFAULT_GENERATED_DIR_NAME = 'modern-tanstack';
|
|
19
14
|
const ENTRYPOINTS_KEY = '@modern-js/plugin-tanstack';
|
|
20
15
|
let runtimeRouterCli;
|
|
21
16
|
function getRuntimeRouterCli() {
|
|
22
17
|
if (runtimeRouterCli) return runtimeRouterCli;
|
|
23
|
-
const cli =
|
|
18
|
+
const cli = __rspack_createRequire_require("@modern-js/runtime/cli");
|
|
24
19
|
if (cli.handleGeneratorEntryCode && cli.getEntrypointRoutesDir && cli.getEntrypointRoutesOwner && cli.updateNestedRoutesSpec) {
|
|
25
20
|
runtimeRouterCli = cli;
|
|
26
21
|
return runtimeRouterCli;
|
|
@@ -102,6 +97,13 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
102
97
|
}));
|
|
103
98
|
api.config(()=>({
|
|
104
99
|
...routeSplittingProfile.defaultConfig,
|
|
100
|
+
builderPlugins: [
|
|
101
|
+
createTanstackRscRouteLayerPlugin(()=>({
|
|
102
|
+
entryNames: api.getAppContext().entrypoints.filter(isTanstackEntrypoint).map((entrypoint)=>entrypoint.entryName),
|
|
103
|
+
internalDirectory: api.getAppContext().internalDirectory,
|
|
104
|
+
rsc: api.getNormalizedConfig().server.rsc
|
|
105
|
+
}))
|
|
106
|
+
],
|
|
105
107
|
source: {
|
|
106
108
|
include: [
|
|
107
109
|
/[\\/]node_modules[\\/]@tanstack[\\/]react-router[\\/]/,
|
|
@@ -128,7 +130,7 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
128
130
|
hydrateRscClientRoutes: true,
|
|
129
131
|
includeRouteServerLoadersInSsrEntry: false,
|
|
130
132
|
isolateRouteDataInRscLayer: true,
|
|
131
|
-
serverRoutesFileName:
|
|
133
|
+
serverRoutesFileName: TANSTACK_SERVER_ROUTES_FILE
|
|
132
134
|
});
|
|
133
135
|
await writeTanstackRouterTypesForEntries({
|
|
134
136
|
appContext: api.getAppContext(),
|
|
@@ -152,7 +154,7 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
152
154
|
hydrateRscClientRoutes: true,
|
|
153
155
|
includeRouteServerLoadersInSsrEntry: false,
|
|
154
156
|
isolateRouteDataInRscLayer: true,
|
|
155
|
-
serverRoutesFileName:
|
|
157
|
+
serverRoutesFileName: TANSTACK_SERVER_ROUTES_FILE
|
|
156
158
|
});
|
|
157
159
|
await writeTanstackRouterTypesForEntries({
|
|
158
160
|
appContext: api.getAppContext(),
|
|
@@ -188,4 +190,4 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
188
190
|
const src_cli = tanstackRouterPlugin;
|
|
189
191
|
export { collectCanonicalRoutesForEntry, generateTanstackRouterTypesSourceForEntry } from "./tanstackTypes.mjs";
|
|
190
192
|
export default src_cli;
|
|
191
|
-
export { createTanstackRsbuildRouteSplittingProfile, generateTanstackRouteArtifacts, resolveTanstackRouteCodeSplittingEnabled, tanstackRouterPlugin, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries };
|
|
193
|
+
export { createTanstackRsbuildRouteSplittingProfile, generateTanstackRouteArtifacts, resolveTanstackRouteCodeSplittingEnabled, tanstackRouterPlugin, writeRouteMetadataManifest, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { readdir } from "node:fs/promises";
|
|
3
|
+
import node_path from "node:path";
|
|
4
|
+
const ROUTE_META_FILE_NAME = 'route.meta.ts';
|
|
5
|
+
const ROUTE_METADATA_MANIFEST_FILE_NAME = 'ultramodern-route-metadata.ts';
|
|
6
|
+
const ROUTE_METADATA_MANIFEST_HEADER = `// @generated by @modern-js/plugin-tanstack from ${ROUTE_META_FILE_NAME} files. Run routes-generate; do not edit.`;
|
|
7
|
+
const PRINT_WIDTH = 120;
|
|
8
|
+
const MANIFEST_BODY = `export const ultramodernLocalisedUrls = Object.fromEntries(
|
|
9
|
+
ultramodernRouteMetadata
|
|
10
|
+
.filter((route: { canonicalPath: string }) => route.canonicalPath !== '/')
|
|
11
|
+
.map((route) => [route.canonicalPath, route.localisedPaths]),
|
|
12
|
+
);
|
|
13
|
+
export const ultramodernPublicRoutes = ultramodernRouteMetadata
|
|
14
|
+
.filter((route) => route.public && route.indexable)
|
|
15
|
+
.map((route) => ({
|
|
16
|
+
canonicalPath: route.canonicalPath,
|
|
17
|
+
descriptionKey: route.descriptionKey,
|
|
18
|
+
id: route.id,
|
|
19
|
+
localisedPaths: route.localisedPaths,
|
|
20
|
+
namespace: route.namespace,
|
|
21
|
+
ownerAppId: route.ownerAppId,
|
|
22
|
+
titleKey: route.titleKey,
|
|
23
|
+
...('jsonLd' in route ? { jsonLd: route.jsonLd } : {}),
|
|
24
|
+
}));
|
|
25
|
+
export const ultramodernRouteConfig = {
|
|
26
|
+
authoring: 'colocated-route-meta',
|
|
27
|
+
generatedManifest: true,
|
|
28
|
+
localisedUrls: ultramodernLocalisedUrls,
|
|
29
|
+
namespace: ultramodernRouteNamespace,
|
|
30
|
+
publicRoutes: ultramodernPublicRoutes,
|
|
31
|
+
routes: ultramodernRouteMetadata,
|
|
32
|
+
source: 'route-owned',
|
|
33
|
+
} as const;
|
|
34
|
+
`;
|
|
35
|
+
const compareCodeUnits = (left, right)=>left < right ? -1 : left > right ? 1 : 0;
|
|
36
|
+
const quoteSpecifier = (specifier)=>specifier.includes("'") ? JSON.stringify(specifier) : `'${specifier}'`;
|
|
37
|
+
function renderRouteMetadataManifest(routeMetaFiles) {
|
|
38
|
+
const specifiers = routeMetaFiles.map((file)=>`./${file.replaceAll('\\', '/').replace(/\.ts$/u, '')}`).sort(compareCodeUnits);
|
|
39
|
+
if (0 === specifiers.length) return null;
|
|
40
|
+
const bindings = specifiers.map((_, index)=>`route${index}`);
|
|
41
|
+
const imports = specifiers.map((specifier, index)=>`import { routeMeta as ${bindings[index]} } from ${quoteSpecifier(specifier)};`);
|
|
42
|
+
const inlineRoutes = `export const ultramodernRouteMetadata = [${bindings.join(', ')}] as const;`;
|
|
43
|
+
const routes = inlineRoutes.length <= PRINT_WIDTH ? inlineRoutes : `export const ultramodernRouteMetadata = [\n${bindings.map((binding)=>` ${binding},\n`).join('')}] as const;`;
|
|
44
|
+
return `${ROUTE_METADATA_MANIFEST_HEADER}
|
|
45
|
+
${imports.join('\n')}
|
|
46
|
+
|
|
47
|
+
export const ultramodernRouteNamespace = route0.namespace;
|
|
48
|
+
${routes}
|
|
49
|
+
${MANIFEST_BODY}`;
|
|
50
|
+
}
|
|
51
|
+
async function findRouteMetaFiles(routesDirectory) {
|
|
52
|
+
const files = [];
|
|
53
|
+
const visit = async (relativeDirectory)=>{
|
|
54
|
+
const entries = await readdir(node_path.join(routesDirectory, relativeDirectory), {
|
|
55
|
+
withFileTypes: true
|
|
56
|
+
});
|
|
57
|
+
for (const entry of entries){
|
|
58
|
+
const relativePath = node_path.join(relativeDirectory, entry.name);
|
|
59
|
+
if (entry.isDirectory()) await visit(relativePath);
|
|
60
|
+
else if (entry.isFile() && entry.name === ROUTE_META_FILE_NAME) files.push(relativePath);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
try {
|
|
64
|
+
await visit('');
|
|
65
|
+
} catch (error) {
|
|
66
|
+
const { code, path: missingPath } = error;
|
|
67
|
+
if ('ENOENT' === code && missingPath === routesDirectory) return [];
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
return files;
|
|
71
|
+
}
|
|
72
|
+
export { ROUTE_METADATA_MANIFEST_FILE_NAME, ROUTE_METADATA_MANIFEST_HEADER, ROUTE_META_FILE_NAME, findRouteMetaFiles, renderRouteMetadataManifest };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import node_path from "node:path";
|
|
3
|
+
const TANSTACK_SERVER_ROUTES_FILE = 'tanstack-routes.server.js';
|
|
4
|
+
function exactResource(...filenames) {
|
|
5
|
+
const escaped = filenames.map((filename)=>filename.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&'));
|
|
6
|
+
return new RegExp(`^(?:${escaped.join('|')})(?:\\?.*)?$`, 'u');
|
|
7
|
+
}
|
|
8
|
+
function createTanstackRscRouteLayerPlugin(getContext) {
|
|
9
|
+
return {
|
|
10
|
+
name: 'modern:tanstack:rsc-route-layer',
|
|
11
|
+
setup (api) {
|
|
12
|
+
api.modifyRspackConfig({
|
|
13
|
+
order: 'post',
|
|
14
|
+
handler (config, { environment, rspack, target }) {
|
|
15
|
+
const { entryNames, internalDirectory, rsc } = getContext();
|
|
16
|
+
if (false === rsc || void 0 === rsc || 0 === entryNames.length) return;
|
|
17
|
+
const rscServerEnvironment = 'object' == typeof rsc ? rsc.environments?.server ?? 'server' : 'server';
|
|
18
|
+
if ('node' !== target && 'node' !== config.target && environment.name !== rscServerEnvironment) return;
|
|
19
|
+
config.module ??= {};
|
|
20
|
+
config.module.rules ??= [];
|
|
21
|
+
config.plugins ??= [];
|
|
22
|
+
for (const entryName of entryNames){
|
|
23
|
+
const routes = node_path.resolve(internalDirectory, entryName, 'routes.js');
|
|
24
|
+
const serverRoutes = node_path.resolve(internalDirectory, entryName, TANSTACK_SERVER_ROUTES_FILE);
|
|
25
|
+
config.plugins.push(new rspack.NormalModuleReplacementPlugin(exactResource(routes), serverRoutes));
|
|
26
|
+
config.module.rules.push({
|
|
27
|
+
resource: exactResource(routes, serverRoutes),
|
|
28
|
+
layer: 'server-side-rendering'
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export { TANSTACK_SERVER_ROUTES_FILE, createTanstackRscRouteLayerPlugin };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
+
import { describeRouteTree } from "../../shared/routeDescriptor.mjs";
|
|
2
3
|
import { toTanstackPath } from "./shared.mjs";
|
|
3
4
|
const LOCALE_PARAM_SEGMENTS = new Set([
|
|
4
5
|
':lang',
|
|
@@ -45,11 +46,13 @@ function collectCanonicalRoutesForEntry(routes, options = {}) {
|
|
|
45
46
|
const key = toTanstackPath(normalized);
|
|
46
47
|
if (!canonicalParams.has(key)) canonicalParams.set(key, paramsTypeForCanonicalPath(normalized));
|
|
47
48
|
};
|
|
48
|
-
const visit = (
|
|
49
|
+
const visit = (descriptor, parentPath)=>{
|
|
50
|
+
const { source: route, children } = descriptor;
|
|
49
51
|
let currentPath = parentPath;
|
|
50
|
-
|
|
52
|
+
const canonicalPath = route.modernLocalisedRoute?.canonicalPath ?? route.modernCanonicalPath;
|
|
53
|
+
if ('string' == typeof canonicalPath) {
|
|
51
54
|
hasI18nSurface = true;
|
|
52
|
-
currentPath = normalizeJoined(
|
|
55
|
+
currentPath = canonicalPath ? normalizeJoined(canonicalPath) : '';
|
|
53
56
|
} else if ('string' == typeof route.path && route.path.length > 0) {
|
|
54
57
|
const segments = route.path.replace(/\[(.+?)\]/g, ':$1').split('/').filter(Boolean);
|
|
55
58
|
if (localeParamHeuristic && '' === parentPath && LOCALE_PARAM_SEGMENTS.has(segments[0])) {
|
|
@@ -58,16 +61,13 @@ function collectCanonicalRoutesForEntry(routes, options = {}) {
|
|
|
58
61
|
}
|
|
59
62
|
currentPath = segments.length ? normalizeJoined(`${parentPath}/${segments.join('/')}`) : parentPath;
|
|
60
63
|
}
|
|
61
|
-
const children = route.children;
|
|
62
64
|
if (children && children.length > 0) {
|
|
63
65
|
for (const child of children)visit(child, currentPath);
|
|
64
66
|
return;
|
|
65
67
|
}
|
|
66
68
|
record(currentPath || '/');
|
|
67
69
|
};
|
|
68
|
-
const
|
|
69
|
-
const topLevel = rootModern ? rootModern.children ?? [] : routes;
|
|
70
|
-
for (const route of topLevel)visit(route, '');
|
|
70
|
+
for (const route of describeRouteTree(routes).children)visit(route, '');
|
|
71
71
|
if (!hasI18nSurface || 0 === canonicalParams.size) return null;
|
|
72
72
|
return Object.fromEntries([
|
|
73
73
|
...canonicalParams.entries()
|