@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.12 → 3.2.0-ultramodern.120
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/cli/index.js +47 -9
- package/dist/cjs/cli/routeSplitting.js +87 -0
- package/dist/cjs/cli/tanstackTypes.js +230 -63
- package/dist/cjs/cli.js +12 -8
- package/dist/cjs/runtime/DefaultNotFound.js +9 -5
- package/dist/cjs/runtime/basepathRewrite.js +12 -8
- package/dist/cjs/runtime/dataMutation.js +9 -5
- package/dist/cjs/runtime/hooks.js +9 -5
- package/dist/cjs/runtime/hydrationBoundary.js +48 -0
- package/dist/cjs/runtime/index.js +330 -74
- package/dist/cjs/runtime/lifecycle.js +15 -11
- package/dist/cjs/runtime/outlet.js +58 -0
- package/dist/cjs/runtime/plugin.js +203 -98
- package/dist/cjs/runtime/plugin.node.js +38 -16
- package/dist/cjs/runtime/plugin.worker.js +53 -0
- package/dist/cjs/runtime/prefetchLink.js +10 -6
- package/dist/cjs/runtime/routeTree.js +81 -17
- package/dist/cjs/runtime/rsc/ClientSlot.js +9 -5
- package/dist/cjs/runtime/rsc/CompositeComponent.js +9 -5
- package/dist/cjs/runtime/rsc/ReplayableStream.js +14 -9
- package/dist/cjs/runtime/rsc/RscNodeRenderer.js +9 -5
- package/dist/cjs/runtime/rsc/SlotContext.js +9 -5
- package/dist/cjs/runtime/rsc/client.js +9 -5
- package/dist/cjs/runtime/rsc/createRscProxy.js +9 -5
- package/dist/cjs/runtime/rsc/index.js +9 -5
- package/dist/cjs/runtime/rsc/payloadRouter.js +9 -5
- package/dist/cjs/runtime/rsc/server.js +9 -5
- package/dist/cjs/runtime/rsc/slotUsageSanitizer.js +9 -5
- package/dist/cjs/runtime/rsc/symbols.js +20 -15
- package/dist/cjs/runtime/types.js +31 -1
- package/dist/cjs/runtime/utils.js +9 -5
- package/dist/cjs/runtime.js +9 -5
- package/dist/esm/cli/index.mjs +28 -6
- package/dist/esm/cli/routeSplitting.mjs +43 -0
- package/dist/esm/cli/tanstackTypes.mjs +219 -59
- 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 -96
- package/dist/esm/runtime/plugin.node.mjs +30 -12
- package/dist/esm/runtime/plugin.worker.mjs +1 -0
- package/dist/esm/runtime/prefetchLink.mjs +1 -1
- package/dist/esm/runtime/routeTree.mjs +73 -13
- package/dist/esm/runtime/types.mjs +7 -0
- package/dist/esm-node/cli/index.mjs +28 -6
- package/dist/esm-node/cli/routeSplitting.mjs +44 -0
- package/dist/esm-node/cli/tanstackTypes.mjs +219 -59
- 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 -96
- 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/prefetchLink.mjs +1 -1
- 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 +7 -1
- package/dist/types/cli/routeSplitting.d.ts +29 -0
- package/dist/types/cli/tanstackTypes.d.ts +9 -0
- package/dist/types/runtime/hooks.d.ts +9 -24
- 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 +20 -20
- package/src/cli/index.ts +59 -2
- package/src/cli/routeSplitting.ts +81 -0
- package/src/cli/tanstackTypes.ts +347 -67
- package/src/runtime/hydrationBoundary.tsx +12 -0
- package/src/runtime/index.tsx +107 -2
- package/src/runtime/outlet.tsx +48 -0
- package/src/runtime/plugin.node.tsx +58 -8
- package/src/runtime/plugin.tsx +372 -157
- package/src/runtime/plugin.worker.tsx +4 -0
- package/src/runtime/prefetchLink.tsx +1 -1
- 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 +315 -0
- package/tests/router/fastDefaults.test.ts +25 -0
- package/tests/router/hydrationBoundary.test.tsx +23 -0
- package/tests/router/prefetchLink.test.tsx +43 -7
- package/tests/router/routeTree.test.ts +416 -1
- package/tests/router/tanstackTypes.test.ts +415 -1
|
@@ -56,6 +56,14 @@ function pickModernLoaderModule(route) {
|
|
|
56
56
|
inline
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
+
function pickRouteSearchContractModules(route) {
|
|
60
|
+
const validateSearchPath = route.validateSearch;
|
|
61
|
+
const loaderDepsPath = route.loaderDeps;
|
|
62
|
+
return {
|
|
63
|
+
validateSearchPath: 'string' == typeof validateSearchPath ? validateSearchPath : null,
|
|
64
|
+
loaderDepsPath: 'string' == typeof loaderDepsPath ? loaderDepsPath : null
|
|
65
|
+
};
|
|
66
|
+
}
|
|
59
67
|
function isPathlessLayout(route) {
|
|
60
68
|
return 'nested' === route.type && 'boolean' != typeof route.index && void 0 === route.path;
|
|
61
69
|
}
|
|
@@ -70,6 +78,78 @@ function createRouteStaticDataSnippet(opts) {
|
|
|
70
78
|
if (!staticDataLines.length) return null;
|
|
71
79
|
return `staticData: createRouteStaticData({\n ${staticDataLines.join('\n ')}\n }),`;
|
|
72
80
|
}
|
|
81
|
+
const LOCALE_PARAM_SEGMENTS = new Set([
|
|
82
|
+
':lang',
|
|
83
|
+
':locale',
|
|
84
|
+
':language',
|
|
85
|
+
'$lang',
|
|
86
|
+
'$locale',
|
|
87
|
+
'$language'
|
|
88
|
+
]);
|
|
89
|
+
function paramsTypeForCanonicalPath(canonicalPath) {
|
|
90
|
+
const fields = [];
|
|
91
|
+
for (const segment of canonicalPath.split('/'))if (segment) {
|
|
92
|
+
if ('*' === segment || '$' === segment) {
|
|
93
|
+
fields.push("'_splat'?: string");
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (segment.startsWith('{-$') && segment.endsWith('}')) {
|
|
97
|
+
fields.push(`${JSON.stringify(segment.slice(3, -1))}?: string`);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (segment.startsWith('$')) {
|
|
101
|
+
fields.push(`${JSON.stringify(segment.slice(1))}: string`);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (segment.startsWith(':')) {
|
|
105
|
+
const optional = segment.endsWith('?');
|
|
106
|
+
const name = segment.slice(1, optional ? void 0 : segment.length);
|
|
107
|
+
fields.push(`${JSON.stringify(optional ? name.slice(0, -1) : name)}${optional ? '?' : ''}: string`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return fields.length > 0 ? `{ ${fields.join('; ')} }` : 'Record<string, never>';
|
|
111
|
+
}
|
|
112
|
+
function collectCanonicalRoutesForEntry(routes) {
|
|
113
|
+
const canonicalParams = new Map();
|
|
114
|
+
let hasI18nSurface = false;
|
|
115
|
+
const normalizeJoined = (joined)=>{
|
|
116
|
+
const collapsed = joined.replace(/\/+/g, '/');
|
|
117
|
+
const withLeading = collapsed.startsWith('/') ? collapsed : `/${collapsed}`;
|
|
118
|
+
return withLeading.length > 1 ? withLeading.replace(/\/+$/, '') : withLeading;
|
|
119
|
+
};
|
|
120
|
+
const record = (canonicalPath)=>{
|
|
121
|
+
const normalized = normalizeJoined(canonicalPath || '/');
|
|
122
|
+
const key = toTanstackPath(normalized);
|
|
123
|
+
if (!canonicalParams.has(key)) canonicalParams.set(key, paramsTypeForCanonicalPath(normalized));
|
|
124
|
+
};
|
|
125
|
+
const visit = (route, parentPath)=>{
|
|
126
|
+
let currentPath = parentPath;
|
|
127
|
+
if ('string' == typeof route.modernCanonicalPath) {
|
|
128
|
+
hasI18nSurface = true;
|
|
129
|
+
currentPath = normalizeJoined(route.modernCanonicalPath);
|
|
130
|
+
} else if ('string' == typeof route.path && route.path.length > 0) {
|
|
131
|
+
const segments = route.path.replace(/\[(.+?)\]/g, ':$1').split('/').filter(Boolean);
|
|
132
|
+
if ('' === parentPath && LOCALE_PARAM_SEGMENTS.has(segments[0])) {
|
|
133
|
+
hasI18nSurface = true;
|
|
134
|
+
segments.shift();
|
|
135
|
+
}
|
|
136
|
+
currentPath = segments.length ? normalizeJoined(`${parentPath}/${segments.join('/')}`) : parentPath;
|
|
137
|
+
}
|
|
138
|
+
const children = route.children;
|
|
139
|
+
if (children && children.length > 0) {
|
|
140
|
+
for (const child of children)visit(child, currentPath);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
record(currentPath || '/');
|
|
144
|
+
};
|
|
145
|
+
const rootModern = routes.find((route)=>route.isRoot);
|
|
146
|
+
const topLevel = rootModern ? rootModern.children ?? [] : routes;
|
|
147
|
+
for (const route of topLevel)visit(route, '');
|
|
148
|
+
if (!hasI18nSurface || 0 === canonicalParams.size) return null;
|
|
149
|
+
return Object.fromEntries([
|
|
150
|
+
...canonicalParams.entries()
|
|
151
|
+
].sort(([a], [b])=>a.localeCompare(b)));
|
|
152
|
+
}
|
|
73
153
|
async function isTanstackRouterFrameworkEnabled(appContext) {
|
|
74
154
|
const runtimeConfigBase = path.join(appContext.srcDirectory, appContext.runtimeConfigFile);
|
|
75
155
|
const runtimeConfigFile = findExists(JS_OR_TS_EXTS.map((ext)=>`${runtimeConfigBase}${ext}`));
|
|
@@ -89,8 +169,21 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
89
169
|
const imports = [];
|
|
90
170
|
const statements = [];
|
|
91
171
|
const loaderImportMap = new Map();
|
|
172
|
+
const searchContractImportMap = new Map();
|
|
173
|
+
const usedRouteVarNames = new Set();
|
|
92
174
|
let loaderIndex = 0;
|
|
175
|
+
let validateSearchIndex = 0;
|
|
176
|
+
let loaderDepsIndex = 0;
|
|
93
177
|
let routeIndex = 0;
|
|
178
|
+
const resolveRouteModuleNoExt = async (aliasedNoExtPath)=>{
|
|
179
|
+
const prefix = `${appContext.internalSrcAlias}/`;
|
|
180
|
+
let absNoExt;
|
|
181
|
+
if (aliasedNoExtPath.startsWith(prefix)) {
|
|
182
|
+
const rel = aliasedNoExtPath.slice(prefix.length);
|
|
183
|
+
absNoExt = path.join(appContext.srcDirectory, rel);
|
|
184
|
+
} else absNoExt = path.isAbsolute(aliasedNoExtPath) ? aliasedNoExtPath : path.join(appContext.srcDirectory, aliasedNoExtPath);
|
|
185
|
+
return resolveFileNoExt(absNoExt);
|
|
186
|
+
};
|
|
94
187
|
const getImportNamesForLoader = async (aliasedNoExtPath, inline, hasAction)=>{
|
|
95
188
|
const key = `${inline ? 'inline' : 'default'}:${hasAction ? 'action' : 'loader'}:${aliasedNoExtPath}`;
|
|
96
189
|
const existing = loaderImportMap.get(key);
|
|
@@ -98,13 +191,7 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
98
191
|
loaderName: existing,
|
|
99
192
|
actionName: hasAction ? existing.replace(/^loader_/, 'action_') : null
|
|
100
193
|
};
|
|
101
|
-
const
|
|
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);
|
|
194
|
+
const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
|
|
108
195
|
if (!resolvedNoExt) return null;
|
|
109
196
|
const relImport = normalizeRelativeImport(path.relative(outDir, resolvedNoExt));
|
|
110
197
|
const importName = `loader_${loaderIndex++}`;
|
|
@@ -122,10 +209,29 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
122
209
|
actionName
|
|
123
210
|
};
|
|
124
211
|
};
|
|
212
|
+
const getImportNameForSearchContract = async (aliasedNoExtPath, exportName)=>{
|
|
213
|
+
const key = `${exportName}:${aliasedNoExtPath}`;
|
|
214
|
+
const existing = searchContractImportMap.get(key);
|
|
215
|
+
if (existing) return existing;
|
|
216
|
+
const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
|
|
217
|
+
if (!resolvedNoExt) return null;
|
|
218
|
+
const relImport = normalizeRelativeImport(path.relative(outDir, resolvedNoExt));
|
|
219
|
+
const importName = 'validateSearch' === exportName ? `validateSearch_${validateSearchIndex++}` : `loaderDeps_${loaderDepsIndex++}`;
|
|
220
|
+
imports.push(`import { ${exportName} as ${importName} } from ${quote(relImport)};`);
|
|
221
|
+
searchContractImportMap.set(key, importName);
|
|
222
|
+
return importName;
|
|
223
|
+
};
|
|
224
|
+
const reserveRouteVarName = (preferred)=>{
|
|
225
|
+
let candidate = preferred;
|
|
226
|
+
let suffix = 1;
|
|
227
|
+
while(usedRouteVarNames.has(candidate))candidate = `${preferred}_${suffix++}`;
|
|
228
|
+
usedRouteVarNames.add(candidate);
|
|
229
|
+
return candidate;
|
|
230
|
+
};
|
|
125
231
|
const createRouteVarName = (route)=>{
|
|
126
232
|
const id = route.id;
|
|
127
233
|
const base = id ? makeLegalIdentifier(id) : `r_${routeIndex++}`;
|
|
128
|
-
return `route_${base}
|
|
234
|
+
return reserveRouteVarName(`route_${base}`);
|
|
129
235
|
};
|
|
130
236
|
const buildRoute = async (opts)=>{
|
|
131
237
|
const { parentVar, route } = opts;
|
|
@@ -135,6 +241,9 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
135
241
|
const loaderImports = loaderInfo ? await getImportNamesForLoader(loaderInfo.loaderPath, loaderInfo.inline, Boolean(loaderInfo.inline && routeAction === loaderInfo.loaderPath)) : null;
|
|
136
242
|
const loaderName = loaderImports?.loaderName || null;
|
|
137
243
|
const actionName = loaderImports?.actionName || null;
|
|
244
|
+
const searchContractInfo = pickRouteSearchContractModules(route);
|
|
245
|
+
const validateSearchName = searchContractInfo.validateSearchPath ? await getImportNameForSearchContract(searchContractInfo.validateSearchPath, 'validateSearch') : null;
|
|
246
|
+
const loaderDepsName = searchContractInfo.loaderDepsPath ? await getImportNameForSearchContract(searchContractInfo.loaderDepsPath, 'loaderDeps') : null;
|
|
138
247
|
const rawPath = route.path;
|
|
139
248
|
const hasSplat = 'string' == typeof rawPath && rawPath.includes('*');
|
|
140
249
|
const routeOpts = [
|
|
@@ -148,20 +257,24 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
148
257
|
routeOpts.push(`path: ${quote(p)},`);
|
|
149
258
|
}
|
|
150
259
|
if (loaderName) routeOpts.push(`loader: modernLoaderToTanstack({ hasSplat: ${hasSplat} }, ${loaderName}),`);
|
|
260
|
+
if (validateSearchName) routeOpts.push(`validateSearch: ${validateSearchName},`);
|
|
261
|
+
if (loaderDepsName) routeOpts.push(`loaderDeps: ${loaderDepsName},`);
|
|
151
262
|
const staticDataSnippet = createRouteStaticDataSnippet({
|
|
152
263
|
modernRouteId: route.id,
|
|
153
264
|
loaderName,
|
|
154
265
|
actionName
|
|
155
266
|
});
|
|
156
267
|
if (staticDataSnippet) routeOpts.push(staticDataSnippet);
|
|
157
|
-
statements.push(`const ${varName} = createRoute({\n ${routeOpts.join('\n ')}\n});`);
|
|
158
268
|
const children = route.children;
|
|
269
|
+
const hasChildren = Boolean(children && children.length > 0);
|
|
270
|
+
const routeCtorVarName = hasChildren ? reserveRouteVarName(`${varName}__base`) : varName;
|
|
271
|
+
statements.push(`const ${routeCtorVarName} = createRoute({\n ${routeOpts.join('\n ')}\n});`);
|
|
159
272
|
if (children && children.length > 0) {
|
|
160
273
|
const childVars = await Promise.all(children.map((child)=>buildRoute({
|
|
161
|
-
parentVar:
|
|
274
|
+
parentVar: routeCtorVarName,
|
|
162
275
|
route: child
|
|
163
276
|
})));
|
|
164
|
-
statements.push(
|
|
277
|
+
statements.push(`const ${varName} = ${routeCtorVarName}.addChildren([${childVars.join(', ')}]);`);
|
|
165
278
|
}
|
|
166
279
|
return varName;
|
|
167
280
|
};
|
|
@@ -170,17 +283,23 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
170
283
|
const rootLoaderImports = rootLoaderInfo?.loaderPath ? await getImportNamesForLoader(rootLoaderInfo.loaderPath, rootLoaderInfo.inline, Boolean(rootLoaderInfo.inline && rootAction === rootLoaderInfo.loaderPath)) : null;
|
|
171
284
|
const rootLoaderName = rootLoaderImports?.loaderName || null;
|
|
172
285
|
const rootActionName = rootLoaderImports?.actionName || null;
|
|
286
|
+
const rootSearchContractInfo = rootModern ? pickRouteSearchContractModules(rootModern) : null;
|
|
287
|
+
const rootValidateSearchName = rootSearchContractInfo?.validateSearchPath ? await getImportNameForSearchContract(rootSearchContractInfo.validateSearchPath, 'validateSearch') : null;
|
|
288
|
+
const rootLoaderDepsName = rootSearchContractInfo?.loaderDepsPath ? await getImportNameForSearchContract(rootSearchContractInfo.loaderDepsPath, 'loaderDeps') : null;
|
|
173
289
|
const topLevelVars = await Promise.all(topLevel.map((route)=>buildRoute({
|
|
174
290
|
parentVar: 'rootRoute',
|
|
175
291
|
route
|
|
176
292
|
})));
|
|
177
293
|
const rootOpts = [];
|
|
178
294
|
if (rootLoaderName) rootOpts.push(`loader: modernLoaderToTanstack({ hasSplat: false }, ${rootLoaderName}),`);
|
|
295
|
+
if (rootValidateSearchName) rootOpts.push(`validateSearch: ${rootValidateSearchName},`);
|
|
296
|
+
if (rootLoaderDepsName) rootOpts.push(`loaderDeps: ${rootLoaderDepsName},`);
|
|
179
297
|
const routerGenTs = `/* eslint-disable */
|
|
180
298
|
// This file is auto-generated by Modern.js. Do not edit manually.
|
|
181
299
|
|
|
182
300
|
import {
|
|
183
301
|
createMemoryHistory,
|
|
302
|
+
modernTanstackRouterFastDefaults,
|
|
184
303
|
createRootRouteWithContext,
|
|
185
304
|
createRoute,
|
|
186
305
|
createRouter,
|
|
@@ -208,7 +327,7 @@ function isRedirectResponse(res: Response) {
|
|
|
208
327
|
}
|
|
209
328
|
|
|
210
329
|
function throwTanstackRedirect(location: string) {
|
|
211
|
-
const target = location
|
|
330
|
+
const target = location.length > 0 ? location : '/';
|
|
212
331
|
try {
|
|
213
332
|
void new URL(target);
|
|
214
333
|
throw redirect({ href: target });
|
|
@@ -234,21 +353,87 @@ function createRouteStaticData(opts: {
|
|
|
234
353
|
modernRouteAction?: unknown;
|
|
235
354
|
modernRouteLoader?: unknown;
|
|
236
355
|
}) {
|
|
237
|
-
const staticData:
|
|
356
|
+
const staticData: {
|
|
357
|
+
modernRouteId?: string;
|
|
358
|
+
modernRouteAction?: unknown;
|
|
359
|
+
modernRouteLoader?: unknown;
|
|
360
|
+
} = {};
|
|
238
361
|
|
|
239
|
-
if (opts.modernRouteId) {
|
|
362
|
+
if (typeof opts.modernRouteId === 'string' && opts.modernRouteId.length > 0) {
|
|
240
363
|
staticData.modernRouteId = opts.modernRouteId;
|
|
241
364
|
}
|
|
242
365
|
|
|
243
|
-
if (opts.modernRouteLoader) {
|
|
366
|
+
if (typeof opts.modernRouteLoader !== 'undefined') {
|
|
244
367
|
staticData.modernRouteLoader = opts.modernRouteLoader;
|
|
245
368
|
}
|
|
246
369
|
|
|
247
|
-
if (opts.modernRouteAction) {
|
|
370
|
+
if (typeof opts.modernRouteAction !== 'undefined') {
|
|
248
371
|
staticData.modernRouteAction = opts.modernRouteAction;
|
|
249
372
|
}
|
|
250
373
|
|
|
251
|
-
return
|
|
374
|
+
return staticData;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function getLoaderSignal(ctx: any): AbortSignal {
|
|
378
|
+
const abortSignal = ctx?.abortController?.signal;
|
|
379
|
+
if (abortSignal instanceof AbortSignal) {
|
|
380
|
+
return abortSignal;
|
|
381
|
+
}
|
|
382
|
+
if (ctx?.signal instanceof AbortSignal) {
|
|
383
|
+
return ctx.signal;
|
|
384
|
+
}
|
|
385
|
+
return new AbortController().signal;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function getLoaderHref(ctx: any): string {
|
|
389
|
+
if (typeof ctx?.location === 'string') {
|
|
390
|
+
return ctx.location;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const publicHref = ctx?.location?.publicHref;
|
|
394
|
+
if (typeof publicHref === 'string') {
|
|
395
|
+
return publicHref;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const href = ctx?.location?.href;
|
|
399
|
+
if (typeof href === 'string') {
|
|
400
|
+
return href;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
const urlHref = ctx?.location?.url?.href;
|
|
404
|
+
return typeof urlHref === 'string' ? urlHref : '';
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function getLoaderParams(ctx: any): Record<string, string> {
|
|
408
|
+
return typeof ctx?.params === 'object' && ctx.params !== null ? ctx.params : {};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function handleModernLoaderResult<LoaderResult>(result: LoaderResult): LoaderResult {
|
|
412
|
+
if (isResponse(result)) {
|
|
413
|
+
if (isRedirectResponse(result)) {
|
|
414
|
+
const location = result.headers.get('Location') ?? '/';
|
|
415
|
+
throwTanstackRedirect(location);
|
|
416
|
+
}
|
|
417
|
+
if (result.status === 404) {
|
|
418
|
+
throw notFound();
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return result;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function handleModernLoaderError(err: unknown): never {
|
|
426
|
+
if (isResponse(err)) {
|
|
427
|
+
if (isRedirectResponse(err)) {
|
|
428
|
+
const location = err.headers.get('Location') ?? '/';
|
|
429
|
+
throwTanstackRedirect(location);
|
|
430
|
+
}
|
|
431
|
+
if (err.status === 404) {
|
|
432
|
+
throw notFound();
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
throw err;
|
|
252
437
|
}
|
|
253
438
|
|
|
254
439
|
function modernLoaderToTanstack<TLoader extends (args: any) => any>(
|
|
@@ -257,57 +442,31 @@ function modernLoaderToTanstack<TLoader extends (args: any) => any>(
|
|
|
257
442
|
) {
|
|
258
443
|
type LoaderResult = Awaited<ReturnType<TLoader>>;
|
|
259
444
|
|
|
260
|
-
return
|
|
445
|
+
return (ctx: any): Promise<LoaderResult> => {
|
|
261
446
|
try {
|
|
262
|
-
const signal
|
|
263
|
-
ctx?.abortController?.signal ||
|
|
264
|
-
ctx?.signal ||
|
|
265
|
-
new AbortController().signal;
|
|
447
|
+
const signal = getLoaderSignal(ctx);
|
|
266
448
|
const baseRequest: Request | undefined =
|
|
267
449
|
ctx?.context?.request instanceof Request ? ctx.context.request : undefined;
|
|
268
450
|
|
|
269
|
-
const href =
|
|
270
|
-
typeof ctx?.location === 'string'
|
|
271
|
-
? ctx.location
|
|
272
|
-
: ctx?.location?.publicHref ||
|
|
273
|
-
ctx?.location?.href ||
|
|
274
|
-
ctx?.location?.url?.href ||
|
|
275
|
-
'';
|
|
451
|
+
const href = getLoaderHref(ctx);
|
|
276
452
|
|
|
277
|
-
const request = baseRequest
|
|
453
|
+
const request = baseRequest !== undefined
|
|
278
454
|
? new Request(baseRequest, { signal })
|
|
279
455
|
: new Request(href, { signal });
|
|
280
456
|
|
|
281
|
-
const params = mapParamsForModernLoader(ctx
|
|
282
|
-
|
|
283
|
-
const result = await (modernLoader as any)({
|
|
284
|
-
request,
|
|
285
|
-
params,
|
|
286
|
-
context: ctx?.context?.requestContext,
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
if (isResponse(result)) {
|
|
290
|
-
if (isRedirectResponse(result)) {
|
|
291
|
-
const location = result.headers.get('Location') || '/';
|
|
292
|
-
throwTanstackRedirect(location);
|
|
293
|
-
}
|
|
294
|
-
if (result.status === 404) {
|
|
295
|
-
throw notFound();
|
|
296
|
-
}
|
|
297
|
-
}
|
|
457
|
+
const params = mapParamsForModernLoader(getLoaderParams(ctx), opts.hasSplat);
|
|
298
458
|
|
|
299
|
-
return
|
|
459
|
+
return Promise.resolve(
|
|
460
|
+
(modernLoader as any)({
|
|
461
|
+
request,
|
|
462
|
+
params,
|
|
463
|
+
context: ctx?.context?.requestContext,
|
|
464
|
+
}),
|
|
465
|
+
)
|
|
466
|
+
.then((result: LoaderResult) => handleModernLoaderResult(result))
|
|
467
|
+
.catch(handleModernLoaderError);
|
|
300
468
|
} catch (err) {
|
|
301
|
-
|
|
302
|
-
if (isRedirectResponse(err)) {
|
|
303
|
-
const location = err.headers.get('Location') || '/';
|
|
304
|
-
throwTanstackRedirect(location);
|
|
305
|
-
}
|
|
306
|
-
if (err.status === 404) {
|
|
307
|
-
throw notFound();
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
throw err;
|
|
469
|
+
handleModernLoaderError(err);
|
|
311
470
|
}
|
|
312
471
|
};
|
|
313
472
|
}
|
|
@@ -328,6 +487,7 @@ ${statements.join('\n\n')}
|
|
|
328
487
|
export const routeTree = rootRoute.addChildren([${topLevelVars.join(', ')}]);
|
|
329
488
|
|
|
330
489
|
export const router = createRouter({
|
|
490
|
+
...modernTanstackRouterFastDefaults,
|
|
331
491
|
routeTree,
|
|
332
492
|
history: createMemoryHistory({
|
|
333
493
|
initialEntries: ['/'],
|
|
@@ -339,4 +499,4 @@ export const router = createRouter({
|
|
|
339
499
|
routerGenTs
|
|
340
500
|
};
|
|
341
501
|
}
|
|
342
|
-
export { generateTanstackRouterTypesSourceForEntry, isTanstackRouterFrameworkEnabled };
|
|
502
|
+
export { collectCanonicalRoutesForEntry, generateTanstackRouterTypesSourceForEntry, isTanstackRouterFrameworkEnabled };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Suspense } from "react";
|
|
4
|
+
function wrapTanstackSsrHydrationBoundary(routerContent, shouldWrap) {
|
|
5
|
+
if (shouldWrap) return /*#__PURE__*/ jsx(Suspense, {
|
|
6
|
+
fallback: null,
|
|
7
|
+
children: routerContent
|
|
8
|
+
});
|
|
9
|
+
return routerContent;
|
|
10
|
+
}
|
|
11
|
+
export { wrapTanstackSsrHydrationBoundary };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
export
|
|
3
|
-
export { useMatch } from "@tanstack/react-router";
|
|
2
|
+
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";
|
|
4
3
|
export { Form, RouteActionResponseError, useFetcher } from "./dataMutation.mjs";
|
|
4
|
+
export { Outlet } from "./outlet.mjs";
|
|
5
5
|
export { tanstackRouterPlugin as default, tanstackRouterPlugin } from "./plugin.mjs";
|
|
6
6
|
export { Link, NavLink } from "./prefetchLink.mjs";
|
|
7
7
|
export { CompositeComponent } from "./rsc/client.mjs";
|
|
8
|
+
export { getModernTanstackRouterFastDefaults, modernTanstackRouterFastDefaults } from "./types.mjs";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Outlet } from "@tanstack/react-router";
|
|
4
|
+
import { createElement, memo } from "react";
|
|
5
|
+
const outlet_Outlet = /*#__PURE__*/ memo(function() {
|
|
6
|
+
return /*#__PURE__*/ jsx(Outlet, {});
|
|
7
|
+
});
|
|
8
|
+
function withModernRouteMatchContext(component, _routeId) {
|
|
9
|
+
if (null == component) return component;
|
|
10
|
+
const Component = component;
|
|
11
|
+
const WrappedRouteComponent = (props)=>/*#__PURE__*/ createElement(Component, props);
|
|
12
|
+
const preloadable = component;
|
|
13
|
+
if ('function' == typeof preloadable.load) WrappedRouteComponent.load = preloadable.load.bind(preloadable);
|
|
14
|
+
if ('function' == typeof preloadable.preload) WrappedRouteComponent.preload = preloadable.preload.bind(preloadable);
|
|
15
|
+
else if ('function' == typeof preloadable.load) WrappedRouteComponent.preload = WrappedRouteComponent.load;
|
|
16
|
+
return WrappedRouteComponent;
|
|
17
|
+
}
|
|
18
|
+
export { outlet_Outlet as Outlet, withModernRouteMatchContext };
|