@bleedingdev/modern-js-plugin-tanstack 3.5.0-ultramodern.9 → 3.5.0-ultramodern.91
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/artifacts.js +157 -0
- package/dist/cjs/cli/index.js +8 -79
- package/dist/cjs/cli/tanstackTypes/canonicalRoutes.js +113 -0
- package/dist/cjs/cli/tanstackTypes/shared.js +123 -0
- package/dist/cjs/cli/tanstackTypes/source.js +255 -0
- package/dist/cjs/cli/tanstackTypes.js +4 -350
- package/dist/cjs/runtime/blockingSubscribe.js +57 -0
- package/dist/cjs/runtime/{pluginCore.js → clientBasepath.js} +12 -19
- package/dist/cjs/runtime/clientHydration.js +118 -0
- package/dist/cjs/runtime/dataMutation.js +11 -176
- package/dist/cjs/runtime/formData.js +116 -0
- package/dist/cjs/runtime/loaderBridge.js +7 -11
- package/dist/cjs/runtime/plugin.js +21 -125
- package/dist/cjs/runtime/plugin.node.js +45 -125
- package/dist/cjs/runtime/pluginShared.js +87 -0
- package/dist/cjs/runtime/prefetchLink.js +15 -2
- package/dist/cjs/runtime/register.js +3 -16
- package/dist/cjs/runtime/routeTree/components.js +102 -0
- package/dist/cjs/runtime/routeTree/construction.js +152 -0
- package/dist/cjs/runtime/routeTree/index.js +47 -0
- package/dist/cjs/runtime/routeTree/loaders.js +158 -0
- package/dist/cjs/runtime/routeTree/paths.js +57 -0
- package/dist/cjs/runtime/routeTree/staticData.js +63 -0
- package/dist/cjs/runtime/routeTree/tanstackRoutes.js +57 -0
- package/dist/cjs/runtime/routeTree/types.js +18 -0
- package/dist/cjs/runtime/routeTree.js +7 -320
- package/dist/cjs/runtime/router.js +15 -2
- package/dist/cjs/runtime/rsc/CompositeComponent.js +18 -13
- package/dist/cjs/runtime/rsc/ReplayableStream.js +0 -4
- package/dist/cjs/runtime/rsc/RscNodeRenderer.js +5 -16
- package/dist/cjs/runtime/rsc/client.js +8 -25
- package/dist/cjs/runtime/rsc/flightSerialization.js +132 -0
- package/dist/cjs/runtime/rsc/payloadErrors.js +99 -0
- package/dist/cjs/runtime/rsc/payloadFetch.js +105 -0
- package/dist/cjs/runtime/rsc/payloadRouter.js +21 -142
- package/dist/cjs/runtime/rsc/payloadRoutes.js +94 -0
- package/dist/cjs/runtime/rsc/payloadStorage.js +58 -0
- package/dist/cjs/runtime/rsc/server.js +14 -18
- package/dist/cjs/runtime/rsc/shared.js +68 -0
- package/dist/cjs/runtime/rsc/slotUsageSanitizer.js +1 -0
- package/dist/cjs/runtime/rsc/treeGetter.js +72 -0
- package/dist/cjs/runtime/shared/isAbsoluteUrl.js +47 -0
- package/dist/cjs/runtime/ssrManagedTags.js +103 -0
- package/dist/cjs/runtime/ssrPreload.js +89 -0
- package/dist/cjs/runtime/ssrTypes.js +18 -0
- package/dist/cjs/runtime/state.js +1 -1
- package/dist/cjs/runtime/submitAction.js +161 -0
- package/dist/cjs/runtime/utils.js +49 -86
- package/dist/esm/cli/artifacts.mjs +103 -0
- package/dist/esm/cli/index.mjs +8 -82
- package/dist/esm/cli/tanstackTypes/canonicalRoutes.mjs +75 -0
- package/dist/esm/cli/tanstackTypes/shared.mjs +61 -0
- package/dist/esm/cli/tanstackTypes/source.mjs +207 -0
- package/dist/esm/cli/tanstackTypes.mjs +2 -339
- package/dist/esm/runtime/blockingSubscribe.mjs +19 -0
- package/dist/esm/runtime/clientBasepath.mjs +10 -0
- package/dist/esm/runtime/clientHydration.mjs +71 -0
- package/dist/esm/runtime/dataMutation.mjs +2 -167
- package/dist/esm/runtime/formData.mjs +63 -0
- package/dist/esm/runtime/loaderBridge.mjs +5 -9
- package/dist/esm/runtime/plugin.mjs +14 -118
- package/dist/esm/runtime/plugin.node.mjs +41 -121
- package/dist/esm/runtime/pluginShared.mjs +40 -0
- package/dist/esm/runtime/prefetchLink.mjs +18 -5
- package/dist/esm/runtime/register.mjs +1 -14
- package/dist/esm/runtime/routeTree/components.mjs +55 -0
- package/dist/esm/runtime/routeTree/construction.mjs +111 -0
- package/dist/esm/runtime/routeTree/index.mjs +2 -0
- package/dist/esm/runtime/routeTree/loaders.mjs +117 -0
- package/dist/esm/runtime/routeTree/paths.mjs +16 -0
- package/dist/esm/runtime/routeTree/staticData.mjs +22 -0
- package/dist/esm/runtime/routeTree/tanstackRoutes.mjs +13 -0
- package/dist/esm/runtime/routeTree/types.mjs +0 -0
- package/dist/esm/runtime/routeTree.mjs +1 -318
- package/dist/esm/runtime/router.mjs +16 -2
- package/dist/esm/runtime/rsc/CompositeComponent.mjs +18 -13
- package/dist/esm/runtime/rsc/ReplayableStream.mjs +1 -1
- package/dist/esm/runtime/rsc/RscNodeRenderer.mjs +4 -15
- package/dist/esm/runtime/rsc/client.mjs +6 -26
- package/dist/esm/runtime/rsc/flightSerialization.mjs +88 -0
- package/dist/esm/runtime/rsc/payloadErrors.mjs +49 -0
- package/dist/esm/runtime/rsc/payloadFetch.mjs +55 -0
- package/dist/esm/runtime/rsc/payloadRouter.mjs +12 -133
- package/dist/esm/runtime/rsc/payloadRoutes.mjs +50 -0
- package/dist/esm/runtime/rsc/payloadStorage.mjs +14 -0
- package/dist/esm/runtime/rsc/server.mjs +17 -21
- package/dist/esm/runtime/rsc/shared.mjs +21 -0
- package/dist/esm/runtime/rsc/slotUsageSanitizer.mjs +1 -0
- package/dist/esm/runtime/rsc/treeGetter.mjs +34 -0
- package/dist/esm/runtime/shared/isAbsoluteUrl.mjs +9 -0
- package/dist/esm/runtime/ssrManagedTags.mjs +53 -0
- package/dist/esm/runtime/ssrPreload.mjs +51 -0
- package/dist/esm/runtime/ssrTypes.mjs +0 -0
- package/dist/esm/runtime/state.mjs +1 -1
- package/dist/esm/runtime/submitAction.mjs +120 -0
- package/dist/esm/runtime/utils.mjs +47 -75
- package/dist/esm-node/cli/artifacts.mjs +104 -0
- package/dist/esm-node/cli/index.mjs +8 -82
- package/dist/esm-node/cli/tanstackTypes/canonicalRoutes.mjs +76 -0
- package/dist/esm-node/cli/tanstackTypes/shared.mjs +62 -0
- package/dist/esm-node/cli/tanstackTypes/source.mjs +208 -0
- package/dist/esm-node/cli/tanstackTypes.mjs +2 -339
- package/dist/esm-node/runtime/blockingSubscribe.mjs +20 -0
- package/dist/esm-node/runtime/clientBasepath.mjs +11 -0
- package/dist/esm-node/runtime/clientHydration.mjs +72 -0
- package/dist/esm-node/runtime/dataMutation.mjs +2 -167
- package/dist/esm-node/runtime/formData.mjs +64 -0
- package/dist/esm-node/runtime/loaderBridge.mjs +5 -9
- package/dist/esm-node/runtime/plugin.mjs +14 -118
- package/dist/esm-node/runtime/plugin.node.mjs +41 -121
- package/dist/esm-node/runtime/pluginShared.mjs +41 -0
- package/dist/esm-node/runtime/prefetchLink.mjs +18 -5
- package/dist/esm-node/runtime/register.mjs +1 -14
- package/dist/esm-node/runtime/routeTree/components.mjs +56 -0
- package/dist/esm-node/runtime/routeTree/construction.mjs +112 -0
- package/dist/esm-node/runtime/routeTree/index.mjs +3 -0
- package/dist/esm-node/runtime/routeTree/loaders.mjs +118 -0
- package/dist/esm-node/runtime/routeTree/paths.mjs +17 -0
- package/dist/esm-node/runtime/routeTree/staticData.mjs +23 -0
- package/dist/esm-node/runtime/routeTree/tanstackRoutes.mjs +14 -0
- package/dist/esm-node/runtime/routeTree/types.mjs +1 -0
- package/dist/esm-node/runtime/routeTree.mjs +1 -318
- package/dist/esm-node/runtime/router.mjs +16 -2
- package/dist/esm-node/runtime/rsc/CompositeComponent.mjs +18 -13
- package/dist/esm-node/runtime/rsc/ReplayableStream.mjs +1 -1
- package/dist/esm-node/runtime/rsc/RscNodeRenderer.mjs +4 -15
- package/dist/esm-node/runtime/rsc/client.mjs +6 -26
- package/dist/esm-node/runtime/rsc/flightSerialization.mjs +89 -0
- package/dist/esm-node/runtime/rsc/payloadErrors.mjs +50 -0
- package/dist/esm-node/runtime/rsc/payloadFetch.mjs +56 -0
- package/dist/esm-node/runtime/rsc/payloadRouter.mjs +12 -133
- package/dist/esm-node/runtime/rsc/payloadRoutes.mjs +51 -0
- package/dist/esm-node/runtime/rsc/payloadStorage.mjs +15 -0
- package/dist/esm-node/runtime/rsc/server.mjs +17 -21
- package/dist/esm-node/runtime/rsc/shared.mjs +22 -0
- package/dist/esm-node/runtime/rsc/slotUsageSanitizer.mjs +1 -0
- package/dist/esm-node/runtime/rsc/treeGetter.mjs +35 -0
- package/dist/esm-node/runtime/shared/isAbsoluteUrl.mjs +10 -0
- package/dist/esm-node/runtime/ssrManagedTags.mjs +54 -0
- package/dist/esm-node/runtime/ssrPreload.mjs +52 -0
- package/dist/esm-node/runtime/ssrTypes.mjs +1 -0
- package/dist/esm-node/runtime/state.mjs +1 -1
- package/dist/esm-node/runtime/submitAction.mjs +121 -0
- package/dist/esm-node/runtime/utils.mjs +47 -75
- package/dist/types/cli/artifacts.d.ts +33 -0
- package/dist/types/cli/index.d.ts +2 -22
- package/dist/types/cli/tanstackTypes/canonicalRoutes.d.ts +22 -0
- package/dist/types/cli/tanstackTypes/shared.d.ts +20 -0
- package/dist/types/cli/tanstackTypes/source.d.ts +12 -0
- package/dist/types/cli/tanstackTypes.d.ts +3 -31
- package/dist/types/runtime/blockingSubscribe.d.ts +1 -0
- package/dist/types/runtime/clientBasepath.d.ts +1 -0
- package/dist/types/runtime/clientHydration.d.ts +10 -0
- package/dist/types/runtime/dataMutation.d.ts +3 -12
- package/dist/types/runtime/formData.d.ts +24 -0
- package/dist/types/runtime/loaderBridge.d.ts +2 -1
- package/dist/types/runtime/plugin.d.ts +1 -1
- package/dist/types/runtime/plugin.node.d.ts +1 -1
- package/dist/types/runtime/pluginShared.d.ts +38 -0
- package/dist/types/runtime/register.d.ts +10 -9
- package/dist/types/runtime/routeTree/components.d.ts +7 -0
- package/dist/types/runtime/routeTree/construction.d.ts +5 -0
- package/dist/types/runtime/routeTree/index.d.ts +2 -0
- package/dist/types/runtime/routeTree/loaders.d.ts +4 -0
- package/dist/types/runtime/routeTree/paths.d.ts +3 -0
- package/dist/types/runtime/routeTree/staticData.d.ts +19 -0
- package/dist/types/runtime/routeTree/tanstackRoutes.d.ts +4 -0
- package/dist/types/runtime/routeTree/types.d.ts +76 -0
- package/dist/types/runtime/routeTree.d.ts +1 -9
- package/dist/types/runtime/router.d.ts +6 -7
- package/dist/types/runtime/rsc/CompositeComponent.d.ts +1 -2
- package/dist/types/runtime/rsc/ReplayableStream.d.ts +3 -2
- package/dist/types/runtime/rsc/RscNodeRenderer.d.ts +2 -3
- package/dist/types/runtime/rsc/SlotContext.d.ts +2 -1
- package/dist/types/runtime/rsc/client.d.ts +2 -0
- package/dist/types/runtime/rsc/flightSerialization.d.ts +3 -0
- package/dist/types/runtime/rsc/payloadErrors.d.ts +6 -0
- package/dist/types/runtime/rsc/payloadFetch.d.ts +8 -0
- package/dist/types/runtime/rsc/payloadRouter.d.ts +2 -10
- package/dist/types/runtime/rsc/payloadRoutes.d.ts +40 -0
- package/dist/types/runtime/rsc/payloadStorage.d.ts +5 -0
- package/dist/types/runtime/rsc/shared.d.ts +18 -0
- package/dist/types/runtime/rsc/treeGetter.d.ts +1 -0
- package/dist/types/runtime/shared/isAbsoluteUrl.d.ts +1 -0
- package/dist/types/runtime/ssrManagedTags.d.ts +7 -0
- package/dist/types/runtime/ssrPreload.d.ts +2 -0
- package/dist/types/runtime/ssrTypes.d.ts +44 -0
- package/dist/types/runtime/state.d.ts +1 -1
- package/dist/types/runtime/submitAction.d.ts +14 -0
- package/dist/types/runtime/types.d.ts +4 -10
- package/dist/types/runtime/utils.d.ts +4 -24
- package/package.json +37 -17
- package/rstest.config.mts +23 -0
- package/src/cli/artifacts.ts +255 -0
- package/src/cli/index.ts +7 -185
- package/src/cli/tanstackTypes/canonicalRoutes.ts +157 -0
- package/src/cli/tanstackTypes/shared.ts +113 -0
- package/src/cli/tanstackTypes/source.ts +414 -0
- package/src/cli/tanstackTypes.ts +4 -647
- package/src/runtime/blockingSubscribe.ts +48 -0
- package/src/runtime/clientBasepath.ts +12 -0
- package/src/runtime/clientHydration.ts +149 -0
- package/src/runtime/dataMutation.tsx +9 -306
- package/src/runtime/formData.ts +153 -0
- package/src/runtime/loaderBridge.ts +11 -12
- package/src/runtime/plugin.node.tsx +76 -291
- package/src/runtime/plugin.tsx +21 -257
- package/src/runtime/pluginShared.ts +112 -0
- package/src/runtime/prefetchLink.tsx +78 -15
- package/src/runtime/register.ts +10 -42
- package/src/runtime/routeTree/components.ts +130 -0
- package/src/runtime/routeTree/construction.ts +238 -0
- package/src/runtime/routeTree/index.ts +7 -0
- package/src/runtime/routeTree/loaders.ts +232 -0
- package/src/runtime/routeTree/paths.ts +36 -0
- package/src/runtime/routeTree/staticData.ts +66 -0
- package/src/runtime/routeTree/tanstackRoutes.ts +36 -0
- package/src/runtime/routeTree/types.ts +87 -0
- package/src/runtime/routeTree.ts +5 -750
- package/src/runtime/router.ts +35 -7
- package/src/runtime/rsc/CompositeComponent.tsx +29 -20
- package/src/runtime/rsc/ReplayableStream.ts +2 -2
- package/src/runtime/rsc/RscNodeRenderer.tsx +9 -27
- package/src/runtime/rsc/SlotContext.tsx +1 -1
- package/src/runtime/rsc/client.tsx +12 -40
- package/src/runtime/rsc/flightSerialization.ts +158 -0
- package/src/runtime/rsc/payloadErrors.ts +73 -0
- package/src/runtime/rsc/payloadFetch.ts +92 -0
- package/src/runtime/rsc/payloadRouter.ts +29 -234
- package/src/runtime/rsc/payloadRoutes.ts +122 -0
- package/src/runtime/rsc/payloadStorage.ts +35 -0
- package/src/runtime/rsc/server.tsx +20 -29
- package/src/runtime/rsc/shared.ts +70 -0
- package/src/runtime/rsc/slotUsageSanitizer.ts +4 -0
- package/src/runtime/rsc/treeGetter.tsx +52 -0
- package/src/runtime/shared/isAbsoluteUrl.ts +8 -0
- package/src/runtime/ssrManagedTags.ts +107 -0
- package/src/runtime/ssrPreload.ts +125 -0
- package/src/runtime/ssrTypes.ts +51 -0
- package/src/runtime/state.ts +9 -3
- package/src/runtime/submitAction.ts +201 -0
- package/src/runtime/types.ts +4 -18
- package/src/runtime/utils.tsx +76 -110
- package/src/types/react-server-dom-rspack.d.ts +56 -0
- package/tests/castRatchet.test.ts +85 -0
- package/tests/realm-isolation.test.ts +114 -0
- package/tests/router/cli.test.ts +7 -0
- package/tests/router/clientHydration.test.tsx +61 -0
- package/tests/router/dataMutation.test.tsx +59 -0
- package/tests/router/fixtures/legacyRuntimeRouter.ts +10 -0
- package/tests/router/fixtures/router-gen.golden.txt +71 -0
- package/tests/router/fixtures/router-gen.oxlint.json +5 -0
- package/tests/router/flightSerialization.roundtrip.test.tsx +137 -0
- package/tests/router/generateRouteArtifacts.test.ts +106 -0
- package/tests/router/hooks.test.ts +14 -0
- package/tests/router/loaderBridge.test.ts +21 -0
- package/tests/router/prefetchLink.test.tsx +106 -59
- package/tests/router/prefetchLinkPreload.test.tsx +85 -0
- package/tests/router/register.test.ts +1 -39
- package/tests/router/routeTree.test.ts +51 -11
- package/tests/router/routerCompatibility.test.ts +245 -0
- package/tests/router/rsc.test.tsx +189 -0
- package/tests/router/rscPayloadRouterMatrix.test.ts +197 -0
- package/tests/router/slotUsageSanitizer.test.ts +23 -0
- package/tests/router/ssrPreload.test.ts +30 -0
- package/tests/router/tanstackTypes.test.ts +298 -1
- package/dist/esm/runtime/pluginCore.mjs +0 -14
- package/dist/esm-node/runtime/pluginCore.mjs +0 -15
- package/dist/types/runtime/pluginCore.d.ts +0 -21
- package/src/runtime/pluginCore.ts +0 -48
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// @effect-diagnostics asyncFunction:off strictBooleanExpressions:off
|
|
2
|
+
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { getPathWithoutExt } from '@modern-js/runtime/cli';
|
|
5
|
+
import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
|
|
6
|
+
import { findExists, formatImportPath, slash } from '@modern-js/utils';
|
|
7
|
+
|
|
8
|
+
const JS_OR_TS_EXTS = [
|
|
9
|
+
'.js',
|
|
10
|
+
'.jsx',
|
|
11
|
+
'.ts',
|
|
12
|
+
'.tsx',
|
|
13
|
+
'.mjs',
|
|
14
|
+
'.mts',
|
|
15
|
+
'.cjs',
|
|
16
|
+
'.cts',
|
|
17
|
+
] as const;
|
|
18
|
+
|
|
19
|
+
export { toTanstackPath } from '../../runtime/routeTree/paths';
|
|
20
|
+
|
|
21
|
+
export async function resolveFileNoExt(inputNoExtPath: string) {
|
|
22
|
+
const file = findExists(JS_OR_TS_EXTS.map(ext => `${inputNoExtPath}${ext}`));
|
|
23
|
+
return file ? getPathWithoutExt(file) : null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function quote(str: string) {
|
|
27
|
+
return JSON.stringify(str);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function normalizeRelativeImport(p: string) {
|
|
31
|
+
const normalized = formatImportPath(slash(p));
|
|
32
|
+
if (normalized.startsWith('.')) {
|
|
33
|
+
return normalized;
|
|
34
|
+
}
|
|
35
|
+
return `./${normalized}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type RouteExtras = {
|
|
39
|
+
data?: unknown;
|
|
40
|
+
loader?: unknown;
|
|
41
|
+
validateSearch?: unknown;
|
|
42
|
+
loaderDeps?: unknown;
|
|
43
|
+
type?: unknown;
|
|
44
|
+
index?: unknown;
|
|
45
|
+
path?: unknown;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export function pickModernLoaderModule(route: NestedRouteForCli | PageRoute) {
|
|
49
|
+
const extras = route as RouteExtras;
|
|
50
|
+
const loaderPath = extras.data || extras.loader;
|
|
51
|
+
if (!loaderPath || typeof loaderPath !== 'string') {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const inline = Boolean(extras.data);
|
|
56
|
+
return { loaderPath, inline };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function pickRouteSearchContractModules(
|
|
60
|
+
route: NestedRouteForCli | PageRoute,
|
|
61
|
+
) {
|
|
62
|
+
const extras = route as RouteExtras;
|
|
63
|
+
const validateSearchPath = extras.validateSearch;
|
|
64
|
+
const loaderDepsPath = extras.loaderDeps;
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
validateSearchPath:
|
|
68
|
+
typeof validateSearchPath === 'string' ? validateSearchPath : null,
|
|
69
|
+
loaderDepsPath: typeof loaderDepsPath === 'string' ? loaderDepsPath : null,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function isPathlessLayout(route: NestedRouteForCli | PageRoute) {
|
|
74
|
+
const extras = route as RouteExtras;
|
|
75
|
+
return (
|
|
76
|
+
extras.type === 'nested' &&
|
|
77
|
+
typeof extras.index !== 'boolean' &&
|
|
78
|
+
typeof extras.path === 'undefined'
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function isIndexRoute(route: NestedRouteForCli | PageRoute) {
|
|
83
|
+
const extras = route as RouteExtras;
|
|
84
|
+
return extras.type === 'nested' && Boolean(extras.index);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function createRouteStaticDataSnippet(opts: {
|
|
88
|
+
modernRouteId?: string;
|
|
89
|
+
loaderName?: string | null;
|
|
90
|
+
actionName?: string | null;
|
|
91
|
+
}) {
|
|
92
|
+
const staticDataLines: string[] = [];
|
|
93
|
+
|
|
94
|
+
if (opts.modernRouteId) {
|
|
95
|
+
staticDataLines.push(`modernRouteId: ${quote(opts.modernRouteId)},`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (opts.loaderName) {
|
|
99
|
+
staticDataLines.push(`modernRouteLoader: ${opts.loaderName},`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (opts.actionName) {
|
|
103
|
+
staticDataLines.push(`modernRouteAction: ${opts.actionName},`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!staticDataLines.length) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return `staticData: createRouteStaticData({\n ${staticDataLines.join(
|
|
111
|
+
'\n ',
|
|
112
|
+
)}\n }),`;
|
|
113
|
+
}
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
// @effect-diagnostics asyncFunction:off strictBooleanExpressions:off
|
|
2
|
+
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import type {
|
|
5
|
+
AppNormalizedConfig,
|
|
6
|
+
AppTools,
|
|
7
|
+
AppToolsContext,
|
|
8
|
+
} from '@modern-js/app-tools';
|
|
9
|
+
import { makeLegalIdentifier } from '@modern-js/runtime/cli';
|
|
10
|
+
import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
createRouteStaticDataSnippet,
|
|
14
|
+
isIndexRoute,
|
|
15
|
+
isPathlessLayout,
|
|
16
|
+
normalizeRelativeImport,
|
|
17
|
+
pickModernLoaderModule,
|
|
18
|
+
pickRouteSearchContractModules,
|
|
19
|
+
quote,
|
|
20
|
+
resolveFileNoExt,
|
|
21
|
+
toTanstackPath,
|
|
22
|
+
} from './shared';
|
|
23
|
+
|
|
24
|
+
type RouteForCli = NestedRouteForCli | PageRoute;
|
|
25
|
+
|
|
26
|
+
type RouteExtras = {
|
|
27
|
+
id?: string;
|
|
28
|
+
type?: unknown;
|
|
29
|
+
isRoot?: unknown;
|
|
30
|
+
children?: RouteForCli[];
|
|
31
|
+
action?: unknown;
|
|
32
|
+
path?: string;
|
|
33
|
+
_component?: unknown;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export async function generateTanstackRouterTypesSourceForEntry(opts: {
|
|
37
|
+
appContext: AppToolsContext;
|
|
38
|
+
entryName: string;
|
|
39
|
+
generatedDirName?: string;
|
|
40
|
+
routes: RouteForCli[];
|
|
41
|
+
}): Promise<{
|
|
42
|
+
routerGenTs: string;
|
|
43
|
+
}> {
|
|
44
|
+
const {
|
|
45
|
+
appContext,
|
|
46
|
+
entryName,
|
|
47
|
+
generatedDirName = 'modern-tanstack',
|
|
48
|
+
routes,
|
|
49
|
+
} = opts;
|
|
50
|
+
const outDir = path.join(
|
|
51
|
+
appContext.srcDirectory,
|
|
52
|
+
generatedDirName,
|
|
53
|
+
entryName,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const rootModern = routes.find(r => {
|
|
57
|
+
const extras = r as RouteExtras;
|
|
58
|
+
return r && extras.type === 'nested' && extras.isRoot;
|
|
59
|
+
}) as NestedRouteForCli | undefined;
|
|
60
|
+
|
|
61
|
+
const rootExtras = rootModern as RouteExtras | undefined;
|
|
62
|
+
const topLevel = rootModern ? rootExtras?.children || [] : routes;
|
|
63
|
+
|
|
64
|
+
const imports: string[] = [];
|
|
65
|
+
const statements: string[] = [];
|
|
66
|
+
|
|
67
|
+
const loaderImportMap = new Map<string, string>();
|
|
68
|
+
const componentImportMap = new Map<string, Promise<string | null>>();
|
|
69
|
+
const searchContractImportMap = new Map<string, string>();
|
|
70
|
+
const usedRouteVarNames = new Set<string>();
|
|
71
|
+
let loaderIndex = 0;
|
|
72
|
+
let componentIndex = 0;
|
|
73
|
+
let validateSearchIndex = 0;
|
|
74
|
+
let loaderDepsIndex = 0;
|
|
75
|
+
let routeIndex = 0;
|
|
76
|
+
|
|
77
|
+
const getImportNameForComponent = (
|
|
78
|
+
componentPath: unknown,
|
|
79
|
+
): Promise<string | null> => {
|
|
80
|
+
if (typeof componentPath !== 'string' || componentPath.length === 0) {
|
|
81
|
+
return Promise.resolve(null);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Cache the in-flight promise: sibling routes sharing a component module
|
|
85
|
+
// are generated concurrently and must reuse one import.
|
|
86
|
+
let pendingImportName = componentImportMap.get(componentPath);
|
|
87
|
+
if (!pendingImportName) {
|
|
88
|
+
pendingImportName = (async () => {
|
|
89
|
+
// Resolve through the same machinery as loaders: the raw `_component`
|
|
90
|
+
// value carries the internal `@_modern_js_src` alias, which the app's
|
|
91
|
+
// tsconfig does not map — the generated file must use relative
|
|
92
|
+
// imports.
|
|
93
|
+
const resolvedNoExt = await resolveRouteModuleNoExt(componentPath);
|
|
94
|
+
if (!resolvedNoExt) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const relImport = normalizeRelativeImport(
|
|
99
|
+
path.relative(outDir, resolvedNoExt),
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const componentName = `component_${componentIndex++}`;
|
|
103
|
+
imports.push(`import ${componentName} from ${quote(relImport)};`);
|
|
104
|
+
return componentName;
|
|
105
|
+
})();
|
|
106
|
+
componentImportMap.set(componentPath, pendingImportName);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return pendingImportName;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const resolveRouteModuleNoExt = async (aliasedNoExtPath: string) => {
|
|
113
|
+
const prefix = `${appContext.internalSrcAlias}/`;
|
|
114
|
+
let absNoExt: string;
|
|
115
|
+
if (aliasedNoExtPath.startsWith(prefix)) {
|
|
116
|
+
const rel = aliasedNoExtPath.slice(prefix.length);
|
|
117
|
+
absNoExt = path.join(appContext.srcDirectory, rel);
|
|
118
|
+
} else if (path.isAbsolute(aliasedNoExtPath)) {
|
|
119
|
+
absNoExt = aliasedNoExtPath;
|
|
120
|
+
} else {
|
|
121
|
+
// Unknown format; treat as already relative to src.
|
|
122
|
+
absNoExt = path.join(appContext.srcDirectory, aliasedNoExtPath);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return resolveFileNoExt(absNoExt);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const getImportNamesForLoader = async (
|
|
129
|
+
aliasedNoExtPath: string,
|
|
130
|
+
inline: boolean,
|
|
131
|
+
hasAction: boolean,
|
|
132
|
+
) => {
|
|
133
|
+
const key = `${
|
|
134
|
+
inline ? 'inline' : 'default'
|
|
135
|
+
}:${hasAction ? 'action' : 'loader'}:${aliasedNoExtPath}`;
|
|
136
|
+
const existing = loaderImportMap.get(key);
|
|
137
|
+
if (existing) {
|
|
138
|
+
return {
|
|
139
|
+
loaderName: existing,
|
|
140
|
+
actionName: hasAction ? existing.replace(/^loader_/, 'action_') : null,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
|
|
145
|
+
if (!resolvedNoExt) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const relImport = normalizeRelativeImport(
|
|
150
|
+
path.relative(outDir, resolvedNoExt),
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const importName = `loader_${loaderIndex++}`;
|
|
154
|
+
const actionName = hasAction
|
|
155
|
+
? importName.replace(/^loader_/, 'action_')
|
|
156
|
+
: null;
|
|
157
|
+
if (inline) {
|
|
158
|
+
const specifiers = [`loader as ${importName}`];
|
|
159
|
+
if (actionName) {
|
|
160
|
+
specifiers.push(`action as ${actionName}`);
|
|
161
|
+
}
|
|
162
|
+
imports.push(
|
|
163
|
+
`import { ${specifiers.join(', ')} } from ${quote(relImport)};`,
|
|
164
|
+
);
|
|
165
|
+
} else {
|
|
166
|
+
imports.push(`import ${importName} from ${quote(relImport)};`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
loaderImportMap.set(key, importName);
|
|
170
|
+
return { loaderName: importName, actionName };
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const getImportNameForSearchContract = async (
|
|
174
|
+
aliasedNoExtPath: string,
|
|
175
|
+
exportName: 'validateSearch' | 'loaderDeps',
|
|
176
|
+
) => {
|
|
177
|
+
const key = `${exportName}:${aliasedNoExtPath}`;
|
|
178
|
+
const existing = searchContractImportMap.get(key);
|
|
179
|
+
if (existing) {
|
|
180
|
+
return existing;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
|
|
184
|
+
if (!resolvedNoExt) {
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const relImport = normalizeRelativeImport(
|
|
189
|
+
path.relative(outDir, resolvedNoExt),
|
|
190
|
+
);
|
|
191
|
+
const importName =
|
|
192
|
+
exportName === 'validateSearch'
|
|
193
|
+
? `validateSearch_${validateSearchIndex++}`
|
|
194
|
+
: `loaderDeps_${loaderDepsIndex++}`;
|
|
195
|
+
imports.push(
|
|
196
|
+
`import { ${exportName} as ${importName} } from ${quote(relImport)};`,
|
|
197
|
+
);
|
|
198
|
+
searchContractImportMap.set(key, importName);
|
|
199
|
+
return importName;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
const reserveRouteVarName = (preferred: string) => {
|
|
203
|
+
let candidate = preferred;
|
|
204
|
+
let suffix = 1;
|
|
205
|
+
while (usedRouteVarNames.has(candidate)) {
|
|
206
|
+
candidate = `${preferred}_${suffix++}`;
|
|
207
|
+
}
|
|
208
|
+
usedRouteVarNames.add(candidate);
|
|
209
|
+
return candidate;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const createRouteVarName = (route: NestedRouteForCli | PageRoute) => {
|
|
213
|
+
const id = (route as RouteExtras).id;
|
|
214
|
+
const base = id ? makeLegalIdentifier(id) : `r_${routeIndex++}`;
|
|
215
|
+
return reserveRouteVarName(`route_${base}`);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const buildRoute = async (opts: {
|
|
219
|
+
parentVar: string;
|
|
220
|
+
route: NestedRouteForCli | PageRoute;
|
|
221
|
+
}): Promise<string> => {
|
|
222
|
+
const { parentVar, route } = opts;
|
|
223
|
+
|
|
224
|
+
const varName = createRouteVarName(route);
|
|
225
|
+
const routeExtras = route as RouteExtras;
|
|
226
|
+
|
|
227
|
+
const loaderInfo = pickModernLoaderModule(route);
|
|
228
|
+
const routeAction = routeExtras.action;
|
|
229
|
+
const loaderImports = loaderInfo
|
|
230
|
+
? await getImportNamesForLoader(
|
|
231
|
+
loaderInfo.loaderPath,
|
|
232
|
+
loaderInfo.inline,
|
|
233
|
+
Boolean(loaderInfo.inline && routeAction === loaderInfo.loaderPath),
|
|
234
|
+
)
|
|
235
|
+
: null;
|
|
236
|
+
const loaderName = loaderImports?.loaderName || null;
|
|
237
|
+
const actionName = loaderImports?.actionName || null;
|
|
238
|
+
const searchContractInfo = pickRouteSearchContractModules(route);
|
|
239
|
+
const validateSearchName = searchContractInfo.validateSearchPath
|
|
240
|
+
? await getImportNameForSearchContract(
|
|
241
|
+
searchContractInfo.validateSearchPath,
|
|
242
|
+
'validateSearch',
|
|
243
|
+
)
|
|
244
|
+
: null;
|
|
245
|
+
const loaderDepsName = searchContractInfo.loaderDepsPath
|
|
246
|
+
? await getImportNameForSearchContract(
|
|
247
|
+
searchContractInfo.loaderDepsPath,
|
|
248
|
+
'loaderDeps',
|
|
249
|
+
)
|
|
250
|
+
: null;
|
|
251
|
+
|
|
252
|
+
const rawPath = routeExtras.path;
|
|
253
|
+
const hasSplat = typeof rawPath === 'string' && rawPath.includes('*');
|
|
254
|
+
|
|
255
|
+
const routeOpts: string[] = [`getParentRoute: () => ${parentVar},`];
|
|
256
|
+
|
|
257
|
+
const componentName = await getImportNameForComponent(
|
|
258
|
+
routeExtras._component,
|
|
259
|
+
);
|
|
260
|
+
if (componentName) {
|
|
261
|
+
routeOpts.push(`component: ${componentName},`);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (isPathlessLayout(route)) {
|
|
265
|
+
const id = routeExtras.id;
|
|
266
|
+
routeOpts.push(`id: ${quote(id || 'pathless')},`);
|
|
267
|
+
} else {
|
|
268
|
+
const p = isIndexRoute(route) ? '/' : toTanstackPath(rawPath || '');
|
|
269
|
+
routeOpts.push(`path: ${quote(p)},`);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (loaderName) {
|
|
273
|
+
routeOpts.push(
|
|
274
|
+
`loader: modernLoaderToTanstack({ hasSplat: ${hasSplat} }, ${loaderName}),`,
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
if (validateSearchName) {
|
|
278
|
+
routeOpts.push(`validateSearch: ${validateSearchName},`);
|
|
279
|
+
}
|
|
280
|
+
if (loaderDepsName) {
|
|
281
|
+
routeOpts.push(`loaderDeps: ${loaderDepsName},`);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const staticDataSnippet = createRouteStaticDataSnippet({
|
|
285
|
+
modernRouteId: routeExtras.id,
|
|
286
|
+
loaderName,
|
|
287
|
+
actionName,
|
|
288
|
+
});
|
|
289
|
+
if (staticDataSnippet) {
|
|
290
|
+
routeOpts.push(staticDataSnippet);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const children = routeExtras.children;
|
|
294
|
+
const hasChildren = Boolean(children && children.length > 0);
|
|
295
|
+
const routeCtorVarName = hasChildren
|
|
296
|
+
? reserveRouteVarName(`${varName}__base`)
|
|
297
|
+
: varName;
|
|
298
|
+
|
|
299
|
+
statements.push(
|
|
300
|
+
`const ${routeCtorVarName} = createRoute({\n ${routeOpts.join('\n ')}\n});`,
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
if (children && children.length > 0) {
|
|
304
|
+
const childVars: string[] = [];
|
|
305
|
+
for (const child of children) {
|
|
306
|
+
childVars.push(
|
|
307
|
+
await buildRoute({ parentVar: routeCtorVarName, route: child }),
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
statements.push(
|
|
311
|
+
`const ${varName} = ${routeCtorVarName}.addChildren([${childVars.join(', ')}]);`,
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return varName;
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const rootLoaderInfo = rootModern ? pickModernLoaderModule(rootModern) : null;
|
|
319
|
+
const rootAction = rootExtras?.action;
|
|
320
|
+
const rootLoaderImports = rootLoaderInfo?.loaderPath
|
|
321
|
+
? await getImportNamesForLoader(
|
|
322
|
+
rootLoaderInfo.loaderPath,
|
|
323
|
+
rootLoaderInfo.inline,
|
|
324
|
+
Boolean(
|
|
325
|
+
rootLoaderInfo.inline && rootAction === rootLoaderInfo.loaderPath,
|
|
326
|
+
),
|
|
327
|
+
)
|
|
328
|
+
: null;
|
|
329
|
+
const rootLoaderName = rootLoaderImports?.loaderName || null;
|
|
330
|
+
const rootActionName = rootLoaderImports?.actionName || null;
|
|
331
|
+
const rootSearchContractInfo = rootModern
|
|
332
|
+
? pickRouteSearchContractModules(rootModern)
|
|
333
|
+
: null;
|
|
334
|
+
const rootValidateSearchName = rootSearchContractInfo?.validateSearchPath
|
|
335
|
+
? await getImportNameForSearchContract(
|
|
336
|
+
rootSearchContractInfo.validateSearchPath,
|
|
337
|
+
'validateSearch',
|
|
338
|
+
)
|
|
339
|
+
: null;
|
|
340
|
+
const rootLoaderDepsName = rootSearchContractInfo?.loaderDepsPath
|
|
341
|
+
? await getImportNameForSearchContract(
|
|
342
|
+
rootSearchContractInfo.loaderDepsPath,
|
|
343
|
+
'loaderDeps',
|
|
344
|
+
)
|
|
345
|
+
: null;
|
|
346
|
+
|
|
347
|
+
const topLevelVars: string[] = [];
|
|
348
|
+
for (const route of topLevel) {
|
|
349
|
+
topLevelVars.push(await buildRoute({ parentVar: 'rootRoute', route }));
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const rootOpts: string[] = [];
|
|
353
|
+
|
|
354
|
+
const rootComponentName = await getImportNameForComponent(
|
|
355
|
+
rootExtras?._component,
|
|
356
|
+
);
|
|
357
|
+
if (rootComponentName) {
|
|
358
|
+
rootOpts.push(`component: ${rootComponentName},`);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (rootLoaderName) {
|
|
362
|
+
rootOpts.push(
|
|
363
|
+
`loader: modernLoaderToTanstack({ hasSplat: false }, ${rootLoaderName}),`,
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
if (rootValidateSearchName) {
|
|
367
|
+
rootOpts.push(`validateSearch: ${rootValidateSearchName},`);
|
|
368
|
+
}
|
|
369
|
+
if (rootLoaderDepsName) {
|
|
370
|
+
rootOpts.push(`loaderDeps: ${rootLoaderDepsName},`);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const routerGenTs = `// This file is auto-generated by Modern.js. Do not edit manually.
|
|
374
|
+
|
|
375
|
+
import {
|
|
376
|
+
createMemoryHistory,
|
|
377
|
+
createRootRouteWithContext,
|
|
378
|
+
createRoute,
|
|
379
|
+
createRouter,
|
|
380
|
+
createRouteStaticData,
|
|
381
|
+
type ModernRouterContext,
|
|
382
|
+
modernLoaderToTanstack,
|
|
383
|
+
modernTanstackRouterFastDefaults,
|
|
384
|
+
} from '@modern-js/plugin-tanstack/runtime';
|
|
385
|
+
|
|
386
|
+
${imports.join('\n')}
|
|
387
|
+
|
|
388
|
+
export const rootRoute = createRootRouteWithContext<ModernRouterContext>()({
|
|
389
|
+
${rootOpts.join('\n ')}
|
|
390
|
+
${
|
|
391
|
+
createRouteStaticDataSnippet({
|
|
392
|
+
modernRouteId: rootExtras?.id,
|
|
393
|
+
loaderName: rootLoaderName,
|
|
394
|
+
actionName: rootActionName,
|
|
395
|
+
}) || ''
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
${statements.join('\n\n')}
|
|
400
|
+
|
|
401
|
+
export const routeTree = rootRoute.addChildren([${topLevelVars.join(', ')}]);
|
|
402
|
+
|
|
403
|
+
export const router = createRouter({
|
|
404
|
+
...modernTanstackRouterFastDefaults,
|
|
405
|
+
routeTree,
|
|
406
|
+
history: createMemoryHistory({
|
|
407
|
+
initialEntries: ['/'],
|
|
408
|
+
}),
|
|
409
|
+
context: {} as ModernRouterContext,
|
|
410
|
+
});
|
|
411
|
+
`;
|
|
412
|
+
|
|
413
|
+
return { routerGenTs };
|
|
414
|
+
}
|