@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.12 → 3.2.0-ultramodern.121
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 +89 -31
- package/dist/cjs/cli/routeSplitting.js +55 -0
- package/dist/cjs/cli/tanstackTypes.js +172 -170
- 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 +48 -0
- package/dist/cjs/runtime/index.js +79 -35
- 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 +195 -114
- package/dist/cjs/runtime/plugin.node.js +45 -45
- package/dist/cjs/runtime/plugin.worker.js +53 -0
- 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 +74 -207
- 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 +31 -1
- package/dist/cjs/runtime/utils.js +9 -10
- package/dist/cjs/runtime.js +9 -5
- package/dist/esm/cli/index.mjs +75 -27
- package/dist/esm/cli/routeSplitting.mjs +14 -0
- package/dist/esm/cli/tanstackTypes.mjs +158 -160
- package/dist/esm/runtime/hooks.mjs +1 -8
- package/dist/esm/runtime/hydrationBoundary.mjs +10 -0
- package/dist/esm/runtime/index.mjs +5 -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 +191 -114
- package/dist/esm/runtime/plugin.node.mjs +40 -44
- package/dist/esm/runtime/plugin.worker.mjs +1 -0
- 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 +59 -193
- 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/types.mjs +7 -0
- package/dist/esm/runtime/utils.mjs +0 -5
- package/dist/esm-node/cli/index.mjs +75 -27
- package/dist/esm-node/cli/routeSplitting.mjs +15 -0
- package/dist/esm-node/cli/tanstackTypes.mjs +158 -160
- package/dist/esm-node/runtime/hooks.mjs +1 -8
- package/dist/esm-node/runtime/hydrationBoundary.mjs +11 -0
- package/dist/esm-node/runtime/index.mjs +5 -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 +191 -114
- package/dist/esm-node/runtime/plugin.node.mjs +40 -44
- package/dist/esm-node/runtime/plugin.worker.mjs +2 -0
- 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 +59 -193
- 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/types.mjs +7 -0
- package/dist/esm-node/runtime/utils.mjs +0 -5
- package/dist/types/cli/index.d.ts +14 -1
- package/dist/types/cli/routeSplitting.d.ts +20 -0
- package/dist/types/cli/tanstackTypes.d.ts +21 -1
- package/dist/types/runtime/hooks.d.ts +8 -33
- package/dist/types/runtime/hydrationBoundary.d.ts +2 -0
- package/dist/types/runtime/index.d.ts +8 -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 +2 -15
- package/dist/types/runtime/plugin.node.d.ts +2 -15
- package/dist/types/runtime/plugin.worker.d.ts +1 -0
- 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 +14 -53
- package/package.json +42 -40
- package/rstest.config.mts +6 -0
- package/src/cli/index.ts +162 -23
- package/src/cli/routeSplitting.ts +43 -0
- package/src/cli/tanstackTypes.ts +331 -187
- package/src/runtime/hooks.ts +10 -27
- package/src/runtime/hydrationBoundary.tsx +12 -0
- package/src/runtime/index.tsx +17 -7
- 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 +72 -85
- package/src/runtime/plugin.tsx +361 -206
- package/src/runtime/plugin.worker.tsx +4 -0
- 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 +163 -354
- 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 +32 -66
- package/src/runtime/utils.tsx +3 -6
- package/tests/router/cli.test.ts +586 -5
- package/tests/router/fastDefaults.test.ts +25 -0
- package/tests/router/hooks.test.ts +26 -0
- package/tests/router/hydrationBoundary.test.tsx +23 -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 +381 -81
- package/tests/router/rsc.test.tsx +70 -0
- package/tests/router/tanstackTypes.test.ts +573 -1
- 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,13 +1,14 @@
|
|
|
1
1
|
import "node:module";
|
|
2
2
|
import node_path from "node:path";
|
|
3
3
|
import { NESTED_ROUTE_SPEC_FILE, filterRoutesForServer, fs } from "@modern-js/utils";
|
|
4
|
-
import {
|
|
4
|
+
import { createTanstackRsbuildRouteSplittingProfile, resolveTanstackRouteCodeSplittingEnabled } from "./routeSplitting.mjs";
|
|
5
|
+
import { collectCanonicalRoutesForEntry, generateTanstackRouterTypesSourceForEntry } from "./tanstackTypes.mjs";
|
|
5
6
|
import { __webpack_require__ } from "../rslib-runtime.mjs";
|
|
6
7
|
import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
|
|
7
8
|
import { dirname as __rspack_dirname } from "node:path";
|
|
8
9
|
import * as __rspack_external__modern_js_runtime_cli_401ee077 from "@modern-js/runtime/cli";
|
|
9
10
|
__webpack_require__.add({
|
|
10
|
-
"@modern-js/runtime/cli" (module) {
|
|
11
|
+
"@modern-js/runtime/cli?9b14" (module) {
|
|
11
12
|
module.exports = __rspack_external__modern_js_runtime_cli_401ee077;
|
|
12
13
|
}
|
|
13
14
|
});
|
|
@@ -18,8 +19,8 @@ const ENTRYPOINTS_KEY = '@modern-js/plugin-tanstack';
|
|
|
18
19
|
let runtimeRouterCli;
|
|
19
20
|
function getRuntimeRouterCli() {
|
|
20
21
|
if (runtimeRouterCli) return runtimeRouterCli;
|
|
21
|
-
const cli = __webpack_require__("@modern-js/runtime/cli");
|
|
22
|
-
if (cli.handleGeneratorEntryCode && cli.getEntrypointRoutesDir) {
|
|
22
|
+
const cli = __webpack_require__("@modern-js/runtime/cli?9b14");
|
|
23
|
+
if (cli.handleGeneratorEntryCode && cli.getEntrypointRoutesDir && cli.getEntrypointRoutesOwner) {
|
|
23
24
|
runtimeRouterCli = cli;
|
|
24
25
|
return runtimeRouterCli;
|
|
25
26
|
}
|
|
@@ -35,6 +36,14 @@ async function writeFileIfChanged(filePath, content) {
|
|
|
35
36
|
function createRegisterDtsContent(opts) {
|
|
36
37
|
const importStatements = opts.entries.map((entryName, index)=>`import type { router as router${index} } from './${entryName}/router.gen';`).join('\n');
|
|
37
38
|
const routerUnionType = opts.entries.map((_, index)=>`typeof router${index}`).join(' | ');
|
|
39
|
+
const canonicalEntries = Object.entries(opts.canonicalRoutes ?? {});
|
|
40
|
+
const canonicalRoutesAugmentation = canonicalEntries.length > 0 ? `
|
|
41
|
+
declare module '${opts.i18nRuntimeModule || '@modern-js/plugin-i18n/runtime'}' {
|
|
42
|
+
interface UltramodernCanonicalRoutes {
|
|
43
|
+
${canonicalEntries.map(([routePath, paramsType])=>` '${routePath}': ${paramsType};`).join('\n')}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
` : '';
|
|
38
47
|
return `// This file is auto-generated by Modern.js. Do not edit manually.
|
|
39
48
|
|
|
40
49
|
${importStatements}
|
|
@@ -44,19 +53,21 @@ declare module '${opts.runtimeModule}' {
|
|
|
44
53
|
router: ${routerUnionType};
|
|
45
54
|
}
|
|
46
55
|
}
|
|
47
|
-
`;
|
|
56
|
+
${canonicalRoutesAugmentation}`;
|
|
48
57
|
}
|
|
49
58
|
async function writeTanstackRegisterFile(opts) {
|
|
50
|
-
const { entries, generatedDirName = DEFAULT_GENERATED_DIR_NAME, runtimeModule = '@modern-js/plugin-tanstack/runtime', srcDirectory } = opts;
|
|
59
|
+
const { entries, generatedDirName = DEFAULT_GENERATED_DIR_NAME, runtimeModule = '@modern-js/plugin-tanstack/runtime', srcDirectory, canonicalRoutes, i18nRuntimeModule } = opts;
|
|
51
60
|
if (0 === entries.length) return;
|
|
52
61
|
const registerDtsPath = node_path.join(srcDirectory, generatedDirName, 'register.gen.d.ts');
|
|
53
62
|
await writeFileIfChanged(registerDtsPath, createRegisterDtsContent({
|
|
54
63
|
entries,
|
|
55
|
-
runtimeModule
|
|
64
|
+
runtimeModule,
|
|
65
|
+
canonicalRoutes,
|
|
66
|
+
i18nRuntimeModule
|
|
56
67
|
}));
|
|
57
68
|
}
|
|
58
69
|
async function writeTanstackRouterTypesForEntries(opts) {
|
|
59
|
-
const { appContext, generatedDirName = DEFAULT_GENERATED_DIR_NAME, routesByEntry } = opts;
|
|
70
|
+
const { appContext, generatedDirName = DEFAULT_GENERATED_DIR_NAME, routesByEntry, i18nPluginInstalled = false } = opts;
|
|
60
71
|
const entryNames = Object.keys(routesByEntry);
|
|
61
72
|
await Promise.all(entryNames.map(async (entryName)=>{
|
|
62
73
|
const { routerGenTs } = await generateTanstackRouterTypesSourceForEntry({
|
|
@@ -73,15 +84,27 @@ async function writeTanstackRouterTypesForEntries(opts) {
|
|
|
73
84
|
if (mainEntryName && b === mainEntryName) return 1;
|
|
74
85
|
return a.localeCompare(b);
|
|
75
86
|
});
|
|
87
|
+
let canonicalRoutes = null;
|
|
88
|
+
if (i18nPluginInstalled) for (const entryName of registerEntries){
|
|
89
|
+
const entryCanonicalRoutes = collectCanonicalRoutesForEntry(routesByEntry[entryName], {
|
|
90
|
+
localeParamHeuristic: true
|
|
91
|
+
});
|
|
92
|
+
if (entryCanonicalRoutes) canonicalRoutes = {
|
|
93
|
+
...entryCanonicalRoutes,
|
|
94
|
+
...canonicalRoutes ?? {}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
76
97
|
await writeTanstackRegisterFile({
|
|
77
98
|
entries: registerEntries,
|
|
78
99
|
generatedDirName,
|
|
79
|
-
srcDirectory: appContext.srcDirectory
|
|
100
|
+
srcDirectory: appContext.srcDirectory,
|
|
101
|
+
canonicalRoutes
|
|
80
102
|
});
|
|
81
103
|
}
|
|
82
104
|
function tanstackRouterPlugin(options = {}) {
|
|
83
105
|
const routesDir = options.routesDir || DEFAULT_ROUTES_DIR;
|
|
84
106
|
const generatedDirName = options.generatedDirName || DEFAULT_GENERATED_DIR_NAME;
|
|
107
|
+
const routeSplittingProfile = createTanstackRsbuildRouteSplittingProfile(options);
|
|
85
108
|
return {
|
|
86
109
|
name: '@modern-js/plugin-tanstack',
|
|
87
110
|
required: [
|
|
@@ -93,16 +116,42 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
93
116
|
const { getEntrypointRoutesDir } = getRuntimeRouterCli();
|
|
94
117
|
return getEntrypointRoutesDir(entrypoint) === routesDir;
|
|
95
118
|
};
|
|
119
|
+
const isForeignRouteEntrypoint = (entrypoint)=>{
|
|
120
|
+
const { getEntrypointRoutesDir, getEntrypointRoutesOwner } = getRuntimeRouterCli();
|
|
121
|
+
if (getEntrypointRoutesOwner(entrypoint)) return true;
|
|
122
|
+
if (entrypoint.pageRoutesEntry) return true;
|
|
123
|
+
return null !== getEntrypointRoutesDir(entrypoint);
|
|
124
|
+
};
|
|
125
|
+
const isI18nPluginInstalled = ()=>{
|
|
126
|
+
const { plugins } = api.getAppContext();
|
|
127
|
+
return Boolean(plugins?.some((plugin)=>plugin?.name === '@modern-js/plugin-i18n'));
|
|
128
|
+
};
|
|
96
129
|
api._internalRuntimePlugins(({ entrypoint, plugins })=>{
|
|
97
|
-
|
|
130
|
+
const { metaName, serverRoutes } = api.getAppContext();
|
|
131
|
+
const serverBase = serverRoutes.filter((route)=>route.entryName === entrypoint.entryName).map((route)=>route.urlPath).sort((a, b)=>a.length - b.length > 0 ? -1 : 1);
|
|
132
|
+
if (isTanstackEntrypoint(entrypoint)) {
|
|
133
|
+
plugins.push({
|
|
134
|
+
name: 'tanstackRouter',
|
|
135
|
+
path: `@${metaName}/plugin-tanstack/runtime`,
|
|
136
|
+
config: {
|
|
137
|
+
serverBase
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
return {
|
|
141
|
+
entrypoint,
|
|
142
|
+
plugins
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (isForeignRouteEntrypoint(entrypoint)) return {
|
|
98
146
|
entrypoint,
|
|
99
147
|
plugins
|
|
100
148
|
};
|
|
101
|
-
const {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
149
|
+
const routerWrapperPath = `@${metaName}/plugin-tanstack/runtime/router`;
|
|
150
|
+
const existingRouterPlugin = plugins.find((plugin)=>'router' === plugin.name);
|
|
151
|
+
if (existingRouterPlugin) existingRouterPlugin.path = routerWrapperPath;
|
|
152
|
+
else plugins.push({
|
|
153
|
+
name: 'router',
|
|
154
|
+
path: routerWrapperPath,
|
|
106
155
|
config: {
|
|
107
156
|
serverBase
|
|
108
157
|
}
|
|
@@ -117,10 +166,13 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
117
166
|
entry: entry || getRuntimeRouterCli().isRouteEntry(entryPath, routesDir)
|
|
118
167
|
}));
|
|
119
168
|
api.config(()=>({
|
|
169
|
+
...routeSplittingProfile.defaultConfig,
|
|
120
170
|
source: {
|
|
121
171
|
include: [
|
|
122
172
|
/[\\/]node_modules[\\/]@tanstack[\\/]react-router[\\/]/,
|
|
123
|
-
|
|
173
|
+
/[\\/]node_modules[\\/]@tanstack[\\/]router-core[\\/]/,
|
|
174
|
+
/[\\/]node_modules[\\/]@tanstack[\\/]react-store[\\/]/,
|
|
175
|
+
node_path.resolve(cli_dirname, '..', '..')
|
|
124
176
|
]
|
|
125
177
|
}
|
|
126
178
|
}));
|
|
@@ -137,15 +189,13 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
137
189
|
if (0 === tanstackEntrypoints.length) return;
|
|
138
190
|
const { handleGeneratorEntryCode } = getRuntimeRouterCli();
|
|
139
191
|
const routesByEntry = await handleGeneratorEntryCode(api, tanstackEntrypoints, {
|
|
140
|
-
entrypointsKey: ENTRYPOINTS_KEY
|
|
141
|
-
generateCodeOptions: {
|
|
142
|
-
enableTanstackTypes: false
|
|
143
|
-
}
|
|
192
|
+
entrypointsKey: ENTRYPOINTS_KEY
|
|
144
193
|
});
|
|
145
194
|
await writeTanstackRouterTypesForEntries({
|
|
146
195
|
appContext: api.getAppContext(),
|
|
147
196
|
generatedDirName,
|
|
148
|
-
routesByEntry
|
|
197
|
+
routesByEntry,
|
|
198
|
+
i18nPluginInstalled: isI18nPluginInstalled()
|
|
149
199
|
});
|
|
150
200
|
});
|
|
151
201
|
api.onFileChanged(async (event)=>{
|
|
@@ -159,15 +209,13 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
159
209
|
regenerate: async ({ api, entrypoints })=>{
|
|
160
210
|
const { handleGeneratorEntryCode } = getRuntimeRouterCli();
|
|
161
211
|
const routesByEntry = await handleGeneratorEntryCode(api, entrypoints, {
|
|
162
|
-
entrypointsKey: ENTRYPOINTS_KEY
|
|
163
|
-
generateCodeOptions: {
|
|
164
|
-
enableTanstackTypes: false
|
|
165
|
-
}
|
|
212
|
+
entrypointsKey: ENTRYPOINTS_KEY
|
|
166
213
|
});
|
|
167
214
|
await writeTanstackRouterTypesForEntries({
|
|
168
215
|
appContext: api.getAppContext(),
|
|
169
216
|
generatedDirName,
|
|
170
|
-
routesByEntry
|
|
217
|
+
routesByEntry,
|
|
218
|
+
i18nPluginInstalled: isI18nPluginInstalled()
|
|
171
219
|
});
|
|
172
220
|
}
|
|
173
221
|
});
|
|
@@ -199,4 +247,4 @@ function tanstackRouterPlugin(options = {}) {
|
|
|
199
247
|
}
|
|
200
248
|
const src_cli = tanstackRouterPlugin;
|
|
201
249
|
export default src_cli;
|
|
202
|
-
export { generateTanstackRouterTypesSourceForEntry,
|
|
250
|
+
export { collectCanonicalRoutesForEntry, createTanstackRsbuildRouteSplittingProfile, generateTanstackRouterTypesSourceForEntry, resolveTanstackRouteCodeSplittingEnabled, tanstackRouterPlugin, writeTanstackRegisterFile, writeTanstackRouterTypesForEntries };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import "node:module";
|
|
2
|
+
function resolveTanstackRouteCodeSplittingEnabled(option) {
|
|
3
|
+
if ('boolean' == typeof option) return option;
|
|
4
|
+
return option?.enabled ?? true;
|
|
5
|
+
}
|
|
6
|
+
function createTanstackRsbuildRouteSplittingProfile(opts) {
|
|
7
|
+
return {
|
|
8
|
+
defaultConfig: {
|
|
9
|
+
output: {
|
|
10
|
+
splitRouteChunks: resolveTanstackRouteCodeSplittingEnabled(opts.routeCodeSplitting)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export { createTanstackRsbuildRouteSplittingProfile, resolveTanstackRouteCodeSplittingEnabled };
|
|
@@ -1,18 +1,7 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
import {
|
|
2
|
+
import { getPathWithoutExt, makeLegalIdentifier } from "@modern-js/runtime/cli";
|
|
3
|
+
import { findExists, formatImportPath, slash } from "@modern-js/utils";
|
|
3
4
|
import path from "path";
|
|
4
|
-
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';
|
|
5
|
-
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';
|
|
6
|
-
const forbidList = new Set(`${reservedWords} ${builtins}`.split(' '));
|
|
7
|
-
function makeLegalIdentifier(str) {
|
|
8
|
-
const identifier = str.replace(/-(\w)/g, (_, letter)=>letter.toUpperCase()).replace(/[^$_a-zA-Z0-9]/g, '_');
|
|
9
|
-
if (/\d/.test(identifier[0]) || forbidList.has(identifier)) return `_${identifier}`;
|
|
10
|
-
return identifier || '_';
|
|
11
|
-
}
|
|
12
|
-
function getPathWithoutExt(filename) {
|
|
13
|
-
const extname = path.extname(filename);
|
|
14
|
-
return extname ? filename.slice(0, -extname.length) : filename;
|
|
15
|
-
}
|
|
16
5
|
const JS_OR_TS_EXTS = [
|
|
17
6
|
'.js',
|
|
18
7
|
'.jsx',
|
|
@@ -56,6 +45,14 @@ function pickModernLoaderModule(route) {
|
|
|
56
45
|
inline
|
|
57
46
|
};
|
|
58
47
|
}
|
|
48
|
+
function pickRouteSearchContractModules(route) {
|
|
49
|
+
const validateSearchPath = route.validateSearch;
|
|
50
|
+
const loaderDepsPath = route.loaderDeps;
|
|
51
|
+
return {
|
|
52
|
+
validateSearchPath: 'string' == typeof validateSearchPath ? validateSearchPath : null,
|
|
53
|
+
loaderDepsPath: 'string' == typeof loaderDepsPath ? loaderDepsPath : null
|
|
54
|
+
};
|
|
55
|
+
}
|
|
59
56
|
function isPathlessLayout(route) {
|
|
60
57
|
return 'nested' === route.type && 'boolean' != typeof route.index && void 0 === route.path;
|
|
61
58
|
}
|
|
@@ -70,16 +67,78 @@ function createRouteStaticDataSnippet(opts) {
|
|
|
70
67
|
if (!staticDataLines.length) return null;
|
|
71
68
|
return `staticData: createRouteStaticData({\n ${staticDataLines.join('\n ')}\n }),`;
|
|
72
69
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
70
|
+
const LOCALE_PARAM_SEGMENTS = new Set([
|
|
71
|
+
':lang',
|
|
72
|
+
':locale',
|
|
73
|
+
':language',
|
|
74
|
+
'$lang',
|
|
75
|
+
'$locale',
|
|
76
|
+
'$language'
|
|
77
|
+
]);
|
|
78
|
+
function paramsTypeForCanonicalPath(canonicalPath) {
|
|
79
|
+
const fields = [];
|
|
80
|
+
for (const segment of canonicalPath.split('/'))if (segment) {
|
|
81
|
+
if ('*' === segment || '$' === segment) {
|
|
82
|
+
fields.push("'_splat'?: string");
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (segment.startsWith('{-$') && segment.endsWith('}')) {
|
|
86
|
+
fields.push(`${JSON.stringify(segment.slice(3, -1))}?: string`);
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (segment.startsWith('$')) {
|
|
90
|
+
fields.push(`${JSON.stringify(segment.slice(1))}: string`);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (segment.startsWith(':')) {
|
|
94
|
+
const optional = segment.endsWith('?');
|
|
95
|
+
const name = segment.slice(1, optional ? void 0 : segment.length);
|
|
96
|
+
fields.push(`${JSON.stringify(optional ? name.slice(0, -1) : name)}${optional ? '?' : ''}: string`);
|
|
97
|
+
}
|
|
82
98
|
}
|
|
99
|
+
return fields.length > 0 ? `{ ${fields.join('; ')} }` : 'Record<string, never>';
|
|
100
|
+
}
|
|
101
|
+
function collectCanonicalRoutesForEntry(routes, options = {}) {
|
|
102
|
+
const { localeParamHeuristic = true } = options;
|
|
103
|
+
const canonicalParams = new Map();
|
|
104
|
+
let hasI18nSurface = false;
|
|
105
|
+
const normalizeJoined = (joined)=>{
|
|
106
|
+
const collapsed = joined.replace(/\/+/g, '/');
|
|
107
|
+
const withLeading = collapsed.startsWith('/') ? collapsed : `/${collapsed}`;
|
|
108
|
+
return withLeading.length > 1 ? withLeading.replace(/\/+$/, '') : withLeading;
|
|
109
|
+
};
|
|
110
|
+
const record = (canonicalPath)=>{
|
|
111
|
+
const normalized = normalizeJoined(canonicalPath || '/');
|
|
112
|
+
const key = toTanstackPath(normalized);
|
|
113
|
+
if (!canonicalParams.has(key)) canonicalParams.set(key, paramsTypeForCanonicalPath(normalized));
|
|
114
|
+
};
|
|
115
|
+
const visit = (route, parentPath)=>{
|
|
116
|
+
let currentPath = parentPath;
|
|
117
|
+
if ('string' == typeof route.modernCanonicalPath) {
|
|
118
|
+
hasI18nSurface = true;
|
|
119
|
+
currentPath = normalizeJoined(route.modernCanonicalPath);
|
|
120
|
+
} else if ('string' == typeof route.path && route.path.length > 0) {
|
|
121
|
+
const segments = route.path.replace(/\[(.+?)\]/g, ':$1').split('/').filter(Boolean);
|
|
122
|
+
if (localeParamHeuristic && '' === parentPath && LOCALE_PARAM_SEGMENTS.has(segments[0])) {
|
|
123
|
+
hasI18nSurface = true;
|
|
124
|
+
segments.shift();
|
|
125
|
+
}
|
|
126
|
+
currentPath = segments.length ? normalizeJoined(`${parentPath}/${segments.join('/')}`) : parentPath;
|
|
127
|
+
}
|
|
128
|
+
const children = route.children;
|
|
129
|
+
if (children && children.length > 0) {
|
|
130
|
+
for (const child of children)visit(child, currentPath);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
record(currentPath || '/');
|
|
134
|
+
};
|
|
135
|
+
const rootModern = routes.find((route)=>route.isRoot);
|
|
136
|
+
const topLevel = rootModern ? rootModern.children ?? [] : routes;
|
|
137
|
+
for (const route of topLevel)visit(route, '');
|
|
138
|
+
if (!hasI18nSurface || 0 === canonicalParams.size) return null;
|
|
139
|
+
return Object.fromEntries([
|
|
140
|
+
...canonicalParams.entries()
|
|
141
|
+
].sort(([a], [b])=>a.localeCompare(b)));
|
|
83
142
|
}
|
|
84
143
|
async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
85
144
|
const { appContext, entryName, generatedDirName = 'modern-tanstack', routes } = opts;
|
|
@@ -89,8 +148,39 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
89
148
|
const imports = [];
|
|
90
149
|
const statements = [];
|
|
91
150
|
const loaderImportMap = new Map();
|
|
151
|
+
const componentImportMap = new Map();
|
|
152
|
+
const searchContractImportMap = new Map();
|
|
153
|
+
const usedRouteVarNames = new Set();
|
|
92
154
|
let loaderIndex = 0;
|
|
155
|
+
let componentIndex = 0;
|
|
156
|
+
let validateSearchIndex = 0;
|
|
157
|
+
let loaderDepsIndex = 0;
|
|
93
158
|
let routeIndex = 0;
|
|
159
|
+
const getImportNameForComponent = (componentPath)=>{
|
|
160
|
+
if ('string' != typeof componentPath || 0 === componentPath.length) return Promise.resolve(null);
|
|
161
|
+
let pendingImportName = componentImportMap.get(componentPath);
|
|
162
|
+
if (!pendingImportName) {
|
|
163
|
+
pendingImportName = (async ()=>{
|
|
164
|
+
const resolvedNoExt = await resolveRouteModuleNoExt(componentPath);
|
|
165
|
+
if (!resolvedNoExt) return null;
|
|
166
|
+
const relImport = normalizeRelativeImport(path.relative(outDir, resolvedNoExt));
|
|
167
|
+
const componentName = `component_${componentIndex++}`;
|
|
168
|
+
imports.push(`import ${componentName} from ${quote(relImport)};`);
|
|
169
|
+
return componentName;
|
|
170
|
+
})();
|
|
171
|
+
componentImportMap.set(componentPath, pendingImportName);
|
|
172
|
+
}
|
|
173
|
+
return pendingImportName;
|
|
174
|
+
};
|
|
175
|
+
const resolveRouteModuleNoExt = async (aliasedNoExtPath)=>{
|
|
176
|
+
const prefix = `${appContext.internalSrcAlias}/`;
|
|
177
|
+
let absNoExt;
|
|
178
|
+
if (aliasedNoExtPath.startsWith(prefix)) {
|
|
179
|
+
const rel = aliasedNoExtPath.slice(prefix.length);
|
|
180
|
+
absNoExt = path.join(appContext.srcDirectory, rel);
|
|
181
|
+
} else absNoExt = path.isAbsolute(aliasedNoExtPath) ? aliasedNoExtPath : path.join(appContext.srcDirectory, aliasedNoExtPath);
|
|
182
|
+
return resolveFileNoExt(absNoExt);
|
|
183
|
+
};
|
|
94
184
|
const getImportNamesForLoader = async (aliasedNoExtPath, inline, hasAction)=>{
|
|
95
185
|
const key = `${inline ? 'inline' : 'default'}:${hasAction ? 'action' : 'loader'}:${aliasedNoExtPath}`;
|
|
96
186
|
const existing = loaderImportMap.get(key);
|
|
@@ -98,13 +188,7 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
98
188
|
loaderName: existing,
|
|
99
189
|
actionName: hasAction ? existing.replace(/^loader_/, 'action_') : null
|
|
100
190
|
};
|
|
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);
|
|
191
|
+
const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
|
|
108
192
|
if (!resolvedNoExt) return null;
|
|
109
193
|
const relImport = normalizeRelativeImport(path.relative(outDir, resolvedNoExt));
|
|
110
194
|
const importName = `loader_${loaderIndex++}`;
|
|
@@ -122,10 +206,29 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
122
206
|
actionName
|
|
123
207
|
};
|
|
124
208
|
};
|
|
209
|
+
const getImportNameForSearchContract = async (aliasedNoExtPath, exportName)=>{
|
|
210
|
+
const key = `${exportName}:${aliasedNoExtPath}`;
|
|
211
|
+
const existing = searchContractImportMap.get(key);
|
|
212
|
+
if (existing) return existing;
|
|
213
|
+
const resolvedNoExt = await resolveRouteModuleNoExt(aliasedNoExtPath);
|
|
214
|
+
if (!resolvedNoExt) return null;
|
|
215
|
+
const relImport = normalizeRelativeImport(path.relative(outDir, resolvedNoExt));
|
|
216
|
+
const importName = 'validateSearch' === exportName ? `validateSearch_${validateSearchIndex++}` : `loaderDeps_${loaderDepsIndex++}`;
|
|
217
|
+
imports.push(`import { ${exportName} as ${importName} } from ${quote(relImport)};`);
|
|
218
|
+
searchContractImportMap.set(key, importName);
|
|
219
|
+
return importName;
|
|
220
|
+
};
|
|
221
|
+
const reserveRouteVarName = (preferred)=>{
|
|
222
|
+
let candidate = preferred;
|
|
223
|
+
let suffix = 1;
|
|
224
|
+
while(usedRouteVarNames.has(candidate))candidate = `${preferred}_${suffix++}`;
|
|
225
|
+
usedRouteVarNames.add(candidate);
|
|
226
|
+
return candidate;
|
|
227
|
+
};
|
|
125
228
|
const createRouteVarName = (route)=>{
|
|
126
229
|
const id = route.id;
|
|
127
230
|
const base = id ? makeLegalIdentifier(id) : `r_${routeIndex++}`;
|
|
128
|
-
return `route_${base}
|
|
231
|
+
return reserveRouteVarName(`route_${base}`);
|
|
129
232
|
};
|
|
130
233
|
const buildRoute = async (opts)=>{
|
|
131
234
|
const { parentVar, route } = opts;
|
|
@@ -135,11 +238,16 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
135
238
|
const loaderImports = loaderInfo ? await getImportNamesForLoader(loaderInfo.loaderPath, loaderInfo.inline, Boolean(loaderInfo.inline && routeAction === loaderInfo.loaderPath)) : null;
|
|
136
239
|
const loaderName = loaderImports?.loaderName || null;
|
|
137
240
|
const actionName = loaderImports?.actionName || null;
|
|
241
|
+
const searchContractInfo = pickRouteSearchContractModules(route);
|
|
242
|
+
const validateSearchName = searchContractInfo.validateSearchPath ? await getImportNameForSearchContract(searchContractInfo.validateSearchPath, 'validateSearch') : null;
|
|
243
|
+
const loaderDepsName = searchContractInfo.loaderDepsPath ? await getImportNameForSearchContract(searchContractInfo.loaderDepsPath, 'loaderDeps') : null;
|
|
138
244
|
const rawPath = route.path;
|
|
139
245
|
const hasSplat = 'string' == typeof rawPath && rawPath.includes('*');
|
|
140
246
|
const routeOpts = [
|
|
141
247
|
`getParentRoute: () => ${parentVar},`
|
|
142
248
|
];
|
|
249
|
+
const componentName = await getImportNameForComponent(route._component);
|
|
250
|
+
if (componentName) routeOpts.push(`component: ${componentName},`);
|
|
143
251
|
if (isPathlessLayout(route)) {
|
|
144
252
|
const id = route.id;
|
|
145
253
|
routeOpts.push(`id: ${quote(id || 'pathless')},`);
|
|
@@ -148,20 +256,24 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
148
256
|
routeOpts.push(`path: ${quote(p)},`);
|
|
149
257
|
}
|
|
150
258
|
if (loaderName) routeOpts.push(`loader: modernLoaderToTanstack({ hasSplat: ${hasSplat} }, ${loaderName}),`);
|
|
259
|
+
if (validateSearchName) routeOpts.push(`validateSearch: ${validateSearchName},`);
|
|
260
|
+
if (loaderDepsName) routeOpts.push(`loaderDeps: ${loaderDepsName},`);
|
|
151
261
|
const staticDataSnippet = createRouteStaticDataSnippet({
|
|
152
262
|
modernRouteId: route.id,
|
|
153
263
|
loaderName,
|
|
154
264
|
actionName
|
|
155
265
|
});
|
|
156
266
|
if (staticDataSnippet) routeOpts.push(staticDataSnippet);
|
|
157
|
-
statements.push(`const ${varName} = createRoute({\n ${routeOpts.join('\n ')}\n});`);
|
|
158
267
|
const children = route.children;
|
|
268
|
+
const hasChildren = Boolean(children && children.length > 0);
|
|
269
|
+
const routeCtorVarName = hasChildren ? reserveRouteVarName(`${varName}__base`) : varName;
|
|
270
|
+
statements.push(`const ${routeCtorVarName} = createRoute({\n ${routeOpts.join('\n ')}\n});`);
|
|
159
271
|
if (children && children.length > 0) {
|
|
160
272
|
const childVars = await Promise.all(children.map((child)=>buildRoute({
|
|
161
|
-
parentVar:
|
|
273
|
+
parentVar: routeCtorVarName,
|
|
162
274
|
route: child
|
|
163
275
|
})));
|
|
164
|
-
statements.push(
|
|
276
|
+
statements.push(`const ${varName} = ${routeCtorVarName}.addChildren([${childVars.join(', ')}]);`);
|
|
165
277
|
}
|
|
166
278
|
return varName;
|
|
167
279
|
};
|
|
@@ -170,12 +282,19 @@ async function generateTanstackRouterTypesSourceForEntry(opts) {
|
|
|
170
282
|
const rootLoaderImports = rootLoaderInfo?.loaderPath ? await getImportNamesForLoader(rootLoaderInfo.loaderPath, rootLoaderInfo.inline, Boolean(rootLoaderInfo.inline && rootAction === rootLoaderInfo.loaderPath)) : null;
|
|
171
283
|
const rootLoaderName = rootLoaderImports?.loaderName || null;
|
|
172
284
|
const rootActionName = rootLoaderImports?.actionName || null;
|
|
285
|
+
const rootSearchContractInfo = rootModern ? pickRouteSearchContractModules(rootModern) : null;
|
|
286
|
+
const rootValidateSearchName = rootSearchContractInfo?.validateSearchPath ? await getImportNameForSearchContract(rootSearchContractInfo.validateSearchPath, 'validateSearch') : null;
|
|
287
|
+
const rootLoaderDepsName = rootSearchContractInfo?.loaderDepsPath ? await getImportNameForSearchContract(rootSearchContractInfo.loaderDepsPath, 'loaderDeps') : null;
|
|
173
288
|
const topLevelVars = await Promise.all(topLevel.map((route)=>buildRoute({
|
|
174
289
|
parentVar: 'rootRoute',
|
|
175
290
|
route
|
|
176
291
|
})));
|
|
177
292
|
const rootOpts = [];
|
|
293
|
+
const rootComponentName = await getImportNameForComponent(rootModern?._component);
|
|
294
|
+
if (rootComponentName) rootOpts.push(`component: ${rootComponentName},`);
|
|
178
295
|
if (rootLoaderName) rootOpts.push(`loader: modernLoaderToTanstack({ hasSplat: false }, ${rootLoaderName}),`);
|
|
296
|
+
if (rootValidateSearchName) rootOpts.push(`validateSearch: ${rootValidateSearchName},`);
|
|
297
|
+
if (rootLoaderDepsName) rootOpts.push(`loaderDeps: ${rootLoaderDepsName},`);
|
|
179
298
|
const routerGenTs = `/* eslint-disable */
|
|
180
299
|
// This file is auto-generated by Modern.js. Do not edit manually.
|
|
181
300
|
|
|
@@ -184,134 +303,12 @@ import {
|
|
|
184
303
|
createRootRouteWithContext,
|
|
185
304
|
createRoute,
|
|
186
305
|
createRouter,
|
|
187
|
-
|
|
188
|
-
|
|
306
|
+
createRouteStaticData,
|
|
307
|
+
type ModernRouterContext,
|
|
308
|
+
modernLoaderToTanstack,
|
|
309
|
+
modernTanstackRouterFastDefaults,
|
|
189
310
|
} from '@modern-js/plugin-tanstack/runtime';
|
|
190
311
|
|
|
191
|
-
type ModernRouterContext = {
|
|
192
|
-
request?: Request;
|
|
193
|
-
requestContext?: unknown;
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
function isResponse(value: unknown): value is Response {
|
|
197
|
-
return (
|
|
198
|
-
value != null &&
|
|
199
|
-
typeof value === 'object' &&
|
|
200
|
-
typeof (value as any).status === 'number' &&
|
|
201
|
-
typeof (value as any).headers === 'object'
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const redirectStatusCodes = new Set([301, 302, 303, 307, 308]);
|
|
206
|
-
function isRedirectResponse(res: Response) {
|
|
207
|
-
return redirectStatusCodes.has(res.status);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
function throwTanstackRedirect(location: string) {
|
|
211
|
-
const target = location || '/';
|
|
212
|
-
try {
|
|
213
|
-
void new URL(target);
|
|
214
|
-
throw redirect({ href: target });
|
|
215
|
-
} catch {
|
|
216
|
-
throw redirect({ to: target });
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
function mapParamsForModernLoader(params: Record<string, string>, hasSplat: boolean) {
|
|
221
|
-
if (!hasSplat) {
|
|
222
|
-
return params;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const { _splat, ...rest } = params as any;
|
|
226
|
-
if (typeof _splat !== 'undefined') {
|
|
227
|
-
return { ...rest, '*': _splat };
|
|
228
|
-
}
|
|
229
|
-
return rest;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function createRouteStaticData(opts: {
|
|
233
|
-
modernRouteId?: string;
|
|
234
|
-
modernRouteAction?: unknown;
|
|
235
|
-
modernRouteLoader?: unknown;
|
|
236
|
-
}) {
|
|
237
|
-
const staticData: Record<string, unknown> = {};
|
|
238
|
-
|
|
239
|
-
if (opts.modernRouteId) {
|
|
240
|
-
staticData.modernRouteId = opts.modernRouteId;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
if (opts.modernRouteLoader) {
|
|
244
|
-
staticData.modernRouteLoader = opts.modernRouteLoader;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (opts.modernRouteAction) {
|
|
248
|
-
staticData.modernRouteAction = opts.modernRouteAction;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return Object.keys(staticData).length > 0 ? staticData : undefined;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function modernLoaderToTanstack<TLoader extends (args: any) => any>(
|
|
255
|
-
opts: { hasSplat: boolean },
|
|
256
|
-
modernLoader: TLoader,
|
|
257
|
-
) {
|
|
258
|
-
type LoaderResult = Awaited<ReturnType<TLoader>>;
|
|
259
|
-
|
|
260
|
-
return async (ctx: any): Promise<LoaderResult> => {
|
|
261
|
-
try {
|
|
262
|
-
const signal: AbortSignal =
|
|
263
|
-
ctx?.abortController?.signal ||
|
|
264
|
-
ctx?.signal ||
|
|
265
|
-
new AbortController().signal;
|
|
266
|
-
const baseRequest: Request | undefined =
|
|
267
|
-
ctx?.context?.request instanceof Request ? ctx.context.request : undefined;
|
|
268
|
-
|
|
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
|
-
'';
|
|
276
|
-
|
|
277
|
-
const request = baseRequest
|
|
278
|
-
? new Request(baseRequest, { signal })
|
|
279
|
-
: new Request(href, { signal });
|
|
280
|
-
|
|
281
|
-
const params = mapParamsForModernLoader(ctx?.params || {}, opts.hasSplat);
|
|
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
|
-
}
|
|
298
|
-
|
|
299
|
-
return result as LoaderResult;
|
|
300
|
-
} catch (err) {
|
|
301
|
-
if (isResponse(err)) {
|
|
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;
|
|
311
|
-
}
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
|
|
315
312
|
${imports.join('\n')}
|
|
316
313
|
|
|
317
314
|
export const rootRoute = createRootRouteWithContext<ModernRouterContext>()({
|
|
@@ -328,6 +325,7 @@ ${statements.join('\n\n')}
|
|
|
328
325
|
export const routeTree = rootRoute.addChildren([${topLevelVars.join(', ')}]);
|
|
329
326
|
|
|
330
327
|
export const router = createRouter({
|
|
328
|
+
...modernTanstackRouterFastDefaults,
|
|
331
329
|
routeTree,
|
|
332
330
|
history: createMemoryHistory({
|
|
333
331
|
initialEntries: ['/'],
|
|
@@ -339,4 +337,4 @@ export const router = createRouter({
|
|
|
339
337
|
routerGenTs
|
|
340
338
|
};
|
|
341
339
|
}
|
|
342
|
-
export {
|
|
340
|
+
export { collectCanonicalRoutesForEntry, generateTanstackRouterTypesSourceForEntry };
|
|
@@ -1,9 +1,2 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
|
|
3
|
-
const modifyRoutes = createSyncHook();
|
|
4
|
-
const onBeforeCreateRoutes = createSyncHook();
|
|
5
|
-
const onBeforeCreateRouter = createSyncHook();
|
|
6
|
-
const onAfterCreateRouter = createSyncHook();
|
|
7
|
-
const onBeforeHydrateRouter = createSyncHook();
|
|
8
|
-
const onAfterHydrateRouter = createSyncHook();
|
|
9
|
-
export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter };
|
|
2
|
+
export { modifyRoutes, onAfterCreateRouter, onAfterHydrateRouter, onBeforeCreateRouter, onBeforeCreateRoutes, onBeforeHydrateRouter, routerProviderRegistryHooks } from "@modern-js/runtime/context";
|
|
@@ -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 };
|