@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.99 → 3.4.0-ultramodern.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/cli/index.js +80 -34
- package/dist/cjs/cli/routeSplitting.js +13 -41
- package/dist/cjs/cli/tanstackTypes.js +114 -200
- package/dist/cjs/cli.js +12 -8
- package/dist/cjs/runtime/basepathRewrite.js +12 -8
- package/dist/cjs/runtime/dataMutation.js +9 -5
- package/dist/cjs/runtime/hooks.js +20 -19
- package/dist/cjs/runtime/hydrationBoundary.js +12 -7
- package/dist/cjs/runtime/index.js +66 -54
- package/dist/cjs/runtime/lifecycle.js +21 -91
- package/dist/cjs/runtime/loaderBridge.js +173 -0
- package/dist/cjs/runtime/outlet.js +58 -0
- package/dist/cjs/runtime/plugin.js +190 -110
- package/dist/cjs/runtime/plugin.node.js +25 -40
- package/dist/cjs/runtime/plugin.worker.js +9 -5
- package/dist/cjs/runtime/pluginCore.js +55 -0
- package/dist/cjs/runtime/prefetchLink.js +10 -6
- package/dist/cjs/runtime/register.js +56 -0
- package/dist/cjs/runtime/routeTree.js +30 -212
- package/dist/cjs/runtime/router.js +41 -0
- package/dist/cjs/runtime/rsc/ClientSlot.js +9 -5
- package/dist/cjs/runtime/rsc/CompositeComponent.js +9 -5
- package/dist/cjs/runtime/rsc/ReplayableStream.js +14 -9
- package/dist/cjs/runtime/rsc/RscNodeRenderer.js +9 -5
- package/dist/cjs/runtime/rsc/SlotContext.js +9 -5
- package/dist/cjs/runtime/rsc/client.js +9 -5
- package/dist/cjs/runtime/rsc/createRscProxy.js +9 -5
- package/dist/cjs/runtime/rsc/index.js +9 -5
- package/dist/cjs/runtime/rsc/payloadRouter.js +44 -6
- package/dist/cjs/runtime/rsc/server.js +9 -5
- package/dist/cjs/runtime/rsc/slotUsageSanitizer.js +9 -5
- package/dist/cjs/runtime/rsc/symbols.js +20 -15
- package/dist/cjs/runtime/state.js +45 -0
- package/dist/cjs/runtime/types.js +13 -9
- package/dist/cjs/runtime/utils.js +9 -11
- package/dist/cjs/runtime.js +9 -5
- package/dist/esm/cli/index.mjs +73 -28
- package/dist/esm/cli/routeSplitting.mjs +1 -30
- package/dist/esm/cli/tanstackTypes.mjs +100 -190
- package/dist/esm/runtime/hooks.mjs +1 -8
- package/dist/esm/runtime/hydrationBoundary.mjs +3 -2
- package/dist/esm/runtime/index.mjs +4 -2
- package/dist/esm/runtime/lifecycle.mjs +1 -82
- package/dist/esm/runtime/loaderBridge.mjs +114 -0
- package/dist/esm/runtime/outlet.mjs +17 -0
- package/dist/esm/runtime/plugin.mjs +183 -107
- package/dist/esm/runtime/plugin.node.mjs +19 -38
- package/dist/esm/runtime/pluginCore.mjs +14 -0
- package/dist/esm/runtime/prefetchLink.mjs +1 -1
- package/dist/esm/runtime/register.mjs +18 -0
- package/dist/esm/runtime/routeTree.mjs +15 -198
- package/dist/esm/runtime/router.mjs +2 -0
- package/dist/esm/runtime/rsc/payloadRouter.mjs +35 -1
- package/dist/esm/runtime/state.mjs +7 -0
- package/dist/esm/runtime/utils.mjs +0 -6
- package/dist/esm-node/cli/index.mjs +73 -28
- package/dist/esm-node/cli/routeSplitting.mjs +1 -30
- package/dist/esm-node/cli/tanstackTypes.mjs +100 -190
- package/dist/esm-node/runtime/hooks.mjs +1 -8
- package/dist/esm-node/runtime/hydrationBoundary.mjs +3 -2
- package/dist/esm-node/runtime/index.mjs +4 -2
- package/dist/esm-node/runtime/lifecycle.mjs +1 -82
- package/dist/esm-node/runtime/loaderBridge.mjs +115 -0
- package/dist/esm-node/runtime/outlet.mjs +18 -0
- package/dist/esm-node/runtime/plugin.mjs +183 -107
- package/dist/esm-node/runtime/plugin.node.mjs +19 -38
- package/dist/esm-node/runtime/pluginCore.mjs +15 -0
- package/dist/esm-node/runtime/prefetchLink.mjs +1 -1
- package/dist/esm-node/runtime/register.mjs +19 -0
- package/dist/esm-node/runtime/routeTree.mjs +15 -198
- package/dist/esm-node/runtime/router.mjs +3 -0
- package/dist/esm-node/runtime/rsc/payloadRouter.mjs +35 -1
- package/dist/esm-node/runtime/state.mjs +8 -0
- package/dist/esm-node/runtime/utils.mjs +0 -6
- package/dist/types/cli/index.d.ts +11 -2
- package/dist/types/cli/routeSplitting.d.ts +6 -15
- package/dist/types/cli/tanstackTypes.d.ts +21 -1
- package/dist/types/runtime/hooks.d.ts +8 -33
- package/dist/types/runtime/index.d.ts +6 -3
- package/dist/types/runtime/lifecycle.d.ts +7 -22
- package/dist/types/runtime/loaderBridge.d.ts +48 -0
- package/dist/types/runtime/outlet.d.ts +2 -0
- package/dist/types/runtime/plugin.d.ts +1 -14
- package/dist/types/runtime/plugin.node.d.ts +1 -14
- package/dist/types/runtime/pluginCore.d.ts +21 -0
- package/dist/types/runtime/register.d.ts +9 -0
- package/dist/types/runtime/routeTree.d.ts +0 -2
- package/dist/types/runtime/router.d.ts +14 -0
- package/dist/types/runtime/state.d.ts +16 -0
- package/dist/types/runtime/types.d.ts +7 -53
- package/package.json +40 -38
- package/rstest.config.mts +6 -0
- package/src/cli/index.ts +146 -24
- package/src/cli/routeSplitting.ts +6 -44
- package/src/cli/tanstackTypes.ts +203 -208
- package/src/runtime/hooks.ts +10 -27
- package/src/runtime/hydrationBoundary.tsx +5 -5
- package/src/runtime/index.tsx +12 -14
- package/src/runtime/lifecycle.ts +16 -151
- package/src/runtime/loaderBridge.ts +257 -0
- package/src/runtime/outlet.tsx +48 -0
- package/src/runtime/plugin.node.tsx +28 -83
- package/src/runtime/plugin.tsx +350 -202
- package/src/runtime/pluginCore.ts +48 -0
- package/src/runtime/prefetchLink.tsx +1 -1
- package/src/runtime/register.ts +58 -0
- package/src/runtime/routeTree.ts +41 -365
- package/src/runtime/router.ts +15 -0
- package/src/runtime/rsc/payloadRouter.ts +45 -2
- package/src/runtime/ssr-shim.d.ts +1 -3
- package/src/runtime/state.ts +29 -0
- package/src/runtime/types.ts +20 -67
- package/src/runtime/utils.tsx +3 -7
- package/tests/router/cli.test.ts +373 -31
- package/tests/router/hooks.test.ts +26 -0
- package/tests/router/loaderBridge.test.ts +211 -0
- package/tests/router/packageSurface.test.ts +24 -0
- package/tests/router/prefetchLink.test.tsx +43 -7
- package/tests/router/register.test.ts +46 -0
- package/tests/router/routeTree.test.ts +176 -139
- package/tests/router/rsc.test.tsx +70 -0
- package/tests/router/tanstackTypes.test.ts +395 -7
- package/dist/cjs/runtime/DefaultNotFound.js +0 -47
- package/dist/esm/runtime/DefaultNotFound.mjs +0 -13
- package/dist/esm-node/runtime/DefaultNotFound.mjs +0 -14
- package/dist/types/runtime/DefaultNotFound.d.ts +0 -2
- package/src/runtime/DefaultNotFound.tsx +0 -15
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getPathWithoutExt, makeLegalIdentifier } from "@modern-js/runtime/cli";
|
|
2
|
+
import { findExists, formatImportPath, slash } from "@modern-js/utils";
|
|
2
3
|
import path from "path";
|
|
3
|
-
const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public';
|
|
4
|
-
const builtins = 'arguments Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl';
|
|
5
|
-
const forbidList = new Set(`${reservedWords} ${builtins}`.split(' '));
|
|
6
|
-
function makeLegalIdentifier(str) {
|
|
7
|
-
const identifier = str.replace(/-(\w)/g, (_, letter)=>letter.toUpperCase()).replace(/[^$_a-zA-Z0-9]/g, '_');
|
|
8
|
-
if (/\d/.test(identifier[0]) || forbidList.has(identifier)) return `_${identifier}`;
|
|
9
|
-
return identifier || '_';
|
|
10
|
-
}
|
|
11
|
-
function getPathWithoutExt(filename) {
|
|
12
|
-
const extname = path.extname(filename);
|
|
13
|
-
return extname ? filename.slice(0, -extname.length) : filename;
|
|
14
|
-
}
|
|
15
4
|
const JS_OR_TS_EXTS = [
|
|
16
5
|
'.js',
|
|
17
6
|
'.jsx',
|
|
@@ -77,16 +66,78 @@ function createRouteStaticDataSnippet(opts) {
|
|
|
77
66
|
if (!staticDataLines.length) return null;
|
|
78
67
|
return `staticData: createRouteStaticData({\n ${staticDataLines.join('\n ')}\n }),`;
|
|
79
68
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
69
|
+
const LOCALE_PARAM_SEGMENTS = new Set([
|
|
70
|
+
':lang',
|
|
71
|
+
':locale',
|
|
72
|
+
':language',
|
|
73
|
+
'$lang',
|
|
74
|
+
'$locale',
|
|
75
|
+
'$language'
|
|
76
|
+
]);
|
|
77
|
+
function paramsTypeForCanonicalPath(canonicalPath) {
|
|
78
|
+
const fields = [];
|
|
79
|
+
for (const segment of canonicalPath.split('/'))if (segment) {
|
|
80
|
+
if ('*' === segment || '$' === segment) {
|
|
81
|
+
fields.push("'_splat'?: string");
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (segment.startsWith('{-$') && segment.endsWith('}')) {
|
|
85
|
+
fields.push(`${JSON.stringify(segment.slice(3, -1))}?: string`);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (segment.startsWith('$')) {
|
|
89
|
+
fields.push(`${JSON.stringify(segment.slice(1))}: string`);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (segment.startsWith(':')) {
|
|
93
|
+
const optional = segment.endsWith('?');
|
|
94
|
+
const name = segment.slice(1, optional ? void 0 : segment.length);
|
|
95
|
+
fields.push(`${JSON.stringify(optional ? name.slice(0, -1) : name)}${optional ? '?' : ''}: string`);
|
|
96
|
+
}
|
|
89
97
|
}
|
|
98
|
+
return fields.length > 0 ? `{ ${fields.join('; ')} }` : 'Record<string, never>';
|
|
99
|
+
}
|
|
100
|
+
function collectCanonicalRoutesForEntry(routes, options = {}) {
|
|
101
|
+
const { localeParamHeuristic = true } = options;
|
|
102
|
+
const canonicalParams = new Map();
|
|
103
|
+
let hasI18nSurface = false;
|
|
104
|
+
const normalizeJoined = (joined)=>{
|
|
105
|
+
const collapsed = joined.replace(/\/+/g, '/');
|
|
106
|
+
const withLeading = collapsed.startsWith('/') ? collapsed : `/${collapsed}`;
|
|
107
|
+
return withLeading.length > 1 ? withLeading.replace(/\/+$/, '') : withLeading;
|
|
108
|
+
};
|
|
109
|
+
const record = (canonicalPath)=>{
|
|
110
|
+
const normalized = normalizeJoined(canonicalPath || '/');
|
|
111
|
+
const key = toTanstackPath(normalized);
|
|
112
|
+
if (!canonicalParams.has(key)) canonicalParams.set(key, paramsTypeForCanonicalPath(normalized));
|
|
113
|
+
};
|
|
114
|
+
const visit = (route, parentPath)=>{
|
|
115
|
+
let currentPath = parentPath;
|
|
116
|
+
if ('string' == typeof route.modernCanonicalPath) {
|
|
117
|
+
hasI18nSurface = true;
|
|
118
|
+
currentPath = normalizeJoined(route.modernCanonicalPath);
|
|
119
|
+
} else if ('string' == typeof route.path && route.path.length > 0) {
|
|
120
|
+
const segments = route.path.replace(/\[(.+?)\]/g, ':$1').split('/').filter(Boolean);
|
|
121
|
+
if (localeParamHeuristic && '' === parentPath && LOCALE_PARAM_SEGMENTS.has(segments[0])) {
|
|
122
|
+
hasI18nSurface = true;
|
|
123
|
+
segments.shift();
|
|
124
|
+
}
|
|
125
|
+
currentPath = segments.length ? normalizeJoined(`${parentPath}/${segments.join('/')}`) : parentPath;
|
|
126
|
+
}
|
|
127
|
+
const children = route.children;
|
|
128
|
+
if (children && children.length > 0) {
|
|
129
|
+
for (const child of children)visit(child, currentPath);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
record(currentPath || '/');
|
|
133
|
+
};
|
|
134
|
+
const rootModern = routes.find((route)=>route.isRoot);
|
|
135
|
+
const topLevel = rootModern ? rootModern.children ?? [] : routes;
|
|
136
|
+
for (const route of topLevel)visit(route, '');
|
|
137
|
+
if (!hasI18nSurface || 0 === canonicalParams.size) return null;
|
|
138
|
+
return Object.fromEntries([
|
|
139
|
+
...canonicalParams.entries()
|
|
140
|
+
].sort(([a], [b])=>a.localeCompare(b)));
|
|
90
141
|
}
|
|
91
142
|
async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
92
143
|
const { appContext, entryName, generatedDirName = 'modern-tanstack', routes } = opts;
|
|
@@ -96,12 +147,30 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
96
147
|
const imports = [];
|
|
97
148
|
const statements = [];
|
|
98
149
|
const loaderImportMap = new Map();
|
|
150
|
+
const componentImportMap = new Map();
|
|
99
151
|
const searchContractImportMap = new Map();
|
|
100
152
|
const usedRouteVarNames = new Set();
|
|
101
153
|
let loaderIndex = 0;
|
|
154
|
+
let componentIndex = 0;
|
|
102
155
|
let validateSearchIndex = 0;
|
|
103
156
|
let loaderDepsIndex = 0;
|
|
104
157
|
let routeIndex = 0;
|
|
158
|
+
const getImportNameForComponent = (componentPath)=>{
|
|
159
|
+
if ('string' != typeof componentPath || 0 === componentPath.length) return Promise.resolve(null);
|
|
160
|
+
let pendingImportName = componentImportMap.get(componentPath);
|
|
161
|
+
if (!pendingImportName) {
|
|
162
|
+
pendingImportName = (async ()=>{
|
|
163
|
+
const resolvedNoExt = await resolveRouteModuleNoExt(componentPath);
|
|
164
|
+
if (!resolvedNoExt) return null;
|
|
165
|
+
const relImport = normalizeRelativeImport(path.relative(outDir, resolvedNoExt));
|
|
166
|
+
const componentName = `component_${componentIndex++}`;
|
|
167
|
+
imports.push(`import ${componentName} from ${quote(relImport)};`);
|
|
168
|
+
return componentName;
|
|
169
|
+
})();
|
|
170
|
+
componentImportMap.set(componentPath, pendingImportName);
|
|
171
|
+
}
|
|
172
|
+
return pendingImportName;
|
|
173
|
+
};
|
|
105
174
|
const resolveRouteModuleNoExt = async (aliasedNoExtPath)=>{
|
|
106
175
|
const prefix = `${appContext.internalSrcAlias}/`;
|
|
107
176
|
let absNoExt;
|
|
@@ -176,6 +245,8 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
176
245
|
const routeOpts = [
|
|
177
246
|
`getParentRoute: () => ${parentVar},`
|
|
178
247
|
];
|
|
248
|
+
const componentName = await getImportNameForComponent(route._component);
|
|
249
|
+
if (componentName) routeOpts.push(`component: ${componentName},`);
|
|
179
250
|
if (isPathlessLayout(route)) {
|
|
180
251
|
const id = route.id;
|
|
181
252
|
routeOpts.push(`id: ${quote(id || 'pathless')},`);
|
|
@@ -218,6 +289,8 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
218
289
|
route
|
|
219
290
|
})));
|
|
220
291
|
const rootOpts = [];
|
|
292
|
+
const rootComponentName = await getImportNameForComponent(rootModern?._component);
|
|
293
|
+
if (rootComponentName) rootOpts.push(`component: ${rootComponentName},`);
|
|
221
294
|
if (rootLoaderName) rootOpts.push(`loader: modernLoaderToTanstack({ hasSplat: false }, ${rootLoaderName}),`);
|
|
222
295
|
if (rootValidateSearchName) rootOpts.push(`validateSearch: ${rootValidateSearchName},`);
|
|
223
296
|
if (rootLoaderDepsName) rootOpts.push(`loaderDeps: ${rootLoaderDepsName},`);
|
|
@@ -226,178 +299,15 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
226
299
|
|
|
227
300
|
import {
|
|
228
301
|
createMemoryHistory,
|
|
229
|
-
modernTanstackRouterFastDefaults,
|
|
230
302
|
createRootRouteWithContext,
|
|
231
303
|
createRoute,
|
|
232
304
|
createRouter,
|
|
233
|
-
|
|
234
|
-
|
|
305
|
+
createRouteStaticData,
|
|
306
|
+
type ModernRouterContext,
|
|
307
|
+
modernLoaderToTanstack,
|
|
308
|
+
modernTanstackRouterFastDefaults,
|
|
235
309
|
} from '@modern-js/plugin-tanstack/runtime';
|
|
236
310
|
|
|
237
|
-
type ModernRouterContext = {
|
|
238
|
-
request?: Request;
|
|
239
|
-
requestContext?: unknown;
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
function isResponse(value: unknown): value is Response {
|
|
243
|
-
return (
|
|
244
|
-
value != null &&
|
|
245
|
-
typeof value === 'object' &&
|
|
246
|
-
typeof (value as any).status === 'number' &&
|
|
247
|
-
typeof (value as any).headers === 'object'
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
const redirectStatusCodes = new Set([301, 302, 303, 307, 308]);
|
|
252
|
-
function isRedirectResponse(res: Response) {
|
|
253
|
-
return redirectStatusCodes.has(res.status);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
function throwTanstackRedirect(location: string) {
|
|
257
|
-
const target = location.length > 0 ? location : '/';
|
|
258
|
-
try {
|
|
259
|
-
void new URL(target);
|
|
260
|
-
throw redirect({ href: target });
|
|
261
|
-
} catch {
|
|
262
|
-
throw redirect({ to: target });
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
function mapParamsForModernLoader(params: Record<string, string>, hasSplat: boolean) {
|
|
267
|
-
if (!hasSplat) {
|
|
268
|
-
return params;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
const { _splat, ...rest } = params as any;
|
|
272
|
-
if (typeof _splat !== 'undefined') {
|
|
273
|
-
return { ...rest, '*': _splat };
|
|
274
|
-
}
|
|
275
|
-
return rest;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
function createRouteStaticData(opts: {
|
|
279
|
-
modernRouteId?: string;
|
|
280
|
-
modernRouteAction?: unknown;
|
|
281
|
-
modernRouteLoader?: unknown;
|
|
282
|
-
}) {
|
|
283
|
-
const staticData: {
|
|
284
|
-
modernRouteId?: string;
|
|
285
|
-
modernRouteAction?: unknown;
|
|
286
|
-
modernRouteLoader?: unknown;
|
|
287
|
-
} = {};
|
|
288
|
-
|
|
289
|
-
if (typeof opts.modernRouteId === 'string' && opts.modernRouteId.length > 0) {
|
|
290
|
-
staticData.modernRouteId = opts.modernRouteId;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
if (typeof opts.modernRouteLoader !== 'undefined') {
|
|
294
|
-
staticData.modernRouteLoader = opts.modernRouteLoader;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (typeof opts.modernRouteAction !== 'undefined') {
|
|
298
|
-
staticData.modernRouteAction = opts.modernRouteAction;
|
|
299
|
-
}
|
|
300
|
-
|
|
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;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
function modernLoaderToTanstack<TLoader extends (args: any) => any>(
|
|
367
|
-
opts: { hasSplat: boolean },
|
|
368
|
-
modernLoader: TLoader,
|
|
369
|
-
) {
|
|
370
|
-
type LoaderResult = Awaited<ReturnType<TLoader>>;
|
|
371
|
-
|
|
372
|
-
return (ctx: any): Promise<LoaderResult> => {
|
|
373
|
-
try {
|
|
374
|
-
const signal = getLoaderSignal(ctx);
|
|
375
|
-
const baseRequest: Request | undefined =
|
|
376
|
-
ctx?.context?.request instanceof Request ? ctx.context.request : undefined;
|
|
377
|
-
|
|
378
|
-
const href = getLoaderHref(ctx);
|
|
379
|
-
|
|
380
|
-
const request = baseRequest !== undefined
|
|
381
|
-
? new Request(baseRequest, { signal })
|
|
382
|
-
: new Request(href, { signal });
|
|
383
|
-
|
|
384
|
-
const params = mapParamsForModernLoader(getLoaderParams(ctx), opts.hasSplat);
|
|
385
|
-
|
|
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);
|
|
395
|
-
} catch (err) {
|
|
396
|
-
handleModernLoaderError(err);
|
|
397
|
-
}
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
|
-
|
|
401
311
|
${imports.join('\n')}
|
|
402
312
|
|
|
403
313
|
export const rootRoute = createRootRouteWithContext<ModernRouterContext>()({
|
|
@@ -426,4 +336,4 @@ export const router = createRouter({
|
|
|
426
336
|
routerGenTs
|
|
427
337
|
};
|
|
428
338
|
}
|
|
429
|
-
export {
|
|
339
|
+
export { collectCanonicalRoutesForEntry, generateTanstackRouterTypesSourceForEntry };
|
|
@@ -1,8 +1 @@
|
|
|
1
|
-
|
|
2
|
-
const modifyRoutes = createSyncHook();
|
|
3
|
-
const onBeforeCreateRoutes = createSyncHook();
|
|
4
|
-
const onBeforeCreateRouter = createSyncHook();
|
|
5
|
-
const onAfterCreateRouter = createSyncHook();
|
|
6
|
-
const onBeforeHydrateRouter = createSyncHook();
|
|
7
|
-
const onAfterHydrateRouter = createSyncHook();
|
|
8
|
-
export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter };
|
|
1
|
+
export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter, routerProviderRegistryHooks } from "@modern-js/runtime/context";
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Suspense } from "react";
|
|
3
3
|
function wrapTanstackSsrHydrationBoundary(routerContent, shouldWrap) {
|
|
4
|
-
|
|
4
|
+
if (shouldWrap) return /*#__PURE__*/ jsx(Suspense, {
|
|
5
5
|
fallback: null,
|
|
6
6
|
children: routerContent
|
|
7
|
-
})
|
|
7
|
+
});
|
|
8
|
+
return routerContent;
|
|
8
9
|
}
|
|
9
10
|
export { wrapTanstackSsrHydrationBoundary };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import "./register.mjs";
|
|
1
2
|
export * from "@tanstack/react-router";
|
|
2
|
-
export { Outlet, useLocation, useMatch, useMatches, useNavigate, useRouter } from "@tanstack/react-router";
|
|
3
3
|
export { Form, RouteActionResponseError, useFetcher } from "./dataMutation.mjs";
|
|
4
|
+
export { createRouteStaticData, isAbsoluteUrl, modernLoaderToTanstack, throwTanstackRedirect } from "./loaderBridge.mjs";
|
|
5
|
+
export { Outlet } from "./outlet.mjs";
|
|
4
6
|
export { tanstackRouterPlugin as default, tanstackRouterPlugin } from "./plugin.mjs";
|
|
5
7
|
export { Link, NavLink } from "./prefetchLink.mjs";
|
|
6
|
-
export {
|
|
8
|
+
export { getTanstackRouterState } from "./state.mjs";
|
|
7
9
|
export { getModernTanstackRouterFastDefaults, modernTanstackRouterFastDefaults } from "./types.mjs";
|
|
@@ -1,82 +1 @@
|
|
|
1
|
-
|
|
2
|
-
if (state.hydrationScripts?.length) return state.hydrationScripts;
|
|
3
|
-
return state.hydrationScript ? [
|
|
4
|
-
state.hydrationScript
|
|
5
|
-
] : void 0;
|
|
6
|
-
}
|
|
7
|
-
function getMatchedRouteIdsFromMatches(matches) {
|
|
8
|
-
const routeIds = matches?.map((match)=>match.assetRouteId ?? match.routeId).filter((routeId)=>'string' == typeof routeId);
|
|
9
|
-
return routeIds?.length ? routeIds : void 0;
|
|
10
|
-
}
|
|
11
|
-
function createRouterServerSnapshot(state) {
|
|
12
|
-
const hydrationScripts = toHydrationScripts(state);
|
|
13
|
-
const matchedRouteIds = state.matchedRouteIds ?? getMatchedRouteIdsFromMatches(state.matches);
|
|
14
|
-
return {
|
|
15
|
-
...state,
|
|
16
|
-
...hydrationScripts?.length ? {
|
|
17
|
-
hydrationScript: state.hydrationScript ?? hydrationScripts[0],
|
|
18
|
-
hydrationScripts
|
|
19
|
-
} : {},
|
|
20
|
-
...matchedRouteIds ? {
|
|
21
|
-
matchedRouteIds
|
|
22
|
-
} : {}
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
function createRouterRuntimeState(state) {
|
|
26
|
-
const hasSnapshotState = Boolean(state.serverSnapshot) || Boolean(state.hydrationScript) || Boolean(state.hydrationScripts?.length) || Boolean(state.matchedRouteIds?.length) || Boolean(state.matches?.length);
|
|
27
|
-
const serverSnapshot = state.serverSnapshot ? createRouterServerSnapshot({
|
|
28
|
-
...state.serverSnapshot,
|
|
29
|
-
framework: state.serverSnapshot.framework ?? state.framework,
|
|
30
|
-
basename: state.serverSnapshot.basename ?? state.basename,
|
|
31
|
-
hydrationScript: state.serverSnapshot.hydrationScript ?? state.hydrationScript,
|
|
32
|
-
hydrationScripts: state.serverSnapshot.hydrationScripts ?? state.hydrationScripts,
|
|
33
|
-
matchedRouteIds: state.serverSnapshot.matchedRouteIds ?? state.matchedRouteIds,
|
|
34
|
-
matches: state.serverSnapshot.matches ?? state.matches
|
|
35
|
-
}) : hasSnapshotState ? createRouterServerSnapshot({
|
|
36
|
-
framework: state.framework,
|
|
37
|
-
basename: state.basename,
|
|
38
|
-
hydrationScript: state.hydrationScript,
|
|
39
|
-
hydrationScripts: state.hydrationScripts,
|
|
40
|
-
matchedRouteIds: state.matchedRouteIds,
|
|
41
|
-
matches: state.matches
|
|
42
|
-
}) : void 0;
|
|
43
|
-
const hydrationScripts = toHydrationScripts({
|
|
44
|
-
hydrationScript: state.hydrationScript ?? serverSnapshot?.hydrationScript,
|
|
45
|
-
hydrationScripts: state.hydrationScripts ?? serverSnapshot?.hydrationScripts
|
|
46
|
-
});
|
|
47
|
-
const matchedRouteIds = state.matchedRouteIds ?? serverSnapshot?.matchedRouteIds ?? getMatchedRouteIdsFromMatches(state.matches);
|
|
48
|
-
return {
|
|
49
|
-
...state,
|
|
50
|
-
...hydrationScripts?.length ? {
|
|
51
|
-
hydrationScript: state.hydrationScript ?? hydrationScripts[0],
|
|
52
|
-
hydrationScripts
|
|
53
|
-
} : {},
|
|
54
|
-
...matchedRouteIds ? {
|
|
55
|
-
matchedRouteIds
|
|
56
|
-
} : {},
|
|
57
|
-
...serverSnapshot ? {
|
|
58
|
-
serverSnapshot
|
|
59
|
-
} : {}
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
function applyRouterRuntimeState(runtimeContext, state) {
|
|
63
|
-
const normalized = createRouterRuntimeState(state);
|
|
64
|
-
const mutableRuntimeContext = runtimeContext;
|
|
65
|
-
mutableRuntimeContext.routerFramework = normalized.framework;
|
|
66
|
-
mutableRuntimeContext.routerInstance = normalized.instance;
|
|
67
|
-
mutableRuntimeContext.routerHydrationScript = normalized.hydrationScript;
|
|
68
|
-
mutableRuntimeContext.routerMatchedRouteIds = normalized.matchedRouteIds;
|
|
69
|
-
mutableRuntimeContext.routerRuntime = normalized;
|
|
70
|
-
if (normalized.serverSnapshot) mutableRuntimeContext.routerServerSnapshot = normalized.serverSnapshot;
|
|
71
|
-
return runtimeContext;
|
|
72
|
-
}
|
|
73
|
-
function applyRouterServerPrepareResult(runtimeContext, result) {
|
|
74
|
-
const state = createRouterRuntimeState({
|
|
75
|
-
...result.state,
|
|
76
|
-
cleanup: result.cleanup ?? result.state.cleanup,
|
|
77
|
-
serverSnapshot: result.snapshot ?? result.state.serverSnapshot
|
|
78
|
-
});
|
|
79
|
-
applyRouterRuntimeState(runtimeContext, state);
|
|
80
|
-
return runtimeContext;
|
|
81
|
-
}
|
|
82
|
-
export { applyRouterRuntimeState, applyRouterServerPrepareResult, createRouterRuntimeState, createRouterServerSnapshot };
|
|
1
|
+
export { applyRouterRuntimeState, applyRouterServerPrepareResult, createRouterRuntimeState, createRouterServerSnapshot, getRouterRuntimeState, getRouterServerSnapshot } from "@modern-js/runtime/context";
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { notFound, redirect } from "@tanstack/react-router";
|
|
2
|
+
function isResponse(value) {
|
|
3
|
+
const record = value;
|
|
4
|
+
return null != record && 'object' == typeof record && 'number' == typeof record.status && 'object' == typeof record.headers;
|
|
5
|
+
}
|
|
6
|
+
const redirectStatusCodes = new Set([
|
|
7
|
+
301,
|
|
8
|
+
302,
|
|
9
|
+
303,
|
|
10
|
+
307,
|
|
11
|
+
308
|
|
12
|
+
]);
|
|
13
|
+
function isRedirectResponse(res) {
|
|
14
|
+
return redirectStatusCodes.has(res.status);
|
|
15
|
+
}
|
|
16
|
+
function isTanstackRedirect(value) {
|
|
17
|
+
return isResponse(value) && 'object' == typeof value.options;
|
|
18
|
+
}
|
|
19
|
+
function isAbsoluteUrl(value) {
|
|
20
|
+
try {
|
|
21
|
+
new URL(value);
|
|
22
|
+
return true;
|
|
23
|
+
} catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function throwTanstackRedirect(location) {
|
|
28
|
+
const target = location || '/';
|
|
29
|
+
if (isAbsoluteUrl(target)) throw redirect({
|
|
30
|
+
href: target
|
|
31
|
+
});
|
|
32
|
+
throw redirect({
|
|
33
|
+
to: target
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function mapSplatParamsForModernLoader(params, hasSplat) {
|
|
37
|
+
if (!hasSplat) return params;
|
|
38
|
+
const { _splat, ...rest } = params;
|
|
39
|
+
if (void 0 !== _splat) return {
|
|
40
|
+
...rest,
|
|
41
|
+
'*': _splat
|
|
42
|
+
};
|
|
43
|
+
return rest;
|
|
44
|
+
}
|
|
45
|
+
function createRouteStaticData(opts) {
|
|
46
|
+
const staticData = {};
|
|
47
|
+
if ('string' == typeof opts.modernRouteId && opts.modernRouteId.length > 0) staticData.modernRouteId = opts.modernRouteId;
|
|
48
|
+
if (void 0 !== opts.modernRouteLoader) staticData.modernRouteLoader = opts.modernRouteLoader;
|
|
49
|
+
if (void 0 !== opts.modernRouteAction) staticData.modernRouteAction = opts.modernRouteAction;
|
|
50
|
+
return staticData;
|
|
51
|
+
}
|
|
52
|
+
function getLoaderSignal(ctx) {
|
|
53
|
+
const abortSignal = ctx?.abortController?.signal;
|
|
54
|
+
if (abortSignal instanceof AbortSignal) return abortSignal;
|
|
55
|
+
if (ctx?.signal instanceof AbortSignal) return ctx.signal;
|
|
56
|
+
return new AbortController().signal;
|
|
57
|
+
}
|
|
58
|
+
function getLoaderHref(ctx) {
|
|
59
|
+
if ('string' == typeof ctx?.location) return ctx.location;
|
|
60
|
+
const publicHref = ctx?.location?.publicHref;
|
|
61
|
+
if ('string' == typeof publicHref) return publicHref;
|
|
62
|
+
const href = ctx?.location?.href;
|
|
63
|
+
if ('string' == typeof href) return href;
|
|
64
|
+
const urlHref = ctx?.location?.url?.href;
|
|
65
|
+
return 'string' == typeof urlHref ? urlHref : '';
|
|
66
|
+
}
|
|
67
|
+
function getLoaderParams(ctx) {
|
|
68
|
+
return 'object' == typeof ctx?.params && null !== ctx.params ? ctx.params : {};
|
|
69
|
+
}
|
|
70
|
+
function handleModernLoaderResult(result) {
|
|
71
|
+
if (isResponse(result)) {
|
|
72
|
+
if (isRedirectResponse(result)) {
|
|
73
|
+
const location = result.headers.get('Location') ?? '/';
|
|
74
|
+
throwTanstackRedirect(location);
|
|
75
|
+
}
|
|
76
|
+
if (404 === result.status) throw notFound();
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
function handleModernLoaderError(err) {
|
|
81
|
+
if (isResponse(err)) {
|
|
82
|
+
if (isTanstackRedirect(err)) throw err;
|
|
83
|
+
if (isRedirectResponse(err)) {
|
|
84
|
+
const location = err.headers.get('Location') ?? '/';
|
|
85
|
+
throwTanstackRedirect(location);
|
|
86
|
+
}
|
|
87
|
+
if (404 === err.status) throw notFound();
|
|
88
|
+
}
|
|
89
|
+
throw err;
|
|
90
|
+
}
|
|
91
|
+
function modernLoaderToTanstack(opts, modernLoader) {
|
|
92
|
+
return (rawCtx)=>{
|
|
93
|
+
const ctx = rawCtx;
|
|
94
|
+
try {
|
|
95
|
+
const signal = getLoaderSignal(ctx);
|
|
96
|
+
const baseRequest = ctx?.context?.request instanceof Request ? ctx.context.request : void 0;
|
|
97
|
+
const href = getLoaderHref(ctx);
|
|
98
|
+
const request = void 0 !== baseRequest ? new Request(baseRequest, {
|
|
99
|
+
signal
|
|
100
|
+
}) : new Request(href, {
|
|
101
|
+
signal
|
|
102
|
+
});
|
|
103
|
+
const params = mapSplatParamsForModernLoader(getLoaderParams(ctx), opts.hasSplat);
|
|
104
|
+
return Promise.resolve(modernLoader({
|
|
105
|
+
request,
|
|
106
|
+
params,
|
|
107
|
+
context: ctx?.context?.requestContext
|
|
108
|
+
})).then((result)=>handleModernLoaderResult(result)).catch(handleModernLoaderError);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
handleModernLoaderError(err);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export { createRouteStaticData, isAbsoluteUrl, isRedirectResponse, isResponse, isTanstackRedirect, mapSplatParamsForModernLoader, modernLoaderToTanstack, throwTanstackRedirect };
|
|
@@ -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 };
|