@tanstack/start-plugin-core 1.169.11 → 1.169.13

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 (43) hide show
  1. package/dist/esm/index.d.ts +1 -1
  2. package/dist/esm/rsbuild/index.d.ts +1 -0
  3. package/dist/esm/rsbuild/plugin.js +2 -0
  4. package/dist/esm/rsbuild/plugin.js.map +1 -1
  5. package/dist/esm/rsbuild/schema.d.ts +27 -27
  6. package/dist/esm/rsbuild/start-compiler-host.d.ts +3 -1
  7. package/dist/esm/rsbuild/start-compiler-host.js +6 -2
  8. package/dist/esm/rsbuild/start-compiler-host.js.map +1 -1
  9. package/dist/esm/schema.d.ts +51 -51
  10. package/dist/esm/start-compiler/compiler.d.ts +21 -5
  11. package/dist/esm/start-compiler/compiler.js +197 -48
  12. package/dist/esm/start-compiler/compiler.js.map +1 -1
  13. package/dist/esm/start-compiler/config.d.ts +7 -3
  14. package/dist/esm/start-compiler/config.js +19 -7
  15. package/dist/esm/start-compiler/config.js.map +1 -1
  16. package/dist/esm/start-compiler/handleCreateServerFn.js +12 -0
  17. package/dist/esm/start-compiler/handleCreateServerFn.js.map +1 -1
  18. package/dist/esm/start-compiler/host.d.ts +3 -1
  19. package/dist/esm/start-compiler/host.js +5 -3
  20. package/dist/esm/start-compiler/host.js.map +1 -1
  21. package/dist/esm/start-compiler/types.d.ts +4 -13
  22. package/dist/esm/types.d.ts +33 -0
  23. package/dist/esm/vite/index.d.ts +1 -0
  24. package/dist/esm/vite/plugin.js +2 -0
  25. package/dist/esm/vite/plugin.js.map +1 -1
  26. package/dist/esm/vite/schema.d.ts +27 -27
  27. package/dist/esm/vite/start-compiler-plugin/plugin.d.ts +3 -1
  28. package/dist/esm/vite/start-compiler-plugin/plugin.js +6 -2
  29. package/dist/esm/vite/start-compiler-plugin/plugin.js.map +1 -1
  30. package/package.json +6 -6
  31. package/src/index.ts +6 -1
  32. package/src/rsbuild/index.ts +5 -0
  33. package/src/rsbuild/plugin.ts +3 -0
  34. package/src/rsbuild/start-compiler-host.ts +22 -3
  35. package/src/start-compiler/compiler.ts +389 -70
  36. package/src/start-compiler/config.ts +43 -6
  37. package/src/start-compiler/handleCreateServerFn.ts +29 -0
  38. package/src/start-compiler/host.ts +13 -3
  39. package/src/start-compiler/types.ts +5 -14
  40. package/src/types.ts +44 -0
  41. package/src/vite/index.ts +5 -0
  42. package/src/vite/plugin.ts +3 -0
  43. package/src/vite/start-compiler-plugin/plugin.ts +22 -3
@@ -1,5 +1,5 @@
1
1
  import { StartCompiler } from './compiler.js';
2
- import { CompileStartFrameworkOptions } from '../types.js';
2
+ import { CompileStartFrameworkOptions, StartCompilerImportTransform } from '../types.js';
3
3
  import { DevServerFnModuleSpecifierEncoder, GenerateFunctionIdFnOptional, ServerFn } from './types.js';
4
4
  export interface CreateStartCompilerOptions {
5
5
  env: 'client' | 'server';
@@ -9,6 +9,8 @@ export interface CreateStartCompilerOptions {
9
9
  providerEnvName: string;
10
10
  mode: 'dev' | 'build';
11
11
  generateFunctionId?: GenerateFunctionIdFnOptional;
12
+ compilerTransforms?: Array<StartCompilerImportTransform> | undefined;
13
+ serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined;
12
14
  onServerFnsById?: (d: Record<string, ServerFn>) => void;
13
15
  getKnownServerFns: () => Record<string, ServerFn>;
14
16
  encodeModuleSpecifierInDev?: DevServerFnModuleSpecifierEncoder;
@@ -1,4 +1,4 @@
1
- import { LookupKindsPerEnv, StartCompiler } from "./compiler.js";
1
+ import { StartCompiler, getLookupKindsForEnv } from "./compiler.js";
2
2
  import { getLookupConfigurationsForEnv } from "./config.js";
3
3
  //#region src/start-compiler/host.ts
4
4
  function createStartCompiler(options) {
@@ -6,13 +6,15 @@ function createStartCompiler(options) {
6
6
  env: options.env,
7
7
  envName: options.envName,
8
8
  root: options.root,
9
- lookupKinds: LookupKindsPerEnv[options.env],
10
- lookupConfigurations: getLookupConfigurationsForEnv(options.env, options.framework),
9
+ lookupKinds: getLookupKindsForEnv(options.env, { compilerTransforms: options.compilerTransforms }),
10
+ lookupConfigurations: getLookupConfigurationsForEnv(options.env, options.framework, { compilerTransforms: options.compilerTransforms }),
11
11
  mode: options.mode,
12
12
  framework: options.framework,
13
13
  providerEnvName: options.providerEnvName,
14
14
  generateFunctionId: options.generateFunctionId,
15
15
  onServerFnsById: options.onServerFnsById,
16
+ compilerTransforms: options.compilerTransforms,
17
+ serverFnProviderModuleDirectives: options.serverFnProviderModuleDirectives,
16
18
  getKnownServerFns: options.getKnownServerFns,
17
19
  devServerFnModuleSpecifierEncoder: options.encodeModuleSpecifierInDev,
18
20
  loadModule: options.loadModule,
@@ -1 +1 @@
1
- {"version":3,"file":"host.js","names":[],"sources":["../../../src/start-compiler/host.ts"],"sourcesContent":["import { LookupKindsPerEnv, StartCompiler } from './compiler'\nimport { getLookupConfigurationsForEnv } from './config'\nimport type { CompileStartFrameworkOptions } from '../types'\nimport type {\n DevServerFnModuleSpecifierEncoder,\n GenerateFunctionIdFnOptional,\n ServerFn,\n} from './types'\n\nexport interface CreateStartCompilerOptions {\n env: 'client' | 'server'\n envName: string\n root: string\n framework: CompileStartFrameworkOptions\n providerEnvName: string\n mode: 'dev' | 'build'\n generateFunctionId?: GenerateFunctionIdFnOptional\n onServerFnsById?: (d: Record<string, ServerFn>) => void\n getKnownServerFns: () => Record<string, ServerFn>\n encodeModuleSpecifierInDev?: DevServerFnModuleSpecifierEncoder\n loadModule: (id: string) => Promise<void>\n resolveId: (id: string, importer?: string) => Promise<string | null>\n}\n\nexport function createStartCompiler(\n options: CreateStartCompilerOptions,\n): StartCompiler {\n return new StartCompiler({\n env: options.env,\n envName: options.envName,\n root: options.root,\n lookupKinds: LookupKindsPerEnv[options.env],\n lookupConfigurations: getLookupConfigurationsForEnv(\n options.env,\n options.framework,\n ),\n mode: options.mode,\n framework: options.framework,\n providerEnvName: options.providerEnvName,\n generateFunctionId: options.generateFunctionId,\n onServerFnsById: options.onServerFnsById,\n getKnownServerFns: options.getKnownServerFns,\n devServerFnModuleSpecifierEncoder: options.encodeModuleSpecifierInDev,\n loadModule: options.loadModule,\n resolveId: options.resolveId,\n })\n}\n\nexport function mergeServerFnsById(\n current: Record<string, ServerFn>,\n next: Record<string, ServerFn>,\n): void {\n for (const [id, fn] of Object.entries(next)) {\n const existing = current[id]\n\n if (existing) {\n current[id] = {\n ...fn,\n isClientReferenced:\n existing.isClientReferenced || fn.isClientReferenced,\n }\n continue\n }\n\n current[id] = fn\n }\n}\n\nexport function matchesCodeFilters(\n code: string,\n filters: ReadonlyArray<RegExp>,\n): boolean {\n for (const pattern of filters) {\n if (pattern.test(code)) {\n return true\n }\n }\n\n return false\n}\n"],"mappings":";;;AAwBA,SAAgB,oBACd,SACe;AACf,QAAO,IAAI,cAAc;EACvB,KAAK,QAAQ;EACb,SAAS,QAAQ;EACjB,MAAM,QAAQ;EACd,aAAa,kBAAkB,QAAQ;EACvC,sBAAsB,8BACpB,QAAQ,KACR,QAAQ,UACT;EACD,MAAM,QAAQ;EACd,WAAW,QAAQ;EACnB,iBAAiB,QAAQ;EACzB,oBAAoB,QAAQ;EAC5B,iBAAiB,QAAQ;EACzB,mBAAmB,QAAQ;EAC3B,mCAAmC,QAAQ;EAC3C,YAAY,QAAQ;EACpB,WAAW,QAAQ;EACpB,CAAC;;AAGJ,SAAgB,mBACd,SACA,MACM;AACN,MAAK,MAAM,CAAC,IAAI,OAAO,OAAO,QAAQ,KAAK,EAAE;EAC3C,MAAM,WAAW,QAAQ;AAEzB,MAAI,UAAU;AACZ,WAAQ,MAAM;IACZ,GAAG;IACH,oBACE,SAAS,sBAAsB,GAAG;IACrC;AACD;;AAGF,UAAQ,MAAM;;;AAIlB,SAAgB,mBACd,MACA,SACS;AACT,MAAK,MAAM,WAAW,QACpB,KAAI,QAAQ,KAAK,KAAK,CACpB,QAAO;AAIX,QAAO"}
1
+ {"version":3,"file":"host.js","names":[],"sources":["../../../src/start-compiler/host.ts"],"sourcesContent":["import { StartCompiler, getLookupKindsForEnv } from './compiler'\nimport { getLookupConfigurationsForEnv } from './config'\nimport type {\n CompileStartFrameworkOptions,\n StartCompilerImportTransform,\n} from '../types'\nimport type {\n DevServerFnModuleSpecifierEncoder,\n GenerateFunctionIdFnOptional,\n ServerFn,\n} from './types'\n\nexport interface CreateStartCompilerOptions {\n env: 'client' | 'server'\n envName: string\n root: string\n framework: CompileStartFrameworkOptions\n providerEnvName: string\n mode: 'dev' | 'build'\n generateFunctionId?: GenerateFunctionIdFnOptional\n compilerTransforms?: Array<StartCompilerImportTransform> | undefined\n serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined\n onServerFnsById?: (d: Record<string, ServerFn>) => void\n getKnownServerFns: () => Record<string, ServerFn>\n encodeModuleSpecifierInDev?: DevServerFnModuleSpecifierEncoder\n loadModule: (id: string) => Promise<void>\n resolveId: (id: string, importer?: string) => Promise<string | null>\n}\n\nexport function createStartCompiler(\n options: CreateStartCompilerOptions,\n): StartCompiler {\n return new StartCompiler({\n env: options.env,\n envName: options.envName,\n root: options.root,\n lookupKinds: getLookupKindsForEnv(options.env, {\n compilerTransforms: options.compilerTransforms,\n }),\n lookupConfigurations: getLookupConfigurationsForEnv(\n options.env,\n options.framework,\n { compilerTransforms: options.compilerTransforms },\n ),\n mode: options.mode,\n framework: options.framework,\n providerEnvName: options.providerEnvName,\n generateFunctionId: options.generateFunctionId,\n onServerFnsById: options.onServerFnsById,\n compilerTransforms: options.compilerTransforms,\n serverFnProviderModuleDirectives: options.serverFnProviderModuleDirectives,\n getKnownServerFns: options.getKnownServerFns,\n devServerFnModuleSpecifierEncoder: options.encodeModuleSpecifierInDev,\n loadModule: options.loadModule,\n resolveId: options.resolveId,\n })\n}\n\nexport function mergeServerFnsById(\n current: Record<string, ServerFn>,\n next: Record<string, ServerFn>,\n): void {\n for (const [id, fn] of Object.entries(next)) {\n const existing = current[id]\n\n if (existing) {\n current[id] = {\n ...fn,\n isClientReferenced:\n existing.isClientReferenced || fn.isClientReferenced,\n }\n continue\n }\n\n current[id] = fn\n }\n}\n\nexport function matchesCodeFilters(\n code: string,\n filters: ReadonlyArray<RegExp>,\n): boolean {\n for (const pattern of filters) {\n if (pattern.test(code)) {\n return true\n }\n }\n\n return false\n}\n"],"mappings":";;;AA6BA,SAAgB,oBACd,SACe;AACf,QAAO,IAAI,cAAc;EACvB,KAAK,QAAQ;EACb,SAAS,QAAQ;EACjB,MAAM,QAAQ;EACd,aAAa,qBAAqB,QAAQ,KAAK,EAC7C,oBAAoB,QAAQ,oBAC7B,CAAC;EACF,sBAAsB,8BACpB,QAAQ,KACR,QAAQ,WACR,EAAE,oBAAoB,QAAQ,oBAAoB,CACnD;EACD,MAAM,QAAQ;EACd,WAAW,QAAQ;EACnB,iBAAiB,QAAQ;EACzB,oBAAoB,QAAQ;EAC5B,iBAAiB,QAAQ;EACzB,oBAAoB,QAAQ;EAC5B,kCAAkC,QAAQ;EAC1C,mBAAmB,QAAQ;EAC3B,mCAAmC,QAAQ;EAC3C,YAAY,QAAQ;EACpB,WAAW,QAAQ;EACpB,CAAC;;AAGJ,SAAgB,mBACd,SACA,MACM;AACN,MAAK,MAAM,CAAC,IAAI,OAAO,OAAO,QAAQ,KAAK,EAAE;EAC3C,MAAM,WAAW,QAAQ;AAEzB,MAAI,UAAU;AACZ,WAAQ,MAAM;IACZ,GAAG;IACH,oBACE,SAAS,sBAAsB,GAAG;IACrC;AACD;;AAGF,UAAQ,MAAM;;;AAIlB,SAAgB,mBACd,MACA,SACS;AACT,MAAK,MAAM,WAAW,QACpB,KAAI,QAAQ,KAAK,KAAK,CACpB,QAAO;AAIX,QAAO"}
@@ -1,26 +1,17 @@
1
- import { CompileStartFrameworkOptions } from '../types.js';
1
+ import { StartCompilerTransformContext } from '../types.js';
2
2
  import type * as babel from '@babel/core';
3
3
  import type * as t from '@babel/types';
4
4
  /**
5
5
  * Context passed to all plugin handlers during compilation.
6
6
  * Contains both read-only input data and mutable state that handlers update.
7
7
  */
8
- export interface CompilationContext {
9
- readonly ast: t.File;
10
- readonly code: string;
11
- readonly id: string;
12
- readonly env: 'client' | 'server';
13
- readonly envName: string;
14
- readonly mode: 'dev' | 'build';
15
- readonly root: string;
16
- /** The framework being used (e.g., 'react', 'solid') */
17
- readonly framework: CompileStartFrameworkOptions;
18
- /** The Vite environment name for the server function provider */
19
- readonly providerEnvName: string;
8
+ export interface CompilationContext extends StartCompilerTransformContext {
20
9
  /** Generate a unique function ID */
21
10
  generateFunctionId: GenerateFunctionIdFn;
22
11
  /** Get known server functions from previous builds (e.g., client build) */
23
12
  getKnownServerFns: () => Record<string, ServerFn>;
13
+ /** Module-level directives to add to extracted server function provider files. */
14
+ serverFnProviderModuleDirectives: ReadonlyArray<string> | undefined;
24
15
  /**
25
16
  * Callback when server functions are discovered.
26
17
  * Called after each file is compiled with its new functions.
@@ -1,4 +1,6 @@
1
1
  import { TanStackStartOutputConfig } from './schema.js';
2
+ import type * as babel from '@babel/core';
3
+ import type * as t from '@babel/types';
2
4
  export type CompileStartFrameworkOptions = 'react' | 'solid' | 'vue';
3
5
  export type ServerFnLookupAccess = {
4
6
  origin: 'client';
@@ -13,6 +15,35 @@ export interface SerializationAdapterModuleRef {
13
15
  }
14
16
  export type SerializationAdapterByRuntime = Partial<Record<SerializationRuntime, SerializationAdapterModuleRef>>;
15
17
  export type SerializationAdapterConfig = SerializationAdapterModuleRef | SerializationAdapterByRuntime;
18
+ export type StartCompilerEnvironment = 'client' | 'server';
19
+ export interface StartCompilerImportTransformImport {
20
+ libName: string;
21
+ rootExport: string;
22
+ }
23
+ export interface StartCompilerTransformCandidate {
24
+ path: babel.NodePath<t.CallExpression>;
25
+ }
26
+ export interface StartCompilerTransformContext {
27
+ readonly ast: t.File;
28
+ readonly code: string;
29
+ readonly id: string;
30
+ readonly env: StartCompilerEnvironment;
31
+ readonly envName: string;
32
+ readonly mode: 'dev' | 'build';
33
+ readonly root: string;
34
+ readonly framework: CompileStartFrameworkOptions;
35
+ readonly providerEnvName: string;
36
+ readonly types: typeof t;
37
+ parseExpression: (code: string) => t.Expression;
38
+ }
39
+ export interface StartCompilerImportTransform {
40
+ name: string;
41
+ environment?: StartCompilerEnvironment | Array<StartCompilerEnvironment> | undefined;
42
+ imports: Array<StartCompilerImportTransformImport>;
43
+ detect: RegExp;
44
+ order?: 'pre' | 'post' | undefined;
45
+ transform: (candidates: Array<StartCompilerTransformCandidate>, context: StartCompilerTransformContext) => void;
46
+ }
16
47
  export interface NormalizedBasePaths {
17
48
  publicBase: string;
18
49
  assetBase: {
@@ -49,6 +80,8 @@ export interface TanStackStartCoreOptions {
49
80
  providerEnvironmentName: string;
50
81
  ssrIsProvider: boolean;
51
82
  serializationAdapters?: Array<SerializationAdapterConfig> | undefined;
83
+ compilerTransforms?: Array<StartCompilerImportTransform> | undefined;
84
+ serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined;
52
85
  }
53
86
  export interface ResolvedStartConfig {
54
87
  root: string;
@@ -1,5 +1,6 @@
1
1
  export type { TanStackStartVitePluginCoreOptions, ViteRscForwardSsrResolverStrategy, } from './types.js';
2
2
  export type { TanStackStartViteInputConfig } from './schema.js';
3
+ export type { StartCompilerImportTransform, StartCompilerTransformCandidate, StartCompilerTransformContext, } from '../types.js';
3
4
  export { START_ENVIRONMENT_NAMES, VITE_ENVIRONMENT_NAMES } from '../constants.js';
4
5
  export { createVirtualModule } from './createVirtualModule.js';
5
6
  export { tanStackStartVite } from './plugin.js';
@@ -126,6 +126,8 @@ function tanStackStartVite(corePluginOpts, startPluginOpts) {
126
126
  framework: corePluginOpts.framework,
127
127
  environments,
128
128
  generateFunctionId: normalizedStartPluginOpts.serverFns?.generateFunctionId,
129
+ compilerTransforms: corePluginOpts.compilerTransforms,
130
+ serverFnProviderModuleDirectives: corePluginOpts.serverFnProviderModuleDirectives,
129
131
  providerEnvName: serverFnProviderEnv
130
132
  }),
131
133
  importProtectionPlugin({
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","names":[],"sources":["../../../src/vite/plugin.ts"],"sourcesContent":["import { crawlFrameworkPkgs } from 'vitefu'\nimport {\n applyResolvedBaseAndOutput,\n applyResolvedRouterBasepath,\n createStartConfigContext,\n} from '../config-context'\nimport { START_ENVIRONMENT_NAMES } from '../constants'\nimport {\n createServerFnBasePath,\n normalizePublicBase,\n shouldRewriteDevBasepath,\n} from '../planning'\nimport { importProtectionPlugin } from './import-protection-plugin/plugin'\nimport { startCompilerPlugin } from './start-compiler-plugin/plugin'\nimport { loadEnvPlugin } from './load-env-plugin/plugin'\nimport {\n buildStartViteEnvironments,\n createViteConfigPlan,\n createViteDefineConfig,\n createViteResolvedEntryAliases,\n} from './planning'\nimport { devServerPlugin } from './dev-server-plugin/plugin'\nimport { previewServerPlugin } from './preview-server-plugin/plugin'\nimport {\n createDevBaseRewritePlugin,\n createPostBuildPlugin,\n createVirtualClientEntryPlugin,\n} from './plugins'\nimport { parseStartConfig } from './schema'\nimport { startManifestPlugin } from './start-manifest-plugin/plugin'\nimport { tanStackStartRouter } from './start-router-plugin/plugin'\nimport {\n getClientOutputDirectory,\n getServerOutputDirectory,\n} from './output-directory'\nimport { postServerBuild } from './post-server-build'\nimport { serializationAdaptersPlugin } from './serialization-adapters-plugin'\nimport type {\n TanStackStartVitePluginCoreOptions,\n ViteRscForwardSsrResolverStrategy,\n} from './types'\nimport type { TanStackStartViteInputConfig } from './schema'\nimport type { PluginOption } from 'vite'\n\nexport function tanStackStartVite(\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n startPluginOpts: TanStackStartViteInputConfig | undefined,\n): Array<PluginOption> {\n const normalizedStartPluginOpts = startPluginOpts ?? {}\n\n const configContext = createStartConfigContext({\n corePluginOpts,\n startPluginOpts: normalizedStartPluginOpts,\n parseConfig: parseStartConfig,\n })\n const { getConfig, resolvedStartConfig } = configContext\n const serverFnProviderEnv = corePluginOpts.providerEnvironmentName\n const ssrIsProvider = corePluginOpts.ssrIsProvider\n\n // When the router basepath and vite base are misaligned during dev,\n // we install a URL rewrite middleware instead of erroring.\n let needsDevBaseRewrite = false\n\n const environments: Array<{\n name: string\n type: 'client' | 'server'\n getServerFnById?: string\n }> = [\n { name: START_ENVIRONMENT_NAMES.client, type: 'client' },\n {\n name: START_ENVIRONMENT_NAMES.server,\n type: 'server',\n getServerFnById:\n corePluginOpts.ssrResolverStrategy.type === 'vite-rsc-forward'\n ? createViteRscForwarder(corePluginOpts.ssrResolverStrategy)\n : undefined,\n },\n ]\n if (\n serverFnProviderEnv !== START_ENVIRONMENT_NAMES.server &&\n !environments.find((e) => e.name === serverFnProviderEnv)\n ) {\n environments.push({\n name: serverFnProviderEnv,\n type: 'server',\n })\n }\n return [\n {\n name: 'tanstack-start-core:config',\n enforce: 'pre',\n async config(viteConfig, { command }) {\n const publicBase = normalizePublicBase(viteConfig.base)\n applyResolvedBaseAndOutput({\n resolvedStartConfig,\n root: viteConfig.root || process.cwd(),\n publicBase,\n clientOutputDirectory: getClientOutputDirectory(viteConfig),\n serverOutputDirectory: getServerOutputDirectory(viteConfig),\n })\n const { startConfig } = getConfig()\n const routerBasepath = applyResolvedRouterBasepath({\n resolvedStartConfig,\n startConfig,\n })\n\n if (\n shouldRewriteDevBasepath({\n command,\n middlewareMode: Boolean(viteConfig.server?.middlewareMode),\n routerBasepath,\n publicBase: resolvedStartConfig.basePaths.publicBase,\n })\n ) {\n // The router basepath and vite base are misaligned.\n // Instead of erroring, we install a dev-server middleware that\n // rewrites incoming request URLs to prepend the vite base prefix.\n // This allows users to have e.g. base: '/_ui/' for asset URLs\n // while keeping router basepath at '/' for page navigation.\n needsDevBaseRewrite = true\n }\n\n const TSS_SERVER_FN_BASE = createServerFnBasePath({\n routerBasepath,\n serverFnBase: startConfig.serverFns.base,\n })\n const resolvedEntryPlan = configContext.resolveEntries()\n\n const entryAliases = createViteResolvedEntryAliases({\n entryPaths: resolvedEntryPlan.entryPaths,\n })\n\n const startPackageName =\n `@tanstack/${corePluginOpts.framework}-start` as const\n\n // crawl packages that have start in \"peerDependencies\"\n // see https://github.com/svitejs/vitefu/blob/d8d82fa121e3b2215ba437107093c77bde51b63b/src/index.js#L95-L101\n\n // this is currently uncached; could be implemented similarly as vite handles lock file changes\n // see https://github.com/vitejs/vite/blob/557f797d29422027e8c451ca50dd84bf8c41b5f0/packages/vite/src/node/optimizer/index.ts#L1282\n\n const crawlFrameworkPkgsResult = await crawlFrameworkPkgs({\n root: process.cwd(),\n isBuild: command === 'build',\n isFrameworkPkgByJson(pkgJson) {\n const peerDependencies = pkgJson['peerDependencies']\n\n if (peerDependencies) {\n if (\n startPackageName in peerDependencies ||\n '@tanstack/start-client-core' in peerDependencies\n ) {\n return true\n }\n }\n\n return false\n },\n })\n\n const viteConfigPlan = createViteConfigPlan({\n viteConfig,\n framework: corePluginOpts.framework,\n entryAliases,\n clientOutputDirectory: resolvedStartConfig.outputDirectories.client,\n serverOutputDirectory: resolvedStartConfig.outputDirectories.server,\n serverFnProviderEnv,\n optimizeDepsExclude: crawlFrameworkPkgsResult.optimizeDeps.exclude,\n noExternal: crawlFrameworkPkgsResult.ssr.noExternal.sort(),\n })\n\n return {\n // see https://vite.dev/config/shared-options.html#apptype\n // this will prevent vite from injecting middlewares that we don't want\n appType: viteConfig.appType ?? 'custom',\n environments: viteConfigPlan.environments,\n resolve: viteConfigPlan.resolve,\n define: createViteDefineConfig({\n command,\n mode: viteConfig.mode,\n serverFnBase: TSS_SERVER_FN_BASE,\n routerBasepath,\n spaEnabled: startConfig.spa?.enabled,\n devSsrStylesEnabled: startConfig.dev.ssrStyles.enabled,\n devSsrStylesBasepath:\n startConfig.dev.ssrStyles.basepath ??\n resolvedStartConfig.basePaths.publicBase,\n inlineCssEnabled:\n command === 'build' && startConfig.server.build.inlineCss,\n staticNodeEnv: startConfig.server.build.staticNodeEnv,\n }),\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n await buildStartViteEnvironments({\n builder,\n providerEnvironmentName: serverFnProviderEnv,\n ssrIsProvider,\n })\n },\n },\n }\n },\n },\n createPostBuildPlugin({\n getConfig,\n postServerBuild,\n }),\n // Server function plugin handles:\n // 1. Identifying createServerFn().handler() calls\n // 2. Extracting server functions to separate modules\n // 3. Replacing call sites with RPC stubs\n // 4. Generating the server function manifest\n // Also handles createIsomorphicFn, createServerOnlyFn, createClientOnlyFn, createMiddleware\n startCompilerPlugin({\n framework: corePluginOpts.framework,\n environments,\n generateFunctionId:\n normalizedStartPluginOpts.serverFns?.generateFunctionId,\n providerEnvName: serverFnProviderEnv,\n }),\n importProtectionPlugin({\n getConfig,\n framework: corePluginOpts.framework,\n environments,\n providerEnvName: serverFnProviderEnv,\n }),\n tanStackStartRouter(normalizedStartPluginOpts, getConfig, corePluginOpts),\n loadEnvPlugin(),\n createVirtualClientEntryPlugin({\n getClientEntry: () => configContext.resolveEntries().entryPaths.client,\n }),\n startManifestPlugin({\n getConfig,\n }),\n // When the vite base and router basepath are misaligned (e.g. base: '/_ui/', basepath: '/'),\n // install a middleware that rewrites incoming request URLs to prepend the vite base prefix.\n // This allows Vite's internal base middleware to accept the requests, then strips the prefix\n // before passing to the SSR handler.\n // Registered BEFORE devServerPlugin so this middleware is added to the Connect stack first,\n // ensuring all subsequent middlewares (CSS, SSR, etc.) see the rewritten URL.\n createDevBaseRewritePlugin({\n shouldRewriteDevBase: () => needsDevBaseRewrite,\n resolvedStartConfig,\n }),\n devServerPlugin({\n getConfig,\n devSsrStylesEnabled:\n normalizedStartPluginOpts.dev?.ssrStyles?.enabled ?? true,\n installDevServerMiddleware:\n normalizedStartPluginOpts.vite?.installDevServerMiddleware,\n }),\n previewServerPlugin(),\n serializationAdaptersPlugin({\n adapters: corePluginOpts.serializationAdapters,\n }),\n ]\n}\n\nfunction createViteRscForwarder(strategy: ViteRscForwardSsrResolverStrategy) {\n return `export async function getServerFnById(id, access) {\n const m = await import.meta.viteRsc.loadModule(${JSON.stringify(strategy.sourceEnvironmentName)}, ${JSON.stringify(strategy.sourceEntry)})\n return m[${JSON.stringify(strategy.exportName)}](id, access)\n}`\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","names":[],"sources":["../../../src/vite/plugin.ts"],"sourcesContent":["import { crawlFrameworkPkgs } from 'vitefu'\nimport {\n applyResolvedBaseAndOutput,\n applyResolvedRouterBasepath,\n createStartConfigContext,\n} from '../config-context'\nimport { START_ENVIRONMENT_NAMES } from '../constants'\nimport {\n createServerFnBasePath,\n normalizePublicBase,\n shouldRewriteDevBasepath,\n} from '../planning'\nimport { importProtectionPlugin } from './import-protection-plugin/plugin'\nimport { startCompilerPlugin } from './start-compiler-plugin/plugin'\nimport { loadEnvPlugin } from './load-env-plugin/plugin'\nimport {\n buildStartViteEnvironments,\n createViteConfigPlan,\n createViteDefineConfig,\n createViteResolvedEntryAliases,\n} from './planning'\nimport { devServerPlugin } from './dev-server-plugin/plugin'\nimport { previewServerPlugin } from './preview-server-plugin/plugin'\nimport {\n createDevBaseRewritePlugin,\n createPostBuildPlugin,\n createVirtualClientEntryPlugin,\n} from './plugins'\nimport { parseStartConfig } from './schema'\nimport { startManifestPlugin } from './start-manifest-plugin/plugin'\nimport { tanStackStartRouter } from './start-router-plugin/plugin'\nimport {\n getClientOutputDirectory,\n getServerOutputDirectory,\n} from './output-directory'\nimport { postServerBuild } from './post-server-build'\nimport { serializationAdaptersPlugin } from './serialization-adapters-plugin'\nimport type {\n TanStackStartVitePluginCoreOptions,\n ViteRscForwardSsrResolverStrategy,\n} from './types'\nimport type { TanStackStartViteInputConfig } from './schema'\nimport type { PluginOption } from 'vite'\n\nexport function tanStackStartVite(\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n startPluginOpts: TanStackStartViteInputConfig | undefined,\n): Array<PluginOption> {\n const normalizedStartPluginOpts = startPluginOpts ?? {}\n\n const configContext = createStartConfigContext({\n corePluginOpts,\n startPluginOpts: normalizedStartPluginOpts,\n parseConfig: parseStartConfig,\n })\n const { getConfig, resolvedStartConfig } = configContext\n const serverFnProviderEnv = corePluginOpts.providerEnvironmentName\n const ssrIsProvider = corePluginOpts.ssrIsProvider\n\n // When the router basepath and vite base are misaligned during dev,\n // we install a URL rewrite middleware instead of erroring.\n let needsDevBaseRewrite = false\n\n const environments: Array<{\n name: string\n type: 'client' | 'server'\n getServerFnById?: string\n }> = [\n { name: START_ENVIRONMENT_NAMES.client, type: 'client' },\n {\n name: START_ENVIRONMENT_NAMES.server,\n type: 'server',\n getServerFnById:\n corePluginOpts.ssrResolverStrategy.type === 'vite-rsc-forward'\n ? createViteRscForwarder(corePluginOpts.ssrResolverStrategy)\n : undefined,\n },\n ]\n if (\n serverFnProviderEnv !== START_ENVIRONMENT_NAMES.server &&\n !environments.find((e) => e.name === serverFnProviderEnv)\n ) {\n environments.push({\n name: serverFnProviderEnv,\n type: 'server',\n })\n }\n return [\n {\n name: 'tanstack-start-core:config',\n enforce: 'pre',\n async config(viteConfig, { command }) {\n const publicBase = normalizePublicBase(viteConfig.base)\n applyResolvedBaseAndOutput({\n resolvedStartConfig,\n root: viteConfig.root || process.cwd(),\n publicBase,\n clientOutputDirectory: getClientOutputDirectory(viteConfig),\n serverOutputDirectory: getServerOutputDirectory(viteConfig),\n })\n const { startConfig } = getConfig()\n const routerBasepath = applyResolvedRouterBasepath({\n resolvedStartConfig,\n startConfig,\n })\n\n if (\n shouldRewriteDevBasepath({\n command,\n middlewareMode: Boolean(viteConfig.server?.middlewareMode),\n routerBasepath,\n publicBase: resolvedStartConfig.basePaths.publicBase,\n })\n ) {\n // The router basepath and vite base are misaligned.\n // Instead of erroring, we install a dev-server middleware that\n // rewrites incoming request URLs to prepend the vite base prefix.\n // This allows users to have e.g. base: '/_ui/' for asset URLs\n // while keeping router basepath at '/' for page navigation.\n needsDevBaseRewrite = true\n }\n\n const TSS_SERVER_FN_BASE = createServerFnBasePath({\n routerBasepath,\n serverFnBase: startConfig.serverFns.base,\n })\n const resolvedEntryPlan = configContext.resolveEntries()\n\n const entryAliases = createViteResolvedEntryAliases({\n entryPaths: resolvedEntryPlan.entryPaths,\n })\n\n const startPackageName =\n `@tanstack/${corePluginOpts.framework}-start` as const\n\n // crawl packages that have start in \"peerDependencies\"\n // see https://github.com/svitejs/vitefu/blob/d8d82fa121e3b2215ba437107093c77bde51b63b/src/index.js#L95-L101\n\n // this is currently uncached; could be implemented similarly as vite handles lock file changes\n // see https://github.com/vitejs/vite/blob/557f797d29422027e8c451ca50dd84bf8c41b5f0/packages/vite/src/node/optimizer/index.ts#L1282\n\n const crawlFrameworkPkgsResult = await crawlFrameworkPkgs({\n root: process.cwd(),\n isBuild: command === 'build',\n isFrameworkPkgByJson(pkgJson) {\n const peerDependencies = pkgJson['peerDependencies']\n\n if (peerDependencies) {\n if (\n startPackageName in peerDependencies ||\n '@tanstack/start-client-core' in peerDependencies\n ) {\n return true\n }\n }\n\n return false\n },\n })\n\n const viteConfigPlan = createViteConfigPlan({\n viteConfig,\n framework: corePluginOpts.framework,\n entryAliases,\n clientOutputDirectory: resolvedStartConfig.outputDirectories.client,\n serverOutputDirectory: resolvedStartConfig.outputDirectories.server,\n serverFnProviderEnv,\n optimizeDepsExclude: crawlFrameworkPkgsResult.optimizeDeps.exclude,\n noExternal: crawlFrameworkPkgsResult.ssr.noExternal.sort(),\n })\n\n return {\n // see https://vite.dev/config/shared-options.html#apptype\n // this will prevent vite from injecting middlewares that we don't want\n appType: viteConfig.appType ?? 'custom',\n environments: viteConfigPlan.environments,\n resolve: viteConfigPlan.resolve,\n define: createViteDefineConfig({\n command,\n mode: viteConfig.mode,\n serverFnBase: TSS_SERVER_FN_BASE,\n routerBasepath,\n spaEnabled: startConfig.spa?.enabled,\n devSsrStylesEnabled: startConfig.dev.ssrStyles.enabled,\n devSsrStylesBasepath:\n startConfig.dev.ssrStyles.basepath ??\n resolvedStartConfig.basePaths.publicBase,\n inlineCssEnabled:\n command === 'build' && startConfig.server.build.inlineCss,\n staticNodeEnv: startConfig.server.build.staticNodeEnv,\n }),\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n await buildStartViteEnvironments({\n builder,\n providerEnvironmentName: serverFnProviderEnv,\n ssrIsProvider,\n })\n },\n },\n }\n },\n },\n createPostBuildPlugin({\n getConfig,\n postServerBuild,\n }),\n // Server function plugin handles:\n // 1. Identifying createServerFn().handler() calls\n // 2. Extracting server functions to separate modules\n // 3. Replacing call sites with RPC stubs\n // 4. Generating the server function manifest\n // Also handles createIsomorphicFn, createServerOnlyFn, createClientOnlyFn, createMiddleware\n startCompilerPlugin({\n framework: corePluginOpts.framework,\n environments,\n generateFunctionId:\n normalizedStartPluginOpts.serverFns?.generateFunctionId,\n compilerTransforms: corePluginOpts.compilerTransforms,\n serverFnProviderModuleDirectives:\n corePluginOpts.serverFnProviderModuleDirectives,\n providerEnvName: serverFnProviderEnv,\n }),\n importProtectionPlugin({\n getConfig,\n framework: corePluginOpts.framework,\n environments,\n providerEnvName: serverFnProviderEnv,\n }),\n tanStackStartRouter(normalizedStartPluginOpts, getConfig, corePluginOpts),\n loadEnvPlugin(),\n createVirtualClientEntryPlugin({\n getClientEntry: () => configContext.resolveEntries().entryPaths.client,\n }),\n startManifestPlugin({\n getConfig,\n }),\n // When the vite base and router basepath are misaligned (e.g. base: '/_ui/', basepath: '/'),\n // install a middleware that rewrites incoming request URLs to prepend the vite base prefix.\n // This allows Vite's internal base middleware to accept the requests, then strips the prefix\n // before passing to the SSR handler.\n // Registered BEFORE devServerPlugin so this middleware is added to the Connect stack first,\n // ensuring all subsequent middlewares (CSS, SSR, etc.) see the rewritten URL.\n createDevBaseRewritePlugin({\n shouldRewriteDevBase: () => needsDevBaseRewrite,\n resolvedStartConfig,\n }),\n devServerPlugin({\n getConfig,\n devSsrStylesEnabled:\n normalizedStartPluginOpts.dev?.ssrStyles?.enabled ?? true,\n installDevServerMiddleware:\n normalizedStartPluginOpts.vite?.installDevServerMiddleware,\n }),\n previewServerPlugin(),\n serializationAdaptersPlugin({\n adapters: corePluginOpts.serializationAdapters,\n }),\n ]\n}\n\nfunction createViteRscForwarder(strategy: ViteRscForwardSsrResolverStrategy) {\n return `export async function getServerFnById(id, access) {\n const m = await import.meta.viteRsc.loadModule(${JSON.stringify(strategy.sourceEnvironmentName)}, ${JSON.stringify(strategy.sourceEntry)})\n return m[${JSON.stringify(strategy.exportName)}](id, access)\n}`\n}\n"],"mappings":"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"}
@@ -224,11 +224,11 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
224
224
  };
225
225
  entry?: string | undefined;
226
226
  }, {
227
- entry?: string | undefined;
228
227
  build?: {
229
228
  staticNodeEnv?: boolean | undefined;
230
229
  inlineCss?: boolean | undefined;
231
230
  } | undefined;
231
+ entry?: string | undefined;
232
232
  }>>>;
233
233
  serverFns: z.ZodDefault<z.ZodOptional<z.ZodObject<{
234
234
  base: z.ZodDefault<z.ZodOptional<z.ZodString>>;
@@ -2294,11 +2294,11 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
2294
2294
  dev: z.ZodOptional<z.ZodEnum<["error", "mock"]>>;
2295
2295
  build: z.ZodOptional<z.ZodEnum<["error", "mock"]>>;
2296
2296
  }, "strip", z.ZodTypeAny, {
2297
- build?: "error" | "mock" | undefined;
2298
2297
  dev?: "error" | "mock" | undefined;
2299
- }, {
2300
2298
  build?: "error" | "mock" | undefined;
2299
+ }, {
2301
2300
  dev?: "error" | "mock" | undefined;
2301
+ build?: "error" | "mock" | undefined;
2302
2302
  }>]>>;
2303
2303
  mockAccess: z.ZodOptional<z.ZodEnum<["error", "warn", "off"]>>;
2304
2304
  onViolation: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodUnion<[z.ZodBoolean, z.ZodVoid, z.ZodPromise<z.ZodUnion<[z.ZodBoolean, z.ZodVoid]>>]>>>;
@@ -2347,8 +2347,8 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
2347
2347
  exclude?: (string | RegExp)[] | undefined;
2348
2348
  enabled?: boolean | undefined;
2349
2349
  behavior?: "error" | "mock" | {
2350
- build?: "error" | "mock" | undefined;
2351
2350
  dev?: "error" | "mock" | undefined;
2351
+ build?: "error" | "mock" | undefined;
2352
2352
  } | undefined;
2353
2353
  mockAccess?: "error" | "warn" | "off" | undefined;
2354
2354
  onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
@@ -2370,8 +2370,8 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
2370
2370
  exclude?: (string | RegExp)[] | undefined;
2371
2371
  enabled?: boolean | undefined;
2372
2372
  behavior?: "error" | "mock" | {
2373
- build?: "error" | "mock" | undefined;
2374
2373
  dev?: "error" | "mock" | undefined;
2374
+ build?: "error" | "mock" | undefined;
2375
2375
  } | undefined;
2376
2376
  mockAccess?: "error" | "warn" | "off" | undefined;
2377
2377
  onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
@@ -2400,6 +2400,12 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
2400
2400
  };
2401
2401
  entry?: string | undefined;
2402
2402
  };
2403
+ dev: {
2404
+ ssrStyles: {
2405
+ enabled: boolean;
2406
+ basepath?: string | undefined;
2407
+ };
2408
+ };
2403
2409
  srcDirectory: string;
2404
2410
  start: {
2405
2411
  entry?: string | undefined;
@@ -2525,12 +2531,6 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
2525
2531
  headers?: Record<string, string> | undefined;
2526
2532
  } | undefined;
2527
2533
  }[];
2528
- dev: {
2529
- ssrStyles: {
2530
- enabled: boolean;
2531
- basepath?: string | undefined;
2532
- };
2533
- };
2534
2534
  sitemap?: {
2535
2535
  enabled: boolean;
2536
2536
  outputPath: string;
@@ -2704,8 +2704,8 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
2704
2704
  exclude?: (string | RegExp)[] | undefined;
2705
2705
  enabled?: boolean | undefined;
2706
2706
  behavior?: "error" | "mock" | {
2707
- build?: "error" | "mock" | undefined;
2708
2707
  dev?: "error" | "mock" | undefined;
2708
+ build?: "error" | "mock" | undefined;
2709
2709
  } | undefined;
2710
2710
  mockAccess?: "error" | "warn" | "off" | undefined;
2711
2711
  onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
@@ -2723,11 +2723,17 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
2723
2723
  base?: string | undefined;
2724
2724
  } | undefined;
2725
2725
  server?: {
2726
- entry?: string | undefined;
2727
2726
  build?: {
2728
2727
  staticNodeEnv?: boolean | undefined;
2729
2728
  inlineCss?: boolean | undefined;
2730
2729
  } | undefined;
2730
+ entry?: string | undefined;
2731
+ } | undefined;
2732
+ dev?: {
2733
+ ssrStyles?: {
2734
+ basepath?: string | undefined;
2735
+ enabled?: boolean | undefined;
2736
+ } | undefined;
2731
2737
  } | undefined;
2732
2738
  srcDirectory?: string | undefined;
2733
2739
  start?: {
@@ -2970,12 +2976,6 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
2970
2976
  headers?: Record<string, string> | undefined;
2971
2977
  } | undefined;
2972
2978
  }[] | undefined;
2973
- dev?: {
2974
- ssrStyles?: {
2975
- basepath?: string | undefined;
2976
- enabled?: boolean | undefined;
2977
- } | undefined;
2978
- } | undefined;
2979
2979
  spa?: {
2980
2980
  enabled?: boolean | undefined;
2981
2981
  prerender?: {
@@ -3033,8 +3033,8 @@ export declare const tanstackStartViteOptionsSchema: z.ZodDefault<z.ZodOptional<
3033
3033
  exclude?: (string | RegExp)[] | undefined;
3034
3034
  enabled?: boolean | undefined;
3035
3035
  behavior?: "error" | "mock" | {
3036
- build?: "error" | "mock" | undefined;
3037
3036
  dev?: "error" | "mock" | undefined;
3037
+ build?: "error" | "mock" | undefined;
3038
3038
  } | undefined;
3039
3039
  mockAccess?: "error" | "warn" | "off" | undefined;
3040
3040
  onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
@@ -3110,6 +3110,12 @@ export declare function parseStartConfig(opts: z.input<typeof tanstackStartViteO
3110
3110
  };
3111
3111
  entry?: string | undefined;
3112
3112
  };
3113
+ dev: {
3114
+ ssrStyles: {
3115
+ enabled: boolean;
3116
+ basepath?: string | undefined;
3117
+ };
3118
+ };
3113
3119
  srcDirectory: string;
3114
3120
  start: {
3115
3121
  entry?: string | undefined;
@@ -3187,12 +3193,6 @@ export declare function parseStartConfig(opts: z.input<typeof tanstackStartViteO
3187
3193
  headers?: Record<string, string> | undefined;
3188
3194
  } | undefined;
3189
3195
  }[];
3190
- dev: {
3191
- ssrStyles: {
3192
- enabled: boolean;
3193
- basepath?: string | undefined;
3194
- };
3195
- };
3196
3196
  sitemap?: {
3197
3197
  enabled: boolean;
3198
3198
  outputPath: string;
@@ -3366,8 +3366,8 @@ export declare function parseStartConfig(opts: z.input<typeof tanstackStartViteO
3366
3366
  exclude?: (string | RegExp)[] | undefined;
3367
3367
  enabled?: boolean | undefined;
3368
3368
  behavior?: "error" | "mock" | {
3369
- build?: "error" | "mock" | undefined;
3370
3369
  dev?: "error" | "mock" | undefined;
3370
+ build?: "error" | "mock" | undefined;
3371
3371
  } | undefined;
3372
3372
  mockAccess?: "error" | "warn" | "off" | undefined;
3373
3373
  onViolation?: ((args_0: any, ...args: unknown[]) => boolean | void | Promise<boolean | void>) | undefined;
@@ -1,5 +1,5 @@
1
1
  import { SERVER_FN_LOOKUP } from '../../constants.js';
2
- import { CompileStartFrameworkOptions } from '../../types.js';
2
+ import { CompileStartFrameworkOptions, StartCompilerImportTransform } from '../../types.js';
3
3
  import { GenerateFunctionIdFnOptional } from '../../start-compiler/types.js';
4
4
  import { PluginOption } from 'vite';
5
5
  export { SERVER_FN_LOOKUP };
@@ -14,6 +14,8 @@ export interface StartCompilerPluginOptions {
14
14
  * Custom function ID generator (optional).
15
15
  */
16
16
  generateFunctionId?: GenerateFunctionIdFnOptional;
17
+ compilerTransforms?: Array<StartCompilerImportTransform> | undefined;
18
+ serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined;
17
19
  /**
18
20
  * The Vite environment name for the server function provider.
19
21
  */
@@ -79,7 +79,9 @@ function startCompilerPlugin(opts) {
79
79
  const ssrIsProvider = opts.providerEnvName === ssrEnvName;
80
80
  const appliedResolverEnvironments = new Set(ssrIsProvider ? [opts.providerEnvName] : [ssrEnvName, opts.providerEnvName]);
81
81
  function perEnvServerFnPlugin(environment) {
82
- const transformCodeFilter = getTransformCodeFilterForEnv(environment.type);
82
+ const compilerTransforms = environment.name === opts.providerEnvName ? opts.compilerTransforms : void 0;
83
+ const serverFnProviderModuleDirectives = environment.name === opts.providerEnvName ? opts.serverFnProviderModuleDirectives : void 0;
84
+ const transformCodeFilter = getTransformCodeFilterForEnv(environment.type, { compilerTransforms });
83
85
  return {
84
86
  name: `tanstack-start-core::server-fn:${environment.name}`,
85
87
  enforce: "pre",
@@ -109,6 +111,8 @@ function startCompilerPlugin(opts) {
109
111
  framework: opts.framework,
110
112
  providerEnvName: opts.providerEnvName,
111
113
  generateFunctionId: opts.generateFunctionId,
114
+ compilerTransforms,
115
+ serverFnProviderModuleDirectives,
112
116
  onServerFnsById,
113
117
  getKnownServerFns: () => serverFnsById,
114
118
  encodeModuleSpecifierInDev: mode === "dev" ? createViteDevServerFnModuleSpecifierEncoder(root) : void 0,
@@ -134,7 +138,7 @@ function startCompilerPlugin(opts) {
134
138
  });
135
139
  compilers.set(this.environment.name, compiler);
136
140
  }
137
- const detectedKinds = detectKindsInCode(code, environment.type);
141
+ const detectedKinds = detectKindsInCode(code, environment.type, { compilerTransforms });
138
142
  return await compiler.compile({
139
143
  id,
140
144
  code,
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","names":[],"sources":["../../../../src/vite/start-compiler-plugin/plugin.ts"],"sourcesContent":["import { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { resolve as resolvePath } from 'pathe'\nimport {\n SERVER_FN_LOOKUP,\n TRANSFORM_ID_REGEX,\n VITE_ENVIRONMENT_NAMES,\n} from '../../constants'\nimport { detectKindsInCode } from '../../start-compiler/compiler'\nimport { getTransformCodeFilterForEnv } from '../../start-compiler/config'\nimport {\n createStartCompiler,\n mergeServerFnsById,\n} from '../../start-compiler/host'\nimport { generateServerFnResolverModule } from '../../start-compiler/server-fn-resolver-module'\nimport { cleanId } from '../../start-compiler/utils'\nimport { createVirtualModule } from '../createVirtualModule'\nimport { resolveViteId } from '../../utils'\nimport {\n createViteDevServerFnModuleSpecifierEncoder,\n decodeViteDevServerModuleSpecifier,\n} from './module-specifier'\nimport { mergeHotUpdateModules } from './hot-update'\nimport type { CompileStartFrameworkOptions } from '../../types'\nimport type {\n GenerateFunctionIdFnOptional,\n ServerFn,\n} from '../../start-compiler/types'\nimport type { EnvironmentModuleNode, PluginOption } from 'vite'\n\n// Re-export from shared constants for backwards compatibility\nexport { SERVER_FN_LOOKUP }\n\nconst validateServerFnIdVirtualModule = `virtual:tanstack-start-validate-server-fn-id`\nconst TSS_SERVERFN_SPLIT_PARAM = 'tss-serverfn-split'\n\ntype ModuleInvalidationEnvironment = {\n moduleGraph: {\n getModulesByFile: (file: string) => Set<EnvironmentModuleNode> | undefined\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n}\n\nfunction invalidateMatchingFileModules(\n environment: ModuleInvalidationEnvironment,\n ids: Iterable<string>,\n shouldInvalidate: (mod: EnvironmentModuleNode) => boolean,\n) {\n const seen = new Set<EnvironmentModuleNode>()\n const invalidatedModules: Array<EnvironmentModuleNode> = []\n\n for (const id of ids) {\n const fileModules = environment.moduleGraph.getModulesByFile(cleanId(id))\n\n if (!fileModules) {\n continue\n }\n\n for (const fileModule of fileModules) {\n if (!shouldInvalidate(fileModule)) {\n continue\n }\n\n environment.moduleGraph.invalidateModule(fileModule, seen)\n invalidatedModules.push(fileModule)\n }\n }\n\n return invalidatedModules\n}\n\nfunction invalidateServerFnProviderModules(\n environment: {\n moduleGraph: {\n getModulesByFile: (file: string) => Set<EnvironmentModuleNode> | undefined\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n },\n ids: Iterable<string>,\n) {\n return invalidateMatchingFileModules(\n environment,\n ids,\n (fileModule) => fileModule.id?.includes(TSS_SERVERFN_SPLIT_PARAM) ?? false,\n )\n}\n\nfunction invalidateServerFnLookupModules(\n environment: ModuleInvalidationEnvironment,\n ids: Iterable<string>,\n) {\n invalidateMatchingFileModules(\n environment,\n ids,\n (fileModule) => fileModule.id?.includes(SERVER_FN_LOOKUP) ?? false,\n )\n}\n\nfunction getServerFnProviderIds(ids: Iterable<string>) {\n const providerIds = new Set<string>()\n\n for (const id of ids) {\n const cleanedId = cleanId(id)\n providerIds.add(`${cleanedId}?${TSS_SERVERFN_SPLIT_PARAM}`)\n }\n\n return providerIds\n}\n\nfunction invalidateModuleNodes(\n environment: {\n moduleGraph: {\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n },\n modules: Iterable<EnvironmentModuleNode>,\n) {\n const seen = new Set<EnvironmentModuleNode>()\n\n for (const mod of modules) {\n environment.moduleGraph.invalidateModule(mod, seen)\n }\n}\n\nfunction getDevServerFnValidatorModule(): string {\n return `\nexport async function getServerFnById(id, _access) {\n const validateIdImport = ${JSON.stringify(validateServerFnIdVirtualModule)} + '?id=' + id\n await import(/* @vite-ignore */ '/@id/__x00__' + validateIdImport)\n const decoded = Buffer.from(id, 'base64url').toString('utf8')\n const devServerFn = JSON.parse(decoded)\n const mod = await import(/* @vite-ignore */ devServerFn.file)\n return mod[devServerFn.export]\n}\n`\n}\n\nfunction parseIdQuery(id: string): {\n filename: string\n query: {\n [k: string]: string\n }\n} {\n if (!id.includes('?')) return { filename: id, query: {} }\n const [filename, rawQuery] = id.split(`?`, 2) as [string, string]\n const query = Object.fromEntries(new URLSearchParams(rawQuery))\n return { filename, query }\n}\n\nexport interface StartCompilerPluginOptions {\n framework: CompileStartFrameworkOptions\n environments: Array<{\n name: string\n type: 'client' | 'server'\n getServerFnById?: string\n }>\n /**\n * Custom function ID generator (optional).\n */\n generateFunctionId?: GenerateFunctionIdFnOptional\n /**\n * The Vite environment name for the server function provider.\n */\n providerEnvName: string\n}\n\nexport function startCompilerPlugin(\n opts: StartCompilerPluginOptions,\n): PluginOption {\n const compilers = new Map<string, ReturnType<typeof createStartCompiler>>()\n\n // Shared registry of server functions across all environments\n const serverFnsById: Record<string, ServerFn> = {}\n\n const onServerFnsById = (d: Record<string, ServerFn>) => {\n mergeServerFnsById(serverFnsById, d)\n }\n\n let root = process.cwd()\n // Determine which environments need the resolver (getServerFnById)\n // SSR environment always needs the resolver for server-side calls\n // Provider environment needs it for the actual implementation\n const ssrEnvName = VITE_ENVIRONMENT_NAMES.server\n\n // SSR is the provider when the provider environment is the default server environment\n const ssrIsProvider = opts.providerEnvName === ssrEnvName\n\n // Environments that need the resolver: SSR (for server calls) and provider (for implementation)\n const appliedResolverEnvironments = new Set(\n ssrIsProvider ? [opts.providerEnvName] : [ssrEnvName, opts.providerEnvName],\n )\n\n function perEnvServerFnPlugin(environment: {\n name: string\n type: 'client' | 'server'\n }): PluginOption {\n // Derive transform code filter from KindDetectionPatterns (single source of truth)\n const transformCodeFilter = getTransformCodeFilterForEnv(environment.type)\n return {\n name: `tanstack-start-core::server-fn:${environment.name}`,\n enforce: 'pre',\n applyToEnvironment(env) {\n return env.name === environment.name\n },\n configResolved(config) {\n root = config.root\n },\n transform: {\n filter: {\n id: {\n exclude: new RegExp(`${SERVER_FN_LOOKUP}$`),\n include: TRANSFORM_ID_REGEX,\n },\n code: {\n include: transformCodeFilter,\n },\n },\n async handler(code, id) {\n let compiler = compilers.get(this.environment.name)\n\n if (!compiler) {\n // Default to 'dev' mode for unknown environments (conservative: no caching)\n const mode = this.environment.mode === 'build' ? 'build' : 'dev'\n\n compiler = createStartCompiler({\n env: environment.type,\n envName: environment.name,\n root,\n mode,\n framework: opts.framework,\n providerEnvName: opts.providerEnvName,\n generateFunctionId: opts.generateFunctionId,\n onServerFnsById,\n getKnownServerFns: () => serverFnsById,\n encodeModuleSpecifierInDev:\n mode === 'dev'\n ? createViteDevServerFnModuleSpecifierEncoder(root)\n : undefined,\n loadModule: async (id: string) => {\n if (mode === 'build') {\n const loaded = await this.load({ id })\n const code = loaded.code ?? ''\n\n compiler!.ingestModule({ code, id })\n return\n }\n\n if (this.environment.mode !== 'dev') {\n this.error(\n `could not load module ${id}: unknown environment mode ${this.environment.mode}`,\n )\n }\n\n await this.environment.transformRequest(\n `${id}?${SERVER_FN_LOOKUP}`,\n )\n },\n\n resolveId: async (source: string, importer?: string) => {\n const r = await this.resolve(source, importer)\n\n if (r) {\n if (!r.external) {\n return cleanId(r.id)\n }\n }\n\n return null\n },\n })\n\n compilers.set(this.environment.name, compiler)\n }\n\n // Detect which kinds are present in this file before parsing\n const detectedKinds = detectKindsInCode(code, environment.type)\n\n const result = await compiler.compile({\n id,\n code,\n detectedKinds,\n })\n return result\n },\n },\n\n hotUpdate(ctx) {\n const compiler = compilers.get(this.environment.name)\n const idsToInvalidate = new Set<string>()\n const transitiveCompilerImportersToInvalidate = new Set<string>()\n const importerModulesToInvalidate = new Set<EnvironmentModuleNode>()\n\n ctx.modules.forEach((m) => {\n if (m.id) {\n idsToInvalidate.add(m.id)\n const deleted = compiler?.invalidateModule(m.id)\n\n if (deleted) {\n transitiveCompilerImportersToInvalidate.add(cleanId(m.id))\n }\n\n if (deleted) {\n m.importers.forEach((importer) => {\n if (importer.id) {\n idsToInvalidate.add(importer.id)\n importerModulesToInvalidate.add(importer)\n transitiveCompilerImportersToInvalidate.add(\n cleanId(importer.id),\n )\n }\n })\n }\n }\n })\n\n const finishHotUpdate = async () => {\n if (environment.type === 'server' && compiler) {\n const pendingImporters = [\n ...transitiveCompilerImportersToInvalidate,\n ]\n const seenImporters = new Set(pendingImporters)\n\n while (pendingImporters.length > 0) {\n const importerId = pendingImporters.pop()!\n const nestedImporters =\n await compiler.getTransitiveImporters(importerId)\n\n for (const nestedImporterId of nestedImporters) {\n if (seenImporters.has(nestedImporterId)) {\n continue\n }\n\n seenImporters.add(nestedImporterId)\n pendingImporters.push(nestedImporterId)\n }\n }\n\n for (const importerId of seenImporters) {\n idsToInvalidate.add(importerId)\n compiler.invalidateModule(importerId)\n }\n }\n\n invalidateModuleNodes(this.environment, importerModulesToInvalidate)\n invalidateServerFnLookupModules(this.environment, idsToInvalidate)\n\n if (environment.type !== 'server') {\n return\n }\n\n invalidateModuleNodes(this.environment, ctx.modules)\n\n const providerIdsToInvalidate =\n getServerFnProviderIds(idsToInvalidate)\n for (const providerId of providerIdsToInvalidate) {\n compiler?.invalidateModule(providerId)\n }\n\n const providerModules = invalidateServerFnProviderModules(\n this.environment,\n [...idsToInvalidate, ...providerIdsToInvalidate],\n )\n\n return mergeHotUpdateModules(ctx.modules, providerModules)\n }\n\n return finishHotUpdate()\n },\n }\n }\n\n return [\n ...opts.environments.map(perEnvServerFnPlugin),\n {\n name: 'tanstack-start-core:capture-server-fn-module-lookup',\n // we only need this plugin in dev mode\n apply: 'serve',\n applyToEnvironment(env) {\n return !!opts.environments.find((e) => e.name === env.name)\n },\n transform: {\n filter: {\n id: new RegExp(`${SERVER_FN_LOOKUP}$`),\n },\n handler(code, id) {\n const compiler = compilers.get(this.environment.name)\n compiler?.ingestModule({ code, id: cleanId(id) })\n },\n },\n },\n // Validate server function ID in dev mode\n {\n name: 'tanstack-start-core:validate-server-fn-id',\n apply: 'serve',\n load: {\n filter: {\n id: new RegExp(resolveViteId(validateServerFnIdVirtualModule)),\n },\n async handler(id) {\n const parsed = parseIdQuery(id)\n const fnId = parsed.query.id\n if (fnId && serverFnsById[fnId]) {\n return `export {}`\n }\n\n // ID not yet registered — the source file may not have been\n // transformed in this dev session yet (e.g. cold restart with\n // cached client). Try to decode the ID, discover the source\n // file, trigger its compilation, and re-check.\n if (fnId) {\n try {\n const decoded = JSON.parse(\n Buffer.from(fnId, 'base64url').toString('utf8'),\n )\n if (\n typeof decoded.file === 'string' &&\n typeof decoded.export === 'string'\n ) {\n // Use the Vite strategy to decode the module specifier\n // back to the original source file path.\n const sourceFile = decodeViteDevServerModuleSpecifier(\n decoded.file,\n )\n\n if (sourceFile) {\n // Resolve to absolute path\n const absPath = resolvePath(root, sourceFile)\n\n // Trigger transform of the source file in this environment,\n // which will compile createServerFn calls and populate\n // serverFnsById as a side effect.\n if (this.environment.mode !== 'dev') {\n this.error(\n `could not validate server function ID ${fnId}: unknown environment mode ${this.environment.mode}`,\n )\n }\n\n await this.environment.transformRequest(\n `${absPath}?${SERVER_FN_LOOKUP}`,\n )\n\n // Re-check after lazy compilation\n if (serverFnsById[fnId]) {\n return `export {}`\n }\n }\n }\n } catch {\n // Decoding or fetching failed — fall through to error\n }\n }\n\n this.error(`Invalid server function ID: ${fnId}`)\n },\n },\n },\n // Manifest plugin for server environments\n createVirtualModule({\n name: 'tanstack-start-core:server-fn-resolver',\n moduleId: VIRTUAL_MODULES.serverFnResolver,\n enforce: 'pre',\n applyToEnvironment: (env) => {\n return appliedResolverEnvironments.has(env.name)\n },\n load() {\n if (this.environment.name !== opts.providerEnvName) {\n const mod = opts.environments.find(\n (e) => e.name === this.environment.name,\n )?.getServerFnById\n if (mod) {\n return mod\n }\n\n this.error(\n `No getServerFnById implementation found for caller environment: ${this.environment.name}`,\n )\n }\n\n if (this.environment.mode !== 'build') {\n return getDevServerFnValidatorModule()\n }\n\n // When SSR is the provider, server-only-referenced functions aren't in the manifest,\n // so no isClientReferenced check is needed.\n // When SSR is NOT the provider (custom provider env), server-only-referenced\n // functions ARE in the manifest and need the isClientReferenced check to\n // block direct client HTTP requests to server-only-referenced functions.\n return generateServerFnResolverModule({\n serverFnsById,\n includeClientReferencedCheck: !ssrIsProvider,\n })\n },\n }),\n ]\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","names":[],"sources":["../../../../src/vite/start-compiler-plugin/plugin.ts"],"sourcesContent":["import { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { resolve as resolvePath } from 'pathe'\nimport {\n SERVER_FN_LOOKUP,\n TRANSFORM_ID_REGEX,\n VITE_ENVIRONMENT_NAMES,\n} from '../../constants'\nimport { detectKindsInCode } from '../../start-compiler/compiler'\nimport { getTransformCodeFilterForEnv } from '../../start-compiler/config'\nimport {\n createStartCompiler,\n mergeServerFnsById,\n} from '../../start-compiler/host'\nimport { generateServerFnResolverModule } from '../../start-compiler/server-fn-resolver-module'\nimport { cleanId } from '../../start-compiler/utils'\nimport { createVirtualModule } from '../createVirtualModule'\nimport { resolveViteId } from '../../utils'\nimport {\n createViteDevServerFnModuleSpecifierEncoder,\n decodeViteDevServerModuleSpecifier,\n} from './module-specifier'\nimport { mergeHotUpdateModules } from './hot-update'\nimport type {\n CompileStartFrameworkOptions,\n StartCompilerImportTransform,\n} from '../../types'\nimport type {\n GenerateFunctionIdFnOptional,\n ServerFn,\n} from '../../start-compiler/types'\nimport type { EnvironmentModuleNode, PluginOption } from 'vite'\n\n// Re-export from shared constants for backwards compatibility\nexport { SERVER_FN_LOOKUP }\n\nconst validateServerFnIdVirtualModule = `virtual:tanstack-start-validate-server-fn-id`\nconst TSS_SERVERFN_SPLIT_PARAM = 'tss-serverfn-split'\n\ntype ModuleInvalidationEnvironment = {\n moduleGraph: {\n getModulesByFile: (file: string) => Set<EnvironmentModuleNode> | undefined\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n}\n\nfunction invalidateMatchingFileModules(\n environment: ModuleInvalidationEnvironment,\n ids: Iterable<string>,\n shouldInvalidate: (mod: EnvironmentModuleNode) => boolean,\n) {\n const seen = new Set<EnvironmentModuleNode>()\n const invalidatedModules: Array<EnvironmentModuleNode> = []\n\n for (const id of ids) {\n const fileModules = environment.moduleGraph.getModulesByFile(cleanId(id))\n\n if (!fileModules) {\n continue\n }\n\n for (const fileModule of fileModules) {\n if (!shouldInvalidate(fileModule)) {\n continue\n }\n\n environment.moduleGraph.invalidateModule(fileModule, seen)\n invalidatedModules.push(fileModule)\n }\n }\n\n return invalidatedModules\n}\n\nfunction invalidateServerFnProviderModules(\n environment: {\n moduleGraph: {\n getModulesByFile: (file: string) => Set<EnvironmentModuleNode> | undefined\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n },\n ids: Iterable<string>,\n) {\n return invalidateMatchingFileModules(\n environment,\n ids,\n (fileModule) => fileModule.id?.includes(TSS_SERVERFN_SPLIT_PARAM) ?? false,\n )\n}\n\nfunction invalidateServerFnLookupModules(\n environment: ModuleInvalidationEnvironment,\n ids: Iterable<string>,\n) {\n invalidateMatchingFileModules(\n environment,\n ids,\n (fileModule) => fileModule.id?.includes(SERVER_FN_LOOKUP) ?? false,\n )\n}\n\nfunction getServerFnProviderIds(ids: Iterable<string>) {\n const providerIds = new Set<string>()\n\n for (const id of ids) {\n const cleanedId = cleanId(id)\n providerIds.add(`${cleanedId}?${TSS_SERVERFN_SPLIT_PARAM}`)\n }\n\n return providerIds\n}\n\nfunction invalidateModuleNodes(\n environment: {\n moduleGraph: {\n invalidateModule: (\n mod: EnvironmentModuleNode,\n seen?: Set<EnvironmentModuleNode>,\n ) => void\n }\n },\n modules: Iterable<EnvironmentModuleNode>,\n) {\n const seen = new Set<EnvironmentModuleNode>()\n\n for (const mod of modules) {\n environment.moduleGraph.invalidateModule(mod, seen)\n }\n}\n\nfunction getDevServerFnValidatorModule(): string {\n return `\nexport async function getServerFnById(id, _access) {\n const validateIdImport = ${JSON.stringify(validateServerFnIdVirtualModule)} + '?id=' + id\n await import(/* @vite-ignore */ '/@id/__x00__' + validateIdImport)\n const decoded = Buffer.from(id, 'base64url').toString('utf8')\n const devServerFn = JSON.parse(decoded)\n const mod = await import(/* @vite-ignore */ devServerFn.file)\n return mod[devServerFn.export]\n}\n`\n}\n\nfunction parseIdQuery(id: string): {\n filename: string\n query: {\n [k: string]: string\n }\n} {\n if (!id.includes('?')) return { filename: id, query: {} }\n const [filename, rawQuery] = id.split(`?`, 2) as [string, string]\n const query = Object.fromEntries(new URLSearchParams(rawQuery))\n return { filename, query }\n}\n\nexport interface StartCompilerPluginOptions {\n framework: CompileStartFrameworkOptions\n environments: Array<{\n name: string\n type: 'client' | 'server'\n getServerFnById?: string\n }>\n /**\n * Custom function ID generator (optional).\n */\n generateFunctionId?: GenerateFunctionIdFnOptional\n compilerTransforms?: Array<StartCompilerImportTransform> | undefined\n serverFnProviderModuleDirectives?: ReadonlyArray<string> | undefined\n /**\n * The Vite environment name for the server function provider.\n */\n providerEnvName: string\n}\n\nexport function startCompilerPlugin(\n opts: StartCompilerPluginOptions,\n): PluginOption {\n const compilers = new Map<string, ReturnType<typeof createStartCompiler>>()\n\n // Shared registry of server functions across all environments\n const serverFnsById: Record<string, ServerFn> = {}\n\n const onServerFnsById = (d: Record<string, ServerFn>) => {\n mergeServerFnsById(serverFnsById, d)\n }\n\n let root = process.cwd()\n // Determine which environments need the resolver (getServerFnById)\n // SSR environment always needs the resolver for server-side calls\n // Provider environment needs it for the actual implementation\n const ssrEnvName = VITE_ENVIRONMENT_NAMES.server\n\n // SSR is the provider when the provider environment is the default server environment\n const ssrIsProvider = opts.providerEnvName === ssrEnvName\n\n // Environments that need the resolver: SSR (for server calls) and provider (for implementation)\n const appliedResolverEnvironments = new Set(\n ssrIsProvider ? [opts.providerEnvName] : [ssrEnvName, opts.providerEnvName],\n )\n\n function perEnvServerFnPlugin(environment: {\n name: string\n type: 'client' | 'server'\n }): PluginOption {\n const compilerTransforms =\n environment.name === opts.providerEnvName\n ? opts.compilerTransforms\n : undefined\n const serverFnProviderModuleDirectives =\n environment.name === opts.providerEnvName\n ? opts.serverFnProviderModuleDirectives\n : undefined\n // Derive transform code filter from KindDetectionPatterns (single source of truth)\n const transformCodeFilter = getTransformCodeFilterForEnv(environment.type, {\n compilerTransforms,\n })\n return {\n name: `tanstack-start-core::server-fn:${environment.name}`,\n enforce: 'pre',\n applyToEnvironment(env) {\n return env.name === environment.name\n },\n configResolved(config) {\n root = config.root\n },\n transform: {\n filter: {\n id: {\n exclude: new RegExp(`${SERVER_FN_LOOKUP}$`),\n include: TRANSFORM_ID_REGEX,\n },\n code: {\n include: transformCodeFilter,\n },\n },\n async handler(code, id) {\n let compiler = compilers.get(this.environment.name)\n\n if (!compiler) {\n // Default to 'dev' mode for unknown environments (conservative: no caching)\n const mode = this.environment.mode === 'build' ? 'build' : 'dev'\n\n compiler = createStartCompiler({\n env: environment.type,\n envName: environment.name,\n root,\n mode,\n framework: opts.framework,\n providerEnvName: opts.providerEnvName,\n generateFunctionId: opts.generateFunctionId,\n compilerTransforms,\n serverFnProviderModuleDirectives,\n onServerFnsById,\n getKnownServerFns: () => serverFnsById,\n encodeModuleSpecifierInDev:\n mode === 'dev'\n ? createViteDevServerFnModuleSpecifierEncoder(root)\n : undefined,\n loadModule: async (id: string) => {\n if (mode === 'build') {\n const loaded = await this.load({ id })\n const code = loaded.code ?? ''\n\n compiler!.ingestModule({ code, id })\n return\n }\n\n if (this.environment.mode !== 'dev') {\n this.error(\n `could not load module ${id}: unknown environment mode ${this.environment.mode}`,\n )\n }\n\n await this.environment.transformRequest(\n `${id}?${SERVER_FN_LOOKUP}`,\n )\n },\n\n resolveId: async (source: string, importer?: string) => {\n const r = await this.resolve(source, importer)\n\n if (r) {\n if (!r.external) {\n return cleanId(r.id)\n }\n }\n\n return null\n },\n })\n\n compilers.set(this.environment.name, compiler)\n }\n\n // Detect which kinds are present in this file before parsing\n const detectedKinds = detectKindsInCode(code, environment.type, {\n compilerTransforms,\n })\n\n const result = await compiler.compile({\n id,\n code,\n detectedKinds,\n })\n return result\n },\n },\n\n hotUpdate(ctx) {\n const compiler = compilers.get(this.environment.name)\n const idsToInvalidate = new Set<string>()\n const transitiveCompilerImportersToInvalidate = new Set<string>()\n const importerModulesToInvalidate = new Set<EnvironmentModuleNode>()\n\n ctx.modules.forEach((m) => {\n if (m.id) {\n idsToInvalidate.add(m.id)\n const deleted = compiler?.invalidateModule(m.id)\n\n if (deleted) {\n transitiveCompilerImportersToInvalidate.add(cleanId(m.id))\n }\n\n if (deleted) {\n m.importers.forEach((importer) => {\n if (importer.id) {\n idsToInvalidate.add(importer.id)\n importerModulesToInvalidate.add(importer)\n transitiveCompilerImportersToInvalidate.add(\n cleanId(importer.id),\n )\n }\n })\n }\n }\n })\n\n const finishHotUpdate = async () => {\n if (environment.type === 'server' && compiler) {\n const pendingImporters = [\n ...transitiveCompilerImportersToInvalidate,\n ]\n const seenImporters = new Set(pendingImporters)\n\n while (pendingImporters.length > 0) {\n const importerId = pendingImporters.pop()!\n const nestedImporters =\n await compiler.getTransitiveImporters(importerId)\n\n for (const nestedImporterId of nestedImporters) {\n if (seenImporters.has(nestedImporterId)) {\n continue\n }\n\n seenImporters.add(nestedImporterId)\n pendingImporters.push(nestedImporterId)\n }\n }\n\n for (const importerId of seenImporters) {\n idsToInvalidate.add(importerId)\n compiler.invalidateModule(importerId)\n }\n }\n\n invalidateModuleNodes(this.environment, importerModulesToInvalidate)\n invalidateServerFnLookupModules(this.environment, idsToInvalidate)\n\n if (environment.type !== 'server') {\n return\n }\n\n invalidateModuleNodes(this.environment, ctx.modules)\n\n const providerIdsToInvalidate =\n getServerFnProviderIds(idsToInvalidate)\n for (const providerId of providerIdsToInvalidate) {\n compiler?.invalidateModule(providerId)\n }\n\n const providerModules = invalidateServerFnProviderModules(\n this.environment,\n [...idsToInvalidate, ...providerIdsToInvalidate],\n )\n\n return mergeHotUpdateModules(ctx.modules, providerModules)\n }\n\n return finishHotUpdate()\n },\n }\n }\n\n return [\n ...opts.environments.map(perEnvServerFnPlugin),\n {\n name: 'tanstack-start-core:capture-server-fn-module-lookup',\n // we only need this plugin in dev mode\n apply: 'serve',\n applyToEnvironment(env) {\n return !!opts.environments.find((e) => e.name === env.name)\n },\n transform: {\n filter: {\n id: new RegExp(`${SERVER_FN_LOOKUP}$`),\n },\n handler(code, id) {\n const compiler = compilers.get(this.environment.name)\n compiler?.ingestModule({ code, id: cleanId(id) })\n },\n },\n },\n // Validate server function ID in dev mode\n {\n name: 'tanstack-start-core:validate-server-fn-id',\n apply: 'serve',\n load: {\n filter: {\n id: new RegExp(resolveViteId(validateServerFnIdVirtualModule)),\n },\n async handler(id) {\n const parsed = parseIdQuery(id)\n const fnId = parsed.query.id\n if (fnId && serverFnsById[fnId]) {\n return `export {}`\n }\n\n // ID not yet registered — the source file may not have been\n // transformed in this dev session yet (e.g. cold restart with\n // cached client). Try to decode the ID, discover the source\n // file, trigger its compilation, and re-check.\n if (fnId) {\n try {\n const decoded = JSON.parse(\n Buffer.from(fnId, 'base64url').toString('utf8'),\n )\n if (\n typeof decoded.file === 'string' &&\n typeof decoded.export === 'string'\n ) {\n // Use the Vite strategy to decode the module specifier\n // back to the original source file path.\n const sourceFile = decodeViteDevServerModuleSpecifier(\n decoded.file,\n )\n\n if (sourceFile) {\n // Resolve to absolute path\n const absPath = resolvePath(root, sourceFile)\n\n // Trigger transform of the source file in this environment,\n // which will compile createServerFn calls and populate\n // serverFnsById as a side effect.\n if (this.environment.mode !== 'dev') {\n this.error(\n `could not validate server function ID ${fnId}: unknown environment mode ${this.environment.mode}`,\n )\n }\n\n await this.environment.transformRequest(\n `${absPath}?${SERVER_FN_LOOKUP}`,\n )\n\n // Re-check after lazy compilation\n if (serverFnsById[fnId]) {\n return `export {}`\n }\n }\n }\n } catch {\n // Decoding or fetching failed — fall through to error\n }\n }\n\n this.error(`Invalid server function ID: ${fnId}`)\n },\n },\n },\n // Manifest plugin for server environments\n createVirtualModule({\n name: 'tanstack-start-core:server-fn-resolver',\n moduleId: VIRTUAL_MODULES.serverFnResolver,\n enforce: 'pre',\n applyToEnvironment: (env) => {\n return appliedResolverEnvironments.has(env.name)\n },\n load() {\n if (this.environment.name !== opts.providerEnvName) {\n const mod = opts.environments.find(\n (e) => e.name === this.environment.name,\n )?.getServerFnById\n if (mod) {\n return mod\n }\n\n this.error(\n `No getServerFnById implementation found for caller environment: ${this.environment.name}`,\n )\n }\n\n if (this.environment.mode !== 'build') {\n return getDevServerFnValidatorModule()\n }\n\n // When SSR is the provider, server-only-referenced functions aren't in the manifest,\n // so no isClientReferenced check is needed.\n // When SSR is NOT the provider (custom provider env), server-only-referenced\n // functions ARE in the manifest and need the isClientReferenced check to\n // block direct client HTTP requests to server-only-referenced functions.\n return generateServerFnResolverModule({\n serverFnsById,\n includeClientReferencedCheck: !ssrIsProvider,\n })\n },\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.169.11",
3
+ "version": "1.169.13",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -86,12 +86,12 @@
86
86
  "vitefu": "^1.1.1",
87
87
  "xmlbuilder2": "^4.0.3",
88
88
  "zod": "^3.24.2",
89
- "@tanstack/router-core": "1.169.0",
90
- "@tanstack/router-generator": "1.166.38",
91
- "@tanstack/router-plugin": "1.167.30",
89
+ "@tanstack/router-core": "1.169.1",
90
+ "@tanstack/router-generator": "1.166.39",
91
+ "@tanstack/router-plugin": "1.167.31",
92
92
  "@tanstack/router-utils": "1.161.7",
93
- "@tanstack/start-client-core": "1.168.0",
94
- "@tanstack/start-server-core": "1.167.25"
93
+ "@tanstack/start-client-core": "1.168.1",
94
+ "@tanstack/start-server-core": "1.167.26"
95
95
  },
96
96
  "devDependencies": {
97
97
  "@rsbuild/core": "^2.0.1",
package/src/index.ts CHANGED
@@ -1,3 +1,8 @@
1
1
  export type { TanStackStartInputConfig } from './schema'
2
- export type { TanStackStartCoreOptions } from './types'
2
+ export type {
3
+ StartCompilerImportTransform,
4
+ StartCompilerTransformCandidate,
5
+ StartCompilerTransformContext,
6
+ TanStackStartCoreOptions,
7
+ } from './types'
3
8
  export { START_ENVIRONMENT_NAMES } from './constants'
@@ -1,4 +1,9 @@
1
1
  export { RSBUILD_ENVIRONMENT_NAMES } from './planning'
2
2
  export type { TanStackStartRsbuildPluginCoreOptions } from './types'
3
3
  export type { TanStackStartRsbuildInputConfig } from './schema'
4
+ export type {
5
+ StartCompilerImportTransform,
6
+ StartCompilerTransformCandidate,
7
+ StartCompilerTransformContext,
8
+ } from '../types'
4
9
  export { tanStackStartRsbuild } from './plugin'
@@ -239,6 +239,9 @@ export function tanStackStartRsbuild(
239
239
  root: () => resolvedStartConfig.root || process.cwd(),
240
240
  providerEnvName: serverFnProviderEnv,
241
241
  generateFunctionId: startPluginOpts.serverFns?.generateFunctionId,
242
+ compilerTransforms: corePluginOpts.compilerTransforms,
243
+ serverFnProviderModuleDirectives:
244
+ corePluginOpts.serverFnProviderModuleDirectives,
242
245
  serverFnsById,
243
246
  onServerFnsByIdChange: () => {
244
247
  updateServerFnResolver?.()