@bleedingdev/modern-js-plugin-tanstack 3.4.0-ultramodern.2 → 3.4.0-ultramodern.20

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.
@@ -73,7 +73,7 @@ var __webpack_exports__ = {};
73
73
  function getRuntimeRouterCli() {
74
74
  if (runtimeRouterCli) return runtimeRouterCli;
75
75
  const cli = __webpack_require__("@modern-js/runtime/cli");
76
- if (cli.handleGeneratorEntryCode && cli.getEntrypointRoutesDir && cli.getEntrypointRoutesOwner) {
76
+ if (cli.handleGeneratorEntryCode && cli.getEntrypointRoutesDir && cli.getEntrypointRoutesOwner && cli.updateNestedRoutesSpec) {
77
77
  runtimeRouterCli = cli;
78
78
  return runtimeRouterCli;
79
79
  }
@@ -284,11 +284,8 @@ ${canonicalRoutesAugmentation}`;
284
284
  if (isTanstackEntrypoint(entrypoint)) {
285
285
  const { distDirectory } = api.getAppContext();
286
286
  const nestedRoutesSpecPath = external_node_path_default().resolve(distDirectory, utils_namespaceObject.NESTED_ROUTE_SPEC_FILE);
287
- const existingNestedRoutes = await utils_namespaceObject.fs.pathExists(nestedRoutesSpecPath) ? await utils_namespaceObject.fs.readJSON(nestedRoutesSpecPath) : {};
288
- await utils_namespaceObject.fs.outputJSON(nestedRoutesSpecPath, {
289
- ...existingNestedRoutes,
290
- ...nestedRoutesForServer
291
- });
287
+ const { updateNestedRoutesSpec } = getRuntimeRouterCli();
288
+ await updateNestedRoutesSpec(nestedRoutesSpecPath, nestedRoutesForServer);
292
289
  }
293
290
  return {
294
291
  entrypoint,
@@ -18,6 +18,9 @@ var __webpack_modules__ = {
18
18
  "./register" (module) {
19
19
  module.exports = require("./register.js");
20
20
  },
21
+ "./routeHooks" (module) {
22
+ module.exports = require("./routeHooks.js");
23
+ },
21
24
  "./state" (module) {
22
25
  module.exports = require("./state.js");
23
26
  },
@@ -80,17 +83,22 @@ var __webpack_exports__ = {};
80
83
  var __rspack_reexport = {};
81
84
  for(const __rspack_import_key in _tanstack_react_router__rspack_import_1)if ([
82
85
  "throwTanstackRedirect",
86
+ "useParentMatches",
83
87
  "useFetcher",
84
88
  "modernLoaderToTanstack",
85
89
  "createRouteStaticData",
90
+ "useMatches",
91
+ "useRouterState",
86
92
  "Form",
87
93
  "Link",
88
94
  "default",
89
95
  "isAbsoluteUrl",
90
96
  "NavLink",
91
97
  "getModernTanstackRouterFastDefaults",
92
- "modernTanstackRouterFastDefaults",
98
+ "useChildMatches",
93
99
  "tanstackRouterPlugin",
100
+ "useMatch",
101
+ "modernTanstackRouterFastDefaults",
94
102
  "RouteActionResponseError",
95
103
  "Outlet",
96
104
  "getTanstackRouterState"
@@ -101,8 +109,9 @@ var __webpack_exports__ = {};
101
109
  var _outlet__rspack_import_4 = __webpack_require__("./outlet");
102
110
  var _plugin__rspack_import_5 = __webpack_require__("./plugin");
103
111
  var _prefetchLink__rspack_import_6 = __webpack_require__("./prefetchLink");
104
- var _state__rspack_import_7 = __webpack_require__("./state");
105
- var _types__rspack_import_8 = __webpack_require__("./types");
112
+ var _routeHooks__rspack_import_7 = __webpack_require__("./routeHooks");
113
+ var _state__rspack_import_8 = __webpack_require__("./state");
114
+ var _types__rspack_import_9 = __webpack_require__("./types");
106
115
  __webpack_require__.d(__webpack_exports__, {
107
116
  Form: ()=>_dataMutation__rspack_import_2.Form,
108
117
  Link: ()=>_prefetchLink__rspack_import_6.Link,
@@ -111,14 +120,19 @@ var __webpack_exports__ = {};
111
120
  RouteActionResponseError: ()=>_dataMutation__rspack_import_2.RouteActionResponseError,
112
121
  createRouteStaticData: ()=>_loaderBridge__rspack_import_3.createRouteStaticData,
113
122
  default: ()=>_plugin__rspack_import_5.tanstackRouterPlugin,
114
- getModernTanstackRouterFastDefaults: ()=>_types__rspack_import_8.getModernTanstackRouterFastDefaults,
115
- getTanstackRouterState: ()=>_state__rspack_import_7.getTanstackRouterState,
123
+ getModernTanstackRouterFastDefaults: ()=>_types__rspack_import_9.getModernTanstackRouterFastDefaults,
124
+ getTanstackRouterState: ()=>_state__rspack_import_8.getTanstackRouterState,
116
125
  isAbsoluteUrl: ()=>_loaderBridge__rspack_import_3.isAbsoluteUrl,
117
126
  modernLoaderToTanstack: ()=>_loaderBridge__rspack_import_3.modernLoaderToTanstack,
118
- modernTanstackRouterFastDefaults: ()=>_types__rspack_import_8.modernTanstackRouterFastDefaults,
127
+ modernTanstackRouterFastDefaults: ()=>_types__rspack_import_9.modernTanstackRouterFastDefaults,
119
128
  tanstackRouterPlugin: ()=>_plugin__rspack_import_5.tanstackRouterPlugin,
120
129
  throwTanstackRedirect: ()=>_loaderBridge__rspack_import_3.throwTanstackRedirect,
121
- useFetcher: ()=>_dataMutation__rspack_import_2.useFetcher
130
+ useChildMatches: ()=>_routeHooks__rspack_import_7.useChildMatches,
131
+ useFetcher: ()=>_dataMutation__rspack_import_2.useFetcher,
132
+ useMatch: ()=>_routeHooks__rspack_import_7.useMatch,
133
+ useMatches: ()=>_routeHooks__rspack_import_7.useMatches,
134
+ useParentMatches: ()=>_routeHooks__rspack_import_7.useParentMatches,
135
+ useRouterState: ()=>_routeHooks__rspack_import_7.useRouterState
122
136
  });
123
137
  })();
124
138
  exports.Form = __webpack_exports__.Form;
@@ -135,7 +149,12 @@ exports.modernLoaderToTanstack = __webpack_exports__.modernLoaderToTanstack;
135
149
  exports.modernTanstackRouterFastDefaults = __webpack_exports__.modernTanstackRouterFastDefaults;
136
150
  exports.tanstackRouterPlugin = __webpack_exports__.tanstackRouterPlugin;
137
151
  exports.throwTanstackRedirect = __webpack_exports__.throwTanstackRedirect;
152
+ exports.useChildMatches = __webpack_exports__.useChildMatches;
138
153
  exports.useFetcher = __webpack_exports__.useFetcher;
154
+ exports.useMatch = __webpack_exports__.useMatch;
155
+ exports.useMatches = __webpack_exports__.useMatches;
156
+ exports.useParentMatches = __webpack_exports__.useParentMatches;
157
+ exports.useRouterState = __webpack_exports__.useRouterState;
139
158
  for(var __rspack_i in __webpack_exports__)if (-1 === [
140
159
  "Form",
141
160
  "Link",
@@ -151,7 +170,12 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
151
170
  "modernTanstackRouterFastDefaults",
152
171
  "tanstackRouterPlugin",
153
172
  "throwTanstackRedirect",
154
- "useFetcher"
173
+ "useChildMatches",
174
+ "useFetcher",
175
+ "useMatch",
176
+ "useMatches",
177
+ "useParentMatches",
178
+ "useRouterState"
155
179
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
156
180
  Object.defineProperty(exports, '__esModule', {
157
181
  value: true
@@ -43,6 +43,7 @@ const external_lifecycle_js_namespaceObject = require("./lifecycle.js");
43
43
  const external_outlet_js_namespaceObject = require("./outlet.js");
44
44
  const external_pluginCore_js_namespaceObject = require("./pluginCore.js");
45
45
  const external_prefetchLink_js_namespaceObject = require("./prefetchLink.js");
46
+ const external_routeHooks_js_namespaceObject = require("./routeHooks.js");
46
47
  const external_routeTree_js_namespaceObject = require("./routeTree.js");
47
48
  const client_js_namespaceObject = require("./rsc/client.js");
48
49
  const external_types_js_namespaceObject = require("./types.js");
@@ -253,7 +254,7 @@ const tanstackRouterPlugin = (userConfig = {})=>{
253
254
  }
254
255
  context.router = {
255
256
  Link: external_prefetchLink_js_namespaceObject.Link,
256
- useMatches: react_router_namespaceObject.useMatches,
257
+ useMatches: external_routeHooks_js_namespaceObject.useMatches,
257
258
  useLocation: react_router_namespaceObject.useLocation,
258
259
  useNavigate: react_router_namespaceObject.useNavigate,
259
260
  useRouter: react_router_namespaceObject.useRouter
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ __webpack_require__.d(__webpack_exports__, {
31
+ useChildMatches: ()=>useChildMatches,
32
+ useMatch: ()=>useMatch,
33
+ useMatches: ()=>useMatches,
34
+ useParentMatches: ()=>useParentMatches,
35
+ useRouterState: ()=>useRouterState
36
+ });
37
+ const react_router_namespaceObject = require("@tanstack/react-router");
38
+ const withWholeObjectStructuralSharingGuard = (options)=>{
39
+ if (void 0 !== options && (void 0 !== options.select || void 0 !== options.structuralSharing)) return options;
40
+ if (void 0 === options) return {
41
+ structuralSharing: false
42
+ };
43
+ return {
44
+ ...options,
45
+ structuralSharing: false
46
+ };
47
+ };
48
+ const useMatchWithWholeObjectGuard = (options)=>(0, react_router_namespaceObject.useMatch)(withWholeObjectStructuralSharingGuard(options));
49
+ const useMatchesWithWholeObjectGuard = (options)=>(0, react_router_namespaceObject.useMatches)(withWholeObjectStructuralSharingGuard(options));
50
+ const useParentMatchesWithWholeObjectGuard = (options)=>(0, react_router_namespaceObject.useParentMatches)(withWholeObjectStructuralSharingGuard(options));
51
+ const useChildMatchesWithWholeObjectGuard = (options)=>(0, react_router_namespaceObject.useChildMatches)(withWholeObjectStructuralSharingGuard(options));
52
+ const useRouterStateWithWholeObjectGuard = (options)=>(0, react_router_namespaceObject.useRouterState)(withWholeObjectStructuralSharingGuard(options));
53
+ const useMatch = useMatchWithWholeObjectGuard;
54
+ const useMatches = useMatchesWithWholeObjectGuard;
55
+ const useParentMatches = useParentMatchesWithWholeObjectGuard;
56
+ const useChildMatches = useChildMatchesWithWholeObjectGuard;
57
+ const useRouterState = useRouterStateWithWholeObjectGuard;
58
+ exports.useChildMatches = __webpack_exports__.useChildMatches;
59
+ exports.useMatch = __webpack_exports__.useMatch;
60
+ exports.useMatches = __webpack_exports__.useMatches;
61
+ exports.useParentMatches = __webpack_exports__.useParentMatches;
62
+ exports.useRouterState = __webpack_exports__.useRouterState;
63
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
64
+ "useChildMatches",
65
+ "useMatch",
66
+ "useMatches",
67
+ "useParentMatches",
68
+ "useRouterState"
69
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
70
+ Object.defineProperty(exports, '__esModule', {
71
+ value: true
72
+ });
@@ -16,7 +16,7 @@ let runtimeRouterCli;
16
16
  function getRuntimeRouterCli() {
17
17
  if (runtimeRouterCli) return runtimeRouterCli;
18
18
  const cli = __webpack_require__(2320);
19
- if (cli.handleGeneratorEntryCode && cli.getEntrypointRoutesDir && cli.getEntrypointRoutesOwner) {
19
+ if (cli.handleGeneratorEntryCode && cli.getEntrypointRoutesDir && cli.getEntrypointRoutesOwner && cli.updateNestedRoutesSpec) {
20
20
  runtimeRouterCli = cli;
21
21
  return runtimeRouterCli;
22
22
  }
@@ -227,11 +227,8 @@ function tanstackRouterPlugin(options = {}) {
227
227
  if (isTanstackEntrypoint(entrypoint)) {
228
228
  const { distDirectory } = api.getAppContext();
229
229
  const nestedRoutesSpecPath = node_path.resolve(distDirectory, NESTED_ROUTE_SPEC_FILE);
230
- const existingNestedRoutes = await fs.pathExists(nestedRoutesSpecPath) ? await fs.readJSON(nestedRoutesSpecPath) : {};
231
- await fs.outputJSON(nestedRoutesSpecPath, {
232
- ...existingNestedRoutes,
233
- ...nestedRoutesForServer
234
- });
230
+ const { updateNestedRoutesSpec } = getRuntimeRouterCli();
231
+ await updateNestedRoutesSpec(nestedRoutesSpecPath, nestedRoutesForServer);
235
232
  }
236
233
  return {
237
234
  entrypoint,
@@ -5,5 +5,6 @@ export { createRouteStaticData, isAbsoluteUrl, modernLoaderToTanstack, throwTans
5
5
  export { Outlet } from "./outlet.mjs";
6
6
  export { tanstackRouterPlugin as default, tanstackRouterPlugin } from "./plugin.mjs";
7
7
  export { Link, NavLink } from "./prefetchLink.mjs";
8
+ export { useChildMatches, useMatch, useMatches, useParentMatches, useRouterState } from "./routeHooks.mjs";
8
9
  export { getTanstackRouterState } from "./state.mjs";
9
10
  export { getModernTanstackRouterFastDefaults, modernTanstackRouterFastDefaults } from "./types.mjs";
@@ -1,7 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { InternalRuntimeContext, getGlobalEnableRsc } from "@modern-js/runtime/context";
3
3
  import { normalizePathname } from "@modern-js/runtime-utils/url";
4
- import { RouterProvider, createBrowserHistory, createHashHistory, createRouter, useLocation, useMatches, useNavigate, useRouter } from "@tanstack/react-router";
4
+ import { RouterProvider, createBrowserHistory, createHashHistory, createRouter, useLocation, useNavigate, useRouter } from "@tanstack/react-router";
5
5
  import { useContext, useMemo } from "react";
6
6
  import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
7
7
  import { routerProviderRegistryHooks } from "./hooks.mjs";
@@ -10,6 +10,7 @@ import { applyRouterRuntimeState } from "./lifecycle.mjs";
10
10
  import { withModernRouteMatchContext } from "./outlet.mjs";
11
11
  import { getFinalRouteConfig, getMergedRouterConfig } from "./pluginCore.mjs";
12
12
  import { Link } from "./prefetchLink.mjs";
13
+ import { useMatches } from "./routeHooks.mjs";
13
14
  import { createRouteTreeFromRouteObjects } from "./routeTree.mjs";
14
15
  import { getTanstackRscSerializationAdapters } from "./rsc/client.mjs";
15
16
  import { getModernTanstackRouterFastDefaults } from "./types.mjs";
@@ -0,0 +1,22 @@
1
+ import { useChildMatches, useMatch, useMatches, useParentMatches, useRouterState } from "@tanstack/react-router";
2
+ const withWholeObjectStructuralSharingGuard = (options)=>{
3
+ if (void 0 !== options && (void 0 !== options.select || void 0 !== options.structuralSharing)) return options;
4
+ if (void 0 === options) return {
5
+ structuralSharing: false
6
+ };
7
+ return {
8
+ ...options,
9
+ structuralSharing: false
10
+ };
11
+ };
12
+ const useMatchWithWholeObjectGuard = (options)=>useMatch(withWholeObjectStructuralSharingGuard(options));
13
+ const useMatchesWithWholeObjectGuard = (options)=>useMatches(withWholeObjectStructuralSharingGuard(options));
14
+ const useParentMatchesWithWholeObjectGuard = (options)=>useParentMatches(withWholeObjectStructuralSharingGuard(options));
15
+ const useChildMatchesWithWholeObjectGuard = (options)=>useChildMatches(withWholeObjectStructuralSharingGuard(options));
16
+ const useRouterStateWithWholeObjectGuard = (options)=>useRouterState(withWholeObjectStructuralSharingGuard(options));
17
+ const routeHooks_useMatch = useMatchWithWholeObjectGuard;
18
+ const routeHooks_useMatches = useMatchesWithWholeObjectGuard;
19
+ const routeHooks_useParentMatches = useParentMatchesWithWholeObjectGuard;
20
+ const routeHooks_useChildMatches = useChildMatchesWithWholeObjectGuard;
21
+ const routeHooks_useRouterState = useRouterStateWithWholeObjectGuard;
22
+ export { routeHooks_useChildMatches as useChildMatches, routeHooks_useMatch as useMatch, routeHooks_useMatches as useMatches, routeHooks_useParentMatches as useParentMatches, routeHooks_useRouterState as useRouterState };
@@ -20,7 +20,7 @@ let runtimeRouterCli;
20
20
  function getRuntimeRouterCli() {
21
21
  if (runtimeRouterCli) return runtimeRouterCli;
22
22
  const cli = __webpack_require__("@modern-js/runtime/cli?9b14");
23
- if (cli.handleGeneratorEntryCode && cli.getEntrypointRoutesDir && cli.getEntrypointRoutesOwner) {
23
+ if (cli.handleGeneratorEntryCode && cli.getEntrypointRoutesDir && cli.getEntrypointRoutesOwner && cli.updateNestedRoutesSpec) {
24
24
  runtimeRouterCli = cli;
25
25
  return runtimeRouterCli;
26
26
  }
@@ -231,11 +231,8 @@ function tanstackRouterPlugin(options = {}) {
231
231
  if (isTanstackEntrypoint(entrypoint)) {
232
232
  const { distDirectory } = api.getAppContext();
233
233
  const nestedRoutesSpecPath = node_path.resolve(distDirectory, NESTED_ROUTE_SPEC_FILE);
234
- const existingNestedRoutes = await fs.pathExists(nestedRoutesSpecPath) ? await fs.readJSON(nestedRoutesSpecPath) : {};
235
- await fs.outputJSON(nestedRoutesSpecPath, {
236
- ...existingNestedRoutes,
237
- ...nestedRoutesForServer
238
- });
234
+ const { updateNestedRoutesSpec } = getRuntimeRouterCli();
235
+ await updateNestedRoutesSpec(nestedRoutesSpecPath, nestedRoutesForServer);
239
236
  }
240
237
  return {
241
238
  entrypoint,
@@ -6,5 +6,6 @@ export { createRouteStaticData, isAbsoluteUrl, modernLoaderToTanstack, throwTans
6
6
  export { Outlet } from "./outlet.mjs";
7
7
  export { tanstackRouterPlugin as default, tanstackRouterPlugin } from "./plugin.mjs";
8
8
  export { Link, NavLink } from "./prefetchLink.mjs";
9
+ export { useChildMatches, useMatch, useMatches, useParentMatches, useRouterState } from "./routeHooks.mjs";
9
10
  export { getTanstackRouterState } from "./state.mjs";
10
11
  export { getModernTanstackRouterFastDefaults, modernTanstackRouterFastDefaults } from "./types.mjs";
@@ -2,7 +2,7 @@ import "node:module";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { InternalRuntimeContext, getGlobalEnableRsc } from "@modern-js/runtime/context";
4
4
  import { normalizePathname } from "@modern-js/runtime-utils/url";
5
- import { RouterProvider, createBrowserHistory, createHashHistory, createRouter, useLocation, useMatches, useNavigate, useRouter } from "@tanstack/react-router";
5
+ import { RouterProvider, createBrowserHistory, createHashHistory, createRouter, useLocation, useNavigate, useRouter } from "@tanstack/react-router";
6
6
  import { useContext, useMemo } from "react";
7
7
  import { createModernBasepathRewrite } from "./basepathRewrite.mjs";
8
8
  import { routerProviderRegistryHooks } from "./hooks.mjs";
@@ -11,6 +11,7 @@ import { applyRouterRuntimeState } from "./lifecycle.mjs";
11
11
  import { withModernRouteMatchContext } from "./outlet.mjs";
12
12
  import { getFinalRouteConfig, getMergedRouterConfig } from "./pluginCore.mjs";
13
13
  import { Link } from "./prefetchLink.mjs";
14
+ import { useMatches } from "./routeHooks.mjs";
14
15
  import { createRouteTreeFromRouteObjects } from "./routeTree.mjs";
15
16
  import { getTanstackRscSerializationAdapters } from "./rsc/client.mjs";
16
17
  import { getModernTanstackRouterFastDefaults } from "./types.mjs";
@@ -0,0 +1,23 @@
1
+ import "node:module";
2
+ import { useChildMatches, useMatch, useMatches, useParentMatches, useRouterState } from "@tanstack/react-router";
3
+ const withWholeObjectStructuralSharingGuard = (options)=>{
4
+ if (void 0 !== options && (void 0 !== options.select || void 0 !== options.structuralSharing)) return options;
5
+ if (void 0 === options) return {
6
+ structuralSharing: false
7
+ };
8
+ return {
9
+ ...options,
10
+ structuralSharing: false
11
+ };
12
+ };
13
+ const useMatchWithWholeObjectGuard = (options)=>useMatch(withWholeObjectStructuralSharingGuard(options));
14
+ const useMatchesWithWholeObjectGuard = (options)=>useMatches(withWholeObjectStructuralSharingGuard(options));
15
+ const useParentMatchesWithWholeObjectGuard = (options)=>useParentMatches(withWholeObjectStructuralSharingGuard(options));
16
+ const useChildMatchesWithWholeObjectGuard = (options)=>useChildMatches(withWholeObjectStructuralSharingGuard(options));
17
+ const useRouterStateWithWholeObjectGuard = (options)=>useRouterState(withWholeObjectStructuralSharingGuard(options));
18
+ const routeHooks_useMatch = useMatchWithWholeObjectGuard;
19
+ const routeHooks_useMatches = useMatchesWithWholeObjectGuard;
20
+ const routeHooks_useParentMatches = useParentMatchesWithWholeObjectGuard;
21
+ const routeHooks_useChildMatches = useChildMatchesWithWholeObjectGuard;
22
+ const routeHooks_useRouterState = useRouterStateWithWholeObjectGuard;
23
+ export { routeHooks_useChildMatches as useChildMatches, routeHooks_useMatch as useMatch, routeHooks_useMatches as useMatches, routeHooks_useParentMatches as useParentMatches, routeHooks_useRouterState as useRouterState };
@@ -8,6 +8,7 @@ export { Outlet } from './outlet';
8
8
  export { tanstackRouterPlugin, tanstackRouterPlugin as default, } from './plugin';
9
9
  export type { LinkProps, NavLinkProps, PrefetchBehavior, } from './prefetchLink';
10
10
  export { Link, NavLink } from './prefetchLink';
11
+ export { useChildMatches, useMatch, useMatches, useParentMatches, useRouterState, } from './routeHooks';
11
12
  export type { TanstackRouterState } from './state';
12
13
  export { getTanstackRouterState } from './state';
13
14
  export type { RouterConfig } from './types';
@@ -0,0 +1,6 @@
1
+ import { useChildMatches as useTanstackChildMatches, useMatch as useTanstackMatch, useMatches as useTanstackMatches, useParentMatches as useTanstackParentMatches, useRouterState as useTanstackRouterState } from '@tanstack/react-router';
2
+ export declare const useMatch: typeof useTanstackMatch;
3
+ export declare const useMatches: typeof useTanstackMatches;
4
+ export declare const useParentMatches: typeof useTanstackParentMatches;
5
+ export declare const useChildMatches: typeof useTanstackChildMatches;
6
+ export declare const useRouterState: typeof useTanstackRouterState;
package/package.json CHANGED
@@ -18,7 +18,7 @@
18
18
  "modern.js",
19
19
  "tanstack-router"
20
20
  ],
21
- "version": "3.4.0-ultramodern.2",
21
+ "version": "3.4.0-ultramodern.20",
22
22
  "engines": {
23
23
  "node": ">=20"
24
24
  },
@@ -77,13 +77,13 @@
77
77
  "@swc/helpers": "^0.5.23",
78
78
  "@tanstack/react-router": "1.170.16",
79
79
  "@tanstack/router-core": "1.171.13",
80
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.4.0-ultramodern.2",
81
- "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.4.0-ultramodern.2",
82
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.4.0-ultramodern.2",
83
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.4.0-ultramodern.2"
80
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.4.0-ultramodern.20",
81
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.4.0-ultramodern.20",
82
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.4.0-ultramodern.20",
83
+ "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.4.0-ultramodern.20"
84
84
  },
85
85
  "peerDependencies": {
86
- "@modern-js/runtime": "3.4.0-ultramodern.2",
86
+ "@modern-js/runtime": "3.4.0-ultramodern.20",
87
87
  "react": "^19.2.7",
88
88
  "react-dom": "^19.2.7"
89
89
  },
@@ -98,9 +98,9 @@
98
98
  "@typescript/native-preview": "7.0.0-dev.20260624.1",
99
99
  "react": "^19.2.7",
100
100
  "react-dom": "^19.2.7",
101
- "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.4.0-ultramodern.2",
102
- "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.4.0-ultramodern.2",
103
- "@scripts/rstest-config": "2.66.0"
101
+ "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.4.0-ultramodern.20",
102
+ "@scripts/rstest-config": "2.66.0",
103
+ "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.4.0-ultramodern.20"
104
104
  },
105
105
  "sideEffects": [
106
106
  "./src/runtime/register.ts",
package/rstest.config.mts CHANGED
@@ -28,7 +28,9 @@ export default {
28
28
  'tests/router/hooks.test.ts',
29
29
  'tests/router/loaderBridge.test.ts',
30
30
  'tests/router/packageSurface.test.ts',
31
+ 'tests/router/preloadRedirect.test.ts',
31
32
  'tests/router/register.test.ts',
33
+ 'tests/router/routeHooks.test.ts',
32
34
  'tests/router/rsc.test.tsx',
33
35
  'tests/router/tanstackTypes.test.ts',
34
36
  'tests/router/routeTree.test.ts',
package/src/cli/index.ts CHANGED
@@ -83,6 +83,10 @@ type RuntimeRouterCliHelpers = {
83
83
  },
84
84
  ) => Promise<Entrypoint[]>;
85
85
  isRouteEntry: (dir: string, routesDir?: string) => string | false;
86
+ updateNestedRoutesSpec: (
87
+ specPath: string,
88
+ nextRoutes: Record<string, unknown>,
89
+ ) => Promise<void>;
86
90
  };
87
91
 
88
92
  let runtimeRouterCli: RuntimeRouterCliHelpers | undefined;
@@ -97,7 +101,8 @@ function getRuntimeRouterCli(): RuntimeRouterCliHelpers {
97
101
  if (
98
102
  cli.handleGeneratorEntryCode &&
99
103
  cli.getEntrypointRoutesDir &&
100
- cli.getEntrypointRoutesOwner
104
+ cli.getEntrypointRoutesOwner &&
105
+ cli.updateNestedRoutesSpec
101
106
  ) {
102
107
  runtimeRouterCli = cli as RuntimeRouterCliHelpers;
103
108
  return runtimeRouterCli;
@@ -497,19 +502,11 @@ export function tanstackRouterPlugin(
497
502
  distDirectory,
498
503
  NESTED_ROUTE_SPEC_FILE,
499
504
  );
500
- const existingNestedRoutes = (await fs.pathExists(
505
+ const { updateNestedRoutesSpec } = getRuntimeRouterCli();
506
+ await updateNestedRoutesSpec(
501
507
  nestedRoutesSpecPath,
502
- ))
503
- ? ((await fs.readJSON(nestedRoutesSpecPath)) as Record<
504
- string,
505
- unknown
506
- >)
507
- : {};
508
-
509
- await fs.outputJSON(nestedRoutesSpecPath, {
510
- ...existingNestedRoutes,
511
- ...nestedRoutesForServer,
512
- });
508
+ nestedRoutesForServer,
509
+ );
513
510
  }
514
511
 
515
512
  return {
@@ -31,6 +31,13 @@ export type {
31
31
  PrefetchBehavior,
32
32
  } from './prefetchLink';
33
33
  export { Link, NavLink } from './prefetchLink';
34
+ export {
35
+ useChildMatches,
36
+ useMatch,
37
+ useMatches,
38
+ useParentMatches,
39
+ useRouterState,
40
+ } from './routeHooks';
34
41
  export type { TanstackRouterState } from './state';
35
42
  export { getTanstackRouterState } from './state';
36
43
  export type { RouterConfig } from './types';
@@ -15,7 +15,6 @@ import {
15
15
  createRouter,
16
16
  RouterProvider,
17
17
  useLocation,
18
- useMatches,
19
18
  useNavigate,
20
19
  useRouter,
21
20
  } from '@tanstack/react-router';
@@ -35,6 +34,7 @@ import {
35
34
  type TanstackRouterRuntimePlugin,
36
35
  } from './pluginCore';
37
36
  import { Link } from './prefetchLink';
37
+ import { useMatches } from './routeHooks';
38
38
  import { createRouteTreeFromRouteObjects } from './routeTree';
39
39
  import { getTanstackRscSerializationAdapters } from './rsc/client';
40
40
  import {
@@ -0,0 +1,92 @@
1
+ import {
2
+ useChildMatches as useTanstackChildMatches,
3
+ useMatch as useTanstackMatch,
4
+ useMatches as useTanstackMatches,
5
+ useParentMatches as useTanstackParentMatches,
6
+ useRouterState as useTanstackRouterState,
7
+ } from '@tanstack/react-router';
8
+
9
+ type WholeObjectStructuralSharingOptions = {
10
+ readonly select?: unknown;
11
+ readonly structuralSharing?: boolean;
12
+ };
13
+
14
+ const withWholeObjectStructuralSharingGuard = <
15
+ TOptions extends WholeObjectStructuralSharingOptions | undefined,
16
+ >(
17
+ options: TOptions,
18
+ ): TOptions | WholeObjectStructuralSharingOptions => {
19
+ if (
20
+ options !== undefined &&
21
+ (options.select !== undefined || options.structuralSharing !== undefined)
22
+ ) {
23
+ return options;
24
+ }
25
+
26
+ if (options === undefined) {
27
+ return { structuralSharing: false };
28
+ }
29
+
30
+ return {
31
+ ...options,
32
+ structuralSharing: false,
33
+ };
34
+ };
35
+
36
+ type UseMatchOptions = Parameters<typeof useTanstackMatch>[0];
37
+ type UseMatchResult = ReturnType<typeof useTanstackMatch>;
38
+ type UseMatchesOptions = Parameters<typeof useTanstackMatches>[0];
39
+ type UseMatchesResult = ReturnType<typeof useTanstackMatches>;
40
+ type UseParentMatchesOptions = Parameters<typeof useTanstackParentMatches>[0];
41
+ type UseParentMatchesResult = ReturnType<typeof useTanstackParentMatches>;
42
+ type UseChildMatchesOptions = Parameters<typeof useTanstackChildMatches>[0];
43
+ type UseChildMatchesResult = ReturnType<typeof useTanstackChildMatches>;
44
+ type UseRouterStateOptions = Parameters<typeof useTanstackRouterState>[0];
45
+ type UseRouterStateResult = ReturnType<typeof useTanstackRouterState>;
46
+
47
+ const useMatchWithWholeObjectGuard = (
48
+ options: UseMatchOptions,
49
+ ): UseMatchResult =>
50
+ useTanstackMatch(
51
+ withWholeObjectStructuralSharingGuard(
52
+ options as WholeObjectStructuralSharingOptions,
53
+ ) as UseMatchOptions,
54
+ );
55
+
56
+ const useMatchesWithWholeObjectGuard = (
57
+ options?: UseMatchesOptions,
58
+ ): UseMatchesResult =>
59
+ useTanstackMatches(
60
+ withWholeObjectStructuralSharingGuard(options) as UseMatchesOptions,
61
+ );
62
+
63
+ const useParentMatchesWithWholeObjectGuard = (
64
+ options?: UseParentMatchesOptions,
65
+ ): UseParentMatchesResult =>
66
+ useTanstackParentMatches(
67
+ withWholeObjectStructuralSharingGuard(options) as UseParentMatchesOptions,
68
+ );
69
+
70
+ const useChildMatchesWithWholeObjectGuard = (
71
+ options?: UseChildMatchesOptions,
72
+ ): UseChildMatchesResult =>
73
+ useTanstackChildMatches(
74
+ withWholeObjectStructuralSharingGuard(options) as UseChildMatchesOptions,
75
+ );
76
+
77
+ const useRouterStateWithWholeObjectGuard = (
78
+ options?: UseRouterStateOptions,
79
+ ): UseRouterStateResult =>
80
+ useTanstackRouterState(
81
+ withWholeObjectStructuralSharingGuard(options) as UseRouterStateOptions,
82
+ );
83
+
84
+ export const useMatch = useMatchWithWholeObjectGuard as typeof useTanstackMatch;
85
+ export const useMatches =
86
+ useMatchesWithWholeObjectGuard as typeof useTanstackMatches;
87
+ export const useParentMatches =
88
+ useParentMatchesWithWholeObjectGuard as typeof useTanstackParentMatches;
89
+ export const useChildMatches =
90
+ useChildMatchesWithWholeObjectGuard as typeof useTanstackChildMatches;
91
+ export const useRouterState =
92
+ useRouterStateWithWholeObjectGuard as typeof useTanstackRouterState;
@@ -57,6 +57,18 @@ rstest.mock('@modern-js/runtime/cli', () => {
57
57
  const routesEntry = path.join(dir, routesDir);
58
58
  return fs.existsSync(routesEntry) ? routesEntry : false;
59
59
  },
60
+ updateNestedRoutesSpec: async (
61
+ specPath: string,
62
+ nextRoutes: Record<string, unknown>,
63
+ ) => {
64
+ const existingRoutes = fs.existsSync(specPath)
65
+ ? await fs.readJSON(specPath)
66
+ : {};
67
+ await fs.outputJSON(specPath, {
68
+ ...existingRoutes,
69
+ ...nextRoutes,
70
+ });
71
+ },
60
72
  };
61
73
  });
62
74
 
@@ -14,6 +14,13 @@ describe('tanstack router fast defaults', () => {
14
14
  });
15
15
 
16
16
  test('allows explicit structural sharing override', () => {
17
+ expect(
18
+ getModernTanstackRouterFastDefaults({
19
+ defaultStructuralSharing: true,
20
+ }),
21
+ ).toEqual({
22
+ defaultStructuralSharing: true,
23
+ });
17
24
  expect(
18
25
  getModernTanstackRouterFastDefaults({
19
26
  defaultStructuralSharing: false,
@@ -0,0 +1,69 @@
1
+ import { createMemoryHistory } from '@tanstack/history';
2
+ import {
3
+ createRootRoute,
4
+ createRoute,
5
+ createRouter,
6
+ redirect,
7
+ } from '@tanstack/react-router';
8
+
9
+ describe('tanstack router-core preload redirects', () => {
10
+ afterEach(() => {
11
+ rstest.restoreAllMocks();
12
+ });
13
+
14
+ test('keeps concurrent cached preload redirects from reading deleted matches', async () => {
15
+ const consoleErrorSpy = rstest
16
+ .spyOn(console, 'error')
17
+ .mockImplementation(() => {});
18
+ const rootRoute = createRootRoute();
19
+ const indexRoute = createRoute({
20
+ getParentRoute: () => rootRoute,
21
+ path: '/',
22
+ component: () => null,
23
+ });
24
+ let redirectLoaderCalls = 0;
25
+ const redirectRoute = createRoute({
26
+ getParentRoute: () => rootRoute,
27
+ path: '/redirect',
28
+ loader: async () => {
29
+ redirectLoaderCalls += 1;
30
+ await Promise.resolve();
31
+ throw redirect({ to: '/target' });
32
+ },
33
+ component: () => null,
34
+ });
35
+ const targetLoader = rstest.fn(async () => 'target');
36
+ const targetRoute = createRoute({
37
+ getParentRoute: () => rootRoute,
38
+ path: '/target',
39
+ loader: targetLoader,
40
+ component: () => null,
41
+ });
42
+ const router = createRouter({
43
+ routeTree: rootRoute.addChildren([
44
+ indexRoute,
45
+ redirectRoute,
46
+ targetRoute,
47
+ ]),
48
+ history: createMemoryHistory({
49
+ initialEntries: ['/'],
50
+ }),
51
+ defaultStructuralSharing: true,
52
+ });
53
+
54
+ await Promise.all([
55
+ router.preloadRoute({ to: '/redirect' }),
56
+ router.preloadRoute({ to: '/redirect' }),
57
+ ]);
58
+
59
+ expect(consoleErrorSpy).not.toHaveBeenCalled();
60
+ expect(router.options.defaultStructuralSharing).toBe(true);
61
+ expect(redirectLoaderCalls).toBeGreaterThan(0);
62
+ expect(targetLoader).toHaveBeenCalled();
63
+ expect(
64
+ router.stores.cachedMatches
65
+ .get()
66
+ .some(match => match.status === 'redirected'),
67
+ ).toBe(false);
68
+ });
69
+ });
@@ -0,0 +1,113 @@
1
+ const calls: Record<string, unknown[]> = {
2
+ useChildMatches: [],
3
+ useMatch: [],
4
+ useMatches: [],
5
+ useParentMatches: [],
6
+ useRouterState: [],
7
+ };
8
+
9
+ rstest.mock('@tanstack/react-router', () => ({
10
+ useChildMatches: (options: unknown) => {
11
+ calls.useChildMatches.push(options);
12
+ return options;
13
+ },
14
+ useMatch: (options: unknown) => {
15
+ calls.useMatch.push(options);
16
+ return options;
17
+ },
18
+ useMatches: (options: unknown) => {
19
+ calls.useMatches.push(options);
20
+ return options;
21
+ },
22
+ useParentMatches: (options: unknown) => {
23
+ calls.useParentMatches.push(options);
24
+ return options;
25
+ },
26
+ useRouterState: (options: unknown) => {
27
+ calls.useRouterState.push(options);
28
+ return options;
29
+ },
30
+ }));
31
+
32
+ import {
33
+ useChildMatches,
34
+ useMatch,
35
+ useMatches,
36
+ useParentMatches,
37
+ useRouterState,
38
+ } from '../../src/runtime/routeHooks';
39
+
40
+ const getLastCall = (hookName: keyof typeof calls) => {
41
+ const callList = calls[hookName];
42
+ return callList[callList.length - 1];
43
+ };
44
+
45
+ describe('tanstack route hook structural sharing guards', () => {
46
+ beforeEach(() => {
47
+ for (const hookName of Object.keys(calls)) {
48
+ calls[hookName] = [];
49
+ }
50
+ });
51
+
52
+ test('disables structural sharing for full internal router objects', () => {
53
+ useMatch({ from: '/' } as never);
54
+ useMatches();
55
+ useParentMatches();
56
+ useChildMatches();
57
+ useRouterState();
58
+
59
+ expect(getLastCall('useMatch')).toEqual({
60
+ from: '/',
61
+ structuralSharing: false,
62
+ });
63
+ expect(getLastCall('useMatches')).toEqual({
64
+ structuralSharing: false,
65
+ });
66
+ expect(getLastCall('useParentMatches')).toEqual({
67
+ structuralSharing: false,
68
+ });
69
+ expect(getLastCall('useChildMatches')).toEqual({
70
+ structuralSharing: false,
71
+ });
72
+ expect(getLastCall('useRouterState')).toEqual({
73
+ structuralSharing: false,
74
+ });
75
+ });
76
+
77
+ test('keeps selected data on the router default', () => {
78
+ const select = (value: unknown) => value;
79
+ const matchOptions = { from: '/', select };
80
+ const matchesOptions = { select };
81
+ const stateOptions = { select };
82
+
83
+ useMatch(matchOptions as never);
84
+ useMatches(matchesOptions as never);
85
+ useParentMatches(matchesOptions as never);
86
+ useChildMatches(matchesOptions as never);
87
+ useRouterState(stateOptions as never);
88
+
89
+ expect(getLastCall('useMatch')).toBe(matchOptions);
90
+ expect(getLastCall('useMatches')).toBe(matchesOptions);
91
+ expect(getLastCall('useParentMatches')).toBe(matchesOptions);
92
+ expect(getLastCall('useChildMatches')).toBe(matchesOptions);
93
+ expect(getLastCall('useRouterState')).toBe(stateOptions);
94
+ });
95
+
96
+ test('honors explicit structural sharing choices', () => {
97
+ const enabled = { structuralSharing: true };
98
+ const disabled = { structuralSharing: false };
99
+ const matchEnabled = { from: '/', structuralSharing: true };
100
+
101
+ useMatch(matchEnabled as never);
102
+ useMatches(enabled as never);
103
+ useParentMatches(disabled as never);
104
+ useChildMatches(enabled as never);
105
+ useRouterState(disabled as never);
106
+
107
+ expect(getLastCall('useMatch')).toBe(matchEnabled);
108
+ expect(getLastCall('useMatches')).toBe(enabled);
109
+ expect(getLastCall('useParentMatches')).toBe(disabled);
110
+ expect(getLastCall('useChildMatches')).toBe(enabled);
111
+ expect(getLastCall('useRouterState')).toBe(disabled);
112
+ });
113
+ });
@@ -279,9 +279,14 @@ describe('tanstack router type generation', () => {
279
279
  );
280
280
 
281
281
  await expect(
282
- execFileAsync('tsgo', ['--noEmit', '-p', 'tsconfig.json'], {
283
- cwd: tempDir,
284
- }),
282
+ execFileAsync(
283
+ process.platform === 'win32' ? 'tsgo.cmd' : 'tsgo',
284
+ ['--noEmit', '-p', 'tsconfig.json'],
285
+ {
286
+ cwd: tempDir,
287
+ shell: process.platform === 'win32',
288
+ },
289
+ ),
285
290
  ).resolves.toBeDefined();
286
291
  });
287
292