@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.11 → 3.2.0-ultramodern.111

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 (86) hide show
  1. package/dist/cjs/cli/index.js +21 -5
  2. package/dist/cjs/cli/routeSplitting.js +87 -0
  3. package/dist/cjs/cli/tanstackTypes.js +155 -63
  4. package/dist/cjs/cli.js +12 -8
  5. package/dist/cjs/runtime/DefaultNotFound.js +9 -5
  6. package/dist/cjs/runtime/basepathRewrite.js +12 -8
  7. package/dist/cjs/runtime/dataMutation.js +9 -5
  8. package/dist/cjs/runtime/hooks.js +9 -5
  9. package/dist/cjs/runtime/hydrationBoundary.js +48 -0
  10. package/dist/cjs/runtime/index.js +330 -74
  11. package/dist/cjs/runtime/lifecycle.js +15 -11
  12. package/dist/cjs/runtime/outlet.js +58 -0
  13. package/dist/cjs/runtime/plugin.js +203 -98
  14. package/dist/cjs/runtime/plugin.node.js +38 -16
  15. package/dist/cjs/runtime/plugin.worker.js +53 -0
  16. package/dist/cjs/runtime/prefetchLink.js +10 -6
  17. package/dist/cjs/runtime/routeTree.js +81 -17
  18. package/dist/cjs/runtime/rsc/ClientSlot.js +9 -5
  19. package/dist/cjs/runtime/rsc/CompositeComponent.js +9 -5
  20. package/dist/cjs/runtime/rsc/ReplayableStream.js +14 -9
  21. package/dist/cjs/runtime/rsc/RscNodeRenderer.js +9 -5
  22. package/dist/cjs/runtime/rsc/SlotContext.js +9 -5
  23. package/dist/cjs/runtime/rsc/client.js +9 -5
  24. package/dist/cjs/runtime/rsc/createRscProxy.js +9 -5
  25. package/dist/cjs/runtime/rsc/index.js +9 -5
  26. package/dist/cjs/runtime/rsc/payloadRouter.js +9 -5
  27. package/dist/cjs/runtime/rsc/server.js +9 -5
  28. package/dist/cjs/runtime/rsc/slotUsageSanitizer.js +9 -5
  29. package/dist/cjs/runtime/rsc/symbols.js +20 -15
  30. package/dist/cjs/runtime/types.js +31 -1
  31. package/dist/cjs/runtime/utils.js +9 -5
  32. package/dist/cjs/runtime.js +9 -5
  33. package/dist/esm/cli/index.mjs +4 -1
  34. package/dist/esm/cli/routeSplitting.mjs +43 -0
  35. package/dist/esm/cli/tanstackTypes.mjs +146 -58
  36. package/dist/esm/runtime/hydrationBoundary.mjs +10 -0
  37. package/dist/esm/runtime/index.mjs +3 -2
  38. package/dist/esm/runtime/outlet.mjs +17 -0
  39. package/dist/esm/runtime/plugin.mjs +197 -96
  40. package/dist/esm/runtime/plugin.node.mjs +30 -12
  41. package/dist/esm/runtime/plugin.worker.mjs +1 -0
  42. package/dist/esm/runtime/prefetchLink.mjs +1 -1
  43. package/dist/esm/runtime/routeTree.mjs +73 -13
  44. package/dist/esm/runtime/types.mjs +7 -0
  45. package/dist/esm-node/cli/index.mjs +4 -1
  46. package/dist/esm-node/cli/routeSplitting.mjs +44 -0
  47. package/dist/esm-node/cli/tanstackTypes.mjs +146 -58
  48. package/dist/esm-node/runtime/hydrationBoundary.mjs +11 -0
  49. package/dist/esm-node/runtime/index.mjs +3 -2
  50. package/dist/esm-node/runtime/outlet.mjs +18 -0
  51. package/dist/esm-node/runtime/plugin.mjs +197 -96
  52. package/dist/esm-node/runtime/plugin.node.mjs +30 -12
  53. package/dist/esm-node/runtime/plugin.worker.mjs +2 -0
  54. package/dist/esm-node/runtime/prefetchLink.mjs +1 -1
  55. package/dist/esm-node/runtime/routeTree.mjs +73 -13
  56. package/dist/esm-node/runtime/types.mjs +7 -0
  57. package/dist/types/cli/index.d.ts +4 -0
  58. package/dist/types/cli/routeSplitting.d.ts +29 -0
  59. package/dist/types/runtime/hooks.d.ts +9 -24
  60. package/dist/types/runtime/hydrationBoundary.d.ts +2 -0
  61. package/dist/types/runtime/index.d.ts +5 -2
  62. package/dist/types/runtime/outlet.d.ts +2 -0
  63. package/dist/types/runtime/plugin.d.ts +1 -1
  64. package/dist/types/runtime/plugin.node.d.ts +1 -1
  65. package/dist/types/runtime/plugin.worker.d.ts +1 -0
  66. package/dist/types/runtime/types.d.ts +7 -0
  67. package/package.json +19 -19
  68. package/src/cli/index.ts +17 -0
  69. package/src/cli/routeSplitting.ts +81 -0
  70. package/src/cli/tanstackTypes.ts +216 -67
  71. package/src/runtime/hydrationBoundary.tsx +12 -0
  72. package/src/runtime/index.tsx +107 -2
  73. package/src/runtime/outlet.tsx +48 -0
  74. package/src/runtime/plugin.node.tsx +58 -8
  75. package/src/runtime/plugin.tsx +372 -157
  76. package/src/runtime/plugin.worker.tsx +4 -0
  77. package/src/runtime/prefetchLink.tsx +1 -1
  78. package/src/runtime/routeTree.ts +194 -23
  79. package/src/runtime/ssr-shim.d.ts +1 -3
  80. package/src/runtime/types.ts +13 -0
  81. package/tests/router/cli.test.ts +239 -0
  82. package/tests/router/fastDefaults.test.ts +25 -0
  83. package/tests/router/hydrationBoundary.test.tsx +23 -0
  84. package/tests/router/prefetchLink.test.tsx +43 -7
  85. package/tests/router/routeTree.test.ts +416 -1
  86. package/tests/router/tanstackTypes.test.ts +184 -0
@@ -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 prefix = `${appContext.internalSrcAlias}/`;
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: varName,
201
+ parentVar: routeCtorVarName,
161
202
  route: child
162
203
  })));
163
- statements.push(`${varName}.addChildren([${childVars.join(', ')}]);`);
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: Record<string, unknown> = {};
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 Object.keys(staticData).length > 0 ? staticData : undefined;
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 async (ctx: any): Promise<LoaderResult> => {
372
+ return (ctx: any): Promise<LoaderResult> => {
260
373
  try {
261
- const signal: AbortSignal =
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?.params || {}, opts.hasSplat);
384
+ const params = mapParamsForModernLoader(getLoaderParams(ctx), opts.hasSplat);
281
385
 
282
- const result = await (modernLoader as any)({
283
- request,
284
- params,
285
- context: ctx?.context?.requestContext,
286
- });
287
-
288
- if (isResponse(result)) {
289
- if (isRedirectResponse(result)) {
290
- const location = result.headers.get('Location') || '/';
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
- if (isResponse(err)) {
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 };
@@ -1,6 +1,7 @@
1
- export * from "@tanstack/react-router";
2
- export { useMatch } from "@tanstack/react-router";
1
+ export { Asset, Await, Block, CatchBoundary, CatchNotFound, ClientOnly, DEFAULT_PROTOCOL_ALLOWLIST, DefaultGlobalNotFound, ErrorComponent, FileRoute, FileRouteLoader, HeadContent, LazyRoute, Match, MatchRoute, Matches, Navigate, NotFoundRoute, RootRoute, Route, RouteApi, Router, RouterContextProvider, RouterProvider, ScriptOnce, Scripts, ScrollRestoration, SearchParamError, cleanPath, composeRewrites, createBrowserHistory, createControlledPromise, createFileRoute, createHashHistory, createHistory, createLazyFileRoute, createLazyRoute, createLink, createMemoryHistory, createRootRoute, createRootRouteWithContext, createRoute, createRouteMask, createRouter, createRouterConfig, createSerializationAdapter, deepEqual, defaultParseSearch, defaultStringifySearch, defer, functionalUpdate, getRouteApi, interpolatePath, isMatch, isNotFound, isPlainArray, isPlainObject, isRedirect, joinPaths, lazyFn, lazyRouteComponent, linkOptions, notFound, parseSearchWith, reactUse, redirect, replaceEqualDeep, resolvePath, retainSearchParams, rootRouteId, rootRouteWithContext, stringifySearchWith, stripSearchParams, trimPath, trimPathLeft, trimPathRight, useAwaited, useBlocker, useCanGoBack, useChildMatches, useElementScrollRestoration, useHydrated, useLayoutEffect, useLinkProps, useLoaderData, useLoaderDeps, useLocation, useMatch, useMatchRoute, useMatches, useNavigate, useParams, useParentMatches, useRouteContext, useRouter, useRouterState, useSearch, useTags } from "@tanstack/react-router";
3
2
  export { Form, RouteActionResponseError, useFetcher } from "./dataMutation.mjs";
3
+ export { Outlet } from "./outlet.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";
@@ -0,0 +1,17 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Outlet } from "@tanstack/react-router";
3
+ import { createElement, memo } from "react";
4
+ const outlet_Outlet = /*#__PURE__*/ memo(function() {
5
+ return /*#__PURE__*/ jsx(Outlet, {});
6
+ });
7
+ function withModernRouteMatchContext(component, _routeId) {
8
+ if (null == component) return component;
9
+ const Component = component;
10
+ const WrappedRouteComponent = (props)=>/*#__PURE__*/ createElement(Component, props);
11
+ const preloadable = component;
12
+ if ('function' == typeof preloadable.load) WrappedRouteComponent.load = preloadable.load.bind(preloadable);
13
+ if ('function' == typeof preloadable.preload) WrappedRouteComponent.preload = preloadable.preload.bind(preloadable);
14
+ else if ('function' == typeof preloadable.load) WrappedRouteComponent.preload = WrappedRouteComponent.load;
15
+ return WrappedRouteComponent;
16
+ }
17
+ export { outlet_Outlet as Outlet, withModernRouteMatchContext };