@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.120 → 3.2.0-ultramodern.122
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/cli/index.js +47 -27
- package/dist/cjs/cli/routeSplitting.js +0 -32
- package/dist/cjs/cli/tanstackTypes.js +34 -199
- package/dist/cjs/runtime/hooks.js +11 -14
- package/dist/cjs/runtime/index.js +107 -319
- package/dist/cjs/runtime/lifecycle.js +12 -86
- package/dist/cjs/runtime/loaderBridge.js +173 -0
- package/dist/cjs/runtime/plugin.js +6 -30
- package/dist/cjs/runtime/plugin.node.js +7 -29
- package/dist/cjs/runtime/pluginCore.js +55 -0
- package/dist/cjs/runtime/register.js +56 -0
- package/dist/cjs/runtime/routeTree.js +10 -207
- package/dist/cjs/runtime/{DefaultNotFound.js → router.js} +5 -15
- package/dist/cjs/runtime/rsc/payloadRouter.js +35 -1
- package/dist/cjs/runtime/state.js +45 -0
- package/dist/cjs/runtime/utils.js +0 -5
- package/dist/esm/cli/index.mjs +52 -26
- package/dist/esm/cli/routeSplitting.mjs +1 -30
- package/dist/esm/cli/tanstackTypes.mjs +32 -194
- package/dist/esm/runtime/hooks.mjs +1 -8
- package/dist/esm/runtime/index.mjs +4 -2
- package/dist/esm/runtime/lifecycle.mjs +1 -82
- package/dist/esm/runtime/loaderBridge.mjs +114 -0
- package/dist/esm/runtime/plugin.mjs +8 -32
- package/dist/esm/runtime/plugin.node.mjs +10 -32
- package/dist/esm/runtime/pluginCore.mjs +14 -0
- package/dist/esm/runtime/register.mjs +18 -0
- package/dist/esm/runtime/routeTree.mjs +4 -198
- package/dist/esm/runtime/router.mjs +2 -0
- package/dist/esm/runtime/rsc/payloadRouter.mjs +35 -1
- package/dist/esm/runtime/state.mjs +7 -0
- package/dist/esm/runtime/utils.mjs +0 -5
- package/dist/esm-node/cli/index.mjs +52 -26
- package/dist/esm-node/cli/routeSplitting.mjs +1 -30
- package/dist/esm-node/cli/tanstackTypes.mjs +32 -194
- package/dist/esm-node/runtime/hooks.mjs +1 -8
- package/dist/esm-node/runtime/index.mjs +4 -2
- package/dist/esm-node/runtime/lifecycle.mjs +1 -82
- package/dist/esm-node/runtime/loaderBridge.mjs +115 -0
- package/dist/esm-node/runtime/plugin.mjs +8 -32
- package/dist/esm-node/runtime/plugin.node.mjs +10 -32
- package/dist/esm-node/runtime/pluginCore.mjs +15 -0
- package/dist/esm-node/runtime/register.mjs +19 -0
- package/dist/esm-node/runtime/routeTree.mjs +4 -198
- package/dist/esm-node/runtime/router.mjs +3 -0
- package/dist/esm-node/runtime/rsc/payloadRouter.mjs +35 -1
- package/dist/esm-node/runtime/state.mjs +8 -0
- package/dist/esm-node/runtime/utils.mjs +0 -5
- package/dist/types/cli/index.d.ts +9 -2
- package/dist/types/cli/routeSplitting.d.ts +6 -15
- package/dist/types/cli/tanstackTypes.d.ts +13 -2
- package/dist/types/runtime/hooks.d.ts +8 -18
- package/dist/types/runtime/index.d.ts +6 -4
- package/dist/types/runtime/lifecycle.d.ts +7 -22
- package/dist/types/runtime/loaderBridge.d.ts +48 -0
- package/dist/types/runtime/plugin.d.ts +1 -14
- package/dist/types/runtime/plugin.node.d.ts +1 -14
- package/dist/types/runtime/pluginCore.d.ts +21 -0
- package/dist/types/runtime/register.d.ts +9 -0
- package/dist/types/runtime/routeTree.d.ts +0 -2
- package/dist/types/runtime/router.d.ts +14 -0
- package/dist/types/runtime/state.d.ts +16 -0
- package/dist/types/runtime/types.d.ts +7 -53
- package/package.json +31 -29
- package/rstest.config.mts +6 -0
- package/src/cli/index.ts +111 -29
- package/src/cli/routeSplitting.ts +6 -44
- package/src/cli/tanstackTypes.ts +78 -214
- package/src/runtime/hooks.ts +10 -27
- package/src/runtime/index.tsx +12 -107
- package/src/runtime/lifecycle.ts +16 -151
- package/src/runtime/loaderBridge.ts +257 -0
- package/src/runtime/plugin.node.tsx +14 -77
- package/src/runtime/plugin.tsx +12 -72
- package/src/runtime/pluginCore.ts +48 -0
- package/src/runtime/register.ts +58 -0
- package/src/runtime/routeTree.ts +8 -370
- package/src/runtime/router.ts +15 -0
- package/src/runtime/rsc/payloadRouter.ts +45 -2
- package/src/runtime/state.ts +29 -0
- package/src/runtime/types.ts +20 -67
- package/src/runtime/utils.tsx +3 -6
- package/tests/router/cli.test.ts +297 -31
- package/tests/router/hooks.test.ts +26 -0
- package/tests/router/loaderBridge.test.ts +211 -0
- package/tests/router/packageSurface.test.ts +24 -0
- package/tests/router/register.test.ts +46 -0
- package/tests/router/routeTree.test.ts +65 -180
- package/tests/router/rsc.test.tsx +70 -0
- package/tests/router/tanstackTypes.test.ts +164 -6
- package/dist/esm/runtime/DefaultNotFound.mjs +0 -13
- package/dist/esm-node/runtime/DefaultNotFound.mjs +0 -14
- package/dist/types/runtime/DefaultNotFound.d.ts +0 -2
- package/src/runtime/DefaultNotFound.tsx +0 -15
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
import { InternalRuntimeContext, getGlobalEnableRsc
|
|
4
|
-
import { merge } from "@modern-js/runtime-utils/merge";
|
|
3
|
+
import { InternalRuntimeContext, getGlobalEnableRsc } from "@modern-js/runtime/context";
|
|
5
4
|
import { createRequestContext, storage } from "@modern-js/runtime-utils/node";
|
|
6
5
|
import { time } from "@modern-js/runtime-utils/time";
|
|
7
6
|
import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
|
|
@@ -9,9 +8,10 @@ import { RouterProvider, createMemoryHistory, createRouter } from "@tanstack/rea
|
|
|
9
8
|
import { attachRouterServerSsrUtils } from "@tanstack/router-core/ssr/server";
|
|
10
9
|
import { useContext } from "react";
|
|
11
10
|
import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
|
|
12
|
-
import {
|
|
11
|
+
import { routerProviderRegistryHooks } from "./hooks.mjs";
|
|
13
12
|
import { wrapTanstackSsrHydrationBoundary } from "./hydrationBoundary.mjs";
|
|
14
|
-
import { applyRouterServerPrepareResult, createRouterServerSnapshot } from "./lifecycle.mjs";
|
|
13
|
+
import { applyRouterServerPrepareResult, createRouterServerSnapshot, getRouterRuntimeState } from "./lifecycle.mjs";
|
|
14
|
+
import { getFinalRouteConfig, getMergedRouterConfig } from "./pluginCore.mjs";
|
|
15
15
|
import { createRouteTreeFromRouteObjects, getModernRouteIdsFromMatches } from "./routeTree.mjs";
|
|
16
16
|
import { createTanstackRscServerPayload, handleTanstackRscRedirect } from "./rsc/payloadRouter.mjs";
|
|
17
17
|
import { getModernTanstackRouterFastDefaults } from "./types.mjs";
|
|
@@ -96,15 +96,6 @@ function createGetSsrHref(request) {
|
|
|
96
96
|
const url = new URL(request.url);
|
|
97
97
|
return `${url.pathname}${url.search}${url.hash}`;
|
|
98
98
|
}
|
|
99
|
-
function stripSyntheticNotFoundRoute(routes) {
|
|
100
|
-
return routes.filter((route)=>!('*' === route.path && !route.id && !route.loader)).map((route)=>{
|
|
101
|
-
if (!route.children?.length) return route;
|
|
102
|
-
return {
|
|
103
|
-
...route,
|
|
104
|
-
children: stripSyntheticNotFoundRoute(route.children)
|
|
105
|
-
};
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
99
|
function collectRouterErrors(tanstackRouter) {
|
|
109
100
|
const state = tanstackRouter.state;
|
|
110
101
|
const matches = Array.isArray(state.matches) ? state.matches : [];
|
|
@@ -119,26 +110,14 @@ function collectRouterErrors(tanstackRouter) {
|
|
|
119
110
|
const tanstackRouterPlugin = (userConfig = {})=>{
|
|
120
111
|
const plugin = {
|
|
121
112
|
name: '@modern-js/plugin-router-tanstack',
|
|
122
|
-
registryHooks:
|
|
123
|
-
modifyRoutes: modifyRoutes,
|
|
124
|
-
onAfterCreateRouter: onAfterCreateRouter,
|
|
125
|
-
onAfterHydrateRouter: onAfterHydrateRouter,
|
|
126
|
-
onBeforeCreateRouter: onBeforeCreateRouter,
|
|
127
|
-
onBeforeCreateRoutes: onBeforeCreateRoutes,
|
|
128
|
-
onBeforeHydrateRouter: onBeforeHydrateRouter
|
|
129
|
-
},
|
|
113
|
+
registryHooks: routerProviderRegistryHooks,
|
|
130
114
|
setup: (api)=>{
|
|
131
115
|
api.onBeforeRender(async (context, interrupt)=>{
|
|
132
|
-
const
|
|
133
|
-
const mergedConfig = merge(pluginConfig.router || {}, userConfig);
|
|
116
|
+
const mergedConfig = getMergedRouterConfig(api, userConfig);
|
|
134
117
|
const serializationAdapters = getGlobalEnableRsc() ? (await import("./rsc/server.mjs")).getTanstackRscSerializationAdapters() : void 0;
|
|
135
118
|
const enableRsc = getGlobalEnableRsc();
|
|
136
|
-
const { basename = '',
|
|
137
|
-
const finalRouteConfig =
|
|
138
|
-
routes: getGlobalRoutes(),
|
|
139
|
-
globalApp: getGlobalLayoutApp(),
|
|
140
|
-
...routesConfig
|
|
141
|
-
};
|
|
119
|
+
const { basename = '', createRoutes } = mergedConfig;
|
|
120
|
+
const finalRouteConfig = getFinalRouteConfig(mergedConfig);
|
|
142
121
|
if (!finalRouteConfig.routes && !createRoutes) return;
|
|
143
122
|
const hooks = api.getHooks();
|
|
144
123
|
await hooks.onBeforeCreateRoutes.call(context);
|
|
@@ -146,8 +125,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
|
|
|
146
125
|
routesConfig: finalRouteConfig,
|
|
147
126
|
ssrMode: context.ssrContext?.mode
|
|
148
127
|
}) || [];
|
|
149
|
-
const
|
|
150
|
-
const modifiedRouteObjects = hooks.modifyRoutes.call(normalizedRouteObjects);
|
|
128
|
+
const modifiedRouteObjects = hooks.modifyRoutes.call(routeObjects);
|
|
151
129
|
if (!modifiedRouteObjects.length) return;
|
|
152
130
|
const { request, nonce, baseUrl, loaderFailureMode = 'errorBoundary' } = context.ssrContext;
|
|
153
131
|
const _basename = '/' === baseUrl ? urlJoin(baseUrl, basename || '') : baseUrl;
|
|
@@ -265,7 +243,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
|
|
|
265
243
|
api.wrapRoot((App)=>{
|
|
266
244
|
const getRouteApp = ()=>(props)=>{
|
|
267
245
|
const context = useContext(InternalRuntimeContext);
|
|
268
|
-
const router = context
|
|
246
|
+
const router = getRouterRuntimeState(context)?.instance;
|
|
269
247
|
if (!router) return App ? /*#__PURE__*/ jsx(App, {
|
|
270
248
|
...props
|
|
271
249
|
}) : null;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { getGlobalLayoutApp, getGlobalRoutes } from "@modern-js/runtime/context";
|
|
3
|
+
import { merge } from "@modern-js/runtime-utils/merge";
|
|
4
|
+
function getMergedRouterConfig(api, userConfig) {
|
|
5
|
+
const pluginConfig = api.getRuntimeConfig();
|
|
6
|
+
return merge(pluginConfig.router || {}, userConfig);
|
|
7
|
+
}
|
|
8
|
+
function getFinalRouteConfig(mergedConfig) {
|
|
9
|
+
return {
|
|
10
|
+
routes: getGlobalRoutes(),
|
|
11
|
+
globalApp: getGlobalLayoutApp(),
|
|
12
|
+
...mergedConfig.routesConfig
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export { getFinalRouteConfig, getMergedRouterConfig };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { registerRouterProvider } from "@modern-js/runtime/context";
|
|
3
|
+
import { Form, RouteActionResponseError, useFetcher } from "./dataMutation.mjs";
|
|
4
|
+
import { Outlet } from "./outlet.mjs";
|
|
5
|
+
import { tanstackRouterPlugin } from "./plugin.mjs";
|
|
6
|
+
import { Link, NavLink } from "./prefetchLink.mjs";
|
|
7
|
+
const tanstackRouterProviderFactory = (userConfig)=>tanstackRouterPlugin(userConfig);
|
|
8
|
+
registerRouterProvider('tanstack', tanstackRouterProviderFactory);
|
|
9
|
+
const COMPAT_BINDINGS_SLOT = Symbol.for('@modern-js/plugin-tanstack:runtime-compat-bindings');
|
|
10
|
+
const tanstackRouterCompatBindings = {
|
|
11
|
+
Form: Form,
|
|
12
|
+
Link: Link,
|
|
13
|
+
NavLink: NavLink,
|
|
14
|
+
Outlet: Outlet,
|
|
15
|
+
RouteActionResponseError: RouteActionResponseError,
|
|
16
|
+
useFetcher: useFetcher
|
|
17
|
+
};
|
|
18
|
+
globalThis[COMPAT_BINDINGS_SLOT] ??= tanstackRouterCompatBindings;
|
|
19
|
+
export { tanstackRouterCompatBindings };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
import {
|
|
2
|
+
import { DefaultNotFound } from "@modern-js/runtime/context";
|
|
3
|
+
import { createRootRoute, createRoute, notFound, rootRouteId } from "@tanstack/react-router";
|
|
3
4
|
import { createElement } from "react";
|
|
4
|
-
import {
|
|
5
|
+
import { isRedirectResponse, isResponse, isTanstackRedirect, throwTanstackRedirect } from "./loaderBridge.mjs";
|
|
5
6
|
import { withModernRouteMatchContext } from "./outlet.mjs";
|
|
6
7
|
import { isTanstackRscPayloadNavigationEnabled, loadTanstackRscRouteData } from "./rsc/payloadRouter.mjs";
|
|
7
8
|
function createTanstackRoute(options) {
|
|
@@ -26,23 +27,6 @@ function toTanstackPath(pathname) {
|
|
|
26
27
|
return segment;
|
|
27
28
|
}).join('/');
|
|
28
29
|
}
|
|
29
|
-
function isResponse(value) {
|
|
30
|
-
const record = value;
|
|
31
|
-
return null != record && 'object' == typeof record && 'number' == typeof record.status && 'object' == typeof record.headers;
|
|
32
|
-
}
|
|
33
|
-
function isTanstackRedirect(value) {
|
|
34
|
-
return isResponse(value) && 'object' == typeof value.options;
|
|
35
|
-
}
|
|
36
|
-
const redirectStatusCodes = new Set([
|
|
37
|
-
301,
|
|
38
|
-
302,
|
|
39
|
-
303,
|
|
40
|
-
307,
|
|
41
|
-
308
|
|
42
|
-
]);
|
|
43
|
-
function isRedirectResponse(res) {
|
|
44
|
-
return redirectStatusCodes.has(res.status);
|
|
45
|
-
}
|
|
46
30
|
function isModernDeferredData(value) {
|
|
47
31
|
if (!value || 'object' != typeof value) return false;
|
|
48
32
|
const deferred = value;
|
|
@@ -95,34 +79,6 @@ function createServerLazyImportComponent(lazyImport, fallbackComponent) {
|
|
|
95
79
|
Component.preload = load;
|
|
96
80
|
return Component;
|
|
97
81
|
}
|
|
98
|
-
function isAbsoluteUrl(value) {
|
|
99
|
-
try {
|
|
100
|
-
new URL(value);
|
|
101
|
-
return true;
|
|
102
|
-
} catch {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
function throwTanstackRedirect(location) {
|
|
107
|
-
const target = location || '/';
|
|
108
|
-
if (isAbsoluteUrl(target)) throw redirect({
|
|
109
|
-
href: target
|
|
110
|
-
});
|
|
111
|
-
throw redirect({
|
|
112
|
-
to: target
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
function mapParamsForModernLoader({ modernRoute, params }) {
|
|
116
|
-
if ('nested' === modernRoute.type && modernRoute.path?.includes('*')) {
|
|
117
|
-
const { _splat, ...rest } = params;
|
|
118
|
-
if (void 0 !== _splat) return {
|
|
119
|
-
...rest,
|
|
120
|
-
'*': _splat
|
|
121
|
-
};
|
|
122
|
-
return rest;
|
|
123
|
-
}
|
|
124
|
-
return params;
|
|
125
|
-
}
|
|
126
82
|
function createModernRequest(input, signal) {
|
|
127
83
|
return new Request(input, {
|
|
128
84
|
signal
|
|
@@ -156,52 +112,6 @@ function createModernShouldReload(shouldRevalidate, state) {
|
|
|
156
112
|
return 'boolean' == typeof result ? result : void 0;
|
|
157
113
|
};
|
|
158
114
|
}
|
|
159
|
-
function wrapModernLoader(modernRoute, modernLoader, revalidationState, options = {}) {
|
|
160
|
-
const route = modernRoute;
|
|
161
|
-
return async (ctx)=>{
|
|
162
|
-
try {
|
|
163
|
-
if (revalidationState) rememberRouteLocation(revalidationState, ctx);
|
|
164
|
-
if ('function' == typeof route.lazyImport) try {
|
|
165
|
-
await route.lazyImport();
|
|
166
|
-
} catch {}
|
|
167
|
-
const signal = ctx?.abortController?.signal || ctx?.signal || new AbortController().signal;
|
|
168
|
-
const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
|
|
169
|
-
const href = 'string' == typeof ctx?.location ? ctx.location : ctx?.location?.publicHref || ctx?.location?.href || ctx?.location?.url?.href || '';
|
|
170
|
-
const request = void 0 !== baseRequest ? new Request(baseRequest, {
|
|
171
|
-
signal
|
|
172
|
-
}) : createModernRequest(href, signal);
|
|
173
|
-
const params = mapParamsForModernLoader({
|
|
174
|
-
modernRoute,
|
|
175
|
-
params: ctx.params || {}
|
|
176
|
-
});
|
|
177
|
-
const loadModernData = async ()=>{
|
|
178
|
-
const result = modernLoader ? await modernLoader({
|
|
179
|
-
request,
|
|
180
|
-
params,
|
|
181
|
-
context: ctx?.context?.requestContext
|
|
182
|
-
}) : null;
|
|
183
|
-
return normalizeModernLoaderResponse(result);
|
|
184
|
-
};
|
|
185
|
-
if (options.rscPayloadRouter && isTanstackRscPayloadNavigationEnabled()) return loadTanstackRscRouteData({
|
|
186
|
-
hasClientLoader: route.hasClientLoader || void 0 !== route.clientData,
|
|
187
|
-
loadClientData: loadModernData,
|
|
188
|
-
request,
|
|
189
|
-
routeId: ctx.route?.id
|
|
190
|
-
});
|
|
191
|
-
return loadModernData();
|
|
192
|
-
} catch (err) {
|
|
193
|
-
if (isResponse(err)) {
|
|
194
|
-
if (isTanstackRedirect(err)) throw err;
|
|
195
|
-
if (isRedirectResponse(err)) {
|
|
196
|
-
const location = err.headers.get('Location') || '/';
|
|
197
|
-
throwTanstackRedirect(location);
|
|
198
|
-
}
|
|
199
|
-
if (404 === err.status) throw notFound();
|
|
200
|
-
}
|
|
201
|
-
throw err;
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
115
|
function isRouteObjectPathlessLayout(route) {
|
|
206
116
|
return !route.path && !route.index;
|
|
207
117
|
}
|
|
@@ -276,11 +186,6 @@ function toRouteComponent(routeObject) {
|
|
|
276
186
|
const element = route.element;
|
|
277
187
|
if (element) return ()=>element;
|
|
278
188
|
}
|
|
279
|
-
function toModernRouteComponent(route) {
|
|
280
|
-
const component = route.component || void 0;
|
|
281
|
-
if ('function' == typeof route.lazyImport && component) return createServerLazyImportComponent(route.lazyImport, component);
|
|
282
|
-
return component;
|
|
283
|
-
}
|
|
284
189
|
function toErrorComponent(routeObject) {
|
|
285
190
|
const route = routeObject;
|
|
286
191
|
if (route.ErrorBoundary) return route.ErrorBoundary;
|
|
@@ -356,105 +261,6 @@ function createRouteFromRouteObject(opts) {
|
|
|
356
261
|
}
|
|
357
262
|
return route;
|
|
358
263
|
}
|
|
359
|
-
function createRouteFromModernRoute(opts) {
|
|
360
|
-
const { options = {}, parent, modernRoute } = opts;
|
|
361
|
-
const route = modernRoute;
|
|
362
|
-
const revalidationState = {};
|
|
363
|
-
const modernId = route.id;
|
|
364
|
-
const stableFallbackId = modernId || route._component || route.filename || route.data || ('function' == typeof route.loader ? route.id : void 0);
|
|
365
|
-
const pendingComponent = route.loading || route.pendingComponent;
|
|
366
|
-
const errorComponent = route.error || route.errorComponent;
|
|
367
|
-
const component = toModernRouteComponent(route);
|
|
368
|
-
const modernLoader = route.loader;
|
|
369
|
-
const modernAction = route.action;
|
|
370
|
-
const modernShouldRevalidate = route.shouldRevalidate;
|
|
371
|
-
const shouldReload = createModernShouldReload(modernShouldRevalidate, revalidationState);
|
|
372
|
-
const isPathlessLayout = 'nested' === route.type && 'boolean' != typeof route.index && void 0 === route.path;
|
|
373
|
-
const isIndexRoute = 'nested' === route.type && Boolean(route.index);
|
|
374
|
-
const base = {
|
|
375
|
-
getParentRoute: ()=>parent,
|
|
376
|
-
component: component || void 0,
|
|
377
|
-
pendingComponent: pendingComponent || void 0,
|
|
378
|
-
errorComponent: errorComponent || void 0,
|
|
379
|
-
validateSearch: route.validateSearch,
|
|
380
|
-
loaderDeps: route.loaderDeps,
|
|
381
|
-
staticData: createRouteStaticData({
|
|
382
|
-
modernRouteId: modernId,
|
|
383
|
-
modernRouteAction: modernAction,
|
|
384
|
-
modernRouteHandle: mergeModernRouteHandle(route),
|
|
385
|
-
modernRouteHasAction: route.hasAction || Boolean(modernAction),
|
|
386
|
-
modernRouteHasClientLoader: route.hasClientLoader || void 0 !== route.clientData,
|
|
387
|
-
modernRouteHasLoader: route.hasLoader || 'function' == typeof modernLoader,
|
|
388
|
-
modernRouteIsClientComponent: route.isClientComponent,
|
|
389
|
-
modernRouteLoader: modernLoader,
|
|
390
|
-
modernRouteShouldRevalidate: modernShouldRevalidate
|
|
391
|
-
}),
|
|
392
|
-
loader: wrapModernLoader(modernRoute, modernLoader, revalidationState, options)
|
|
393
|
-
};
|
|
394
|
-
if (route.inValidSSRRoute) base.ssr = false;
|
|
395
|
-
if (shouldReload) base.shouldReload = shouldReload;
|
|
396
|
-
if (isPathlessLayout) base.id = stableFallbackId || 'pathless';
|
|
397
|
-
else {
|
|
398
|
-
const rawPath = route.path;
|
|
399
|
-
base.path = isIndexRoute ? '/' : toTanstackPath(rawPath || '');
|
|
400
|
-
}
|
|
401
|
-
const tanstackRoute = createTanstackRoute(base);
|
|
402
|
-
wrapRouteComponentWithModernContext(tanstackRoute, component, modernId);
|
|
403
|
-
const children = route.children;
|
|
404
|
-
if (children && children.length > 0) {
|
|
405
|
-
const childRoutes = children.map((child)=>createRouteFromModernRoute({
|
|
406
|
-
options,
|
|
407
|
-
parent: tanstackRoute,
|
|
408
|
-
modernRoute: child
|
|
409
|
-
}));
|
|
410
|
-
tanstackRoute.addChildren(childRoutes);
|
|
411
|
-
}
|
|
412
|
-
return tanstackRoute;
|
|
413
|
-
}
|
|
414
|
-
function createRouteTreeFromModernRoutes(routes, options = {}) {
|
|
415
|
-
const rootModern = routes.find((r)=>r && 'nested' === r.type && r.isRoot);
|
|
416
|
-
const rootComponent = rootModern ? toModernRouteComponent(rootModern) : void 0;
|
|
417
|
-
const pendingComponent = rootModern?.loading;
|
|
418
|
-
const errorComponent = rootModern?.error;
|
|
419
|
-
const rootLoader = rootModern?.loader;
|
|
420
|
-
const rootAction = rootModern?.action;
|
|
421
|
-
const rootModernId = rootModern?.id;
|
|
422
|
-
const rootShouldRevalidate = rootModern?.shouldRevalidate;
|
|
423
|
-
const rootRevalidationState = {};
|
|
424
|
-
const rootShouldReload = createModernShouldReload(rootShouldRevalidate, rootRevalidationState);
|
|
425
|
-
const rootRouteOptions = {
|
|
426
|
-
component: rootComponent || void 0,
|
|
427
|
-
pendingComponent: pendingComponent || void 0,
|
|
428
|
-
errorComponent: errorComponent || void 0,
|
|
429
|
-
validateSearch: rootModern?.validateSearch,
|
|
430
|
-
loaderDeps: rootModern?.loaderDeps,
|
|
431
|
-
notFoundComponent: DefaultNotFound,
|
|
432
|
-
staticData: createRouteStaticData({
|
|
433
|
-
modernRouteId: rootModernId,
|
|
434
|
-
modernRouteAction: rootAction,
|
|
435
|
-
modernRouteHandle: rootModern ? mergeModernRouteHandle(rootModern) : void 0,
|
|
436
|
-
modernRouteHasAction: rootModern?.hasAction || Boolean(rootAction),
|
|
437
|
-
modernRouteHasClientLoader: rootModern?.hasClientLoader || void 0 !== rootModern?.clientData,
|
|
438
|
-
modernRouteHasLoader: rootModern?.hasLoader || 'function' == typeof rootLoader,
|
|
439
|
-
modernRouteIsClientComponent: rootModern?.isClientComponent,
|
|
440
|
-
modernRouteLoader: rootLoader,
|
|
441
|
-
modernRouteShouldRevalidate: rootShouldRevalidate
|
|
442
|
-
}),
|
|
443
|
-
loader: rootModern ? wrapModernLoader(rootModern, rootLoader, rootRevalidationState, options) : void 0
|
|
444
|
-
};
|
|
445
|
-
if (rootShouldReload) rootRouteOptions.shouldReload = rootShouldReload;
|
|
446
|
-
if (rootModern?.inValidSSRRoute) rootRouteOptions.ssr = false;
|
|
447
|
-
const rootRoute = createTanstackRootRoute(rootRouteOptions);
|
|
448
|
-
if (rootComponent) rootRoute.options.component = withModernRouteMatchContext(rootComponent, rootRouteId);
|
|
449
|
-
const topLevel = rootModern ? rootModern.children || [] : routes;
|
|
450
|
-
const childRoutes = topLevel.map((child)=>createRouteFromModernRoute({
|
|
451
|
-
options,
|
|
452
|
-
parent: rootRoute,
|
|
453
|
-
modernRoute: child
|
|
454
|
-
}));
|
|
455
|
-
rootRoute.addChildren(childRoutes);
|
|
456
|
-
return rootRoute;
|
|
457
|
-
}
|
|
458
264
|
function getRootLikeRouteObject(routes) {
|
|
459
265
|
return routes.find((route)=>'/' === route.path && !route.index);
|
|
460
266
|
}
|
|
@@ -510,4 +316,4 @@ function getModernRouteIdsFromMatches(router) {
|
|
|
510
316
|
}).filter((id)=>'string' == typeof id);
|
|
511
317
|
return Array.from(new Set(ids));
|
|
512
318
|
}
|
|
513
|
-
export {
|
|
319
|
+
export { createRouteTreeFromRouteObjects, getModernRouteIdsFromMatches };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
+
import { isRouteErrorResponse } from "@modern-js/runtime-utils/router";
|
|
2
3
|
import { notFound, redirect } from "@tanstack/react-router";
|
|
3
4
|
const payloadFetchCache = new Map();
|
|
4
5
|
let payloadDecoder;
|
|
@@ -38,6 +39,39 @@ function toPayloadRoute(match) {
|
|
|
38
39
|
pathnameBase: 'string' == typeof match.pathnameBase ? match.pathnameBase : pathname
|
|
39
40
|
};
|
|
40
41
|
}
|
|
42
|
+
function shouldRedactServerError(status = 500) {
|
|
43
|
+
return status >= 500 && 'development' !== process.env.NODE_ENV && 'test' !== process.env.NODE_ENV;
|
|
44
|
+
}
|
|
45
|
+
function serializePayloadError(error) {
|
|
46
|
+
if (isRouteErrorResponse(error)) {
|
|
47
|
+
if (shouldRedactServerError(error.status)) return {
|
|
48
|
+
status: error.status,
|
|
49
|
+
statusText: 'Internal Server Error',
|
|
50
|
+
data: 'Unexpected Server Error',
|
|
51
|
+
__type: 'RouteErrorResponse'
|
|
52
|
+
};
|
|
53
|
+
return {
|
|
54
|
+
...error,
|
|
55
|
+
__type: 'RouteErrorResponse'
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (error instanceof Error) {
|
|
59
|
+
if (shouldRedactServerError()) return {
|
|
60
|
+
message: 'Unexpected Server Error',
|
|
61
|
+
stack: void 0,
|
|
62
|
+
__type: 'Error'
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
message: error.message,
|
|
66
|
+
stack: error.stack,
|
|
67
|
+
__type: 'Error',
|
|
68
|
+
...'Error' !== error.name ? {
|
|
69
|
+
__subType: error.name
|
|
70
|
+
} : {}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return error;
|
|
74
|
+
}
|
|
41
75
|
function createTanstackRscServerPayload(router, options = {}) {
|
|
42
76
|
const matches = Array.isArray(router.state?.matches) ? router.state.matches : [];
|
|
43
77
|
const routes = [];
|
|
@@ -48,7 +82,7 @@ function createTanstackRscServerPayload(router, options = {}) {
|
|
|
48
82
|
if (payloadRoute) {
|
|
49
83
|
routes.push(payloadRoute);
|
|
50
84
|
if ('loaderData' in match && void 0 !== match.loaderData && !(options.omitClientLoaderData && payloadRoute.hasClientLoader)) loaderData[payloadRoute.id] = match.loaderData;
|
|
51
|
-
if (void 0 !== match.error) errors[payloadRoute.id] = match.error;
|
|
85
|
+
if (void 0 !== match.error) errors[payloadRoute.id] = serializePayloadError(match.error);
|
|
52
86
|
}
|
|
53
87
|
}
|
|
54
88
|
return {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { getRouterRuntimeState } from "@modern-js/runtime/context";
|
|
3
|
+
function getTanstackRouterState(context) {
|
|
4
|
+
const state = getRouterRuntimeState(context);
|
|
5
|
+
if (void 0 === state || 'tanstack' !== state.framework) return;
|
|
6
|
+
return state;
|
|
7
|
+
}
|
|
8
|
+
export { getTanstackRouterState };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import react from "react";
|
|
4
|
-
import { DefaultNotFound } from "./DefaultNotFound.mjs";
|
|
5
4
|
function getRouteObjects(routes, { globalApp, ssrMode, props }) {
|
|
6
5
|
const createLayoutElement = (Component)=>{
|
|
7
6
|
const GlobalLayout = globalApp;
|
|
@@ -58,10 +57,6 @@ function getRouteObjects(routes, { globalApp, ssrMode, props }) {
|
|
|
58
57
|
};
|
|
59
58
|
routeObjects.push(routeObject);
|
|
60
59
|
}
|
|
61
|
-
routeObjects.push({
|
|
62
|
-
path: '*',
|
|
63
|
-
element: /*#__PURE__*/ jsx(DefaultNotFound, {})
|
|
64
|
-
});
|
|
65
60
|
return routeObjects;
|
|
66
61
|
}
|
|
67
62
|
function createRouteObjectsFromConfig({ routesConfig, props, ssrMode }) {
|
|
@@ -2,8 +2,8 @@ import type { AppTools, AppToolsContext, CliPlugin } from '@modern-js/app-tools'
|
|
|
2
2
|
import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
|
|
3
3
|
import { type TanstackRouteCodeSplittingOption } from './routeSplitting';
|
|
4
4
|
export type { TanstackRouteCodeSplittingOption, TanstackRsbuildRouteSplittingProfile, } from './routeSplitting';
|
|
5
|
-
export { createTanstackRsbuildRouteSplittingProfile,
|
|
6
|
-
export { collectCanonicalRoutesForEntry, generateTanstackRouterTypesSourceForEntry,
|
|
5
|
+
export { createTanstackRsbuildRouteSplittingProfile, resolveTanstackRouteCodeSplittingEnabled, } from './routeSplitting';
|
|
6
|
+
export { type CollectCanonicalRoutesOptions, collectCanonicalRoutesForEntry, generateTanstackRouterTypesSourceForEntry, } from './tanstackTypes';
|
|
7
7
|
export type TanstackRouterPluginOptions = {
|
|
8
8
|
routesDir?: string;
|
|
9
9
|
generatedDirName?: string;
|
|
@@ -21,6 +21,13 @@ export declare function writeTanstackRouterTypesForEntries(opts: {
|
|
|
21
21
|
appContext: AppToolsContext;
|
|
22
22
|
generatedDirName?: string;
|
|
23
23
|
routesByEntry: Record<string, (NestedRouteForCli | PageRoute)[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Whether `@modern-js/plugin-i18n` is actually installed in the app. The
|
|
26
|
+
* `register.gen.d.ts` augmentation of '@modern-js/plugin-i18n/runtime' is
|
|
27
|
+
* only emitted when this is true — otherwise apps with a hand-rolled
|
|
28
|
+
* `/:lang/` param would fail typechecking on an unresolvable module.
|
|
29
|
+
*/
|
|
30
|
+
i18nPluginInstalled?: boolean;
|
|
24
31
|
}): Promise<void>;
|
|
25
32
|
export declare function tanstackRouterPlugin(options?: TanstackRouterPluginOptions): CliPlugin<AppTools>;
|
|
26
33
|
export default tanstackRouterPlugin;
|
|
@@ -7,23 +7,14 @@ export type TanstackRsbuildRouteSplittingProfile = {
|
|
|
7
7
|
splitRouteChunks: boolean;
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
|
-
modernRouteChunks: {
|
|
11
|
-
enabled: boolean;
|
|
12
|
-
owner: 'modern';
|
|
13
|
-
};
|
|
14
|
-
builderChunkSplit: {
|
|
15
|
-
owner: 'modern-rsbuild';
|
|
16
|
-
preserved: true;
|
|
17
|
-
};
|
|
18
|
-
tanstackStartRspackSplitter: {
|
|
19
|
-
compatible: boolean;
|
|
20
|
-
reason: string;
|
|
21
|
-
clientDeleteNodes: string[];
|
|
22
|
-
routeFactoryCalls: string[];
|
|
23
|
-
};
|
|
24
10
|
};
|
|
25
|
-
export declare function isTanstackStartRouteModuleSource(source: string): boolean;
|
|
26
11
|
export declare function resolveTanstackRouteCodeSplittingEnabled(option?: TanstackRouteCodeSplittingOption): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Route chunking for TanStack entries is owned by Modern's
|
|
14
|
+
* `output.splitRouteChunks`; the TanStack Start Rspack splitter does not
|
|
15
|
+
* apply because Modern generates TanStack route trees from Modern route
|
|
16
|
+
* metadata rather than TanStack file-route factory modules.
|
|
17
|
+
*/
|
|
27
18
|
export declare function createTanstackRsbuildRouteSplittingProfile(opts: {
|
|
28
19
|
routeCodeSplitting?: TanstackRouteCodeSplittingOption;
|
|
29
20
|
}): TanstackRsbuildRouteSplittingProfile;
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import type { AppToolsContext } from '@modern-js/app-tools';
|
|
2
2
|
import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
|
|
3
|
+
export type CollectCanonicalRoutesOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* Whether a leading `:lang`/`:locale`/`:language` route param may be
|
|
6
|
+
* treated as an i18n locale prefix. This MUST only be enabled when
|
|
7
|
+
* `@modern-js/plugin-i18n` is actually installed: the emitted
|
|
8
|
+
* `declare module '@modern-js/plugin-i18n/runtime'` augmentation breaks
|
|
9
|
+
* typechecking (TS2664) for apps that hand-roll a `/:lang/` param without
|
|
10
|
+
* the plugin. Routes carrying `modernCanonicalPath` metadata are always
|
|
11
|
+
* honored — only plugin-i18n produces them.
|
|
12
|
+
*/
|
|
13
|
+
localeParamHeuristic?: boolean;
|
|
14
|
+
};
|
|
3
15
|
/**
|
|
4
16
|
* Derive the canonical (language-agnostic) route map for an entry: the
|
|
5
17
|
* leading locale param is stripped and localized physical variants (routes
|
|
@@ -8,8 +20,7 @@ import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
|
|
|
8
20
|
* i18n routing surface (no locale param and no localized variants), so plain
|
|
9
21
|
* TanStack apps never get a `@modern-js/plugin-i18n` module augmentation.
|
|
10
22
|
*/
|
|
11
|
-
export declare function collectCanonicalRoutesForEntry(routes: (NestedRouteForCli | PageRoute)[]): Record<string, string> | null;
|
|
12
|
-
export declare function isTanstackRouterFrameworkEnabled(appContext: AppToolsContext): Promise<boolean>;
|
|
23
|
+
export declare function collectCanonicalRoutesForEntry(routes: (NestedRouteForCli | PageRoute)[], options?: CollectCanonicalRoutesOptions): Record<string, string> | null;
|
|
13
24
|
export declare function generateTanstackRouterTypesSourceForEntry(opts: {
|
|
14
25
|
appContext: AppToolsContext;
|
|
15
26
|
entryName: string;
|
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
declare const onAfterHydrateRouter: import("@modern-js/plugin").SyncHook<(context: RouterLifecycleContext) => void>;
|
|
10
|
-
export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter, };
|
|
11
|
-
export type RouterExtendsHooks = {
|
|
12
|
-
modifyRoutes: typeof modifyRoutes;
|
|
13
|
-
onBeforeCreateRoutes: typeof onBeforeCreateRoutes;
|
|
14
|
-
onBeforeCreateRouter: typeof onBeforeCreateRouter;
|
|
15
|
-
onAfterCreateRouter: typeof onAfterCreateRouter;
|
|
16
|
-
onBeforeHydrateRouter: typeof onBeforeHydrateRouter;
|
|
17
|
-
onAfterHydrateRouter: typeof onAfterHydrateRouter;
|
|
18
|
-
};
|
|
1
|
+
/**
|
|
2
|
+
* The router hooks are owned by @modern-js/runtime — this module re-exports
|
|
3
|
+
* the canonical instances through the `/context` seam, so the TanStack
|
|
4
|
+
* provider taps and calls the exact same hooks the built-in router wrapper
|
|
5
|
+
* registers. Creating separate hook instances here would silently split the
|
|
6
|
+
* hook registry between the wrapper and this provider.
|
|
7
|
+
*/
|
|
8
|
+
export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter, type RouterExtendsHooks, routerProviderRegistryHooks, } from '@modern-js/runtime/context';
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
import './register';
|
|
2
|
+
export * from '@tanstack/react-router';
|
|
3
3
|
export type { Fetcher, FetcherState, FetcherSubmitOptions, FormProps, SubmitOptions, } from './dataMutation';
|
|
4
4
|
export { Form, RouteActionResponseError, useFetcher, } from './dataMutation';
|
|
5
|
+
export type { ModernRouterContext } from './loaderBridge';
|
|
6
|
+
export { createRouteStaticData, isAbsoluteUrl, modernLoaderToTanstack, throwTanstackRedirect, } from './loaderBridge';
|
|
5
7
|
export { Outlet } from './outlet';
|
|
6
8
|
export { tanstackRouterPlugin, tanstackRouterPlugin as default, } from './plugin';
|
|
7
9
|
export type { LinkProps, NavLinkProps, PrefetchBehavior, } from './prefetchLink';
|
|
8
10
|
export { Link, NavLink } from './prefetchLink';
|
|
9
|
-
export type {
|
|
10
|
-
export {
|
|
11
|
+
export type { TanstackRouterState } from './state';
|
|
12
|
+
export { getTanstackRouterState } from './state';
|
|
11
13
|
export type { RouterConfig } from './types';
|
|
12
14
|
export { getModernTanstackRouterFastDefaults, modernTanstackRouterFastDefaults, } from './types';
|
|
@@ -1,22 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
routes: RouteObject[];
|
|
9
|
-
runtimeContext: TInternalRuntimeContext;
|
|
10
|
-
basename?: string;
|
|
11
|
-
hydrationData?: unknown;
|
|
12
|
-
router?: unknown;
|
|
13
|
-
matches?: RouterRouteMatchSnapshot[];
|
|
14
|
-
cleanup?: () => void | Promise<void>;
|
|
15
|
-
serverSnapshot?: InternalRouterServerSnapshot;
|
|
16
|
-
};
|
|
17
|
-
type RouterSnapshotLike = Partial<InternalRouterServerSnapshot>;
|
|
18
|
-
export declare function createRouterServerSnapshot(state: RouterSnapshotLike): InternalRouterServerSnapshot;
|
|
19
|
-
export declare function createRouterRuntimeState(state: InternalRouterRuntimeState): InternalRouterRuntimeState;
|
|
20
|
-
export declare function applyRouterRuntimeState(runtimeContext: TInternalRuntimeContext, state: InternalRouterRuntimeState): TInternalRuntimeContext;
|
|
21
|
-
export declare function applyRouterServerPrepareResult(runtimeContext: TInternalRuntimeContext, result: RouterServerPrepareResult): TInternalRuntimeContext;
|
|
22
|
-
export {};
|
|
1
|
+
/**
|
|
2
|
+
* The router runtime state helpers are owned by @modern-js/runtime (the same
|
|
3
|
+
* implementation backs the built-in react-router provider and the SSR
|
|
4
|
+
* pipeline). This module only re-exports them so every router provider
|
|
5
|
+
* writes to the exact same runtime-context extension slot.
|
|
6
|
+
*/
|
|
7
|
+
export { applyRouterRuntimeState, applyRouterServerPrepareResult, createRouterRuntimeState, createRouterServerSnapshot, getRouterRuntimeState, getRouterServerSnapshot, type RouterLifecycleContext, type RouterLifecyclePhase, } from '@modern-js/runtime/context';
|