@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.10 → 3.2.0-ultramodern.100
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 +12 -0
- package/dist/cjs/cli/routeSplitting.js +83 -0
- package/dist/cjs/cli/tanstackTypes.js +146 -58
- package/dist/cjs/runtime/hydrationBoundary.js +44 -0
- package/dist/cjs/runtime/index.js +321 -69
- package/dist/cjs/runtime/outlet.js +54 -0
- package/dist/cjs/runtime/plugin.js +194 -90
- package/dist/cjs/runtime/plugin.node.js +29 -11
- package/dist/cjs/runtime/plugin.worker.js +49 -0
- package/dist/cjs/runtime/routeTree.js +72 -12
- package/dist/cjs/runtime/types.js +27 -1
- package/dist/esm/cli/index.mjs +4 -1
- package/dist/esm/cli/routeSplitting.mjs +43 -0
- package/dist/esm/cli/tanstackTypes.mjs +146 -58
- package/dist/esm/runtime/hydrationBoundary.mjs +10 -0
- package/dist/esm/runtime/index.mjs +3 -2
- package/dist/esm/runtime/outlet.mjs +17 -0
- package/dist/esm/runtime/plugin.mjs +197 -93
- package/dist/esm/runtime/plugin.node.mjs +30 -12
- package/dist/esm/runtime/plugin.worker.mjs +1 -0
- package/dist/esm/runtime/routeTree.mjs +73 -13
- package/dist/esm/runtime/types.mjs +7 -0
- package/dist/esm-node/cli/index.mjs +4 -1
- package/dist/esm-node/cli/routeSplitting.mjs +44 -0
- package/dist/esm-node/cli/tanstackTypes.mjs +146 -58
- package/dist/esm-node/runtime/hydrationBoundary.mjs +11 -0
- package/dist/esm-node/runtime/index.mjs +3 -2
- package/dist/esm-node/runtime/outlet.mjs +18 -0
- package/dist/esm-node/runtime/plugin.mjs +197 -93
- package/dist/esm-node/runtime/plugin.node.mjs +30 -12
- package/dist/esm-node/runtime/plugin.worker.mjs +2 -0
- package/dist/esm-node/runtime/routeTree.mjs +73 -13
- package/dist/esm-node/runtime/types.mjs +7 -0
- package/dist/types/cli/index.d.ts +4 -0
- package/dist/types/cli/routeSplitting.d.ts +29 -0
- package/dist/types/runtime/hydrationBoundary.d.ts +2 -0
- package/dist/types/runtime/index.d.ts +5 -2
- package/dist/types/runtime/outlet.d.ts +2 -0
- package/dist/types/runtime/plugin.d.ts +1 -1
- package/dist/types/runtime/plugin.node.d.ts +1 -1
- package/dist/types/runtime/plugin.worker.d.ts +1 -0
- package/dist/types/runtime/types.d.ts +7 -0
- package/package.json +15 -15
- package/src/cli/index.ts +17 -0
- package/src/cli/routeSplitting.ts +81 -0
- package/src/cli/tanstackTypes.ts +216 -67
- package/src/runtime/hydrationBoundary.tsx +12 -0
- package/src/runtime/index.tsx +107 -2
- package/src/runtime/outlet.tsx +42 -0
- package/src/runtime/plugin.node.tsx +57 -8
- package/src/runtime/plugin.tsx +353 -149
- package/src/runtime/plugin.worker.tsx +4 -0
- package/src/runtime/routeTree.ts +194 -23
- package/src/runtime/ssr-shim.d.ts +1 -3
- package/src/runtime/types.ts +13 -0
- package/tests/router/cli.test.ts +239 -0
- package/tests/router/fastDefaults.test.ts +25 -0
- package/tests/router/hydrationBoundary.test.tsx +23 -0
- package/tests/router/routeTree.test.ts +416 -1
- package/tests/router/tanstackTypes.test.ts +184 -0
|
@@ -29,7 +29,9 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
29
29
|
getModernRouteIdsFromMatches: ()=>getModernRouteIdsFromMatches
|
|
30
30
|
});
|
|
31
31
|
const react_router_namespaceObject = require("@tanstack/react-router");
|
|
32
|
+
const external_react_namespaceObject = require("react");
|
|
32
33
|
const external_DefaultNotFound_js_namespaceObject = require("./DefaultNotFound.js");
|
|
34
|
+
const external_outlet_js_namespaceObject = require("./outlet.js");
|
|
33
35
|
const payloadRouter_js_namespaceObject = require("./rsc/payloadRouter.js");
|
|
34
36
|
function createTanstackRoute(options) {
|
|
35
37
|
return (0, react_router_namespaceObject.createRoute)(options);
|
|
@@ -37,6 +39,10 @@ function createTanstackRoute(options) {
|
|
|
37
39
|
function createTanstackRootRoute(options) {
|
|
38
40
|
return (0, react_router_namespaceObject.createRootRoute)(options);
|
|
39
41
|
}
|
|
42
|
+
function wrapRouteComponentWithModernContext(route, component, routeId) {
|
|
43
|
+
const routeMatchId = routeId || route.id;
|
|
44
|
+
if (component && routeMatchId) route.options.component = (0, external_outlet_js_namespaceObject.withModernRouteMatchContext)(component, routeMatchId);
|
|
45
|
+
}
|
|
40
46
|
function toTanstackPath(pathname) {
|
|
41
47
|
return pathname.split('/').map((segment)=>{
|
|
42
48
|
if (!segment) return segment;
|
|
@@ -84,6 +90,40 @@ function normalizeModernLoaderResponse(result) {
|
|
|
84
90
|
}
|
|
85
91
|
return normalizeModernLoaderResult(result);
|
|
86
92
|
}
|
|
93
|
+
function pickRouteModuleComponent(routeModule, seen = new Set()) {
|
|
94
|
+
if ('function' == typeof routeModule || routeModule && 'object' == typeof routeModule && '$$typeof' in routeModule) return routeModule;
|
|
95
|
+
if (!routeModule || 'object' != typeof routeModule) return;
|
|
96
|
+
if (seen.has(routeModule)) return;
|
|
97
|
+
seen.add(routeModule);
|
|
98
|
+
const module = routeModule;
|
|
99
|
+
for (const candidate of [
|
|
100
|
+
module.default,
|
|
101
|
+
module.Component
|
|
102
|
+
]){
|
|
103
|
+
const component = pickRouteModuleComponent(candidate, seen);
|
|
104
|
+
if (component) return component;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function createServerLazyImportComponent(lazyImport, fallbackComponent) {
|
|
108
|
+
if ("u" > typeof document) return fallbackComponent;
|
|
109
|
+
let resolvedComponent;
|
|
110
|
+
let pendingLoad;
|
|
111
|
+
const load = async ()=>{
|
|
112
|
+
if (resolvedComponent) return resolvedComponent;
|
|
113
|
+
const routeModule = await lazyImport();
|
|
114
|
+
const component = pickRouteModuleComponent(routeModule);
|
|
115
|
+
if (component) resolvedComponent = component;
|
|
116
|
+
return resolvedComponent;
|
|
117
|
+
};
|
|
118
|
+
const Component = (props)=>{
|
|
119
|
+
if (resolvedComponent) return (0, external_react_namespaceObject.createElement)(resolvedComponent, props);
|
|
120
|
+
pendingLoad ||= load();
|
|
121
|
+
throw pendingLoad;
|
|
122
|
+
};
|
|
123
|
+
Component.load = load;
|
|
124
|
+
Component.preload = load;
|
|
125
|
+
return Component;
|
|
126
|
+
}
|
|
87
127
|
function isAbsoluteUrl(value) {
|
|
88
128
|
try {
|
|
89
129
|
new URL(value);
|
|
@@ -156,7 +196,7 @@ function wrapModernLoader(modernRoute, modernLoader, revalidationState, options
|
|
|
156
196
|
const signal = ctx?.abortController?.signal || ctx?.signal || new AbortController().signal;
|
|
157
197
|
const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
|
|
158
198
|
const href = 'string' == typeof ctx?.location ? ctx.location : ctx?.location?.publicHref || ctx?.location?.href || ctx?.location?.url?.href || '';
|
|
159
|
-
const request = baseRequest ? new Request(baseRequest, {
|
|
199
|
+
const request = void 0 !== baseRequest ? new Request(baseRequest, {
|
|
160
200
|
signal
|
|
161
201
|
}) : createModernRequest(href, signal);
|
|
162
202
|
const params = mapParamsForModernLoader({
|
|
@@ -221,7 +261,7 @@ function wrapRouteObjectLoader(route, revalidationState, options = {}) {
|
|
|
221
261
|
const signal = ctx?.abortController?.signal || ctx?.signal || new AbortController().signal;
|
|
222
262
|
const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
|
|
223
263
|
const href = 'string' == typeof ctx?.location ? ctx.location : ctx?.location?.publicHref || ctx?.location?.href || ctx?.location?.url?.href || '';
|
|
224
|
-
const request = baseRequest ? new Request(baseRequest, {
|
|
264
|
+
const request = void 0 !== baseRequest ? new Request(baseRequest, {
|
|
225
265
|
signal
|
|
226
266
|
}) : createModernRequest(href, signal);
|
|
227
267
|
const params = mapParamsForRouteObjectLoader({
|
|
@@ -258,10 +298,18 @@ function wrapRouteObjectLoader(route, revalidationState, options = {}) {
|
|
|
258
298
|
}
|
|
259
299
|
function toRouteComponent(routeObject) {
|
|
260
300
|
const route = routeObject;
|
|
301
|
+
const lazyImport = 'function' == typeof route.lazyImport ? route.lazyImport : void 0;
|
|
302
|
+
const fallbackComponent = route.Component ? route.Component : route.element ? ()=>route.element : void 0;
|
|
303
|
+
if (lazyImport && fallbackComponent) return createServerLazyImportComponent(lazyImport, fallbackComponent);
|
|
261
304
|
if (route.Component) return route.Component;
|
|
262
305
|
const element = route.element;
|
|
263
306
|
if (element) return ()=>element;
|
|
264
307
|
}
|
|
308
|
+
function toModernRouteComponent(route) {
|
|
309
|
+
const component = route.component || void 0;
|
|
310
|
+
if ('function' == typeof route.lazyImport && component) return createServerLazyImportComponent(route.lazyImport, component);
|
|
311
|
+
return component;
|
|
312
|
+
}
|
|
265
313
|
function toErrorComponent(routeObject) {
|
|
266
314
|
const route = routeObject;
|
|
267
315
|
if (route.ErrorBoundary) return route.ErrorBoundary;
|
|
@@ -299,12 +347,14 @@ function createRouteFromRouteObject(opts) {
|
|
|
299
347
|
const shouldRevalidate = modernRouteObject.shouldRevalidate;
|
|
300
348
|
const shouldReload = createModernShouldReload(shouldRevalidate, revalidationState);
|
|
301
349
|
const stableFallbackId = routeObject.id || modernRouteObject.file || routeObject.path || 'pathless';
|
|
350
|
+
const component = toRouteComponent(routeObject);
|
|
302
351
|
const base = {
|
|
303
352
|
getParentRoute: ()=>parent,
|
|
304
|
-
component
|
|
353
|
+
component,
|
|
305
354
|
pendingComponent: toPendingComponent(routeObject),
|
|
306
355
|
errorComponent: toErrorComponent(routeObject),
|
|
307
|
-
|
|
356
|
+
validateSearch: modernRouteObject.validateSearch,
|
|
357
|
+
loaderDeps: modernRouteObject.loaderDeps,
|
|
308
358
|
staticData: createRouteStaticData({
|
|
309
359
|
modernRouteId: routeObject.id,
|
|
310
360
|
modernRouteAction: modernRouteObject.action,
|
|
@@ -323,6 +373,7 @@ function createRouteFromRouteObject(opts) {
|
|
|
323
373
|
if (isRouteObjectPathlessLayout(routeObject)) base.id = stableFallbackId;
|
|
324
374
|
else base.path = routeObject.index ? '/' : toTanstackPath(routeObject.path || '');
|
|
325
375
|
const route = createTanstackRoute(base);
|
|
376
|
+
wrapRouteComponentWithModernContext(route, component, routeObject.id);
|
|
326
377
|
const children = routeObject.children;
|
|
327
378
|
if (children && children.length > 0) {
|
|
328
379
|
const childRoutes = children.map((child)=>createRouteFromRouteObject({
|
|
@@ -342,7 +393,7 @@ function createRouteFromModernRoute(opts) {
|
|
|
342
393
|
const stableFallbackId = modernId || route._component || route.filename || route.data || ('function' == typeof route.loader ? route.id : void 0);
|
|
343
394
|
const pendingComponent = route.loading || route.pendingComponent;
|
|
344
395
|
const errorComponent = route.error || route.errorComponent;
|
|
345
|
-
const component = route
|
|
396
|
+
const component = toModernRouteComponent(route);
|
|
346
397
|
const modernLoader = route.loader;
|
|
347
398
|
const modernAction = route.action;
|
|
348
399
|
const modernShouldRevalidate = route.shouldRevalidate;
|
|
@@ -354,7 +405,8 @@ function createRouteFromModernRoute(opts) {
|
|
|
354
405
|
component: component || void 0,
|
|
355
406
|
pendingComponent: pendingComponent || void 0,
|
|
356
407
|
errorComponent: errorComponent || void 0,
|
|
357
|
-
|
|
408
|
+
validateSearch: route.validateSearch,
|
|
409
|
+
loaderDeps: route.loaderDeps,
|
|
358
410
|
staticData: createRouteStaticData({
|
|
359
411
|
modernRouteId: modernId,
|
|
360
412
|
modernRouteAction: modernAction,
|
|
@@ -376,6 +428,7 @@ function createRouteFromModernRoute(opts) {
|
|
|
376
428
|
base.path = isIndexRoute ? '/' : toTanstackPath(rawPath || '');
|
|
377
429
|
}
|
|
378
430
|
const tanstackRoute = createTanstackRoute(base);
|
|
431
|
+
wrapRouteComponentWithModernContext(tanstackRoute, component, modernId);
|
|
379
432
|
const children = route.children;
|
|
380
433
|
if (children && children.length > 0) {
|
|
381
434
|
const childRoutes = children.map((child)=>createRouteFromModernRoute({
|
|
@@ -389,7 +442,7 @@ function createRouteFromModernRoute(opts) {
|
|
|
389
442
|
}
|
|
390
443
|
function createRouteTreeFromModernRoutes(routes, options = {}) {
|
|
391
444
|
const rootModern = routes.find((r)=>r && 'nested' === r.type && r.isRoot);
|
|
392
|
-
const rootComponent = rootModern
|
|
445
|
+
const rootComponent = rootModern ? toModernRouteComponent(rootModern) : void 0;
|
|
393
446
|
const pendingComponent = rootModern?.loading;
|
|
394
447
|
const errorComponent = rootModern?.error;
|
|
395
448
|
const rootLoader = rootModern?.loader;
|
|
@@ -402,7 +455,8 @@ function createRouteTreeFromModernRoutes(routes, options = {}) {
|
|
|
402
455
|
component: rootComponent || void 0,
|
|
403
456
|
pendingComponent: pendingComponent || void 0,
|
|
404
457
|
errorComponent: errorComponent || void 0,
|
|
405
|
-
|
|
458
|
+
validateSearch: rootModern?.validateSearch,
|
|
459
|
+
loaderDeps: rootModern?.loaderDeps,
|
|
406
460
|
notFoundComponent: external_DefaultNotFound_js_namespaceObject.DefaultNotFound,
|
|
407
461
|
staticData: createRouteStaticData({
|
|
408
462
|
modernRouteId: rootModernId,
|
|
@@ -420,6 +474,7 @@ function createRouteTreeFromModernRoutes(routes, options = {}) {
|
|
|
420
474
|
if (rootShouldReload) rootRouteOptions.shouldReload = rootShouldReload;
|
|
421
475
|
if (rootModern?.inValidSSRRoute) rootRouteOptions.ssr = false;
|
|
422
476
|
const rootRoute = createTanstackRootRoute(rootRouteOptions);
|
|
477
|
+
if (rootComponent) rootRoute.options.component = (0, external_outlet_js_namespaceObject.withModernRouteMatchContext)(rootComponent, react_router_namespaceObject.rootRouteId);
|
|
423
478
|
const topLevel = rootModern ? rootModern.children || [] : routes;
|
|
424
479
|
const childRoutes = topLevel.map((child)=>createRouteFromModernRoute({
|
|
425
480
|
options,
|
|
@@ -437,11 +492,13 @@ function createRouteTreeFromRouteObjects(routes, options = {}) {
|
|
|
437
492
|
const rootRevalidationState = {};
|
|
438
493
|
const rootShouldRevalidate = rootLikeRoute?.shouldRevalidate;
|
|
439
494
|
const rootShouldReload = createModernShouldReload(rootShouldRevalidate, rootRevalidationState);
|
|
495
|
+
const rootComponent = rootLikeRoute ? toRouteComponent(rootLikeRoute) : void 0;
|
|
440
496
|
const rootRouteOptions = {
|
|
441
|
-
component:
|
|
497
|
+
component: rootComponent,
|
|
442
498
|
pendingComponent: rootLikeRoute ? toPendingComponent(rootLikeRoute) : void 0,
|
|
443
499
|
errorComponent: rootLikeRoute ? toErrorComponent(rootLikeRoute) : void 0,
|
|
444
|
-
|
|
500
|
+
validateSearch: rootLikeRoute?.validateSearch,
|
|
501
|
+
loaderDeps: rootLikeRoute?.loaderDeps,
|
|
445
502
|
notFoundComponent: external_DefaultNotFound_js_namespaceObject.DefaultNotFound,
|
|
446
503
|
staticData: createRouteStaticData({
|
|
447
504
|
modernRouteId: rootLikeRoute?.id,
|
|
@@ -459,6 +516,7 @@ function createRouteTreeFromRouteObjects(routes, options = {}) {
|
|
|
459
516
|
if (rootShouldReload) rootRouteOptions.shouldReload = rootShouldReload;
|
|
460
517
|
if (rootLikeRoute?.inValidSSRRoute) rootRouteOptions.ssr = false;
|
|
461
518
|
const rootRoute = createTanstackRootRoute(rootRouteOptions);
|
|
519
|
+
if (rootComponent) rootRoute.options.component = (0, external_outlet_js_namespaceObject.withModernRouteMatchContext)(rootComponent, react_router_namespaceObject.rootRouteId);
|
|
462
520
|
const topLevel = rootLikeRoute ? [
|
|
463
521
|
...rootLikeRoute.children || [],
|
|
464
522
|
...routes.filter((route)=>route !== rootLikeRoute)
|
|
@@ -473,9 +531,11 @@ function createRouteTreeFromRouteObjects(routes, options = {}) {
|
|
|
473
531
|
}
|
|
474
532
|
function getModernRouteIdsFromMatches(router) {
|
|
475
533
|
const matches = router.state.matches || [];
|
|
534
|
+
const routesById = router.routesById;
|
|
476
535
|
const ids = matches.map((match)=>{
|
|
477
|
-
const
|
|
478
|
-
|
|
536
|
+
const normalizedMatch = match;
|
|
537
|
+
const routeId = 'string' == typeof normalizedMatch.routeId ? normalizedMatch.routeId : void 0;
|
|
538
|
+
return normalizedMatch.route?.options?.staticData?.modernRouteId ?? (routeId ? routesById?.[routeId]?.options?.staticData?.modernRouteId : void 0);
|
|
479
539
|
}).filter((id)=>'string' == typeof id);
|
|
480
540
|
return Array.from(new Set(ids));
|
|
481
541
|
}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
3
14
|
(()=>{
|
|
4
15
|
__webpack_require__.r = (exports1)=>{
|
|
5
16
|
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
@@ -12,7 +23,22 @@ var __webpack_require__ = {};
|
|
|
12
23
|
})();
|
|
13
24
|
var __webpack_exports__ = {};
|
|
14
25
|
__webpack_require__.r(__webpack_exports__);
|
|
15
|
-
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
getModernTanstackRouterFastDefaults: ()=>getModernTanstackRouterFastDefaults,
|
|
28
|
+
modernTanstackRouterFastDefaults: ()=>modernTanstackRouterFastDefaults
|
|
29
|
+
});
|
|
30
|
+
const modernTanstackRouterFastDefaults = {
|
|
31
|
+
defaultStructuralSharing: true
|
|
32
|
+
};
|
|
33
|
+
const getModernTanstackRouterFastDefaults = (config = {})=>({
|
|
34
|
+
defaultStructuralSharing: config.defaultStructuralSharing ?? modernTanstackRouterFastDefaults.defaultStructuralSharing
|
|
35
|
+
});
|
|
36
|
+
exports.getModernTanstackRouterFastDefaults = __webpack_exports__.getModernTanstackRouterFastDefaults;
|
|
37
|
+
exports.modernTanstackRouterFastDefaults = __webpack_exports__.modernTanstackRouterFastDefaults;
|
|
38
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
39
|
+
"getModernTanstackRouterFastDefaults",
|
|
40
|
+
"modernTanstackRouterFastDefaults"
|
|
41
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
16
42
|
Object.defineProperty(exports, '__esModule', {
|
|
17
43
|
value: true
|
|
18
44
|
});
|
package/dist/esm/cli/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import node_path from "node:path";
|
|
2
2
|
import { NESTED_ROUTE_SPEC_FILE, filterRoutesForServer, fs } from "@modern-js/utils";
|
|
3
|
+
import { createTanstackRsbuildRouteSplittingProfile, isTanstackStartRouteModuleSource, resolveTanstackRouteCodeSplittingEnabled } from "./routeSplitting.mjs";
|
|
3
4
|
import { generateTanstackRouterTypesSourceForEntry, isTanstackRouterFrameworkEnabled } from "./tanstackTypes.mjs";
|
|
4
5
|
import { __webpack_require__ } from "../rslib-runtime.mjs";
|
|
5
6
|
import * as __rspack_external__modern_js_runtime_cli_401ee077 from "@modern-js/runtime/cli";
|
|
@@ -78,6 +79,7 @@ async function writeTanstackRouterTypesForEntries(opts) {
|
|
|
78
79
|
function tanstackRouterPlugin(options = {}) {
|
|
79
80
|
const routesDir = options.routesDir || DEFAULT_ROUTES_DIR;
|
|
80
81
|
const generatedDirName = options.generatedDirName || DEFAULT_GENERATED_DIR_NAME;
|
|
82
|
+
const routeSplittingProfile = createTanstackRsbuildRouteSplittingProfile(options);
|
|
81
83
|
return {
|
|
82
84
|
name: '@modern-js/plugin-tanstack',
|
|
83
85
|
required: [
|
|
@@ -113,6 +115,7 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
113
115
|
entry: entry || getRuntimeRouterCli().isRouteEntry(entryPath, routesDir)
|
|
114
116
|
}));
|
|
115
117
|
api.config(()=>({
|
|
118
|
+
...routeSplittingProfile.defaultConfig,
|
|
116
119
|
source: {
|
|
117
120
|
include: [
|
|
118
121
|
/[\\/]node_modules[\\/]@tanstack[\\/]react-router[\\/]/,
|
|
@@ -195,4 +198,4 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
195
198
|
}
|
|
196
199
|
const src_cli = tanstackRouterPlugin;
|
|
197
200
|
export default src_cli;
|
|
198
|
-
export { generateTanstackRouterTypesSourceForEntry, isTanstackRouterFrameworkEnabled, tanstackRouterPlugin, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries };
|
|
201
|
+
export { createTanstackRsbuildRouteSplittingProfile, generateTanstackRouterTypesSourceForEntry, isTanstackRouterFrameworkEnabled, isTanstackStartRouteModuleSource, resolveTanstackRouteCodeSplittingEnabled, tanstackRouterPlugin, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const TANSTACK_START_ROUTE_FACTORY_CALLS = [
|
|
2
|
+
'createFileRoute',
|
|
3
|
+
'createRootRoute',
|
|
4
|
+
'createRootRouteWithContext'
|
|
5
|
+
];
|
|
6
|
+
const TANSTACK_START_ROUTE_FACTORY_REGEX = /\b(createFileRoute|createRootRoute|createRootRouteWithContext)\s*(?:<|\()/;
|
|
7
|
+
function isTanstackStartRouteModuleSource(source) {
|
|
8
|
+
return TANSTACK_START_ROUTE_FACTORY_REGEX.test(source);
|
|
9
|
+
}
|
|
10
|
+
function resolveTanstackRouteCodeSplittingEnabled(option) {
|
|
11
|
+
if ('boolean' == typeof option) return option;
|
|
12
|
+
return option?.enabled ?? true;
|
|
13
|
+
}
|
|
14
|
+
function createTanstackRsbuildRouteSplittingProfile(opts) {
|
|
15
|
+
return {
|
|
16
|
+
defaultConfig: {
|
|
17
|
+
output: {
|
|
18
|
+
splitRouteChunks: resolveTanstackRouteCodeSplittingEnabled(opts.routeCodeSplitting)
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
modernRouteChunks: {
|
|
22
|
+
enabled: resolveTanstackRouteCodeSplittingEnabled(opts.routeCodeSplitting),
|
|
23
|
+
owner: 'modern'
|
|
24
|
+
},
|
|
25
|
+
builderChunkSplit: {
|
|
26
|
+
owner: 'modern-rsbuild',
|
|
27
|
+
preserved: true
|
|
28
|
+
},
|
|
29
|
+
tanstackStartRspackSplitter: {
|
|
30
|
+
compatible: false,
|
|
31
|
+
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.',
|
|
32
|
+
clientDeleteNodes: [
|
|
33
|
+
'ssr',
|
|
34
|
+
'server',
|
|
35
|
+
'headers'
|
|
36
|
+
],
|
|
37
|
+
routeFactoryCalls: [
|
|
38
|
+
...TANSTACK_START_ROUTE_FACTORY_CALLS
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export { createTanstackRsbuildRouteSplittingProfile, isTanstackStartRouteModuleSource, resolveTanstackRouteCodeSplittingEnabled };
|
|
@@ -55,6 +55,14 @@ function pickModernLoaderModule(route) {
|
|
|
55
55
|
inline
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
+
function pickRouteSearchContractModules(route) {
|
|
59
|
+
const validateSearchPath = route.validateSearch;
|
|
60
|
+
const loaderDepsPath = route.loaderDeps;
|
|
61
|
+
return {
|
|
62
|
+
validateSearchPath: 'string' == typeof validateSearchPath ? validateSearchPath : null,
|
|
63
|
+
loaderDepsPath: 'string' == typeof loaderDepsPath ? loaderDepsPath : null
|
|
64
|
+
};
|
|
65
|
+
}
|
|
58
66
|
function isPathlessLayout(route) {
|
|
59
67
|
return 'nested' === route.type && 'boolean' != typeof route.index && void 0 === route.path;
|
|
60
68
|
}
|
|
@@ -88,8 +96,21 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
88
96
|
const imports = [];
|
|
89
97
|
const statements = [];
|
|
90
98
|
const loaderImportMap = new Map();
|
|
99
|
+
const searchContractImportMap = new Map();
|
|
100
|
+
const usedRouteVarNames = new Set();
|
|
91
101
|
let loaderIndex = 0;
|
|
102
|
+
let validateSearchIndex = 0;
|
|
103
|
+
let loaderDepsIndex = 0;
|
|
92
104
|
let routeIndex = 0;
|
|
105
|
+
const resolveRouteModuleNoExt = async (aliasedNoExtPath)=>{
|
|
106
|
+
const prefix = `${appContext.internalSrcAlias}/`;
|
|
107
|
+
let absNoExt;
|
|
108
|
+
if (aliasedNoExtPath.startsWith(prefix)) {
|
|
109
|
+
const rel = aliasedNoExtPath.slice(prefix.length);
|
|
110
|
+
absNoExt = path.join(appContext.srcDirectory, rel);
|
|
111
|
+
} else absNoExt = path.isAbsolute(aliasedNoExtPath) ? aliasedNoExtPath : path.join(appContext.srcDirectory, aliasedNoExtPath);
|
|
112
|
+
return resolveFileNoExt(absNoExt);
|
|
113
|
+
};
|
|
93
114
|
const getImportNamesForLoader = async (aliasedNoExtPath, inline, hasAction)=>{
|
|
94
115
|
const key = `${inline ? 'inline' : 'default'}:${hasAction ? 'action' : 'loader'}:${aliasedNoExtPath}`;
|
|
95
116
|
const existing = loaderImportMap.get(key);
|
|
@@ -97,13 +118,7 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
97
118
|
loaderName: existing,
|
|
98
119
|
actionName: hasAction ? existing.replace(/^loader_/, 'action_') : null
|
|
99
120
|
};
|
|
100
|
-
const
|
|
101
|
-
let absNoExt;
|
|
102
|
-
if (aliasedNoExtPath.startsWith(prefix)) {
|
|
103
|
-
const rel = aliasedNoExtPath.slice(prefix.length);
|
|
104
|
-
absNoExt = path.join(appContext.srcDirectory, rel);
|
|
105
|
-
} else absNoExt = path.isAbsolute(aliasedNoExtPath) ? aliasedNoExtPath : path.join(appContext.srcDirectory, aliasedNoExtPath);
|
|
106
|
-
const resolvedNoExt = await resolveFileNoExt(absNoExt);
|
|
121
|
+
const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
|
|
107
122
|
if (!resolvedNoExt) return null;
|
|
108
123
|
const relImport = normalizeRelativeImport(path.relative(outDir, resolvedNoExt));
|
|
109
124
|
const importName = `loader_${loaderIndex++}`;
|
|
@@ -121,10 +136,29 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
121
136
|
actionName
|
|
122
137
|
};
|
|
123
138
|
};
|
|
139
|
+
const getImportNameForSearchContract = async (aliasedNoExtPath, exportName)=>{
|
|
140
|
+
const key = `${exportName}:${aliasedNoExtPath}`;
|
|
141
|
+
const existing = searchContractImportMap.get(key);
|
|
142
|
+
if (existing) return existing;
|
|
143
|
+
const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
|
|
144
|
+
if (!resolvedNoExt) return null;
|
|
145
|
+
const relImport = normalizeRelativeImport(path.relative(outDir, resolvedNoExt));
|
|
146
|
+
const importName = 'validateSearch' === exportName ? `validateSearch_${validateSearchIndex++}` : `loaderDeps_${loaderDepsIndex++}`;
|
|
147
|
+
imports.push(`import { ${exportName} as ${importName} } from ${quote(relImport)};`);
|
|
148
|
+
searchContractImportMap.set(key, importName);
|
|
149
|
+
return importName;
|
|
150
|
+
};
|
|
151
|
+
const reserveRouteVarName = (preferred)=>{
|
|
152
|
+
let candidate = preferred;
|
|
153
|
+
let suffix = 1;
|
|
154
|
+
while(usedRouteVarNames.has(candidate))candidate = `${preferred}_${suffix++}`;
|
|
155
|
+
usedRouteVarNames.add(candidate);
|
|
156
|
+
return candidate;
|
|
157
|
+
};
|
|
124
158
|
const createRouteVarName = (route)=>{
|
|
125
159
|
const id = route.id;
|
|
126
160
|
const base = id ? makeLegalIdentifier(id) : `r_${routeIndex++}`;
|
|
127
|
-
return `route_${base}
|
|
161
|
+
return reserveRouteVarName(`route_${base}`);
|
|
128
162
|
};
|
|
129
163
|
const buildRoute = async (opts)=>{
|
|
130
164
|
const { parentVar, route } = opts;
|
|
@@ -134,6 +168,9 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
134
168
|
const loaderImports = loaderInfo ? await getImportNamesForLoader(loaderInfo.loaderPath, loaderInfo.inline, Boolean(loaderInfo.inline && routeAction === loaderInfo.loaderPath)) : null;
|
|
135
169
|
const loaderName = loaderImports?.loaderName || null;
|
|
136
170
|
const actionName = loaderImports?.actionName || null;
|
|
171
|
+
const searchContractInfo = pickRouteSearchContractModules(route);
|
|
172
|
+
const validateSearchName = searchContractInfo.validateSearchPath ? await getImportNameForSearchContract(searchContractInfo.validateSearchPath, 'validateSearch') : null;
|
|
173
|
+
const loaderDepsName = searchContractInfo.loaderDepsPath ? await getImportNameForSearchContract(searchContractInfo.loaderDepsPath, 'loaderDeps') : null;
|
|
137
174
|
const rawPath = route.path;
|
|
138
175
|
const hasSplat = 'string' == typeof rawPath && rawPath.includes('*');
|
|
139
176
|
const routeOpts = [
|
|
@@ -147,20 +184,24 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
147
184
|
routeOpts.push(`path: ${quote(p)},`);
|
|
148
185
|
}
|
|
149
186
|
if (loaderName) routeOpts.push(`loader: modernLoaderToTanstack({ hasSplat: ${hasSplat} }, ${loaderName}),`);
|
|
187
|
+
if (validateSearchName) routeOpts.push(`validateSearch: ${validateSearchName},`);
|
|
188
|
+
if (loaderDepsName) routeOpts.push(`loaderDeps: ${loaderDepsName},`);
|
|
150
189
|
const staticDataSnippet = createRouteStaticDataSnippet({
|
|
151
190
|
modernRouteId: route.id,
|
|
152
191
|
loaderName,
|
|
153
192
|
actionName
|
|
154
193
|
});
|
|
155
194
|
if (staticDataSnippet) routeOpts.push(staticDataSnippet);
|
|
156
|
-
statements.push(`const ${varName} = createRoute({\n ${routeOpts.join('\n ')}\n});`);
|
|
157
195
|
const children = route.children;
|
|
196
|
+
const hasChildren = Boolean(children && children.length > 0);
|
|
197
|
+
const routeCtorVarName = hasChildren ? reserveRouteVarName(`${varName}__base`) : varName;
|
|
198
|
+
statements.push(`const ${routeCtorVarName} = createRoute({\n ${routeOpts.join('\n ')}\n});`);
|
|
158
199
|
if (children && children.length > 0) {
|
|
159
200
|
const childVars = await Promise.all(children.map((child)=>buildRoute({
|
|
160
|
-
parentVar:
|
|
201
|
+
parentVar: routeCtorVarName,
|
|
161
202
|
route: child
|
|
162
203
|
})));
|
|
163
|
-
statements.push(
|
|
204
|
+
statements.push(`const ${varName} = ${routeCtorVarName}.addChildren([${childVars.join(', ')}]);`);
|
|
164
205
|
}
|
|
165
206
|
return varName;
|
|
166
207
|
};
|
|
@@ -169,17 +210,23 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
169
210
|
const rootLoaderImports = rootLoaderInfo?.loaderPath ? await getImportNamesForLoader(rootLoaderInfo.loaderPath, rootLoaderInfo.inline, Boolean(rootLoaderInfo.inline && rootAction === rootLoaderInfo.loaderPath)) : null;
|
|
170
211
|
const rootLoaderName = rootLoaderImports?.loaderName || null;
|
|
171
212
|
const rootActionName = rootLoaderImports?.actionName || null;
|
|
213
|
+
const rootSearchContractInfo = rootModern ? pickRouteSearchContractModules(rootModern) : null;
|
|
214
|
+
const rootValidateSearchName = rootSearchContractInfo?.validateSearchPath ? await getImportNameForSearchContract(rootSearchContractInfo.validateSearchPath, 'validateSearch') : null;
|
|
215
|
+
const rootLoaderDepsName = rootSearchContractInfo?.loaderDepsPath ? await getImportNameForSearchContract(rootSearchContractInfo.loaderDepsPath, 'loaderDeps') : null;
|
|
172
216
|
const topLevelVars = await Promise.all(topLevel.map((route)=>buildRoute({
|
|
173
217
|
parentVar: 'rootRoute',
|
|
174
218
|
route
|
|
175
219
|
})));
|
|
176
220
|
const rootOpts = [];
|
|
177
221
|
if (rootLoaderName) rootOpts.push(`loader: modernLoaderToTanstack({ hasSplat: false }, ${rootLoaderName}),`);
|
|
222
|
+
if (rootValidateSearchName) rootOpts.push(`validateSearch: ${rootValidateSearchName},`);
|
|
223
|
+
if (rootLoaderDepsName) rootOpts.push(`loaderDeps: ${rootLoaderDepsName},`);
|
|
178
224
|
const routerGenTs = `/* eslint-disable */
|
|
179
225
|
// This file is auto-generated by Modern.js. Do not edit manually.
|
|
180
226
|
|
|
181
227
|
import {
|
|
182
228
|
createMemoryHistory,
|
|
229
|
+
modernTanstackRouterFastDefaults,
|
|
183
230
|
createRootRouteWithContext,
|
|
184
231
|
createRoute,
|
|
185
232
|
createRouter,
|
|
@@ -207,7 +254,7 @@ function isRedirectResponse(res: Response) {
|
|
|
207
254
|
}
|
|
208
255
|
|
|
209
256
|
function throwTanstackRedirect(location: string) {
|
|
210
|
-
const target = location
|
|
257
|
+
const target = location.length > 0 ? location : '/';
|
|
211
258
|
try {
|
|
212
259
|
void new URL(target);
|
|
213
260
|
throw redirect({ href: target });
|
|
@@ -233,21 +280,87 @@ function createRouteStaticData(opts: {
|
|
|
233
280
|
modernRouteAction?: unknown;
|
|
234
281
|
modernRouteLoader?: unknown;
|
|
235
282
|
}) {
|
|
236
|
-
const staticData:
|
|
283
|
+
const staticData: {
|
|
284
|
+
modernRouteId?: string;
|
|
285
|
+
modernRouteAction?: unknown;
|
|
286
|
+
modernRouteLoader?: unknown;
|
|
287
|
+
} = {};
|
|
237
288
|
|
|
238
|
-
if (opts.modernRouteId) {
|
|
289
|
+
if (typeof opts.modernRouteId === 'string' && opts.modernRouteId.length > 0) {
|
|
239
290
|
staticData.modernRouteId = opts.modernRouteId;
|
|
240
291
|
}
|
|
241
292
|
|
|
242
|
-
if (opts.modernRouteLoader) {
|
|
293
|
+
if (typeof opts.modernRouteLoader !== 'undefined') {
|
|
243
294
|
staticData.modernRouteLoader = opts.modernRouteLoader;
|
|
244
295
|
}
|
|
245
296
|
|
|
246
|
-
if (opts.modernRouteAction) {
|
|
297
|
+
if (typeof opts.modernRouteAction !== 'undefined') {
|
|
247
298
|
staticData.modernRouteAction = opts.modernRouteAction;
|
|
248
299
|
}
|
|
249
300
|
|
|
250
|
-
return
|
|
301
|
+
return staticData;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function getLoaderSignal(ctx: any): AbortSignal {
|
|
305
|
+
const abortSignal = ctx?.abortController?.signal;
|
|
306
|
+
if (abortSignal instanceof AbortSignal) {
|
|
307
|
+
return abortSignal;
|
|
308
|
+
}
|
|
309
|
+
if (ctx?.signal instanceof AbortSignal) {
|
|
310
|
+
return ctx.signal;
|
|
311
|
+
}
|
|
312
|
+
return new AbortController().signal;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function getLoaderHref(ctx: any): string {
|
|
316
|
+
if (typeof ctx?.location === 'string') {
|
|
317
|
+
return ctx.location;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const publicHref = ctx?.location?.publicHref;
|
|
321
|
+
if (typeof publicHref === 'string') {
|
|
322
|
+
return publicHref;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const href = ctx?.location?.href;
|
|
326
|
+
if (typeof href === 'string') {
|
|
327
|
+
return href;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const urlHref = ctx?.location?.url?.href;
|
|
331
|
+
return typeof urlHref === 'string' ? urlHref : '';
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function getLoaderParams(ctx: any): Record<string, string> {
|
|
335
|
+
return typeof ctx?.params === 'object' && ctx.params !== null ? ctx.params : {};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function handleModernLoaderResult<LoaderResult>(result: LoaderResult): LoaderResult {
|
|
339
|
+
if (isResponse(result)) {
|
|
340
|
+
if (isRedirectResponse(result)) {
|
|
341
|
+
const location = result.headers.get('Location') ?? '/';
|
|
342
|
+
throwTanstackRedirect(location);
|
|
343
|
+
}
|
|
344
|
+
if (result.status === 404) {
|
|
345
|
+
throw notFound();
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return result;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function handleModernLoaderError(err: unknown): never {
|
|
353
|
+
if (isResponse(err)) {
|
|
354
|
+
if (isRedirectResponse(err)) {
|
|
355
|
+
const location = err.headers.get('Location') ?? '/';
|
|
356
|
+
throwTanstackRedirect(location);
|
|
357
|
+
}
|
|
358
|
+
if (err.status === 404) {
|
|
359
|
+
throw notFound();
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
throw err;
|
|
251
364
|
}
|
|
252
365
|
|
|
253
366
|
function modernLoaderToTanstack<TLoader extends (args: any) => any>(
|
|
@@ -256,57 +369,31 @@ function modernLoaderToTanstack<TLoader extends (args: any) => any>(
|
|
|
256
369
|
) {
|
|
257
370
|
type LoaderResult = Awaited<ReturnType<TLoader>>;
|
|
258
371
|
|
|
259
|
-
return
|
|
372
|
+
return (ctx: any): Promise<LoaderResult> => {
|
|
260
373
|
try {
|
|
261
|
-
const signal
|
|
262
|
-
ctx?.abortController?.signal ||
|
|
263
|
-
ctx?.signal ||
|
|
264
|
-
new AbortController().signal;
|
|
374
|
+
const signal = getLoaderSignal(ctx);
|
|
265
375
|
const baseRequest: Request | undefined =
|
|
266
376
|
ctx?.context?.request instanceof Request ? ctx.context.request : undefined;
|
|
267
377
|
|
|
268
|
-
const href =
|
|
269
|
-
typeof ctx?.location === 'string'
|
|
270
|
-
? ctx.location
|
|
271
|
-
: ctx?.location?.publicHref ||
|
|
272
|
-
ctx?.location?.href ||
|
|
273
|
-
ctx?.location?.url?.href ||
|
|
274
|
-
'';
|
|
378
|
+
const href = getLoaderHref(ctx);
|
|
275
379
|
|
|
276
|
-
const request = baseRequest
|
|
380
|
+
const request = baseRequest !== undefined
|
|
277
381
|
? new Request(baseRequest, { signal })
|
|
278
382
|
: new Request(href, { signal });
|
|
279
383
|
|
|
280
|
-
const params = mapParamsForModernLoader(ctx
|
|
384
|
+
const params = mapParamsForModernLoader(getLoaderParams(ctx), opts.hasSplat);
|
|
281
385
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
throwTanstackRedirect(location);
|
|
292
|
-
}
|
|
293
|
-
if (result.status === 404) {
|
|
294
|
-
throw notFound();
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
return result as LoaderResult;
|
|
386
|
+
return Promise.resolve(
|
|
387
|
+
(modernLoader as any)({
|
|
388
|
+
request,
|
|
389
|
+
params,
|
|
390
|
+
context: ctx?.context?.requestContext,
|
|
391
|
+
}),
|
|
392
|
+
)
|
|
393
|
+
.then((result: LoaderResult) => handleModernLoaderResult(result))
|
|
394
|
+
.catch(handleModernLoaderError);
|
|
299
395
|
} catch (err) {
|
|
300
|
-
|
|
301
|
-
if (isRedirectResponse(err)) {
|
|
302
|
-
const location = err.headers.get('Location') || '/';
|
|
303
|
-
throwTanstackRedirect(location);
|
|
304
|
-
}
|
|
305
|
-
if (err.status === 404) {
|
|
306
|
-
throw notFound();
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
throw err;
|
|
396
|
+
handleModernLoaderError(err);
|
|
310
397
|
}
|
|
311
398
|
};
|
|
312
399
|
}
|
|
@@ -327,6 +414,7 @@ ${statements.join('\n\n')}
|
|
|
327
414
|
export const routeTree = rootRoute.addChildren([${topLevelVars.join(', ')}]);
|
|
328
415
|
|
|
329
416
|
export const router = createRouter({
|
|
417
|
+
...modernTanstackRouterFastDefaults,
|
|
330
418
|
routeTree,
|
|
331
419
|
history: createMemoryHistory({
|
|
332
420
|
initialEntries: ['/'],
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Suspense } from "react";
|
|
3
|
+
function wrapTanstackSsrHydrationBoundary(routerContent, shouldWrap) {
|
|
4
|
+
if (shouldWrap) return /*#__PURE__*/ jsx(Suspense, {
|
|
5
|
+
fallback: null,
|
|
6
|
+
children: routerContent
|
|
7
|
+
});
|
|
8
|
+
return routerContent;
|
|
9
|
+
}
|
|
10
|
+
export { wrapTanstackSsrHydrationBoundary };
|