@tanstack/router-plugin 1.167.21 → 1.167.23
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/core/code-splitter/compilers.cjs +8 -4
- package/dist/cjs/core/code-splitter/compilers.cjs.map +1 -1
- package/dist/cjs/core/code-splitter/plugins/framework-plugins.cjs +8 -5
- package/dist/cjs/core/code-splitter/plugins/framework-plugins.cjs.map +1 -1
- package/dist/cjs/core/code-splitter/plugins/framework-plugins.d.cts +2 -2
- package/dist/cjs/core/code-splitter/plugins/react-refresh-ignored-route-exports.cjs +5 -9
- package/dist/cjs/core/code-splitter/plugins/react-refresh-ignored-route-exports.cjs.map +1 -1
- package/dist/cjs/core/code-splitter/plugins/react-refresh-ignored-route-exports.d.cts +1 -3
- package/dist/cjs/core/code-splitter/plugins/react-stable-hmr-split-route-components.cjs +6 -4
- package/dist/cjs/core/code-splitter/plugins/react-stable-hmr-split-route-components.cjs.map +1 -1
- package/dist/cjs/core/code-splitter/plugins/react-stable-hmr-split-route-components.d.cts +3 -2
- package/dist/cjs/core/code-splitter/plugins.d.cts +3 -2
- package/dist/cjs/core/config.cjs +1 -1
- package/dist/cjs/core/config.cjs.map +1 -1
- package/dist/cjs/core/config.d.cts +26 -18
- package/dist/cjs/core/{route-hmr-statement.cjs → hmr/handle-route-update.cjs} +39 -25
- package/dist/cjs/core/hmr/handle-route-update.cjs.map +1 -0
- package/dist/cjs/core/hmr/handle-route-update.d.cts +1 -0
- package/dist/cjs/core/hmr/index.d.cts +5 -0
- package/dist/cjs/core/hmr/select-adapter.cjs +20 -0
- package/dist/cjs/core/hmr/select-adapter.cjs.map +1 -0
- package/dist/cjs/core/hmr/select-adapter.d.cts +13 -0
- package/dist/cjs/core/hmr/vite-adapter.cjs +36 -0
- package/dist/cjs/core/hmr/vite-adapter.cjs.map +1 -0
- package/dist/cjs/core/hmr/vite-adapter.d.cts +12 -0
- package/dist/cjs/core/hmr/webpack-adapter.cjs +64 -0
- package/dist/cjs/core/hmr/webpack-adapter.cjs.map +1 -0
- package/dist/cjs/core/hmr/webpack-adapter.d.cts +20 -0
- package/dist/cjs/core/router-code-splitter-plugin.cjs +5 -5
- package/dist/cjs/core/router-code-splitter-plugin.cjs.map +1 -1
- package/dist/cjs/core/router-composed-plugin.cjs +2 -1
- package/dist/cjs/core/router-composed-plugin.cjs.map +1 -1
- package/dist/cjs/core/router-composed-plugin.d.cts +1 -1
- package/dist/cjs/core/router-hmr-plugin.cjs +17 -11
- package/dist/cjs/core/router-hmr-plugin.cjs.map +1 -1
- package/dist/cjs/esbuild.d.cts +14 -14
- package/dist/cjs/rspack.cjs +22 -3
- package/dist/cjs/rspack.cjs.map +1 -1
- package/dist/cjs/rspack.d.cts +3 -3
- package/dist/cjs/vite.d.cts +14 -14
- package/dist/cjs/webpack.cjs +19 -3
- package/dist/cjs/webpack.cjs.map +1 -1
- package/dist/cjs/webpack.d.cts +3 -3
- package/dist/esm/core/code-splitter/compilers.js +7 -3
- package/dist/esm/core/code-splitter/compilers.js.map +1 -1
- package/dist/esm/core/code-splitter/plugins/framework-plugins.d.ts +2 -2
- package/dist/esm/core/code-splitter/plugins/framework-plugins.js +8 -5
- package/dist/esm/core/code-splitter/plugins/framework-plugins.js.map +1 -1
- package/dist/esm/core/code-splitter/plugins/react-refresh-ignored-route-exports.d.ts +1 -3
- package/dist/esm/core/code-splitter/plugins/react-refresh-ignored-route-exports.js +4 -8
- package/dist/esm/core/code-splitter/plugins/react-refresh-ignored-route-exports.js.map +1 -1
- package/dist/esm/core/code-splitter/plugins/react-stable-hmr-split-route-components.d.ts +3 -2
- package/dist/esm/core/code-splitter/plugins/react-stable-hmr-split-route-components.js +5 -3
- package/dist/esm/core/code-splitter/plugins/react-stable-hmr-split-route-components.js.map +1 -1
- package/dist/esm/core/code-splitter/plugins.d.ts +3 -2
- package/dist/esm/core/config.d.ts +26 -18
- package/dist/esm/core/config.js +1 -1
- package/dist/esm/core/config.js.map +1 -1
- package/dist/esm/core/hmr/handle-route-update.d.ts +1 -0
- package/dist/esm/core/{route-hmr-statement.js → hmr/handle-route-update.js} +39 -23
- package/dist/esm/core/hmr/handle-route-update.js.map +1 -0
- package/dist/esm/core/hmr/index.d.ts +5 -0
- package/dist/esm/core/hmr/select-adapter.d.ts +13 -0
- package/dist/esm/core/hmr/select-adapter.js +20 -0
- package/dist/esm/core/hmr/select-adapter.js.map +1 -0
- package/dist/esm/core/hmr/vite-adapter.d.ts +12 -0
- package/dist/esm/core/hmr/vite-adapter.js +34 -0
- package/dist/esm/core/hmr/vite-adapter.js.map +1 -0
- package/dist/esm/core/hmr/webpack-adapter.d.ts +20 -0
- package/dist/esm/core/hmr/webpack-adapter.js +62 -0
- package/dist/esm/core/hmr/webpack-adapter.js.map +1 -0
- package/dist/esm/core/router-code-splitter-plugin.js +5 -5
- package/dist/esm/core/router-code-splitter-plugin.js.map +1 -1
- package/dist/esm/core/router-composed-plugin.d.ts +1 -1
- package/dist/esm/core/router-composed-plugin.js +2 -1
- package/dist/esm/core/router-composed-plugin.js.map +1 -1
- package/dist/esm/core/router-hmr-plugin.js +17 -11
- package/dist/esm/core/router-hmr-plugin.js.map +1 -1
- package/dist/esm/esbuild.d.ts +14 -14
- package/dist/esm/rspack.d.ts +3 -3
- package/dist/esm/rspack.js +22 -3
- package/dist/esm/rspack.js.map +1 -1
- package/dist/esm/vite.d.ts +14 -14
- package/dist/esm/webpack.d.ts +3 -3
- package/dist/esm/webpack.js +19 -3
- package/dist/esm/webpack.js.map +1 -1
- package/package.json +6 -6
- package/src/core/code-splitter/compilers.ts +4 -2
- package/src/core/code-splitter/plugins/framework-plugins.ts +7 -8
- package/src/core/code-splitter/plugins/react-refresh-ignored-route-exports.ts +2 -8
- package/src/core/code-splitter/plugins/react-stable-hmr-split-route-components.ts +10 -6
- package/src/core/code-splitter/plugins.ts +3 -2
- package/src/core/config.ts +11 -2
- package/src/core/{route-hmr-statement.ts → hmr/handle-route-update.ts} +85 -39
- package/src/core/hmr/index.ts +5 -0
- package/src/core/hmr/select-adapter.ts +32 -0
- package/src/core/hmr/vite-adapter.ts +47 -0
- package/src/core/hmr/webpack-adapter.ts +110 -0
- package/src/core/router-code-splitter-plugin.ts +5 -7
- package/src/core/router-composed-plugin.ts +8 -3
- package/src/core/router-hmr-plugin.ts +12 -9
- package/src/rspack.ts +37 -9
- package/src/webpack.ts +22 -9
- package/dist/cjs/core/hmr-hot-expression.cjs +0 -27
- package/dist/cjs/core/hmr-hot-expression.cjs.map +0 -1
- package/dist/cjs/core/hmr-hot-expression.d.cts +0 -6
- package/dist/cjs/core/route-hmr-statement.cjs.map +0 -1
- package/dist/cjs/core/route-hmr-statement.d.cts +0 -4
- package/dist/esm/core/hmr-hot-expression.d.ts +0 -6
- package/dist/esm/core/hmr-hot-expression.js +0 -23
- package/dist/esm/core/hmr-hot-expression.js.map +0 -1
- package/dist/esm/core/route-hmr-statement.d.ts +0 -4
- package/dist/esm/core/route-hmr-statement.js.map +0 -1
- package/src/core/hmr-hot-expression.ts +0 -31
package/src/rspack.ts
CHANGED
|
@@ -1,12 +1,42 @@
|
|
|
1
1
|
import { createRspackPlugin } from 'unplugin'
|
|
2
2
|
|
|
3
3
|
import { configSchema } from './core/config'
|
|
4
|
-
import { withHmrHotExpression } from './core/hmr-hot-expression'
|
|
5
4
|
import { unpluginRouterCodeSplitterFactory } from './core/router-code-splitter-plugin'
|
|
6
5
|
import { unpluginRouterGeneratorFactory } from './core/router-generator-plugin'
|
|
7
6
|
import { unpluginRouterComposedFactory } from './core/router-composed-plugin'
|
|
8
7
|
import type { CodeSplittingOptions, Config } from './core/config'
|
|
9
8
|
|
|
9
|
+
type RspackRouterPluginOptions = Partial<Config> | (() => Partial<Config>)
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Rspack uses webpack-compatible `module.hot` / `import.meta.webpackHot` HMR.
|
|
13
|
+
* Force `plugin.hmr.style = 'webpack'` so the router HMR adapter emits
|
|
14
|
+
* `module.hot`-style accept/dispose code instead of Vite's callback-receive
|
|
15
|
+
* variant, regardless of what the user passes (or doesn't pass).
|
|
16
|
+
*/
|
|
17
|
+
function withWebpackHmrStyle(
|
|
18
|
+
options: RspackRouterPluginOptions | undefined,
|
|
19
|
+
): RspackRouterPluginOptions {
|
|
20
|
+
const mergeHmrStyle = (
|
|
21
|
+
config: Partial<Config> | undefined,
|
|
22
|
+
): Partial<Config> => ({
|
|
23
|
+
...config,
|
|
24
|
+
plugin: {
|
|
25
|
+
...config?.plugin,
|
|
26
|
+
hmr: {
|
|
27
|
+
...config?.plugin?.hmr,
|
|
28
|
+
style: 'webpack',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
if (typeof options === 'function') {
|
|
34
|
+
return () => mergeHmrStyle(options())
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return mergeHmrStyle(options)
|
|
38
|
+
}
|
|
39
|
+
|
|
10
40
|
/**
|
|
11
41
|
* @example
|
|
12
42
|
* ```ts
|
|
@@ -40,10 +70,9 @@ const TanStackRouterGeneratorRspack = /* #__PURE__ */ createRspackPlugin(
|
|
|
40
70
|
const TanStackRouterCodeSplitterRspack = /* #__PURE__ */ createRspackPlugin(
|
|
41
71
|
(options, meta) =>
|
|
42
72
|
unpluginRouterCodeSplitterFactory(
|
|
43
|
-
|
|
44
|
-
options as
|
|
45
|
-
|
|
46
|
-
),
|
|
73
|
+
withWebpackHmrStyle(
|
|
74
|
+
options as RspackRouterPluginOptions | undefined,
|
|
75
|
+
) as Partial<Config | (() => Config)>,
|
|
47
76
|
meta,
|
|
48
77
|
),
|
|
49
78
|
)
|
|
@@ -64,10 +93,9 @@ const TanStackRouterCodeSplitterRspack = /* #__PURE__ */ createRspackPlugin(
|
|
|
64
93
|
const TanStackRouterRspack = /* #__PURE__ */ createRspackPlugin(
|
|
65
94
|
(options, meta) =>
|
|
66
95
|
unpluginRouterComposedFactory(
|
|
67
|
-
|
|
68
|
-
options as
|
|
69
|
-
|
|
70
|
-
),
|
|
96
|
+
withWebpackHmrStyle(
|
|
97
|
+
options as RspackRouterPluginOptions | undefined,
|
|
98
|
+
) as Partial<Config | (() => Config)>,
|
|
71
99
|
meta,
|
|
72
100
|
),
|
|
73
101
|
)
|
package/src/webpack.ts
CHANGED
|
@@ -1,12 +1,31 @@
|
|
|
1
1
|
import { createWebpackPlugin } from 'unplugin'
|
|
2
2
|
|
|
3
3
|
import { configSchema } from './core/config'
|
|
4
|
-
import { withHmrHotExpression } from './core/hmr-hot-expression'
|
|
5
4
|
import { unpluginRouterCodeSplitterFactory } from './core/router-code-splitter-plugin'
|
|
6
5
|
import { unpluginRouterGeneratorFactory } from './core/router-generator-plugin'
|
|
7
6
|
import { unpluginRouterComposedFactory } from './core/router-composed-plugin'
|
|
8
7
|
import type { CodeSplittingOptions, Config } from './core/config'
|
|
9
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Webpack uses `module.hot` / `import.meta.webpackHot` HMR. Force
|
|
11
|
+
* `plugin.hmr.style = 'webpack'` so the router HMR adapter emits the correct
|
|
12
|
+
* accept/dispose shape regardless of user config.
|
|
13
|
+
*/
|
|
14
|
+
function withWebpackHmrStyle(
|
|
15
|
+
options: Partial<Config> | undefined,
|
|
16
|
+
): Partial<Config> {
|
|
17
|
+
return {
|
|
18
|
+
...options,
|
|
19
|
+
plugin: {
|
|
20
|
+
...options?.plugin,
|
|
21
|
+
hmr: {
|
|
22
|
+
...options?.plugin?.hmr,
|
|
23
|
+
style: 'webpack',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
10
29
|
/**
|
|
11
30
|
* @example
|
|
12
31
|
* ```ts
|
|
@@ -32,10 +51,7 @@ const TanStackRouterGeneratorWebpack = /* #__PURE__ */ createWebpackPlugin(
|
|
|
32
51
|
const TanStackRouterCodeSplitterWebpack = /* #__PURE__ */ createWebpackPlugin(
|
|
33
52
|
(options, meta) =>
|
|
34
53
|
unpluginRouterCodeSplitterFactory(
|
|
35
|
-
|
|
36
|
-
options as Partial<Config> | undefined,
|
|
37
|
-
'import.meta.webpackHot',
|
|
38
|
-
),
|
|
54
|
+
withWebpackHmrStyle(options as Partial<Config> | undefined),
|
|
39
55
|
meta,
|
|
40
56
|
),
|
|
41
57
|
)
|
|
@@ -52,10 +68,7 @@ const TanStackRouterCodeSplitterWebpack = /* #__PURE__ */ createWebpackPlugin(
|
|
|
52
68
|
const TanStackRouterWebpack = /* #__PURE__ */ createWebpackPlugin(
|
|
53
69
|
(options, meta) =>
|
|
54
70
|
unpluginRouterComposedFactory(
|
|
55
|
-
|
|
56
|
-
options as Partial<Config> | undefined,
|
|
57
|
-
'import.meta.webpackHot',
|
|
58
|
-
),
|
|
71
|
+
withWebpackHmrStyle(options as Partial<Config> | undefined),
|
|
59
72
|
meta,
|
|
60
73
|
),
|
|
61
74
|
)
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
-
let _babel_template = require("@babel/template");
|
|
3
|
-
_babel_template = require_runtime.__toESM(_babel_template);
|
|
4
|
-
function resolveHmrHotExpression(hotExpression) {
|
|
5
|
-
return hotExpression ?? "import.meta.hot";
|
|
6
|
-
}
|
|
7
|
-
function createHmrHotExpressionAst(hotExpression) {
|
|
8
|
-
return _babel_template.expression.ast(resolveHmrHotExpression(hotExpression));
|
|
9
|
-
}
|
|
10
|
-
function withHmrHotExpression(config, hotExpression) {
|
|
11
|
-
return {
|
|
12
|
-
...config,
|
|
13
|
-
plugin: {
|
|
14
|
-
...config?.plugin,
|
|
15
|
-
hmr: {
|
|
16
|
-
...config?.plugin?.hmr,
|
|
17
|
-
hotExpression: config?.plugin?.hmr?.hotExpression ?? hotExpression
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
//#endregion
|
|
23
|
-
exports.createHmrHotExpressionAst = createHmrHotExpressionAst;
|
|
24
|
-
exports.resolveHmrHotExpression = resolveHmrHotExpression;
|
|
25
|
-
exports.withHmrHotExpression = withHmrHotExpression;
|
|
26
|
-
|
|
27
|
-
//# sourceMappingURL=hmr-hot-expression.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hmr-hot-expression.cjs","names":[],"sources":["../../../src/core/hmr-hot-expression.ts"],"sourcesContent":["import * as template from '@babel/template'\nimport type * as t from '@babel/types'\nimport type { Config } from './config'\n\nexport const DEFAULT_HMR_HOT_EXPRESSION = 'import.meta.hot'\n\nexport function resolveHmrHotExpression(hotExpression?: string): string {\n return hotExpression ?? DEFAULT_HMR_HOT_EXPRESSION\n}\n\nexport function createHmrHotExpressionAst(\n hotExpression?: string,\n): t.Expression {\n return template.expression.ast(resolveHmrHotExpression(hotExpression))\n}\n\nexport function withHmrHotExpression(\n config: Partial<Config> | undefined,\n hotExpression: string,\n): Partial<Config> {\n return {\n ...config,\n plugin: {\n ...config?.plugin,\n hmr: {\n ...config?.plugin?.hmr,\n hotExpression: config?.plugin?.hmr?.hotExpression ?? hotExpression,\n },\n },\n }\n}\n"],"mappings":";;;AAMA,SAAgB,wBAAwB,eAAgC;AACtE,QAAO,iBAAA;;AAGT,SAAgB,0BACd,eACc;AACd,QAAO,gBAAS,WAAW,IAAI,wBAAwB,cAAc,CAAC;;AAGxE,SAAgB,qBACd,QACA,eACiB;AACjB,QAAO;EACL,GAAG;EACH,QAAQ;GACN,GAAG,QAAQ;GACX,KAAK;IACH,GAAG,QAAQ,QAAQ;IACnB,eAAe,QAAQ,QAAQ,KAAK,iBAAiB;IACtD;GACF;EACF"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { Config } from './config.cjs';
|
|
2
|
-
import type * as t from '@babel/types';
|
|
3
|
-
export declare const DEFAULT_HMR_HOT_EXPRESSION = "import.meta.hot";
|
|
4
|
-
export declare function resolveHmrHotExpression(hotExpression?: string): string;
|
|
5
|
-
export declare function createHmrHotExpressionAst(hotExpression?: string): t.Expression;
|
|
6
|
-
export declare function withHmrHotExpression(config: Partial<Config> | undefined, hotExpression: string): Partial<Config>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"route-hmr-statement.cjs","names":[],"sources":["../../../src/core/route-hmr-statement.ts"],"sourcesContent":["import * as template from '@babel/template'\nimport { createHmrHotExpressionAst } from './hmr-hot-expression'\nimport type * as t from '@babel/types'\nimport type {\n AnyRoute,\n AnyRouteMatch,\n AnyRouter,\n RouterWritableStore,\n} from '@tanstack/router-core'\n\ntype AnyRouteWithPrivateProps = AnyRoute & {\n options: Record<string, unknown>\n _componentsPromise?: Promise<void>\n _lazyPromise?: Promise<void>\n update: (options: Record<string, unknown>) => unknown\n _path: string\n _id: string\n _fullPath: string\n _to: string\n}\n\ntype AnyRouterWithPrivateMaps = AnyRouter & {\n routesById: Record<string, AnyRoute>\n routesByPath: Record<string, AnyRoute>\n stores: AnyRouter['stores'] & {\n cachedMatchStores: Map<\n string,\n Pick<RouterWritableStore<AnyRouteMatch>, 'set'>\n >\n pendingMatchStores: Map<\n string,\n Pick<RouterWritableStore<AnyRouteMatch>, 'set'>\n >\n matchStores: Map<string, Pick<RouterWritableStore<AnyRouteMatch>, 'set'>>\n }\n}\n\ntype AnyRouteMatchWithPrivateProps = AnyRouteMatch & {\n __beforeLoadContext?: unknown\n}\n\nfunction handleRouteUpdate(\n routeId: string,\n newRoute: AnyRouteWithPrivateProps,\n) {\n const router = window.__TSR_ROUTER__ as AnyRouterWithPrivateMaps\n const oldRoute = router.routesById[routeId] as\n | AnyRouteWithPrivateProps\n | undefined\n\n if (!oldRoute) {\n return\n }\n\n // Keys whose identity must remain stable to prevent React from\n // unmounting/remounting the component tree. React Fast Refresh already\n // handles hot-updating the function bodies of these components — our job\n // is only to update non-component route options (loader, head, etc.).\n // For code-split (splittable) routes, the lazyRouteComponent wrapper is\n // already cached in the bundler hot data so its identity is stable.\n // For unsplittable routes (e.g. root routes), the component is a plain\n // function reference that gets recreated on every module re-execution,\n // so we must explicitly preserve the old reference.\n const removedKeys = new Set<string>()\n Object.keys(oldRoute.options).forEach((key) => {\n if (!(key in newRoute.options)) {\n removedKeys.add(key)\n delete oldRoute.options[key]\n }\n })\n\n // Preserve component identity so React doesn't remount.\n // React Fast Refresh patches the function bodies in-place.\n const componentKeys = '__TSR_COMPONENT_TYPES__' as unknown as Array<string>\n componentKeys.forEach((key) => {\n if (key in oldRoute.options && key in newRoute.options) {\n newRoute.options[key] = oldRoute.options[key]\n }\n })\n\n oldRoute.options = newRoute.options\n oldRoute.update(newRoute.options)\n oldRoute._componentsPromise = undefined\n oldRoute._lazyPromise = undefined\n\n router.routesById[oldRoute.id] = oldRoute\n router.routesByPath[oldRoute.fullPath] = oldRoute\n\n router.processedTree.matchCache.clear()\n router.processedTree.flatCache?.clear()\n router.processedTree.singleCache.clear()\n router.resolvePathCache.clear()\n walkReplaceSegmentTree(oldRoute, router.processedTree.segmentTree)\n\n const filter = (m: AnyRouteMatch) => m.routeId === oldRoute.id\n const activeMatch = router.stores.matches.get().find(filter)\n const pendingMatch = router.stores.pendingMatches.get().find(filter)\n const cachedMatches = router.stores.cachedMatches.get().filter(filter)\n\n if (activeMatch || pendingMatch || cachedMatches.length > 0) {\n // Clear stale match data for removed route options BEFORE invalidating.\n // Without this, router.invalidate() -> matchRoutes() reuses the existing\n // match from the store (via ...existingMatch spread) and the stale\n // loaderData / __beforeLoadContext survives the reload cycle.\n //\n // We must update the store directly (not via router.updateMatch) because\n // updateMatch wraps in startTransition which may defer the state update,\n // and we need the clear to be visible before invalidate reads the store.\n if (removedKeys.has('loader') || removedKeys.has('beforeLoad')) {\n const matchIds = [\n activeMatch?.id,\n pendingMatch?.id,\n ...cachedMatches.map((match) => match.id),\n ].filter(Boolean) as Array<string>\n router.batch(() => {\n for (const matchId of matchIds) {\n const store =\n router.stores.pendingMatchStores.get(matchId) ||\n router.stores.matchStores.get(matchId) ||\n router.stores.cachedMatchStores.get(matchId)\n if (store) {\n store.set((prev) => {\n const next: AnyRouteMatchWithPrivateProps = { ...prev }\n\n if (removedKeys.has('loader')) {\n next.loaderData = undefined\n }\n if (removedKeys.has('beforeLoad')) {\n next.__beforeLoadContext = undefined\n }\n\n return next\n })\n }\n }\n })\n }\n\n router.invalidate({ filter, sync: true })\n }\n\n function walkReplaceSegmentTree(\n route: AnyRouteWithPrivateProps,\n node: AnyRouter['processedTree']['segmentTree'],\n ) {\n if (node.route?.id === route.id) node.route = route\n if (node.index) walkReplaceSegmentTree(route, node.index)\n node.static?.forEach((child) => walkReplaceSegmentTree(route, child))\n node.staticInsensitive?.forEach((child) =>\n walkReplaceSegmentTree(route, child),\n )\n node.dynamic?.forEach((child) => walkReplaceSegmentTree(route, child))\n node.optional?.forEach((child) => walkReplaceSegmentTree(route, child))\n node.wildcard?.forEach((child) => walkReplaceSegmentTree(route, child))\n }\n}\n\nconst handleRouteUpdateStr = handleRouteUpdate.toString()\n\nexport function createRouteHmrStatement(\n stableRouteOptionKeys: Array<string>,\n opts?: { hotExpression?: string },\n): t.Statement {\n return template.statement(\n `\nif (%%hotExpression%%) {\n const hot = %%hotExpression%%\n const hotData = hot.data ??= {}\n hot.accept((newModule) => {\n if (Route && newModule && newModule.Route) {\n const routeId = hotData['tsr-route-id'] ?? Route.id\n if (routeId) {\n hotData['tsr-route-id'] = routeId\n }\n (${handleRouteUpdateStr.replace(\n /['\"]__TSR_COMPONENT_TYPES__['\"]/,\n JSON.stringify(stableRouteOptionKeys),\n )})(routeId, newModule.Route)\n }\n })\n}\n`,\n {\n syntacticPlaceholders: true,\n },\n )({\n hotExpression: createHmrHotExpressionAst(opts?.hotExpression),\n })\n}\n"],"mappings":";;;;;AAyCA,SAAS,kBACP,SACA,UACA;CACA,MAAM,SAAS,OAAO;CACtB,MAAM,WAAW,OAAO,WAAW;AAInC,KAAI,CAAC,SACH;CAYF,MAAM,8BAAc,IAAI,KAAa;AACrC,QAAO,KAAK,SAAS,QAAQ,CAAC,SAAS,QAAQ;AAC7C,MAAI,EAAE,OAAO,SAAS,UAAU;AAC9B,eAAY,IAAI,IAAI;AACpB,UAAO,SAAS,QAAQ;;GAE1B;AAIoB,2BACR,SAAS,QAAQ;AAC7B,MAAI,OAAO,SAAS,WAAW,OAAO,SAAS,QAC7C,UAAS,QAAQ,OAAO,SAAS,QAAQ;GAE3C;AAEF,UAAS,UAAU,SAAS;AAC5B,UAAS,OAAO,SAAS,QAAQ;AACjC,UAAS,qBAAqB,KAAA;AAC9B,UAAS,eAAe,KAAA;AAExB,QAAO,WAAW,SAAS,MAAM;AACjC,QAAO,aAAa,SAAS,YAAY;AAEzC,QAAO,cAAc,WAAW,OAAO;AACvC,QAAO,cAAc,WAAW,OAAO;AACvC,QAAO,cAAc,YAAY,OAAO;AACxC,QAAO,iBAAiB,OAAO;AAC/B,wBAAuB,UAAU,OAAO,cAAc,YAAY;CAElE,MAAM,UAAU,MAAqB,EAAE,YAAY,SAAS;CAC5D,MAAM,cAAc,OAAO,OAAO,QAAQ,KAAK,CAAC,KAAK,OAAO;CAC5D,MAAM,eAAe,OAAO,OAAO,eAAe,KAAK,CAAC,KAAK,OAAO;CACpE,MAAM,gBAAgB,OAAO,OAAO,cAAc,KAAK,CAAC,OAAO,OAAO;AAEtE,KAAI,eAAe,gBAAgB,cAAc,SAAS,GAAG;AAS3D,MAAI,YAAY,IAAI,SAAS,IAAI,YAAY,IAAI,aAAa,EAAE;GAC9D,MAAM,WAAW;IACf,aAAa;IACb,cAAc;IACd,GAAG,cAAc,KAAK,UAAU,MAAM,GAAG;IAC1C,CAAC,OAAO,QAAQ;AACjB,UAAO,YAAY;AACjB,SAAK,MAAM,WAAW,UAAU;KAC9B,MAAM,QACJ,OAAO,OAAO,mBAAmB,IAAI,QAAQ,IAC7C,OAAO,OAAO,YAAY,IAAI,QAAQ,IACtC,OAAO,OAAO,kBAAkB,IAAI,QAAQ;AAC9C,SAAI,MACF,OAAM,KAAK,SAAS;MAClB,MAAM,OAAsC,EAAE,GAAG,MAAM;AAEvD,UAAI,YAAY,IAAI,SAAS,CAC3B,MAAK,aAAa,KAAA;AAEpB,UAAI,YAAY,IAAI,aAAa,CAC/B,MAAK,sBAAsB,KAAA;AAG7B,aAAO;OACP;;KAGN;;AAGJ,SAAO,WAAW;GAAE;GAAQ,MAAM;GAAM,CAAC;;CAG3C,SAAS,uBACP,OACA,MACA;AACA,MAAI,KAAK,OAAO,OAAO,MAAM,GAAI,MAAK,QAAQ;AAC9C,MAAI,KAAK,MAAO,wBAAuB,OAAO,KAAK,MAAM;AACzD,OAAK,QAAQ,SAAS,UAAU,uBAAuB,OAAO,MAAM,CAAC;AACrE,OAAK,mBAAmB,SAAS,UAC/B,uBAAuB,OAAO,MAAM,CACrC;AACD,OAAK,SAAS,SAAS,UAAU,uBAAuB,OAAO,MAAM,CAAC;AACtE,OAAK,UAAU,SAAS,UAAU,uBAAuB,OAAO,MAAM,CAAC;AACvE,OAAK,UAAU,SAAS,UAAU,uBAAuB,OAAO,MAAM,CAAC;;;AAI3E,IAAM,uBAAuB,kBAAkB,UAAU;AAEzD,SAAgB,wBACd,uBACA,MACa;AACb,QAAO,gBAAS,UACd;;;;;;;;;;SAUK,qBAAqB,QACtB,mCACA,KAAK,UAAU,sBAAsB,CACtC,CAAC;;;;GAKJ,EACE,uBAAuB,MACxB,CACF,CAAC,EACA,eAAe,2BAAA,0BAA0B,MAAM,cAAc,EAC9D,CAAC"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { Config } from './config.js';
|
|
2
|
-
import type * as t from '@babel/types';
|
|
3
|
-
export declare const DEFAULT_HMR_HOT_EXPRESSION = "import.meta.hot";
|
|
4
|
-
export declare function resolveHmrHotExpression(hotExpression?: string): string;
|
|
5
|
-
export declare function createHmrHotExpressionAst(hotExpression?: string): t.Expression;
|
|
6
|
-
export declare function withHmrHotExpression(config: Partial<Config> | undefined, hotExpression: string): Partial<Config>;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import * as template from "@babel/template";
|
|
2
|
-
function resolveHmrHotExpression(hotExpression) {
|
|
3
|
-
return hotExpression ?? "import.meta.hot";
|
|
4
|
-
}
|
|
5
|
-
function createHmrHotExpressionAst(hotExpression) {
|
|
6
|
-
return template.expression.ast(resolveHmrHotExpression(hotExpression));
|
|
7
|
-
}
|
|
8
|
-
function withHmrHotExpression(config, hotExpression) {
|
|
9
|
-
return {
|
|
10
|
-
...config,
|
|
11
|
-
plugin: {
|
|
12
|
-
...config?.plugin,
|
|
13
|
-
hmr: {
|
|
14
|
-
...config?.plugin?.hmr,
|
|
15
|
-
hotExpression: config?.plugin?.hmr?.hotExpression ?? hotExpression
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
//#endregion
|
|
21
|
-
export { createHmrHotExpressionAst, resolveHmrHotExpression, withHmrHotExpression };
|
|
22
|
-
|
|
23
|
-
//# sourceMappingURL=hmr-hot-expression.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hmr-hot-expression.js","names":[],"sources":["../../../src/core/hmr-hot-expression.ts"],"sourcesContent":["import * as template from '@babel/template'\nimport type * as t from '@babel/types'\nimport type { Config } from './config'\n\nexport const DEFAULT_HMR_HOT_EXPRESSION = 'import.meta.hot'\n\nexport function resolveHmrHotExpression(hotExpression?: string): string {\n return hotExpression ?? DEFAULT_HMR_HOT_EXPRESSION\n}\n\nexport function createHmrHotExpressionAst(\n hotExpression?: string,\n): t.Expression {\n return template.expression.ast(resolveHmrHotExpression(hotExpression))\n}\n\nexport function withHmrHotExpression(\n config: Partial<Config> | undefined,\n hotExpression: string,\n): Partial<Config> {\n return {\n ...config,\n plugin: {\n ...config?.plugin,\n hmr: {\n ...config?.plugin?.hmr,\n hotExpression: config?.plugin?.hmr?.hotExpression ?? hotExpression,\n },\n },\n }\n}\n"],"mappings":";AAMA,SAAgB,wBAAwB,eAAgC;AACtE,QAAO,iBAAA;;AAGT,SAAgB,0BACd,eACc;AACd,QAAO,SAAS,WAAW,IAAI,wBAAwB,cAAc,CAAC;;AAGxE,SAAgB,qBACd,QACA,eACiB;AACjB,QAAO;EACL,GAAG;EACH,QAAQ;GACN,GAAG,QAAQ;GACX,KAAK;IACH,GAAG,QAAQ,QAAQ;IACnB,eAAe,QAAQ,QAAQ,KAAK,iBAAiB;IACtD;GACF;EACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"route-hmr-statement.js","names":[],"sources":["../../../src/core/route-hmr-statement.ts"],"sourcesContent":["import * as template from '@babel/template'\nimport { createHmrHotExpressionAst } from './hmr-hot-expression'\nimport type * as t from '@babel/types'\nimport type {\n AnyRoute,\n AnyRouteMatch,\n AnyRouter,\n RouterWritableStore,\n} from '@tanstack/router-core'\n\ntype AnyRouteWithPrivateProps = AnyRoute & {\n options: Record<string, unknown>\n _componentsPromise?: Promise<void>\n _lazyPromise?: Promise<void>\n update: (options: Record<string, unknown>) => unknown\n _path: string\n _id: string\n _fullPath: string\n _to: string\n}\n\ntype AnyRouterWithPrivateMaps = AnyRouter & {\n routesById: Record<string, AnyRoute>\n routesByPath: Record<string, AnyRoute>\n stores: AnyRouter['stores'] & {\n cachedMatchStores: Map<\n string,\n Pick<RouterWritableStore<AnyRouteMatch>, 'set'>\n >\n pendingMatchStores: Map<\n string,\n Pick<RouterWritableStore<AnyRouteMatch>, 'set'>\n >\n matchStores: Map<string, Pick<RouterWritableStore<AnyRouteMatch>, 'set'>>\n }\n}\n\ntype AnyRouteMatchWithPrivateProps = AnyRouteMatch & {\n __beforeLoadContext?: unknown\n}\n\nfunction handleRouteUpdate(\n routeId: string,\n newRoute: AnyRouteWithPrivateProps,\n) {\n const router = window.__TSR_ROUTER__ as AnyRouterWithPrivateMaps\n const oldRoute = router.routesById[routeId] as\n | AnyRouteWithPrivateProps\n | undefined\n\n if (!oldRoute) {\n return\n }\n\n // Keys whose identity must remain stable to prevent React from\n // unmounting/remounting the component tree. React Fast Refresh already\n // handles hot-updating the function bodies of these components — our job\n // is only to update non-component route options (loader, head, etc.).\n // For code-split (splittable) routes, the lazyRouteComponent wrapper is\n // already cached in the bundler hot data so its identity is stable.\n // For unsplittable routes (e.g. root routes), the component is a plain\n // function reference that gets recreated on every module re-execution,\n // so we must explicitly preserve the old reference.\n const removedKeys = new Set<string>()\n Object.keys(oldRoute.options).forEach((key) => {\n if (!(key in newRoute.options)) {\n removedKeys.add(key)\n delete oldRoute.options[key]\n }\n })\n\n // Preserve component identity so React doesn't remount.\n // React Fast Refresh patches the function bodies in-place.\n const componentKeys = '__TSR_COMPONENT_TYPES__' as unknown as Array<string>\n componentKeys.forEach((key) => {\n if (key in oldRoute.options && key in newRoute.options) {\n newRoute.options[key] = oldRoute.options[key]\n }\n })\n\n oldRoute.options = newRoute.options\n oldRoute.update(newRoute.options)\n oldRoute._componentsPromise = undefined\n oldRoute._lazyPromise = undefined\n\n router.routesById[oldRoute.id] = oldRoute\n router.routesByPath[oldRoute.fullPath] = oldRoute\n\n router.processedTree.matchCache.clear()\n router.processedTree.flatCache?.clear()\n router.processedTree.singleCache.clear()\n router.resolvePathCache.clear()\n walkReplaceSegmentTree(oldRoute, router.processedTree.segmentTree)\n\n const filter = (m: AnyRouteMatch) => m.routeId === oldRoute.id\n const activeMatch = router.stores.matches.get().find(filter)\n const pendingMatch = router.stores.pendingMatches.get().find(filter)\n const cachedMatches = router.stores.cachedMatches.get().filter(filter)\n\n if (activeMatch || pendingMatch || cachedMatches.length > 0) {\n // Clear stale match data for removed route options BEFORE invalidating.\n // Without this, router.invalidate() -> matchRoutes() reuses the existing\n // match from the store (via ...existingMatch spread) and the stale\n // loaderData / __beforeLoadContext survives the reload cycle.\n //\n // We must update the store directly (not via router.updateMatch) because\n // updateMatch wraps in startTransition which may defer the state update,\n // and we need the clear to be visible before invalidate reads the store.\n if (removedKeys.has('loader') || removedKeys.has('beforeLoad')) {\n const matchIds = [\n activeMatch?.id,\n pendingMatch?.id,\n ...cachedMatches.map((match) => match.id),\n ].filter(Boolean) as Array<string>\n router.batch(() => {\n for (const matchId of matchIds) {\n const store =\n router.stores.pendingMatchStores.get(matchId) ||\n router.stores.matchStores.get(matchId) ||\n router.stores.cachedMatchStores.get(matchId)\n if (store) {\n store.set((prev) => {\n const next: AnyRouteMatchWithPrivateProps = { ...prev }\n\n if (removedKeys.has('loader')) {\n next.loaderData = undefined\n }\n if (removedKeys.has('beforeLoad')) {\n next.__beforeLoadContext = undefined\n }\n\n return next\n })\n }\n }\n })\n }\n\n router.invalidate({ filter, sync: true })\n }\n\n function walkReplaceSegmentTree(\n route: AnyRouteWithPrivateProps,\n node: AnyRouter['processedTree']['segmentTree'],\n ) {\n if (node.route?.id === route.id) node.route = route\n if (node.index) walkReplaceSegmentTree(route, node.index)\n node.static?.forEach((child) => walkReplaceSegmentTree(route, child))\n node.staticInsensitive?.forEach((child) =>\n walkReplaceSegmentTree(route, child),\n )\n node.dynamic?.forEach((child) => walkReplaceSegmentTree(route, child))\n node.optional?.forEach((child) => walkReplaceSegmentTree(route, child))\n node.wildcard?.forEach((child) => walkReplaceSegmentTree(route, child))\n }\n}\n\nconst handleRouteUpdateStr = handleRouteUpdate.toString()\n\nexport function createRouteHmrStatement(\n stableRouteOptionKeys: Array<string>,\n opts?: { hotExpression?: string },\n): t.Statement {\n return template.statement(\n `\nif (%%hotExpression%%) {\n const hot = %%hotExpression%%\n const hotData = hot.data ??= {}\n hot.accept((newModule) => {\n if (Route && newModule && newModule.Route) {\n const routeId = hotData['tsr-route-id'] ?? Route.id\n if (routeId) {\n hotData['tsr-route-id'] = routeId\n }\n (${handleRouteUpdateStr.replace(\n /['\"]__TSR_COMPONENT_TYPES__['\"]/,\n JSON.stringify(stableRouteOptionKeys),\n )})(routeId, newModule.Route)\n }\n })\n}\n`,\n {\n syntacticPlaceholders: true,\n },\n )({\n hotExpression: createHmrHotExpressionAst(opts?.hotExpression),\n })\n}\n"],"mappings":";;;AAyCA,SAAS,kBACP,SACA,UACA;CACA,MAAM,SAAS,OAAO;CACtB,MAAM,WAAW,OAAO,WAAW;AAInC,KAAI,CAAC,SACH;CAYF,MAAM,8BAAc,IAAI,KAAa;AACrC,QAAO,KAAK,SAAS,QAAQ,CAAC,SAAS,QAAQ;AAC7C,MAAI,EAAE,OAAO,SAAS,UAAU;AAC9B,eAAY,IAAI,IAAI;AACpB,UAAO,SAAS,QAAQ;;GAE1B;AAIoB,2BACR,SAAS,QAAQ;AAC7B,MAAI,OAAO,SAAS,WAAW,OAAO,SAAS,QAC7C,UAAS,QAAQ,OAAO,SAAS,QAAQ;GAE3C;AAEF,UAAS,UAAU,SAAS;AAC5B,UAAS,OAAO,SAAS,QAAQ;AACjC,UAAS,qBAAqB,KAAA;AAC9B,UAAS,eAAe,KAAA;AAExB,QAAO,WAAW,SAAS,MAAM;AACjC,QAAO,aAAa,SAAS,YAAY;AAEzC,QAAO,cAAc,WAAW,OAAO;AACvC,QAAO,cAAc,WAAW,OAAO;AACvC,QAAO,cAAc,YAAY,OAAO;AACxC,QAAO,iBAAiB,OAAO;AAC/B,wBAAuB,UAAU,OAAO,cAAc,YAAY;CAElE,MAAM,UAAU,MAAqB,EAAE,YAAY,SAAS;CAC5D,MAAM,cAAc,OAAO,OAAO,QAAQ,KAAK,CAAC,KAAK,OAAO;CAC5D,MAAM,eAAe,OAAO,OAAO,eAAe,KAAK,CAAC,KAAK,OAAO;CACpE,MAAM,gBAAgB,OAAO,OAAO,cAAc,KAAK,CAAC,OAAO,OAAO;AAEtE,KAAI,eAAe,gBAAgB,cAAc,SAAS,GAAG;AAS3D,MAAI,YAAY,IAAI,SAAS,IAAI,YAAY,IAAI,aAAa,EAAE;GAC9D,MAAM,WAAW;IACf,aAAa;IACb,cAAc;IACd,GAAG,cAAc,KAAK,UAAU,MAAM,GAAG;IAC1C,CAAC,OAAO,QAAQ;AACjB,UAAO,YAAY;AACjB,SAAK,MAAM,WAAW,UAAU;KAC9B,MAAM,QACJ,OAAO,OAAO,mBAAmB,IAAI,QAAQ,IAC7C,OAAO,OAAO,YAAY,IAAI,QAAQ,IACtC,OAAO,OAAO,kBAAkB,IAAI,QAAQ;AAC9C,SAAI,MACF,OAAM,KAAK,SAAS;MAClB,MAAM,OAAsC,EAAE,GAAG,MAAM;AAEvD,UAAI,YAAY,IAAI,SAAS,CAC3B,MAAK,aAAa,KAAA;AAEpB,UAAI,YAAY,IAAI,aAAa,CAC/B,MAAK,sBAAsB,KAAA;AAG7B,aAAO;OACP;;KAGN;;AAGJ,SAAO,WAAW;GAAE;GAAQ,MAAM;GAAM,CAAC;;CAG3C,SAAS,uBACP,OACA,MACA;AACA,MAAI,KAAK,OAAO,OAAO,MAAM,GAAI,MAAK,QAAQ;AAC9C,MAAI,KAAK,MAAO,wBAAuB,OAAO,KAAK,MAAM;AACzD,OAAK,QAAQ,SAAS,UAAU,uBAAuB,OAAO,MAAM,CAAC;AACrE,OAAK,mBAAmB,SAAS,UAC/B,uBAAuB,OAAO,MAAM,CACrC;AACD,OAAK,SAAS,SAAS,UAAU,uBAAuB,OAAO,MAAM,CAAC;AACtE,OAAK,UAAU,SAAS,UAAU,uBAAuB,OAAO,MAAM,CAAC;AACvE,OAAK,UAAU,SAAS,UAAU,uBAAuB,OAAO,MAAM,CAAC;;;AAI3E,IAAM,uBAAuB,kBAAkB,UAAU;AAEzD,SAAgB,wBACd,uBACA,MACa;AACb,QAAO,SAAS,UACd;;;;;;;;;;SAUK,qBAAqB,QACtB,mCACA,KAAK,UAAU,sBAAsB,CACtC,CAAC;;;;GAKJ,EACE,uBAAuB,MACxB,CACF,CAAC,EACA,eAAe,0BAA0B,MAAM,cAAc,EAC9D,CAAC"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import * as template from '@babel/template'
|
|
2
|
-
import type * as t from '@babel/types'
|
|
3
|
-
import type { Config } from './config'
|
|
4
|
-
|
|
5
|
-
export const DEFAULT_HMR_HOT_EXPRESSION = 'import.meta.hot'
|
|
6
|
-
|
|
7
|
-
export function resolveHmrHotExpression(hotExpression?: string): string {
|
|
8
|
-
return hotExpression ?? DEFAULT_HMR_HOT_EXPRESSION
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function createHmrHotExpressionAst(
|
|
12
|
-
hotExpression?: string,
|
|
13
|
-
): t.Expression {
|
|
14
|
-
return template.expression.ast(resolveHmrHotExpression(hotExpression))
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function withHmrHotExpression(
|
|
18
|
-
config: Partial<Config> | undefined,
|
|
19
|
-
hotExpression: string,
|
|
20
|
-
): Partial<Config> {
|
|
21
|
-
return {
|
|
22
|
-
...config,
|
|
23
|
-
plugin: {
|
|
24
|
-
...config?.plugin,
|
|
25
|
-
hmr: {
|
|
26
|
-
...config?.plugin?.hmr,
|
|
27
|
-
hotExpression: config?.plugin?.hmr?.hotExpression ?? hotExpression,
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
}
|
|
31
|
-
}
|