@tanstack/start-plugin-core 1.167.17 → 1.167.19

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 (183) hide show
  1. package/dist/esm/config-context.d.ts +26 -0
  2. package/dist/esm/config-context.js +81 -0
  3. package/dist/esm/config-context.js.map +1 -0
  4. package/dist/esm/constants.d.ts +6 -1
  5. package/dist/esm/constants.js +3 -2
  6. package/dist/esm/constants.js.map +1 -1
  7. package/dist/esm/import-protection-plugin/extensionlessAbsoluteIdResolver.js +1 -1
  8. package/dist/esm/import-protection-plugin/plugin.js +1 -1
  9. package/dist/esm/import-protection-plugin/virtualModules.js +1 -1
  10. package/dist/esm/index.d.ts +5 -3
  11. package/dist/esm/index.js +3 -4
  12. package/dist/esm/planning.d.ts +40 -0
  13. package/dist/esm/planning.js +107 -0
  14. package/dist/esm/planning.js.map +1 -0
  15. package/dist/esm/schema.d.ts +3093 -44
  16. package/dist/esm/schema.js +5 -5
  17. package/dist/esm/schema.js.map +1 -1
  18. package/dist/esm/serialization-adapters-module.d.ts +17 -0
  19. package/dist/esm/serialization-adapters-module.js +39 -0
  20. package/dist/esm/serialization-adapters-module.js.map +1 -0
  21. package/dist/esm/{start-compiler-plugin → start-compiler}/compiler.d.ts +2 -3
  22. package/dist/esm/{start-compiler-plugin → start-compiler}/compiler.js +17 -16
  23. package/dist/esm/start-compiler/compiler.js.map +1 -0
  24. package/dist/esm/start-compiler/config.d.ts +4 -0
  25. package/dist/esm/start-compiler/config.js +54 -0
  26. package/dist/esm/start-compiler/config.js.map +1 -0
  27. package/dist/esm/{start-compiler-plugin → start-compiler}/handleClientOnlyJSX.js +1 -1
  28. package/dist/esm/start-compiler/handleClientOnlyJSX.js.map +1 -0
  29. package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateIsomorphicFn.js +1 -1
  30. package/dist/esm/start-compiler/handleCreateIsomorphicFn.js.map +1 -0
  31. package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateMiddleware.js +1 -1
  32. package/dist/esm/start-compiler/handleCreateMiddleware.js.map +1 -0
  33. package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateServerFn.js +6 -17
  34. package/dist/esm/start-compiler/handleCreateServerFn.js.map +1 -0
  35. package/dist/esm/{start-compiler-plugin → start-compiler}/handleEnvOnly.js +1 -1
  36. package/dist/esm/start-compiler/handleEnvOnly.js.map +1 -0
  37. package/dist/esm/start-compiler/host.d.ts +20 -0
  38. package/dist/esm/start-compiler/host.js +38 -0
  39. package/dist/esm/start-compiler/host.js.map +1 -0
  40. package/dist/esm/start-compiler/load-module.d.ts +14 -0
  41. package/dist/esm/start-compiler/load-module.js +18 -0
  42. package/dist/esm/start-compiler/load-module.js.map +1 -0
  43. package/dist/esm/start-compiler/server-fn-resolver-module.d.ts +8 -0
  44. package/dist/esm/start-compiler/server-fn-resolver-module.js +77 -0
  45. package/dist/esm/start-compiler/server-fn-resolver-module.js.map +1 -0
  46. package/dist/esm/{start-compiler-plugin → start-compiler}/types.d.ts +4 -0
  47. package/dist/esm/{start-compiler-plugin → start-compiler}/utils.js +1 -1
  48. package/dist/esm/start-compiler/utils.js.map +1 -0
  49. package/dist/esm/start-manifest-plugin/manifestBuilder.d.ts +16 -16
  50. package/dist/esm/start-manifest-plugin/manifestBuilder.js +14 -45
  51. package/dist/esm/start-manifest-plugin/manifestBuilder.js.map +1 -1
  52. package/dist/esm/start-router-plugin/route-tree-footer.d.ts +6 -0
  53. package/dist/esm/start-router-plugin/route-tree-footer.js +44 -0
  54. package/dist/esm/start-router-plugin/route-tree-footer.js.map +1 -0
  55. package/dist/esm/types.d.ts +44 -10
  56. package/dist/esm/{dev-server-plugin → vite/dev-server-plugin}/dev-styles.js +1 -1
  57. package/dist/esm/vite/dev-server-plugin/dev-styles.js.map +1 -0
  58. package/dist/esm/{dev-server-plugin → vite/dev-server-plugin}/extract-html-scripts.js +1 -1
  59. package/dist/esm/vite/dev-server-plugin/extract-html-scripts.js.map +1 -0
  60. package/dist/esm/vite/dev-server-plugin/plugin.d.ts +7 -0
  61. package/dist/esm/{dev-server-plugin → vite/dev-server-plugin}/plugin.js +5 -6
  62. package/dist/esm/vite/dev-server-plugin/plugin.js.map +1 -0
  63. package/dist/esm/{load-env-plugin → vite/load-env-plugin}/plugin.js +1 -1
  64. package/dist/esm/vite/load-env-plugin/plugin.js.map +1 -0
  65. package/dist/esm/{output-directory.js → vite/output-directory.js} +2 -2
  66. package/dist/esm/vite/output-directory.js.map +1 -0
  67. package/dist/esm/vite/planning.d.ts +105 -0
  68. package/dist/esm/vite/planning.js +116 -0
  69. package/dist/esm/vite/planning.js.map +1 -0
  70. package/dist/esm/vite/plugin.d.ts +4 -0
  71. package/dist/esm/vite/plugin.js +169 -0
  72. package/dist/esm/vite/plugin.js.map +1 -0
  73. package/dist/esm/vite/plugins.d.ts +17 -0
  74. package/dist/esm/vite/plugins.js +50 -0
  75. package/dist/esm/vite/plugins.js.map +1 -0
  76. package/dist/esm/{post-server-build.d.ts → vite/post-server-build.d.ts} +1 -1
  77. package/dist/esm/{post-server-build.js → vite/post-server-build.js} +4 -4
  78. package/dist/esm/vite/post-server-build.js.map +1 -0
  79. package/dist/esm/{prerender.d.ts → vite/prerender.d.ts} +1 -1
  80. package/dist/esm/{prerender.js → vite/prerender.js} +5 -10
  81. package/dist/esm/vite/prerender.js.map +1 -0
  82. package/dist/esm/{preview-server-plugin → vite/preview-server-plugin}/plugin.js +4 -4
  83. package/dist/esm/vite/preview-server-plugin/plugin.js.map +1 -0
  84. package/dist/esm/vite/schema.d.ts +3373 -0
  85. package/dist/esm/vite/schema.js +12 -0
  86. package/dist/esm/vite/schema.js.map +1 -0
  87. package/dist/esm/vite/serialization-adapters-plugin.d.ts +5 -0
  88. package/dist/esm/vite/serialization-adapters-plugin.js +42 -0
  89. package/dist/esm/vite/serialization-adapters-plugin.js.map +1 -0
  90. package/dist/esm/vite/start-compiler-plugin/module-specifier.d.ts +3 -0
  91. package/dist/esm/vite/start-compiler-plugin/module-specifier.js +19 -0
  92. package/dist/esm/vite/start-compiler-plugin/module-specifier.js.map +1 -0
  93. package/dist/esm/{start-compiler-plugin → vite/start-compiler-plugin}/plugin.d.ts +4 -3
  94. package/dist/esm/vite/start-compiler-plugin/plugin.js +202 -0
  95. package/dist/esm/vite/start-compiler-plugin/plugin.js.map +1 -0
  96. package/dist/esm/vite/start-manifest-plugin/normalized-client-build.d.ts +6 -0
  97. package/dist/esm/vite/start-manifest-plugin/normalized-client-build.js +81 -0
  98. package/dist/esm/vite/start-manifest-plugin/normalized-client-build.js.map +1 -0
  99. package/dist/esm/vite/start-manifest-plugin/plugin.d.ts +6 -0
  100. package/dist/esm/{start-manifest-plugin → vite/start-manifest-plugin}/plugin.js +14 -9
  101. package/dist/esm/vite/start-manifest-plugin/plugin.js.map +1 -0
  102. package/dist/esm/{start-router-plugin → vite/start-router-plugin}/plugin.d.ts +3 -2
  103. package/dist/esm/{start-router-plugin → vite/start-router-plugin}/plugin.js +14 -37
  104. package/dist/esm/vite/start-router-plugin/plugin.js.map +1 -0
  105. package/dist/esm/vite/types.d.ts +15 -0
  106. package/package.json +14 -3
  107. package/src/config-context.ts +138 -0
  108. package/src/constants.ts +7 -3
  109. package/src/index.ts +5 -5
  110. package/src/planning.ts +151 -0
  111. package/src/schema.ts +93 -93
  112. package/src/serialization-adapters-module.ts +82 -0
  113. package/src/{start-compiler-plugin → start-compiler}/compiler.ts +67 -61
  114. package/src/start-compiler/config.ts +73 -0
  115. package/src/{start-compiler-plugin → start-compiler}/handleCreateServerFn.ts +14 -41
  116. package/src/start-compiler/host.ts +80 -0
  117. package/src/start-compiler/load-module.ts +31 -0
  118. package/src/start-compiler/server-fn-resolver-module.ts +129 -0
  119. package/src/{start-compiler-plugin → start-compiler}/types.ts +5 -0
  120. package/src/start-manifest-plugin/manifestBuilder.ts +65 -107
  121. package/src/start-router-plugin/route-tree-footer.ts +99 -0
  122. package/src/types.ts +53 -10
  123. package/src/{dev-server-plugin → vite/dev-server-plugin}/plugin.ts +7 -6
  124. package/src/{output-directory.ts → vite/output-directory.ts} +2 -2
  125. package/src/vite/planning.ts +234 -0
  126. package/src/vite/plugin.ts +276 -0
  127. package/src/vite/plugins.ts +81 -0
  128. package/src/{post-server-build.ts → vite/post-server-build.ts} +4 -6
  129. package/src/{prerender.ts → vite/prerender.ts} +21 -46
  130. package/src/{preview-server-plugin → vite/preview-server-plugin}/plugin.ts +2 -2
  131. package/src/vite/schema.ts +30 -0
  132. package/src/vite/serialization-adapters-plugin.ts +69 -0
  133. package/src/vite/start-compiler-plugin/module-specifier.ts +31 -0
  134. package/src/vite/start-compiler-plugin/plugin.ts +345 -0
  135. package/src/vite/start-manifest-plugin/normalized-client-build.ts +131 -0
  136. package/src/{start-manifest-plugin → vite/start-manifest-plugin}/plugin.ts +21 -13
  137. package/src/{start-router-plugin → vite/start-router-plugin}/plugin.ts +14 -80
  138. package/src/vite/types.ts +18 -0
  139. package/dist/esm/dev-server-plugin/dev-styles.js.map +0 -1
  140. package/dist/esm/dev-server-plugin/extract-html-scripts.js.map +0 -1
  141. package/dist/esm/dev-server-plugin/plugin.d.ts +0 -6
  142. package/dist/esm/dev-server-plugin/plugin.js.map +0 -1
  143. package/dist/esm/load-env-plugin/plugin.js.map +0 -1
  144. package/dist/esm/output-directory.js.map +0 -1
  145. package/dist/esm/plugin.d.ts +0 -4
  146. package/dist/esm/plugin.js +0 -301
  147. package/dist/esm/plugin.js.map +0 -1
  148. package/dist/esm/post-server-build.js.map +0 -1
  149. package/dist/esm/prerender.js.map +0 -1
  150. package/dist/esm/preview-server-plugin/plugin.js.map +0 -1
  151. package/dist/esm/start-compiler-plugin/compiler.js.map +0 -1
  152. package/dist/esm/start-compiler-plugin/handleClientOnlyJSX.js.map +0 -1
  153. package/dist/esm/start-compiler-plugin/handleCreateIsomorphicFn.js.map +0 -1
  154. package/dist/esm/start-compiler-plugin/handleCreateMiddleware.js.map +0 -1
  155. package/dist/esm/start-compiler-plugin/handleCreateServerFn.js.map +0 -1
  156. package/dist/esm/start-compiler-plugin/handleEnvOnly.js.map +0 -1
  157. package/dist/esm/start-compiler-plugin/plugin.js +0 -297
  158. package/dist/esm/start-compiler-plugin/plugin.js.map +0 -1
  159. package/dist/esm/start-compiler-plugin/utils.js.map +0 -1
  160. package/dist/esm/start-manifest-plugin/plugin.d.ts +0 -6
  161. package/dist/esm/start-manifest-plugin/plugin.js.map +0 -1
  162. package/dist/esm/start-router-plugin/plugin.js.map +0 -1
  163. package/src/plugin.ts +0 -471
  164. package/src/start-compiler-plugin/plugin.ts +0 -478
  165. /package/dist/esm/{start-compiler-plugin → start-compiler}/handleClientOnlyJSX.d.ts +0 -0
  166. /package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateIsomorphicFn.d.ts +0 -0
  167. /package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateMiddleware.d.ts +0 -0
  168. /package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateServerFn.d.ts +0 -0
  169. /package/dist/esm/{start-compiler-plugin → start-compiler}/handleEnvOnly.d.ts +0 -0
  170. /package/dist/esm/{start-compiler-plugin → start-compiler}/utils.d.ts +0 -0
  171. /package/dist/esm/{dev-server-plugin → vite/dev-server-plugin}/dev-styles.d.ts +0 -0
  172. /package/dist/esm/{dev-server-plugin → vite/dev-server-plugin}/extract-html-scripts.d.ts +0 -0
  173. /package/dist/esm/{load-env-plugin → vite/load-env-plugin}/plugin.d.ts +0 -0
  174. /package/dist/esm/{output-directory.d.ts → vite/output-directory.d.ts} +0 -0
  175. /package/dist/esm/{preview-server-plugin → vite/preview-server-plugin}/plugin.d.ts +0 -0
  176. /package/src/{start-compiler-plugin → start-compiler}/handleClientOnlyJSX.ts +0 -0
  177. /package/src/{start-compiler-plugin → start-compiler}/handleCreateIsomorphicFn.ts +0 -0
  178. /package/src/{start-compiler-plugin → start-compiler}/handleCreateMiddleware.ts +0 -0
  179. /package/src/{start-compiler-plugin → start-compiler}/handleEnvOnly.ts +0 -0
  180. /package/src/{start-compiler-plugin → start-compiler}/utils.ts +0 -0
  181. /package/src/{dev-server-plugin → vite/dev-server-plugin}/dev-styles.ts +0 -0
  182. /package/src/{dev-server-plugin → vite/dev-server-plugin}/extract-html-scripts.ts +0 -0
  183. /package/src/{load-env-plugin → vite/load-env-plugin}/plugin.ts +0 -0
@@ -0,0 +1,129 @@
1
+ import type { ServerFn } from './types'
2
+
3
+ interface ResolverManifestEntry {
4
+ id: string
5
+ functionName: string
6
+ extractedFilename: string
7
+ isClientReferenced: boolean
8
+ }
9
+
10
+ interface GenerateServerFnResolverModuleOptions {
11
+ serverFnsById: Record<string, ServerFn>
12
+ includeClientReferencedCheck: boolean
13
+ useStaticImports?: boolean
14
+ }
15
+
16
+ function getResolverManifestEntries(
17
+ serverFnsById: Record<string, ServerFn>,
18
+ ): Array<ResolverManifestEntry> {
19
+ return Object.entries(serverFnsById).map(([id, fn]) => ({
20
+ id,
21
+ functionName: fn.functionName,
22
+ extractedFilename: fn.extractedFilename,
23
+ isClientReferenced: fn.isClientReferenced ?? true,
24
+ }))
25
+ }
26
+
27
+ function getClientReferencedCheck(
28
+ includeClientReferencedCheck: boolean,
29
+ ): string {
30
+ if (!includeClientReferencedCheck) {
31
+ return ''
32
+ }
33
+
34
+ return `
35
+ if (access.origin === 'client' && !serverFnInfo.isClientReferenced) {
36
+ throw new Error('Server function not accessible from client: ' + id)
37
+ }
38
+ `
39
+ }
40
+
41
+ function getResolverBody(): string {
42
+ return `
43
+ export async function getServerFnById(id, access) {
44
+ const serverFnInfo = manifest[id]
45
+ if (!serverFnInfo) {
46
+ throw new Error('Server function info not found for ' + id)
47
+ }
48
+ __CLIENT_REFERENCED_CHECK__
49
+ const fnModule = serverFnInfo.module ?? (await serverFnInfo.importer())
50
+ if (!fnModule) {
51
+ throw new Error('Server function module not resolved for ' + id)
52
+ }
53
+ const action = fnModule[serverFnInfo.functionName]
54
+ if (!action) {
55
+ throw new Error('Server function module export not resolved for serverFn ID: ' + id)
56
+ }
57
+ return action
58
+ }
59
+ `
60
+ }
61
+
62
+ function getResolverManifestModuleAccess(opts: {
63
+ useStaticImports?: boolean
64
+ extractedFilename: string
65
+ moduleRef: string
66
+ }): string {
67
+ if (opts.useStaticImports) {
68
+ return `module: ${opts.moduleRef}`
69
+ }
70
+
71
+ return `importer: () => import(${JSON.stringify(opts.extractedFilename)})`
72
+ }
73
+
74
+ function getResolverManifestEntry(opts: {
75
+ entry: ResolverManifestEntry
76
+ moduleAccess: string
77
+ includeClientReferencedCheck: boolean
78
+ }): string {
79
+ const clientReferenced = opts.includeClientReferencedCheck
80
+ ? `,\n isClientReferenced: ${opts.entry.isClientReferenced}`
81
+ : ''
82
+
83
+ return `'${opts.entry.id}': {
84
+ functionName: '${opts.entry.functionName}',
85
+ ${opts.moduleAccess}${clientReferenced}
86
+ }`
87
+ }
88
+
89
+ export function generateServerFnResolverModule(
90
+ opts: GenerateServerFnResolverModuleOptions,
91
+ ): string {
92
+ const manifestEntries = getResolverManifestEntries(opts.serverFnsById)
93
+ const staticImports: Array<string> = []
94
+
95
+ const manifest = manifestEntries
96
+ .map((entry, index) => {
97
+ const moduleRef = `serverFnModule${index}`
98
+
99
+ if (opts.useStaticImports) {
100
+ staticImports.push(
101
+ `import * as ${moduleRef} from ${JSON.stringify(entry.extractedFilename)}`,
102
+ )
103
+ }
104
+
105
+ return getResolverManifestEntry({
106
+ entry,
107
+ moduleAccess: getResolverManifestModuleAccess({
108
+ useStaticImports: opts.useStaticImports,
109
+ extractedFilename: entry.extractedFilename,
110
+ moduleRef,
111
+ }),
112
+ includeClientReferencedCheck: opts.includeClientReferencedCheck,
113
+ })
114
+ })
115
+ .join(',\n ')
116
+
117
+ const body = getResolverBody().replace(
118
+ '__CLIENT_REFERENCED_CHECK__',
119
+ getClientReferencedCheck(opts.includeClientReferencedCheck),
120
+ )
121
+
122
+ return `
123
+ ${staticImports.join('\n')}
124
+ const manifest = {
125
+ ${manifest}
126
+ }
127
+ ${body}
128
+ `
129
+ }
@@ -112,6 +112,11 @@ export type GenerateFunctionIdFnOptional = (
112
112
  * Function type for generating replacement code for server functions.
113
113
  * Used internally by handleCreateServerFn.
114
114
  */
115
+ export type DevServerFnModuleSpecifierEncoder = (opts: {
116
+ extractedFilename: string
117
+ root: string
118
+ }) => string
119
+
115
120
  export type ReplacerFn = (opts: {
116
121
  /** Placeholder for the original function expression */
117
122
  fn: string
@@ -1,9 +1,13 @@
1
1
  /* eslint-disable @typescript-eslint/prefer-for-of */
2
2
  import { joinURL } from 'ufo'
3
3
  import { resolveManifestAssetLink, rootRouteId } from '@tanstack/router-core'
4
- import { tsrSplit } from '@tanstack/router-plugin'
4
+ import {
5
+ getRouteFilePathsFromModuleIds,
6
+ normalizeViteClientBuild,
7
+ normalizeViteClientChunk,
8
+ } from '../vite/start-manifest-plugin/normalized-client-build'
5
9
  import type { ManifestAssetLink, RouterManagedTag } from '@tanstack/router-core'
6
- import type { Rollup } from 'vite'
10
+ import type { NormalizedClientBuild, NormalizedClientChunk } from '../types'
7
11
 
8
12
  const ROUTER_MANAGED_MODE = 1
9
13
  const NON_ROUTE_DYNAMIC_MODE = 2
@@ -19,15 +23,15 @@ type RouteTreeRoute = {
19
23
  type RouteTreeRoutes = Record<string, RouteTreeRoute>
20
24
 
21
25
  interface ScannedClientChunks {
22
- entryChunk: Rollup.OutputChunk
23
- chunksByFileName: Map<string, Rollup.OutputChunk>
24
- routeChunksByFilePath: Map<string, Array<Rollup.OutputChunk>>
25
- routeEntryChunks: Set<Rollup.OutputChunk>
26
+ entryChunk: NormalizedClientChunk
27
+ chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>
28
+ routeChunksByFilePath: ReadonlyMap<string, Array<NormalizedClientChunk>>
29
+ routeEntryChunks: ReadonlySet<NormalizedClientChunk>
26
30
  }
27
31
 
28
32
  interface ManifestAssetResolvers {
29
33
  getAssetPath: (fileName: string) => string
30
- getChunkPreloads: (chunk: Rollup.OutputChunk) => Array<string>
34
+ getChunkPreloads: (chunk: NormalizedClientChunk) => Array<string>
31
35
  getStylesheetAsset: (cssFile: string) => RouterManagedTag
32
36
  }
33
37
 
@@ -121,9 +125,9 @@ function getAssetIdentity(asset: RouterManagedTag) {
121
125
 
122
126
  function mergeRouteChunkData(options: {
123
127
  route: RouteTreeRoute
124
- chunk: Rollup.OutputChunk
125
- getChunkCssAssets: (chunk: Rollup.OutputChunk) => Array<RouterManagedTag>
126
- getChunkPreloads: (chunk: Rollup.OutputChunk) => Array<string>
128
+ chunk: NormalizedClientChunk
129
+ getChunkCssAssets: (chunk: NormalizedClientChunk) => Array<RouterManagedTag>
130
+ getChunkPreloads: (chunk: NormalizedClientChunk) => Array<string>
127
131
  }) {
128
132
  const chunkAssets = options.getChunkCssAssets(options.chunk)
129
133
  const chunkPreloads = options.getChunkPreloads(options.chunk)
@@ -136,11 +140,11 @@ function mergeRouteChunkData(options: {
136
140
  }
137
141
 
138
142
  export function buildStartManifest(options: {
139
- clientBundle: Rollup.OutputBundle
143
+ clientBuild: NormalizedClientBuild
140
144
  routeTreeRoutes: RouteTreeRoutes
141
145
  basePath: string
142
146
  }) {
143
- const scannedChunks = scanClientChunks(options.clientBundle)
147
+ const scannedChunks = scanClientChunks(options.clientBuild)
144
148
  const hashedCssFiles = collectDynamicImportCss(
145
149
  scannedChunks.routeEntryChunks,
146
150
  scannedChunks.chunksByFileName,
@@ -178,110 +182,52 @@ export function buildStartManifest(options: {
178
182
  }
179
183
 
180
184
  export function scanClientChunks(
181
- clientBundle: Rollup.OutputBundle,
185
+ clientBuild: NormalizedClientBuild,
182
186
  ): ScannedClientChunks {
183
- let entryChunk: Rollup.OutputChunk | undefined
184
- const chunksByFileName = new Map<string, Rollup.OutputChunk>()
185
- const routeChunksByFilePath = new Map<string, Array<Rollup.OutputChunk>>()
186
- const routeEntryChunks = new Set<Rollup.OutputChunk>()
187
-
188
- for (const fileName in clientBundle) {
189
- const bundleEntry = clientBundle[fileName]!
190
- if (bundleEntry.type !== 'chunk') {
191
- continue
192
- }
193
-
194
- chunksByFileName.set(bundleEntry.fileName, bundleEntry)
187
+ const entryChunk = clientBuild.chunksByFileName.get(
188
+ clientBuild.entryChunkFileName,
189
+ )
195
190
 
196
- if (bundleEntry.isEntry) {
197
- if (entryChunk) {
198
- throw new Error(
199
- `multiple entries detected: ${entryChunk.fileName} ${bundleEntry.fileName}`,
200
- )
201
- }
202
- entryChunk = bundleEntry
203
- }
191
+ if (!entryChunk) {
192
+ throw new Error(`Missing entry chunk: ${clientBuild.entryChunkFileName}`)
193
+ }
204
194
 
205
- const routeFilePaths = getRouteFilePathsFromModuleIds(bundleEntry.moduleIds)
206
- if (routeFilePaths.length === 0) {
207
- continue
208
- }
195
+ const routeEntryChunks = new Set<NormalizedClientChunk>()
196
+ const routeChunksByFilePath = new Map<string, Array<NormalizedClientChunk>>()
209
197
 
210
- routeEntryChunks.add(bundleEntry)
198
+ for (const chunk of clientBuild.chunksByFileName.values()) {
199
+ if (chunk.routeFilePaths.length > 0) {
200
+ routeEntryChunks.add(chunk)
211
201
 
212
- for (let i = 0; i < routeFilePaths.length; i++) {
213
- const routeFilePath = routeFilePaths[i]!
214
- let chunks = routeChunksByFilePath.get(routeFilePath)
215
- if (chunks === undefined) {
216
- chunks = []
217
- routeChunksByFilePath.set(routeFilePath, chunks)
202
+ for (const routeFilePath of chunk.routeFilePaths) {
203
+ let chunks = routeChunksByFilePath.get(routeFilePath)
204
+ if (chunks === undefined) {
205
+ chunks = []
206
+ routeChunksByFilePath.set(routeFilePath, chunks)
207
+ }
208
+ chunks.push(chunk)
218
209
  }
219
- chunks.push(bundleEntry)
220
210
  }
221
211
  }
222
212
 
223
- if (!entryChunk) {
224
- throw new Error('No entry file found')
225
- }
226
-
227
213
  return {
228
214
  entryChunk,
229
- chunksByFileName,
215
+ chunksByFileName: clientBuild.chunksByFileName,
230
216
  routeChunksByFilePath,
231
217
  routeEntryChunks,
232
218
  }
233
219
  }
234
220
 
235
- export function getRouteFilePathsFromModuleIds(moduleIds: Array<string>) {
236
- let routeFilePaths: Array<string> | undefined
237
- let seenRouteFilePaths: Set<string> | undefined
238
-
239
- for (const moduleId of moduleIds) {
240
- const queryIndex = moduleId.indexOf('?')
241
-
242
- if (queryIndex < 0) {
243
- continue
244
- }
245
-
246
- const query = moduleId.slice(queryIndex + 1)
247
-
248
- // Fast check before allocating URLSearchParams
249
- if (!query.includes(tsrSplit)) {
250
- continue
251
- }
252
-
253
- if (!new URLSearchParams(query).has(tsrSplit)) {
254
- continue
255
- }
256
-
257
- const routeFilePath = moduleId.slice(0, queryIndex)
258
-
259
- if (seenRouteFilePaths?.has(routeFilePath)) {
260
- continue
261
- }
262
-
263
- if (routeFilePaths === undefined) {
264
- routeFilePaths = []
265
- seenRouteFilePaths = new Set<string>()
266
- }
267
-
268
- routeFilePaths.push(routeFilePath)
269
- seenRouteFilePaths!.add(routeFilePath)
270
- }
271
-
272
- return routeFilePaths ?? []
273
- }
274
-
275
221
  export function collectDynamicImportCss(
276
- routeEntryChunks: Set<Rollup.OutputChunk>,
277
- chunksByFileName: Map<string, Rollup.OutputChunk>,
278
- entryChunk?: Rollup.OutputChunk,
222
+ routeEntryChunks: ReadonlySet<NormalizedClientChunk>,
223
+ chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>,
224
+ entryChunk?: NormalizedClientChunk,
279
225
  ) {
280
226
  const routerManagedCssFiles = new Set<string>()
281
227
  const nonRouteDynamicCssFiles = new Set<string>()
282
228
  const hashedCssFiles = new Set<string>()
283
- const visitedByChunk = new Map<Rollup.OutputChunk, number>()
284
- const chunkStack: Array<Rollup.OutputChunk> = []
229
+ const visitedByChunk = new Map<NormalizedClientChunk, number>()
230
+ const chunkStack: Array<NormalizedClientChunk> = []
285
231
  const modeStack: Array<number> = []
286
232
 
287
233
  for (const routeEntryChunk of routeEntryChunks) {
@@ -306,13 +252,13 @@ export function collectDynamicImportCss(
306
252
  visitedByChunk.set(chunk, previousMode | mode)
307
253
 
308
254
  if ((mode & ROUTER_MANAGED_MODE) !== 0) {
309
- for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {
255
+ for (const cssFile of chunk.css) {
310
256
  routerManagedCssFiles.add(cssFile)
311
257
  }
312
258
  }
313
259
 
314
260
  if ((mode & NON_ROUTE_DYNAMIC_MODE) !== 0) {
315
- for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {
261
+ for (const cssFile of chunk.css) {
316
262
  nonRouteDynamicCssFiles.add(cssFile)
317
263
  }
318
264
  }
@@ -356,7 +302,7 @@ export function createManifestAssetResolvers(options: {
356
302
  }): ManifestAssetResolvers {
357
303
  const assetPathByFileName = new Map<string, string>()
358
304
  const stylesheetAssetByFileName = new Map<string, RouterManagedTag>()
359
- const preloadsByChunk = new Map<Rollup.OutputChunk, Array<string>>()
305
+ const preloadsByChunk = new Map<NormalizedClientChunk, Array<string>>()
360
306
 
361
307
  const getAssetPath = (fileName: string) => {
362
308
  const cachedPath = assetPathByFileName.get(fileName)
@@ -389,7 +335,7 @@ export function createManifestAssetResolvers(options: {
389
335
  return asset
390
336
  }
391
337
 
392
- const getChunkPreloads = (chunk: Rollup.OutputChunk) => {
338
+ const getChunkPreloads = (chunk: NormalizedClientChunk) => {
393
339
  const cachedPreloads = preloadsByChunk.get(chunk)
394
340
  if (cachedPreloads) {
395
341
  return cachedPreloads
@@ -413,11 +359,14 @@ export function createManifestAssetResolvers(options: {
413
359
  }
414
360
 
415
361
  export function createChunkCssAssetCollector(options: {
416
- chunksByFileName: Map<string, Rollup.OutputChunk>
362
+ chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>
417
363
  getStylesheetAsset: (cssFile: string) => RouterManagedTag
418
364
  }) {
419
- const assetsByChunk = new Map<Rollup.OutputChunk, Array<RouterManagedTag>>()
420
- const stateByChunk = new Map<Rollup.OutputChunk, number>()
365
+ const assetsByChunk = new Map<
366
+ NormalizedClientChunk,
367
+ Array<RouterManagedTag>
368
+ >()
369
+ const stateByChunk = new Map<NormalizedClientChunk, number>()
421
370
 
422
371
  const appendAsset = (
423
372
  assets: Array<RouterManagedTag>,
@@ -434,7 +383,7 @@ export function createChunkCssAssetCollector(options: {
434
383
  }
435
384
 
436
385
  const getChunkCssAssets = (
437
- chunk: Rollup.OutputChunk,
386
+ chunk: NormalizedClientChunk,
438
387
  ): Array<RouterManagedTag> => {
439
388
  const cachedAssets = assetsByChunk.get(chunk)
440
389
  if (cachedAssets) {
@@ -449,7 +398,7 @@ export function createChunkCssAssetCollector(options: {
449
398
  const assets: Array<RouterManagedTag> = []
450
399
  const seenAssets = new Set<string>()
451
400
 
452
- for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {
401
+ for (const cssFile of chunk.css) {
453
402
  appendAsset(assets, seenAssets, options.getStylesheetAsset(cssFile))
454
403
  }
455
404
 
@@ -475,9 +424,12 @@ export function createChunkCssAssetCollector(options: {
475
424
 
476
425
  export function buildRouteManifestRoutes(options: {
477
426
  routeTreeRoutes: RouteTreeRoutes
478
- routeChunksByFilePath: Map<string, Array<Rollup.OutputChunk>>
479
- chunksByFileName: Map<string, Rollup.OutputChunk>
480
- entryChunk: Rollup.OutputChunk
427
+ routeChunksByFilePath: ReadonlyMap<
428
+ string,
429
+ ReadonlyArray<NormalizedClientChunk>
430
+ >
431
+ chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>
432
+ entryChunk: NormalizedClientChunk
481
433
  assetResolvers: ManifestAssetResolvers
482
434
  }) {
483
435
  const routes: Record<string, RouteTreeRoute> = {}
@@ -526,6 +478,12 @@ export function buildRouteManifestRoutes(options: {
526
478
  return routes
527
479
  }
528
480
 
481
+ export {
482
+ getRouteFilePathsFromModuleIds,
483
+ normalizeViteClientBuild,
484
+ normalizeViteClientChunk,
485
+ }
486
+
529
487
  function dedupeNestedRouteManifestEntries(
530
488
  routeId: string,
531
489
  route: DedupeRoute,
@@ -0,0 +1,99 @@
1
+ import path from 'pathe'
2
+ import type { GetConfigFn, TanStackStartCoreOptions } from '../types'
3
+
4
+ function buildRouteTreeFileFooter(opts: {
5
+ generatedRouteTreePath: string
6
+ startFilePath: string | undefined
7
+ routerFilePath: string
8
+ framework: TanStackStartCoreOptions['framework']
9
+ userFooter?: Array<string> | (() => Array<string>)
10
+ }): Array<string> {
11
+ function getImportPath(absolutePath: string) {
12
+ let relativePath = path.relative(
13
+ path.dirname(opts.generatedRouteTreePath),
14
+ absolutePath,
15
+ )
16
+
17
+ if (!relativePath.startsWith('.')) {
18
+ relativePath = './' + relativePath
19
+ }
20
+
21
+ return relativePath.split(path.sep).join('/')
22
+ }
23
+
24
+ function appendFooterBlock(lines: Array<string>, block: string) {
25
+ if (!block) {
26
+ return
27
+ }
28
+
29
+ if (lines.length > 0) {
30
+ lines[lines.length - 1] += `\n${block}`
31
+ return
32
+ }
33
+
34
+ lines.push(block)
35
+ }
36
+
37
+ const footer: Array<string> = []
38
+
39
+ appendFooterBlock(
40
+ footer,
41
+ `import type { getRouter } from '${getImportPath(opts.routerFilePath)}'`,
42
+ )
43
+
44
+ if (opts.startFilePath) {
45
+ appendFooterBlock(
46
+ footer,
47
+ `import type { startInstance } from '${getImportPath(opts.startFilePath)}'`,
48
+ )
49
+ } else {
50
+ appendFooterBlock(
51
+ footer,
52
+ `import type { createStart } from '@tanstack/${opts.framework}-start'`,
53
+ )
54
+ }
55
+
56
+ appendFooterBlock(
57
+ footer,
58
+ `declare module '@tanstack/${opts.framework}-start' {
59
+ interface Register {
60
+ ssr: true
61
+ router: Awaited<ReturnType<typeof getRouter>>`,
62
+ )
63
+
64
+ if (opts.startFilePath) {
65
+ appendFooterBlock(
66
+ footer,
67
+ ` config: Awaited<ReturnType<typeof startInstance.getOptions>>`,
68
+ )
69
+ }
70
+
71
+ appendFooterBlock(
72
+ footer,
73
+ ` }
74
+ }`,
75
+ )
76
+
77
+ if (opts.userFooter) {
78
+ footer.push(
79
+ ...(Array.isArray(opts.userFooter) ? opts.userFooter : opts.userFooter()),
80
+ )
81
+ }
82
+
83
+ return footer
84
+ }
85
+
86
+ export function buildRouteTreeFileFooterFromConfig(opts: {
87
+ generatedRouteTreePath: string
88
+ getConfig: GetConfigFn
89
+ corePluginOpts: TanStackStartCoreOptions
90
+ }): Array<string> {
91
+ const { startConfig, resolvedStartConfig } = opts.getConfig()
92
+ return buildRouteTreeFileFooter({
93
+ generatedRouteTreePath: opts.generatedRouteTreePath,
94
+ startFilePath: resolvedStartConfig.startFilePath,
95
+ routerFilePath: resolvedStartConfig.routerFilePath,
96
+ framework: opts.corePluginOpts.framework,
97
+ userFooter: startConfig.router.routeTreeFileFooter,
98
+ })
99
+ }
package/src/types.ts CHANGED
@@ -2,19 +2,63 @@ import type { TanStackStartOutputConfig } from './schema'
2
2
 
3
3
  export type CompileStartFrameworkOptions = 'react' | 'solid' | 'vue'
4
4
 
5
- export interface TanStackStartVitePluginCoreOptions {
5
+ export type ServerFnLookupAccess = { origin: 'client' } | { origin: 'server' }
6
+
7
+ export type SerializationRuntime = 'client' | 'server'
8
+
9
+ export interface SerializationAdapterModuleRef {
10
+ module: string
11
+ export: string
12
+ isFactory?: boolean
13
+ }
14
+
15
+ export type SerializationAdapterByRuntime = Partial<
16
+ Record<SerializationRuntime, SerializationAdapterModuleRef>
17
+ >
18
+
19
+ export type SerializationAdapterConfig =
20
+ | SerializationAdapterModuleRef
21
+ | SerializationAdapterByRuntime
22
+
23
+ export interface NormalizedBasePaths {
24
+ publicBase: string
25
+ assetBase: {
26
+ dev: string
27
+ build: string
28
+ }
29
+ }
30
+
31
+ export interface NormalizedOutputDirectories {
32
+ client: string
33
+ server: string
34
+ }
35
+
36
+ export interface NormalizedClientChunk {
37
+ fileName: string
38
+ isEntry: boolean
39
+ imports: Array<string>
40
+ dynamicImports: Array<string>
41
+ css: Array<string>
42
+ routeFilePaths: Array<string>
43
+ }
44
+
45
+ export interface NormalizedClientBuild {
46
+ entryChunkFileName: string
47
+ chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>
48
+ chunkFileNamesByRouteFilePath: ReadonlyMap<string, ReadonlyArray<string>>
49
+ cssFilesBySourcePath: ReadonlyMap<string, ReadonlyArray<string>>
50
+ }
51
+
52
+ export interface TanStackStartCoreOptions {
6
53
  framework: CompileStartFrameworkOptions
7
54
  defaultEntryPaths: {
8
55
  client: string
9
56
  server: string
10
57
  start: string
11
58
  }
12
- serverFn?: {
13
- ssr?: {
14
- getServerFnById?: string
15
- }
16
- providerEnv?: string
17
- }
59
+ providerEnvironmentName: string
60
+ ssrIsProvider: boolean
61
+ serializationAdapters?: Array<SerializationAdapterConfig> | undefined
18
62
  }
19
63
 
20
64
  export interface ResolvedStartConfig {
@@ -22,12 +66,11 @@ export interface ResolvedStartConfig {
22
66
  startFilePath: string | undefined
23
67
  routerFilePath: string
24
68
  srcDirectory: string
25
- viteAppBase: string
26
- serverFnProviderEnv: string
69
+ basePaths: NormalizedBasePaths
70
+ outputDirectories: NormalizedOutputDirectories
27
71
  }
28
72
 
29
73
  export type GetConfigFn = () => {
30
74
  startConfig: TanStackStartOutputConfig
31
75
  resolvedStartConfig: ResolvedStartConfig
32
- corePluginOpts: TanStackStartVitePluginCoreOptions
33
76
  }
@@ -1,8 +1,8 @@
1
1
  import { isRunnableDevEnvironment } from 'vite'
2
2
  import { VIRTUAL_MODULES } from '@tanstack/start-server-core'
3
3
  import { NodeRequest, sendNodeResponse } from 'srvx/node'
4
- import { ENTRY_POINTS, VITE_ENVIRONMENT_NAMES } from '../constants'
5
- import { resolveViteId } from '../utils'
4
+ import { ENTRY_POINTS, VITE_ENVIRONMENT_NAMES } from '../../constants'
5
+ import { resolveViteId } from '../../utils'
6
6
  import { extractHtmlScripts } from './extract-html-scripts'
7
7
  import {
8
8
  CSS_MODULES_REGEX,
@@ -10,14 +10,16 @@ import {
10
10
  normalizeCssModuleCacheKey,
11
11
  } from './dev-styles'
12
12
  import type { Connect, DevEnvironment, PluginOption } from 'vite'
13
- import type { GetConfigFn } from '../types'
13
+ import type { GetConfigFn } from '../../types'
14
14
 
15
15
  export function devServerPlugin({
16
- getConfig,
16
+ getConfig: _getConfig,
17
17
  devSsrStylesEnabled,
18
+ installDevServerMiddleware,
18
19
  }: {
19
20
  getConfig: GetConfigFn
20
21
  devSsrStylesEnabled: boolean
22
+ installDevServerMiddleware: boolean | undefined
21
23
  }): PluginOption {
22
24
  let isTest = false
23
25
 
@@ -132,8 +134,7 @@ export function devServerPlugin({
132
134
  )
133
135
  }
134
136
 
135
- const { startConfig } = getConfig()
136
- const installMiddleware = startConfig.vite?.installDevServerMiddleware
137
+ const installMiddleware = installDevServerMiddleware
137
138
  if (installMiddleware === false) {
138
139
  return
139
140
  }
@@ -1,6 +1,6 @@
1
1
  import { join } from 'pathe'
2
- import { VITE_ENVIRONMENT_NAMES } from './constants'
3
- import type { ViteEnvironmentNames } from './constants'
2
+ import { VITE_ENVIRONMENT_NAMES } from '../constants'
3
+ import type { ViteEnvironmentNames } from '../constants'
4
4
  import type * as vite from 'vite'
5
5
 
6
6
  export function getClientOutputDirectory(