@bleedingdev/modern-js-plugin-tanstack 3.8.3-ultramodern.6 → 3.9.0-ultramodern.10

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.
Files changed (114) hide show
  1. package/dist/cjs/cli/index.js +9 -0
  2. package/dist/cjs/cli/tanstackTypes/source.js +3 -1
  3. package/dist/cjs/runtime/basepathRewrite.js +13 -6
  4. package/dist/cjs/runtime/lifecycle.js +7 -7
  5. package/dist/cjs/runtime/plugin.js +1 -1
  6. package/dist/cjs/runtime/plugin.node.js +5 -1
  7. package/dist/cjs/runtime/prefetchLink.js +2 -7
  8. package/dist/cjs/runtime/register.js +0 -2
  9. package/dist/cjs/runtime/routeTree/construction.js +2 -0
  10. package/dist/cjs/runtime/router.js +25 -9
  11. package/dist/cjs/runtime/state.js +2 -2
  12. package/dist/cjs/runtime/utils.js +2 -0
  13. package/dist/esm/cli/index.mjs +13 -5
  14. package/dist/esm/cli/tanstackTypes/source.mjs +3 -1
  15. package/dist/esm/runtime/basepathRewrite.mjs +10 -3
  16. package/dist/esm/runtime/lifecycle.mjs +1 -1
  17. package/dist/esm/runtime/plugin.mjs +1 -1
  18. package/dist/esm/runtime/plugin.node.mjs +5 -1
  19. package/dist/esm/runtime/prefetchLink.mjs +1 -6
  20. package/dist/esm/runtime/register.mjs +0 -2
  21. package/dist/esm/runtime/routeTree/construction.mjs +2 -0
  22. package/dist/esm/runtime/router.mjs +27 -11
  23. package/dist/esm/runtime/state.mjs +1 -1
  24. package/dist/esm/runtime/utils.mjs +2 -0
  25. package/dist/esm-node/cli/index.mjs +15 -5
  26. package/dist/esm-node/cli/tanstackTypes/source.mjs +3 -1
  27. package/dist/esm-node/runtime/basepathRewrite.mjs +10 -3
  28. package/dist/esm-node/runtime/lifecycle.mjs +1 -1
  29. package/dist/esm-node/runtime/plugin.mjs +1 -1
  30. package/dist/esm-node/runtime/plugin.node.mjs +5 -1
  31. package/dist/esm-node/runtime/prefetchLink.mjs +1 -6
  32. package/dist/esm-node/runtime/register.mjs +0 -2
  33. package/dist/esm-node/runtime/routeTree/construction.mjs +2 -0
  34. package/dist/esm-node/runtime/router.mjs +27 -11
  35. package/dist/esm-node/runtime/state.mjs +1 -1
  36. package/dist/esm-node/runtime/utils.mjs +2 -0
  37. package/dist/types/cli/index.d.ts +5 -5
  38. package/dist/types/cli/tanstackTypes/shared.d.ts +1 -1
  39. package/dist/types/cli/tanstackTypes.d.ts +3 -3
  40. package/dist/types/cli.d.ts +2 -2
  41. package/dist/types/runtime/basepathRewrite.d.ts +2 -1
  42. package/dist/types/runtime/dataMutation.d.ts +3 -3
  43. package/dist/types/runtime/index.d.ts +14 -14
  44. package/dist/types/runtime/lifecycle.d.ts +9 -2
  45. package/dist/types/runtime/loaderBridge.d.ts +2 -2
  46. package/dist/types/runtime/plugin.d.ts +2 -2
  47. package/dist/types/runtime/plugin.node.d.ts +2 -2
  48. package/dist/types/runtime/plugin.worker.d.ts +1 -1
  49. package/dist/types/runtime/pluginShared.d.ts +2 -2
  50. package/dist/types/runtime/register.d.ts +1 -9
  51. package/dist/types/runtime/routeTree/construction.d.ts +1 -1
  52. package/dist/types/runtime/routeTree/index.d.ts +2 -2
  53. package/dist/types/runtime/routeTree/loaders.d.ts +1 -1
  54. package/dist/types/runtime/routeTree/tanstackRoutes.d.ts +1 -1
  55. package/dist/types/runtime/router.d.ts +2 -13
  56. package/dist/types/runtime/rsc/CompositeComponent.d.ts +1 -1
  57. package/dist/types/runtime/rsc/RscNodeRenderer.d.ts +1 -1
  58. package/dist/types/runtime/rsc/client.d.ts +4 -4
  59. package/dist/types/runtime/rsc/createRscProxy.d.ts +1 -1
  60. package/dist/types/runtime/rsc/payloadFetch.d.ts +1 -1
  61. package/dist/types/runtime/rsc/payloadRouter.d.ts +2 -2
  62. package/dist/types/runtime/rsc/payloadStorage.d.ts +1 -1
  63. package/dist/types/runtime/rsc/server.d.ts +3 -3
  64. package/dist/types/runtime/rsc/shared.d.ts +1 -1
  65. package/dist/types/runtime/rsc/slotUsageSanitizer.d.ts +1 -1
  66. package/dist/types/runtime/ssrManagedTags.d.ts +1 -1
  67. package/dist/types/runtime/ssrPreload.d.ts +1 -1
  68. package/dist/types/runtime/state.d.ts +1 -1
  69. package/dist/types/runtime/submitAction.d.ts +1 -1
  70. package/dist/types/runtime/types.d.ts +2 -1
  71. package/dist/types/runtime/utils.d.ts +1 -1
  72. package/dist/types/runtime.d.ts +1 -1
  73. package/package.json +19 -16
  74. package/rstest.config.mts +1 -24
  75. package/src/cli/index.ts +10 -0
  76. package/src/cli/tanstackTypes/source.ts +3 -1
  77. package/src/runtime/basepathRewrite.ts +11 -2
  78. package/src/runtime/lifecycle.ts +14 -3
  79. package/src/runtime/plugin.node.tsx +9 -2
  80. package/src/runtime/plugin.tsx +5 -1
  81. package/src/runtime/prefetchLink.tsx +1 -23
  82. package/src/runtime/register.ts +1 -12
  83. package/src/runtime/routeTree/construction.ts +2 -0
  84. package/src/runtime/router.ts +25 -40
  85. package/src/runtime/state.ts +1 -1
  86. package/src/runtime/types.ts +2 -2
  87. package/src/runtime/utils.tsx +3 -1
  88. package/tests/router/cli.test.ts +148 -824
  89. package/tests/router/dataMutation.test.tsx +17 -85
  90. package/tests/router/flightSerialization.roundtrip.test.tsx +9 -6
  91. package/tests/router/generateRouteArtifacts.test.ts +68 -28
  92. package/tests/router/loaderBridge.test.ts +0 -25
  93. package/tests/router/localisedIdentity.test.tsx +95 -0
  94. package/tests/router/prefetchLink.test.tsx +17 -21
  95. package/tests/router/prefetchLinkPreload.test.tsx +11 -31
  96. package/tests/router/routeHooks.test.ts +41 -105
  97. package/tests/router/routeTree.test.ts +144 -836
  98. package/tests/router/rsc.test.tsx +131 -166
  99. package/tests/router/serverPlugin.test.ts +43 -1
  100. package/tests/router/tanstackTypes.test.ts +109 -973
  101. package/tests/realm-isolation.test.ts +0 -114
  102. package/tests/router/fastDefaults.test.ts +0 -32
  103. package/tests/router/fixtures/legacyRuntimeRouter.ts +0 -10
  104. package/tests/router/fixtures/rscDecoderSecurityChild.cjs +0 -162
  105. package/tests/router/hooks.test.ts +0 -40
  106. package/tests/router/hydrationBoundary.test.tsx +0 -23
  107. package/tests/router/packageSurface.test.ts +0 -24
  108. package/tests/router/preloadRedirect.test.ts +0 -64
  109. package/tests/router/register.test.ts +0 -8
  110. package/tests/router/routerCompatibility.test.ts +0 -239
  111. package/tests/router/rscDecoderSecurity.test.ts +0 -113
  112. package/tests/router/rscPayloadRouterMatrix.test.ts +0 -197
  113. /package/dist/esm/{rslib-runtime.mjs → rslib-runtime~1.mjs} +0 -0
  114. /package/dist/esm-node/{rslib-runtime.mjs → rslib-runtime~0.mjs} +0 -0
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 undefined;
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
- return {
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
  }
@@ -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/context';
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(_basename);
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',
@@ -149,7 +149,11 @@ export const tanstackRouterPlugin = (
149
149
  const history = supportHtml5History
150
150
  ? createBrowserHistory()
151
151
  : createHashHistory();
152
- const rewrite = createModernBasepathRewrite(_basename);
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,
@@ -1,16 +1,7 @@
1
- /**
2
- * Registers TanStack in the @modern-js/runtime compatibility registry.
3
- * Runtime entries bind the exported local factory into their own provider
4
- * realm; registration remains for older runtime wrappers and mixed cohorts.
5
- *
6
- * This module is intentionally side-effectful (see `sideEffects` in
7
- * package.json).
8
- */
9
1
  import {
10
2
  type RouterProviderFactory,
11
3
  type RouterProviderPlugin,
12
- registerRouterProvider,
13
- } from '@modern-js/runtime/context';
4
+ } from '@modern-js/runtime-extensions/router-provider';
14
5
  import { tanstackRouterPlugin } from './plugin';
15
6
 
16
7
  // TanStack runtime plugin types its API against its own hook registry,
@@ -22,5 +13,3 @@ import { tanstackRouterPlugin } from './plugin';
22
13
  export const tanstackRouterProviderFactory: RouterProviderFactory =
23
14
  userConfig =>
24
15
  tanstackRouterPlugin(userConfig) as unknown as RouterProviderPlugin;
25
-
26
- registerRouterProvider('tanstack', tanstackRouterProviderFactory);
@@ -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;
@@ -1,43 +1,28 @@
1
- /**
2
- * Entry-injected router module for entrypoints that are NOT TanStack
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';
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
- type LegacyRouterPlugin = (typeof runtimeRouter)['routerPlugin'];
14
- type CurrentRouterPluginCreator = (
15
- localProviders: readonly {
16
- name: string;
17
- factory: typeof tanstackRouterProviderFactory;
18
- }[],
19
- ) => LegacyRouterPlugin;
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
- function getRouterPlugin(): LegacyRouterPlugin {
22
- const createRouterPlugin = Reflect.get(runtimeRouter, 'createRouterPlugin') as
23
- | CurrentRouterPluginCreator
24
- | undefined;
25
-
26
- if (typeof createRouterPlugin === 'function') {
27
- return createRouterPlugin([
28
- { name: 'tanstack', factory: tanstackRouterProviderFactory },
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
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getRouterRuntimeState,
3
3
  type InternalRouterRuntimeState,
4
- } from '@modern-js/runtime/context';
4
+ } from '@modern-js/runtime-extensions/router-state';
5
5
  import type { AnyRouter } from '@tanstack/react-router';
6
6
 
7
7
  /**
@@ -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/context';
9
+ } from '@modern-js/runtime-extensions/router-state';
10
10
 
11
11
  /** TanStack-specific router config. */
12
12
  export type RouterConfig = {
@@ -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({