@tanstack/router-plugin 1.167.12 → 1.167.14

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 (86) hide show
  1. package/dist/cjs/core/code-splitter/compilers.cjs +5 -4
  2. package/dist/cjs/core/code-splitter/compilers.cjs.map +1 -1
  3. package/dist/cjs/core/code-splitter/compilers.d.cts +2 -10
  4. package/dist/cjs/core/code-splitter/plugins/framework-plugins.cjs +2 -2
  5. package/dist/cjs/core/code-splitter/plugins/framework-plugins.cjs.map +1 -1
  6. package/dist/cjs/core/code-splitter/plugins/framework-plugins.d.cts +1 -0
  7. package/dist/cjs/core/code-splitter/plugins/react-refresh-ignored-route-exports.cjs +12 -6
  8. package/dist/cjs/core/code-splitter/plugins/react-refresh-ignored-route-exports.cjs.map +1 -1
  9. package/dist/cjs/core/code-splitter/plugins/react-refresh-ignored-route-exports.d.cts +3 -1
  10. package/dist/cjs/core/code-splitter/plugins/react-stable-hmr-split-route-components.cjs +12 -7
  11. package/dist/cjs/core/code-splitter/plugins/react-stable-hmr-split-route-components.cjs.map +1 -1
  12. package/dist/cjs/core/code-splitter/plugins/react-stable-hmr-split-route-components.d.cts +3 -1
  13. package/dist/cjs/core/code-splitter/plugins.d.cts +2 -0
  14. package/dist/cjs/core/config.cjs +4 -1
  15. package/dist/cjs/core/config.cjs.map +1 -1
  16. package/dist/cjs/core/config.d.cts +25 -0
  17. package/dist/cjs/core/hmr-hot-expression.cjs +27 -0
  18. package/dist/cjs/core/hmr-hot-expression.cjs.map +1 -0
  19. package/dist/cjs/core/hmr-hot-expression.d.cts +6 -0
  20. package/dist/cjs/core/route-autoimport-plugin.cjs +2 -2
  21. package/dist/cjs/core/route-hmr-statement.cjs +14 -11
  22. package/dist/cjs/core/route-hmr-statement.cjs.map +1 -1
  23. package/dist/cjs/core/route-hmr-statement.d.cts +3 -1
  24. package/dist/cjs/core/router-code-splitter-plugin.cjs +7 -10
  25. package/dist/cjs/core/router-code-splitter-plugin.cjs.map +1 -1
  26. package/dist/cjs/core/router-hmr-plugin.cjs +6 -2
  27. package/dist/cjs/core/router-hmr-plugin.cjs.map +1 -1
  28. package/dist/cjs/esbuild.d.cts +12 -0
  29. package/dist/cjs/index.d.cts +1 -1
  30. package/dist/cjs/rspack.cjs +3 -2
  31. package/dist/cjs/rspack.cjs.map +1 -1
  32. package/dist/cjs/rspack.d.cts +6 -135
  33. package/dist/cjs/vite.d.cts +15 -0
  34. package/dist/cjs/webpack.cjs +3 -2
  35. package/dist/cjs/webpack.cjs.map +1 -1
  36. package/dist/cjs/webpack.d.cts +6 -135
  37. package/dist/esm/core/code-splitter/compilers.d.ts +2 -10
  38. package/dist/esm/core/code-splitter/compilers.js +4 -3
  39. package/dist/esm/core/code-splitter/compilers.js.map +1 -1
  40. package/dist/esm/core/code-splitter/plugins/framework-plugins.d.ts +1 -0
  41. package/dist/esm/core/code-splitter/plugins/framework-plugins.js +2 -2
  42. package/dist/esm/core/code-splitter/plugins/framework-plugins.js.map +1 -1
  43. package/dist/esm/core/code-splitter/plugins/react-refresh-ignored-route-exports.d.ts +3 -1
  44. package/dist/esm/core/code-splitter/plugins/react-refresh-ignored-route-exports.js +11 -5
  45. package/dist/esm/core/code-splitter/plugins/react-refresh-ignored-route-exports.js.map +1 -1
  46. package/dist/esm/core/code-splitter/plugins/react-stable-hmr-split-route-components.d.ts +3 -1
  47. package/dist/esm/core/code-splitter/plugins/react-stable-hmr-split-route-components.js +11 -6
  48. package/dist/esm/core/code-splitter/plugins/react-stable-hmr-split-route-components.js.map +1 -1
  49. package/dist/esm/core/code-splitter/plugins.d.ts +2 -0
  50. package/dist/esm/core/config.d.ts +25 -0
  51. package/dist/esm/core/config.js +4 -1
  52. package/dist/esm/core/config.js.map +1 -1
  53. package/dist/esm/core/hmr-hot-expression.d.ts +6 -0
  54. package/dist/esm/core/hmr-hot-expression.js +23 -0
  55. package/dist/esm/core/hmr-hot-expression.js.map +1 -0
  56. package/dist/esm/core/route-autoimport-plugin.js +1 -1
  57. package/dist/esm/core/route-hmr-statement.d.ts +3 -1
  58. package/dist/esm/core/route-hmr-statement.js +14 -11
  59. package/dist/esm/core/route-hmr-statement.js.map +1 -1
  60. package/dist/esm/core/router-code-splitter-plugin.js +7 -10
  61. package/dist/esm/core/router-code-splitter-plugin.js.map +1 -1
  62. package/dist/esm/core/router-hmr-plugin.js +6 -2
  63. package/dist/esm/core/router-hmr-plugin.js.map +1 -1
  64. package/dist/esm/esbuild.d.ts +12 -0
  65. package/dist/esm/index.d.ts +1 -1
  66. package/dist/esm/rspack.d.ts +6 -135
  67. package/dist/esm/rspack.js +3 -2
  68. package/dist/esm/rspack.js.map +1 -1
  69. package/dist/esm/vite.d.ts +15 -0
  70. package/dist/esm/webpack.d.ts +6 -135
  71. package/dist/esm/webpack.js +3 -2
  72. package/dist/esm/webpack.js.map +1 -1
  73. package/package.json +4 -4
  74. package/src/core/code-splitter/compilers.ts +8 -12
  75. package/src/core/code-splitter/plugins/framework-plugins.ts +7 -2
  76. package/src/core/code-splitter/plugins/react-refresh-ignored-route-exports.ts +12 -4
  77. package/src/core/code-splitter/plugins/react-stable-hmr-split-route-components.ts +14 -5
  78. package/src/core/code-splitter/plugins.ts +2 -0
  79. package/src/core/config.ts +9 -0
  80. package/src/core/hmr-hot-expression.ts +31 -0
  81. package/src/core/route-hmr-statement.ts +36 -30
  82. package/src/core/router-code-splitter-plugin.ts +8 -14
  83. package/src/core/router-hmr-plugin.ts +10 -1
  84. package/src/index.ts +1 -0
  85. package/src/rspack.ts +17 -2
  86. package/src/webpack.ts +17 -2
@@ -1,6 +1,7 @@
1
+ import { createHmrHotExpressionAst } from "../../hmr-hot-expression.js";
1
2
  import { getUniqueProgramIdentifier } from "../../utils.js";
2
- import * as t from "@babel/types";
3
3
  import * as template from "@babel/template";
4
+ import * as t from "@babel/types";
4
5
  //#region src/core/code-splitter/plugins/react-stable-hmr-split-route-components.ts
5
6
  function capitalizeIdentifier(str) {
6
7
  return str[0].toUpperCase() + str.slice(1);
@@ -9,13 +10,16 @@ function createHotDataKey(exportName) {
9
10
  return `tsr-split-component:${exportName}`;
10
11
  }
11
12
  var buildStableSplitComponentStatements = template.statements(`
12
- const %%stableComponentIdent%% = import.meta.hot?.data?.[%%hotDataKey%%] ?? %%lazyRouteComponentIdent%%(%%localImporterIdent%%, %%exporterIdent%%)
13
- if (import.meta.hot) {
14
- import.meta.hot.data ??= {}
15
- import.meta.hot.data[%%hotDataKey%%] = %%stableComponentIdent%%
13
+ const %%stableComponentIdent%% = (() => {
14
+ const hot = %%hotExpression%%
15
+ const hotData = hot ? (hot.data ??= {}) : undefined
16
+ return hotData?.[%%hotDataKey%%] ?? %%lazyRouteComponentIdent%%(%%localImporterIdent%%, %%exporterIdent%%)
17
+ })()
18
+ if (%%hotExpression%%) {
19
+ ((%%hotExpression%%).data ??= {})[%%hotDataKey%%] = %%stableComponentIdent%%
16
20
  }
17
21
  `, { syntacticPlaceholders: true });
18
- function createReactStableHmrSplitRouteComponentsPlugin() {
22
+ function createReactStableHmrSplitRouteComponentsPlugin(opts) {
19
23
  return {
20
24
  name: "react-stable-hmr-split-route-components",
21
25
  onSplitRouteProperty(ctx) {
@@ -25,6 +29,7 @@ function createReactStableHmrSplitRouteComponentsPlugin() {
25
29
  ctx.insertionPath.insertBefore(buildStableSplitComponentStatements({
26
30
  stableComponentIdent,
27
31
  hotDataKey: t.stringLiteral(hotDataKey),
32
+ hotExpression: createHmrHotExpressionAst(opts?.hotExpression ?? ctx.opts.hmrHotExpression),
28
33
  lazyRouteComponentIdent: t.identifier(ctx.lazyRouteComponentIdent),
29
34
  localImporterIdent: t.identifier(ctx.splitNodeMeta.localImporterIdent),
30
35
  exporterIdent: t.stringLiteral(ctx.splitNodeMeta.exporterIdent)
@@ -1 +1 @@
1
- {"version":3,"file":"react-stable-hmr-split-route-components.js","names":[],"sources":["../../../../../src/core/code-splitter/plugins/react-stable-hmr-split-route-components.ts"],"sourcesContent":["import * as template from '@babel/template'\nimport * as t from '@babel/types'\nimport { getUniqueProgramIdentifier } from '../../utils'\nimport type { ReferenceRouteCompilerPlugin } from '../plugins'\n\nfunction capitalizeIdentifier(str: string) {\n return str[0]!.toUpperCase() + str.slice(1)\n}\n\nfunction createHotDataKey(exportName: string) {\n return `tsr-split-component:${exportName}`\n}\n\nconst buildStableSplitComponentStatements = template.statements(\n `\n const %%stableComponentIdent%% = import.meta.hot?.data?.[%%hotDataKey%%] ?? %%lazyRouteComponentIdent%%(%%localImporterIdent%%, %%exporterIdent%%)\n if (import.meta.hot) {\n import.meta.hot.data ??= {}\n import.meta.hot.data[%%hotDataKey%%] = %%stableComponentIdent%%\n }\n `,\n {\n syntacticPlaceholders: true,\n },\n)\n\nexport function createReactStableHmrSplitRouteComponentsPlugin(): ReferenceRouteCompilerPlugin {\n return {\n name: 'react-stable-hmr-split-route-components',\n onSplitRouteProperty(ctx) {\n if (ctx.splitNodeMeta.splitStrategy !== 'lazyRouteComponent') {\n return\n }\n\n const stableComponentIdent = getUniqueProgramIdentifier(\n ctx.programPath,\n `TSRSplit${capitalizeIdentifier(ctx.splitNodeMeta.exporterIdent)}`,\n )\n\n const hotDataKey = createHotDataKey(ctx.splitNodeMeta.exporterIdent)\n\n ctx.insertionPath.insertBefore(\n buildStableSplitComponentStatements({\n stableComponentIdent,\n hotDataKey: t.stringLiteral(hotDataKey),\n lazyRouteComponentIdent: t.identifier(ctx.lazyRouteComponentIdent),\n localImporterIdent: t.identifier(\n ctx.splitNodeMeta.localImporterIdent,\n ),\n exporterIdent: t.stringLiteral(ctx.splitNodeMeta.exporterIdent),\n }),\n )\n\n return t.identifier(stableComponentIdent.name)\n },\n }\n}\n"],"mappings":";;;;AAKA,SAAS,qBAAqB,KAAa;AACzC,QAAO,IAAI,GAAI,aAAa,GAAG,IAAI,MAAM,EAAE;;AAG7C,SAAS,iBAAiB,YAAoB;AAC5C,QAAO,uBAAuB;;AAGhC,IAAM,sCAAsC,SAAS,WACnD;;;;;;KAOA,EACE,uBAAuB,MACxB,CACF;AAED,SAAgB,iDAA+E;AAC7F,QAAO;EACL,MAAM;EACN,qBAAqB,KAAK;AACxB,OAAI,IAAI,cAAc,kBAAkB,qBACtC;GAGF,MAAM,uBAAuB,2BAC3B,IAAI,aACJ,WAAW,qBAAqB,IAAI,cAAc,cAAc,GACjE;GAED,MAAM,aAAa,iBAAiB,IAAI,cAAc,cAAc;AAEpE,OAAI,cAAc,aAChB,oCAAoC;IAClC;IACA,YAAY,EAAE,cAAc,WAAW;IACvC,yBAAyB,EAAE,WAAW,IAAI,wBAAwB;IAClE,oBAAoB,EAAE,WACpB,IAAI,cAAc,mBACnB;IACD,eAAe,EAAE,cAAc,IAAI,cAAc,cAAc;IAChE,CAAC,CACH;AAED,UAAO,EAAE,WAAW,qBAAqB,KAAK;;EAEjD"}
1
+ {"version":3,"file":"react-stable-hmr-split-route-components.js","names":[],"sources":["../../../../../src/core/code-splitter/plugins/react-stable-hmr-split-route-components.ts"],"sourcesContent":["import * as template from '@babel/template'\nimport * as t from '@babel/types'\nimport { createHmrHotExpressionAst } from '../../hmr-hot-expression'\nimport { getUniqueProgramIdentifier } from '../../utils'\nimport type { ReferenceRouteCompilerPlugin } from '../plugins'\n\nfunction capitalizeIdentifier(str: string) {\n return str[0]!.toUpperCase() + str.slice(1)\n}\n\nfunction createHotDataKey(exportName: string) {\n return `tsr-split-component:${exportName}`\n}\n\nconst buildStableSplitComponentStatements = template.statements(\n `\n const %%stableComponentIdent%% = (() => {\n const hot = %%hotExpression%%\n const hotData = hot ? (hot.data ??= {}) : undefined\n return hotData?.[%%hotDataKey%%] ?? %%lazyRouteComponentIdent%%(%%localImporterIdent%%, %%exporterIdent%%)\n })()\n if (%%hotExpression%%) {\n ((%%hotExpression%%).data ??= {})[%%hotDataKey%%] = %%stableComponentIdent%%\n }\n `,\n {\n syntacticPlaceholders: true,\n },\n)\n\nexport function createReactStableHmrSplitRouteComponentsPlugin(opts?: {\n hotExpression?: string\n}): ReferenceRouteCompilerPlugin {\n return {\n name: 'react-stable-hmr-split-route-components',\n onSplitRouteProperty(ctx) {\n if (ctx.splitNodeMeta.splitStrategy !== 'lazyRouteComponent') {\n return\n }\n\n const stableComponentIdent = getUniqueProgramIdentifier(\n ctx.programPath,\n `TSRSplit${capitalizeIdentifier(ctx.splitNodeMeta.exporterIdent)}`,\n )\n\n const hotDataKey = createHotDataKey(ctx.splitNodeMeta.exporterIdent)\n\n ctx.insertionPath.insertBefore(\n buildStableSplitComponentStatements({\n stableComponentIdent,\n hotDataKey: t.stringLiteral(hotDataKey),\n hotExpression: createHmrHotExpressionAst(\n opts?.hotExpression ?? ctx.opts.hmrHotExpression,\n ),\n lazyRouteComponentIdent: t.identifier(ctx.lazyRouteComponentIdent),\n localImporterIdent: t.identifier(\n ctx.splitNodeMeta.localImporterIdent,\n ),\n exporterIdent: t.stringLiteral(ctx.splitNodeMeta.exporterIdent),\n }),\n )\n\n return t.identifier(stableComponentIdent.name)\n },\n }\n}\n"],"mappings":";;;;;AAMA,SAAS,qBAAqB,KAAa;AACzC,QAAO,IAAI,GAAI,aAAa,GAAG,IAAI,MAAM,EAAE;;AAG7C,SAAS,iBAAiB,YAAoB;AAC5C,QAAO,uBAAuB;;AAGhC,IAAM,sCAAsC,SAAS,WACnD;;;;;;;;;KAUA,EACE,uBAAuB,MACxB,CACF;AAED,SAAgB,+CAA+C,MAE9B;AAC/B,QAAO;EACL,MAAM;EACN,qBAAqB,KAAK;AACxB,OAAI,IAAI,cAAc,kBAAkB,qBACtC;GAGF,MAAM,uBAAuB,2BAC3B,IAAI,aACJ,WAAW,qBAAqB,IAAI,cAAc,cAAc,GACjE;GAED,MAAM,aAAa,iBAAiB,IAAI,cAAc,cAAc;AAEpE,OAAI,cAAc,aAChB,oCAAoC;IAClC;IACA,YAAY,EAAE,cAAc,WAAW;IACvC,eAAe,0BACb,MAAM,iBAAiB,IAAI,KAAK,iBACjC;IACD,yBAAyB,EAAE,WAAW,IAAI,wBAAwB;IAClE,oBAAoB,EAAE,WACpB,IAAI,cAAc,mBACnB;IACD,eAAe,EAAE,cAAc,IAAI,cAAc,cAAc;IAChE,CAAC,CACH;AAED,UAAO,EAAE,WAAW,qBAAqB,KAAK;;EAEjD"}
@@ -10,6 +10,7 @@ export type CompileCodeSplitReferenceRouteOptions = {
10
10
  filename: string;
11
11
  id: string;
12
12
  addHmr?: boolean;
13
+ hmrHotExpression?: string;
13
14
  sharedBindings?: Set<string>;
14
15
  };
15
16
  export type ReferenceRouteCompilerPluginContext = {
@@ -28,6 +29,7 @@ export type ReferenceRouteSplitPropertyCompilerPluginContext = {
28
29
  prop: t.ObjectProperty;
29
30
  splitNodeMeta: SplitNodeMeta;
30
31
  lazyRouteComponentIdent: string;
32
+ opts: CompileCodeSplitReferenceRouteOptions;
31
33
  };
32
34
  export type ReferenceRouteCompilerPluginResult = {
33
35
  modified?: boolean;
@@ -28,6 +28,9 @@ export type CodeSplittingOptions = {
28
28
  */
29
29
  addHmr?: boolean;
30
30
  };
31
+ export type HmrOptions = {
32
+ hotExpression?: string;
33
+ };
31
34
  type FileRouteKeys = keyof (Parameters<CreateFileRoute<any, any, any, any, any>>[0] & {});
32
35
  export type DeletableNodes = FileRouteKeys | (string & {});
33
36
  export declare const configSchema: z.ZodObject<{
@@ -94,6 +97,13 @@ export declare const configSchema: z.ZodObject<{
94
97
  enableRouteGeneration: z.ZodOptional<z.ZodBoolean>;
95
98
  codeSplittingOptions: z.ZodOptional<z.ZodType<CodeSplittingOptions, z.ZodTypeDef, CodeSplittingOptions>>;
96
99
  plugin: z.ZodOptional<z.ZodObject<{
100
+ hmr: z.ZodOptional<z.ZodObject<{
101
+ hotExpression: z.ZodOptional<z.ZodString>;
102
+ }, "strip", z.ZodTypeAny, {
103
+ hotExpression?: string | undefined;
104
+ }, {
105
+ hotExpression?: string | undefined;
106
+ }>>;
97
107
  vite: z.ZodOptional<z.ZodObject<{
98
108
  environmentName: z.ZodOptional<z.ZodString>;
99
109
  }, "strip", z.ZodTypeAny, {
@@ -102,10 +112,16 @@ export declare const configSchema: z.ZodObject<{
102
112
  environmentName?: string | undefined;
103
113
  }>>;
104
114
  }, "strip", z.ZodTypeAny, {
115
+ hmr?: {
116
+ hotExpression?: string | undefined;
117
+ } | undefined;
105
118
  vite?: {
106
119
  environmentName?: string | undefined;
107
120
  } | undefined;
108
121
  }, {
122
+ hmr?: {
123
+ hotExpression?: string | undefined;
124
+ } | undefined;
109
125
  vite?: {
110
126
  environmentName?: string | undefined;
111
127
  } | undefined;
@@ -135,6 +151,9 @@ export declare const configSchema: z.ZodObject<{
135
151
  enableRouteGeneration?: boolean | undefined;
136
152
  codeSplittingOptions?: CodeSplittingOptions | undefined;
137
153
  plugin?: {
154
+ hmr?: {
155
+ hotExpression?: string | undefined;
156
+ } | undefined;
138
157
  vite?: {
139
158
  environmentName?: string | undefined;
140
159
  } | undefined;
@@ -158,6 +177,9 @@ export declare const configSchema: z.ZodObject<{
158
177
  enableRouteGeneration?: boolean | undefined;
159
178
  codeSplittingOptions?: CodeSplittingOptions | undefined;
160
179
  plugin?: {
180
+ hmr?: {
181
+ hotExpression?: string | undefined;
182
+ } | undefined;
161
183
  vite?: {
162
184
  environmentName?: string | undefined;
163
185
  } | undefined;
@@ -224,6 +246,9 @@ export declare const getConfig: (inlineConfig: Partial<Config>, root: string) =>
224
246
  enableRouteGeneration?: boolean | undefined;
225
247
  codeSplittingOptions?: CodeSplittingOptions | undefined;
226
248
  plugin?: {
249
+ hmr?: {
250
+ hotExpression?: string | undefined;
251
+ } | undefined;
227
252
  vite?: {
228
253
  environmentName?: string | undefined;
229
254
  } | undefined;
@@ -25,7 +25,10 @@ var configSchema$1 = configSchema.extend({
25
25
  codeSplittingOptions: z.custom((v) => {
26
26
  return codeSplittingOptionsSchema.parse(v);
27
27
  }).optional(),
28
- plugin: z.object({ vite: z.object({ environmentName: z.string().optional() }).optional() }).optional()
28
+ plugin: z.object({
29
+ hmr: z.object({ hotExpression: z.string().optional() }).optional(),
30
+ vite: z.object({ environmentName: z.string().optional() }).optional()
31
+ }).optional()
29
32
  });
30
33
  var getConfig$1 = (inlineConfig, root) => {
31
34
  const config = getConfig(inlineConfig, root);
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":[],"sources":["../../../src/core/config.ts"],"sourcesContent":["import { z } from 'zod'\nimport {\n configSchema as generatorConfigSchema,\n getConfig as getGeneratorConfig,\n} from '@tanstack/router-generator'\nimport type {\n CreateFileRoute,\n RegisteredRouter,\n RouteIds,\n} from '@tanstack/router-core'\nimport type { CodeSplitGroupings } from './constants'\n\nexport const splitGroupingsSchema = z\n .array(\n z.array(\n z.union([\n z.literal('loader'),\n z.literal('component'),\n z.literal('pendingComponent'),\n z.literal('errorComponent'),\n z.literal('notFoundComponent'),\n ]),\n ),\n {\n message:\n \" Must be an Array of Arrays containing the split groupings. i.e. [['component'], ['pendingComponent'], ['errorComponent', 'notFoundComponent']]\",\n },\n )\n .superRefine((val, ctx) => {\n const flattened = val.flat()\n const unique = [...new Set(flattened)]\n\n // Elements must be unique,\n // ie. this shouldn't be allows [['component'], ['component', 'loader']]\n if (unique.length !== flattened.length) {\n ctx.addIssue({\n code: 'custom',\n message:\n \" Split groupings must be unique and not repeated. i.e. i.e. [['component'], ['pendingComponent'], ['errorComponent', 'notFoundComponent']].\" +\n `\\n You input was: ${JSON.stringify(val)}.`,\n })\n }\n })\n\nexport type CodeSplittingOptions = {\n /**\n * Use this function to programmatically control the code splitting behavior\n * based on the `routeId` for each route.\n *\n * If you just need to change the default behavior, you can use the `defaultBehavior` option.\n * @param params\n */\n splitBehavior?: (params: {\n routeId: RouteIds<RegisteredRouter['routeTree']>\n }) => CodeSplitGroupings | undefined | void\n\n /**\n * The default/global configuration to control your code splitting behavior per route.\n * @default [['component'],['pendingComponent'],['errorComponent'],['notFoundComponent']]\n */\n defaultBehavior?: CodeSplitGroupings\n\n /**\n * The nodes that shall be deleted from the route.\n * @default undefined\n */\n deleteNodes?: Array<DeletableNodes>\n\n /**\n * @default true\n */\n addHmr?: boolean\n}\n\nconst codeSplittingOptionsSchema = z.object({\n splitBehavior: z.function().optional(),\n defaultBehavior: splitGroupingsSchema.optional(),\n deleteNodes: z.array(z.string()).optional(),\n addHmr: z.boolean().optional().default(true),\n})\n\ntype FileRouteKeys = keyof (Parameters<\n CreateFileRoute<any, any, any, any, any>\n>[0] & {})\nexport type DeletableNodes = FileRouteKeys | (string & {})\n\nexport const configSchema = generatorConfigSchema.extend({\n enableRouteGeneration: z.boolean().optional(),\n codeSplittingOptions: z\n .custom<CodeSplittingOptions>((v) => {\n return codeSplittingOptionsSchema.parse(v)\n })\n .optional(),\n plugin: z\n .object({\n vite: z\n .object({\n environmentName: z.string().optional(),\n })\n .optional(),\n })\n .optional(),\n})\n\nexport const getConfig = (inlineConfig: Partial<Config>, root: string) => {\n const config = getGeneratorConfig(inlineConfig, root)\n\n return configSchema.parse({ ...inlineConfig, ...config })\n}\n\nexport type Config = z.infer<typeof configSchema>\nexport type ConfigInput = z.input<typeof configSchema>\nexport type ConfigOutput = z.output<typeof configSchema>\n"],"mappings":";;;AAYA,IAAa,uBAAuB,EACjC,MACC,EAAE,MACA,EAAE,MAAM;CACN,EAAE,QAAQ,SAAS;CACnB,EAAE,QAAQ,YAAY;CACtB,EAAE,QAAQ,mBAAmB;CAC7B,EAAE,QAAQ,iBAAiB;CAC3B,EAAE,QAAQ,oBAAoB;CAC/B,CAAC,CACH,EACD,EACE,SACE,oJACH,CACF,CACA,aAAa,KAAK,QAAQ;CACzB,MAAM,YAAY,IAAI,MAAM;AAK5B,KAJe,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC,CAI3B,WAAW,UAAU,OAC9B,KAAI,SAAS;EACX,MAAM;EACN,SACE,kKACsB,KAAK,UAAU,IAAI,CAAC;EAC7C,CAAC;EAEJ;AAgCJ,IAAM,6BAA6B,EAAE,OAAO;CAC1C,eAAe,EAAE,UAAU,CAAC,UAAU;CACtC,iBAAiB,qBAAqB,UAAU;CAChD,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;CAC3C,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,QAAQ,KAAK;CAC7C,CAAC;AAOF,IAAa,iBAAe,aAAsB,OAAO;CACvD,uBAAuB,EAAE,SAAS,CAAC,UAAU;CAC7C,sBAAsB,EACnB,QAA8B,MAAM;AACnC,SAAO,2BAA2B,MAAM,EAAE;GAC1C,CACD,UAAU;CACb,QAAQ,EACL,OAAO,EACN,MAAM,EACH,OAAO,EACN,iBAAiB,EAAE,QAAQ,CAAC,UAAU,EACvC,CAAC,CACD,UAAU,EACd,CAAC,CACD,UAAU;CACd,CAAC;AAEF,IAAa,eAAa,cAA+B,SAAiB;CACxE,MAAM,SAAS,UAAmB,cAAc,KAAK;AAErD,QAAO,eAAa,MAAM;EAAE,GAAG;EAAc,GAAG;EAAQ,CAAC"}
1
+ {"version":3,"file":"config.js","names":[],"sources":["../../../src/core/config.ts"],"sourcesContent":["import { z } from 'zod'\nimport {\n configSchema as generatorConfigSchema,\n getConfig as getGeneratorConfig,\n} from '@tanstack/router-generator'\nimport type {\n CreateFileRoute,\n RegisteredRouter,\n RouteIds,\n} from '@tanstack/router-core'\nimport type { CodeSplitGroupings } from './constants'\n\nexport const splitGroupingsSchema = z\n .array(\n z.array(\n z.union([\n z.literal('loader'),\n z.literal('component'),\n z.literal('pendingComponent'),\n z.literal('errorComponent'),\n z.literal('notFoundComponent'),\n ]),\n ),\n {\n message:\n \" Must be an Array of Arrays containing the split groupings. i.e. [['component'], ['pendingComponent'], ['errorComponent', 'notFoundComponent']]\",\n },\n )\n .superRefine((val, ctx) => {\n const flattened = val.flat()\n const unique = [...new Set(flattened)]\n\n // Elements must be unique,\n // ie. this shouldn't be allows [['component'], ['component', 'loader']]\n if (unique.length !== flattened.length) {\n ctx.addIssue({\n code: 'custom',\n message:\n \" Split groupings must be unique and not repeated. i.e. i.e. [['component'], ['pendingComponent'], ['errorComponent', 'notFoundComponent']].\" +\n `\\n You input was: ${JSON.stringify(val)}.`,\n })\n }\n })\n\nexport type CodeSplittingOptions = {\n /**\n * Use this function to programmatically control the code splitting behavior\n * based on the `routeId` for each route.\n *\n * If you just need to change the default behavior, you can use the `defaultBehavior` option.\n * @param params\n */\n splitBehavior?: (params: {\n routeId: RouteIds<RegisteredRouter['routeTree']>\n }) => CodeSplitGroupings | undefined | void\n\n /**\n * The default/global configuration to control your code splitting behavior per route.\n * @default [['component'],['pendingComponent'],['errorComponent'],['notFoundComponent']]\n */\n defaultBehavior?: CodeSplitGroupings\n\n /**\n * The nodes that shall be deleted from the route.\n * @default undefined\n */\n deleteNodes?: Array<DeletableNodes>\n\n /**\n * @default true\n */\n addHmr?: boolean\n}\n\nexport type HmrOptions = {\n hotExpression?: string\n}\n\nconst codeSplittingOptionsSchema = z.object({\n splitBehavior: z.function().optional(),\n defaultBehavior: splitGroupingsSchema.optional(),\n deleteNodes: z.array(z.string()).optional(),\n addHmr: z.boolean().optional().default(true),\n})\n\ntype FileRouteKeys = keyof (Parameters<\n CreateFileRoute<any, any, any, any, any>\n>[0] & {})\nexport type DeletableNodes = FileRouteKeys | (string & {})\n\nexport const configSchema = generatorConfigSchema.extend({\n enableRouteGeneration: z.boolean().optional(),\n codeSplittingOptions: z\n .custom<CodeSplittingOptions>((v) => {\n return codeSplittingOptionsSchema.parse(v)\n })\n .optional(),\n plugin: z\n .object({\n hmr: z\n .object({\n hotExpression: z.string().optional(),\n })\n .optional(),\n vite: z\n .object({\n environmentName: z.string().optional(),\n })\n .optional(),\n })\n .optional(),\n})\n\nexport const getConfig = (inlineConfig: Partial<Config>, root: string) => {\n const config = getGeneratorConfig(inlineConfig, root)\n\n return configSchema.parse({ ...inlineConfig, ...config })\n}\n\nexport type Config = z.infer<typeof configSchema>\nexport type ConfigInput = z.input<typeof configSchema>\nexport type ConfigOutput = z.output<typeof configSchema>\n"],"mappings":";;;AAYA,IAAa,uBAAuB,EACjC,MACC,EAAE,MACA,EAAE,MAAM;CACN,EAAE,QAAQ,SAAS;CACnB,EAAE,QAAQ,YAAY;CACtB,EAAE,QAAQ,mBAAmB;CAC7B,EAAE,QAAQ,iBAAiB;CAC3B,EAAE,QAAQ,oBAAoB;CAC/B,CAAC,CACH,EACD,EACE,SACE,oJACH,CACF,CACA,aAAa,KAAK,QAAQ;CACzB,MAAM,YAAY,IAAI,MAAM;AAK5B,KAJe,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC,CAI3B,WAAW,UAAU,OAC9B,KAAI,SAAS;EACX,MAAM;EACN,SACE,kKACsB,KAAK,UAAU,IAAI,CAAC;EAC7C,CAAC;EAEJ;AAoCJ,IAAM,6BAA6B,EAAE,OAAO;CAC1C,eAAe,EAAE,UAAU,CAAC,UAAU;CACtC,iBAAiB,qBAAqB,UAAU;CAChD,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;CAC3C,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,QAAQ,KAAK;CAC7C,CAAC;AAOF,IAAa,iBAAe,aAAsB,OAAO;CACvD,uBAAuB,EAAE,SAAS,CAAC,UAAU;CAC7C,sBAAsB,EACnB,QAA8B,MAAM;AACnC,SAAO,2BAA2B,MAAM,EAAE;GAC1C,CACD,UAAU;CACb,QAAQ,EACL,OAAO;EACN,KAAK,EACF,OAAO,EACN,eAAe,EAAE,QAAQ,CAAC,UAAU,EACrC,CAAC,CACD,UAAU;EACb,MAAM,EACH,OAAO,EACN,iBAAiB,EAAE,QAAQ,CAAC,UAAU,EACvC,CAAC,CACD,UAAU;EACd,CAAC,CACD,UAAU;CACd,CAAC;AAEF,IAAa,eAAa,cAA+B,SAAiB;CACxE,MAAM,SAAS,UAAmB,cAAc,KAAK;AAErD,QAAO,eAAa,MAAM;EAAE,GAAG;EAAc,GAAG;EAAQ,CAAC"}
@@ -0,0 +1,6 @@
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>;
@@ -0,0 +1,23 @@
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
@@ -0,0 +1 @@
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,8 +1,8 @@
1
1
  import { getConfig } from "./config.js";
2
2
  import { debug, normalizePath } from "./utils.js";
3
3
  import { generateFromAst, logDiff, parseAst } from "@tanstack/router-utils";
4
- import * as babel from "@babel/core";
5
4
  import * as template from "@babel/template";
5
+ import * as babel from "@babel/core";
6
6
  //#region src/core/route-autoimport-plugin.ts
7
7
  /**
8
8
  * This plugin adds imports for createFileRoute and createLazyFileRoute to the file route.
@@ -1 +1,3 @@
1
- export declare function createRouteHmrStatement(stableRouteOptionKeys: Array<string>): import('@babel/types').Statement;
1
+ export declare function createRouteHmrStatement(stableRouteOptionKeys: Array<string>, opts?: {
2
+ hotExpression?: string;
3
+ }): import('@babel/types').Statement;
@@ -1,3 +1,4 @@
1
+ import { createHmrHotExpressionAst } from "./hmr-hot-expression.js";
1
2
  import * as template from "@babel/template";
2
3
  //#region src/core/route-hmr-statement.ts
3
4
  function handleRouteUpdate(routeId, newRoute) {
@@ -26,9 +27,9 @@ function handleRouteUpdate(routeId, newRoute) {
26
27
  router.resolvePathCache.clear();
27
28
  walkReplaceSegmentTree(oldRoute, router.processedTree.segmentTree);
28
29
  const filter = (m) => m.routeId === oldRoute.id;
29
- const activeMatch = router.stores.activeMatchesSnapshot.state.find(filter);
30
- const pendingMatch = router.stores.pendingMatchesSnapshot.state.find(filter);
31
- const cachedMatches = router.stores.cachedMatchesSnapshot.state.filter(filter);
30
+ const activeMatch = router.stores.matches.get().find(filter);
31
+ const pendingMatch = router.stores.pendingMatches.get().find(filter);
32
+ const cachedMatches = router.stores.cachedMatches.get().filter(filter);
32
33
  if (activeMatch || pendingMatch || cachedMatches.length > 0) {
33
34
  if (removedKeys.has("loader") || removedKeys.has("beforeLoad")) {
34
35
  const matchIds = [
@@ -38,8 +39,8 @@ function handleRouteUpdate(routeId, newRoute) {
38
39
  ].filter(Boolean);
39
40
  router.batch(() => {
40
41
  for (const matchId of matchIds) {
41
- const store = router.stores.pendingMatchStoresById.get(matchId) || router.stores.activeMatchStoresById.get(matchId) || router.stores.cachedMatchStoresById.get(matchId);
42
- if (store) store.setState((prev) => {
42
+ const store = router.stores.pendingMatchStores.get(matchId) || router.stores.matchStores.get(matchId) || router.stores.cachedMatchStores.get(matchId);
43
+ if (store) store.set((prev) => {
43
44
  const next = { ...prev };
44
45
  if (removedKeys.has("loader")) next.loaderData = void 0;
45
46
  if (removedKeys.has("beforeLoad")) next.__beforeLoadContext = void 0;
@@ -64,20 +65,22 @@ function handleRouteUpdate(routeId, newRoute) {
64
65
  }
65
66
  }
66
67
  var handleRouteUpdateStr = handleRouteUpdate.toString();
67
- function createRouteHmrStatement(stableRouteOptionKeys) {
68
+ function createRouteHmrStatement(stableRouteOptionKeys, opts) {
68
69
  return template.statement(`
69
- if (import.meta.hot) {
70
- import.meta.hot.accept((newModule) => {
70
+ if (%%hotExpression%%) {
71
+ const hot = %%hotExpression%%
72
+ const hotData = hot.data ??= {}
73
+ hot.accept((newModule) => {
71
74
  if (Route && newModule && newModule.Route) {
72
- const routeId = import.meta.hot.data['tsr-route-id'] ?? Route.id
75
+ const routeId = hotData['tsr-route-id'] ?? Route.id
73
76
  if (routeId) {
74
- import.meta.hot.data['tsr-route-id'] = routeId
77
+ hotData['tsr-route-id'] = routeId
75
78
  }
76
79
  (${handleRouteUpdateStr.replace(/['"]__TSR_COMPONENT_TYPES__['"]/, JSON.stringify(stableRouteOptionKeys))})(routeId, newModule.Route)
77
80
  }
78
81
  })
79
82
  }
80
- `, { placeholderPattern: false })();
83
+ `, { syntacticPlaceholders: true })({ hotExpression: createHmrHotExpressionAst(opts?.hotExpression) });
81
84
  }
82
85
  //#endregion
83
86
  export { createRouteHmrStatement };
@@ -1 +1 @@
1
- {"version":3,"file":"route-hmr-statement.js","names":[],"sources":["../../../src/core/route-hmr-statement.ts"],"sourcesContent":["import * as template from '@babel/template'\nimport type { AnyRoute, AnyRouteMatch, AnyRouter } 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 cachedMatchStoresById: Map<\n string,\n {\n setState: (updater: (prev: AnyRouteMatch) => AnyRouteMatch) => void\n }\n >\n pendingMatchStoresById: Map<\n string,\n {\n setState: (updater: (prev: AnyRouteMatch) => AnyRouteMatch) => void\n }\n >\n activeMatchStoresById: Map<\n string,\n {\n setState: (updater: (prev: AnyRouteMatch) => AnyRouteMatch) => void\n }\n >\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 import.meta.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.activeMatchesSnapshot.state.find(filter)\n const pendingMatch = router.stores.pendingMatchesSnapshot.state.find(filter)\n const cachedMatches = router.stores.cachedMatchesSnapshot.state.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.pendingMatchStoresById.get(matchId) ||\n router.stores.activeMatchStoresById.get(matchId) ||\n router.stores.cachedMatchStoresById.get(matchId)\n if (store) {\n store.setState((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(stableRouteOptionKeys: Array<string>) {\n return template.statement(\n `\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {\n if (Route && newModule && newModule.Route) {\n const routeId = import.meta.hot.data['tsr-route-id'] ?? Route.id\n if (routeId) {\n import.meta.hot.data['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 { placeholderPattern: false },\n )()\n}\n"],"mappings":";;AA2CA,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,sBAAsB,MAAM,KAAK,OAAO;CAC1E,MAAM,eAAe,OAAO,OAAO,uBAAuB,MAAM,KAAK,OAAO;CAC5E,MAAM,gBAAgB,OAAO,OAAO,sBAAsB,MAAM,OAAO,OAAO;AAE9E,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,uBAAuB,IAAI,QAAQ,IACjD,OAAO,OAAO,sBAAsB,IAAI,QAAQ,IAChD,OAAO,OAAO,sBAAsB,IAAI,QAAQ;AAClD,SAAI,MACF,OAAM,UAAU,SAAS;MACvB,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,wBAAwB,uBAAsC;AAC5E,QAAO,SAAS,UACd;;;;;;;;SAQK,qBAAqB,QACtB,mCACA,KAAK,UAAU,sBAAsB,CACtC,CAAC;;;;GAKJ,EAAE,oBAAoB,OAAO,CAC9B,EAAE"}
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 {\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) {\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":";;;AAwCA,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;AACA,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,4 +1,5 @@
1
1
  import { getConfig, splitGroupingsSchema } from "./config.js";
2
+ import { resolveHmrHotExpression } from "./hmr-hot-expression.js";
2
3
  import { defaultCodeSplitGroupings, splitRouteIdentNodes, tsrShared, tsrSplit } from "./constants.js";
3
4
  import { debug, normalizePath } from "./utils.js";
4
5
  import { decodeIdentifier } from "./code-splitter/path-ids.js";
@@ -11,7 +12,6 @@ import { logDiff } from "@tanstack/router-utils";
11
12
  * It is important to familiarize yourself with how the code-splitting works in this plugin.
12
13
  * https://github.com/TanStack/router/pull/3355
13
14
  */
14
- var PLUGIN_NAME = "unplugin:router-code-splitter";
15
15
  var CODE_SPLITTER_PLUGIN_NAME = "tanstack-router:code-splitter:compile-reference-file";
16
16
  /**
17
17
  * JSX transformation plugins grouped by framework.
@@ -82,6 +82,7 @@ var unpluginRouterCodeSplitterFactory = (options = {}, { framework: _framework }
82
82
  if (sharedBindings.size > 0) sharedBindingsMap.set(id, sharedBindings);
83
83
  else sharedBindingsMap.delete(id);
84
84
  const addHmr = (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction;
85
+ const hmrHotExpression = resolveHmrHotExpression(userConfig.plugin?.hmr?.hotExpression);
85
86
  const compiledReferenceRoute = compileCodeSplitReferenceRoute({
86
87
  code,
87
88
  codeSplitGroupings: splitGroupings,
@@ -90,10 +91,12 @@ var unpluginRouterCodeSplitterFactory = (options = {}, { framework: _framework }
90
91
  id,
91
92
  deleteNodes: userConfig.codeSplittingOptions?.deleteNodes ? new Set(userConfig.codeSplittingOptions.deleteNodes) : void 0,
92
93
  addHmr,
94
+ hmrHotExpression,
93
95
  sharedBindings: sharedBindings.size > 0 ? sharedBindings : void 0,
94
96
  compilerPlugins: getReferenceRouteCompilerPlugins({
95
97
  targetFramework: userConfig.target,
96
- addHmr
98
+ addHmr,
99
+ hmrHotExpression
97
100
  })
98
101
  });
99
102
  if (compiledReferenceRoute === null) {
@@ -168,19 +171,13 @@ var unpluginRouterCodeSplitterFactory = (options = {}, { framework: _framework }
168
171
  return true;
169
172
  }
170
173
  },
171
- rspack(compiler) {
174
+ rspack() {
172
175
  ROOT = process.cwd();
173
176
  initUserConfig();
174
- if (compiler.options.mode === "production") compiler.hooks.done.tap(PLUGIN_NAME, () => {
175
- console.info("✅ " + PLUGIN_NAME + ": code-splitting done!");
176
- });
177
177
  },
178
- webpack(compiler) {
178
+ webpack() {
179
179
  ROOT = process.cwd();
180
180
  initUserConfig();
181
- if (compiler.options.mode === "production") compiler.hooks.done.tap(PLUGIN_NAME, () => {
182
- console.info("✅ " + PLUGIN_NAME + ": code-splitting done!");
183
- });
184
181
  }
185
182
  },
186
183
  {
@@ -1 +1 @@
1
- {"version":3,"file":"router-code-splitter-plugin.js","names":[],"sources":["../../../src/core/router-code-splitter-plugin.ts"],"sourcesContent":["/**\n * It is important to familiarize yourself with how the code-splitting works in this plugin.\n * https://github.com/TanStack/router/pull/3355\n */\n\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { logDiff } from '@tanstack/router-utils'\nimport { getConfig, splitGroupingsSchema } from './config'\nimport {\n compileCodeSplitReferenceRoute,\n compileCodeSplitSharedRoute,\n compileCodeSplitVirtualRoute,\n computeSharedBindings,\n detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport { getReferenceRouteCompilerPlugins } from './code-splitter/plugins/framework-plugins'\nimport {\n defaultCodeSplitGroupings,\n splitRouteIdentNodes,\n tsrShared,\n tsrSplit,\n} from './constants'\nimport { decodeIdentifier } from './code-splitter/path-ids'\nimport { debug, normalizePath } from './utils'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { Config } from './config'\nimport type {\n UnpluginFactory,\n TransformResult as UnpluginTransformResult,\n} from 'unplugin'\n\nconst PLUGIN_NAME = 'unplugin:router-code-splitter'\nconst CODE_SPLITTER_PLUGIN_NAME =\n 'tanstack-router:code-splitter:compile-reference-file'\n\ntype TransformationPluginInfo = {\n pluginNames: Array<string>\n pkg: string\n usage: string\n}\n\n/**\n * JSX transformation plugins grouped by framework.\n * These plugins must come AFTER the TanStack Router plugin in the Vite config.\n */\nconst TRANSFORMATION_PLUGINS_BY_FRAMEWORK: Record<\n string,\n Array<TransformationPluginInfo>\n> = {\n react: [\n {\n // Babel-based React plugin\n pluginNames: ['vite:react-babel', 'vite:react-refresh'],\n pkg: '@vitejs/plugin-react',\n usage: 'react()',\n },\n {\n // SWC-based React plugin\n pluginNames: ['vite:react-swc', 'vite:react-swc:resolve-runtime'],\n pkg: '@vitejs/plugin-react-swc',\n usage: 'reactSwc()',\n },\n {\n // OXC-based React plugin (deprecated but should still be handled)\n pluginNames: ['vite:react-oxc:config', 'vite:react-oxc:refresh-runtime'],\n pkg: '@vitejs/plugin-react-oxc',\n usage: 'reactOxc()',\n },\n ],\n solid: [\n {\n pluginNames: ['solid'],\n pkg: 'vite-plugin-solid',\n usage: 'solid()',\n },\n ],\n}\n\nexport const unpluginRouterCodeSplitterFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}, { framework: _framework }) => {\n let ROOT: string = process.cwd()\n let userConfig: Config\n\n function initUserConfig() {\n if (typeof options === 'function') {\n userConfig = options()\n } else {\n userConfig = getConfig(options, ROOT)\n }\n }\n const isProduction = process.env.NODE_ENV === 'production'\n // Map from normalized route file path → set of shared binding names.\n // Populated by the reference compiler, consumed by virtual and shared compilers.\n const sharedBindingsMap = new Map<string, Set<string>>()\n\n const getGlobalCodeSplitGroupings = () => {\n return (\n userConfig.codeSplittingOptions?.defaultBehavior ||\n defaultCodeSplitGroupings\n )\n }\n const getShouldSplitFn = () => {\n return userConfig.codeSplittingOptions?.splitBehavior\n }\n\n const handleCompilingReferenceFile = (\n code: string,\n id: string,\n generatorNodeInfo: GetRoutesByFileMapResultValue,\n ): UnpluginTransformResult => {\n if (debug) console.info('Compiling Route: ', id)\n\n const fromCode = detectCodeSplitGroupingsFromRoute({\n code,\n })\n\n if (fromCode.groupings !== undefined) {\n const res = splitGroupingsSchema.safeParse(fromCode.groupings)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const userShouldSplitFn = getShouldSplitFn()\n\n const pluginSplitBehavior = userShouldSplitFn?.({\n routeId: generatorNodeInfo.routePath,\n }) as CodeSplitGroupings | undefined\n\n if (pluginSplitBehavior) {\n const res = splitGroupingsSchema.safeParse(pluginSplitBehavior)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings returned when using \\`splitBehavior\\` for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const splitGroupings: CodeSplitGroupings =\n fromCode.groupings ?? pluginSplitBehavior ?? getGlobalCodeSplitGroupings()\n\n // Compute shared bindings before compiling the reference route\n const sharedBindings = computeSharedBindings({\n code,\n codeSplitGroupings: splitGroupings,\n })\n if (sharedBindings.size > 0) {\n sharedBindingsMap.set(id, sharedBindings)\n } else {\n sharedBindingsMap.delete(id)\n }\n\n const addHmr =\n (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction\n\n const compiledReferenceRoute = compileCodeSplitReferenceRoute({\n code,\n codeSplitGroupings: splitGroupings,\n targetFramework: userConfig.target,\n filename: id,\n id,\n deleteNodes: userConfig.codeSplittingOptions?.deleteNodes\n ? new Set(userConfig.codeSplittingOptions.deleteNodes)\n : undefined,\n addHmr,\n sharedBindings: sharedBindings.size > 0 ? sharedBindings : undefined,\n compilerPlugins: getReferenceRouteCompilerPlugins({\n targetFramework: userConfig.target,\n addHmr,\n }),\n })\n\n if (compiledReferenceRoute === null) {\n if (debug) {\n console.info(\n `No changes made to route \"${id}\", skipping code-splitting.`,\n )\n }\n return null\n }\n if (debug) {\n logDiff(code, compiledReferenceRoute.code)\n console.log('Output:\\n', compiledReferenceRoute.code + '\\n\\n')\n }\n\n return compiledReferenceRoute\n }\n\n const handleCompilingVirtualFile = (\n code: string,\n id: string,\n ): UnpluginTransformResult => {\n if (debug) console.info('Splitting Route: ', id)\n\n const [_, ...pathnameParts] = id.split('?')\n\n const searchParams = new URLSearchParams(pathnameParts.join('?'))\n const splitValue = searchParams.get(tsrSplit)\n\n if (!splitValue) {\n throw new Error(\n `The split value for the virtual route \"${id}\" was not found.`,\n )\n }\n\n const rawGrouping = decodeIdentifier(splitValue)\n const grouping = [...new Set(rawGrouping)].filter((p) =>\n splitRouteIdentNodes.includes(p as any),\n ) as Array<SplitRouteIdentNodes>\n\n const baseId = id.split('?')[0]!\n const resolvedSharedBindings = sharedBindingsMap.get(baseId)\n\n const result = compileCodeSplitVirtualRoute({\n code,\n filename: id,\n splitTargets: grouping,\n sharedBindings: resolvedSharedBindings,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n }\n\n const includedCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n ]\n return [\n {\n name: 'tanstack-router:code-splitter:compile-reference-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: {\n exclude: [tsrSplit, tsrShared],\n // this is necessary for webpack / rspack to avoid matching .html files\n include: /\\.(m|c)?(j|t)sx?$/,\n },\n code: {\n include: includedCode,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n const generatorFileInfo =\n globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId)\n if (\n generatorFileInfo &&\n includedCode.some((included) => code.includes(included))\n ) {\n return handleCompilingReferenceFile(\n code,\n normalizedId,\n generatorFileInfo,\n )\n }\n\n return null\n },\n },\n\n vite: {\n configResolved(config) {\n ROOT = config.root\n initUserConfig()\n\n // Validate plugin order - router must come before JSX transformation plugins\n const routerPluginIndex = config.plugins.findIndex(\n (p) => p.name === CODE_SPLITTER_PLUGIN_NAME,\n )\n\n if (routerPluginIndex === -1) return\n\n const frameworkPlugins =\n TRANSFORMATION_PLUGINS_BY_FRAMEWORK[userConfig.target]\n if (!frameworkPlugins) return\n\n for (const transformPlugin of frameworkPlugins) {\n const transformPluginIndex = config.plugins.findIndex((p) =>\n transformPlugin.pluginNames.includes(p.name),\n )\n\n if (\n transformPluginIndex !== -1 &&\n transformPluginIndex < routerPluginIndex\n ) {\n throw new Error(\n `Plugin order error: '${transformPlugin.pkg}' is placed before '@tanstack/router-plugin'.\\n\\n` +\n `The TanStack Router plugin must come BEFORE JSX transformation plugins.\\n\\n` +\n `Please update your Vite config:\\n\\n` +\n ` plugins: [\\n` +\n ` tanstackRouter(),\\n` +\n ` ${transformPlugin.usage},\\n` +\n ` ]\\n`,\n )\n }\n }\n },\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n\n rspack(compiler) {\n ROOT = process.cwd()\n initUserConfig()\n\n if (compiler.options.mode === 'production') {\n compiler.hooks.done.tap(PLUGIN_NAME, () => {\n console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')\n })\n }\n },\n\n webpack(compiler) {\n ROOT = process.cwd()\n initUserConfig()\n\n if (compiler.options.mode === 'production') {\n compiler.hooks.done.tap(PLUGIN_NAME, () => {\n console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')\n })\n }\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-virtual-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-split/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n return handleCompilingVirtualFile(code, normalizedId)\n },\n },\n\n vite: {\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-shared-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-shared/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n const [baseId] = normalizedId.split('?')\n\n if (!baseId) return null\n\n const sharedBindings = sharedBindingsMap.get(baseId)\n if (!sharedBindings || sharedBindings.size === 0) return null\n\n if (debug) console.info('Compiling Shared Module: ', id)\n\n const result = compileCodeSplitSharedRoute({\n code,\n sharedBindings,\n filename: normalizedId,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n },\n },\n\n vite: {\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n },\n ]\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"router-code-splitter-plugin.js","names":[],"sources":["../../../src/core/router-code-splitter-plugin.ts"],"sourcesContent":["/**\n * It is important to familiarize yourself with how the code-splitting works in this plugin.\n * https://github.com/TanStack/router/pull/3355\n */\n\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { logDiff } from '@tanstack/router-utils'\nimport { getConfig, splitGroupingsSchema } from './config'\nimport { resolveHmrHotExpression } from './hmr-hot-expression'\nimport {\n compileCodeSplitReferenceRoute,\n compileCodeSplitSharedRoute,\n compileCodeSplitVirtualRoute,\n computeSharedBindings,\n detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport { getReferenceRouteCompilerPlugins } from './code-splitter/plugins/framework-plugins'\nimport {\n defaultCodeSplitGroupings,\n splitRouteIdentNodes,\n tsrShared,\n tsrSplit,\n} from './constants'\nimport { decodeIdentifier } from './code-splitter/path-ids'\nimport { debug, normalizePath } from './utils'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { Config } from './config'\nimport type {\n UnpluginFactory,\n TransformResult as UnpluginTransformResult,\n} from 'unplugin'\n\nconst PLUGIN_NAME = 'unplugin:router-code-splitter'\nconst CODE_SPLITTER_PLUGIN_NAME =\n 'tanstack-router:code-splitter:compile-reference-file'\n\ntype TransformationPluginInfo = {\n pluginNames: Array<string>\n pkg: string\n usage: string\n}\n\n/**\n * JSX transformation plugins grouped by framework.\n * These plugins must come AFTER the TanStack Router plugin in the Vite config.\n */\nconst TRANSFORMATION_PLUGINS_BY_FRAMEWORK: Record<\n string,\n Array<TransformationPluginInfo>\n> = {\n react: [\n {\n // Babel-based React plugin\n pluginNames: ['vite:react-babel', 'vite:react-refresh'],\n pkg: '@vitejs/plugin-react',\n usage: 'react()',\n },\n {\n // SWC-based React plugin\n pluginNames: ['vite:react-swc', 'vite:react-swc:resolve-runtime'],\n pkg: '@vitejs/plugin-react-swc',\n usage: 'reactSwc()',\n },\n {\n // OXC-based React plugin (deprecated but should still be handled)\n pluginNames: ['vite:react-oxc:config', 'vite:react-oxc:refresh-runtime'],\n pkg: '@vitejs/plugin-react-oxc',\n usage: 'reactOxc()',\n },\n ],\n solid: [\n {\n pluginNames: ['solid'],\n pkg: 'vite-plugin-solid',\n usage: 'solid()',\n },\n ],\n}\n\nexport const unpluginRouterCodeSplitterFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}, { framework: _framework }) => {\n let ROOT: string = process.cwd()\n let userConfig: Config\n\n function initUserConfig() {\n if (typeof options === 'function') {\n userConfig = options()\n } else {\n userConfig = getConfig(options, ROOT)\n }\n }\n const isProduction = process.env.NODE_ENV === 'production'\n // Map from normalized route file path → set of shared binding names.\n // Populated by the reference compiler, consumed by virtual and shared compilers.\n const sharedBindingsMap = new Map<string, Set<string>>()\n\n const getGlobalCodeSplitGroupings = () => {\n return (\n userConfig.codeSplittingOptions?.defaultBehavior ||\n defaultCodeSplitGroupings\n )\n }\n const getShouldSplitFn = () => {\n return userConfig.codeSplittingOptions?.splitBehavior\n }\n\n const handleCompilingReferenceFile = (\n code: string,\n id: string,\n generatorNodeInfo: GetRoutesByFileMapResultValue,\n ): UnpluginTransformResult => {\n if (debug) console.info('Compiling Route: ', id)\n\n const fromCode = detectCodeSplitGroupingsFromRoute({\n code,\n })\n\n if (fromCode.groupings !== undefined) {\n const res = splitGroupingsSchema.safeParse(fromCode.groupings)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const userShouldSplitFn = getShouldSplitFn()\n\n const pluginSplitBehavior = userShouldSplitFn?.({\n routeId: generatorNodeInfo.routePath,\n }) as CodeSplitGroupings | undefined\n\n if (pluginSplitBehavior) {\n const res = splitGroupingsSchema.safeParse(pluginSplitBehavior)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings returned when using \\`splitBehavior\\` for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const splitGroupings: CodeSplitGroupings =\n fromCode.groupings ?? pluginSplitBehavior ?? getGlobalCodeSplitGroupings()\n\n // Compute shared bindings before compiling the reference route\n const sharedBindings = computeSharedBindings({\n code,\n codeSplitGroupings: splitGroupings,\n })\n if (sharedBindings.size > 0) {\n sharedBindingsMap.set(id, sharedBindings)\n } else {\n sharedBindingsMap.delete(id)\n }\n\n const addHmr =\n (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction\n const hmrHotExpression = resolveHmrHotExpression(\n userConfig.plugin?.hmr?.hotExpression,\n )\n\n const compiledReferenceRoute = compileCodeSplitReferenceRoute({\n code,\n codeSplitGroupings: splitGroupings,\n targetFramework: userConfig.target,\n filename: id,\n id,\n deleteNodes: userConfig.codeSplittingOptions?.deleteNodes\n ? new Set(userConfig.codeSplittingOptions.deleteNodes)\n : undefined,\n addHmr,\n hmrHotExpression,\n sharedBindings: sharedBindings.size > 0 ? sharedBindings : undefined,\n compilerPlugins: getReferenceRouteCompilerPlugins({\n targetFramework: userConfig.target,\n addHmr,\n hmrHotExpression,\n }),\n })\n\n if (compiledReferenceRoute === null) {\n if (debug) {\n console.info(\n `No changes made to route \"${id}\", skipping code-splitting.`,\n )\n }\n return null\n }\n if (debug) {\n logDiff(code, compiledReferenceRoute.code)\n console.log('Output:\\n', compiledReferenceRoute.code + '\\n\\n')\n }\n\n return compiledReferenceRoute\n }\n\n const handleCompilingVirtualFile = (\n code: string,\n id: string,\n ): UnpluginTransformResult => {\n if (debug) console.info('Splitting Route: ', id)\n\n const [_, ...pathnameParts] = id.split('?')\n\n const searchParams = new URLSearchParams(pathnameParts.join('?'))\n const splitValue = searchParams.get(tsrSplit)\n\n if (!splitValue) {\n throw new Error(\n `The split value for the virtual route \"${id}\" was not found.`,\n )\n }\n\n const rawGrouping = decodeIdentifier(splitValue)\n const grouping = [...new Set(rawGrouping)].filter((p) =>\n splitRouteIdentNodes.includes(p as any),\n ) as Array<SplitRouteIdentNodes>\n\n const baseId = id.split('?')[0]!\n const resolvedSharedBindings = sharedBindingsMap.get(baseId)\n\n const result = compileCodeSplitVirtualRoute({\n code,\n filename: id,\n splitTargets: grouping,\n sharedBindings: resolvedSharedBindings,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n }\n\n const includedCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n ]\n return [\n {\n name: 'tanstack-router:code-splitter:compile-reference-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: {\n exclude: [tsrSplit, tsrShared],\n // this is necessary for webpack / rspack to avoid matching .html files\n include: /\\.(m|c)?(j|t)sx?$/,\n },\n code: {\n include: includedCode,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n const generatorFileInfo =\n globalThis.TSR_ROUTES_BY_ID_MAP?.get(normalizedId)\n if (\n generatorFileInfo &&\n includedCode.some((included) => code.includes(included))\n ) {\n return handleCompilingReferenceFile(\n code,\n normalizedId,\n generatorFileInfo,\n )\n }\n\n return null\n },\n },\n\n vite: {\n configResolved(config) {\n ROOT = config.root\n initUserConfig()\n\n // Validate plugin order - router must come before JSX transformation plugins\n const routerPluginIndex = config.plugins.findIndex(\n (p) => p.name === CODE_SPLITTER_PLUGIN_NAME,\n )\n\n if (routerPluginIndex === -1) return\n\n const frameworkPlugins =\n TRANSFORMATION_PLUGINS_BY_FRAMEWORK[userConfig.target]\n if (!frameworkPlugins) return\n\n for (const transformPlugin of frameworkPlugins) {\n const transformPluginIndex = config.plugins.findIndex((p) =>\n transformPlugin.pluginNames.includes(p.name),\n )\n\n if (\n transformPluginIndex !== -1 &&\n transformPluginIndex < routerPluginIndex\n ) {\n throw new Error(\n `Plugin order error: '${transformPlugin.pkg}' is placed before '@tanstack/router-plugin'.\\n\\n` +\n `The TanStack Router plugin must come BEFORE JSX transformation plugins.\\n\\n` +\n `Please update your Vite config:\\n\\n` +\n ` plugins: [\\n` +\n ` tanstackRouter(),\\n` +\n ` ${transformPlugin.usage},\\n` +\n ` ]\\n`,\n )\n }\n }\n },\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n\n rspack() {\n ROOT = process.cwd()\n initUserConfig()\n },\n\n webpack() {\n ROOT = process.cwd()\n initUserConfig()\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-virtual-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-split/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n return handleCompilingVirtualFile(code, normalizedId)\n },\n },\n\n vite: {\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-shared-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-shared/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n const [baseId] = normalizedId.split('?')\n\n if (!baseId) return null\n\n const sharedBindings = sharedBindingsMap.get(baseId)\n if (!sharedBindings || sharedBindings.size === 0) return null\n\n if (debug) console.info('Compiling Shared Module: ', id)\n\n const result = compileCodeSplitSharedRoute({\n code,\n sharedBindings,\n filename: normalizedId,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n },\n },\n\n vite: {\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n },\n ]\n}\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { getConfig } from "./config.js";
2
+ import { resolveHmrHotExpression } from "./hmr-hot-expression.js";
2
3
  import { createRouteHmrStatement } from "./route-hmr-statement.js";
3
4
  import { debug, normalizePath } from "./utils.js";
4
5
  import { compileCodeSplitReferenceRoute } from "./code-splitter/compilers.js";
@@ -30,17 +31,20 @@ var unpluginRouterHmrFactory = (options = {}) => {
30
31
  const normalizedId = normalizePath(id);
31
32
  if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) return null;
32
33
  if (debug) console.info("Adding HMR handling to route ", normalizedId);
34
+ const hmrHotExpression = resolveHmrHotExpression(userConfig.plugin?.hmr?.hotExpression);
33
35
  if (userConfig.target === "react") {
34
36
  const compiled = compileCodeSplitReferenceRoute({
35
37
  code,
36
38
  filename: normalizedId,
37
39
  id: normalizedId,
38
40
  addHmr: true,
41
+ hmrHotExpression,
39
42
  codeSplitGroupings: [],
40
43
  targetFramework: "react",
41
44
  compilerPlugins: getReferenceRouteCompilerPlugins({
42
45
  targetFramework: "react",
43
- addHmr: true
46
+ addHmr: true,
47
+ hmrHotExpression
44
48
  })
45
49
  });
46
50
  if (compiled) {
@@ -52,7 +56,7 @@ var unpluginRouterHmrFactory = (options = {}) => {
52
56
  }
53
57
  }
54
58
  const ast = parseAst({ code });
55
- ast.program.body.push(createRouteHmrStatement([]));
59
+ ast.program.body.push(createRouteHmrStatement([], { hotExpression: hmrHotExpression }));
56
60
  const result = generateFromAst(ast, {
57
61
  sourceMaps: true,
58
62
  filename: normalizedId,
@@ -1 +1 @@
1
- {"version":3,"file":"router-hmr-plugin.js","names":[],"sources":["../../../src/core/router-hmr-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport { compileCodeSplitReferenceRoute } from './code-splitter/compilers'\nimport { getReferenceRouteCompilerPlugins } from './code-splitter/plugins/framework-plugins'\nimport { createRouteHmrStatement } from './route-hmr-statement'\nimport { debug, normalizePath } from './utils'\nimport { getConfig } from './config'\nimport type { UnpluginFactory } from 'unplugin'\nimport type { Config } from './config'\n\n/**\n * This plugin adds HMR support for file routes.\n * It is only added to the composed plugin in dev when autoCodeSplitting is disabled, since the code splitting plugin\n * handles HMR for code-split routes itself.\n */\n\nconst includeCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n]\nexport const unpluginRouterHmrFactory: UnpluginFactory<\n Partial<Config> | undefined\n> = (options = {}) => {\n let ROOT: string = process.cwd()\n let userConfig = options as Config\n\n return {\n name: 'tanstack-router:hmr',\n enforce: 'pre',\n transform: {\n filter: {\n // this is necessary for webpack / rspack to avoid matching .html files\n id: /\\.(m|c)?(j|t)sx?$/,\n code: {\n include: includeCode,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {\n return null\n }\n\n if (debug) console.info('Adding HMR handling to route ', normalizedId)\n\n if (userConfig.target === 'react') {\n const compilerPlugins = getReferenceRouteCompilerPlugins({\n targetFramework: 'react',\n addHmr: true,\n })\n const compiled = compileCodeSplitReferenceRoute({\n code,\n filename: normalizedId,\n id: normalizedId,\n addHmr: true,\n codeSplitGroupings: [],\n targetFramework: 'react',\n compilerPlugins,\n })\n\n if (compiled) {\n if (debug) {\n logDiff(code, compiled.code)\n console.log('Output:\\n', compiled.code + '\\n\\n')\n }\n\n return compiled\n }\n }\n\n const ast = parseAst({ code })\n ast.program.body.push(createRouteHmrStatement([]))\n const result = generateFromAst(ast, {\n sourceMaps: true,\n filename: normalizedId,\n sourceFileName: normalizedId,\n })\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n return result\n },\n },\n vite: {\n configResolved(config) {\n ROOT = config.root\n userConfig = getConfig(options, ROOT)\n },\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;AAeA,IAAM,cAAc;CAClB;CACA;CACA;CACD;AACD,IAAa,4BAER,UAAU,EAAE,KAAK;CACpB,IAAI,OAAe,QAAQ,KAAK;CAChC,IAAI,aAAa;AAEjB,QAAO;EACL,MAAM;EACN,SAAS;EACT,WAAW;GACT,QAAQ;IAEN,IAAI;IACJ,MAAM,EACJ,SAAS,aACV;IACF;GACD,QAAQ,MAAM,IAAI;IAChB,MAAM,eAAe,cAAc,GAAG;AACtC,QAAI,CAAC,WAAW,sBAAsB,IAAI,aAAa,CACrD,QAAO;AAGT,QAAI,MAAO,SAAQ,KAAK,iCAAiC,aAAa;AAEtE,QAAI,WAAW,WAAW,SAAS;KAKjC,MAAM,WAAW,+BAA+B;MAC9C;MACA,UAAU;MACV,IAAI;MACJ,QAAQ;MACR,oBAAoB,EAAE;MACtB,iBAAiB;MACjB,iBAXsB,iCAAiC;OACvD,iBAAiB;OACjB,QAAQ;OACT,CAAC;MASD,CAAC;AAEF,SAAI,UAAU;AACZ,UAAI,OAAO;AACT,eAAQ,MAAM,SAAS,KAAK;AAC5B,eAAQ,IAAI,aAAa,SAAS,OAAO,OAAO;;AAGlD,aAAO;;;IAIX,MAAM,MAAM,SAAS,EAAE,MAAM,CAAC;AAC9B,QAAI,QAAQ,KAAK,KAAK,wBAAwB,EAAE,CAAC,CAAC;IAClD,MAAM,SAAS,gBAAgB,KAAK;KAClC,YAAY;KACZ,UAAU;KACV,gBAAgB;KACjB,CAAC;AACF,QAAI,OAAO;AACT,aAAQ,MAAM,OAAO,KAAK;AAC1B,aAAQ,IAAI,aAAa,OAAO,OAAO,OAAO;;AAEhD,WAAO;;GAEV;EACD,MAAM;GACJ,eAAe,QAAQ;AACrB,WAAO,OAAO;AACd,iBAAa,UAAU,SAAS,KAAK;;GAEvC,mBAAmB,aAAa;AAC9B,QAAI,WAAW,QAAQ,MAAM,gBAC3B,QAAO,WAAW,OAAO,KAAK,oBAAoB,YAAY;AAEhE,WAAO;;GAEV;EACF"}
1
+ {"version":3,"file":"router-hmr-plugin.js","names":[],"sources":["../../../src/core/router-hmr-plugin.ts"],"sourcesContent":["import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'\nimport { compileCodeSplitReferenceRoute } from './code-splitter/compilers'\nimport { getReferenceRouteCompilerPlugins } from './code-splitter/plugins/framework-plugins'\nimport { createRouteHmrStatement } from './route-hmr-statement'\nimport { debug, normalizePath } from './utils'\nimport { getConfig } from './config'\nimport { resolveHmrHotExpression } from './hmr-hot-expression'\nimport type { UnpluginFactory } from 'unplugin'\nimport type { Config } from './config'\n\n/**\n * This plugin adds HMR support for file routes.\n * It is only added to the composed plugin in dev when autoCodeSplitting is disabled, since the code splitting plugin\n * handles HMR for code-split routes itself.\n */\n\nconst includeCode = [\n 'createFileRoute(',\n 'createRootRoute(',\n 'createRootRouteWithContext(',\n]\nexport const unpluginRouterHmrFactory: UnpluginFactory<\n Partial<Config> | undefined\n> = (options = {}) => {\n let ROOT: string = process.cwd()\n let userConfig = options as Config\n\n return {\n name: 'tanstack-router:hmr',\n enforce: 'pre',\n transform: {\n filter: {\n // this is necessary for webpack / rspack to avoid matching .html files\n id: /\\.(m|c)?(j|t)sx?$/,\n code: {\n include: includeCode,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n if (!globalThis.TSR_ROUTES_BY_ID_MAP?.has(normalizedId)) {\n return null\n }\n\n if (debug) console.info('Adding HMR handling to route ', normalizedId)\n\n const hmrHotExpression = resolveHmrHotExpression(\n userConfig.plugin?.hmr?.hotExpression,\n )\n\n if (userConfig.target === 'react') {\n const compilerPlugins = getReferenceRouteCompilerPlugins({\n targetFramework: 'react',\n addHmr: true,\n hmrHotExpression,\n })\n const compiled = compileCodeSplitReferenceRoute({\n code,\n filename: normalizedId,\n id: normalizedId,\n addHmr: true,\n hmrHotExpression,\n codeSplitGroupings: [],\n targetFramework: 'react',\n compilerPlugins,\n })\n\n if (compiled) {\n if (debug) {\n logDiff(code, compiled.code)\n console.log('Output:\\n', compiled.code + '\\n\\n')\n }\n\n return compiled\n }\n }\n\n const ast = parseAst({ code })\n ast.program.body.push(\n createRouteHmrStatement([], { hotExpression: hmrHotExpression }),\n )\n const result = generateFromAst(ast, {\n sourceMaps: true,\n filename: normalizedId,\n sourceFileName: normalizedId,\n })\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n return result\n },\n },\n vite: {\n configResolved(config) {\n ROOT = config.root\n userConfig = getConfig(options, ROOT)\n },\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAgBA,IAAM,cAAc;CAClB;CACA;CACA;CACD;AACD,IAAa,4BAER,UAAU,EAAE,KAAK;CACpB,IAAI,OAAe,QAAQ,KAAK;CAChC,IAAI,aAAa;AAEjB,QAAO;EACL,MAAM;EACN,SAAS;EACT,WAAW;GACT,QAAQ;IAEN,IAAI;IACJ,MAAM,EACJ,SAAS,aACV;IACF;GACD,QAAQ,MAAM,IAAI;IAChB,MAAM,eAAe,cAAc,GAAG;AACtC,QAAI,CAAC,WAAW,sBAAsB,IAAI,aAAa,CACrD,QAAO;AAGT,QAAI,MAAO,SAAQ,KAAK,iCAAiC,aAAa;IAEtE,MAAM,mBAAmB,wBACvB,WAAW,QAAQ,KAAK,cACzB;AAED,QAAI,WAAW,WAAW,SAAS;KAMjC,MAAM,WAAW,+BAA+B;MAC9C;MACA,UAAU;MACV,IAAI;MACJ,QAAQ;MACR;MACA,oBAAoB,EAAE;MACtB,iBAAiB;MACjB,iBAbsB,iCAAiC;OACvD,iBAAiB;OACjB,QAAQ;OACR;OACD,CAAC;MAUD,CAAC;AAEF,SAAI,UAAU;AACZ,UAAI,OAAO;AACT,eAAQ,MAAM,SAAS,KAAK;AAC5B,eAAQ,IAAI,aAAa,SAAS,OAAO,OAAO;;AAGlD,aAAO;;;IAIX,MAAM,MAAM,SAAS,EAAE,MAAM,CAAC;AAC9B,QAAI,QAAQ,KAAK,KACf,wBAAwB,EAAE,EAAE,EAAE,eAAe,kBAAkB,CAAC,CACjE;IACD,MAAM,SAAS,gBAAgB,KAAK;KAClC,YAAY;KACZ,UAAU;KACV,gBAAgB;KACjB,CAAC;AACF,QAAI,OAAO;AACT,aAAQ,MAAM,OAAO,KAAK;AAC1B,aAAQ,IAAI,aAAa,OAAO,OAAO,OAAO;;AAEhD,WAAO;;GAEV;EACD,MAAM;GACJ,eAAe,QAAQ;AACrB,WAAO,OAAO;AACd,iBAAa,UAAU,SAAS,KAAK;;GAEvC,mBAAmB,aAAa;AAC9B,QAAI,WAAW,QAAQ,MAAM,gBAC3B,QAAO,WAAW,OAAO,KAAK,oBAAoB,YAAY;AAEhE,WAAO;;GAEV;EACF"}
@@ -33,6 +33,9 @@ declare const TanStackRouterGeneratorEsbuild: (options?: Partial<{
33
33
  enableRouteGeneration?: boolean | undefined;
34
34
  codeSplittingOptions?: CodeSplittingOptions | undefined;
35
35
  plugin?: {
36
+ hmr?: {
37
+ hotExpression?: string | undefined;
38
+ } | undefined;
36
39
  vite?: {
37
40
  environmentName?: string | undefined;
38
41
  } | undefined;
@@ -87,6 +90,9 @@ declare const TanStackRouterCodeSplitterEsbuild: (options?: Partial<{
87
90
  enableRouteGeneration?: boolean | undefined;
88
91
  codeSplittingOptions?: CodeSplittingOptions | undefined;
89
92
  plugin?: {
93
+ hmr?: {
94
+ hotExpression?: string | undefined;
95
+ } | undefined;
90
96
  vite?: {
91
97
  environmentName?: string | undefined;
92
98
  } | undefined;
@@ -141,6 +147,9 @@ declare const TanStackRouterEsbuild: (options?: Partial<{
141
147
  enableRouteGeneration?: boolean | undefined;
142
148
  codeSplittingOptions?: CodeSplittingOptions | undefined;
143
149
  plugin?: {
150
+ hmr?: {
151
+ hotExpression?: string | undefined;
152
+ } | undefined;
144
153
  vite?: {
145
154
  environmentName?: string | undefined;
146
155
  } | undefined;
@@ -186,6 +195,9 @@ declare const tanstackRouter: (options?: Partial<{
186
195
  enableRouteGeneration?: boolean | undefined;
187
196
  codeSplittingOptions?: CodeSplittingOptions | undefined;
188
197
  plugin?: {
198
+ hmr?: {
199
+ hotExpression?: string | undefined;
200
+ } | undefined;
189
201
  vite?: {
190
202
  environmentName?: string | undefined;
191
203
  } | undefined;
@@ -1,5 +1,5 @@
1
1
  export { configSchema, getConfig } from './core/config.js';
2
2
  export { unpluginRouterCodeSplitterFactory } from './core/router-code-splitter-plugin.js';
3
3
  export { unpluginRouterGeneratorFactory } from './core/router-generator-plugin.js';
4
- export type { Config, ConfigInput, ConfigOutput, CodeSplittingOptions, DeletableNodes, } from './core/config.js';
4
+ export type { Config, ConfigInput, ConfigOutput, CodeSplittingOptions, DeletableNodes, HmrOptions, } from './core/config.js';
5
5
  export { tsrSplit, splitRouteIdentNodes, defaultCodeSplitGroupings, } from './core/constants.js';