@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.89 → 3.2.0-ultramodern.90

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.
Files changed (43) hide show
  1. package/dist/cjs/cli/index.js +12 -0
  2. package/dist/cjs/cli/routeSplitting.js +83 -0
  3. package/dist/cjs/cli/tanstackTypes.js +45 -7
  4. package/dist/cjs/runtime/index.js +12 -0
  5. package/dist/cjs/runtime/plugin.js +2 -0
  6. package/dist/cjs/runtime/plugin.node.js +2 -0
  7. package/dist/cjs/runtime/routeTree.js +8 -0
  8. package/dist/cjs/runtime/types.js +27 -1
  9. package/dist/esm/cli/index.mjs +4 -1
  10. package/dist/esm/cli/routeSplitting.mjs +43 -0
  11. package/dist/esm/cli/tanstackTypes.mjs +45 -7
  12. package/dist/esm/runtime/index.mjs +1 -0
  13. package/dist/esm/runtime/plugin.mjs +2 -0
  14. package/dist/esm/runtime/plugin.node.mjs +2 -0
  15. package/dist/esm/runtime/routeTree.mjs +8 -0
  16. package/dist/esm/runtime/types.mjs +7 -0
  17. package/dist/esm-node/cli/index.mjs +4 -1
  18. package/dist/esm-node/cli/routeSplitting.mjs +44 -0
  19. package/dist/esm-node/cli/tanstackTypes.mjs +45 -7
  20. package/dist/esm-node/runtime/index.mjs +1 -0
  21. package/dist/esm-node/runtime/plugin.mjs +2 -0
  22. package/dist/esm-node/runtime/plugin.node.mjs +2 -0
  23. package/dist/esm-node/runtime/routeTree.mjs +8 -0
  24. package/dist/esm-node/runtime/types.mjs +7 -0
  25. package/dist/types/cli/index.d.ts +4 -0
  26. package/dist/types/cli/routeSplitting.d.ts +29 -0
  27. package/dist/types/runtime/index.d.ts +2 -0
  28. package/dist/types/runtime/plugin.d.ts +1 -1
  29. package/dist/types/runtime/plugin.node.d.ts +1 -1
  30. package/dist/types/runtime/types.d.ts +7 -0
  31. package/package.json +10 -10
  32. package/src/cli/index.ts +17 -0
  33. package/src/cli/routeSplitting.ts +81 -0
  34. package/src/cli/tanstackTypes.ts +102 -13
  35. package/src/runtime/index.tsx +5 -0
  36. package/src/runtime/plugin.node.tsx +6 -1
  37. package/src/runtime/plugin.tsx +5 -1
  38. package/src/runtime/routeTree.ts +12 -0
  39. package/src/runtime/types.ts +13 -0
  40. package/tests/router/cli.test.ts +239 -0
  41. package/tests/router/fastDefaults.test.ts +25 -0
  42. package/tests/router/routeTree.test.ts +87 -0
  43. package/tests/router/tanstackTypes.test.ts +120 -0
@@ -48,9 +48,12 @@ var __webpack_exports__ = {};
48
48
  (()=>{
49
49
  __webpack_require__.r(__webpack_exports__);
50
50
  __webpack_require__.d(__webpack_exports__, {
51
+ createTanstackRsbuildRouteSplittingProfile: ()=>external_routeSplitting_js_namespaceObject.createTanstackRsbuildRouteSplittingProfile,
51
52
  default: ()=>src_cli,
52
53
  generateTanstackRouterTypesSourceForEntry: ()=>external_tanstackTypes_js_namespaceObject.generateTanstackRouterTypesSourceForEntry,
53
54
  isTanstackRouterFrameworkEnabled: ()=>external_tanstackTypes_js_namespaceObject.isTanstackRouterFrameworkEnabled,
55
+ isTanstackStartRouteModuleSource: ()=>external_routeSplitting_js_namespaceObject.isTanstackStartRouteModuleSource,
56
+ resolveTanstackRouteCodeSplittingEnabled: ()=>external_routeSplitting_js_namespaceObject.resolveTanstackRouteCodeSplittingEnabled,
54
57
  tanstackRouterPlugin: ()=>tanstackRouterPlugin,
55
58
  writeTanstackRegisterFile: ()=>writeTanstackRegisterFile,
56
59
  writeTanstackRouterTypesForEntries: ()=>writeTanstackRouterTypesForEntries
@@ -58,6 +61,7 @@ var __webpack_exports__ = {};
58
61
  const external_node_path_namespaceObject = require("node:path");
59
62
  var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
60
63
  const utils_namespaceObject = require("@modern-js/utils");
64
+ const external_routeSplitting_js_namespaceObject = require("./routeSplitting.js");
61
65
  const external_tanstackTypes_js_namespaceObject = require("./tanstackTypes.js");
62
66
  const DEFAULT_ROUTES_DIR = 'routes';
63
67
  const DEFAULT_GENERATED_DIR_NAME = 'modern-tanstack';
@@ -129,6 +133,7 @@ declare module '${opts.runtimeModule}' {
129
133
  function tanstackRouterPlugin(options = {}) {
130
134
  const routesDir = options.routesDir || DEFAULT_ROUTES_DIR;
131
135
  const generatedDirName = options.generatedDirName || DEFAULT_GENERATED_DIR_NAME;
136
+ const routeSplittingProfile = (0, external_routeSplitting_js_namespaceObject.createTanstackRsbuildRouteSplittingProfile)(options);
132
137
  return {
133
138
  name: '@modern-js/plugin-tanstack',
134
139
  required: [
@@ -164,6 +169,7 @@ declare module '${opts.runtimeModule}' {
164
169
  entry: entry || getRuntimeRouterCli().isRouteEntry(entryPath, routesDir)
165
170
  }));
166
171
  api.config(()=>({
172
+ ...routeSplittingProfile.defaultConfig,
167
173
  source: {
168
174
  include: [
169
175
  /[\\/]node_modules[\\/]@tanstack[\\/]react-router[\\/]/,
@@ -246,16 +252,22 @@ declare module '${opts.runtimeModule}' {
246
252
  }
247
253
  const src_cli = tanstackRouterPlugin;
248
254
  })();
255
+ exports.createTanstackRsbuildRouteSplittingProfile = __webpack_exports__.createTanstackRsbuildRouteSplittingProfile;
249
256
  exports["default"] = __webpack_exports__["default"];
250
257
  exports.generateTanstackRouterTypesSourceForEntry = __webpack_exports__.generateTanstackRouterTypesSourceForEntry;
251
258
  exports.isTanstackRouterFrameworkEnabled = __webpack_exports__.isTanstackRouterFrameworkEnabled;
259
+ exports.isTanstackStartRouteModuleSource = __webpack_exports__.isTanstackStartRouteModuleSource;
260
+ exports.resolveTanstackRouteCodeSplittingEnabled = __webpack_exports__.resolveTanstackRouteCodeSplittingEnabled;
252
261
  exports.tanstackRouterPlugin = __webpack_exports__.tanstackRouterPlugin;
253
262
  exports.writeTanstackRegisterFile = __webpack_exports__.writeTanstackRegisterFile;
254
263
  exports.writeTanstackRouterTypesForEntries = __webpack_exports__.writeTanstackRouterTypesForEntries;
255
264
  for(var __rspack_i in __webpack_exports__)if (-1 === [
265
+ "createTanstackRsbuildRouteSplittingProfile",
256
266
  "default",
257
267
  "generateTanstackRouterTypesSourceForEntry",
258
268
  "isTanstackRouterFrameworkEnabled",
269
+ "isTanstackStartRouteModuleSource",
270
+ "resolveTanstackRouteCodeSplittingEnabled",
259
271
  "tanstackRouterPlugin",
260
272
  "writeTanstackRegisterFile",
261
273
  "writeTanstackRouterTypesForEntries"
@@ -0,0 +1,83 @@
1
+ "use strict";
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
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ createTanstackRsbuildRouteSplittingProfile: ()=>createTanstackRsbuildRouteSplittingProfile,
28
+ isTanstackStartRouteModuleSource: ()=>isTanstackStartRouteModuleSource,
29
+ resolveTanstackRouteCodeSplittingEnabled: ()=>resolveTanstackRouteCodeSplittingEnabled
30
+ });
31
+ const TANSTACK_START_ROUTE_FACTORY_CALLS = [
32
+ 'createFileRoute',
33
+ 'createRootRoute',
34
+ 'createRootRouteWithContext'
35
+ ];
36
+ const TANSTACK_START_ROUTE_FACTORY_REGEX = /\b(createFileRoute|createRootRoute|createRootRouteWithContext)\s*(?:<|\()/;
37
+ function isTanstackStartRouteModuleSource(source) {
38
+ return TANSTACK_START_ROUTE_FACTORY_REGEX.test(source);
39
+ }
40
+ function resolveTanstackRouteCodeSplittingEnabled(option) {
41
+ if ('boolean' == typeof option) return option;
42
+ return option?.enabled ?? true;
43
+ }
44
+ function createTanstackRsbuildRouteSplittingProfile(opts) {
45
+ return {
46
+ defaultConfig: {
47
+ output: {
48
+ splitRouteChunks: resolveTanstackRouteCodeSplittingEnabled(opts.routeCodeSplitting)
49
+ }
50
+ },
51
+ modernRouteChunks: {
52
+ enabled: resolveTanstackRouteCodeSplittingEnabled(opts.routeCodeSplitting),
53
+ owner: 'modern'
54
+ },
55
+ builderChunkSplit: {
56
+ owner: 'modern-rsbuild',
57
+ preserved: true
58
+ },
59
+ tanstackStartRspackSplitter: {
60
+ compatible: false,
61
+ 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.',
62
+ clientDeleteNodes: [
63
+ 'ssr',
64
+ 'server',
65
+ 'headers'
66
+ ],
67
+ routeFactoryCalls: [
68
+ ...TANSTACK_START_ROUTE_FACTORY_CALLS
69
+ ]
70
+ }
71
+ };
72
+ }
73
+ exports.createTanstackRsbuildRouteSplittingProfile = __webpack_exports__.createTanstackRsbuildRouteSplittingProfile;
74
+ exports.isTanstackStartRouteModuleSource = __webpack_exports__.isTanstackStartRouteModuleSource;
75
+ exports.resolveTanstackRouteCodeSplittingEnabled = __webpack_exports__.resolveTanstackRouteCodeSplittingEnabled;
76
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
77
+ "createTanstackRsbuildRouteSplittingProfile",
78
+ "isTanstackStartRouteModuleSource",
79
+ "resolveTanstackRouteCodeSplittingEnabled"
80
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
81
+ Object.defineProperty(exports, '__esModule', {
82
+ value: true
83
+ });
@@ -94,6 +94,14 @@ function pickModernLoaderModule(route) {
94
94
  inline
95
95
  };
96
96
  }
97
+ function pickRouteSearchContractModules(route) {
98
+ const validateSearchPath = route.validateSearch;
99
+ const loaderDepsPath = route.loaderDeps;
100
+ return {
101
+ validateSearchPath: 'string' == typeof validateSearchPath ? validateSearchPath : null,
102
+ loaderDepsPath: 'string' == typeof loaderDepsPath ? loaderDepsPath : null
103
+ };
104
+ }
97
105
  function isPathlessLayout(route) {
98
106
  return 'nested' === route.type && 'boolean' != typeof route.index && void 0 === route.path;
99
107
  }
@@ -127,9 +135,21 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
127
135
  const imports = [];
128
136
  const statements = [];
129
137
  const loaderImportMap = new Map();
138
+ const searchContractImportMap = new Map();
130
139
  const usedRouteVarNames = new Set();
131
140
  let loaderIndex = 0;
141
+ let validateSearchIndex = 0;
142
+ let loaderDepsIndex = 0;
132
143
  let routeIndex = 0;
144
+ const resolveRouteModuleNoExt = async (aliasedNoExtPath)=>{
145
+ const prefix = `${appContext.internalSrcAlias}/`;
146
+ let absNoExt;
147
+ if (aliasedNoExtPath.startsWith(prefix)) {
148
+ const rel = aliasedNoExtPath.slice(prefix.length);
149
+ absNoExt = external_path_default().join(appContext.srcDirectory, rel);
150
+ } else absNoExt = external_path_default().isAbsolute(aliasedNoExtPath) ? aliasedNoExtPath : external_path_default().join(appContext.srcDirectory, aliasedNoExtPath);
151
+ return resolveFileNoExt(absNoExt);
152
+ };
133
153
  const getImportNamesForLoader = async (aliasedNoExtPath, inline, hasAction)=>{
134
154
  const key = `${inline ? 'inline' : 'default'}:${hasAction ? 'action' : 'loader'}:${aliasedNoExtPath}`;
135
155
  const existing = loaderImportMap.get(key);
@@ -137,13 +157,7 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
137
157
  loaderName: existing,
138
158
  actionName: hasAction ? existing.replace(/^loader_/, 'action_') : null
139
159
  };
140
- const prefix = `${appContext.internalSrcAlias}/`;
141
- let absNoExt;
142
- if (aliasedNoExtPath.startsWith(prefix)) {
143
- const rel = aliasedNoExtPath.slice(prefix.length);
144
- absNoExt = external_path_default().join(appContext.srcDirectory, rel);
145
- } else absNoExt = external_path_default().isAbsolute(aliasedNoExtPath) ? aliasedNoExtPath : external_path_default().join(appContext.srcDirectory, aliasedNoExtPath);
146
- const resolvedNoExt = await resolveFileNoExt(absNoExt);
160
+ const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
147
161
  if (!resolvedNoExt) return null;
148
162
  const relImport = normalizeRelativeImport(external_path_default().relative(outDir, resolvedNoExt));
149
163
  const importName = `loader_${loaderIndex++}`;
@@ -161,6 +175,18 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
161
175
  actionName
162
176
  };
163
177
  };
178
+ const getImportNameForSearchContract = async (aliasedNoExtPath, exportName)=>{
179
+ const key = `${exportName}:${aliasedNoExtPath}`;
180
+ const existing = searchContractImportMap.get(key);
181
+ if (existing) return existing;
182
+ const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
183
+ if (!resolvedNoExt) return null;
184
+ const relImport = normalizeRelativeImport(external_path_default().relative(outDir, resolvedNoExt));
185
+ const importName = 'validateSearch' === exportName ? `validateSearch_${validateSearchIndex++}` : `loaderDeps_${loaderDepsIndex++}`;
186
+ imports.push(`import { ${exportName} as ${importName} } from ${quote(relImport)};`);
187
+ searchContractImportMap.set(key, importName);
188
+ return importName;
189
+ };
164
190
  const reserveRouteVarName = (preferred)=>{
165
191
  let candidate = preferred;
166
192
  let suffix = 1;
@@ -181,6 +207,9 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
181
207
  const loaderImports = loaderInfo ? await getImportNamesForLoader(loaderInfo.loaderPath, loaderInfo.inline, Boolean(loaderInfo.inline && routeAction === loaderInfo.loaderPath)) : null;
182
208
  const loaderName = loaderImports?.loaderName || null;
183
209
  const actionName = loaderImports?.actionName || null;
210
+ const searchContractInfo = pickRouteSearchContractModules(route);
211
+ const validateSearchName = searchContractInfo.validateSearchPath ? await getImportNameForSearchContract(searchContractInfo.validateSearchPath, 'validateSearch') : null;
212
+ const loaderDepsName = searchContractInfo.loaderDepsPath ? await getImportNameForSearchContract(searchContractInfo.loaderDepsPath, 'loaderDeps') : null;
184
213
  const rawPath = route.path;
185
214
  const hasSplat = 'string' == typeof rawPath && rawPath.includes('*');
186
215
  const routeOpts = [
@@ -194,6 +223,8 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
194
223
  routeOpts.push(`path: ${quote(p)},`);
195
224
  }
196
225
  if (loaderName) routeOpts.push(`loader: modernLoaderToTanstack({ hasSplat: ${hasSplat} }, ${loaderName}),`);
226
+ if (validateSearchName) routeOpts.push(`validateSearch: ${validateSearchName},`);
227
+ if (loaderDepsName) routeOpts.push(`loaderDeps: ${loaderDepsName},`);
197
228
  const staticDataSnippet = createRouteStaticDataSnippet({
198
229
  modernRouteId: route.id,
199
230
  loaderName,
@@ -218,17 +249,23 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
218
249
  const rootLoaderImports = rootLoaderInfo?.loaderPath ? await getImportNamesForLoader(rootLoaderInfo.loaderPath, rootLoaderInfo.inline, Boolean(rootLoaderInfo.inline && rootAction === rootLoaderInfo.loaderPath)) : null;
219
250
  const rootLoaderName = rootLoaderImports?.loaderName || null;
220
251
  const rootActionName = rootLoaderImports?.actionName || null;
252
+ const rootSearchContractInfo = rootModern ? pickRouteSearchContractModules(rootModern) : null;
253
+ const rootValidateSearchName = rootSearchContractInfo?.validateSearchPath ? await getImportNameForSearchContract(rootSearchContractInfo.validateSearchPath, 'validateSearch') : null;
254
+ const rootLoaderDepsName = rootSearchContractInfo?.loaderDepsPath ? await getImportNameForSearchContract(rootSearchContractInfo.loaderDepsPath, 'loaderDeps') : null;
221
255
  const topLevelVars = await Promise.all(topLevel.map((route)=>buildRoute({
222
256
  parentVar: 'rootRoute',
223
257
  route
224
258
  })));
225
259
  const rootOpts = [];
226
260
  if (rootLoaderName) rootOpts.push(`loader: modernLoaderToTanstack({ hasSplat: false }, ${rootLoaderName}),`);
261
+ if (rootValidateSearchName) rootOpts.push(`validateSearch: ${rootValidateSearchName},`);
262
+ if (rootLoaderDepsName) rootOpts.push(`loaderDeps: ${rootLoaderDepsName},`);
227
263
  const routerGenTs = `/* eslint-disable */
228
264
  // This file is auto-generated by Modern.js. Do not edit manually.
229
265
 
230
266
  import {
231
267
  createMemoryHistory,
268
+ modernTanstackRouterFastDefaults,
232
269
  createRootRouteWithContext,
233
270
  createRoute,
234
271
  createRouter,
@@ -416,6 +453,7 @@ ${statements.join('\n\n')}
416
453
  export const routeTree = rootRoute.addChildren([${topLevelVars.join(', ')}]);
417
454
 
418
455
  export const router = createRouter({
456
+ ...modernTanstackRouterFastDefaults,
419
457
  routeTree,
420
458
  history: createMemoryHistory({
421
459
  initialEntries: ['/'],
@@ -12,6 +12,9 @@ var __webpack_modules__ = {
12
12
  "./rsc/client" (module) {
13
13
  module.exports = require("./rsc/client.js");
14
14
  },
15
+ "./types" (module) {
16
+ module.exports = require("./types.js");
17
+ },
15
18
  "@tanstack/react-router" (module) {
16
19
  module.exports = require("@tanstack/react-router");
17
20
  }
@@ -67,6 +70,8 @@ var __webpack_exports__ = {};
67
70
  Outlet: ()=>_tanstack_react_router__rspack_import_0.Outlet,
68
71
  RouteActionResponseError: ()=>_dataMutation__rspack_import_1.RouteActionResponseError,
69
72
  default: ()=>_plugin__rspack_import_2.tanstackRouterPlugin,
73
+ getModernTanstackRouterFastDefaults: ()=>_types__rspack_import_5.getModernTanstackRouterFastDefaults,
74
+ modernTanstackRouterFastDefaults: ()=>_types__rspack_import_5.modernTanstackRouterFastDefaults,
70
75
  tanstackRouterPlugin: ()=>_plugin__rspack_import_2.tanstackRouterPlugin,
71
76
  useFetcher: ()=>_dataMutation__rspack_import_1.useFetcher,
72
77
  useLocation: ()=>_tanstack_react_router__rspack_import_0.useLocation,
@@ -87,9 +92,11 @@ var __webpack_exports__ = {};
87
92
  "Link",
88
93
  "default",
89
94
  "NavLink",
95
+ "getModernTanstackRouterFastDefaults",
90
96
  "useMatch",
91
97
  "tanstackRouterPlugin",
92
98
  "useLocation",
99
+ "modernTanstackRouterFastDefaults",
93
100
  "RouteActionResponseError",
94
101
  "Outlet"
95
102
  ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_tanstack_react_router__rspack_import_0[__rspack_import_key];
@@ -98,6 +105,7 @@ var __webpack_exports__ = {};
98
105
  var _plugin__rspack_import_2 = __webpack_require__("./plugin");
99
106
  var _prefetchLink__rspack_import_3 = __webpack_require__("./prefetchLink");
100
107
  var _rsc_client__rspack_import_4 = __webpack_require__("./rsc/client");
108
+ var _types__rspack_import_5 = __webpack_require__("./types");
101
109
  })();
102
110
  exports.CompositeComponent = __webpack_exports__.CompositeComponent;
103
111
  exports.Form = __webpack_exports__.Form;
@@ -106,6 +114,8 @@ exports.NavLink = __webpack_exports__.NavLink;
106
114
  exports.Outlet = __webpack_exports__.Outlet;
107
115
  exports.RouteActionResponseError = __webpack_exports__.RouteActionResponseError;
108
116
  exports["default"] = __webpack_exports__["default"];
117
+ exports.getModernTanstackRouterFastDefaults = __webpack_exports__.getModernTanstackRouterFastDefaults;
118
+ exports.modernTanstackRouterFastDefaults = __webpack_exports__.modernTanstackRouterFastDefaults;
109
119
  exports.tanstackRouterPlugin = __webpack_exports__.tanstackRouterPlugin;
110
120
  exports.useFetcher = __webpack_exports__.useFetcher;
111
121
  exports.useLocation = __webpack_exports__.useLocation;
@@ -121,6 +131,8 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
121
131
  "Outlet",
122
132
  "RouteActionResponseError",
123
133
  "default",
134
+ "getModernTanstackRouterFastDefaults",
135
+ "modernTanstackRouterFastDefaults",
124
136
  "tanstackRouterPlugin",
125
137
  "useFetcher",
126
138
  "useLocation",
@@ -40,6 +40,7 @@ const external_lifecycle_js_namespaceObject = require("./lifecycle.js");
40
40
  const external_prefetchLink_js_namespaceObject = require("./prefetchLink.js");
41
41
  const external_routeTree_js_namespaceObject = require("./routeTree.js");
42
42
  const client_js_namespaceObject = require("./rsc/client.js");
43
+ const external_types_js_namespaceObject = require("./types.js");
43
44
  const external_utils_js_namespaceObject = require("./utils.js");
44
45
  const BLOCKING_SUBSCRIBE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-subscribe');
45
46
  const BLOCKING_STATE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-state');
@@ -173,6 +174,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
173
174
  const rewrite = (0, external_basepathRewrite_js_namespaceObject.createModernBasepathRewrite)(_basename);
174
175
  const serializationAdapters = (0, context_namespaceObject.getGlobalEnableRsc)() ? (0, client_js_namespaceObject.getTanstackRscSerializationAdapters)() : void 0;
175
176
  cachedRouter = (0, react_router_namespaceObject.createRouter)({
177
+ ...(0, external_types_js_namespaceObject.getModernTanstackRouterFastDefaults)(mergedConfig),
176
178
  routeTree,
177
179
  basepath: '/',
178
180
  rewrite,
@@ -41,6 +41,7 @@ const external_hooks_js_namespaceObject = require("./hooks.js");
41
41
  const external_lifecycle_js_namespaceObject = require("./lifecycle.js");
42
42
  const external_routeTree_js_namespaceObject = require("./routeTree.js");
43
43
  const payloadRouter_js_namespaceObject = require("./rsc/payloadRouter.js");
44
+ const external_types_js_namespaceObject = require("./types.js");
44
45
  const external_utils_js_namespaceObject = require("./utils.js");
45
46
  const setTanstackRscServerPayload = (payload)=>{
46
47
  const storageContext = node_namespaceObject.storage.useContext?.();
@@ -206,6 +207,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
206
207
  };
207
208
  hooks.onBeforeCreateRouter.call(routerLifecycleContext);
208
209
  const tanstackRouter = (0, react_router_namespaceObject.createRouter)({
210
+ ...(0, external_types_js_namespaceObject.getModernTanstackRouterFastDefaults)(mergedConfig),
209
211
  routeTree,
210
212
  history,
211
213
  basepath: '/',
@@ -347,6 +347,8 @@ function createRouteFromRouteObject(opts) {
347
347
  component: toRouteComponent(routeObject),
348
348
  pendingComponent: toPendingComponent(routeObject),
349
349
  errorComponent: toErrorComponent(routeObject),
350
+ validateSearch: modernRouteObject.validateSearch,
351
+ loaderDeps: modernRouteObject.loaderDeps,
350
352
  wrapInSuspense: true,
351
353
  staticData: createRouteStaticData({
352
354
  modernRouteId: routeObject.id,
@@ -397,6 +399,8 @@ function createRouteFromModernRoute(opts) {
397
399
  component: component || void 0,
398
400
  pendingComponent: pendingComponent || void 0,
399
401
  errorComponent: errorComponent || void 0,
402
+ validateSearch: route.validateSearch,
403
+ loaderDeps: route.loaderDeps,
400
404
  wrapInSuspense: true,
401
405
  staticData: createRouteStaticData({
402
406
  modernRouteId: modernId,
@@ -445,6 +449,8 @@ function createRouteTreeFromModernRoutes(routes, options = {}) {
445
449
  component: rootComponent || void 0,
446
450
  pendingComponent: pendingComponent || void 0,
447
451
  errorComponent: errorComponent || void 0,
452
+ validateSearch: rootModern?.validateSearch,
453
+ loaderDeps: rootModern?.loaderDeps,
448
454
  wrapInSuspense: true,
449
455
  notFoundComponent: external_DefaultNotFound_js_namespaceObject.DefaultNotFound,
450
456
  staticData: createRouteStaticData({
@@ -484,6 +490,8 @@ function createRouteTreeFromRouteObjects(routes, options = {}) {
484
490
  component: rootLikeRoute ? toRouteComponent(rootLikeRoute) : void 0,
485
491
  pendingComponent: rootLikeRoute ? toPendingComponent(rootLikeRoute) : void 0,
486
492
  errorComponent: rootLikeRoute ? toErrorComponent(rootLikeRoute) : void 0,
493
+ validateSearch: rootLikeRoute?.validateSearch,
494
+ loaderDeps: rootLikeRoute?.loaderDeps,
487
495
  wrapInSuspense: true,
488
496
  notFoundComponent: external_DefaultNotFound_js_namespaceObject.DefaultNotFound,
489
497
  staticData: createRouteStaticData({
@@ -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
- for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
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
  });
@@ -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,9 +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();
91
100
  const usedRouteVarNames = new Set();
92
101
  let loaderIndex = 0;
102
+ let validateSearchIndex = 0;
103
+ let loaderDepsIndex = 0;
93
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
+ };
94
114
  const getImportNamesForLoader = async (aliasedNoExtPath, inline, hasAction)=>{
95
115
  const key = `${inline ? 'inline' : 'default'}:${hasAction ? 'action' : 'loader'}:${aliasedNoExtPath}`;
96
116
  const existing = loaderImportMap.get(key);
@@ -98,13 +118,7 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
98
118
  loaderName: existing,
99
119
  actionName: hasAction ? existing.replace(/^loader_/, 'action_') : null
100
120
  };
101
- const prefix = `${appContext.internalSrcAlias}/`;
102
- let absNoExt;
103
- if (aliasedNoExtPath.startsWith(prefix)) {
104
- const rel = aliasedNoExtPath.slice(prefix.length);
105
- absNoExt = path.join(appContext.srcDirectory, rel);
106
- } else absNoExt = path.isAbsolute(aliasedNoExtPath) ? aliasedNoExtPath : path.join(appContext.srcDirectory, aliasedNoExtPath);
107
- const resolvedNoExt = await resolveFileNoExt(absNoExt);
121
+ const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
108
122
  if (!resolvedNoExt) return null;
109
123
  const relImport = normalizeRelativeImport(path.relative(outDir, resolvedNoExt));
110
124
  const importName = `loader_${loaderIndex++}`;
@@ -122,6 +136,18 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
122
136
  actionName
123
137
  };
124
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
+ };
125
151
  const reserveRouteVarName = (preferred)=>{
126
152
  let candidate = preferred;
127
153
  let suffix = 1;
@@ -142,6 +168,9 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
142
168
  const loaderImports = loaderInfo ? await getImportNamesForLoader(loaderInfo.loaderPath, loaderInfo.inline, Boolean(loaderInfo.inline && routeAction === loaderInfo.loaderPath)) : null;
143
169
  const loaderName = loaderImports?.loaderName || null;
144
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;
145
174
  const rawPath = route.path;
146
175
  const hasSplat = 'string' == typeof rawPath && rawPath.includes('*');
147
176
  const routeOpts = [
@@ -155,6 +184,8 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
155
184
  routeOpts.push(`path: ${quote(p)},`);
156
185
  }
157
186
  if (loaderName) routeOpts.push(`loader: modernLoaderToTanstack({ hasSplat: ${hasSplat} }, ${loaderName}),`);
187
+ if (validateSearchName) routeOpts.push(`validateSearch: ${validateSearchName},`);
188
+ if (loaderDepsName) routeOpts.push(`loaderDeps: ${loaderDepsName},`);
158
189
  const staticDataSnippet = createRouteStaticDataSnippet({
159
190
  modernRouteId: route.id,
160
191
  loaderName,
@@ -179,17 +210,23 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
179
210
  const rootLoaderImports = rootLoaderInfo?.loaderPath ? await getImportNamesForLoader(rootLoaderInfo.loaderPath, rootLoaderInfo.inline, Boolean(rootLoaderInfo.inline && rootAction === rootLoaderInfo.loaderPath)) : null;
180
211
  const rootLoaderName = rootLoaderImports?.loaderName || null;
181
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;
182
216
  const topLevelVars = await Promise.all(topLevel.map((route)=>buildRoute({
183
217
  parentVar: 'rootRoute',
184
218
  route
185
219
  })));
186
220
  const rootOpts = [];
187
221
  if (rootLoaderName) rootOpts.push(`loader: modernLoaderToTanstack({ hasSplat: false }, ${rootLoaderName}),`);
222
+ if (rootValidateSearchName) rootOpts.push(`validateSearch: ${rootValidateSearchName},`);
223
+ if (rootLoaderDepsName) rootOpts.push(`loaderDeps: ${rootLoaderDepsName},`);
188
224
  const routerGenTs = `/* eslint-disable */
189
225
  // This file is auto-generated by Modern.js. Do not edit manually.
190
226
 
191
227
  import {
192
228
  createMemoryHistory,
229
+ modernTanstackRouterFastDefaults,
193
230
  createRootRouteWithContext,
194
231
  createRoute,
195
232
  createRouter,
@@ -377,6 +414,7 @@ ${statements.join('\n\n')}
377
414
  export const routeTree = rootRoute.addChildren([${topLevelVars.join(', ')}]);
378
415
 
379
416
  export const router = createRouter({
417
+ ...modernTanstackRouterFastDefaults,
380
418
  routeTree,
381
419
  history: createMemoryHistory({
382
420
  initialEntries: ['/'],
@@ -4,3 +4,4 @@ export { Form, RouteActionResponseError, useFetcher } from "./dataMutation.mjs";
4
4
  export { tanstackRouterPlugin as default, tanstackRouterPlugin } from "./plugin.mjs";
5
5
  export { Link, NavLink } from "./prefetchLink.mjs";
6
6
  export { CompositeComponent } from "./rsc/client.mjs";
7
+ export { getModernTanstackRouterFastDefaults, modernTanstackRouterFastDefaults } from "./types.mjs";
@@ -11,6 +11,7 @@ import { applyRouterRuntimeState } from "./lifecycle.mjs";
11
11
  import { Link } from "./prefetchLink.mjs";
12
12
  import { createRouteTreeFromRouteObjects } from "./routeTree.mjs";
13
13
  import { getTanstackRscSerializationAdapters } from "./rsc/client.mjs";
14
+ import { getModernTanstackRouterFastDefaults } from "./types.mjs";
14
15
  import { createRouteObjectsFromConfig, urlJoin } from "./utils.mjs";
15
16
  const BLOCKING_SUBSCRIBE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-subscribe');
16
17
  const BLOCKING_STATE_SYMBOL = Symbol.for('@modern-js/plugin-tanstack:blocking-state');
@@ -144,6 +145,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
144
145
  const rewrite = createModernBasepathRewrite(_basename);
145
146
  const serializationAdapters = getGlobalEnableRsc() ? getTanstackRscSerializationAdapters() : void 0;
146
147
  cachedRouter = createRouter({
148
+ ...getModernTanstackRouterFastDefaults(mergedConfig),
147
149
  routeTree,
148
150
  basepath: '/',
149
151
  rewrite,