@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.99 → 3.4.0-ultramodern.0
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 +80 -34
- package/dist/cjs/cli/routeSplitting.js +13 -41
- package/dist/cjs/cli/tanstackTypes.js +114 -200
- package/dist/cjs/cli.js +12 -8
- package/dist/cjs/runtime/basepathRewrite.js +12 -8
- package/dist/cjs/runtime/dataMutation.js +9 -5
- package/dist/cjs/runtime/hooks.js +20 -19
- package/dist/cjs/runtime/hydrationBoundary.js +12 -7
- package/dist/cjs/runtime/index.js +66 -54
- package/dist/cjs/runtime/lifecycle.js +21 -91
- package/dist/cjs/runtime/loaderBridge.js +173 -0
- package/dist/cjs/runtime/outlet.js +58 -0
- package/dist/cjs/runtime/plugin.js +190 -110
- package/dist/cjs/runtime/plugin.node.js +25 -40
- package/dist/cjs/runtime/plugin.worker.js +9 -5
- package/dist/cjs/runtime/pluginCore.js +55 -0
- package/dist/cjs/runtime/prefetchLink.js +10 -6
- package/dist/cjs/runtime/register.js +56 -0
- package/dist/cjs/runtime/routeTree.js +30 -212
- package/dist/cjs/runtime/router.js +41 -0
- package/dist/cjs/runtime/rsc/ClientSlot.js +9 -5
- package/dist/cjs/runtime/rsc/CompositeComponent.js +9 -5
- package/dist/cjs/runtime/rsc/ReplayableStream.js +14 -9
- package/dist/cjs/runtime/rsc/RscNodeRenderer.js +9 -5
- package/dist/cjs/runtime/rsc/SlotContext.js +9 -5
- package/dist/cjs/runtime/rsc/client.js +9 -5
- package/dist/cjs/runtime/rsc/createRscProxy.js +9 -5
- package/dist/cjs/runtime/rsc/index.js +9 -5
- package/dist/cjs/runtime/rsc/payloadRouter.js +44 -6
- package/dist/cjs/runtime/rsc/server.js +9 -5
- package/dist/cjs/runtime/rsc/slotUsageSanitizer.js +9 -5
- package/dist/cjs/runtime/rsc/symbols.js +20 -15
- package/dist/cjs/runtime/state.js +45 -0
- package/dist/cjs/runtime/types.js +13 -9
- package/dist/cjs/runtime/utils.js +9 -11
- package/dist/cjs/runtime.js +9 -5
- package/dist/esm/cli/index.mjs +73 -28
- package/dist/esm/cli/routeSplitting.mjs +1 -30
- package/dist/esm/cli/tanstackTypes.mjs +100 -190
- package/dist/esm/runtime/hooks.mjs +1 -8
- package/dist/esm/runtime/hydrationBoundary.mjs +3 -2
- 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/outlet.mjs +17 -0
- package/dist/esm/runtime/plugin.mjs +183 -107
- package/dist/esm/runtime/plugin.node.mjs +19 -38
- package/dist/esm/runtime/pluginCore.mjs +14 -0
- package/dist/esm/runtime/prefetchLink.mjs +1 -1
- package/dist/esm/runtime/register.mjs +18 -0
- package/dist/esm/runtime/routeTree.mjs +15 -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 -6
- package/dist/esm-node/cli/index.mjs +73 -28
- package/dist/esm-node/cli/routeSplitting.mjs +1 -30
- package/dist/esm-node/cli/tanstackTypes.mjs +100 -190
- package/dist/esm-node/runtime/hooks.mjs +1 -8
- package/dist/esm-node/runtime/hydrationBoundary.mjs +3 -2
- 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/outlet.mjs +18 -0
- package/dist/esm-node/runtime/plugin.mjs +183 -107
- package/dist/esm-node/runtime/plugin.node.mjs +19 -38
- package/dist/esm-node/runtime/pluginCore.mjs +15 -0
- package/dist/esm-node/runtime/prefetchLink.mjs +1 -1
- package/dist/esm-node/runtime/register.mjs +19 -0
- package/dist/esm-node/runtime/routeTree.mjs +15 -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 -6
- package/dist/types/cli/index.d.ts +11 -2
- package/dist/types/cli/routeSplitting.d.ts +6 -15
- package/dist/types/cli/tanstackTypes.d.ts +21 -1
- package/dist/types/runtime/hooks.d.ts +8 -33
- package/dist/types/runtime/index.d.ts +6 -3
- package/dist/types/runtime/lifecycle.d.ts +7 -22
- package/dist/types/runtime/loaderBridge.d.ts +48 -0
- package/dist/types/runtime/outlet.d.ts +2 -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 +40 -38
- package/rstest.config.mts +6 -0
- package/src/cli/index.ts +146 -24
- package/src/cli/routeSplitting.ts +6 -44
- package/src/cli/tanstackTypes.ts +203 -208
- package/src/runtime/hooks.ts +10 -27
- package/src/runtime/hydrationBoundary.tsx +5 -5
- package/src/runtime/index.tsx +12 -14
- package/src/runtime/lifecycle.ts +16 -151
- package/src/runtime/loaderBridge.ts +257 -0
- package/src/runtime/outlet.tsx +48 -0
- package/src/runtime/plugin.node.tsx +28 -83
- package/src/runtime/plugin.tsx +350 -202
- package/src/runtime/pluginCore.ts +48 -0
- package/src/runtime/prefetchLink.tsx +1 -1
- package/src/runtime/register.ts +58 -0
- package/src/runtime/routeTree.ts +41 -365
- package/src/runtime/router.ts +15 -0
- package/src/runtime/rsc/payloadRouter.ts +45 -2
- package/src/runtime/ssr-shim.d.ts +1 -3
- package/src/runtime/state.ts +29 -0
- package/src/runtime/types.ts +20 -67
- package/src/runtime/utils.tsx +3 -7
- package/tests/router/cli.test.ts +373 -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/prefetchLink.test.tsx +43 -7
- package/tests/router/register.test.ts +46 -0
- package/tests/router/routeTree.test.ts +176 -139
- package/tests/router/rsc.test.tsx +70 -0
- package/tests/router/tanstackTypes.test.ts +395 -7
- package/dist/cjs/runtime/DefaultNotFound.js +0 -47
- 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,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DefaultNotFound } from "@modern-js/runtime/context";
|
|
2
|
+
import { createRootRoute, createRoute, notFound, rootRouteId } from "@tanstack/react-router";
|
|
2
3
|
import { createElement } from "react";
|
|
3
|
-
import {
|
|
4
|
+
import { isRedirectResponse, isResponse, isTanstackRedirect, throwTanstackRedirect } from "./loaderBridge.mjs";
|
|
5
|
+
import { withModernRouteMatchContext } from "./outlet.mjs";
|
|
4
6
|
import { isTanstackRscPayloadNavigationEnabled, loadTanstackRscRouteData } from "./rsc/payloadRouter.mjs";
|
|
5
7
|
function createTanstackRoute(options) {
|
|
6
8
|
return createRoute(options);
|
|
@@ -8,6 +10,10 @@ function createTanstackRoute(options) {
|
|
|
8
10
|
function createTanstackRootRoute(options) {
|
|
9
11
|
return createRootRoute(options);
|
|
10
12
|
}
|
|
13
|
+
function wrapRouteComponentWithModernContext(route, component, routeId) {
|
|
14
|
+
const routeMatchId = routeId || route.id;
|
|
15
|
+
if (component && routeMatchId) route.options.component = withModernRouteMatchContext(component, routeMatchId);
|
|
16
|
+
}
|
|
11
17
|
function toTanstackPath(pathname) {
|
|
12
18
|
return pathname.split('/').map((segment)=>{
|
|
13
19
|
if (!segment) return segment;
|
|
@@ -20,23 +26,6 @@ function toTanstackPath(pathname) {
|
|
|
20
26
|
return segment;
|
|
21
27
|
}).join('/');
|
|
22
28
|
}
|
|
23
|
-
function isResponse(value) {
|
|
24
|
-
const record = value;
|
|
25
|
-
return null != record && 'object' == typeof record && 'number' == typeof record.status && 'object' == typeof record.headers;
|
|
26
|
-
}
|
|
27
|
-
function isTanstackRedirect(value) {
|
|
28
|
-
return isResponse(value) && 'object' == typeof value.options;
|
|
29
|
-
}
|
|
30
|
-
const redirectStatusCodes = new Set([
|
|
31
|
-
301,
|
|
32
|
-
302,
|
|
33
|
-
303,
|
|
34
|
-
307,
|
|
35
|
-
308
|
|
36
|
-
]);
|
|
37
|
-
function isRedirectResponse(res) {
|
|
38
|
-
return redirectStatusCodes.has(res.status);
|
|
39
|
-
}
|
|
40
29
|
function isModernDeferredData(value) {
|
|
41
30
|
if (!value || 'object' != typeof value) return false;
|
|
42
31
|
const deferred = value;
|
|
@@ -89,34 +78,6 @@ function createServerLazyImportComponent(lazyImport, fallbackComponent) {
|
|
|
89
78
|
Component.preload = load;
|
|
90
79
|
return Component;
|
|
91
80
|
}
|
|
92
|
-
function isAbsoluteUrl(value) {
|
|
93
|
-
try {
|
|
94
|
-
new URL(value);
|
|
95
|
-
return true;
|
|
96
|
-
} catch {
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
function throwTanstackRedirect(location) {
|
|
101
|
-
const target = location || '/';
|
|
102
|
-
if (isAbsoluteUrl(target)) throw redirect({
|
|
103
|
-
href: target
|
|
104
|
-
});
|
|
105
|
-
throw redirect({
|
|
106
|
-
to: target
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
function mapParamsForModernLoader({ modernRoute, params }) {
|
|
110
|
-
if ('nested' === modernRoute.type && modernRoute.path?.includes('*')) {
|
|
111
|
-
const { _splat, ...rest } = params;
|
|
112
|
-
if (void 0 !== _splat) return {
|
|
113
|
-
...rest,
|
|
114
|
-
'*': _splat
|
|
115
|
-
};
|
|
116
|
-
return rest;
|
|
117
|
-
}
|
|
118
|
-
return params;
|
|
119
|
-
}
|
|
120
81
|
function createModernRequest(input, signal) {
|
|
121
82
|
return new Request(input, {
|
|
122
83
|
signal
|
|
@@ -150,52 +111,6 @@ function createModernShouldReload(shouldRevalidate, state) {
|
|
|
150
111
|
return 'boolean' == typeof result ? result : void 0;
|
|
151
112
|
};
|
|
152
113
|
}
|
|
153
|
-
function wrapModernLoader(modernRoute, modernLoader, revalidationState, options = {}) {
|
|
154
|
-
const route = modernRoute;
|
|
155
|
-
return async (ctx)=>{
|
|
156
|
-
try {
|
|
157
|
-
if (revalidationState) rememberRouteLocation(revalidationState, ctx);
|
|
158
|
-
if ('function' == typeof route.lazyImport) try {
|
|
159
|
-
await route.lazyImport();
|
|
160
|
-
} catch {}
|
|
161
|
-
const signal = ctx?.abortController?.signal || ctx?.signal || new AbortController().signal;
|
|
162
|
-
const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
|
|
163
|
-
const href = 'string' == typeof ctx?.location ? ctx.location : ctx?.location?.publicHref || ctx?.location?.href || ctx?.location?.url?.href || '';
|
|
164
|
-
const request = void 0 !== baseRequest ? new Request(baseRequest, {
|
|
165
|
-
signal
|
|
166
|
-
}) : createModernRequest(href, signal);
|
|
167
|
-
const params = mapParamsForModernLoader({
|
|
168
|
-
modernRoute,
|
|
169
|
-
params: ctx.params || {}
|
|
170
|
-
});
|
|
171
|
-
const loadModernData = async ()=>{
|
|
172
|
-
const result = modernLoader ? await modernLoader({
|
|
173
|
-
request,
|
|
174
|
-
params,
|
|
175
|
-
context: ctx?.context?.requestContext
|
|
176
|
-
}) : null;
|
|
177
|
-
return normalizeModernLoaderResponse(result);
|
|
178
|
-
};
|
|
179
|
-
if (options.rscPayloadRouter && isTanstackRscPayloadNavigationEnabled()) return loadTanstackRscRouteData({
|
|
180
|
-
hasClientLoader: route.hasClientLoader || void 0 !== route.clientData,
|
|
181
|
-
loadClientData: loadModernData,
|
|
182
|
-
request,
|
|
183
|
-
routeId: ctx.route?.id
|
|
184
|
-
});
|
|
185
|
-
return loadModernData();
|
|
186
|
-
} catch (err) {
|
|
187
|
-
if (isResponse(err)) {
|
|
188
|
-
if (isTanstackRedirect(err)) throw err;
|
|
189
|
-
if (isRedirectResponse(err)) {
|
|
190
|
-
const location = err.headers.get('Location') || '/';
|
|
191
|
-
throwTanstackRedirect(location);
|
|
192
|
-
}
|
|
193
|
-
if (404 === err.status) throw notFound();
|
|
194
|
-
}
|
|
195
|
-
throw err;
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
114
|
function isRouteObjectPathlessLayout(route) {
|
|
200
115
|
return !route.path && !route.index;
|
|
201
116
|
}
|
|
@@ -270,11 +185,6 @@ function toRouteComponent(routeObject) {
|
|
|
270
185
|
const element = route.element;
|
|
271
186
|
if (element) return ()=>element;
|
|
272
187
|
}
|
|
273
|
-
function toModernRouteComponent(route) {
|
|
274
|
-
const component = route.component || void 0;
|
|
275
|
-
if ('function' == typeof route.lazyImport && component) return createServerLazyImportComponent(route.lazyImport, component);
|
|
276
|
-
return component;
|
|
277
|
-
}
|
|
278
188
|
function toErrorComponent(routeObject) {
|
|
279
189
|
const route = routeObject;
|
|
280
190
|
if (route.ErrorBoundary) return route.ErrorBoundary;
|
|
@@ -312,9 +222,10 @@ function createRouteFromRouteObject(opts) {
|
|
|
312
222
|
const shouldRevalidate = modernRouteObject.shouldRevalidate;
|
|
313
223
|
const shouldReload = createModernShouldReload(shouldRevalidate, revalidationState);
|
|
314
224
|
const stableFallbackId = routeObject.id || modernRouteObject.file || routeObject.path || 'pathless';
|
|
225
|
+
const component = toRouteComponent(routeObject);
|
|
315
226
|
const base = {
|
|
316
227
|
getParentRoute: ()=>parent,
|
|
317
|
-
component
|
|
228
|
+
component,
|
|
318
229
|
pendingComponent: toPendingComponent(routeObject),
|
|
319
230
|
errorComponent: toErrorComponent(routeObject),
|
|
320
231
|
validateSearch: modernRouteObject.validateSearch,
|
|
@@ -337,6 +248,7 @@ function createRouteFromRouteObject(opts) {
|
|
|
337
248
|
if (isRouteObjectPathlessLayout(routeObject)) base.id = stableFallbackId;
|
|
338
249
|
else base.path = routeObject.index ? '/' : toTanstackPath(routeObject.path || '');
|
|
339
250
|
const route = createTanstackRoute(base);
|
|
251
|
+
wrapRouteComponentWithModernContext(route, component, routeObject.id);
|
|
340
252
|
const children = routeObject.children;
|
|
341
253
|
if (children && children.length > 0) {
|
|
342
254
|
const childRoutes = children.map((child)=>createRouteFromRouteObject({
|
|
@@ -348,103 +260,6 @@ function createRouteFromRouteObject(opts) {
|
|
|
348
260
|
}
|
|
349
261
|
return route;
|
|
350
262
|
}
|
|
351
|
-
function createRouteFromModernRoute(opts) {
|
|
352
|
-
const { options = {}, parent, modernRoute } = opts;
|
|
353
|
-
const route = modernRoute;
|
|
354
|
-
const revalidationState = {};
|
|
355
|
-
const modernId = route.id;
|
|
356
|
-
const stableFallbackId = modernId || route._component || route.filename || route.data || ('function' == typeof route.loader ? route.id : void 0);
|
|
357
|
-
const pendingComponent = route.loading || route.pendingComponent;
|
|
358
|
-
const errorComponent = route.error || route.errorComponent;
|
|
359
|
-
const component = toModernRouteComponent(route);
|
|
360
|
-
const modernLoader = route.loader;
|
|
361
|
-
const modernAction = route.action;
|
|
362
|
-
const modernShouldRevalidate = route.shouldRevalidate;
|
|
363
|
-
const shouldReload = createModernShouldReload(modernShouldRevalidate, revalidationState);
|
|
364
|
-
const isPathlessLayout = 'nested' === route.type && 'boolean' != typeof route.index && void 0 === route.path;
|
|
365
|
-
const isIndexRoute = 'nested' === route.type && Boolean(route.index);
|
|
366
|
-
const base = {
|
|
367
|
-
getParentRoute: ()=>parent,
|
|
368
|
-
component: component || void 0,
|
|
369
|
-
pendingComponent: pendingComponent || void 0,
|
|
370
|
-
errorComponent: errorComponent || void 0,
|
|
371
|
-
validateSearch: route.validateSearch,
|
|
372
|
-
loaderDeps: route.loaderDeps,
|
|
373
|
-
staticData: createRouteStaticData({
|
|
374
|
-
modernRouteId: modernId,
|
|
375
|
-
modernRouteAction: modernAction,
|
|
376
|
-
modernRouteHandle: mergeModernRouteHandle(route),
|
|
377
|
-
modernRouteHasAction: route.hasAction || Boolean(modernAction),
|
|
378
|
-
modernRouteHasClientLoader: route.hasClientLoader || void 0 !== route.clientData,
|
|
379
|
-
modernRouteHasLoader: route.hasLoader || 'function' == typeof modernLoader,
|
|
380
|
-
modernRouteIsClientComponent: route.isClientComponent,
|
|
381
|
-
modernRouteLoader: modernLoader,
|
|
382
|
-
modernRouteShouldRevalidate: modernShouldRevalidate
|
|
383
|
-
}),
|
|
384
|
-
loader: wrapModernLoader(modernRoute, modernLoader, revalidationState, options)
|
|
385
|
-
};
|
|
386
|
-
if (route.inValidSSRRoute) base.ssr = false;
|
|
387
|
-
if (shouldReload) base.shouldReload = shouldReload;
|
|
388
|
-
if (isPathlessLayout) base.id = stableFallbackId || 'pathless';
|
|
389
|
-
else {
|
|
390
|
-
const rawPath = route.path;
|
|
391
|
-
base.path = isIndexRoute ? '/' : toTanstackPath(rawPath || '');
|
|
392
|
-
}
|
|
393
|
-
const tanstackRoute = createTanstackRoute(base);
|
|
394
|
-
const children = route.children;
|
|
395
|
-
if (children && children.length > 0) {
|
|
396
|
-
const childRoutes = children.map((child)=>createRouteFromModernRoute({
|
|
397
|
-
options,
|
|
398
|
-
parent: tanstackRoute,
|
|
399
|
-
modernRoute: child
|
|
400
|
-
}));
|
|
401
|
-
tanstackRoute.addChildren(childRoutes);
|
|
402
|
-
}
|
|
403
|
-
return tanstackRoute;
|
|
404
|
-
}
|
|
405
|
-
function createRouteTreeFromModernRoutes(routes, options = {}) {
|
|
406
|
-
const rootModern = routes.find((r)=>r && 'nested' === r.type && r.isRoot);
|
|
407
|
-
const rootComponent = rootModern ? toModernRouteComponent(rootModern) : void 0;
|
|
408
|
-
const pendingComponent = rootModern?.loading;
|
|
409
|
-
const errorComponent = rootModern?.error;
|
|
410
|
-
const rootLoader = rootModern?.loader;
|
|
411
|
-
const rootAction = rootModern?.action;
|
|
412
|
-
const rootModernId = rootModern?.id;
|
|
413
|
-
const rootShouldRevalidate = rootModern?.shouldRevalidate;
|
|
414
|
-
const rootRevalidationState = {};
|
|
415
|
-
const rootShouldReload = createModernShouldReload(rootShouldRevalidate, rootRevalidationState);
|
|
416
|
-
const rootRouteOptions = {
|
|
417
|
-
component: rootComponent || void 0,
|
|
418
|
-
pendingComponent: pendingComponent || void 0,
|
|
419
|
-
errorComponent: errorComponent || void 0,
|
|
420
|
-
validateSearch: rootModern?.validateSearch,
|
|
421
|
-
loaderDeps: rootModern?.loaderDeps,
|
|
422
|
-
notFoundComponent: DefaultNotFound,
|
|
423
|
-
staticData: createRouteStaticData({
|
|
424
|
-
modernRouteId: rootModernId,
|
|
425
|
-
modernRouteAction: rootAction,
|
|
426
|
-
modernRouteHandle: rootModern ? mergeModernRouteHandle(rootModern) : void 0,
|
|
427
|
-
modernRouteHasAction: rootModern?.hasAction || Boolean(rootAction),
|
|
428
|
-
modernRouteHasClientLoader: rootModern?.hasClientLoader || void 0 !== rootModern?.clientData,
|
|
429
|
-
modernRouteHasLoader: rootModern?.hasLoader || 'function' == typeof rootLoader,
|
|
430
|
-
modernRouteIsClientComponent: rootModern?.isClientComponent,
|
|
431
|
-
modernRouteLoader: rootLoader,
|
|
432
|
-
modernRouteShouldRevalidate: rootShouldRevalidate
|
|
433
|
-
}),
|
|
434
|
-
loader: rootModern ? wrapModernLoader(rootModern, rootLoader, rootRevalidationState, options) : void 0
|
|
435
|
-
};
|
|
436
|
-
if (rootShouldReload) rootRouteOptions.shouldReload = rootShouldReload;
|
|
437
|
-
if (rootModern?.inValidSSRRoute) rootRouteOptions.ssr = false;
|
|
438
|
-
const rootRoute = createTanstackRootRoute(rootRouteOptions);
|
|
439
|
-
const topLevel = rootModern ? rootModern.children || [] : routes;
|
|
440
|
-
const childRoutes = topLevel.map((child)=>createRouteFromModernRoute({
|
|
441
|
-
options,
|
|
442
|
-
parent: rootRoute,
|
|
443
|
-
modernRoute: child
|
|
444
|
-
}));
|
|
445
|
-
rootRoute.addChildren(childRoutes);
|
|
446
|
-
return rootRoute;
|
|
447
|
-
}
|
|
448
263
|
function getRootLikeRouteObject(routes) {
|
|
449
264
|
return routes.find((route)=>'/' === route.path && !route.index);
|
|
450
265
|
}
|
|
@@ -453,8 +268,9 @@ function createRouteTreeFromRouteObjects(routes, options = {}) {
|
|
|
453
268
|
const rootRevalidationState = {};
|
|
454
269
|
const rootShouldRevalidate = rootLikeRoute?.shouldRevalidate;
|
|
455
270
|
const rootShouldReload = createModernShouldReload(rootShouldRevalidate, rootRevalidationState);
|
|
271
|
+
const rootComponent = rootLikeRoute ? toRouteComponent(rootLikeRoute) : void 0;
|
|
456
272
|
const rootRouteOptions = {
|
|
457
|
-
component:
|
|
273
|
+
component: rootComponent,
|
|
458
274
|
pendingComponent: rootLikeRoute ? toPendingComponent(rootLikeRoute) : void 0,
|
|
459
275
|
errorComponent: rootLikeRoute ? toErrorComponent(rootLikeRoute) : void 0,
|
|
460
276
|
validateSearch: rootLikeRoute?.validateSearch,
|
|
@@ -476,6 +292,7 @@ function createRouteTreeFromRouteObjects(routes, options = {}) {
|
|
|
476
292
|
if (rootShouldReload) rootRouteOptions.shouldReload = rootShouldReload;
|
|
477
293
|
if (rootLikeRoute?.inValidSSRRoute) rootRouteOptions.ssr = false;
|
|
478
294
|
const rootRoute = createTanstackRootRoute(rootRouteOptions);
|
|
295
|
+
if (rootComponent) rootRoute.options.component = withModernRouteMatchContext(rootComponent, rootRouteId);
|
|
479
296
|
const topLevel = rootLikeRoute ? [
|
|
480
297
|
...rootLikeRoute.children || [],
|
|
481
298
|
...routes.filter((route)=>route !== rootLikeRoute)
|
|
@@ -498,4 +315,4 @@ function getModernRouteIdsFromMatches(router) {
|
|
|
498
315
|
}).filter((id)=>'string' == typeof id);
|
|
499
316
|
return Array.from(new Set(ids));
|
|
500
317
|
}
|
|
501
|
-
export {
|
|
318
|
+
export { createRouteTreeFromRouteObjects, getModernRouteIdsFromMatches };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isRouteErrorResponse } from "@modern-js/runtime-utils/router";
|
|
1
2
|
import { notFound, redirect } from "@tanstack/react-router";
|
|
2
3
|
const payloadFetchCache = new Map();
|
|
3
4
|
let payloadDecoder;
|
|
@@ -37,6 +38,39 @@ function toPayloadRoute(match) {
|
|
|
37
38
|
pathnameBase: 'string' == typeof match.pathnameBase ? match.pathnameBase : pathname
|
|
38
39
|
};
|
|
39
40
|
}
|
|
41
|
+
function shouldRedactServerError(status = 500) {
|
|
42
|
+
return status >= 500 && 'development' !== process.env.NODE_ENV && 'test' !== process.env.NODE_ENV;
|
|
43
|
+
}
|
|
44
|
+
function serializePayloadError(error) {
|
|
45
|
+
if (isRouteErrorResponse(error)) {
|
|
46
|
+
if (shouldRedactServerError(error.status)) return {
|
|
47
|
+
status: error.status,
|
|
48
|
+
statusText: 'Internal Server Error',
|
|
49
|
+
data: 'Unexpected Server Error',
|
|
50
|
+
__type: 'RouteErrorResponse'
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
...error,
|
|
54
|
+
__type: 'RouteErrorResponse'
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (error instanceof Error) {
|
|
58
|
+
if (shouldRedactServerError()) return {
|
|
59
|
+
message: 'Unexpected Server Error',
|
|
60
|
+
stack: void 0,
|
|
61
|
+
__type: 'Error'
|
|
62
|
+
};
|
|
63
|
+
return {
|
|
64
|
+
message: error.message,
|
|
65
|
+
stack: error.stack,
|
|
66
|
+
__type: 'Error',
|
|
67
|
+
...'Error' !== error.name ? {
|
|
68
|
+
__subType: error.name
|
|
69
|
+
} : {}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return error;
|
|
73
|
+
}
|
|
40
74
|
function createTanstackRscServerPayload(router, options = {}) {
|
|
41
75
|
const matches = Array.isArray(router.state?.matches) ? router.state.matches : [];
|
|
42
76
|
const routes = [];
|
|
@@ -47,7 +81,7 @@ function createTanstackRscServerPayload(router, options = {}) {
|
|
|
47
81
|
if (payloadRoute) {
|
|
48
82
|
routes.push(payloadRoute);
|
|
49
83
|
if ('loaderData' in match && void 0 !== match.loaderData && !(options.omitClientLoaderData && payloadRoute.hasClientLoader)) loaderData[payloadRoute.id] = match.loaderData;
|
|
50
|
-
if (void 0 !== match.error) errors[payloadRoute.id] = match.error;
|
|
84
|
+
if (void 0 !== match.error) errors[payloadRoute.id] = serializePayloadError(match.error);
|
|
51
85
|
}
|
|
52
86
|
}
|
|
53
87
|
return {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { getRouterRuntimeState } from "@modern-js/runtime/context";
|
|
2
|
+
function getTanstackRouterState(context) {
|
|
3
|
+
const state = getRouterRuntimeState(context);
|
|
4
|
+
if (void 0 === state || 'tanstack' !== state.framework) return;
|
|
5
|
+
return state;
|
|
6
|
+
}
|
|
7
|
+
export { getTanstackRouterState };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import react from "react";
|
|
3
|
-
import { DefaultNotFound } from "./DefaultNotFound.mjs";
|
|
4
3
|
function getRouteObjects(routes, { globalApp, ssrMode, props }) {
|
|
5
4
|
const createLayoutElement = (Component)=>{
|
|
6
5
|
const GlobalLayout = globalApp;
|
|
@@ -21,7 +20,6 @@ function getRouteObjects(routes, { globalApp, ssrMode, props }) {
|
|
|
21
20
|
id: route.id,
|
|
22
21
|
loader: route.loader,
|
|
23
22
|
action: route.action,
|
|
24
|
-
hasErrorBoundary: route.hasErrorBoundary,
|
|
25
23
|
shouldRevalidate: route.shouldRevalidate,
|
|
26
24
|
handle: {
|
|
27
25
|
...route.handle,
|
|
@@ -57,10 +55,6 @@ function getRouteObjects(routes, { globalApp, ssrMode, props }) {
|
|
|
57
55
|
};
|
|
58
56
|
routeObjects.push(routeObject);
|
|
59
57
|
}
|
|
60
|
-
routeObjects.push({
|
|
61
|
-
path: '*',
|
|
62
|
-
element: /*#__PURE__*/ jsx(DefaultNotFound, {})
|
|
63
|
-
});
|
|
64
58
|
return routeObjects;
|
|
65
59
|
}
|
|
66
60
|
function createRouteObjectsFromConfig({ routesConfig, props, ssrMode }) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import node_path from "node:path";
|
|
3
3
|
import { NESTED_ROUTE_SPEC_FILE, filterRoutesForServer, fs } from "@modern-js/utils";
|
|
4
|
-
import { createTanstackRsbuildRouteSplittingProfile,
|
|
5
|
-
import {
|
|
4
|
+
import { createTanstackRsbuildRouteSplittingProfile, resolveTanstackRouteCodeSplittingEnabled } from "./routeSplitting.mjs";
|
|
5
|
+
import { collectCanonicalRoutesForEntry, generateTanstackRouterTypesSourceForEntry } from "./tanstackTypes.mjs";
|
|
6
6
|
import { __webpack_require__ } from "../rslib-runtime.mjs";
|
|
7
7
|
import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
|
|
8
8
|
import { dirname as __rspack_dirname } from "node:path";
|
|
9
9
|
import * as __rspack_external__modern_js_runtime_cli_401ee077 from "@modern-js/runtime/cli";
|
|
10
10
|
__webpack_require__.add({
|
|
11
|
-
"@modern-js/runtime/cli" (module) {
|
|
11
|
+
"@modern-js/runtime/cli?9b14" (module) {
|
|
12
12
|
module.exports = __rspack_external__modern_js_runtime_cli_401ee077;
|
|
13
13
|
}
|
|
14
14
|
});
|
|
@@ -19,8 +19,8 @@ const ENTRYPOINTS_KEY = '@modern-js/plugin-tanstack';
|
|
|
19
19
|
let runtimeRouterCli;
|
|
20
20
|
function getRuntimeRouterCli() {
|
|
21
21
|
if (runtimeRouterCli) return runtimeRouterCli;
|
|
22
|
-
const cli = __webpack_require__("@modern-js/runtime/cli");
|
|
23
|
-
if (cli.handleGeneratorEntryCode && cli.getEntrypointRoutesDir) {
|
|
22
|
+
const cli = __webpack_require__("@modern-js/runtime/cli?9b14");
|
|
23
|
+
if (cli.handleGeneratorEntryCode && cli.getEntrypointRoutesDir && cli.getEntrypointRoutesOwner) {
|
|
24
24
|
runtimeRouterCli = cli;
|
|
25
25
|
return runtimeRouterCli;
|
|
26
26
|
}
|
|
@@ -36,6 +36,14 @@ async function writeFileIfChanged(filePath, content) {
|
|
|
36
36
|
function createRegisterDtsContent(opts) {
|
|
37
37
|
const importStatements = opts.entries.map((entryName, index)=>`import type { router as router${index} } from './${entryName}/router.gen';`).join('\n');
|
|
38
38
|
const routerUnionType = opts.entries.map((_, index)=>`typeof router${index}`).join(' | ');
|
|
39
|
+
const canonicalEntries = Object.entries(opts.canonicalRoutes ?? {});
|
|
40
|
+
const canonicalRoutesAugmentation = canonicalEntries.length > 0 ? `
|
|
41
|
+
declare module '${opts.i18nRuntimeModule || '@modern-js/plugin-i18n/runtime'}' {
|
|
42
|
+
interface UltramodernCanonicalRoutes {
|
|
43
|
+
${canonicalEntries.map(([routePath, paramsType])=>` '${routePath}': ${paramsType};`).join('\n')}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
` : '';
|
|
39
47
|
return `// This file is auto-generated by Modern.js. Do not edit manually.
|
|
40
48
|
|
|
41
49
|
${importStatements}
|
|
@@ -45,19 +53,21 @@ declare module '${opts.runtimeModule}' {
|
|
|
45
53
|
router: ${routerUnionType};
|
|
46
54
|
}
|
|
47
55
|
}
|
|
48
|
-
`;
|
|
56
|
+
${canonicalRoutesAugmentation}`;
|
|
49
57
|
}
|
|
50
58
|
async function writeTanstackRegisterFile(opts) {
|
|
51
|
-
const { entries, generatedDirName = DEFAULT_GENERATED_DIR_NAME, runtimeModule = '@modern-js/plugin-tanstack/runtime', srcDirectory } = opts;
|
|
59
|
+
const { entries, generatedDirName = DEFAULT_GENERATED_DIR_NAME, runtimeModule = '@modern-js/plugin-tanstack/runtime', srcDirectory, canonicalRoutes, i18nRuntimeModule } = opts;
|
|
52
60
|
if (0 === entries.length) return;
|
|
53
61
|
const registerDtsPath = node_path.join(srcDirectory, generatedDirName, 'register.gen.d.ts');
|
|
54
62
|
await writeFileIfChanged(registerDtsPath, createRegisterDtsContent({
|
|
55
63
|
entries,
|
|
56
|
-
runtimeModule
|
|
64
|
+
runtimeModule,
|
|
65
|
+
canonicalRoutes,
|
|
66
|
+
i18nRuntimeModule
|
|
57
67
|
}));
|
|
58
68
|
}
|
|
59
69
|
async function writeTanstackRouterTypesForEntries(opts) {
|
|
60
|
-
const { appContext, generatedDirName = DEFAULT_GENERATED_DIR_NAME, routesByEntry } = opts;
|
|
70
|
+
const { appContext, generatedDirName = DEFAULT_GENERATED_DIR_NAME, routesByEntry, i18nPluginInstalled = false } = opts;
|
|
61
71
|
const entryNames = Object.keys(routesByEntry);
|
|
62
72
|
await Promise.all(entryNames.map(async (entryName)=>{
|
|
63
73
|
const { routerGenTs } = await generateTanstackRouterTypesSourceForEntry({
|
|
@@ -74,10 +84,21 @@ async function writeTanstackRouterTypesForEntries(opts) {
|
|
|
74
84
|
if (mainEntryName && b === mainEntryName) return 1;
|
|
75
85
|
return a.localeCompare(b);
|
|
76
86
|
});
|
|
87
|
+
let canonicalRoutes = null;
|
|
88
|
+
if (i18nPluginInstalled) for (const entryName of registerEntries){
|
|
89
|
+
const entryCanonicalRoutes = collectCanonicalRoutesForEntry(routesByEntry[entryName], {
|
|
90
|
+
localeParamHeuristic: true
|
|
91
|
+
});
|
|
92
|
+
if (entryCanonicalRoutes) canonicalRoutes = {
|
|
93
|
+
...entryCanonicalRoutes,
|
|
94
|
+
...canonicalRoutes ?? {}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
77
97
|
await writeTanstackRegisterFile({
|
|
78
98
|
entries: registerEntries,
|
|
79
99
|
generatedDirName,
|
|
80
|
-
srcDirectory: appContext.srcDirectory
|
|
100
|
+
srcDirectory: appContext.srcDirectory,
|
|
101
|
+
canonicalRoutes
|
|
81
102
|
});
|
|
82
103
|
}
|
|
83
104
|
function tanstackRouterPlugin(options = {}) {
|
|
@@ -95,16 +116,42 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
95
116
|
const { getEntrypointRoutesDir } = getRuntimeRouterCli();
|
|
96
117
|
return getEntrypointRoutesDir(entrypoint) === routesDir;
|
|
97
118
|
};
|
|
119
|
+
const isForeignRouteEntrypoint = (entrypoint)=>{
|
|
120
|
+
const { getEntrypointRoutesDir, getEntrypointRoutesOwner } = getRuntimeRouterCli();
|
|
121
|
+
if (getEntrypointRoutesOwner(entrypoint)) return true;
|
|
122
|
+
if (entrypoint.pageRoutesEntry) return true;
|
|
123
|
+
return null !== getEntrypointRoutesDir(entrypoint);
|
|
124
|
+
};
|
|
125
|
+
const isI18nPluginInstalled = ()=>{
|
|
126
|
+
const { plugins } = api.getAppContext();
|
|
127
|
+
return Boolean(plugins?.some((plugin)=>plugin?.name === '@modern-js/plugin-i18n'));
|
|
128
|
+
};
|
|
98
129
|
api._internalRuntimePlugins(({ entrypoint, plugins })=>{
|
|
99
|
-
|
|
130
|
+
const { metaName, serverRoutes } = api.getAppContext();
|
|
131
|
+
const serverBase = serverRoutes.filter((route)=>route.entryName === entrypoint.entryName).map((route)=>route.urlPath).sort((a, b)=>a.length - b.length > 0 ? -1 : 1);
|
|
132
|
+
if (isTanstackEntrypoint(entrypoint)) {
|
|
133
|
+
plugins.push({
|
|
134
|
+
name: 'tanstackRouter',
|
|
135
|
+
path: `@${metaName}/plugin-tanstack/runtime`,
|
|
136
|
+
config: {
|
|
137
|
+
serverBase
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
return {
|
|
141
|
+
entrypoint,
|
|
142
|
+
plugins
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (isForeignRouteEntrypoint(entrypoint)) return {
|
|
100
146
|
entrypoint,
|
|
101
147
|
plugins
|
|
102
148
|
};
|
|
103
|
-
const {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
149
|
+
const routerWrapperPath = `@${metaName}/plugin-tanstack/runtime/router`;
|
|
150
|
+
const existingRouterPlugin = plugins.find((plugin)=>'router' === plugin.name);
|
|
151
|
+
if (existingRouterPlugin) existingRouterPlugin.path = routerWrapperPath;
|
|
152
|
+
else plugins.push({
|
|
153
|
+
name: 'router',
|
|
154
|
+
path: routerWrapperPath,
|
|
108
155
|
config: {
|
|
109
156
|
serverBase
|
|
110
157
|
}
|
|
@@ -123,7 +170,9 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
123
170
|
source: {
|
|
124
171
|
include: [
|
|
125
172
|
/[\\/]node_modules[\\/]@tanstack[\\/]react-router[\\/]/,
|
|
126
|
-
|
|
173
|
+
/[\\/]node_modules[\\/]@tanstack[\\/]router-core[\\/]/,
|
|
174
|
+
/[\\/]node_modules[\\/]@tanstack[\\/]react-store[\\/]/,
|
|
175
|
+
node_path.resolve(cli_dirname, '..', '..')
|
|
127
176
|
]
|
|
128
177
|
}
|
|
129
178
|
}));
|
|
@@ -140,15 +189,13 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
140
189
|
if (0 === tanstackEntrypoints.length) return;
|
|
141
190
|
const { handleGeneratorEntryCode } = getRuntimeRouterCli();
|
|
142
191
|
const routesByEntry = await handleGeneratorEntryCode(api, tanstackEntrypoints, {
|
|
143
|
-
entrypointsKey: ENTRYPOINTS_KEY
|
|
144
|
-
generateCodeOptions: {
|
|
145
|
-
enableTanstackTypes: false
|
|
146
|
-
}
|
|
192
|
+
entrypointsKey: ENTRYPOINTS_KEY
|
|
147
193
|
});
|
|
148
194
|
await writeTanstackRouterTypesForEntries({
|
|
149
195
|
appContext: api.getAppContext(),
|
|
150
196
|
generatedDirName,
|
|
151
|
-
routesByEntry
|
|
197
|
+
routesByEntry,
|
|
198
|
+
i18nPluginInstalled: isI18nPluginInstalled()
|
|
152
199
|
});
|
|
153
200
|
});
|
|
154
201
|
api.onFileChanged(async (event)=>{
|
|
@@ -162,15 +209,13 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
162
209
|
regenerate: async ({ api, entrypoints })=>{
|
|
163
210
|
const { handleGeneratorEntryCode } = getRuntimeRouterCli();
|
|
164
211
|
const routesByEntry = await handleGeneratorEntryCode(api, entrypoints, {
|
|
165
|
-
entrypointsKey: ENTRYPOINTS_KEY
|
|
166
|
-
generateCodeOptions: {
|
|
167
|
-
enableTanstackTypes: false
|
|
168
|
-
}
|
|
212
|
+
entrypointsKey: ENTRYPOINTS_KEY
|
|
169
213
|
});
|
|
170
214
|
await writeTanstackRouterTypesForEntries({
|
|
171
215
|
appContext: api.getAppContext(),
|
|
172
216
|
generatedDirName,
|
|
173
|
-
routesByEntry
|
|
217
|
+
routesByEntry,
|
|
218
|
+
i18nPluginInstalled: isI18nPluginInstalled()
|
|
174
219
|
});
|
|
175
220
|
}
|
|
176
221
|
});
|
|
@@ -202,4 +247,4 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
202
247
|
}
|
|
203
248
|
const src_cli = tanstackRouterPlugin;
|
|
204
249
|
export default src_cli;
|
|
205
|
-
export { createTanstackRsbuildRouteSplittingProfile, generateTanstackRouterTypesSourceForEntry,
|
|
250
|
+
export { collectCanonicalRoutesForEntry, createTanstackRsbuildRouteSplittingProfile, generateTanstackRouterTypesSourceForEntry, resolveTanstackRouteCodeSplittingEnabled, tanstackRouterPlugin, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries };
|
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
const TANSTACK_START_ROUTE_FACTORY_CALLS = [
|
|
3
|
-
'createFileRoute',
|
|
4
|
-
'createRootRoute',
|
|
5
|
-
'createRootRouteWithContext'
|
|
6
|
-
];
|
|
7
|
-
const TANSTACK_START_ROUTE_FACTORY_REGEX = /\b(createFileRoute|createRootRoute|createRootRouteWithContext)\s*(?:<|\()/;
|
|
8
|
-
function isTanstackStartRouteModuleSource(source) {
|
|
9
|
-
return TANSTACK_START_ROUTE_FACTORY_REGEX.test(source);
|
|
10
|
-
}
|
|
11
2
|
function resolveTanstackRouteCodeSplittingEnabled(option) {
|
|
12
3
|
if ('boolean' == typeof option) return option;
|
|
13
4
|
return option?.enabled ?? true;
|
|
@@ -18,27 +9,7 @@ function createTanstackRsbuildRouteSplittingProfile(opts) {
|
|
|
18
9
|
output: {
|
|
19
10
|
splitRouteChunks: resolveTanstackRouteCodeSplittingEnabled(opts.routeCodeSplitting)
|
|
20
11
|
}
|
|
21
|
-
},
|
|
22
|
-
modernRouteChunks: {
|
|
23
|
-
enabled: resolveTanstackRouteCodeSplittingEnabled(opts.routeCodeSplitting),
|
|
24
|
-
owner: 'modern'
|
|
25
|
-
},
|
|
26
|
-
builderChunkSplit: {
|
|
27
|
-
owner: 'modern-rsbuild',
|
|
28
|
-
preserved: true
|
|
29
|
-
},
|
|
30
|
-
tanstackStartRspackSplitter: {
|
|
31
|
-
compatible: false,
|
|
32
|
-
reason: 'TanStack Start Rsbuild route splitting is tied to TanStack file-route factory modules; Modern generates TanStack route trees from Modern route metadata and owns route chunking through output.splitRouteChunks.',
|
|
33
|
-
clientDeleteNodes: [
|
|
34
|
-
'ssr',
|
|
35
|
-
'server',
|
|
36
|
-
'headers'
|
|
37
|
-
],
|
|
38
|
-
routeFactoryCalls: [
|
|
39
|
-
...TANSTACK_START_ROUTE_FACTORY_CALLS
|
|
40
|
-
]
|
|
41
12
|
}
|
|
42
13
|
};
|
|
43
14
|
}
|
|
44
|
-
export { createTanstackRsbuildRouteSplittingProfile,
|
|
15
|
+
export { createTanstackRsbuildRouteSplittingProfile, resolveTanstackRouteCodeSplittingEnabled };
|