@bleedingdev/modern-js-plugin-tanstack 3.9.0-ultramodern.3 → 3.9.0-ultramodern.5
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 +9 -0
- package/dist/cjs/cli/tanstackTypes/source.js +3 -1
- package/dist/cjs/runtime/basepathRewrite.js +13 -6
- package/dist/cjs/runtime/lifecycle.js +7 -7
- package/dist/cjs/runtime/plugin.js +1 -1
- package/dist/cjs/runtime/plugin.node.js +5 -1
- package/dist/cjs/runtime/prefetchLink.js +2 -7
- package/dist/cjs/runtime/register.js +2 -2
- package/dist/cjs/runtime/routeTree/construction.js +2 -0
- package/dist/cjs/runtime/router.js +25 -9
- package/dist/cjs/runtime/state.js +2 -2
- package/dist/cjs/runtime/utils.js +2 -0
- package/dist/esm/cli/index.mjs +9 -0
- package/dist/esm/cli/tanstackTypes/source.mjs +3 -1
- package/dist/esm/runtime/basepathRewrite.mjs +10 -3
- package/dist/esm/runtime/lifecycle.mjs +1 -1
- package/dist/esm/runtime/plugin.mjs +1 -1
- package/dist/esm/runtime/plugin.node.mjs +5 -1
- package/dist/esm/runtime/prefetchLink.mjs +1 -6
- package/dist/esm/runtime/register.mjs +1 -1
- package/dist/esm/runtime/routeTree/construction.mjs +2 -0
- package/dist/esm/runtime/router.mjs +27 -11
- package/dist/esm/runtime/state.mjs +1 -1
- package/dist/esm/runtime/utils.mjs +2 -0
- package/dist/esm-node/cli/index.mjs +9 -0
- package/dist/esm-node/cli/tanstackTypes/source.mjs +3 -1
- package/dist/esm-node/runtime/basepathRewrite.mjs +10 -3
- package/dist/esm-node/runtime/lifecycle.mjs +1 -1
- package/dist/esm-node/runtime/plugin.mjs +1 -1
- package/dist/esm-node/runtime/plugin.node.mjs +5 -1
- package/dist/esm-node/runtime/prefetchLink.mjs +1 -6
- package/dist/esm-node/runtime/register.mjs +1 -1
- package/dist/esm-node/runtime/routeTree/construction.mjs +2 -0
- package/dist/esm-node/runtime/router.mjs +27 -11
- package/dist/esm-node/runtime/state.mjs +1 -1
- package/dist/esm-node/runtime/utils.mjs +2 -0
- package/dist/types/runtime/basepathRewrite.d.ts +2 -1
- package/dist/types/runtime/lifecycle.d.ts +9 -2
- package/dist/types/runtime/register.d.ts +1 -1
- package/dist/types/runtime/router.d.ts +2 -13
- package/dist/types/runtime/state.d.ts +1 -1
- package/dist/types/runtime/types.d.ts +2 -1
- package/package.json +12 -9
- package/rstest.config.mts +1 -6
- package/src/cli/index.ts +10 -0
- package/src/cli/tanstackTypes/source.ts +3 -1
- package/src/runtime/basepathRewrite.ts +11 -2
- package/src/runtime/lifecycle.ts +14 -3
- package/src/runtime/plugin.node.tsx +9 -2
- package/src/runtime/plugin.tsx +5 -1
- package/src/runtime/prefetchLink.tsx +1 -23
- package/src/runtime/register.ts +1 -1
- package/src/runtime/routeTree/construction.ts +2 -0
- package/src/runtime/router.ts +25 -40
- package/src/runtime/state.ts +1 -1
- package/src/runtime/types.ts +2 -2
- package/src/runtime/utils.tsx +3 -1
- package/tests/realm-isolation.test.ts +8 -2
- package/tests/router/cli.test.ts +108 -9
- package/tests/router/dataMutation.test.tsx +17 -121
- package/tests/router/flightSerialization.roundtrip.test.tsx +9 -6
- package/tests/router/generateRouteArtifacts.test.ts +69 -29
- package/tests/router/hooks.test.ts +1 -18
- package/tests/router/loaderBridge.test.ts +0 -77
- package/tests/router/localisedIdentity.test.tsx +95 -0
- package/tests/router/prefetchLink.test.tsx +28 -16
- package/tests/router/prefetchLinkPreload.test.tsx +21 -28
- package/tests/router/register.test.ts +1 -1
- package/tests/router/routeHooks.test.ts +41 -105
- package/tests/router/routeTree.test.ts +0 -212
- package/tests/router/routerCompatibility.test.ts +32 -9
- package/tests/router/rsc.test.tsx +118 -136
- package/tests/router/rscDecoderSecurity.test.ts +24 -53
- package/tests/router/serverPlugin.test.ts +43 -1
- package/tests/router/tanstackTypes.test.ts +24 -364
- package/tests/router/fastDefaults.test.ts +0 -32
- package/tests/router/hydrationBoundary.test.tsx +0 -23
- package/tests/router/packageSurface.test.ts +0 -24
- package/tests/router/preloadRedirect.test.ts +0 -64
- package/tests/router/rscPayloadRouterMatrix.test.ts +0 -197
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
+
import { canonicaliseLocalisedRoutes } from "@modern-js/i18n-runtime-extensions";
|
|
2
3
|
import { DefaultNotFound } from "@modern-js/runtime/context";
|
|
3
4
|
import { rootRouteId } from "@tanstack/react-router";
|
|
4
5
|
import { createRouteStaticData } from "../../shared/routeStaticData.mjs";
|
|
@@ -58,6 +59,7 @@ function getRootLikeRouteObject(routes) {
|
|
|
58
59
|
return routes.find((route)=>'/' === route.path && !route.index);
|
|
59
60
|
}
|
|
60
61
|
function createRouteTreeFromRouteObjects(routes, options = {}) {
|
|
62
|
+
routes = canonicaliseLocalisedRoutes(routes);
|
|
61
63
|
const rootLikeRoute = getRootLikeRouteObject(routes);
|
|
62
64
|
const rootRevalidationState = {};
|
|
63
65
|
const rootShouldRevalidate = rootLikeRoute?.shouldRevalidate;
|
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
import
|
|
2
|
+
import { routerProviderRegistryHooks } from "@modern-js/runtime/context";
|
|
3
|
+
import { routerPlugin } from "@modern-js/runtime/router/internal";
|
|
4
|
+
import { createRouterPlugin } from "@modern-js/runtime-extensions/router-provider";
|
|
5
|
+
import { createRouterStatePlugin } from "@modern-js/runtime-extensions/router-state-plugin";
|
|
3
6
|
import { tanstackRouterProviderFactory } from "./register.mjs";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
const createProviderPlugin = createRouterPlugin({
|
|
8
|
+
defaultProvider: {
|
|
9
|
+
name: 'react-router',
|
|
10
|
+
factory: routerPlugin
|
|
11
|
+
},
|
|
12
|
+
registryHooks: routerProviderRegistryHooks,
|
|
13
|
+
localProviders: [
|
|
7
14
|
{
|
|
8
15
|
name: 'tanstack',
|
|
9
16
|
factory: tanstackRouterProviderFactory
|
|
10
17
|
}
|
|
11
|
-
]
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
+
]
|
|
19
|
+
});
|
|
20
|
+
const statePlugin = createRouterStatePlugin({
|
|
21
|
+
registryHooks: routerProviderRegistryHooks
|
|
22
|
+
});
|
|
23
|
+
const router_routerPlugin = (userConfig = {})=>{
|
|
24
|
+
const providerPlugin = createProviderPlugin(userConfig);
|
|
25
|
+
return {
|
|
26
|
+
...providerPlugin,
|
|
27
|
+
setup (api) {
|
|
28
|
+
statePlugin.setup(api);
|
|
29
|
+
providerPlugin.setup(api);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
export { router_routerPlugin as routerPlugin };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "node:module";
|
|
2
|
-
import { getRouterRuntimeState } from "@modern-js/runtime/
|
|
2
|
+
import { getRouterRuntimeState } from "@modern-js/runtime-extensions/router-state";
|
|
3
3
|
function getTanstackRouterState(context) {
|
|
4
4
|
const state = getRouterRuntimeState(context);
|
|
5
5
|
if (void 0 === state || 'tanstack' !== state.framework || void 0 === state.instance) return;
|
|
@@ -14,6 +14,7 @@ function withGlobalLayout(Component, globalApp) {
|
|
|
14
14
|
}
|
|
15
15
|
function toTanstackRouteObject(route, globalApp) {
|
|
16
16
|
if ('nested' === route.type) return {
|
|
17
|
+
modernLocalisedRoute: Reflect.get(route, 'modernLocalisedRoute'),
|
|
17
18
|
path: route.path,
|
|
18
19
|
id: route.id,
|
|
19
20
|
loader: route.loader,
|
|
@@ -38,6 +39,7 @@ function toTanstackRouteObject(route, globalApp) {
|
|
|
38
39
|
if ('function' != typeof route.component && 'object' != typeof route.component) return null;
|
|
39
40
|
const LayoutComponent = withGlobalLayout(route.component, globalApp);
|
|
40
41
|
return {
|
|
42
|
+
modernLocalisedRoute: Reflect.get(route, 'modernLocalisedRoute'),
|
|
41
43
|
path: route.path,
|
|
42
44
|
element: /*#__PURE__*/ react.createElement(LayoutComponent)
|
|
43
45
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import type { RouteObject } from '@modern-js/runtime-utils/router';
|
|
2
|
+
export declare function createModernBasepathRewrite(basepath: string, caseSensitive?: boolean, routes?: RouteObject[]): {
|
|
2
3
|
input: ({ url }: {
|
|
3
4
|
url: URL;
|
|
4
5
|
}) => URL;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The router runtime state helpers are owned by @modern-js/runtime (the same
|
|
2
|
+
* The router runtime state helpers are owned by @modern-js/runtime-extensions (the same
|
|
3
3
|
* implementation backs the built-in react-router provider and the SSR
|
|
4
4
|
* pipeline). This module only re-exports them so every router provider
|
|
5
5
|
* writes to the exact same runtime-context extension slot.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
import type { RouterLifecycleContext as NativeRouterLifecycleContext } from '@modern-js/runtime/context';
|
|
8
|
+
import type { InternalRouterServerSnapshot, RouterRouteMatchSnapshot } from '@modern-js/runtime-extensions/router-state';
|
|
9
|
+
export type RouterLifecycleContext = NativeRouterLifecycleContext & {
|
|
10
|
+
matches?: RouterRouteMatchSnapshot[];
|
|
11
|
+
cleanup?: () => void | Promise<void>;
|
|
12
|
+
serverSnapshot?: InternalRouterServerSnapshot;
|
|
13
|
+
};
|
|
14
|
+
export { applyRouterRuntimeState, applyRouterServerPrepareResult, createRouterRuntimeState, createRouterServerSnapshot, getRouterRuntimeState, getRouterServerSnapshot, type RouterLifecyclePhase, } from '@modern-js/runtime-extensions/router-state';
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
* This module is intentionally side-effectful (see `sideEffects` in
|
|
7
7
|
* package.json).
|
|
8
8
|
*/
|
|
9
|
-
import { type RouterProviderFactory } from '@modern-js/runtime/
|
|
9
|
+
import { type RouterProviderFactory } from '@modern-js/runtime-extensions/router-provider';
|
|
10
10
|
export declare const tanstackRouterProviderFactory: RouterProviderFactory;
|
|
@@ -1,13 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* file-route entrypoints (e.g. apps configuring
|
|
4
|
-
* `router: { framework: 'tanstack', createRoutes }` in modern.runtime.ts).
|
|
5
|
-
*
|
|
6
|
-
* The CLI plugin injects `{ name: 'router', path: '<pkg>/runtime/router' }`
|
|
7
|
-
* for those entries. This module creates a framework-resolving wrapper whose
|
|
8
|
-
* app-owned provider realm contains this module graph's TanStack factory.
|
|
9
|
-
*/
|
|
10
|
-
import * as runtimeRouter from '@modern-js/runtime/router/internal';
|
|
11
|
-
type LegacyRouterPlugin = (typeof runtimeRouter)['routerPlugin'];
|
|
12
|
-
export declare const routerPlugin: LegacyRouterPlugin;
|
|
13
|
-
export {};
|
|
1
|
+
import { routerPlugin as nativeRouterPlugin } from '@modern-js/runtime/router/internal';
|
|
2
|
+
export declare const routerPlugin: typeof nativeRouterPlugin;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type InternalRouterRuntimeState } from '@modern-js/runtime/
|
|
1
|
+
import { type InternalRouterRuntimeState } from '@modern-js/runtime-extensions/router-state';
|
|
2
2
|
import type { AnyRouter } from '@tanstack/react-router';
|
|
3
3
|
/**
|
|
4
4
|
* Router runtime state as published by the TanStack router provider into the
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { ModernRoute } from '@modern-js/runtime/context';
|
|
2
2
|
import type { RouteObject } from '@modern-js/runtime-utils/router';
|
|
3
3
|
import type React from 'react';
|
|
4
|
-
export type {
|
|
4
|
+
export type { ModernRoute } from '@modern-js/runtime/context';
|
|
5
|
+
export type { InternalRouterServerSnapshot, RouterFramework, } from '@modern-js/runtime-extensions/router-state';
|
|
5
6
|
/** TanStack-specific router config. */
|
|
6
7
|
export type RouterConfig = {
|
|
7
8
|
routesConfig: {
|
package/package.json
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"modern.js",
|
|
19
19
|
"tanstack-router"
|
|
20
20
|
],
|
|
21
|
-
"version": "3.9.0-ultramodern.
|
|
21
|
+
"version": "3.9.0-ultramodern.5",
|
|
22
22
|
"engines": {
|
|
23
23
|
"node": ">=20"
|
|
24
24
|
},
|
|
@@ -94,17 +94,19 @@
|
|
|
94
94
|
}
|
|
95
95
|
},
|
|
96
96
|
"dependencies": {
|
|
97
|
-
"@modern-js/
|
|
98
|
-
"@modern-js/
|
|
99
|
-
"@modern-js/
|
|
100
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.
|
|
97
|
+
"@modern-js/i18n-runtime-extensions": "npm:@bleedingdev/modern-js-i18n-runtime-extensions@3.9.0-ultramodern.5",
|
|
98
|
+
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.5",
|
|
99
|
+
"@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.9.0-ultramodern.5",
|
|
100
|
+
"@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.0-ultramodern.5",
|
|
101
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.5",
|
|
102
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.5",
|
|
101
103
|
"@swc/helpers": "^0.5.23",
|
|
102
104
|
"@tanstack/react-router": "1.170.33",
|
|
103
105
|
"@tanstack/router-core": "1.171.28"
|
|
104
106
|
},
|
|
105
107
|
"peerDependencies": {
|
|
106
|
-
"@modern-js/app-tools": "3.9.0-ultramodern.
|
|
107
|
-
"@modern-js/runtime": "3.9.0-ultramodern.
|
|
108
|
+
"@modern-js/app-tools": "3.9.0-ultramodern.5",
|
|
109
|
+
"@modern-js/runtime": "3.9.0-ultramodern.5",
|
|
108
110
|
"react": "^19.2.8",
|
|
109
111
|
"react-dom": "^19.2.8",
|
|
110
112
|
"react-server-dom-rspack": "0.1.0"
|
|
@@ -115,8 +117,9 @@
|
|
|
115
117
|
}
|
|
116
118
|
},
|
|
117
119
|
"devDependencies": {
|
|
118
|
-
"@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.9.0-ultramodern.
|
|
119
|
-
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.9.0-ultramodern.
|
|
120
|
+
"@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.9.0-ultramodern.5",
|
|
121
|
+
"@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.9.0-ultramodern.5",
|
|
122
|
+
"@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.9.0-ultramodern.5",
|
|
120
123
|
"@rslib/core": "1.0.0",
|
|
121
124
|
"@scripts/rstest-config": "2.66.0",
|
|
122
125
|
"@tanstack/history": "1.162.2",
|
package/rstest.config.mts
CHANGED
|
@@ -26,18 +26,14 @@ export default {
|
|
|
26
26
|
include: [
|
|
27
27
|
'tests/realm-isolation.test.ts',
|
|
28
28
|
'tests/router/cli.test.ts',
|
|
29
|
-
'tests/router/fastDefaults.test.ts',
|
|
30
29
|
'tests/router/flightSerialization.roundtrip.test.tsx',
|
|
31
30
|
'tests/router/generateRouteArtifacts.test.ts',
|
|
32
31
|
'tests/router/hooks.test.ts',
|
|
33
32
|
'tests/router/loaderBridge.test.ts',
|
|
34
|
-
'tests/router/
|
|
35
|
-
'tests/router/preloadRedirect.test.ts',
|
|
36
|
-
'tests/router/register.test.ts',
|
|
33
|
+
'tests/router/localisedIdentity.test.tsx',
|
|
37
34
|
'tests/router/routeHooks.test.ts',
|
|
38
35
|
'tests/router/serverPlugin.test.ts',
|
|
39
36
|
'tests/router/rscDecoderSecurity.test.ts',
|
|
40
|
-
'tests/router/rscPayloadRouterMatrix.test.ts',
|
|
41
37
|
'tests/router/rsc.test.tsx',
|
|
42
38
|
'tests/router/slotUsageSanitizer.test.ts',
|
|
43
39
|
'tests/router/ssrPreload.test.ts',
|
|
@@ -66,7 +62,6 @@ export default {
|
|
|
66
62
|
include: [
|
|
67
63
|
'tests/router/clientHydration.test.tsx',
|
|
68
64
|
'tests/router/dataMutation.test.tsx',
|
|
69
|
-
'tests/router/hydrationBoundary.test.tsx',
|
|
70
65
|
'tests/router/prefetchLink.test.tsx',
|
|
71
66
|
'tests/router/prefetchLinkPreload.test.tsx',
|
|
72
67
|
],
|
package/src/cli/index.ts
CHANGED
|
@@ -132,6 +132,16 @@ export function tanstackRouterPlugin(
|
|
|
132
132
|
name: '@modern-js/plugin-tanstack',
|
|
133
133
|
required: ['@modern-js/runtime'],
|
|
134
134
|
setup: api => {
|
|
135
|
+
const { srcDirectory, serverCompileExcludedFiles = [] } =
|
|
136
|
+
api.getAppContext();
|
|
137
|
+
api.updateAppContext({
|
|
138
|
+
serverCompileExcludedFiles: [
|
|
139
|
+
...new Set([
|
|
140
|
+
...serverCompileExcludedFiles,
|
|
141
|
+
path.join(srcDirectory, generatedDirName, 'register.gen.d.ts'),
|
|
142
|
+
]),
|
|
143
|
+
],
|
|
144
|
+
});
|
|
135
145
|
const nestedRoutesForServer: Record<string, unknown> = {};
|
|
136
146
|
|
|
137
147
|
const isTanstackEntrypoint = (entrypoint: Entrypoint) => {
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
AppTools,
|
|
6
6
|
AppToolsContext,
|
|
7
7
|
} from '@modern-js/app-tools';
|
|
8
|
+
import { canonicaliseLocalisedRoutes } from '@modern-js/i18n-runtime-extensions';
|
|
8
9
|
import { makeLegalIdentifier } from '@modern-js/runtime/cli';
|
|
9
10
|
import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
|
|
10
11
|
import { upath as path } from '@modern-js/utils';
|
|
@@ -45,8 +46,9 @@ export async function generateTanstackRouterTypesSourceForEntry(opts: {
|
|
|
45
46
|
appContext,
|
|
46
47
|
entryName,
|
|
47
48
|
generatedDirName = 'modern-tanstack',
|
|
48
|
-
routes,
|
|
49
|
+
routes: rawRoutes,
|
|
49
50
|
} = opts;
|
|
51
|
+
const routes: RouteForCli[] = canonicaliseLocalisedRoutes(rawRoutes);
|
|
50
52
|
const outDir = path.join(
|
|
51
53
|
appContext.srcDirectory,
|
|
52
54
|
generatedDirName,
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
// @effect-diagnostics strictBooleanExpressions:off
|
|
2
|
+
import { createLocalisedRouteRewrite } from '@modern-js/i18n-runtime-extensions';
|
|
3
|
+
import type { RouteObject } from '@modern-js/runtime-utils/router';
|
|
4
|
+
import { composeRewrites } from '@tanstack/react-router';
|
|
5
|
+
|
|
2
6
|
function normalizeBasepath(basepath: string): string {
|
|
3
7
|
if (!basepath) {
|
|
4
8
|
return '/';
|
|
@@ -15,10 +19,12 @@ function normalizeBasepath(basepath: string): string {
|
|
|
15
19
|
export function createModernBasepathRewrite(
|
|
16
20
|
basepath: string,
|
|
17
21
|
caseSensitive = false,
|
|
22
|
+
routes: RouteObject[] = [],
|
|
18
23
|
) {
|
|
24
|
+
const localisedRewrite = createLocalisedRouteRewrite(routes);
|
|
19
25
|
const normalizedBasepath = normalizeBasepath(basepath);
|
|
20
26
|
if (normalizedBasepath === '/') {
|
|
21
|
-
return
|
|
27
|
+
return localisedRewrite;
|
|
22
28
|
}
|
|
23
29
|
|
|
24
30
|
const normalizedBasepathWithSlash = `${normalizedBasepath}/`;
|
|
@@ -29,7 +35,7 @@ export function createModernBasepathRewrite(
|
|
|
29
35
|
? normalizedBasepathWithSlash
|
|
30
36
|
: normalizedBasepathWithSlash.toLowerCase();
|
|
31
37
|
|
|
32
|
-
|
|
38
|
+
const basepathRewrite = {
|
|
33
39
|
input: ({ url }: { url: URL }) => {
|
|
34
40
|
const pathname = caseSensitive
|
|
35
41
|
? url.pathname
|
|
@@ -57,4 +63,7 @@ export function createModernBasepathRewrite(
|
|
|
57
63
|
return url;
|
|
58
64
|
},
|
|
59
65
|
};
|
|
66
|
+
return localisedRewrite
|
|
67
|
+
? composeRewrites([basepathRewrite, localisedRewrite])
|
|
68
|
+
: basepathRewrite;
|
|
60
69
|
}
|
package/src/runtime/lifecycle.ts
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The router runtime state helpers are owned by @modern-js/runtime (the same
|
|
2
|
+
* The router runtime state helpers are owned by @modern-js/runtime-extensions (the same
|
|
3
3
|
* implementation backs the built-in react-router provider and the SSR
|
|
4
4
|
* pipeline). This module only re-exports them so every router provider
|
|
5
5
|
* writes to the exact same runtime-context extension slot.
|
|
6
6
|
*/
|
|
7
|
+
|
|
8
|
+
import type { RouterLifecycleContext as NativeRouterLifecycleContext } from '@modern-js/runtime/context';
|
|
9
|
+
import type {
|
|
10
|
+
InternalRouterServerSnapshot,
|
|
11
|
+
RouterRouteMatchSnapshot,
|
|
12
|
+
} from '@modern-js/runtime-extensions/router-state';
|
|
13
|
+
|
|
14
|
+
export type RouterLifecycleContext = NativeRouterLifecycleContext & {
|
|
15
|
+
matches?: RouterRouteMatchSnapshot[];
|
|
16
|
+
cleanup?: () => void | Promise<void>;
|
|
17
|
+
serverSnapshot?: InternalRouterServerSnapshot;
|
|
18
|
+
};
|
|
7
19
|
export {
|
|
8
20
|
applyRouterRuntimeState,
|
|
9
21
|
applyRouterServerPrepareResult,
|
|
@@ -11,6 +23,5 @@ export {
|
|
|
11
23
|
createRouterServerSnapshot,
|
|
12
24
|
getRouterRuntimeState,
|
|
13
25
|
getRouterServerSnapshot,
|
|
14
|
-
type RouterLifecycleContext,
|
|
15
26
|
type RouterLifecyclePhase,
|
|
16
|
-
} from '@modern-js/runtime/
|
|
27
|
+
} from '@modern-js/runtime-extensions/router-state';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// @effect-diagnostics asyncFunction:off newPromise:off strictBooleanExpressions:off unnecessaryArrowBlock:off
|
|
2
2
|
import {
|
|
3
3
|
getGlobalEnableRsc,
|
|
4
|
-
type InternalRouterServerSnapshot,
|
|
5
4
|
InternalRuntimeContext,
|
|
6
5
|
type TInternalRuntimeContext,
|
|
7
6
|
} from '@modern-js/runtime/context';
|
|
7
|
+
import type { InternalRouterServerSnapshot } from '@modern-js/runtime-extensions/router-state';
|
|
8
8
|
import {
|
|
9
9
|
createRequestContext,
|
|
10
10
|
type RequestContext,
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
type TanstackRouterPluginAPI,
|
|
36
36
|
type TanstackRouterRuntimePlugin,
|
|
37
37
|
} from './pluginShared';
|
|
38
|
+
import { Link } from './prefetchLink';
|
|
38
39
|
import {
|
|
39
40
|
createRouteTreeFromRouteObjects,
|
|
40
41
|
getModernRouteIdsFromMatches,
|
|
@@ -98,6 +99,8 @@ export const tanstackRouterPlugin = (
|
|
|
98
99
|
return;
|
|
99
100
|
}
|
|
100
101
|
|
|
102
|
+
context.router = { Link };
|
|
103
|
+
|
|
101
104
|
const {
|
|
102
105
|
request,
|
|
103
106
|
nonce,
|
|
@@ -134,7 +137,11 @@ export const tanstackRouterPlugin = (
|
|
|
134
137
|
initialEntries: [initialHref],
|
|
135
138
|
});
|
|
136
139
|
|
|
137
|
-
const rewrite = createModernBasepathRewrite(
|
|
140
|
+
const rewrite = createModernBasepathRewrite(
|
|
141
|
+
_basename,
|
|
142
|
+
false,
|
|
143
|
+
modifiedRouteObjects,
|
|
144
|
+
);
|
|
138
145
|
const routerLifecycleContext: RouterLifecycleContext = {
|
|
139
146
|
framework: 'tanstack',
|
|
140
147
|
phase: 'ssr-prepare',
|
package/src/runtime/plugin.tsx
CHANGED
|
@@ -149,7 +149,11 @@ export const tanstackRouterPlugin = (
|
|
|
149
149
|
const history = supportHtml5History
|
|
150
150
|
? createBrowserHistory()
|
|
151
151
|
: createHashHistory();
|
|
152
|
-
const rewrite = createModernBasepathRewrite(
|
|
152
|
+
const rewrite = createModernBasepathRewrite(
|
|
153
|
+
_basename,
|
|
154
|
+
false,
|
|
155
|
+
getRouteObjects(),
|
|
156
|
+
);
|
|
153
157
|
const serializationAdapters = getGlobalEnableRsc()
|
|
154
158
|
? getTanstackRscSerializationAdapters()
|
|
155
159
|
: undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolvePreloadFromPrefetch } from '@modern-js/runtime-extensions';
|
|
1
2
|
import {
|
|
2
3
|
type AnyRouter,
|
|
3
4
|
type LinkComponentProps,
|
|
@@ -8,29 +9,6 @@ import type { AnchorHTMLAttributes, ReactElement, ReactNode, Ref } from 'react';
|
|
|
8
9
|
|
|
9
10
|
export type PrefetchBehavior = 'intent' | 'render' | 'viewport' | 'none';
|
|
10
11
|
|
|
11
|
-
function resolvePreloadFromPrefetch(
|
|
12
|
-
prefetch: PrefetchBehavior | undefined,
|
|
13
|
-
preload: unknown,
|
|
14
|
-
) {
|
|
15
|
-
if (typeof preload !== 'undefined') {
|
|
16
|
-
return preload;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (prefetch === 'none') {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (
|
|
24
|
-
prefetch === 'intent' ||
|
|
25
|
-
prefetch === 'render' ||
|
|
26
|
-
prefetch === 'viewport'
|
|
27
|
-
) {
|
|
28
|
-
return prefetch;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return 'viewport';
|
|
32
|
-
}
|
|
33
|
-
|
|
34
12
|
export type LinkProps<
|
|
35
13
|
TRouter extends AnyRouter = RegisteredRouter,
|
|
36
14
|
TFrom extends string = string,
|
package/src/runtime/register.ts
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
type RouterProviderFactory,
|
|
11
11
|
type RouterProviderPlugin,
|
|
12
12
|
registerRouterProvider,
|
|
13
|
-
} from '@modern-js/runtime/
|
|
13
|
+
} from '@modern-js/runtime-extensions/router-provider';
|
|
14
14
|
import { tanstackRouterPlugin } from './plugin';
|
|
15
15
|
|
|
16
16
|
// TanStack runtime plugin types its API against its own hook registry,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// @effect-diagnostics asyncFunction:off strictBooleanExpressions:off
|
|
2
2
|
|
|
3
|
+
import { canonicaliseLocalisedRoutes } from '@modern-js/i18n-runtime-extensions';
|
|
3
4
|
import { DefaultNotFound } from '@modern-js/runtime/context';
|
|
4
5
|
import type { RouteObject } from '@modern-js/runtime-utils/router';
|
|
5
6
|
import type { AnyRoute, AnyRouter } from '@tanstack/react-router';
|
|
@@ -121,6 +122,7 @@ export function createRouteTreeFromRouteObjects(
|
|
|
121
122
|
routes: RouteObject[],
|
|
122
123
|
options: RouteTreeOptions = {},
|
|
123
124
|
): ModernTanstackRootRoute {
|
|
125
|
+
routes = canonicaliseLocalisedRoutes(routes);
|
|
124
126
|
const rootLikeRoute = getRootLikeRouteObject(routes) as
|
|
125
127
|
| ModernRouteObject
|
|
126
128
|
| undefined;
|
package/src/runtime/router.ts
CHANGED
|
@@ -1,43 +1,28 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* The CLI plugin injects `{ name: 'router', path: '<pkg>/runtime/router' }`
|
|
7
|
-
* for those entries. This module creates a framework-resolving wrapper whose
|
|
8
|
-
* app-owned provider realm contains this module graph's TanStack factory.
|
|
9
|
-
*/
|
|
10
|
-
import * as runtimeRouter from '@modern-js/runtime/router/internal';
|
|
1
|
+
/** App-local composition for custom entries using runtime router selection. */
|
|
2
|
+
import { routerProviderRegistryHooks } from '@modern-js/runtime/context';
|
|
3
|
+
import { routerPlugin as nativeRouterPlugin } from '@modern-js/runtime/router/internal';
|
|
4
|
+
import { createRouterPlugin } from '@modern-js/runtime-extensions/router-provider';
|
|
5
|
+
import { createRouterStatePlugin } from '@modern-js/runtime-extensions/router-state-plugin';
|
|
11
6
|
import { tanstackRouterProviderFactory } from './register';
|
|
12
7
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
factory:
|
|
18
|
-
|
|
19
|
-
)
|
|
8
|
+
const createProviderPlugin = createRouterPlugin({
|
|
9
|
+
defaultProvider: { name: 'react-router', factory: nativeRouterPlugin },
|
|
10
|
+
registryHooks: routerProviderRegistryHooks,
|
|
11
|
+
localProviders: [
|
|
12
|
+
{ name: 'tanstack', factory: tanstackRouterProviderFactory },
|
|
13
|
+
],
|
|
14
|
+
});
|
|
15
|
+
const statePlugin = createRouterStatePlugin({
|
|
16
|
+
registryHooks: routerProviderRegistryHooks,
|
|
17
|
+
});
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const legacyRouterPlugin = Reflect.get(runtimeRouter, 'routerPlugin');
|
|
33
|
-
|
|
34
|
-
if (typeof legacyRouterPlugin === 'function') {
|
|
35
|
-
return tanstackRouterProviderFactory as unknown as LegacyRouterPlugin;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
throw new Error(
|
|
39
|
-
'[@modern-js/plugin-tanstack] The installed @modern-js/runtime/router/internal exports neither createRouterPlugin nor routerPlugin. Install a compatible @modern-js/runtime version.',
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export const routerPlugin: LegacyRouterPlugin = getRouterPlugin();
|
|
19
|
+
export const routerPlugin: typeof nativeRouterPlugin = (userConfig = {}) => {
|
|
20
|
+
const providerPlugin = createProviderPlugin(userConfig);
|
|
21
|
+
return {
|
|
22
|
+
...providerPlugin,
|
|
23
|
+
setup(api) {
|
|
24
|
+
statePlugin.setup(api);
|
|
25
|
+
providerPlugin.setup(api);
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
};
|
package/src/runtime/state.ts
CHANGED
package/src/runtime/types.ts
CHANGED
|
@@ -2,11 +2,11 @@ import type { ModernRoute } from '@modern-js/runtime/context';
|
|
|
2
2
|
import type { RouteObject } from '@modern-js/runtime-utils/router';
|
|
3
3
|
import type React from 'react';
|
|
4
4
|
|
|
5
|
+
export type { ModernRoute } from '@modern-js/runtime/context';
|
|
5
6
|
export type {
|
|
6
7
|
InternalRouterServerSnapshot,
|
|
7
|
-
ModernRoute,
|
|
8
8
|
RouterFramework,
|
|
9
|
-
} from '@modern-js/runtime/
|
|
9
|
+
} from '@modern-js/runtime-extensions/router-state';
|
|
10
10
|
|
|
11
11
|
/** TanStack-specific router config. */
|
|
12
12
|
export type RouterConfig = {
|
package/src/runtime/utils.tsx
CHANGED
|
@@ -54,6 +54,7 @@ function toTanstackRouteObject(
|
|
|
54
54
|
): RouteObject | null {
|
|
55
55
|
if (route.type === 'nested') {
|
|
56
56
|
return {
|
|
57
|
+
modernLocalisedRoute: Reflect.get(route, 'modernLocalisedRoute'),
|
|
57
58
|
path: route.path,
|
|
58
59
|
id: route.id,
|
|
59
60
|
loader: route.loader,
|
|
@@ -91,9 +92,10 @@ function toTanstackRouteObject(
|
|
|
91
92
|
globalApp,
|
|
92
93
|
);
|
|
93
94
|
return {
|
|
95
|
+
modernLocalisedRoute: Reflect.get(route, 'modernLocalisedRoute'),
|
|
94
96
|
path: route.path,
|
|
95
97
|
element: React.createElement(LayoutComponent),
|
|
96
|
-
};
|
|
98
|
+
} as ModernRouteObject;
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
export function createTanstackRouteObjectsFromConfig({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RouterProviderFactory } from '@modern-js/runtime/
|
|
1
|
+
import type { RouterProviderFactory } from '@modern-js/runtime-extensions/router-provider';
|
|
2
2
|
import { rstest } from '@rstest/core';
|
|
3
3
|
import type { RouterExtendsHooks } from '../src/runtime/hooks';
|
|
4
4
|
|
|
@@ -12,6 +12,7 @@ type RouterModule = typeof import('../src/runtime/router');
|
|
|
12
12
|
|
|
13
13
|
type Vertical = {
|
|
14
14
|
context: RuntimeContextModule;
|
|
15
|
+
providers: typeof import('@modern-js/runtime-extensions/router-provider');
|
|
15
16
|
factory: RouterProviderFactory;
|
|
16
17
|
hooks: RouterExtendsHooks;
|
|
17
18
|
Link: unknown;
|
|
@@ -32,8 +33,12 @@ async function loadVertical(): Promise<Vertical> {
|
|
|
32
33
|
const { Link } = await import('../src/runtime/prefetchLink');
|
|
33
34
|
const { useMatches } = await import('../src/runtime/routeHooks');
|
|
34
35
|
|
|
36
|
+
const providers = await import(
|
|
37
|
+
'@modern-js/runtime-extensions/router-provider'
|
|
38
|
+
);
|
|
35
39
|
return {
|
|
36
40
|
context,
|
|
41
|
+
providers,
|
|
37
42
|
factory: tanstackRouterProviderFactory,
|
|
38
43
|
hooks: routerProviderRegistryHooks,
|
|
39
44
|
Link,
|
|
@@ -50,6 +55,7 @@ function setupRouterWrapper(vertical: Vertical) {
|
|
|
50
55
|
const plugin = vertical.routerPlugin({ framework: 'tanstack' });
|
|
51
56
|
plugin.setup?.({
|
|
52
57
|
getHooks: () => vertical.hooks,
|
|
58
|
+
onAfterCreateRouter: () => undefined,
|
|
53
59
|
getRuntimeConfig: () => ({ router: { framework: 'tanstack' } }),
|
|
54
60
|
onBeforeRender: listener => {
|
|
55
61
|
onBeforeRender = listener;
|
|
@@ -101,7 +107,7 @@ describe('TanStack provider runtime-realm isolation', () => {
|
|
|
101
107
|
|
|
102
108
|
// Mixed-version callers that do not supply a realm still see the shared
|
|
103
109
|
// keep-first fallback, but production wrappers no longer consume it.
|
|
104
|
-
expect(verticalB.
|
|
110
|
+
expect(verticalB.providers.resolveRouterProvider('tanstack')).toBe(
|
|
105
111
|
verticalA.factory,
|
|
106
112
|
);
|
|
107
113
|
expect(warnSpy).toHaveBeenCalledWith(
|