@tanstack/start-plugin-core 1.167.6 → 1.167.8

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.
@@ -29,6 +29,7 @@ function previewServerPlugin() {
29
29
  res
30
30
  });
31
31
  const webRes = await serverBuild.fetch(webReq);
32
+ if (webRes.headers.get("content-type")?.startsWith("text/html")) res.setHeader("content-encoding", "identity");
32
33
  res.setHeaders(webRes.headers);
33
34
  res.writeHead(webRes.status, webRes.statusText);
34
35
  return sendNodeResponse(res, webRes);
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","names":[],"sources":["../../../src/preview-server-plugin/plugin.ts"],"sourcesContent":["import { pathToFileURL } from 'node:url'\nimport { basename, extname, join } from 'pathe'\nimport { NodeRequest, sendNodeResponse } from 'srvx/node'\nimport { joinURL } from 'ufo'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { getServerOutputDirectory } from '../output-directory'\nimport { getBundlerOptions } from '../utils'\nimport type { Plugin } from 'vite'\n\nexport function previewServerPlugin(): Plugin {\n return {\n name: 'tanstack-start-core:preview-server',\n configurePreviewServer: {\n // Run last so platform plugins (Cloudflare, Vercel, etc.) can register their handlers first\n order: 'post',\n handler(server) {\n // Return a function so Vite's internal middlewares (static files, etc.) handle requests first.\n // Our SSR handler only processes requests that nothing else handled.\n return () => {\n // Cache the server build to avoid re-importing on every request\n let serverBuild: any = null\n\n server.middlewares.use(async (req, res, next) => {\n try {\n // Lazy load server build on first request\n if (!serverBuild) {\n // Derive output filename from input\n const serverEnv =\n server.config.environments[VITE_ENVIRONMENT_NAMES.server]\n const serverInput =\n getBundlerOptions(serverEnv?.build)?.input ?? 'server'\n\n if (typeof serverInput !== 'string') {\n throw new Error('Invalid server input. Expected a string.')\n }\n\n // Get basename without extension and add .js\n const outputFilename = `${basename(serverInput, extname(serverInput))}.js`\n const serverOutputDir = getServerOutputDirectory(server.config)\n const serverEntryPath = join(serverOutputDir, outputFilename)\n const imported = await import(\n pathToFileURL(serverEntryPath).toString()\n )\n\n serverBuild = imported.default\n }\n\n // Prepend base path to request URL to match routing setup\n req.url = joinURL(server.config.base, req.url ?? '/')\n\n const webReq = new NodeRequest({ req, res })\n const webRes: Response = await serverBuild.fetch(webReq)\n\n // Temporary workaround\n // Vite preview's compression middleware doesn't support flattened array headers that srvx sets\n // Call writeHead() before srvx to avoid corruption\n res.setHeaders(webRes.headers)\n res.writeHead(webRes.status, webRes.statusText)\n\n return sendNodeResponse(res, webRes)\n } catch (error) {\n next(error)\n }\n })\n }\n },\n },\n }\n}\n"],"mappings":";;;;;;;;AASA,SAAgB,sBAA8B;AAC5C,QAAO;EACL,MAAM;EACN,wBAAwB;GAEtB,OAAO;GACP,QAAQ,QAAQ;AAGd,iBAAa;KAEX,IAAI,cAAmB;AAEvB,YAAO,YAAY,IAAI,OAAO,KAAK,KAAK,SAAS;AAC/C,UAAI;AAEF,WAAI,CAAC,aAAa;QAEhB,MAAM,YACJ,OAAO,OAAO,aAAa,uBAAuB;QACpD,MAAM,cACJ,kBAAkB,WAAW,MAAM,EAAE,SAAS;AAEhD,YAAI,OAAO,gBAAgB,SACzB,OAAM,IAAI,MAAM,2CAA2C;QAI7D,MAAM,iBAAiB,GAAG,SAAS,aAAa,QAAQ,YAAY,CAAC,CAAC;AAOtE,uBAJiB,MAAM,OACrB,cAFsB,KADA,yBAAyB,OAAO,OAAO,EACjB,eAAe,CAE7B,CAAC,UAAU,GAGpB;;AAIzB,WAAI,MAAM,QAAQ,OAAO,OAAO,MAAM,IAAI,OAAO,IAAI;OAErD,MAAM,SAAS,IAAI,YAAY;QAAE;QAAK;QAAK,CAAC;OAC5C,MAAM,SAAmB,MAAM,YAAY,MAAM,OAAO;AAKxD,WAAI,WAAW,OAAO,QAAQ;AAC9B,WAAI,UAAU,OAAO,QAAQ,OAAO,WAAW;AAE/C,cAAO,iBAAiB,KAAK,OAAO;eAC7B,OAAO;AACd,YAAK,MAAM;;OAEb;;;GAGP;EACF"}
1
+ {"version":3,"file":"plugin.js","names":[],"sources":["../../../src/preview-server-plugin/plugin.ts"],"sourcesContent":["import { pathToFileURL } from 'node:url'\nimport { basename, extname, join } from 'pathe'\nimport { NodeRequest, sendNodeResponse } from 'srvx/node'\nimport { joinURL } from 'ufo'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { getServerOutputDirectory } from '../output-directory'\nimport { getBundlerOptions } from '../utils'\nimport type { Plugin } from 'vite'\n\nexport function previewServerPlugin(): Plugin {\n return {\n name: 'tanstack-start-core:preview-server',\n configurePreviewServer: {\n // Run last so platform plugins (Cloudflare, Vercel, etc.) can register their handlers first\n order: 'post',\n handler(server) {\n // Return a function so Vite's internal middlewares (static files, etc.) handle requests first.\n // Our SSR handler only processes requests that nothing else handled.\n return () => {\n // Cache the server build to avoid re-importing on every request\n let serverBuild: any = null\n\n server.middlewares.use(async (req, res, next) => {\n try {\n // Lazy load server build on first request\n if (!serverBuild) {\n // Derive output filename from input\n const serverEnv =\n server.config.environments[VITE_ENVIRONMENT_NAMES.server]\n const serverInput =\n getBundlerOptions(serverEnv?.build)?.input ?? 'server'\n\n if (typeof serverInput !== 'string') {\n throw new Error('Invalid server input. Expected a string.')\n }\n\n // Get basename without extension and add .js\n const outputFilename = `${basename(serverInput, extname(serverInput))}.js`\n const serverOutputDir = getServerOutputDirectory(server.config)\n const serverEntryPath = join(serverOutputDir, outputFilename)\n const imported = await import(\n pathToFileURL(serverEntryPath).toString()\n )\n\n serverBuild = imported.default\n }\n\n // Prepend base path to request URL to match routing setup\n req.url = joinURL(server.config.base, req.url ?? '/')\n\n const webReq = new NodeRequest({ req, res })\n const webRes: Response = await serverBuild.fetch(webReq)\n\n if (webRes.headers.get('content-type')?.startsWith('text/html')) {\n res.setHeader('content-encoding', 'identity')\n }\n\n // Temporary workaround\n // Vite preview's compression middleware doesn't support flattened array headers that srvx sets\n // Call writeHead() before srvx to avoid corruption\n res.setHeaders(webRes.headers)\n res.writeHead(webRes.status, webRes.statusText)\n\n return sendNodeResponse(res, webRes)\n } catch (error) {\n next(error)\n }\n })\n }\n },\n },\n }\n}\n"],"mappings":";;;;;;;;AASA,SAAgB,sBAA8B;AAC5C,QAAO;EACL,MAAM;EACN,wBAAwB;GAEtB,OAAO;GACP,QAAQ,QAAQ;AAGd,iBAAa;KAEX,IAAI,cAAmB;AAEvB,YAAO,YAAY,IAAI,OAAO,KAAK,KAAK,SAAS;AAC/C,UAAI;AAEF,WAAI,CAAC,aAAa;QAEhB,MAAM,YACJ,OAAO,OAAO,aAAa,uBAAuB;QACpD,MAAM,cACJ,kBAAkB,WAAW,MAAM,EAAE,SAAS;AAEhD,YAAI,OAAO,gBAAgB,SACzB,OAAM,IAAI,MAAM,2CAA2C;QAI7D,MAAM,iBAAiB,GAAG,SAAS,aAAa,QAAQ,YAAY,CAAC,CAAC;AAOtE,uBAJiB,MAAM,OACrB,cAFsB,KADA,yBAAyB,OAAO,OAAO,EACjB,eAAe,CAE7B,CAAC,UAAU,GAGpB;;AAIzB,WAAI,MAAM,QAAQ,OAAO,OAAO,MAAM,IAAI,OAAO,IAAI;OAErD,MAAM,SAAS,IAAI,YAAY;QAAE;QAAK;QAAK,CAAC;OAC5C,MAAM,SAAmB,MAAM,YAAY,MAAM,OAAO;AAExD,WAAI,OAAO,QAAQ,IAAI,eAAe,EAAE,WAAW,YAAY,CAC7D,KAAI,UAAU,oBAAoB,WAAW;AAM/C,WAAI,WAAW,OAAO,QAAQ;AAC9B,WAAI,UAAU,OAAO,QAAQ,OAAO,WAAW;AAE/C,cAAO,iBAAiB,KAAK,OAAO;eAC7B,OAAO;AACd,YAAK,MAAM;;OAEb;;;GAGP;EACF"}
@@ -1,4 +1,4 @@
1
- import { RouterManagedTag } from '@tanstack/router-core';
1
+ import { ManifestAssetLink, RouterManagedTag } from '@tanstack/router-core';
2
2
  import { Rollup } from 'vite';
3
3
  type RouteTreeRoute = {
4
4
  filePath?: string;
@@ -18,6 +18,10 @@ interface ManifestAssetResolvers {
18
18
  getChunkPreloads: (chunk: Rollup.OutputChunk) => Array<string>;
19
19
  getStylesheetAsset: (cssFile: string) => RouterManagedTag;
20
20
  }
21
+ type DedupePreloadRoute = {
22
+ preloads?: Array<ManifestAssetLink>;
23
+ children?: Array<string>;
24
+ };
21
25
  export declare function appendUniqueStrings(target: Array<string> | undefined, source: Array<string>): string[] | undefined;
22
26
  export declare function appendUniqueAssets(target: Array<RouterManagedTag> | undefined, source: Array<RouterManagedTag>): RouterManagedTag[] | undefined;
23
27
  export declare function buildStartManifest(options: {
@@ -48,8 +52,5 @@ export declare function buildRouteManifestRoutes(options: {
48
52
  entryChunk: Rollup.OutputChunk;
49
53
  assetResolvers: ManifestAssetResolvers;
50
54
  }): Record<string, RouteTreeRoute>;
51
- export declare function dedupeNestedRoutePreloads(route: {
52
- preloads?: Array<string>;
53
- children?: Array<string>;
54
- }, routesById: Record<string, RouteTreeRoute>, seenPreloads?: Set<string>): void;
55
+ export declare function dedupeNestedRoutePreloads(route: DedupePreloadRoute, routesById: Record<string, DedupePreloadRoute>, seenPreloads?: Set<string>): void;
55
56
  export {};
@@ -1,4 +1,4 @@
1
- import { rootRouteId } from "@tanstack/router-core";
1
+ import { resolveManifestAssetLink, rootRouteId } from "@tanstack/router-core";
2
2
  import { joinURL } from "ufo";
3
3
  import { tsrSplit } from "@tanstack/router-plugin";
4
4
  //#region src/start-manifest-plugin/manifestBuilder.ts
@@ -277,11 +277,12 @@ function dedupeNestedRoutePreloads(route, routesById, seenPreloads = /* @__PURE_
277
277
  let dedupedPreloads;
278
278
  for (let i = 0; i < routePreloads.length; i++) {
279
279
  const preload = routePreloads[i];
280
- if (seenPreloads.has(preload)) {
280
+ const preloadHref = resolveManifestAssetLink(preload).href;
281
+ if (seenPreloads.has(preloadHref)) {
281
282
  if (dedupedPreloads === void 0) dedupedPreloads = routePreloads.slice(0, i);
282
283
  continue;
283
284
  }
284
- seenPreloads.add(preload);
285
+ seenPreloads.add(preloadHref);
285
286
  if (dedupedPreloads) dedupedPreloads.push(preload);
286
287
  }
287
288
  if (dedupedPreloads) {
@@ -290,7 +291,7 @@ function dedupeNestedRoutePreloads(route, routesById, seenPreloads = /* @__PURE_
290
291
  }
291
292
  }
292
293
  if (route.children) for (const childRouteId of route.children) dedupeNestedRoutePreloads(routesById[childRouteId], routesById, seenPreloads);
293
- if (routePreloads) for (let i = routePreloads.length - 1; i >= 0; i--) seenPreloads.delete(routePreloads[i]);
294
+ if (routePreloads) for (let i = routePreloads.length - 1; i >= 0; i--) seenPreloads.delete(resolveManifestAssetLink(routePreloads[i]).href);
294
295
  }
295
296
  //#endregion
296
297
  export { buildStartManifest };
@@ -1 +1 @@
1
- {"version":3,"file":"manifestBuilder.js","names":[],"sources":["../../../src/start-manifest-plugin/manifestBuilder.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/prefer-for-of */\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { tsrSplit } from '@tanstack/router-plugin'\nimport type { RouterManagedTag } from '@tanstack/router-core'\nimport type { Rollup } from 'vite'\n\nconst ROUTER_MANAGED_MODE = 1\nconst NON_ROUTE_DYNAMIC_MODE = 2\nconst VISITING_CHUNK = 1\n\ntype RouteTreeRoute = {\n filePath?: string\n preloads?: Array<string>\n assets?: Array<RouterManagedTag>\n children?: Array<string>\n}\n\ntype RouteTreeRoutes = Record<string, RouteTreeRoute>\n\ninterface ScannedClientChunks {\n entryChunk: Rollup.OutputChunk\n chunksByFileName: Map<string, Rollup.OutputChunk>\n routeChunksByFilePath: Map<string, Array<Rollup.OutputChunk>>\n routeEntryChunks: Set<Rollup.OutputChunk>\n}\n\ninterface ManifestAssetResolvers {\n getAssetPath: (fileName: string) => string\n getChunkPreloads: (chunk: Rollup.OutputChunk) => Array<string>\n getStylesheetAsset: (cssFile: string) => RouterManagedTag\n}\n\nexport function appendUniqueStrings(\n target: Array<string> | undefined,\n source: Array<string>,\n) {\n // Similar to Set.prototype.union, but for ordered arrays.\n // It preserves first-seen order and returns the original target array when\n // source contributes no new values, which avoids extra allocations.\n if (source.length === 0) {\n return target\n }\n\n if (!target || target.length === 0) {\n return source\n }\n\n const seen = new Set(target)\n let result: Array<string> | undefined\n\n for (const value of source) {\n if (seen.has(value)) {\n continue\n }\n\n seen.add(value)\n if (!result) {\n result = target.slice()\n }\n result.push(value)\n }\n\n return result ?? target\n}\n\nexport function appendUniqueAssets(\n target: Array<RouterManagedTag> | undefined,\n source: Array<RouterManagedTag>,\n) {\n // Same semantics as appendUniqueStrings, but uniqueness is based on the\n // serialized asset identity instead of object reference.\n if (source.length === 0) {\n return target\n }\n\n if (!target || target.length === 0) {\n return source\n }\n\n const seen = new Set(target.map(getAssetIdentity))\n let result: Array<RouterManagedTag> | undefined\n\n for (const asset of source) {\n const identity = getAssetIdentity(asset)\n if (seen.has(identity)) {\n continue\n }\n\n seen.add(identity)\n if (!result) {\n result = target.slice()\n }\n result.push(asset)\n }\n\n return result ?? target\n}\n\nfunction getAssetIdentity(asset: RouterManagedTag) {\n if (asset.tag === 'link' || asset.tag === 'script') {\n const attrs = asset.attrs ?? {}\n return [\n asset.tag,\n 'href' in attrs ? String(attrs.href) : '',\n 'src' in attrs ? String(attrs.src) : '',\n 'rel' in attrs ? String(attrs.rel) : '',\n 'type' in attrs ? String(attrs.type) : '',\n asset.children ?? '',\n ].join('|')\n }\n\n return JSON.stringify(asset)\n}\n\nfunction mergeRouteChunkData(options: {\n route: RouteTreeRoute\n chunk: Rollup.OutputChunk\n getChunkCssAssets: (chunk: Rollup.OutputChunk) => Array<RouterManagedTag>\n getChunkPreloads: (chunk: Rollup.OutputChunk) => Array<string>\n}) {\n const chunkAssets = options.getChunkCssAssets(options.chunk)\n const chunkPreloads = options.getChunkPreloads(options.chunk)\n\n options.route.assets = appendUniqueAssets(options.route.assets, chunkAssets)\n options.route.preloads = appendUniqueStrings(\n options.route.preloads,\n chunkPreloads,\n )\n}\n\nexport function buildStartManifest(options: {\n clientBundle: Rollup.OutputBundle\n routeTreeRoutes: RouteTreeRoutes\n basePath: string\n}) {\n const scannedChunks = scanClientChunks(options.clientBundle)\n const hashedCssFiles = collectDynamicImportCss(\n scannedChunks.routeEntryChunks,\n scannedChunks.chunksByFileName,\n scannedChunks.entryChunk,\n )\n const assetResolvers = createManifestAssetResolvers({\n basePath: options.basePath,\n hashedCssFiles,\n })\n\n const routes = buildRouteManifestRoutes({\n routeTreeRoutes: options.routeTreeRoutes,\n routeChunksByFilePath: scannedChunks.routeChunksByFilePath,\n chunksByFileName: scannedChunks.chunksByFileName,\n entryChunk: scannedChunks.entryChunk,\n assetResolvers,\n })\n\n dedupeNestedRoutePreloads(routes[rootRouteId]!, routes)\n\n // Prune routes with no assets or preloads from the manifest\n for (const routeId of Object.keys(routes)) {\n const route = routes[routeId]!\n const hasAssets = route.assets && route.assets.length > 0\n const hasPreloads = route.preloads && route.preloads.length > 0\n if (!hasAssets && !hasPreloads) {\n delete routes[routeId]\n }\n }\n\n return {\n routes,\n clientEntry: assetResolvers.getAssetPath(scannedChunks.entryChunk.fileName),\n }\n}\n\nexport function scanClientChunks(\n clientBundle: Rollup.OutputBundle,\n): ScannedClientChunks {\n let entryChunk: Rollup.OutputChunk | undefined\n const chunksByFileName = new Map<string, Rollup.OutputChunk>()\n const routeChunksByFilePath = new Map<string, Array<Rollup.OutputChunk>>()\n const routeEntryChunks = new Set<Rollup.OutputChunk>()\n\n for (const fileName in clientBundle) {\n const bundleEntry = clientBundle[fileName]!\n if (bundleEntry.type !== 'chunk') {\n continue\n }\n\n chunksByFileName.set(bundleEntry.fileName, bundleEntry)\n\n if (bundleEntry.isEntry) {\n if (entryChunk) {\n throw new Error(\n `multiple entries detected: ${entryChunk.fileName} ${bundleEntry.fileName}`,\n )\n }\n entryChunk = bundleEntry\n }\n\n const routeFilePaths = getRouteFilePathsFromModuleIds(bundleEntry.moduleIds)\n if (routeFilePaths.length === 0) {\n continue\n }\n\n routeEntryChunks.add(bundleEntry)\n\n for (let i = 0; i < routeFilePaths.length; i++) {\n const routeFilePath = routeFilePaths[i]!\n let chunks = routeChunksByFilePath.get(routeFilePath)\n if (chunks === undefined) {\n chunks = []\n routeChunksByFilePath.set(routeFilePath, chunks)\n }\n chunks.push(bundleEntry)\n }\n }\n\n if (!entryChunk) {\n throw new Error('No entry file found')\n }\n\n return {\n entryChunk,\n chunksByFileName,\n routeChunksByFilePath,\n routeEntryChunks,\n }\n}\n\nexport function getRouteFilePathsFromModuleIds(moduleIds: Array<string>) {\n let routeFilePaths: Array<string> | undefined\n let seenRouteFilePaths: Set<string> | undefined\n\n for (const moduleId of moduleIds) {\n const queryIndex = moduleId.indexOf('?')\n\n if (queryIndex < 0) {\n continue\n }\n\n const query = moduleId.slice(queryIndex + 1)\n\n // Fast check before allocating URLSearchParams\n if (!query.includes(tsrSplit)) {\n continue\n }\n\n if (!new URLSearchParams(query).has(tsrSplit)) {\n continue\n }\n\n const routeFilePath = moduleId.slice(0, queryIndex)\n\n if (seenRouteFilePaths?.has(routeFilePath)) {\n continue\n }\n\n if (routeFilePaths === undefined) {\n routeFilePaths = []\n seenRouteFilePaths = new Set<string>()\n }\n\n routeFilePaths.push(routeFilePath)\n seenRouteFilePaths!.add(routeFilePath)\n }\n\n return routeFilePaths ?? []\n}\n\nexport function collectDynamicImportCss(\n routeEntryChunks: Set<Rollup.OutputChunk>,\n chunksByFileName: Map<string, Rollup.OutputChunk>,\n entryChunk?: Rollup.OutputChunk,\n) {\n const routerManagedCssFiles = new Set<string>()\n const nonRouteDynamicCssFiles = new Set<string>()\n const hashedCssFiles = new Set<string>()\n const visitedByChunk = new Map<Rollup.OutputChunk, number>()\n const chunkStack: Array<Rollup.OutputChunk> = []\n const modeStack: Array<number> = []\n\n for (const routeEntryChunk of routeEntryChunks) {\n chunkStack.push(routeEntryChunk)\n modeStack.push(ROUTER_MANAGED_MODE)\n }\n\n if (entryChunk) {\n chunkStack.push(entryChunk)\n modeStack.push(ROUTER_MANAGED_MODE)\n }\n\n while (chunkStack.length > 0) {\n const chunk = chunkStack.pop()!\n const mode = modeStack.pop()!\n const previousMode = visitedByChunk.get(chunk) ?? 0\n\n if ((previousMode & mode) === mode) {\n continue\n }\n\n visitedByChunk.set(chunk, previousMode | mode)\n\n if ((mode & ROUTER_MANAGED_MODE) !== 0) {\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n routerManagedCssFiles.add(cssFile)\n }\n }\n\n if ((mode & NON_ROUTE_DYNAMIC_MODE) !== 0) {\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n nonRouteDynamicCssFiles.add(cssFile)\n }\n }\n\n for (let i = 0; i < chunk.imports.length; i++) {\n const importedChunk = chunksByFileName.get(chunk.imports[i]!)\n if (importedChunk) {\n chunkStack.push(importedChunk)\n modeStack.push(mode)\n }\n }\n\n for (let i = 0; i < chunk.dynamicImports.length; i++) {\n const dynamicImportedChunk = chunksByFileName.get(\n chunk.dynamicImports[i]!,\n )\n if (dynamicImportedChunk) {\n chunkStack.push(dynamicImportedChunk)\n modeStack.push(\n (mode & NON_ROUTE_DYNAMIC_MODE) !== 0 ||\n !routeEntryChunks.has(dynamicImportedChunk)\n ? NON_ROUTE_DYNAMIC_MODE\n : ROUTER_MANAGED_MODE,\n )\n }\n }\n }\n\n for (const cssFile of routerManagedCssFiles) {\n if (nonRouteDynamicCssFiles.has(cssFile)) {\n hashedCssFiles.add(cssFile)\n }\n }\n\n return hashedCssFiles\n}\n\nexport function createManifestAssetResolvers(options: {\n basePath: string\n hashedCssFiles?: Set<string>\n}): ManifestAssetResolvers {\n const assetPathByFileName = new Map<string, string>()\n const stylesheetAssetByFileName = new Map<string, RouterManagedTag>()\n const preloadsByChunk = new Map<Rollup.OutputChunk, Array<string>>()\n\n const getAssetPath = (fileName: string) => {\n const cachedPath = assetPathByFileName.get(fileName)\n if (cachedPath) {\n return cachedPath\n }\n\n const assetPath = joinURL(options.basePath, fileName)\n assetPathByFileName.set(fileName, assetPath)\n return assetPath\n }\n\n const getStylesheetAsset = (cssFile: string) => {\n const cachedAsset = stylesheetAssetByFileName.get(cssFile)\n if (cachedAsset) {\n return cachedAsset\n }\n\n const href = getAssetPath(cssFile)\n const asset = {\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: options.hashedCssFiles?.has(cssFile) ? `${href}#` : href,\n type: 'text/css',\n },\n } satisfies RouterManagedTag\n\n stylesheetAssetByFileName.set(cssFile, asset)\n return asset\n }\n\n const getChunkPreloads = (chunk: Rollup.OutputChunk) => {\n const cachedPreloads = preloadsByChunk.get(chunk)\n if (cachedPreloads) {\n return cachedPreloads\n }\n\n const preloads = [getAssetPath(chunk.fileName)]\n\n for (let i = 0; i < chunk.imports.length; i++) {\n preloads.push(getAssetPath(chunk.imports[i]!))\n }\n\n preloadsByChunk.set(chunk, preloads)\n return preloads\n }\n\n return {\n getAssetPath,\n getChunkPreloads,\n getStylesheetAsset,\n }\n}\n\nexport function createChunkCssAssetCollector(options: {\n chunksByFileName: Map<string, Rollup.OutputChunk>\n getStylesheetAsset: (cssFile: string) => RouterManagedTag\n}) {\n const assetsByChunk = new Map<Rollup.OutputChunk, Array<RouterManagedTag>>()\n const stateByChunk = new Map<Rollup.OutputChunk, number>()\n\n const getChunkCssAssets = (\n chunk: Rollup.OutputChunk,\n ): Array<RouterManagedTag> => {\n const cachedAssets = assetsByChunk.get(chunk)\n if (cachedAssets) {\n return cachedAssets\n }\n\n if (stateByChunk.get(chunk) === VISITING_CHUNK) {\n return []\n }\n stateByChunk.set(chunk, VISITING_CHUNK)\n\n const assets: Array<RouterManagedTag> = []\n\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n assets.push(options.getStylesheetAsset(cssFile))\n }\n\n for (let i = 0; i < chunk.imports.length; i++) {\n const importedChunk = options.chunksByFileName.get(chunk.imports[i]!)\n if (!importedChunk) {\n continue\n }\n\n const importedAssets = getChunkCssAssets(importedChunk)\n for (let j = 0; j < importedAssets.length; j++) {\n assets.push(importedAssets[j]!)\n }\n }\n\n stateByChunk.delete(chunk)\n assetsByChunk.set(chunk, assets)\n return assets\n }\n\n return { getChunkCssAssets }\n}\n\nexport function buildRouteManifestRoutes(options: {\n routeTreeRoutes: RouteTreeRoutes\n routeChunksByFilePath: Map<string, Array<Rollup.OutputChunk>>\n chunksByFileName: Map<string, Rollup.OutputChunk>\n entryChunk: Rollup.OutputChunk\n assetResolvers: ManifestAssetResolvers\n}) {\n const routes: Record<string, RouteTreeRoute> = {}\n const getChunkCssAssets = createChunkCssAssetCollector({\n chunksByFileName: options.chunksByFileName,\n getStylesheetAsset: options.assetResolvers.getStylesheetAsset,\n }).getChunkCssAssets\n\n for (const [routeId, route] of Object.entries(options.routeTreeRoutes)) {\n if (!route.filePath) {\n if (routeId === rootRouteId) {\n routes[routeId] = route\n continue\n }\n\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n\n const chunks = options.routeChunksByFilePath.get(route.filePath)\n if (!chunks) {\n routes[routeId] = route\n continue\n }\n\n const existing = routes[routeId]\n const targetRoute = (routes[routeId] = existing ? existing : { ...route })\n\n for (const chunk of chunks) {\n mergeRouteChunkData({\n route: targetRoute,\n chunk,\n getChunkCssAssets,\n getChunkPreloads: options.assetResolvers.getChunkPreloads,\n })\n }\n }\n\n const rootRoute = (routes[rootRouteId] = routes[rootRouteId] || {})\n mergeRouteChunkData({\n route: rootRoute,\n chunk: options.entryChunk,\n getChunkCssAssets,\n getChunkPreloads: options.assetResolvers.getChunkPreloads,\n })\n\n return routes\n}\n\nexport function dedupeNestedRoutePreloads(\n route: { preloads?: Array<string>; children?: Array<string> },\n routesById: Record<string, RouteTreeRoute>,\n seenPreloads = new Set<string>(),\n) {\n let routePreloads = route.preloads\n\n if (routePreloads && routePreloads.length > 0) {\n let dedupedPreloads: Array<string> | undefined\n\n for (let i = 0; i < routePreloads.length; i++) {\n const preload = routePreloads[i]!\n if (seenPreloads.has(preload)) {\n if (dedupedPreloads === undefined) {\n dedupedPreloads = routePreloads.slice(0, i)\n }\n continue\n }\n\n seenPreloads.add(preload)\n\n if (dedupedPreloads) {\n dedupedPreloads.push(preload)\n }\n }\n\n if (dedupedPreloads) {\n routePreloads = dedupedPreloads\n route.preloads = dedupedPreloads\n }\n }\n\n if (route.children) {\n for (const childRouteId of route.children) {\n dedupeNestedRoutePreloads(\n routesById[childRouteId]!,\n routesById,\n seenPreloads,\n )\n }\n }\n\n if (routePreloads) {\n for (let i = routePreloads.length - 1; i >= 0; i--) {\n seenPreloads.delete(routePreloads[i]!)\n }\n }\n}\n"],"mappings":";;;;AAOA,IAAM,sBAAsB;AAC5B,IAAM,yBAAyB;AAC/B,IAAM,iBAAiB;AAwBvB,SAAgB,oBACd,QACA,QACA;AAIA,KAAI,OAAO,WAAW,EACpB,QAAO;AAGT,KAAI,CAAC,UAAU,OAAO,WAAW,EAC/B,QAAO;CAGT,MAAM,OAAO,IAAI,IAAI,OAAO;CAC5B,IAAI;AAEJ,MAAK,MAAM,SAAS,QAAQ;AAC1B,MAAI,KAAK,IAAI,MAAM,CACjB;AAGF,OAAK,IAAI,MAAM;AACf,MAAI,CAAC,OACH,UAAS,OAAO,OAAO;AAEzB,SAAO,KAAK,MAAM;;AAGpB,QAAO,UAAU;;AAGnB,SAAgB,mBACd,QACA,QACA;AAGA,KAAI,OAAO,WAAW,EACpB,QAAO;AAGT,KAAI,CAAC,UAAU,OAAO,WAAW,EAC/B,QAAO;CAGT,MAAM,OAAO,IAAI,IAAI,OAAO,IAAI,iBAAiB,CAAC;CAClD,IAAI;AAEJ,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,WAAW,iBAAiB,MAAM;AACxC,MAAI,KAAK,IAAI,SAAS,CACpB;AAGF,OAAK,IAAI,SAAS;AAClB,MAAI,CAAC,OACH,UAAS,OAAO,OAAO;AAEzB,SAAO,KAAK,MAAM;;AAGpB,QAAO,UAAU;;AAGnB,SAAS,iBAAiB,OAAyB;AACjD,KAAI,MAAM,QAAQ,UAAU,MAAM,QAAQ,UAAU;EAClD,MAAM,QAAQ,MAAM,SAAS,EAAE;AAC/B,SAAO;GACL,MAAM;GACN,UAAU,QAAQ,OAAO,MAAM,KAAK,GAAG;GACvC,SAAS,QAAQ,OAAO,MAAM,IAAI,GAAG;GACrC,SAAS,QAAQ,OAAO,MAAM,IAAI,GAAG;GACrC,UAAU,QAAQ,OAAO,MAAM,KAAK,GAAG;GACvC,MAAM,YAAY;GACnB,CAAC,KAAK,IAAI;;AAGb,QAAO,KAAK,UAAU,MAAM;;AAG9B,SAAS,oBAAoB,SAK1B;CACD,MAAM,cAAc,QAAQ,kBAAkB,QAAQ,MAAM;CAC5D,MAAM,gBAAgB,QAAQ,iBAAiB,QAAQ,MAAM;AAE7D,SAAQ,MAAM,SAAS,mBAAmB,QAAQ,MAAM,QAAQ,YAAY;AAC5E,SAAQ,MAAM,WAAW,oBACvB,QAAQ,MAAM,UACd,cACD;;AAGH,SAAgB,mBAAmB,SAIhC;CACD,MAAM,gBAAgB,iBAAiB,QAAQ,aAAa;CAC5D,MAAM,iBAAiB,wBACrB,cAAc,kBACd,cAAc,kBACd,cAAc,WACf;CACD,MAAM,iBAAiB,6BAA6B;EAClD,UAAU,QAAQ;EAClB;EACD,CAAC;CAEF,MAAM,SAAS,yBAAyB;EACtC,iBAAiB,QAAQ;EACzB,uBAAuB,cAAc;EACrC,kBAAkB,cAAc;EAChC,YAAY,cAAc;EAC1B;EACD,CAAC;AAEF,2BAA0B,OAAO,cAAe,OAAO;AAGvD,MAAK,MAAM,WAAW,OAAO,KAAK,OAAO,EAAE;EACzC,MAAM,QAAQ,OAAO;EACrB,MAAM,YAAY,MAAM,UAAU,MAAM,OAAO,SAAS;EACxD,MAAM,cAAc,MAAM,YAAY,MAAM,SAAS,SAAS;AAC9D,MAAI,CAAC,aAAa,CAAC,YACjB,QAAO,OAAO;;AAIlB,QAAO;EACL;EACA,aAAa,eAAe,aAAa,cAAc,WAAW,SAAS;EAC5E;;AAGH,SAAgB,iBACd,cACqB;CACrB,IAAI;CACJ,MAAM,mCAAmB,IAAI,KAAiC;CAC9D,MAAM,wCAAwB,IAAI,KAAwC;CAC1E,MAAM,mCAAmB,IAAI,KAAyB;AAEtD,MAAK,MAAM,YAAY,cAAc;EACnC,MAAM,cAAc,aAAa;AACjC,MAAI,YAAY,SAAS,QACvB;AAGF,mBAAiB,IAAI,YAAY,UAAU,YAAY;AAEvD,MAAI,YAAY,SAAS;AACvB,OAAI,WACF,OAAM,IAAI,MACR,8BAA8B,WAAW,SAAS,GAAG,YAAY,WAClE;AAEH,gBAAa;;EAGf,MAAM,iBAAiB,+BAA+B,YAAY,UAAU;AAC5E,MAAI,eAAe,WAAW,EAC5B;AAGF,mBAAiB,IAAI,YAAY;AAEjC,OAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;GAC9C,MAAM,gBAAgB,eAAe;GACrC,IAAI,SAAS,sBAAsB,IAAI,cAAc;AACrD,OAAI,WAAW,KAAA,GAAW;AACxB,aAAS,EAAE;AACX,0BAAsB,IAAI,eAAe,OAAO;;AAElD,UAAO,KAAK,YAAY;;;AAI5B,KAAI,CAAC,WACH,OAAM,IAAI,MAAM,sBAAsB;AAGxC,QAAO;EACL;EACA;EACA;EACA;EACD;;AAGH,SAAgB,+BAA+B,WAA0B;CACvE,IAAI;CACJ,IAAI;AAEJ,MAAK,MAAM,YAAY,WAAW;EAChC,MAAM,aAAa,SAAS,QAAQ,IAAI;AAExC,MAAI,aAAa,EACf;EAGF,MAAM,QAAQ,SAAS,MAAM,aAAa,EAAE;AAG5C,MAAI,CAAC,MAAM,SAAS,SAAS,CAC3B;AAGF,MAAI,CAAC,IAAI,gBAAgB,MAAM,CAAC,IAAI,SAAS,CAC3C;EAGF,MAAM,gBAAgB,SAAS,MAAM,GAAG,WAAW;AAEnD,MAAI,oBAAoB,IAAI,cAAc,CACxC;AAGF,MAAI,mBAAmB,KAAA,GAAW;AAChC,oBAAiB,EAAE;AACnB,wCAAqB,IAAI,KAAa;;AAGxC,iBAAe,KAAK,cAAc;AAClC,qBAAoB,IAAI,cAAc;;AAGxC,QAAO,kBAAkB,EAAE;;AAG7B,SAAgB,wBACd,kBACA,kBACA,YACA;CACA,MAAM,wCAAwB,IAAI,KAAa;CAC/C,MAAM,0CAA0B,IAAI,KAAa;CACjD,MAAM,iCAAiB,IAAI,KAAa;CACxC,MAAM,iCAAiB,IAAI,KAAiC;CAC5D,MAAM,aAAwC,EAAE;CAChD,MAAM,YAA2B,EAAE;AAEnC,MAAK,MAAM,mBAAmB,kBAAkB;AAC9C,aAAW,KAAK,gBAAgB;AAChC,YAAU,KAAK,oBAAoB;;AAGrC,KAAI,YAAY;AACd,aAAW,KAAK,WAAW;AAC3B,YAAU,KAAK,oBAAoB;;AAGrC,QAAO,WAAW,SAAS,GAAG;EAC5B,MAAM,QAAQ,WAAW,KAAK;EAC9B,MAAM,OAAO,UAAU,KAAK;EAC5B,MAAM,eAAe,eAAe,IAAI,MAAM,IAAI;AAElD,OAAK,eAAe,UAAU,KAC5B;AAGF,iBAAe,IAAI,OAAO,eAAe,KAAK;AAE9C,OAAK,OAAO,yBAAyB,EACnC,MAAK,MAAM,WAAW,MAAM,cAAc,eAAe,EAAE,CACzD,uBAAsB,IAAI,QAAQ;AAItC,OAAK,OAAO,4BAA4B,EACtC,MAAK,MAAM,WAAW,MAAM,cAAc,eAAe,EAAE,CACzD,yBAAwB,IAAI,QAAQ;AAIxC,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,QAAQ,KAAK;GAC7C,MAAM,gBAAgB,iBAAiB,IAAI,MAAM,QAAQ,GAAI;AAC7D,OAAI,eAAe;AACjB,eAAW,KAAK,cAAc;AAC9B,cAAU,KAAK,KAAK;;;AAIxB,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,eAAe,QAAQ,KAAK;GACpD,MAAM,uBAAuB,iBAAiB,IAC5C,MAAM,eAAe,GACtB;AACD,OAAI,sBAAsB;AACxB,eAAW,KAAK,qBAAqB;AACrC,cAAU,MACP,OAAO,4BAA4B,KAClC,CAAC,iBAAiB,IAAI,qBAAqB,GACzC,yBACA,oBACL;;;;AAKP,MAAK,MAAM,WAAW,sBACpB,KAAI,wBAAwB,IAAI,QAAQ,CACtC,gBAAe,IAAI,QAAQ;AAI/B,QAAO;;AAGT,SAAgB,6BAA6B,SAGlB;CACzB,MAAM,sCAAsB,IAAI,KAAqB;CACrD,MAAM,4CAA4B,IAAI,KAA+B;CACrE,MAAM,kCAAkB,IAAI,KAAwC;CAEpE,MAAM,gBAAgB,aAAqB;EACzC,MAAM,aAAa,oBAAoB,IAAI,SAAS;AACpD,MAAI,WACF,QAAO;EAGT,MAAM,YAAY,QAAQ,QAAQ,UAAU,SAAS;AACrD,sBAAoB,IAAI,UAAU,UAAU;AAC5C,SAAO;;CAGT,MAAM,sBAAsB,YAAoB;EAC9C,MAAM,cAAc,0BAA0B,IAAI,QAAQ;AAC1D,MAAI,YACF,QAAO;EAGT,MAAM,OAAO,aAAa,QAAQ;EAClC,MAAM,QAAQ;GACZ,KAAK;GACL,OAAO;IACL,KAAK;IACL,MAAM,QAAQ,gBAAgB,IAAI,QAAQ,GAAG,GAAG,KAAK,KAAK;IAC1D,MAAM;IACP;GACF;AAED,4BAA0B,IAAI,SAAS,MAAM;AAC7C,SAAO;;CAGT,MAAM,oBAAoB,UAA8B;EACtD,MAAM,iBAAiB,gBAAgB,IAAI,MAAM;AACjD,MAAI,eACF,QAAO;EAGT,MAAM,WAAW,CAAC,aAAa,MAAM,SAAS,CAAC;AAE/C,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,QAAQ,IACxC,UAAS,KAAK,aAAa,MAAM,QAAQ,GAAI,CAAC;AAGhD,kBAAgB,IAAI,OAAO,SAAS;AACpC,SAAO;;AAGT,QAAO;EACL;EACA;EACA;EACD;;AAGH,SAAgB,6BAA6B,SAG1C;CACD,MAAM,gCAAgB,IAAI,KAAkD;CAC5E,MAAM,+BAAe,IAAI,KAAiC;CAE1D,MAAM,qBACJ,UAC4B;EAC5B,MAAM,eAAe,cAAc,IAAI,MAAM;AAC7C,MAAI,aACF,QAAO;AAGT,MAAI,aAAa,IAAI,MAAM,KAAK,eAC9B,QAAO,EAAE;AAEX,eAAa,IAAI,OAAO,eAAe;EAEvC,MAAM,SAAkC,EAAE;AAE1C,OAAK,MAAM,WAAW,MAAM,cAAc,eAAe,EAAE,CACzD,QAAO,KAAK,QAAQ,mBAAmB,QAAQ,CAAC;AAGlD,OAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,QAAQ,KAAK;GAC7C,MAAM,gBAAgB,QAAQ,iBAAiB,IAAI,MAAM,QAAQ,GAAI;AACrE,OAAI,CAAC,cACH;GAGF,MAAM,iBAAiB,kBAAkB,cAAc;AACvD,QAAK,IAAI,IAAI,GAAG,IAAI,eAAe,QAAQ,IACzC,QAAO,KAAK,eAAe,GAAI;;AAInC,eAAa,OAAO,MAAM;AAC1B,gBAAc,IAAI,OAAO,OAAO;AAChC,SAAO;;AAGT,QAAO,EAAE,mBAAmB;;AAG9B,SAAgB,yBAAyB,SAMtC;CACD,MAAM,SAAyC,EAAE;CACjD,MAAM,oBAAoB,6BAA6B;EACrD,kBAAkB,QAAQ;EAC1B,oBAAoB,QAAQ,eAAe;EAC5C,CAAC,CAAC;AAEH,MAAK,MAAM,CAAC,SAAS,UAAU,OAAO,QAAQ,QAAQ,gBAAgB,EAAE;AACtE,MAAI,CAAC,MAAM,UAAU;AACnB,OAAI,YAAY,aAAa;AAC3B,WAAO,WAAW;AAClB;;AAGF,SAAM,IAAI,MAAM,mCAAmC,UAAU;;EAG/D,MAAM,SAAS,QAAQ,sBAAsB,IAAI,MAAM,SAAS;AAChE,MAAI,CAAC,QAAQ;AACX,UAAO,WAAW;AAClB;;EAGF,MAAM,WAAW,OAAO;EACxB,MAAM,cAAe,OAAO,WAAW,WAAW,WAAW,EAAE,GAAG,OAAO;AAEzE,OAAK,MAAM,SAAS,OAClB,qBAAoB;GAClB,OAAO;GACP;GACA;GACA,kBAAkB,QAAQ,eAAe;GAC1C,CAAC;;AAKN,qBAAoB;EAClB,OAFiB,OAAO,eAAe,OAAO,gBAAgB,EAAE;EAGhE,OAAO,QAAQ;EACf;EACA,kBAAkB,QAAQ,eAAe;EAC1C,CAAC;AAEF,QAAO;;AAGT,SAAgB,0BACd,OACA,YACA,+BAAe,IAAI,KAAa,EAChC;CACA,IAAI,gBAAgB,MAAM;AAE1B,KAAI,iBAAiB,cAAc,SAAS,GAAG;EAC7C,IAAI;AAEJ,OAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;GAC7C,MAAM,UAAU,cAAc;AAC9B,OAAI,aAAa,IAAI,QAAQ,EAAE;AAC7B,QAAI,oBAAoB,KAAA,EACtB,mBAAkB,cAAc,MAAM,GAAG,EAAE;AAE7C;;AAGF,gBAAa,IAAI,QAAQ;AAEzB,OAAI,gBACF,iBAAgB,KAAK,QAAQ;;AAIjC,MAAI,iBAAiB;AACnB,mBAAgB;AAChB,SAAM,WAAW;;;AAIrB,KAAI,MAAM,SACR,MAAK,MAAM,gBAAgB,MAAM,SAC/B,2BACE,WAAW,eACX,YACA,aACD;AAIL,KAAI,cACF,MAAK,IAAI,IAAI,cAAc,SAAS,GAAG,KAAK,GAAG,IAC7C,cAAa,OAAO,cAAc,GAAI"}
1
+ {"version":3,"file":"manifestBuilder.js","names":[],"sources":["../../../src/start-manifest-plugin/manifestBuilder.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/prefer-for-of */\nimport { joinURL } from 'ufo'\nimport { resolveManifestAssetLink, rootRouteId } from '@tanstack/router-core'\nimport { tsrSplit } from '@tanstack/router-plugin'\nimport type { ManifestAssetLink, RouterManagedTag } from '@tanstack/router-core'\nimport type { Rollup } from 'vite'\n\nconst ROUTER_MANAGED_MODE = 1\nconst NON_ROUTE_DYNAMIC_MODE = 2\nconst VISITING_CHUNK = 1\n\ntype RouteTreeRoute = {\n filePath?: string\n preloads?: Array<string>\n assets?: Array<RouterManagedTag>\n children?: Array<string>\n}\n\ntype RouteTreeRoutes = Record<string, RouteTreeRoute>\n\ninterface ScannedClientChunks {\n entryChunk: Rollup.OutputChunk\n chunksByFileName: Map<string, Rollup.OutputChunk>\n routeChunksByFilePath: Map<string, Array<Rollup.OutputChunk>>\n routeEntryChunks: Set<Rollup.OutputChunk>\n}\n\ninterface ManifestAssetResolvers {\n getAssetPath: (fileName: string) => string\n getChunkPreloads: (chunk: Rollup.OutputChunk) => Array<string>\n getStylesheetAsset: (cssFile: string) => RouterManagedTag\n}\n\ntype DedupePreloadRoute = {\n preloads?: Array<ManifestAssetLink>\n children?: Array<string>\n}\n\nexport function appendUniqueStrings(\n target: Array<string> | undefined,\n source: Array<string>,\n) {\n // Similar to Set.prototype.union, but for ordered arrays.\n // It preserves first-seen order and returns the original target array when\n // source contributes no new values, which avoids extra allocations.\n if (source.length === 0) {\n return target\n }\n\n if (!target || target.length === 0) {\n return source\n }\n\n const seen = new Set(target)\n let result: Array<string> | undefined\n\n for (const value of source) {\n if (seen.has(value)) {\n continue\n }\n\n seen.add(value)\n if (!result) {\n result = target.slice()\n }\n result.push(value)\n }\n\n return result ?? target\n}\n\nexport function appendUniqueAssets(\n target: Array<RouterManagedTag> | undefined,\n source: Array<RouterManagedTag>,\n) {\n // Same semantics as appendUniqueStrings, but uniqueness is based on the\n // serialized asset identity instead of object reference.\n if (source.length === 0) {\n return target\n }\n\n if (!target || target.length === 0) {\n return source\n }\n\n const seen = new Set(target.map(getAssetIdentity))\n let result: Array<RouterManagedTag> | undefined\n\n for (const asset of source) {\n const identity = getAssetIdentity(asset)\n if (seen.has(identity)) {\n continue\n }\n\n seen.add(identity)\n if (!result) {\n result = target.slice()\n }\n result.push(asset)\n }\n\n return result ?? target\n}\n\nfunction getAssetIdentity(asset: RouterManagedTag) {\n if (asset.tag === 'link' || asset.tag === 'script') {\n const attrs = asset.attrs ?? {}\n return [\n asset.tag,\n 'href' in attrs ? String(attrs.href) : '',\n 'src' in attrs ? String(attrs.src) : '',\n 'rel' in attrs ? String(attrs.rel) : '',\n 'type' in attrs ? String(attrs.type) : '',\n asset.children ?? '',\n ].join('|')\n }\n\n return JSON.stringify(asset)\n}\n\nfunction mergeRouteChunkData(options: {\n route: RouteTreeRoute\n chunk: Rollup.OutputChunk\n getChunkCssAssets: (chunk: Rollup.OutputChunk) => Array<RouterManagedTag>\n getChunkPreloads: (chunk: Rollup.OutputChunk) => Array<string>\n}) {\n const chunkAssets = options.getChunkCssAssets(options.chunk)\n const chunkPreloads = options.getChunkPreloads(options.chunk)\n\n options.route.assets = appendUniqueAssets(options.route.assets, chunkAssets)\n options.route.preloads = appendUniqueStrings(\n options.route.preloads,\n chunkPreloads,\n )\n}\n\nexport function buildStartManifest(options: {\n clientBundle: Rollup.OutputBundle\n routeTreeRoutes: RouteTreeRoutes\n basePath: string\n}) {\n const scannedChunks = scanClientChunks(options.clientBundle)\n const hashedCssFiles = collectDynamicImportCss(\n scannedChunks.routeEntryChunks,\n scannedChunks.chunksByFileName,\n scannedChunks.entryChunk,\n )\n const assetResolvers = createManifestAssetResolvers({\n basePath: options.basePath,\n hashedCssFiles,\n })\n\n const routes = buildRouteManifestRoutes({\n routeTreeRoutes: options.routeTreeRoutes,\n routeChunksByFilePath: scannedChunks.routeChunksByFilePath,\n chunksByFileName: scannedChunks.chunksByFileName,\n entryChunk: scannedChunks.entryChunk,\n assetResolvers,\n })\n\n dedupeNestedRoutePreloads(routes[rootRouteId]!, routes)\n\n // Prune routes with no assets or preloads from the manifest\n for (const routeId of Object.keys(routes)) {\n const route = routes[routeId]!\n const hasAssets = route.assets && route.assets.length > 0\n const hasPreloads = route.preloads && route.preloads.length > 0\n if (!hasAssets && !hasPreloads) {\n delete routes[routeId]\n }\n }\n\n return {\n routes,\n clientEntry: assetResolvers.getAssetPath(scannedChunks.entryChunk.fileName),\n }\n}\n\nexport function scanClientChunks(\n clientBundle: Rollup.OutputBundle,\n): ScannedClientChunks {\n let entryChunk: Rollup.OutputChunk | undefined\n const chunksByFileName = new Map<string, Rollup.OutputChunk>()\n const routeChunksByFilePath = new Map<string, Array<Rollup.OutputChunk>>()\n const routeEntryChunks = new Set<Rollup.OutputChunk>()\n\n for (const fileName in clientBundle) {\n const bundleEntry = clientBundle[fileName]!\n if (bundleEntry.type !== 'chunk') {\n continue\n }\n\n chunksByFileName.set(bundleEntry.fileName, bundleEntry)\n\n if (bundleEntry.isEntry) {\n if (entryChunk) {\n throw new Error(\n `multiple entries detected: ${entryChunk.fileName} ${bundleEntry.fileName}`,\n )\n }\n entryChunk = bundleEntry\n }\n\n const routeFilePaths = getRouteFilePathsFromModuleIds(bundleEntry.moduleIds)\n if (routeFilePaths.length === 0) {\n continue\n }\n\n routeEntryChunks.add(bundleEntry)\n\n for (let i = 0; i < routeFilePaths.length; i++) {\n const routeFilePath = routeFilePaths[i]!\n let chunks = routeChunksByFilePath.get(routeFilePath)\n if (chunks === undefined) {\n chunks = []\n routeChunksByFilePath.set(routeFilePath, chunks)\n }\n chunks.push(bundleEntry)\n }\n }\n\n if (!entryChunk) {\n throw new Error('No entry file found')\n }\n\n return {\n entryChunk,\n chunksByFileName,\n routeChunksByFilePath,\n routeEntryChunks,\n }\n}\n\nexport function getRouteFilePathsFromModuleIds(moduleIds: Array<string>) {\n let routeFilePaths: Array<string> | undefined\n let seenRouteFilePaths: Set<string> | undefined\n\n for (const moduleId of moduleIds) {\n const queryIndex = moduleId.indexOf('?')\n\n if (queryIndex < 0) {\n continue\n }\n\n const query = moduleId.slice(queryIndex + 1)\n\n // Fast check before allocating URLSearchParams\n if (!query.includes(tsrSplit)) {\n continue\n }\n\n if (!new URLSearchParams(query).has(tsrSplit)) {\n continue\n }\n\n const routeFilePath = moduleId.slice(0, queryIndex)\n\n if (seenRouteFilePaths?.has(routeFilePath)) {\n continue\n }\n\n if (routeFilePaths === undefined) {\n routeFilePaths = []\n seenRouteFilePaths = new Set<string>()\n }\n\n routeFilePaths.push(routeFilePath)\n seenRouteFilePaths!.add(routeFilePath)\n }\n\n return routeFilePaths ?? []\n}\n\nexport function collectDynamicImportCss(\n routeEntryChunks: Set<Rollup.OutputChunk>,\n chunksByFileName: Map<string, Rollup.OutputChunk>,\n entryChunk?: Rollup.OutputChunk,\n) {\n const routerManagedCssFiles = new Set<string>()\n const nonRouteDynamicCssFiles = new Set<string>()\n const hashedCssFiles = new Set<string>()\n const visitedByChunk = new Map<Rollup.OutputChunk, number>()\n const chunkStack: Array<Rollup.OutputChunk> = []\n const modeStack: Array<number> = []\n\n for (const routeEntryChunk of routeEntryChunks) {\n chunkStack.push(routeEntryChunk)\n modeStack.push(ROUTER_MANAGED_MODE)\n }\n\n if (entryChunk) {\n chunkStack.push(entryChunk)\n modeStack.push(ROUTER_MANAGED_MODE)\n }\n\n while (chunkStack.length > 0) {\n const chunk = chunkStack.pop()!\n const mode = modeStack.pop()!\n const previousMode = visitedByChunk.get(chunk) ?? 0\n\n if ((previousMode & mode) === mode) {\n continue\n }\n\n visitedByChunk.set(chunk, previousMode | mode)\n\n if ((mode & ROUTER_MANAGED_MODE) !== 0) {\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n routerManagedCssFiles.add(cssFile)\n }\n }\n\n if ((mode & NON_ROUTE_DYNAMIC_MODE) !== 0) {\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n nonRouteDynamicCssFiles.add(cssFile)\n }\n }\n\n for (let i = 0; i < chunk.imports.length; i++) {\n const importedChunk = chunksByFileName.get(chunk.imports[i]!)\n if (importedChunk) {\n chunkStack.push(importedChunk)\n modeStack.push(mode)\n }\n }\n\n for (let i = 0; i < chunk.dynamicImports.length; i++) {\n const dynamicImportedChunk = chunksByFileName.get(\n chunk.dynamicImports[i]!,\n )\n if (dynamicImportedChunk) {\n chunkStack.push(dynamicImportedChunk)\n modeStack.push(\n (mode & NON_ROUTE_DYNAMIC_MODE) !== 0 ||\n !routeEntryChunks.has(dynamicImportedChunk)\n ? NON_ROUTE_DYNAMIC_MODE\n : ROUTER_MANAGED_MODE,\n )\n }\n }\n }\n\n for (const cssFile of routerManagedCssFiles) {\n if (nonRouteDynamicCssFiles.has(cssFile)) {\n hashedCssFiles.add(cssFile)\n }\n }\n\n return hashedCssFiles\n}\n\nexport function createManifestAssetResolvers(options: {\n basePath: string\n hashedCssFiles?: Set<string>\n}): ManifestAssetResolvers {\n const assetPathByFileName = new Map<string, string>()\n const stylesheetAssetByFileName = new Map<string, RouterManagedTag>()\n const preloadsByChunk = new Map<Rollup.OutputChunk, Array<string>>()\n\n const getAssetPath = (fileName: string) => {\n const cachedPath = assetPathByFileName.get(fileName)\n if (cachedPath) {\n return cachedPath\n }\n\n const assetPath = joinURL(options.basePath, fileName)\n assetPathByFileName.set(fileName, assetPath)\n return assetPath\n }\n\n const getStylesheetAsset = (cssFile: string) => {\n const cachedAsset = stylesheetAssetByFileName.get(cssFile)\n if (cachedAsset) {\n return cachedAsset\n }\n\n const href = getAssetPath(cssFile)\n const asset = {\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: options.hashedCssFiles?.has(cssFile) ? `${href}#` : href,\n type: 'text/css',\n },\n } satisfies RouterManagedTag\n\n stylesheetAssetByFileName.set(cssFile, asset)\n return asset\n }\n\n const getChunkPreloads = (chunk: Rollup.OutputChunk) => {\n const cachedPreloads = preloadsByChunk.get(chunk)\n if (cachedPreloads) {\n return cachedPreloads\n }\n\n const preloads = [getAssetPath(chunk.fileName)]\n\n for (let i = 0; i < chunk.imports.length; i++) {\n preloads.push(getAssetPath(chunk.imports[i]!))\n }\n\n preloadsByChunk.set(chunk, preloads)\n return preloads\n }\n\n return {\n getAssetPath,\n getChunkPreloads,\n getStylesheetAsset,\n }\n}\n\nexport function createChunkCssAssetCollector(options: {\n chunksByFileName: Map<string, Rollup.OutputChunk>\n getStylesheetAsset: (cssFile: string) => RouterManagedTag\n}) {\n const assetsByChunk = new Map<Rollup.OutputChunk, Array<RouterManagedTag>>()\n const stateByChunk = new Map<Rollup.OutputChunk, number>()\n\n const getChunkCssAssets = (\n chunk: Rollup.OutputChunk,\n ): Array<RouterManagedTag> => {\n const cachedAssets = assetsByChunk.get(chunk)\n if (cachedAssets) {\n return cachedAssets\n }\n\n if (stateByChunk.get(chunk) === VISITING_CHUNK) {\n return []\n }\n stateByChunk.set(chunk, VISITING_CHUNK)\n\n const assets: Array<RouterManagedTag> = []\n\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n assets.push(options.getStylesheetAsset(cssFile))\n }\n\n for (let i = 0; i < chunk.imports.length; i++) {\n const importedChunk = options.chunksByFileName.get(chunk.imports[i]!)\n if (!importedChunk) {\n continue\n }\n\n const importedAssets = getChunkCssAssets(importedChunk)\n for (let j = 0; j < importedAssets.length; j++) {\n assets.push(importedAssets[j]!)\n }\n }\n\n stateByChunk.delete(chunk)\n assetsByChunk.set(chunk, assets)\n return assets\n }\n\n return { getChunkCssAssets }\n}\n\nexport function buildRouteManifestRoutes(options: {\n routeTreeRoutes: RouteTreeRoutes\n routeChunksByFilePath: Map<string, Array<Rollup.OutputChunk>>\n chunksByFileName: Map<string, Rollup.OutputChunk>\n entryChunk: Rollup.OutputChunk\n assetResolvers: ManifestAssetResolvers\n}) {\n const routes: Record<string, RouteTreeRoute> = {}\n const getChunkCssAssets = createChunkCssAssetCollector({\n chunksByFileName: options.chunksByFileName,\n getStylesheetAsset: options.assetResolvers.getStylesheetAsset,\n }).getChunkCssAssets\n\n for (const [routeId, route] of Object.entries(options.routeTreeRoutes)) {\n if (!route.filePath) {\n if (routeId === rootRouteId) {\n routes[routeId] = route\n continue\n }\n\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n\n const chunks = options.routeChunksByFilePath.get(route.filePath)\n if (!chunks) {\n routes[routeId] = route\n continue\n }\n\n const existing = routes[routeId]\n const targetRoute = (routes[routeId] = existing ? existing : { ...route })\n\n for (const chunk of chunks) {\n mergeRouteChunkData({\n route: targetRoute,\n chunk,\n getChunkCssAssets,\n getChunkPreloads: options.assetResolvers.getChunkPreloads,\n })\n }\n }\n\n const rootRoute = (routes[rootRouteId] = routes[rootRouteId] || {})\n mergeRouteChunkData({\n route: rootRoute,\n chunk: options.entryChunk,\n getChunkCssAssets,\n getChunkPreloads: options.assetResolvers.getChunkPreloads,\n })\n\n return routes\n}\n\nexport function dedupeNestedRoutePreloads(\n route: DedupePreloadRoute,\n routesById: Record<string, DedupePreloadRoute>,\n seenPreloads = new Set<string>(),\n) {\n let routePreloads = route.preloads\n\n if (routePreloads && routePreloads.length > 0) {\n let dedupedPreloads: Array<ManifestAssetLink> | undefined\n\n for (let i = 0; i < routePreloads.length; i++) {\n const preload = routePreloads[i]!\n const preloadHref = resolveManifestAssetLink(preload).href\n\n if (seenPreloads.has(preloadHref)) {\n if (dedupedPreloads === undefined) {\n dedupedPreloads = routePreloads.slice(0, i)\n }\n continue\n }\n\n seenPreloads.add(preloadHref)\n\n if (dedupedPreloads) {\n dedupedPreloads.push(preload)\n }\n }\n\n if (dedupedPreloads) {\n routePreloads = dedupedPreloads\n route.preloads = dedupedPreloads\n }\n }\n\n if (route.children) {\n for (const childRouteId of route.children) {\n dedupeNestedRoutePreloads(\n routesById[childRouteId]!,\n routesById,\n seenPreloads,\n )\n }\n }\n\n if (routePreloads) {\n for (let i = routePreloads.length - 1; i >= 0; i--) {\n seenPreloads.delete(resolveManifestAssetLink(routePreloads[i]!).href)\n }\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/start-plugin-core",
3
- "version": "1.167.6",
3
+ "version": "1.167.8",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -60,12 +60,12 @@
60
60
  "vitefu": "^1.1.1",
61
61
  "xmlbuilder2": "^4.0.3",
62
62
  "zod": "^3.24.2",
63
- "@tanstack/router-core": "1.168.2",
64
- "@tanstack/router-generator": "1.166.16",
65
- "@tanstack/router-plugin": "1.167.3",
63
+ "@tanstack/router-core": "1.168.3",
64
+ "@tanstack/router-generator": "1.166.17",
65
+ "@tanstack/router-plugin": "1.167.4",
66
66
  "@tanstack/router-utils": "1.161.6",
67
- "@tanstack/start-client-core": "1.167.2",
68
- "@tanstack/start-server-core": "1.167.2"
67
+ "@tanstack/start-client-core": "1.167.3",
68
+ "@tanstack/start-server-core": "1.167.3"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/babel__code-frame": "^7.0.6",
@@ -51,6 +51,10 @@ export function previewServerPlugin(): Plugin {
51
51
  const webReq = new NodeRequest({ req, res })
52
52
  const webRes: Response = await serverBuild.fetch(webReq)
53
53
 
54
+ if (webRes.headers.get('content-type')?.startsWith('text/html')) {
55
+ res.setHeader('content-encoding', 'identity')
56
+ }
57
+
54
58
  // Temporary workaround
55
59
  // Vite preview's compression middleware doesn't support flattened array headers that srvx sets
56
60
  // Call writeHead() before srvx to avoid corruption
@@ -1,8 +1,8 @@
1
1
  /* eslint-disable @typescript-eslint/prefer-for-of */
2
2
  import { joinURL } from 'ufo'
3
- import { rootRouteId } from '@tanstack/router-core'
3
+ import { resolveManifestAssetLink, rootRouteId } from '@tanstack/router-core'
4
4
  import { tsrSplit } from '@tanstack/router-plugin'
5
- import type { RouterManagedTag } from '@tanstack/router-core'
5
+ import type { ManifestAssetLink, RouterManagedTag } from '@tanstack/router-core'
6
6
  import type { Rollup } from 'vite'
7
7
 
8
8
  const ROUTER_MANAGED_MODE = 1
@@ -31,6 +31,11 @@ interface ManifestAssetResolvers {
31
31
  getStylesheetAsset: (cssFile: string) => RouterManagedTag
32
32
  }
33
33
 
34
+ type DedupePreloadRoute = {
35
+ preloads?: Array<ManifestAssetLink>
36
+ children?: Array<string>
37
+ }
38
+
34
39
  export function appendUniqueStrings(
35
40
  target: Array<string> | undefined,
36
41
  source: Array<string>,
@@ -506,25 +511,27 @@ export function buildRouteManifestRoutes(options: {
506
511
  }
507
512
 
508
513
  export function dedupeNestedRoutePreloads(
509
- route: { preloads?: Array<string>; children?: Array<string> },
510
- routesById: Record<string, RouteTreeRoute>,
514
+ route: DedupePreloadRoute,
515
+ routesById: Record<string, DedupePreloadRoute>,
511
516
  seenPreloads = new Set<string>(),
512
517
  ) {
513
518
  let routePreloads = route.preloads
514
519
 
515
520
  if (routePreloads && routePreloads.length > 0) {
516
- let dedupedPreloads: Array<string> | undefined
521
+ let dedupedPreloads: Array<ManifestAssetLink> | undefined
517
522
 
518
523
  for (let i = 0; i < routePreloads.length; i++) {
519
524
  const preload = routePreloads[i]!
520
- if (seenPreloads.has(preload)) {
525
+ const preloadHref = resolveManifestAssetLink(preload).href
526
+
527
+ if (seenPreloads.has(preloadHref)) {
521
528
  if (dedupedPreloads === undefined) {
522
529
  dedupedPreloads = routePreloads.slice(0, i)
523
530
  }
524
531
  continue
525
532
  }
526
533
 
527
- seenPreloads.add(preload)
534
+ seenPreloads.add(preloadHref)
528
535
 
529
536
  if (dedupedPreloads) {
530
537
  dedupedPreloads.push(preload)
@@ -549,7 +556,7 @@ export function dedupeNestedRoutePreloads(
549
556
 
550
557
  if (routePreloads) {
551
558
  for (let i = routePreloads.length - 1; i >= 0; i--) {
552
- seenPreloads.delete(routePreloads[i]!)
559
+ seenPreloads.delete(resolveManifestAssetLink(routePreloads[i]!).href)
553
560
  }
554
561
  }
555
562
  }