@bleedingdev/modern-js-plugin-tanstack 3.2.0-ultramodern.120 → 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.
Files changed (94) hide show
  1. package/dist/cjs/cli/index.js +47 -27
  2. package/dist/cjs/cli/routeSplitting.js +0 -32
  3. package/dist/cjs/cli/tanstackTypes.js +34 -199
  4. package/dist/cjs/runtime/hooks.js +11 -14
  5. package/dist/cjs/runtime/index.js +107 -319
  6. package/dist/cjs/runtime/lifecycle.js +12 -86
  7. package/dist/cjs/runtime/loaderBridge.js +173 -0
  8. package/dist/cjs/runtime/plugin.js +6 -30
  9. package/dist/cjs/runtime/plugin.node.js +7 -29
  10. package/dist/cjs/runtime/pluginCore.js +55 -0
  11. package/dist/cjs/runtime/register.js +56 -0
  12. package/dist/cjs/runtime/routeTree.js +10 -207
  13. package/dist/cjs/runtime/{DefaultNotFound.js → router.js} +5 -15
  14. package/dist/cjs/runtime/rsc/payloadRouter.js +35 -1
  15. package/dist/cjs/runtime/state.js +45 -0
  16. package/dist/cjs/runtime/utils.js +0 -5
  17. package/dist/esm/cli/index.mjs +52 -26
  18. package/dist/esm/cli/routeSplitting.mjs +1 -30
  19. package/dist/esm/cli/tanstackTypes.mjs +32 -194
  20. package/dist/esm/runtime/hooks.mjs +1 -8
  21. package/dist/esm/runtime/index.mjs +4 -2
  22. package/dist/esm/runtime/lifecycle.mjs +1 -82
  23. package/dist/esm/runtime/loaderBridge.mjs +114 -0
  24. package/dist/esm/runtime/plugin.mjs +8 -32
  25. package/dist/esm/runtime/plugin.node.mjs +10 -32
  26. package/dist/esm/runtime/pluginCore.mjs +14 -0
  27. package/dist/esm/runtime/register.mjs +18 -0
  28. package/dist/esm/runtime/routeTree.mjs +4 -198
  29. package/dist/esm/runtime/router.mjs +2 -0
  30. package/dist/esm/runtime/rsc/payloadRouter.mjs +35 -1
  31. package/dist/esm/runtime/state.mjs +7 -0
  32. package/dist/esm/runtime/utils.mjs +0 -5
  33. package/dist/esm-node/cli/index.mjs +52 -26
  34. package/dist/esm-node/cli/routeSplitting.mjs +1 -30
  35. package/dist/esm-node/cli/tanstackTypes.mjs +32 -194
  36. package/dist/esm-node/runtime/hooks.mjs +1 -8
  37. package/dist/esm-node/runtime/index.mjs +4 -2
  38. package/dist/esm-node/runtime/lifecycle.mjs +1 -82
  39. package/dist/esm-node/runtime/loaderBridge.mjs +115 -0
  40. package/dist/esm-node/runtime/plugin.mjs +8 -32
  41. package/dist/esm-node/runtime/plugin.node.mjs +10 -32
  42. package/dist/esm-node/runtime/pluginCore.mjs +15 -0
  43. package/dist/esm-node/runtime/register.mjs +19 -0
  44. package/dist/esm-node/runtime/routeTree.mjs +4 -198
  45. package/dist/esm-node/runtime/router.mjs +3 -0
  46. package/dist/esm-node/runtime/rsc/payloadRouter.mjs +35 -1
  47. package/dist/esm-node/runtime/state.mjs +8 -0
  48. package/dist/esm-node/runtime/utils.mjs +0 -5
  49. package/dist/types/cli/index.d.ts +9 -2
  50. package/dist/types/cli/routeSplitting.d.ts +6 -15
  51. package/dist/types/cli/tanstackTypes.d.ts +13 -2
  52. package/dist/types/runtime/hooks.d.ts +8 -18
  53. package/dist/types/runtime/index.d.ts +6 -4
  54. package/dist/types/runtime/lifecycle.d.ts +7 -22
  55. package/dist/types/runtime/loaderBridge.d.ts +48 -0
  56. package/dist/types/runtime/plugin.d.ts +1 -14
  57. package/dist/types/runtime/plugin.node.d.ts +1 -14
  58. package/dist/types/runtime/pluginCore.d.ts +21 -0
  59. package/dist/types/runtime/register.d.ts +9 -0
  60. package/dist/types/runtime/routeTree.d.ts +0 -2
  61. package/dist/types/runtime/router.d.ts +14 -0
  62. package/dist/types/runtime/state.d.ts +16 -0
  63. package/dist/types/runtime/types.d.ts +7 -53
  64. package/package.json +30 -28
  65. package/rstest.config.mts +6 -0
  66. package/src/cli/index.ts +111 -29
  67. package/src/cli/routeSplitting.ts +6 -44
  68. package/src/cli/tanstackTypes.ts +78 -214
  69. package/src/runtime/hooks.ts +10 -27
  70. package/src/runtime/index.tsx +12 -107
  71. package/src/runtime/lifecycle.ts +16 -151
  72. package/src/runtime/loaderBridge.ts +257 -0
  73. package/src/runtime/plugin.node.tsx +14 -77
  74. package/src/runtime/plugin.tsx +12 -72
  75. package/src/runtime/pluginCore.ts +48 -0
  76. package/src/runtime/register.ts +58 -0
  77. package/src/runtime/routeTree.ts +8 -370
  78. package/src/runtime/router.ts +15 -0
  79. package/src/runtime/rsc/payloadRouter.ts +45 -2
  80. package/src/runtime/state.ts +29 -0
  81. package/src/runtime/types.ts +20 -67
  82. package/src/runtime/utils.tsx +3 -6
  83. package/tests/router/cli.test.ts +297 -31
  84. package/tests/router/hooks.test.ts +26 -0
  85. package/tests/router/loaderBridge.test.ts +211 -0
  86. package/tests/router/packageSurface.test.ts +24 -0
  87. package/tests/router/register.test.ts +46 -0
  88. package/tests/router/routeTree.test.ts +65 -180
  89. package/tests/router/rsc.test.tsx +70 -0
  90. package/tests/router/tanstackTypes.test.ts +164 -6
  91. package/dist/esm/runtime/DefaultNotFound.mjs +0 -13
  92. package/dist/esm-node/runtime/DefaultNotFound.mjs +0 -14
  93. package/dist/types/runtime/DefaultNotFound.d.ts +0 -2
  94. package/src/runtime/DefaultNotFound.tsx +0 -15
@@ -10,35 +10,8 @@ export type TanstackRsbuildRouteSplittingProfile = {
10
10
  splitRouteChunks: boolean;
11
11
  };
12
12
  };
13
- modernRouteChunks: {
14
- enabled: boolean;
15
- owner: 'modern';
16
- };
17
- builderChunkSplit: {
18
- owner: 'modern-rsbuild';
19
- preserved: true;
20
- };
21
- tanstackStartRspackSplitter: {
22
- compatible: boolean;
23
- reason: string;
24
- clientDeleteNodes: string[];
25
- routeFactoryCalls: string[];
26
- };
27
13
  };
28
14
 
29
- const TANSTACK_START_ROUTE_FACTORY_CALLS = [
30
- 'createFileRoute',
31
- 'createRootRoute',
32
- 'createRootRouteWithContext',
33
- ] as const;
34
-
35
- const TANSTACK_START_ROUTE_FACTORY_REGEX =
36
- /\b(createFileRoute|createRootRoute|createRootRouteWithContext)\s*(?:<|\()/;
37
-
38
- export function isTanstackStartRouteModuleSource(source: string) {
39
- return TANSTACK_START_ROUTE_FACTORY_REGEX.test(source);
40
- }
41
-
42
15
  export function resolveTanstackRouteCodeSplittingEnabled(
43
16
  option?: TanstackRouteCodeSplittingOption,
44
17
  ) {
@@ -49,6 +22,12 @@ export function resolveTanstackRouteCodeSplittingEnabled(
49
22
  return option?.enabled ?? true;
50
23
  }
51
24
 
25
+ /**
26
+ * Route chunking for TanStack entries is owned by Modern's
27
+ * `output.splitRouteChunks`; the TanStack Start Rspack splitter does not
28
+ * apply because Modern generates TanStack route trees from Modern route
29
+ * metadata rather than TanStack file-route factory modules.
30
+ */
52
31
  export function createTanstackRsbuildRouteSplittingProfile(opts: {
53
32
  routeCodeSplitting?: TanstackRouteCodeSplittingOption;
54
33
  }): TanstackRsbuildRouteSplittingProfile {
@@ -60,22 +39,5 @@ export function createTanstackRsbuildRouteSplittingProfile(opts: {
60
39
  ),
61
40
  },
62
41
  },
63
- modernRouteChunks: {
64
- enabled: resolveTanstackRouteCodeSplittingEnabled(
65
- opts.routeCodeSplitting,
66
- ),
67
- owner: 'modern',
68
- },
69
- builderChunkSplit: {
70
- owner: 'modern-rsbuild',
71
- preserved: true,
72
- },
73
- tanstackStartRspackSplitter: {
74
- compatible: false,
75
- reason:
76
- 'TanStack Start Rsbuild route splitting is tied to TanStack file-route factory modules; Modern generates TanStack route trees from Modern route metadata and owns route chunking through output.splitRouteChunks.',
77
- clientDeleteNodes: ['ssr', 'server', 'headers'],
78
- routeFactoryCalls: [...TANSTACK_START_ROUTE_FACTORY_CALLS],
79
- },
80
42
  };
81
43
  }
@@ -1,31 +1,10 @@
1
1
  // @effect-diagnostics asyncFunction:off nodeBuiltinImport:off strictBooleanExpressions:off
2
2
  import type { AppToolsContext } from '@modern-js/app-tools';
3
+ import { getPathWithoutExt, makeLegalIdentifier } from '@modern-js/runtime/cli';
3
4
  import type { NestedRouteForCli, PageRoute } from '@modern-js/types';
4
- import { findExists, formatImportPath, fs, slash } from '@modern-js/utils';
5
+ import { findExists, formatImportPath, slash } from '@modern-js/utils';
5
6
  import path from 'path';
6
7
 
7
- const reservedWords =
8
- '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';
9
- const builtins =
10
- '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';
11
- const forbidList = new Set<string>(`${reservedWords} ${builtins}`.split(' '));
12
-
13
- function makeLegalIdentifier(str: string) {
14
- const identifier = str
15
- .replace(/-(\w)/g, (_, letter) => letter.toUpperCase())
16
- .replace(/[^$_a-zA-Z0-9]/g, '_');
17
-
18
- if (/\d/.test(identifier[0]) || forbidList.has(identifier)) {
19
- return `_${identifier}`;
20
- }
21
- return identifier || '_';
22
- }
23
-
24
- function getPathWithoutExt(filename: string) {
25
- const extname = path.extname(filename);
26
- return extname ? filename.slice(0, -extname.length) : filename;
27
- }
28
-
29
8
  const JS_OR_TS_EXTS = [
30
9
  '.js',
31
10
  '.jsx',
@@ -188,6 +167,19 @@ function paramsTypeForCanonicalPath(canonicalPath: string): string {
188
167
  : 'Record<string, never>';
189
168
  }
190
169
 
170
+ export type CollectCanonicalRoutesOptions = {
171
+ /**
172
+ * Whether a leading `:lang`/`:locale`/`:language` route param may be
173
+ * treated as an i18n locale prefix. This MUST only be enabled when
174
+ * `@modern-js/plugin-i18n` is actually installed: the emitted
175
+ * `declare module '@modern-js/plugin-i18n/runtime'` augmentation breaks
176
+ * typechecking (TS2664) for apps that hand-roll a `/:lang/` param without
177
+ * the plugin. Routes carrying `modernCanonicalPath` metadata are always
178
+ * honored — only plugin-i18n produces them.
179
+ */
180
+ localeParamHeuristic?: boolean;
181
+ };
182
+
191
183
  /**
192
184
  * Derive the canonical (language-agnostic) route map for an entry: the
193
185
  * leading locale param is stripped and localized physical variants (routes
@@ -198,7 +190,9 @@ function paramsTypeForCanonicalPath(canonicalPath: string): string {
198
190
  */
199
191
  export function collectCanonicalRoutesForEntry(
200
192
  routes: (NestedRouteForCli | PageRoute)[],
193
+ options: CollectCanonicalRoutesOptions = {},
201
194
  ): Record<string, string> | null {
195
+ const { localeParamHeuristic = true } = options;
202
196
  const canonicalParams = new Map<string, string>();
203
197
  let hasI18nSurface = false;
204
198
 
@@ -229,7 +223,11 @@ export function collectCanonicalRoutesForEntry(
229
223
  .replace(/\[(.+?)\]/g, ':$1')
230
224
  .split('/')
231
225
  .filter(Boolean);
232
- if (parentPath === '' && LOCALE_PARAM_SEGMENTS.has(segments[0])) {
226
+ if (
227
+ localeParamHeuristic &&
228
+ parentPath === '' &&
229
+ LOCALE_PARAM_SEGMENTS.has(segments[0])
230
+ ) {
233
231
  hasI18nSurface = true;
234
232
  segments.shift();
235
233
  }
@@ -268,29 +266,6 @@ export function collectCanonicalRoutesForEntry(
268
266
  );
269
267
  }
270
268
 
271
- export async function isTanstackRouterFrameworkEnabled(
272
- appContext: AppToolsContext,
273
- ): Promise<boolean> {
274
- const runtimeConfigBase = path.join(
275
- appContext.srcDirectory,
276
- appContext.runtimeConfigFile,
277
- );
278
- const runtimeConfigFile = findExists(
279
- JS_OR_TS_EXTS.map(ext => `${runtimeConfigBase}${ext}`),
280
- );
281
- if (!runtimeConfigFile) {
282
- return false;
283
- }
284
-
285
- try {
286
- const content = await fs.readFile(runtimeConfigFile, 'utf-8');
287
- // Heuristic: allow both single and double quotes, tolerate whitespace/newlines.
288
- return /framework\s*:\s*['"]tanstack['"]/.test(content);
289
- } catch {
290
- return false;
291
- }
292
- }
293
-
294
269
  export async function generateTanstackRouterTypesSourceForEntry(opts: {
295
270
  appContext: AppToolsContext;
296
271
  entryName: string;
@@ -324,13 +299,50 @@ export async function generateTanstackRouterTypesSourceForEntry(opts: {
324
299
  const statements: string[] = [];
325
300
 
326
301
  const loaderImportMap = new Map<string, string>();
302
+ const componentImportMap = new Map<string, Promise<string | null>>();
327
303
  const searchContractImportMap = new Map<string, string>();
328
304
  const usedRouteVarNames = new Set<string>();
329
305
  let loaderIndex = 0;
306
+ let componentIndex = 0;
330
307
  let validateSearchIndex = 0;
331
308
  let loaderDepsIndex = 0;
332
309
  let routeIndex = 0;
333
310
 
311
+ const getImportNameForComponent = (
312
+ componentPath: unknown,
313
+ ): Promise<string | null> => {
314
+ if (typeof componentPath !== 'string' || componentPath.length === 0) {
315
+ return Promise.resolve(null);
316
+ }
317
+
318
+ // Cache the in-flight promise: sibling routes sharing a component module
319
+ // are generated concurrently and must reuse one import.
320
+ let pendingImportName = componentImportMap.get(componentPath);
321
+ if (!pendingImportName) {
322
+ pendingImportName = (async () => {
323
+ // Resolve through the same machinery as loaders: the raw `_component`
324
+ // value carries the internal `@_modern_js_src` alias, which the app's
325
+ // tsconfig does not map — the generated file must use relative
326
+ // imports.
327
+ const resolvedNoExt = await resolveRouteModuleNoExt(componentPath);
328
+ if (!resolvedNoExt) {
329
+ return null;
330
+ }
331
+
332
+ const relImport = normalizeRelativeImport(
333
+ path.relative(outDir, resolvedNoExt),
334
+ );
335
+
336
+ const componentName = `component_${componentIndex++}`;
337
+ imports.push(`import ${componentName} from ${quote(relImport)};`);
338
+ return componentName;
339
+ })();
340
+ componentImportMap.set(componentPath, pendingImportName);
341
+ }
342
+
343
+ return pendingImportName;
344
+ };
345
+
334
346
  const resolveRouteModuleNoExt = async (aliasedNoExtPath: string) => {
335
347
  const prefix = `${appContext.internalSrcAlias}/`;
336
348
  let absNoExt: string;
@@ -475,6 +487,13 @@ export async function generateTanstackRouterTypesSourceForEntry(opts: {
475
487
 
476
488
  const routeOpts: string[] = [`getParentRoute: () => ${parentVar},`];
477
489
 
490
+ const componentName = await getImportNameForComponent(
491
+ (route as any)._component,
492
+ );
493
+ if (componentName) {
494
+ routeOpts.push(`component: ${componentName},`);
495
+ }
496
+
478
497
  if (isPathlessLayout(route)) {
479
498
  const id = (route as any).id as string | undefined;
480
499
  routeOpts.push(`id: ${quote(id || 'pathless')},`);
@@ -564,6 +583,14 @@ export async function generateTanstackRouterTypesSourceForEntry(opts: {
564
583
  );
565
584
 
566
585
  const rootOpts: string[] = [];
586
+
587
+ const rootComponentName = await getImportNameForComponent(
588
+ (rootModern as any)?._component,
589
+ );
590
+ if (rootComponentName) {
591
+ rootOpts.push(`component: ${rootComponentName},`);
592
+ }
593
+
567
594
  if (rootLoaderName) {
568
595
  rootOpts.push(
569
596
  `loader: modernLoaderToTanstack({ hasSplat: false }, ${rootLoaderName}),`,
@@ -581,178 +608,15 @@ export async function generateTanstackRouterTypesSourceForEntry(opts: {
581
608
 
582
609
  import {
583
610
  createMemoryHistory,
584
- modernTanstackRouterFastDefaults,
585
611
  createRootRouteWithContext,
586
612
  createRoute,
587
613
  createRouter,
588
- notFound,
589
- redirect,
614
+ createRouteStaticData,
615
+ type ModernRouterContext,
616
+ modernLoaderToTanstack,
617
+ modernTanstackRouterFastDefaults,
590
618
  } from '@modern-js/plugin-tanstack/runtime';
591
619
 
592
- type ModernRouterContext = {
593
- request?: Request;
594
- requestContext?: unknown;
595
- };
596
-
597
- function isResponse(value: unknown): value is Response {
598
- return (
599
- value != null &&
600
- typeof value === 'object' &&
601
- typeof (value as any).status === 'number' &&
602
- typeof (value as any).headers === 'object'
603
- );
604
- }
605
-
606
- const redirectStatusCodes = new Set([301, 302, 303, 307, 308]);
607
- function isRedirectResponse(res: Response) {
608
- return redirectStatusCodes.has(res.status);
609
- }
610
-
611
- function throwTanstackRedirect(location: string) {
612
- const target = location.length > 0 ? location : '/';
613
- try {
614
- void new URL(target);
615
- throw redirect({ href: target });
616
- } catch {
617
- throw redirect({ to: target });
618
- }
619
- }
620
-
621
- function mapParamsForModernLoader(params: Record<string, string>, hasSplat: boolean) {
622
- if (!hasSplat) {
623
- return params;
624
- }
625
-
626
- const { _splat, ...rest } = params as any;
627
- if (typeof _splat !== 'undefined') {
628
- return { ...rest, '*': _splat };
629
- }
630
- return rest;
631
- }
632
-
633
- function createRouteStaticData(opts: {
634
- modernRouteId?: string;
635
- modernRouteAction?: unknown;
636
- modernRouteLoader?: unknown;
637
- }) {
638
- const staticData: {
639
- modernRouteId?: string;
640
- modernRouteAction?: unknown;
641
- modernRouteLoader?: unknown;
642
- } = {};
643
-
644
- if (typeof opts.modernRouteId === 'string' && opts.modernRouteId.length > 0) {
645
- staticData.modernRouteId = opts.modernRouteId;
646
- }
647
-
648
- if (typeof opts.modernRouteLoader !== 'undefined') {
649
- staticData.modernRouteLoader = opts.modernRouteLoader;
650
- }
651
-
652
- if (typeof opts.modernRouteAction !== 'undefined') {
653
- staticData.modernRouteAction = opts.modernRouteAction;
654
- }
655
-
656
- return staticData;
657
- }
658
-
659
- function getLoaderSignal(ctx: any): AbortSignal {
660
- const abortSignal = ctx?.abortController?.signal;
661
- if (abortSignal instanceof AbortSignal) {
662
- return abortSignal;
663
- }
664
- if (ctx?.signal instanceof AbortSignal) {
665
- return ctx.signal;
666
- }
667
- return new AbortController().signal;
668
- }
669
-
670
- function getLoaderHref(ctx: any): string {
671
- if (typeof ctx?.location === 'string') {
672
- return ctx.location;
673
- }
674
-
675
- const publicHref = ctx?.location?.publicHref;
676
- if (typeof publicHref === 'string') {
677
- return publicHref;
678
- }
679
-
680
- const href = ctx?.location?.href;
681
- if (typeof href === 'string') {
682
- return href;
683
- }
684
-
685
- const urlHref = ctx?.location?.url?.href;
686
- return typeof urlHref === 'string' ? urlHref : '';
687
- }
688
-
689
- function getLoaderParams(ctx: any): Record<string, string> {
690
- return typeof ctx?.params === 'object' && ctx.params !== null ? ctx.params : {};
691
- }
692
-
693
- function handleModernLoaderResult<LoaderResult>(result: LoaderResult): LoaderResult {
694
- if (isResponse(result)) {
695
- if (isRedirectResponse(result)) {
696
- const location = result.headers.get('Location') ?? '/';
697
- throwTanstackRedirect(location);
698
- }
699
- if (result.status === 404) {
700
- throw notFound();
701
- }
702
- }
703
-
704
- return result;
705
- }
706
-
707
- function handleModernLoaderError(err: unknown): never {
708
- if (isResponse(err)) {
709
- if (isRedirectResponse(err)) {
710
- const location = err.headers.get('Location') ?? '/';
711
- throwTanstackRedirect(location);
712
- }
713
- if (err.status === 404) {
714
- throw notFound();
715
- }
716
- }
717
-
718
- throw err;
719
- }
720
-
721
- function modernLoaderToTanstack<TLoader extends (args: any) => any>(
722
- opts: { hasSplat: boolean },
723
- modernLoader: TLoader,
724
- ) {
725
- type LoaderResult = Awaited<ReturnType<TLoader>>;
726
-
727
- return (ctx: any): Promise<LoaderResult> => {
728
- try {
729
- const signal = getLoaderSignal(ctx);
730
- const baseRequest: Request | undefined =
731
- ctx?.context?.request instanceof Request ? ctx.context.request : undefined;
732
-
733
- const href = getLoaderHref(ctx);
734
-
735
- const request = baseRequest !== undefined
736
- ? new Request(baseRequest, { signal })
737
- : new Request(href, { signal });
738
-
739
- const params = mapParamsForModernLoader(getLoaderParams(ctx), opts.hasSplat);
740
-
741
- return Promise.resolve(
742
- (modernLoader as any)({
743
- request,
744
- params,
745
- context: ctx?.context?.requestContext,
746
- }),
747
- )
748
- .then((result: LoaderResult) => handleModernLoaderResult(result))
749
- .catch(handleModernLoaderError);
750
- } catch (err) {
751
- handleModernLoaderError(err);
752
- }
753
- };
754
- }
755
-
756
620
  ${imports.join('\n')}
757
621
 
758
622
  export const rootRoute = createRootRouteWithContext<ModernRouterContext>()({
@@ -1,20 +1,10 @@
1
- import { createSyncHook } from '@modern-js/plugin';
2
- import type { TRuntimeContext } from '@modern-js/runtime/context';
3
- import type { RouteObject } from '@modern-js/runtime-utils/router';
4
- import type { RouterLifecycleContext } from './lifecycle';
5
-
6
- const modifyRoutes = createSyncHook<(routes: RouteObject[]) => RouteObject[]>();
7
- const onBeforeCreateRoutes =
8
- createSyncHook<(context: TRuntimeContext) => void>();
9
- const onBeforeCreateRouter =
10
- createSyncHook<(context: RouterLifecycleContext) => void>();
11
- const onAfterCreateRouter =
12
- createSyncHook<(context: RouterLifecycleContext) => void>();
13
- const onBeforeHydrateRouter =
14
- createSyncHook<(context: RouterLifecycleContext) => void>();
15
- const onAfterHydrateRouter =
16
- createSyncHook<(context: RouterLifecycleContext) => void>();
17
-
1
+ /**
2
+ * The router hooks are owned by @modern-js/runtime — this module re-exports
3
+ * the canonical instances through the `/context` seam, so the TanStack
4
+ * provider taps and calls the exact same hooks the built-in router wrapper
5
+ * registers. Creating separate hook instances here would silently split the
6
+ * hook registry between the wrapper and this provider.
7
+ */
18
8
  export {
19
9
  modifyRoutes,
20
10
  onAfterCreateRouter,
@@ -22,13 +12,6 @@ export {
22
12
  onBeforeCreateRouter,
23
13
  onBeforeCreateRoutes,
24
14
  onBeforeHydrateRouter,
25
- };
26
-
27
- export type RouterExtendsHooks = {
28
- modifyRoutes: typeof modifyRoutes;
29
- onBeforeCreateRoutes: typeof onBeforeCreateRoutes;
30
- onBeforeCreateRouter: typeof onBeforeCreateRouter;
31
- onAfterCreateRouter: typeof onAfterCreateRouter;
32
- onBeforeHydrateRouter: typeof onBeforeHydrateRouter;
33
- onAfterHydrateRouter: typeof onAfterHydrateRouter;
34
- };
15
+ type RouterExtendsHooks,
16
+ routerProviderRegistryHooks,
17
+ } from '@modern-js/runtime/context';
@@ -1,104 +1,6 @@
1
- export type * from '@tanstack/react-router';
2
- export {
3
- Asset,
4
- Await,
5
- Block,
6
- CatchBoundary,
7
- CatchNotFound,
8
- ClientOnly,
9
- cleanPath,
10
- composeRewrites,
11
- createBrowserHistory,
12
- createControlledPromise,
13
- createFileRoute,
14
- createHashHistory,
15
- createHistory,
16
- createLazyFileRoute,
17
- createLazyRoute,
18
- createLink,
19
- createMemoryHistory,
20
- createRootRoute,
21
- createRootRouteWithContext,
22
- createRoute,
23
- createRouteMask,
24
- createRouter,
25
- createRouterConfig,
26
- createSerializationAdapter,
27
- DEFAULT_PROTOCOL_ALLOWLIST,
28
- DefaultGlobalNotFound,
29
- deepEqual,
30
- defaultParseSearch,
31
- defaultStringifySearch,
32
- defer,
33
- ErrorComponent,
34
- FileRoute,
35
- FileRouteLoader,
36
- functionalUpdate,
37
- getRouteApi,
38
- HeadContent,
39
- interpolatePath,
40
- isMatch,
41
- isNotFound,
42
- isPlainArray,
43
- isPlainObject,
44
- isRedirect,
45
- joinPaths,
46
- LazyRoute,
47
- lazyFn,
48
- lazyRouteComponent,
49
- linkOptions,
50
- Match,
51
- Matches,
52
- MatchRoute,
53
- Navigate,
54
- NotFoundRoute,
55
- notFound,
56
- parseSearchWith,
57
- RootRoute,
58
- Route,
59
- RouteApi,
60
- Router,
61
- RouterContextProvider,
62
- RouterProvider,
63
- reactUse,
64
- redirect,
65
- replaceEqualDeep,
66
- resolvePath,
67
- retainSearchParams,
68
- rootRouteId,
69
- rootRouteWithContext,
70
- ScriptOnce,
71
- Scripts,
72
- ScrollRestoration,
73
- SearchParamError,
74
- stringifySearchWith,
75
- stripSearchParams,
76
- trimPath,
77
- trimPathLeft,
78
- trimPathRight,
79
- useAwaited,
80
- useBlocker,
81
- useCanGoBack,
82
- useChildMatches,
83
- useElementScrollRestoration,
84
- useHydrated,
85
- useLayoutEffect,
86
- useLinkProps,
87
- useLoaderData,
88
- useLoaderDeps,
89
- useLocation,
90
- useMatch,
91
- useMatches,
92
- useMatchRoute,
93
- useNavigate,
94
- useParams,
95
- useParentMatches,
96
- useRouteContext,
97
- useRouter,
98
- useRouterState,
99
- useSearch,
100
- useTags,
101
- } from '@tanstack/react-router';
1
+ import './register';
2
+
3
+ export * from '@tanstack/react-router';
102
4
  export type {
103
5
  Fetcher,
104
6
  FetcherState,
@@ -111,6 +13,13 @@ export {
111
13
  RouteActionResponseError,
112
14
  useFetcher,
113
15
  } from './dataMutation';
16
+ export type { ModernRouterContext } from './loaderBridge';
17
+ export {
18
+ createRouteStaticData,
19
+ isAbsoluteUrl,
20
+ modernLoaderToTanstack,
21
+ throwTanstackRedirect,
22
+ } from './loaderBridge';
114
23
  export { Outlet } from './outlet';
115
24
  export {
116
25
  tanstackRouterPlugin,
@@ -122,12 +31,8 @@ export type {
122
31
  PrefetchBehavior,
123
32
  } from './prefetchLink';
124
33
  export { Link, NavLink } from './prefetchLink';
125
- export type {
126
- AnyCompositeComponent,
127
- AnyRenderableServerComponent,
128
- CompositeComponentProps,
129
- } from './rsc/client';
130
- export { CompositeComponent } from './rsc/client';
34
+ export type { TanstackRouterState } from './state';
35
+ export { getTanstackRouterState } from './state';
131
36
  export type { RouterConfig } from './types';
132
37
  export {
133
38
  getModernTanstackRouterFastDefaults,