@tanstack/start-plugin-core 1.142.8 → 1.142.11

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 (64) hide show
  1. package/dist/esm/create-server-fn-plugin/compiler.d.ts +8 -5
  2. package/dist/esm/create-server-fn-plugin/compiler.js +108 -43
  3. package/dist/esm/create-server-fn-plugin/compiler.js.map +1 -1
  4. package/dist/esm/create-server-fn-plugin/handleCreateIsomorphicFn.d.ts +4 -0
  5. package/dist/esm/create-server-fn-plugin/handleCreateIsomorphicFn.js +31 -0
  6. package/dist/esm/create-server-fn-plugin/handleCreateIsomorphicFn.js.map +1 -0
  7. package/dist/esm/create-server-fn-plugin/handleCreateServerFn.js +1 -1
  8. package/dist/esm/create-server-fn-plugin/handleCreateServerFn.js.map +1 -1
  9. package/dist/esm/create-server-fn-plugin/handleEnvOnly.d.ts +6 -0
  10. package/dist/esm/create-server-fn-plugin/handleEnvOnly.js +36 -0
  11. package/dist/esm/create-server-fn-plugin/handleEnvOnly.js.map +1 -0
  12. package/dist/esm/create-server-fn-plugin/plugin.d.ts +1 -1
  13. package/dist/esm/create-server-fn-plugin/plugin.js +50 -12
  14. package/dist/esm/create-server-fn-plugin/plugin.js.map +1 -1
  15. package/dist/esm/create-server-fn-plugin/types.d.ts +0 -1
  16. package/dist/esm/{start-compiler-plugin → create-server-fn-plugin}/utils.d.ts +0 -3
  17. package/dist/esm/create-server-fn-plugin/utils.js +19 -0
  18. package/dist/esm/create-server-fn-plugin/utils.js.map +1 -0
  19. package/dist/esm/plugin.d.ts +2 -30
  20. package/dist/esm/plugin.js +2 -2
  21. package/dist/esm/plugin.js.map +1 -1
  22. package/dist/esm/schema.d.ts +288 -288
  23. package/dist/esm/schema.js.map +1 -1
  24. package/dist/esm/start-manifest-plugin/plugin.d.ts +1 -1
  25. package/dist/esm/start-manifest-plugin/plugin.js.map +1 -1
  26. package/dist/esm/start-router-plugin/plugin.d.ts +1 -1
  27. package/dist/esm/start-router-plugin/plugin.js.map +1 -1
  28. package/dist/esm/types.d.ts +30 -0
  29. package/package.json +7 -7
  30. package/src/create-server-fn-plugin/compiler.ts +164 -58
  31. package/src/create-server-fn-plugin/handleCreateIsomorphicFn.ts +46 -0
  32. package/src/create-server-fn-plugin/handleCreateServerFn.ts +1 -1
  33. package/src/create-server-fn-plugin/handleEnvOnly.ts +45 -0
  34. package/src/create-server-fn-plugin/plugin.ts +58 -14
  35. package/src/create-server-fn-plugin/types.ts +0 -8
  36. package/src/create-server-fn-plugin/utils.ts +24 -0
  37. package/src/plugin.ts +7 -34
  38. package/src/schema.ts +1 -1
  39. package/src/start-manifest-plugin/plugin.ts +1 -1
  40. package/src/start-router-plugin/plugin.ts +1 -1
  41. package/src/types.ts +34 -0
  42. package/dist/esm/start-compiler-plugin/compilers.d.ts +0 -15
  43. package/dist/esm/start-compiler-plugin/compilers.js +0 -114
  44. package/dist/esm/start-compiler-plugin/compilers.js.map +0 -1
  45. package/dist/esm/start-compiler-plugin/constants.d.ts +0 -1
  46. package/dist/esm/start-compiler-plugin/constants.js +0 -9
  47. package/dist/esm/start-compiler-plugin/constants.js.map +0 -1
  48. package/dist/esm/start-compiler-plugin/envOnly.d.ts +0 -5
  49. package/dist/esm/start-compiler-plugin/envOnly.js +0 -41
  50. package/dist/esm/start-compiler-plugin/envOnly.js.map +0 -1
  51. package/dist/esm/start-compiler-plugin/isomorphicFn.d.ts +0 -4
  52. package/dist/esm/start-compiler-plugin/isomorphicFn.js +0 -49
  53. package/dist/esm/start-compiler-plugin/isomorphicFn.js.map +0 -1
  54. package/dist/esm/start-compiler-plugin/plugin.d.ts +0 -12
  55. package/dist/esm/start-compiler-plugin/plugin.js +0 -88
  56. package/dist/esm/start-compiler-plugin/plugin.js.map +0 -1
  57. package/dist/esm/start-compiler-plugin/utils.js +0 -30
  58. package/dist/esm/start-compiler-plugin/utils.js.map +0 -1
  59. package/src/start-compiler-plugin/compilers.ts +0 -176
  60. package/src/start-compiler-plugin/constants.ts +0 -5
  61. package/src/start-compiler-plugin/envOnly.ts +0 -58
  62. package/src/start-compiler-plugin/isomorphicFn.ts +0 -78
  63. package/src/start-compiler-plugin/plugin.ts +0 -111
  64. package/src/start-compiler-plugin/utils.ts +0 -41
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-plugin'\nimport type { TanStackStartVitePluginCoreOptions } from './plugin'\n\nconst tsrConfig = configSchema\n .omit({ autoCodeSplitting: true, target: true, verboseFileRoutes: true })\n .partial()\n\nexport function parseStartConfig(\n opts: z.input<typeof tanstackStartOptionsSchema>,\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n root: string,\n) {\n const options = tanstackStartOptionsSchema.parse(opts)\n\n const srcDirectory = options.srcDirectory\n\n const routesDirectory = path.resolve(\n root,\n srcDirectory,\n options.router.routesDirectory ?? 'routes',\n )\n\n const generatedRouteTree = path.resolve(\n root,\n srcDirectory,\n options.router.generatedRouteTree ?? 'routeTree.gen.ts',\n )\n\n return {\n ...options,\n router: {\n ...options.router,\n ...getConfig(\n {\n ...options.router,\n routesDirectory,\n generatedRouteTree,\n },\n root,\n ),\n target: corePluginOpts.framework,\n },\n }\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n outputPath: z.string().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n headers: z.record(z.string(), z.string()).optional(),\n})\n\nconst spaSchema = z.object({\n enabled: z.boolean().optional().default(true),\n maskPath: z.string().optional().default('/'),\n prerender: pagePrerenderOptionsSchema\n .optional()\n .default({})\n .transform((opts) => ({\n outputPath: opts.outputPath ?? '/_shell',\n crawlLinks: false,\n retryCount: 0,\n ...opts,\n enabled: true,\n })),\n})\n\nconst pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nconst tanstackStartOptionsSchema = z\n .object({\n srcDirectory: z.string().optional().default('src'),\n start: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n router: z\n .object({\n entry: z.string().optional(),\n basepath: z.string().optional(),\n })\n .and(tsrConfig.optional().default({}))\n .optional()\n .default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_serverFn'),\n generateFunctionId: z\n .function()\n .args(\n z.object({\n filename: z.string(),\n functionName: z.string(),\n }),\n )\n .returns(z.string().optional())\n .optional(),\n })\n .optional()\n .default({}),\n pages: z.array(pageSchema).optional().default([]),\n sitemap: z\n .object({\n enabled: z.boolean().optional().default(true),\n host: z.string().optional(),\n outputPath: z.string().optional().default('sitemap.xml'),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n autoStaticPathsDiscovery: z.boolean().optional(),\n maxRedirects: z.number().min(0).optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n spa: spaSchema.optional(),\n vite: z\n .object({ installDevServerMiddleware: z.boolean().optional() })\n .optional(),\n })\n .optional()\n .default({})\n\nexport type Page = z.infer<typeof pageSchema>\n\nexport type TanStackStartInputConfig = z.input<\n typeof tanstackStartOptionsSchema\n>\nexport type TanStackStartOutputConfig = ReturnType<typeof parseStartConfig>\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-plugin'\nimport type { TanStackStartVitePluginCoreOptions } from './types'\n\nconst tsrConfig = configSchema\n .omit({ autoCodeSplitting: true, target: true, verboseFileRoutes: true })\n .partial()\n\nexport function parseStartConfig(\n opts: z.input<typeof tanstackStartOptionsSchema>,\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n root: string,\n) {\n const options = tanstackStartOptionsSchema.parse(opts)\n\n const srcDirectory = options.srcDirectory\n\n const routesDirectory = path.resolve(\n root,\n srcDirectory,\n options.router.routesDirectory ?? 'routes',\n )\n\n const generatedRouteTree = path.resolve(\n root,\n srcDirectory,\n options.router.generatedRouteTree ?? 'routeTree.gen.ts',\n )\n\n return {\n ...options,\n router: {\n ...options.router,\n ...getConfig(\n {\n ...options.router,\n routesDirectory,\n generatedRouteTree,\n },\n root,\n ),\n target: corePluginOpts.framework,\n },\n }\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n outputPath: z.string().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n headers: z.record(z.string(), z.string()).optional(),\n})\n\nconst spaSchema = z.object({\n enabled: z.boolean().optional().default(true),\n maskPath: z.string().optional().default('/'),\n prerender: pagePrerenderOptionsSchema\n .optional()\n .default({})\n .transform((opts) => ({\n outputPath: opts.outputPath ?? '/_shell',\n crawlLinks: false,\n retryCount: 0,\n ...opts,\n enabled: true,\n })),\n})\n\nconst pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nconst tanstackStartOptionsSchema = z\n .object({\n srcDirectory: z.string().optional().default('src'),\n start: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n router: z\n .object({\n entry: z.string().optional(),\n basepath: z.string().optional(),\n })\n .and(tsrConfig.optional().default({}))\n .optional()\n .default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_serverFn'),\n generateFunctionId: z\n .function()\n .args(\n z.object({\n filename: z.string(),\n functionName: z.string(),\n }),\n )\n .returns(z.string().optional())\n .optional(),\n })\n .optional()\n .default({}),\n pages: z.array(pageSchema).optional().default([]),\n sitemap: z\n .object({\n enabled: z.boolean().optional().default(true),\n host: z.string().optional(),\n outputPath: z.string().optional().default('sitemap.xml'),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n autoStaticPathsDiscovery: z.boolean().optional(),\n maxRedirects: z.number().min(0).optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n spa: spaSchema.optional(),\n vite: z\n .object({ installDevServerMiddleware: z.boolean().optional() })\n .optional(),\n })\n .optional()\n .default({})\n\nexport type Page = z.infer<typeof pageSchema>\n\nexport type TanStackStartInputConfig = z.input<\n typeof tanstackStartOptionsSchema\n>\nexport type TanStackStartOutputConfig = ReturnType<typeof parseStartConfig>\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { GetConfigFn } from '../plugin.js';
1
+ import { GetConfigFn } from '../types.js';
2
2
  import { PluginOption, Rollup } from 'vite';
3
3
  export declare function startManifestPlugin(opts: {
4
4
  getClientBundle: () => Rollup.OutputBundle;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../../src/start-manifest-plugin/plugin.ts"],"sourcesContent":["import { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { tsrSplit } from '@tanstack/router-plugin'\nimport { resolveViteId } from '../utils'\nimport { ENTRY_POINTS } from '../constants'\nimport type { GetConfigFn } from '../plugin'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { Manifest, RouterManagedTag } from '@tanstack/router-core'\n\nconst getCSSRecursively = (\n chunk: Rollup.OutputChunk,\n chunksByFileName: Map<string, Rollup.OutputChunk>,\n basePath: string,\n cache: Map<Rollup.OutputChunk, Array<RouterManagedTag>>,\n visited = new Set<Rollup.OutputChunk>(),\n) => {\n if (visited.has(chunk)) {\n return []\n }\n visited.add(chunk)\n const cachedResult = cache.get(chunk)\n if (cachedResult) {\n return cachedResult\n }\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const importedFileName of chunk.imports) {\n const importedChunk = chunksByFileName.get(importedFileName)\n if (importedChunk) {\n result.push(\n ...getCSSRecursively(\n importedChunk,\n chunksByFileName,\n basePath,\n cache,\n visited,\n ),\n )\n }\n }\n\n cache.set(chunk, result)\n return result\n}\n\nconst resolvedModuleId = resolveViteId(VIRTUAL_MODULES.startManifest)\nexport function startManifestPlugin(opts: {\n getClientBundle: () => Rollup.OutputBundle\n getConfig: GetConfigFn\n}): PluginOption {\n return {\n name: 'tanstack-start:start-manifest-plugin',\n enforce: 'pre',\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.startManifest) },\n handler(id) {\n if (id === VIRTUAL_MODULES.startManifest) {\n return resolvedModuleId\n }\n return undefined\n },\n },\n load: {\n filter: {\n id: new RegExp(resolvedModuleId),\n },\n handler(id) {\n const { resolvedStartConfig } = opts.getConfig()\n if (id === resolvedModuleId) {\n if (\n this.environment.name !== resolvedStartConfig.serverFnProviderEnv\n ) {\n // this will ultimately fail the build if the plugin is used outside the provider environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // If we're in development, return a dummy manifest\n if (this.environment.config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {},\n clientEntry: '${joinURL(resolvedStartConfig.viteAppBase, '@id', ENTRY_POINTS.client)}',\n })`\n }\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/routeTree.gen.ts`\n const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST\n\n const cssPerChunkCache = new Map<\n Rollup.OutputChunk,\n Array<RouterManagedTag>\n >()\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n let entryFile: Rollup.OutputChunk | undefined\n\n const clientBundle = opts.getClientBundle()\n const chunksByFileName = new Map<string, Rollup.OutputChunk>()\n\n const routeChunks: Record<\n string /** fullPath of route file **/,\n Array<Rollup.OutputChunk>\n > = {}\n for (const bundleEntry of Object.values(clientBundle)) {\n if (bundleEntry.type === 'chunk') {\n chunksByFileName.set(bundleEntry.fileName, bundleEntry)\n if (bundleEntry.isEntry) {\n if (entryFile) {\n throw new Error(\n `multiple entries detected: ${entryFile.fileName} ${bundleEntry.fileName}`,\n )\n }\n entryFile = bundleEntry\n }\n const routePieces = bundleEntry.moduleIds.flatMap((m) => {\n const [id, query] = m.split('?')\n if (id === undefined) {\n throw new Error('expected id to be defined')\n }\n if (query === undefined) {\n return []\n }\n const searchParams = new URLSearchParams(query)\n const split = searchParams.get(tsrSplit)\n\n if (split !== null) {\n return {\n id,\n split,\n }\n }\n return []\n })\n if (routePieces.length > 0) {\n routePieces.forEach((r) => {\n let array = routeChunks[r.id]\n if (array === undefined) {\n array = []\n routeChunks[r.id] = array\n }\n array.push(bundleEntry)\n })\n }\n }\n }\n\n const manifest: Manifest = { routes: {} }\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n if (!v.filePath) {\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n const chunks = routeChunks[v.filePath]\n if (chunks) {\n chunks.forEach((chunk) => {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = chunk.imports.map((d) => {\n const preloadPath = joinURL(\n resolvedStartConfig.viteAppBase,\n d,\n )\n return preloadPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n preloads.unshift(\n joinURL(resolvedStartConfig.viteAppBase, chunk.fileName),\n )\n\n const assets = getCSSRecursively(\n chunk,\n chunksByFileName,\n resolvedStartConfig.viteAppBase,\n cssPerChunkCache,\n )\n\n manifest.routes[routeId] = {\n ...v,\n assets,\n preloads,\n }\n })\n } else {\n manifest.routes[routeId] = v\n }\n })\n\n if (!entryFile) {\n throw new Error('No entry file found')\n }\n\n manifest.routes[rootRouteId] = manifest.routes[rootRouteId] || {}\n manifest.routes[rootRouteId].preloads = [\n joinURL(resolvedStartConfig.viteAppBase, entryFile.fileName),\n ...entryFile.imports.map((d) =>\n joinURL(resolvedStartConfig.viteAppBase, d),\n ),\n ]\n\n // Gather all the CSS files from the entry file in\n // the `css` key and add them to the root route\n const entryCssAssetsList = getCSSRecursively(\n entryFile,\n chunksByFileName,\n resolvedStartConfig.viteAppBase,\n cssPerChunkCache,\n )\n\n manifest.routes[rootRouteId].assets = [\n ...(manifest.routes[rootRouteId].assets || []),\n ...entryCssAssetsList,\n ]\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = manifest.routes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n recurseRoute(manifest.routes[rootRouteId])\n\n // Filter out routes that have neither assets nor preloads\n Object.keys(manifest.routes).forEach((routeId) => {\n const route = manifest.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 routeTreeRoutes[routeId]\n }\n })\n\n const startManifest = {\n routes: manifest.routes,\n clientEntry: joinURL(\n resolvedStartConfig.viteAppBase,\n entryFile.fileName,\n ),\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(startManifest)})`\n }\n\n return undefined\n },\n },\n }\n}\n"],"names":["id"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sources":["../../../src/start-manifest-plugin/plugin.ts"],"sourcesContent":["import { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { tsrSplit } from '@tanstack/router-plugin'\nimport { resolveViteId } from '../utils'\nimport { ENTRY_POINTS } from '../constants'\nimport type { GetConfigFn } from '../types'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { Manifest, RouterManagedTag } from '@tanstack/router-core'\n\nconst getCSSRecursively = (\n chunk: Rollup.OutputChunk,\n chunksByFileName: Map<string, Rollup.OutputChunk>,\n basePath: string,\n cache: Map<Rollup.OutputChunk, Array<RouterManagedTag>>,\n visited = new Set<Rollup.OutputChunk>(),\n) => {\n if (visited.has(chunk)) {\n return []\n }\n visited.add(chunk)\n const cachedResult = cache.get(chunk)\n if (cachedResult) {\n return cachedResult\n }\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const importedFileName of chunk.imports) {\n const importedChunk = chunksByFileName.get(importedFileName)\n if (importedChunk) {\n result.push(\n ...getCSSRecursively(\n importedChunk,\n chunksByFileName,\n basePath,\n cache,\n visited,\n ),\n )\n }\n }\n\n cache.set(chunk, result)\n return result\n}\n\nconst resolvedModuleId = resolveViteId(VIRTUAL_MODULES.startManifest)\nexport function startManifestPlugin(opts: {\n getClientBundle: () => Rollup.OutputBundle\n getConfig: GetConfigFn\n}): PluginOption {\n return {\n name: 'tanstack-start:start-manifest-plugin',\n enforce: 'pre',\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.startManifest) },\n handler(id) {\n if (id === VIRTUAL_MODULES.startManifest) {\n return resolvedModuleId\n }\n return undefined\n },\n },\n load: {\n filter: {\n id: new RegExp(resolvedModuleId),\n },\n handler(id) {\n const { resolvedStartConfig } = opts.getConfig()\n if (id === resolvedModuleId) {\n if (\n this.environment.name !== resolvedStartConfig.serverFnProviderEnv\n ) {\n // this will ultimately fail the build if the plugin is used outside the provider environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // If we're in development, return a dummy manifest\n if (this.environment.config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {},\n clientEntry: '${joinURL(resolvedStartConfig.viteAppBase, '@id', ENTRY_POINTS.client)}',\n })`\n }\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/routeTree.gen.ts`\n const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST\n\n const cssPerChunkCache = new Map<\n Rollup.OutputChunk,\n Array<RouterManagedTag>\n >()\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n let entryFile: Rollup.OutputChunk | undefined\n\n const clientBundle = opts.getClientBundle()\n const chunksByFileName = new Map<string, Rollup.OutputChunk>()\n\n const routeChunks: Record<\n string /** fullPath of route file **/,\n Array<Rollup.OutputChunk>\n > = {}\n for (const bundleEntry of Object.values(clientBundle)) {\n if (bundleEntry.type === 'chunk') {\n chunksByFileName.set(bundleEntry.fileName, bundleEntry)\n if (bundleEntry.isEntry) {\n if (entryFile) {\n throw new Error(\n `multiple entries detected: ${entryFile.fileName} ${bundleEntry.fileName}`,\n )\n }\n entryFile = bundleEntry\n }\n const routePieces = bundleEntry.moduleIds.flatMap((m) => {\n const [id, query] = m.split('?')\n if (id === undefined) {\n throw new Error('expected id to be defined')\n }\n if (query === undefined) {\n return []\n }\n const searchParams = new URLSearchParams(query)\n const split = searchParams.get(tsrSplit)\n\n if (split !== null) {\n return {\n id,\n split,\n }\n }\n return []\n })\n if (routePieces.length > 0) {\n routePieces.forEach((r) => {\n let array = routeChunks[r.id]\n if (array === undefined) {\n array = []\n routeChunks[r.id] = array\n }\n array.push(bundleEntry)\n })\n }\n }\n }\n\n const manifest: Manifest = { routes: {} }\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n if (!v.filePath) {\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n const chunks = routeChunks[v.filePath]\n if (chunks) {\n chunks.forEach((chunk) => {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = chunk.imports.map((d) => {\n const preloadPath = joinURL(\n resolvedStartConfig.viteAppBase,\n d,\n )\n return preloadPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n preloads.unshift(\n joinURL(resolvedStartConfig.viteAppBase, chunk.fileName),\n )\n\n const assets = getCSSRecursively(\n chunk,\n chunksByFileName,\n resolvedStartConfig.viteAppBase,\n cssPerChunkCache,\n )\n\n manifest.routes[routeId] = {\n ...v,\n assets,\n preloads,\n }\n })\n } else {\n manifest.routes[routeId] = v\n }\n })\n\n if (!entryFile) {\n throw new Error('No entry file found')\n }\n\n manifest.routes[rootRouteId] = manifest.routes[rootRouteId] || {}\n manifest.routes[rootRouteId].preloads = [\n joinURL(resolvedStartConfig.viteAppBase, entryFile.fileName),\n ...entryFile.imports.map((d) =>\n joinURL(resolvedStartConfig.viteAppBase, d),\n ),\n ]\n\n // Gather all the CSS files from the entry file in\n // the `css` key and add them to the root route\n const entryCssAssetsList = getCSSRecursively(\n entryFile,\n chunksByFileName,\n resolvedStartConfig.viteAppBase,\n cssPerChunkCache,\n )\n\n manifest.routes[rootRouteId].assets = [\n ...(manifest.routes[rootRouteId].assets || []),\n ...entryCssAssetsList,\n ]\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = manifest.routes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n recurseRoute(manifest.routes[rootRouteId])\n\n // Filter out routes that have neither assets nor preloads\n Object.keys(manifest.routes).forEach((routeId) => {\n const route = manifest.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 routeTreeRoutes[routeId]\n }\n })\n\n const startManifest = {\n routes: manifest.routes,\n clientEntry: joinURL(\n resolvedStartConfig.viteAppBase,\n entryFile.fileName,\n ),\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(startManifest)})`\n }\n\n return undefined\n },\n },\n }\n}\n"],"names":["id"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
+ import { GetConfigFn, TanStackStartVitePluginCoreOptions } from '../types.js';
1
2
  import { PluginOption } from 'vite';
2
3
  import { TanStackStartInputConfig } from '../schema.js';
3
- import { GetConfigFn, TanStackStartVitePluginCoreOptions } from '../plugin.js';
4
4
  export declare function tanStackStartRouter(startPluginOpts: TanStackStartInputConfig, getConfig: GetConfigFn, corePluginOpts: TanStackStartVitePluginCoreOptions): Array<PluginOption>;
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../../src/start-router-plugin/plugin.ts"],"sourcesContent":["import {\n tanStackRouterCodeSplitter,\n tanstackRouterAutoImport,\n tanstackRouterGenerator,\n} from '@tanstack/router-plugin/vite'\nimport { normalizePath } from 'vite'\nimport path from 'pathe'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { routesManifestPlugin } from './generator-plugins/routes-manifest-plugin'\nimport { prerenderRoutesPlugin } from './generator-plugins/prerender-routes-plugin'\nimport { pruneServerOnlySubtrees } from './pruneServerOnlySubtrees'\nimport { SERVER_PROP } from './constants'\nimport type {\n Generator,\n GeneratorPlugin,\n RouteNode,\n} from '@tanstack/router-generator'\nimport type { DevEnvironment, Plugin, PluginOption } from 'vite'\nimport type { TanStackStartInputConfig } from '../schema'\nimport type { GetConfigFn, TanStackStartVitePluginCoreOptions } from '../plugin'\n\nfunction isServerOnlyNode(node: RouteNode | undefined) {\n if (!node?.createFileRouteProps) {\n return false\n }\n return (\n node.createFileRouteProps.has(SERVER_PROP) &&\n node.createFileRouteProps.size === 1\n )\n}\n\nfunction moduleDeclaration({\n startFilePath,\n routerFilePath,\n corePluginOpts,\n generatedRouteTreePath,\n}: {\n startFilePath: string | undefined\n routerFilePath: string\n corePluginOpts: TanStackStartVitePluginCoreOptions\n generatedRouteTreePath: string\n}): string {\n function getImportPath(absolutePath: string) {\n let relativePath = path.relative(\n path.dirname(generatedRouteTreePath),\n absolutePath,\n )\n\n if (!relativePath.startsWith('.')) {\n relativePath = './' + relativePath\n }\n\n // convert to POSIX-style for ESM imports (important on Windows)\n relativePath = relativePath.split(path.sep).join('/')\n return relativePath\n }\n\n const result: Array<string> = [\n `import type { getRouter } from '${getImportPath(routerFilePath)}'`,\n ]\n if (startFilePath) {\n result.push(\n `import type { startInstance } from '${getImportPath(startFilePath)}'`,\n )\n }\n // make sure we import something from start to get the server route declaration merge\n else {\n result.push(\n `import type { createStart } from '@tanstack/${corePluginOpts.framework}-start'`,\n )\n }\n result.push(\n `declare module '@tanstack/${corePluginOpts.framework}-start' {\n interface Register {\n ssr: true\n router: Awaited<ReturnType<typeof getRouter>>`,\n )\n if (startFilePath) {\n result.push(\n ` config: Awaited<ReturnType<typeof startInstance.getOptions>>`,\n )\n }\n result.push(` }\n}`)\n\n return result.join('\\n')\n}\n\nexport function tanStackStartRouter(\n startPluginOpts: TanStackStartInputConfig,\n getConfig: GetConfigFn,\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n): Array<PluginOption> {\n const getGeneratedRouteTreePath = () => {\n const { startConfig } = getConfig()\n return path.resolve(startConfig.router.generatedRouteTree)\n }\n\n let clientEnvironment: DevEnvironment | null = null\n function invalidate() {\n if (!clientEnvironment) {\n return\n }\n\n const mod = clientEnvironment.moduleGraph.getModuleById(\n getGeneratedRouteTreePath(),\n )\n if (mod) {\n clientEnvironment.moduleGraph.invalidateModule(mod)\n }\n clientEnvironment.hot.send({ type: 'full-reload', path: '*' })\n }\n\n let generatorInstance: Generator | null = null\n\n const clientTreeGeneratorPlugin: GeneratorPlugin = {\n name: 'start-client-tree-plugin',\n init({ generator }) {\n generatorInstance = generator\n },\n afterTransform({ node, prevNode }) {\n if (isServerOnlyNode(node) !== isServerOnlyNode(prevNode)) {\n invalidate()\n }\n },\n }\n\n let routeTreeFileFooter: Array<string> | null = null\n\n function getRouteTreeFileFooter() {\n if (routeTreeFileFooter) {\n return routeTreeFileFooter\n }\n const { startConfig, resolvedStartConfig } = getConfig()\n const ogRouteTreeFileFooter = startConfig.router.routeTreeFileFooter\n if (ogRouteTreeFileFooter) {\n if (Array.isArray(ogRouteTreeFileFooter)) {\n routeTreeFileFooter = ogRouteTreeFileFooter\n } else {\n routeTreeFileFooter = ogRouteTreeFileFooter()\n }\n }\n routeTreeFileFooter = [\n moduleDeclaration({\n generatedRouteTreePath: getGeneratedRouteTreePath(),\n corePluginOpts,\n startFilePath: resolvedStartConfig.startFilePath,\n routerFilePath: resolvedStartConfig.routerFilePath,\n }),\n ...(routeTreeFileFooter ?? []),\n ]\n return routeTreeFileFooter\n }\n\n let resolvedGeneratedRouteTreePath: string | null = null\n const clientTreePlugin: Plugin = {\n name: 'tanstack-start:route-tree-client-plugin',\n enforce: 'pre',\n applyToEnvironment: (env) => env.name === VITE_ENVIRONMENT_NAMES.client,\n configureServer(server) {\n clientEnvironment = server.environments[VITE_ENVIRONMENT_NAMES.client]\n },\n config() {\n type LoadObjectHook = Extract<\n typeof clientTreePlugin.load,\n { filter?: unknown }\n >\n resolvedGeneratedRouteTreePath = normalizePath(\n getGeneratedRouteTreePath(),\n )\n ;(clientTreePlugin.load as LoadObjectHook).filter = {\n id: { include: new RegExp(resolvedGeneratedRouteTreePath) },\n }\n },\n\n load: {\n filter: {\n // this will be set in the config hook above since it relies on `config` hook being called first\n },\n async handler() {\n if (!generatorInstance) {\n throw new Error('Generator instance not initialized')\n }\n const crawlingResult = await generatorInstance.getCrawlingResult()\n if (!crawlingResult) {\n throw new Error('Crawling result not available')\n }\n const prunedAcc = pruneServerOnlySubtrees(crawlingResult)\n const acc = {\n ...crawlingResult.acc,\n ...prunedAcc,\n }\n const buildResult = generatorInstance.buildRouteTree({\n ...crawlingResult,\n acc,\n config: {\n // importRoutesUsingAbsolutePaths: true,\n // addExtensions: true,\n disableTypes: true,\n enableRouteTreeFormatting: false,\n routeTreeFileHeader: [],\n routeTreeFileFooter: [],\n },\n })\n return { code: buildResult.routeTreeContent, map: null }\n },\n },\n }\n return [\n clientTreePlugin,\n tanstackRouterGenerator(() => {\n const routerConfig = getConfig().startConfig.router\n const plugins = [clientTreeGeneratorPlugin, routesManifestPlugin()]\n if (startPluginOpts?.prerender?.enabled === true) {\n plugins.push(prerenderRoutesPlugin())\n }\n return {\n ...routerConfig,\n target: corePluginOpts.framework,\n routeTreeFileFooter: getRouteTreeFileFooter,\n plugins,\n }\n }),\n tanStackRouterCodeSplitter(() => {\n const routerConfig = getConfig().startConfig.router\n return {\n ...routerConfig,\n codeSplittingOptions: {\n ...routerConfig.codeSplittingOptions,\n deleteNodes: ['ssr', 'server', 'headers'],\n addHmr: true,\n },\n plugin: {\n vite: { environmentName: VITE_ENVIRONMENT_NAMES.client },\n },\n }\n }),\n tanStackRouterCodeSplitter(() => {\n const routerConfig = getConfig().startConfig.router\n return {\n ...routerConfig,\n codeSplittingOptions: {\n ...routerConfig.codeSplittingOptions,\n addHmr: false,\n },\n plugin: {\n vite: { environmentName: VITE_ENVIRONMENT_NAMES.server },\n },\n }\n }),\n tanstackRouterAutoImport(startPluginOpts?.router),\n ]\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sources":["../../../src/start-router-plugin/plugin.ts"],"sourcesContent":["import {\n tanStackRouterCodeSplitter,\n tanstackRouterAutoImport,\n tanstackRouterGenerator,\n} from '@tanstack/router-plugin/vite'\nimport { normalizePath } from 'vite'\nimport path from 'pathe'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { routesManifestPlugin } from './generator-plugins/routes-manifest-plugin'\nimport { prerenderRoutesPlugin } from './generator-plugins/prerender-routes-plugin'\nimport { pruneServerOnlySubtrees } from './pruneServerOnlySubtrees'\nimport { SERVER_PROP } from './constants'\nimport type { GetConfigFn, TanStackStartVitePluginCoreOptions } from '../types'\nimport type {\n Generator,\n GeneratorPlugin,\n RouteNode,\n} from '@tanstack/router-generator'\nimport type { DevEnvironment, Plugin, PluginOption } from 'vite'\nimport type { TanStackStartInputConfig } from '../schema'\n\nfunction isServerOnlyNode(node: RouteNode | undefined) {\n if (!node?.createFileRouteProps) {\n return false\n }\n return (\n node.createFileRouteProps.has(SERVER_PROP) &&\n node.createFileRouteProps.size === 1\n )\n}\n\nfunction moduleDeclaration({\n startFilePath,\n routerFilePath,\n corePluginOpts,\n generatedRouteTreePath,\n}: {\n startFilePath: string | undefined\n routerFilePath: string\n corePluginOpts: TanStackStartVitePluginCoreOptions\n generatedRouteTreePath: string\n}): string {\n function getImportPath(absolutePath: string) {\n let relativePath = path.relative(\n path.dirname(generatedRouteTreePath),\n absolutePath,\n )\n\n if (!relativePath.startsWith('.')) {\n relativePath = './' + relativePath\n }\n\n // convert to POSIX-style for ESM imports (important on Windows)\n relativePath = relativePath.split(path.sep).join('/')\n return relativePath\n }\n\n const result: Array<string> = [\n `import type { getRouter } from '${getImportPath(routerFilePath)}'`,\n ]\n if (startFilePath) {\n result.push(\n `import type { startInstance } from '${getImportPath(startFilePath)}'`,\n )\n }\n // make sure we import something from start to get the server route declaration merge\n else {\n result.push(\n `import type { createStart } from '@tanstack/${corePluginOpts.framework}-start'`,\n )\n }\n result.push(\n `declare module '@tanstack/${corePluginOpts.framework}-start' {\n interface Register {\n ssr: true\n router: Awaited<ReturnType<typeof getRouter>>`,\n )\n if (startFilePath) {\n result.push(\n ` config: Awaited<ReturnType<typeof startInstance.getOptions>>`,\n )\n }\n result.push(` }\n}`)\n\n return result.join('\\n')\n}\n\nexport function tanStackStartRouter(\n startPluginOpts: TanStackStartInputConfig,\n getConfig: GetConfigFn,\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n): Array<PluginOption> {\n const getGeneratedRouteTreePath = () => {\n const { startConfig } = getConfig()\n return path.resolve(startConfig.router.generatedRouteTree)\n }\n\n let clientEnvironment: DevEnvironment | null = null\n function invalidate() {\n if (!clientEnvironment) {\n return\n }\n\n const mod = clientEnvironment.moduleGraph.getModuleById(\n getGeneratedRouteTreePath(),\n )\n if (mod) {\n clientEnvironment.moduleGraph.invalidateModule(mod)\n }\n clientEnvironment.hot.send({ type: 'full-reload', path: '*' })\n }\n\n let generatorInstance: Generator | null = null\n\n const clientTreeGeneratorPlugin: GeneratorPlugin = {\n name: 'start-client-tree-plugin',\n init({ generator }) {\n generatorInstance = generator\n },\n afterTransform({ node, prevNode }) {\n if (isServerOnlyNode(node) !== isServerOnlyNode(prevNode)) {\n invalidate()\n }\n },\n }\n\n let routeTreeFileFooter: Array<string> | null = null\n\n function getRouteTreeFileFooter() {\n if (routeTreeFileFooter) {\n return routeTreeFileFooter\n }\n const { startConfig, resolvedStartConfig } = getConfig()\n const ogRouteTreeFileFooter = startConfig.router.routeTreeFileFooter\n if (ogRouteTreeFileFooter) {\n if (Array.isArray(ogRouteTreeFileFooter)) {\n routeTreeFileFooter = ogRouteTreeFileFooter\n } else {\n routeTreeFileFooter = ogRouteTreeFileFooter()\n }\n }\n routeTreeFileFooter = [\n moduleDeclaration({\n generatedRouteTreePath: getGeneratedRouteTreePath(),\n corePluginOpts,\n startFilePath: resolvedStartConfig.startFilePath,\n routerFilePath: resolvedStartConfig.routerFilePath,\n }),\n ...(routeTreeFileFooter ?? []),\n ]\n return routeTreeFileFooter\n }\n\n let resolvedGeneratedRouteTreePath: string | null = null\n const clientTreePlugin: Plugin = {\n name: 'tanstack-start:route-tree-client-plugin',\n enforce: 'pre',\n applyToEnvironment: (env) => env.name === VITE_ENVIRONMENT_NAMES.client,\n configureServer(server) {\n clientEnvironment = server.environments[VITE_ENVIRONMENT_NAMES.client]\n },\n config() {\n type LoadObjectHook = Extract<\n typeof clientTreePlugin.load,\n { filter?: unknown }\n >\n resolvedGeneratedRouteTreePath = normalizePath(\n getGeneratedRouteTreePath(),\n )\n ;(clientTreePlugin.load as LoadObjectHook).filter = {\n id: { include: new RegExp(resolvedGeneratedRouteTreePath) },\n }\n },\n\n load: {\n filter: {\n // this will be set in the config hook above since it relies on `config` hook being called first\n },\n async handler() {\n if (!generatorInstance) {\n throw new Error('Generator instance not initialized')\n }\n const crawlingResult = await generatorInstance.getCrawlingResult()\n if (!crawlingResult) {\n throw new Error('Crawling result not available')\n }\n const prunedAcc = pruneServerOnlySubtrees(crawlingResult)\n const acc = {\n ...crawlingResult.acc,\n ...prunedAcc,\n }\n const buildResult = generatorInstance.buildRouteTree({\n ...crawlingResult,\n acc,\n config: {\n // importRoutesUsingAbsolutePaths: true,\n // addExtensions: true,\n disableTypes: true,\n enableRouteTreeFormatting: false,\n routeTreeFileHeader: [],\n routeTreeFileFooter: [],\n },\n })\n return { code: buildResult.routeTreeContent, map: null }\n },\n },\n }\n return [\n clientTreePlugin,\n tanstackRouterGenerator(() => {\n const routerConfig = getConfig().startConfig.router\n const plugins = [clientTreeGeneratorPlugin, routesManifestPlugin()]\n if (startPluginOpts?.prerender?.enabled === true) {\n plugins.push(prerenderRoutesPlugin())\n }\n return {\n ...routerConfig,\n target: corePluginOpts.framework,\n routeTreeFileFooter: getRouteTreeFileFooter,\n plugins,\n }\n }),\n tanStackRouterCodeSplitter(() => {\n const routerConfig = getConfig().startConfig.router\n return {\n ...routerConfig,\n codeSplittingOptions: {\n ...routerConfig.codeSplittingOptions,\n deleteNodes: ['ssr', 'server', 'headers'],\n addHmr: true,\n },\n plugin: {\n vite: { environmentName: VITE_ENVIRONMENT_NAMES.client },\n },\n }\n }),\n tanStackRouterCodeSplitter(() => {\n const routerConfig = getConfig().startConfig.router\n return {\n ...routerConfig,\n codeSplittingOptions: {\n ...routerConfig.codeSplittingOptions,\n addHmr: false,\n },\n plugin: {\n vite: { environmentName: VITE_ENVIRONMENT_NAMES.server },\n },\n }\n }),\n tanstackRouterAutoImport(startPluginOpts?.router),\n ]\n}\n"],"names":[],"mappings":";;;;;;;;AAqBA,SAAS,iBAAiB,MAA6B;AACrD,MAAI,CAAC,MAAM,sBAAsB;AAC/B,WAAO;AAAA,EACT;AACA,SACE,KAAK,qBAAqB,IAAI,WAAW,KACzC,KAAK,qBAAqB,SAAS;AAEvC;AAEA,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKW;AACT,WAAS,cAAc,cAAsB;AAC3C,QAAI,eAAe,KAAK;AAAA,MACtB,KAAK,QAAQ,sBAAsB;AAAA,MACnC;AAAA,IAAA;AAGF,QAAI,CAAC,aAAa,WAAW,GAAG,GAAG;AACjC,qBAAe,OAAO;AAAA,IACxB;AAGA,mBAAe,aAAa,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AACpD,WAAO;AAAA,EACT;AAEA,QAAM,SAAwB;AAAA,IAC5B,mCAAmC,cAAc,cAAc,CAAC;AAAA,EAAA;AAElE,MAAI,eAAe;AACjB,WAAO;AAAA,MACL,uCAAuC,cAAc,aAAa,CAAC;AAAA,IAAA;AAAA,EAEvE,OAEK;AACH,WAAO;AAAA,MACL,+CAA+C,eAAe,SAAS;AAAA,IAAA;AAAA,EAE3E;AACA,SAAO;AAAA,IACL,6BAA6B,eAAe,SAAS;AAAA;AAAA;AAAA;AAAA,EAAA;AAKvD,MAAI,eAAe;AACjB,WAAO;AAAA,MACL;AAAA,IAAA;AAAA,EAEJ;AACA,SAAO,KAAK;AAAA,EACZ;AAEA,SAAO,OAAO,KAAK,IAAI;AACzB;AAEO,SAAS,oBACd,iBACA,WACA,gBACqB;AACrB,QAAM,4BAA4B,MAAM;AACtC,UAAM,EAAE,YAAA,IAAgB,UAAA;AACxB,WAAO,KAAK,QAAQ,YAAY,OAAO,kBAAkB;AAAA,EAC3D;AAEA,MAAI,oBAA2C;AAC/C,WAAS,aAAa;AACpB,QAAI,CAAC,mBAAmB;AACtB;AAAA,IACF;AAEA,UAAM,MAAM,kBAAkB,YAAY;AAAA,MACxC,0BAAA;AAAA,IAA0B;AAE5B,QAAI,KAAK;AACP,wBAAkB,YAAY,iBAAiB,GAAG;AAAA,IACpD;AACA,sBAAkB,IAAI,KAAK,EAAE,MAAM,eAAe,MAAM,KAAK;AAAA,EAC/D;AAEA,MAAI,oBAAsC;AAE1C,QAAM,4BAA6C;AAAA,IACjD,MAAM;AAAA,IACN,KAAK,EAAE,aAAa;AAClB,0BAAoB;AAAA,IACtB;AAAA,IACA,eAAe,EAAE,MAAM,YAAY;AACjC,UAAI,iBAAiB,IAAI,MAAM,iBAAiB,QAAQ,GAAG;AACzD,mBAAA;AAAA,MACF;AAAA,IACF;AAAA,EAAA;AAGF,MAAI,sBAA4C;AAEhD,WAAS,yBAAyB;AAChC,QAAI,qBAAqB;AACvB,aAAO;AAAA,IACT;AACA,UAAM,EAAE,aAAa,oBAAA,IAAwB,UAAA;AAC7C,UAAM,wBAAwB,YAAY,OAAO;AACjD,QAAI,uBAAuB;AACzB,UAAI,MAAM,QAAQ,qBAAqB,GAAG;AACxC,8BAAsB;AAAA,MACxB,OAAO;AACL,8BAAsB,sBAAA;AAAA,MACxB;AAAA,IACF;AACA,0BAAsB;AAAA,MACpB,kBAAkB;AAAA,QAChB,wBAAwB,0BAAA;AAAA,QACxB;AAAA,QACA,eAAe,oBAAoB;AAAA,QACnC,gBAAgB,oBAAoB;AAAA,MAAA,CACrC;AAAA,MACD,GAAI,uBAAuB,CAAA;AAAA,IAAC;AAE9B,WAAO;AAAA,EACT;AAEA,MAAI,iCAAgD;AACpD,QAAM,mBAA2B;AAAA,IAC/B,MAAM;AAAA,IACN,SAAS;AAAA,IACT,oBAAoB,CAAC,QAAQ,IAAI,SAAS,uBAAuB;AAAA,IACjE,gBAAgB,QAAQ;AACtB,0BAAoB,OAAO,aAAa,uBAAuB,MAAM;AAAA,IACvE;AAAA,IACA,SAAS;AAKP,uCAAiC;AAAA,QAC/B,0BAAA;AAAA,MAA0B;AAE1B,uBAAiB,KAAwB,SAAS;AAAA,QAClD,IAAI,EAAE,SAAS,IAAI,OAAO,8BAA8B,EAAA;AAAA,MAAE;AAAA,IAE9D;AAAA,IAEA,MAAM;AAAA,MACJ,QAAQ;AAAA;AAAA,MAAA;AAAA,MAGR,MAAM,UAAU;AACd,YAAI,CAAC,mBAAmB;AACtB,gBAAM,IAAI,MAAM,oCAAoC;AAAA,QACtD;AACA,cAAM,iBAAiB,MAAM,kBAAkB,kBAAA;AAC/C,YAAI,CAAC,gBAAgB;AACnB,gBAAM,IAAI,MAAM,+BAA+B;AAAA,QACjD;AACA,cAAM,YAAY,wBAAwB,cAAc;AACxD,cAAM,MAAM;AAAA,UACV,GAAG,eAAe;AAAA,UAClB,GAAG;AAAA,QAAA;AAEL,cAAM,cAAc,kBAAkB,eAAe;AAAA,UACnD,GAAG;AAAA,UACH;AAAA,UACA,QAAQ;AAAA;AAAA;AAAA,YAGN,cAAc;AAAA,YACd,2BAA2B;AAAA,YAC3B,qBAAqB,CAAA;AAAA,YACrB,qBAAqB,CAAA;AAAA,UAAC;AAAA,QACxB,CACD;AACD,eAAO,EAAE,MAAM,YAAY,kBAAkB,KAAK,KAAA;AAAA,MACpD;AAAA,IAAA;AAAA,EACF;AAEF,SAAO;AAAA,IACL;AAAA,IACA,wBAAwB,MAAM;AAC5B,YAAM,eAAe,YAAY,YAAY;AAC7C,YAAM,UAAU,CAAC,2BAA2B,sBAAsB;AAClE,UAAI,iBAAiB,WAAW,YAAY,MAAM;AAChD,gBAAQ,KAAK,uBAAuB;AAAA,MACtC;AACA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,QAAQ,eAAe;AAAA,QACvB,qBAAqB;AAAA,QACrB;AAAA,MAAA;AAAA,IAEJ,CAAC;AAAA,IACD,2BAA2B,MAAM;AAC/B,YAAM,eAAe,YAAY,YAAY;AAC7C,aAAO;AAAA,QACL,GAAG;AAAA,QACH,sBAAsB;AAAA,UACpB,GAAG,aAAa;AAAA,UAChB,aAAa,CAAC,OAAO,UAAU,SAAS;AAAA,UACxC,QAAQ;AAAA,QAAA;AAAA,QAEV,QAAQ;AAAA,UACN,MAAM,EAAE,iBAAiB,uBAAuB,OAAA;AAAA,QAAO;AAAA,MACzD;AAAA,IAEJ,CAAC;AAAA,IACD,2BAA2B,MAAM;AAC/B,YAAM,eAAe,YAAY,YAAY;AAC7C,aAAO;AAAA,QACL,GAAG;AAAA,QACH,sBAAsB;AAAA,UACpB,GAAG,aAAa;AAAA,UAChB,QAAQ;AAAA,QAAA;AAAA,QAEV,QAAQ;AAAA,UACN,MAAM,EAAE,iBAAiB,uBAAuB,OAAA;AAAA,QAAO;AAAA,MACzD;AAAA,IAEJ,CAAC;AAAA,IACD,yBAAyB,iBAAiB,MAAM;AAAA,EAAA;AAEpD;"}
@@ -0,0 +1,30 @@
1
+ import { TanStackStartOutputConfig } from './schema.js';
2
+ export type CompileStartFrameworkOptions = 'react' | 'solid' | 'vue';
3
+ export interface TanStackStartVitePluginCoreOptions {
4
+ framework: CompileStartFrameworkOptions;
5
+ defaultEntryPaths: {
6
+ client: string;
7
+ server: string;
8
+ start: string;
9
+ };
10
+ serverFn?: {
11
+ directive?: string;
12
+ ssr?: {
13
+ getServerFnById?: string;
14
+ };
15
+ providerEnv?: string;
16
+ };
17
+ }
18
+ export interface ResolvedStartConfig {
19
+ root: string;
20
+ startFilePath: string | undefined;
21
+ routerFilePath: string;
22
+ srcDirectory: string;
23
+ viteAppBase: string;
24
+ serverFnProviderEnv: string;
25
+ }
26
+ export type GetConfigFn = () => {
27
+ startConfig: TanStackStartOutputConfig;
28
+ resolvedStartConfig: ResolvedStartConfig;
29
+ corePluginOpts: TanStackStartVitePluginCoreOptions;
30
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/start-plugin-core",
3
- "version": "1.142.8",
3
+ "version": "1.142.11",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -59,13 +59,13 @@
59
59
  "vitefu": "^1.1.1",
60
60
  "xmlbuilder2": "^4.0.0",
61
61
  "zod": "^3.24.2",
62
- "@tanstack/router-core": "1.142.8",
63
- "@tanstack/router-generator": "1.142.8",
64
- "@tanstack/router-plugin": "1.142.8",
65
- "@tanstack/server-functions-plugin": "1.142.1",
62
+ "@tanstack/router-core": "1.142.11",
66
63
  "@tanstack/router-utils": "1.141.0",
67
- "@tanstack/start-client-core": "1.142.8",
68
- "@tanstack/start-server-core": "1.142.8"
64
+ "@tanstack/server-functions-plugin": "1.142.1",
65
+ "@tanstack/router-generator": "1.142.11",
66
+ "@tanstack/router-plugin": "1.142.11",
67
+ "@tanstack/start-client-core": "1.142.11",
68
+ "@tanstack/start-server-core": "1.142.11"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/babel__code-frame": "^7.0.6",
@@ -8,6 +8,8 @@ import {
8
8
  } from 'babel-dead-code-elimination'
9
9
  import { handleCreateServerFn } from './handleCreateServerFn'
10
10
  import { handleCreateMiddleware } from './handleCreateMiddleware'
11
+ import { handleCreateIsomorphicFn } from './handleCreateIsomorphicFn'
12
+ import { handleEnvOnlyFn } from './handleEnvOnly'
11
13
  import type { MethodChainPaths, RewriteCandidate } from './types'
12
14
 
13
15
  type Binding =
@@ -30,36 +32,68 @@ type ExportEntry =
30
32
 
31
33
  type Kind = 'None' | `Root` | `Builder` | LookupKind
32
34
 
33
- export type LookupKind = 'ServerFn' | 'Middleware'
35
+ export type LookupKind =
36
+ | 'ServerFn'
37
+ | 'Middleware'
38
+ | 'IsomorphicFn'
39
+ | 'ServerOnlyFn'
40
+ | 'ClientOnlyFn'
41
+
42
+ // Detection strategy for each kind
43
+ type MethodChainSetup = {
44
+ type: 'methodChain'
45
+ candidateCallIdentifier: Set<string>
46
+ // If true, a call to the root function (e.g., createIsomorphicFn()) is also a candidate
47
+ // even without chained method calls. This is used for IsomorphicFn which can be
48
+ // called without .client() or .server() (resulting in a no-op function).
49
+ allowRootAsCandidate?: boolean
50
+ }
51
+ type DirectCallSetup = { type: 'directCall' }
34
52
 
35
- const LookupSetup: Record<
36
- LookupKind,
37
- { candidateCallIdentifier: Set<string> }
38
- > = {
39
- ServerFn: { candidateCallIdentifier: new Set(['handler']) },
53
+ const LookupSetup: Record<LookupKind, MethodChainSetup | DirectCallSetup> = {
54
+ ServerFn: {
55
+ type: 'methodChain',
56
+ candidateCallIdentifier: new Set(['handler']),
57
+ },
40
58
  Middleware: {
59
+ type: 'methodChain',
41
60
  candidateCallIdentifier: new Set(['server', 'client', 'createMiddlewares']),
42
61
  },
62
+ IsomorphicFn: {
63
+ type: 'methodChain',
64
+ candidateCallIdentifier: new Set(['server', 'client']),
65
+ allowRootAsCandidate: true, // createIsomorphicFn() alone is valid (returns no-op)
66
+ },
67
+ ServerOnlyFn: { type: 'directCall' },
68
+ ClientOnlyFn: { type: 'directCall' },
43
69
  }
44
70
 
45
- // Pre-computed map: identifier name -> LookupKind for fast candidate detection
46
- const IdentifierToKind = new Map<string, LookupKind>()
71
+ // Pre-computed map: identifier name -> Set<LookupKind> for fast candidate detection (method chain only)
72
+ // Multiple kinds can share the same identifier (e.g., 'server' and 'client' are used by both Middleware and IsomorphicFn)
73
+ const IdentifierToKinds = new Map<string, Set<LookupKind>>()
47
74
  for (const [kind, setup] of Object.entries(LookupSetup) as Array<
48
- [LookupKind, { candidateCallIdentifier: Set<string> }]
75
+ [LookupKind, MethodChainSetup | DirectCallSetup]
49
76
  >) {
50
- for (const id of setup.candidateCallIdentifier) {
51
- IdentifierToKind.set(id, kind)
77
+ if (setup.type === 'methodChain') {
78
+ for (const id of setup.candidateCallIdentifier) {
79
+ let kinds = IdentifierToKinds.get(id)
80
+ if (!kinds) {
81
+ kinds = new Set()
82
+ IdentifierToKinds.set(id, kinds)
83
+ }
84
+ kinds.add(kind)
85
+ }
52
86
  }
53
87
  }
54
88
 
55
89
  export type LookupConfig = {
56
90
  libName: string
57
91
  rootExport: string
92
+ kind: LookupKind | 'Root' // 'Root' for builder pattern, LookupKind for direct call
58
93
  }
94
+
59
95
  interface ModuleInfo {
60
96
  id: string
61
- code: string
62
- ast: ReturnType<typeof parseAst>
63
97
  bindings: Map<string, Binding>
64
98
  exports: Map<string, ExportEntry>
65
99
  // Track `export * from './module'` declarations for re-export resolution
@@ -70,6 +104,9 @@ export class ServerFnCompiler {
70
104
  private moduleCache = new Map<string, ModuleInfo>()
71
105
  private initialized = false
72
106
  private validLookupKinds: Set<LookupKind>
107
+ // Precomputed flags for candidate detection (avoid recomputing on each collectCandidates call)
108
+ private hasDirectCallKinds: boolean
109
+ private hasRootAsCandidateKinds: boolean
73
110
  // Fast lookup for direct imports from known libraries (e.g., '@tanstack/react-start')
74
111
  // Maps: libName → (exportName → Kind)
75
112
  // This allows O(1) resolution for the common case without async resolveId calls
@@ -85,12 +122,44 @@ export class ServerFnCompiler {
85
122
  },
86
123
  ) {
87
124
  this.validLookupKinds = options.lookupKinds
125
+
126
+ // Precompute flags for candidate detection
127
+ this.hasDirectCallKinds = false
128
+ this.hasRootAsCandidateKinds = false
129
+ for (const kind of options.lookupKinds) {
130
+ const setup = LookupSetup[kind]
131
+ if (setup.type === 'directCall') {
132
+ this.hasDirectCallKinds = true
133
+ } else if (setup.allowRootAsCandidate) {
134
+ this.hasRootAsCandidateKinds = true
135
+ }
136
+ }
88
137
  }
89
138
 
90
- private async init(id: string) {
139
+ private async init() {
140
+ // Register internal stub package exports for recognition.
141
+ // These don't need module resolution - only the knownRootImports fast path.
142
+ this.knownRootImports.set(
143
+ '@tanstack/start-fn-stubs',
144
+ new Map<string, Kind>([
145
+ ['createIsomorphicFn', 'IsomorphicFn'],
146
+ ['createServerOnlyFn', 'ServerOnlyFn'],
147
+ ['createClientOnlyFn', 'ClientOnlyFn'],
148
+ ]),
149
+ )
150
+
91
151
  await Promise.all(
92
152
  this.options.lookupConfigurations.map(async (config) => {
93
- const libId = await this.options.resolveId(config.libName, id)
153
+ // Populate the fast lookup map for direct imports (by package name)
154
+ // This allows O(1) recognition of imports from known packages.
155
+ let libExports = this.knownRootImports.get(config.libName)
156
+ if (!libExports) {
157
+ libExports = new Map()
158
+ this.knownRootImports.set(config.libName, libExports)
159
+ }
160
+ libExports.set(config.rootExport, config.kind)
161
+
162
+ const libId = await this.options.resolveId(config.libName)
94
163
  if (!libId) {
95
164
  throw new Error(`could not resolve "${config.libName}"`)
96
165
  }
@@ -98,10 +167,8 @@ export class ServerFnCompiler {
98
167
  if (!rootModule) {
99
168
  // insert root binding
100
169
  rootModule = {
101
- ast: null as any,
102
170
  bindings: new Map(),
103
171
  exports: new Map(),
104
- code: '',
105
172
  id: libId,
106
173
  reExportAllSources: [],
107
174
  }
@@ -119,18 +186,10 @@ export class ServerFnCompiler {
119
186
  })
120
187
  rootModule.bindings.set(config.rootExport, {
121
188
  type: 'var',
122
- init: t.identifier(config.rootExport),
123
- resolvedKind: `Root` satisfies Kind,
189
+ init: null, // Not needed since resolvedKind is set
190
+ resolvedKind: config.kind satisfies Kind,
124
191
  })
125
192
  this.moduleCache.set(libId, rootModule)
126
-
127
- // Also populate the fast lookup map for direct imports
128
- let libExports = this.knownRootImports.get(config.libName)
129
- if (!libExports) {
130
- libExports = new Map()
131
- this.knownRootImports.set(config.libName, libExports)
132
- }
133
- libExports.set(config.rootExport, 'Root')
134
193
  }),
135
194
  )
136
195
 
@@ -234,15 +293,13 @@ export class ServerFnCompiler {
234
293
  }
235
294
 
236
295
  const info: ModuleInfo = {
237
- code,
238
296
  id,
239
- ast,
240
297
  bindings,
241
298
  exports,
242
299
  reExportAllSources,
243
300
  }
244
301
  this.moduleCache.set(id, info)
245
- return info
302
+ return { info, ast }
246
303
  }
247
304
 
248
305
  public invalidateModule(id: string) {
@@ -259,10 +316,10 @@ export class ServerFnCompiler {
259
316
  isProviderFile: boolean
260
317
  }) {
261
318
  if (!this.initialized) {
262
- await this.init(id)
319
+ await this.init()
263
320
  }
264
- const { bindings, ast } = this.ingestModule({ code, id })
265
- const candidates = this.collectCandidates(bindings)
321
+ const { info, ast } = this.ingestModule({ code, id })
322
+ const candidates = this.collectCandidates(info.bindings)
266
323
  if (candidates.length === 0) {
267
324
  // this hook will only be invoked if there is `.handler(` | `.server(` | `.client(` in the code,
268
325
  // so not discovering a handler candidate is rather unlikely, but maybe possible?
@@ -378,10 +435,20 @@ export class ServerFnCompiler {
378
435
  directive: this.options.directive,
379
436
  isProviderFile,
380
437
  })
381
- } else {
438
+ } else if (kind === 'Middleware') {
382
439
  handleCreateMiddleware(candidate, {
383
440
  env: this.options.env,
384
441
  })
442
+ } else if (kind === 'IsomorphicFn') {
443
+ handleCreateIsomorphicFn(candidate, {
444
+ env: this.options.env,
445
+ })
446
+ } else {
447
+ // ServerOnlyFn or ClientOnlyFn
448
+ handleEnvOnlyFn(candidate, {
449
+ env: this.options.env,
450
+ kind,
451
+ })
385
452
  }
386
453
  }
387
454
 
@@ -399,13 +466,31 @@ export class ServerFnCompiler {
399
466
  const candidates: Array<t.CallExpression> = []
400
467
 
401
468
  for (const binding of bindings.values()) {
402
- if (binding.type === 'var') {
403
- const candidate = isCandidateCallExpression(
469
+ if (binding.type === 'var' && t.isCallExpression(binding.init)) {
470
+ // Pattern 1: Method chain pattern (.handler(), .server(), etc.)
471
+ const methodChainCandidate = isCandidateCallExpression(
404
472
  binding.init,
405
473
  this.validLookupKinds,
406
474
  )
407
- if (candidate) {
408
- candidates.push(candidate)
475
+ if (methodChainCandidate) {
476
+ candidates.push(methodChainCandidate)
477
+ continue
478
+ }
479
+
480
+ // Pattern 2: Direct call pattern
481
+ // Handles:
482
+ // - createServerOnlyFn(), createClientOnlyFn() (direct call kinds)
483
+ // - createIsomorphicFn() (root-as-candidate kinds)
484
+ // - TanStackStart.createServerOnlyFn() (namespace calls)
485
+ if (this.hasDirectCallKinds || this.hasRootAsCandidateKinds) {
486
+ if (
487
+ t.isIdentifier(binding.init.callee) ||
488
+ (t.isMemberExpression(binding.init.callee) &&
489
+ t.isIdentifier(binding.init.callee.property))
490
+ ) {
491
+ // Include as candidate - kind resolution will verify it's actually a known export
492
+ candidates.push(binding.init)
493
+ }
409
494
  }
410
495
  }
411
496
  }
@@ -617,25 +702,40 @@ export class ServerFnCompiler {
617
702
  if (t.isMemberExpression(callee) && t.isIdentifier(callee.property)) {
618
703
  const prop = callee.property.name
619
704
 
620
- if (
621
- this.validLookupKinds.has('ServerFn') &&
622
- LookupSetup['ServerFn'].candidateCallIdentifier.has(prop)
623
- ) {
624
- const base = await this.resolveExprKind(callee.object, fileId, visited)
625
- if (base === 'Root' || base === 'Builder') {
626
- return 'ServerFn'
627
- }
628
- return 'None'
629
- } else if (
630
- this.validLookupKinds.has('Middleware') &&
631
- LookupSetup['Middleware'].candidateCallIdentifier.has(prop)
632
- ) {
705
+ // Check if this property matches any method chain pattern
706
+ const possibleKinds = IdentifierToKinds.get(prop)
707
+ if (possibleKinds) {
708
+ // Resolve base expression ONCE and reuse for all pattern checks
633
709
  const base = await this.resolveExprKind(callee.object, fileId, visited)
634
- if (base === 'Root' || base === 'Builder' || base === 'Middleware') {
635
- return 'Middleware'
710
+
711
+ // Check each possible kind that uses this identifier
712
+ for (const kind of possibleKinds) {
713
+ if (!this.validLookupKinds.has(kind)) continue
714
+
715
+ if (kind === 'ServerFn') {
716
+ if (base === 'Root' || base === 'Builder') {
717
+ return 'ServerFn'
718
+ }
719
+ } else if (kind === 'Middleware') {
720
+ if (
721
+ base === 'Root' ||
722
+ base === 'Builder' ||
723
+ base === 'Middleware'
724
+ ) {
725
+ return 'Middleware'
726
+ }
727
+ } else if (kind === 'IsomorphicFn') {
728
+ if (
729
+ base === 'Root' ||
730
+ base === 'Builder' ||
731
+ base === 'IsomorphicFn'
732
+ ) {
733
+ return 'IsomorphicFn'
734
+ }
735
+ }
636
736
  }
637
- return 'None'
638
737
  }
738
+
639
739
  // Check if the object is a namespace import
640
740
  if (t.isIdentifier(callee.object)) {
641
741
  const info = await this.getModuleInfo(fileId)
@@ -704,10 +804,16 @@ function isCandidateCallExpression(
704
804
  return undefined
705
805
  }
706
806
 
707
- // Use pre-computed map for O(1) lookup instead of iterating over lookupKinds
708
- const kind = IdentifierToKind.get(callee.property.name)
709
- if (kind && lookupKinds.has(kind)) {
710
- return node
807
+ // Use pre-computed map for O(1) lookup
808
+ // IdentifierToKinds maps identifier -> Set<LookupKind> to handle shared identifiers
809
+ const possibleKinds = IdentifierToKinds.get(callee.property.name)
810
+ if (possibleKinds) {
811
+ // Check if any of the possible kinds are in the valid lookup kinds
812
+ for (const kind of possibleKinds) {
813
+ if (lookupKinds.has(kind)) {
814
+ return node
815
+ }
816
+ }
711
817
  }
712
818
 
713
819
  return undefined
@@ -0,0 +1,46 @@
1
+ import * as t from '@babel/types'
2
+ import type { RewriteCandidate } from './types'
3
+
4
+ export function handleCreateIsomorphicFn(
5
+ candidate: RewriteCandidate,
6
+ opts: { env: 'client' | 'server' },
7
+ ) {
8
+ const { path, methodChain } = candidate
9
+
10
+ // Get the environment-specific call (.client() or .server())
11
+ const envCallInfo =
12
+ opts.env === 'client' ? methodChain.client : methodChain.server
13
+
14
+ // Check if we have any implementation at all
15
+ if (!methodChain.client && !methodChain.server) {
16
+ // No implementations provided - warn and replace with no-op
17
+ const variableId = path.parentPath.isVariableDeclarator()
18
+ ? path.parentPath.node.id
19
+ : null
20
+ console.warn(
21
+ 'createIsomorphicFn called without a client or server implementation!',
22
+ 'This will result in a no-op function.',
23
+ 'Variable name:',
24
+ t.isIdentifier(variableId) ? variableId.name : 'unknown',
25
+ )
26
+ path.replaceWith(t.arrowFunctionExpression([], t.blockStatement([])))
27
+ return
28
+ }
29
+
30
+ if (!envCallInfo) {
31
+ // No implementation for this environment - replace with no-op
32
+ path.replaceWith(t.arrowFunctionExpression([], t.blockStatement([])))
33
+ return
34
+ }
35
+
36
+ // Extract the function argument from the environment-specific call
37
+ const innerFn = envCallInfo.firstArgPath?.node
38
+
39
+ if (!t.isExpression(innerFn)) {
40
+ throw new Error(
41
+ `createIsomorphicFn().${opts.env}(func) must be called with a function!`,
42
+ )
43
+ }
44
+
45
+ path.replaceWith(innerFn)
46
+ }
@@ -1,5 +1,5 @@
1
1
  import * as t from '@babel/types'
2
- import { codeFrameError } from '../start-compiler-plugin/utils'
2
+ import { codeFrameError } from './utils'
3
3
  import type { RewriteCandidate } from './types'
4
4
 
5
5
  /**