{"version":3,"file":"index.cjs","sources":["../../src/index.ts"],"sourcesContent":["import {\n  TanStackDirectiveFunctionsPlugin,\n  TanStackDirectiveFunctionsPluginEnv,\n} from '@tanstack/directive-functions-plugin'\nimport type { DevEnvironment, Plugin, ViteDevServer } from 'vite'\nimport type {\n  DirectiveFn,\n  ReplacerFn,\n} from '@tanstack/directive-functions-plugin'\n\nexport type CreateRpcFn = (\n  functionId: string,\n  serverBase: string,\n  splitImportFn?: string,\n) => any\n\nexport type ServerFnPluginOpts = {\n  /**\n   * The virtual import ID that will be used to import the server function manifest.\n   * This virtual import ID will be used in the server build to import the manifest\n   * and its modules.\n   */\n  manifestVirtualImportId: string\n  client: ServerFnPluginEnvOpts\n  ssr: ServerFnPluginEnvOpts\n  server: ServerFnPluginEnvOpts\n}\n\nexport type ServerFnPluginEnvOpts = {\n  getRuntimeCode: () => string\n  replacer: ReplacerFn\n}\n\nconst debug =\n  process.env.TSR_VITE_DEBUG &&\n  ['true', 'server-functions-plugin'].includes(process.env.TSR_VITE_DEBUG)\n\nexport function createTanStackServerFnPlugin(opts: ServerFnPluginOpts): {\n  client: Array<Plugin>\n  ssr: Array<Plugin>\n  server: Array<Plugin>\n} {\n  const directiveFnsById: Record<string, DirectiveFn> = {}\n  let viteDevServer: ViteDevServer | undefined\n\n  const onDirectiveFnsById = buildOnDirectiveFnsByIdCallback({\n    directiveFnsById,\n    manifestVirtualImportId: opts.manifestVirtualImportId,\n    invalidateModule: (id) => {\n      if (viteDevServer) {\n        const mod = viteDevServer.moduleGraph.getModuleById(id)\n        if (mod) {\n          if (debug) {\n            console.info(`invalidating module ${JSON.stringify(mod.id)}`)\n          }\n          viteDevServer.moduleGraph.invalidateModule(mod)\n        }\n      }\n    },\n  })\n\n  const directive = 'use server'\n  const directiveLabel = 'Server Function'\n\n  return {\n    client: [\n      // The client plugin is used to compile the client directives\n      // and save them so we can create a manifest\n      TanStackDirectiveFunctionsPlugin({\n        envLabel: 'Client',\n        directive,\n        directiveLabel,\n        getRuntimeCode: opts.client.getRuntimeCode,\n        replacer: opts.client.replacer,\n        onDirectiveFnsById,\n      }),\n    ],\n    ssr: [\n      // The SSR plugin is used to compile the server directives\n      TanStackDirectiveFunctionsPlugin({\n        envLabel: 'SSR',\n        directive,\n        directiveLabel,\n        getRuntimeCode: opts.ssr.getRuntimeCode,\n        replacer: opts.ssr.replacer,\n        onDirectiveFnsById,\n      }),\n    ],\n    server: [\n      {\n        // On the server, we need to be able to read the server-function manifest from the client build.\n        // This is likely used in the handler for server functions, so we can find the server function\n        // by its ID, import it, and call it.\n        name: 'tanstack-start-server-fn-vite-plugin-manifest-server',\n        enforce: 'pre',\n        configureServer(server) {\n          viteDevServer = server\n        },\n        resolveId(id) {\n          if (id === opts.manifestVirtualImportId) {\n            return resolveViteId(id)\n          }\n\n          return undefined\n        },\n        load(id) {\n          if (id !== resolveViteId(opts.manifestVirtualImportId)) {\n            return undefined\n          }\n\n          const manifestWithImports = `\n          export default {${Object.entries(directiveFnsById)\n            .map(\n              ([id, fn]: any) =>\n                `'${id}': {\n                  functionName: '${fn.functionName}',\n                  importer: () => import(${JSON.stringify(fn.extractedFilename)})\n                }`,\n            )\n            .join(',')}}`\n\n          return manifestWithImports\n        },\n      },\n      // On the server, we need to compile the server functions\n      // so they can be called by other server functions.\n      // This is also where we split the server function into a separate file\n      // so we can load them on demand in the worker.\n      TanStackDirectiveFunctionsPlugin({\n        envLabel: 'Server',\n        directive,\n        directiveLabel,\n        getRuntimeCode: opts.server.getRuntimeCode,\n        replacer: opts.server.replacer,\n        onDirectiveFnsById,\n      }),\n    ],\n  }\n}\n\nexport interface TanStackServerFnPluginEnvOpts {\n  /**\n   * The virtual import ID that will be used to import the server function manifest.\n   * This virtual import ID will be used in the server build to import the manifest\n   * and its modules.\n   */\n  manifestVirtualImportId: string\n  client: {\n    envName?: string\n    getRuntimeCode: () => string\n    replacer: ReplacerFn\n  }\n  server: {\n    envName?: string\n    getRuntimeCode: () => string\n    replacer: ReplacerFn\n  }\n}\n\nexport function TanStackServerFnPluginEnv(\n  _opts: TanStackServerFnPluginEnvOpts,\n): Array<Plugin> {\n  const opts = {\n    ..._opts,\n    client: {\n      ..._opts.client,\n      envName: _opts.client.envName || 'client',\n    },\n    server: {\n      ..._opts.server,\n      envName: _opts.server.envName || 'server',\n    },\n  }\n\n  const directiveFnsById: Record<string, DirectiveFn> = {}\n  let serverDevEnv: DevEnvironment | undefined\n\n  const onDirectiveFnsById = buildOnDirectiveFnsByIdCallback({\n    directiveFnsById,\n    manifestVirtualImportId: opts.manifestVirtualImportId,\n    invalidateModule: (id) => {\n      if (serverDevEnv) {\n        const mod = serverDevEnv.moduleGraph.getModuleById(id)\n        if (mod) {\n          if (debug) {\n            console.info(\n              `invalidating module ${JSON.stringify(mod.id)} in server environment`,\n            )\n          }\n          serverDevEnv.moduleGraph.invalidateModule(mod)\n        }\n      }\n    },\n  })\n\n  const directive = 'use server'\n  const directiveLabel = 'Server Function'\n\n  return [\n    // The client plugin is used to compile the client directives\n    // and save them so we can create a manifest\n    TanStackDirectiveFunctionsPluginEnv({\n      directive,\n      directiveLabel,\n      onDirectiveFnsById,\n      environments: {\n        client: {\n          envLabel: 'Client',\n          getRuntimeCode: opts.client.getRuntimeCode,\n          replacer: opts.client.replacer,\n          envName: opts.client.envName,\n        },\n        server: {\n          envLabel: 'Server',\n          getRuntimeCode: opts.server.getRuntimeCode,\n          replacer: opts.server.replacer,\n          envName: opts.server.envName,\n        },\n      },\n    }),\n    {\n      // On the server, we need to be able to read the server-function manifest from the client build.\n      // This is likely used in the handler for server functions, so we can find the server function\n      // by its ID, import it, and call it.\n      name: 'tanstack-start-server-fn-vite-plugin-manifest-server',\n      enforce: 'pre',\n      configureServer(viteDevServer) {\n        serverDevEnv = viteDevServer.environments[opts.server.envName]\n        if (!serverDevEnv) {\n          throw new Error(\n            `TanStackServerFnPluginEnv: environment \"${opts.server.envName}\" not found`,\n          )\n        }\n      },\n      resolveId: {\n        filter: { id: new RegExp(opts.manifestVirtualImportId) },\n        handler(id) {\n          return resolveViteId(id)\n        },\n      },\n      load: {\n        filter: { id: new RegExp(resolveViteId(opts.manifestVirtualImportId)) },\n        handler() {\n          if (this.environment.name !== opts.server.envName) {\n            return `export default {}`\n          }\n          const manifestWithImports = `\n          export default {${Object.entries(directiveFnsById)\n            .map(\n              ([id, fn]: any) =>\n                `'${id}': {\n                  functionName: '${fn.functionName}',\n                  importer: () => import(${JSON.stringify(fn.extractedFilename)})\n                }`,\n            )\n            .join(',')}}`\n\n          return manifestWithImports\n        },\n      },\n    },\n  ]\n}\n\nfunction resolveViteId(id: string) {\n  return `\\0${id}`\n}\n\nfunction buildOnDirectiveFnsByIdCallback(opts: {\n  invalidateModule: (resolvedId: string) => void\n  directiveFnsById: Record<string, DirectiveFn>\n  manifestVirtualImportId: string\n}) {\n  const onDirectiveFnsById = (d: Record<string, DirectiveFn>) => {\n    if (debug) {\n      console.info(`onDirectiveFnsById received: `, d)\n    }\n\n    // do we already know all the server functions? if so, we can exit early\n    // this could happen if the same file is compiled first in the client and then in the server environment\n    const newKeys = Object.keys(d).filter(\n      (key) => !(key in opts.directiveFnsById),\n    )\n    if (newKeys.length > 0) {\n      // When directives are compiled, save them to `directiveFnsById`\n      // This state will be used both during development to incrementally\n      // look up server functions and during build/production to produce a\n      // static manifest that can be read by the server build\n      Object.assign(opts.directiveFnsById, d)\n      if (debug) {\n        console.info(`directiveFnsById after update: `, opts.directiveFnsById)\n      }\n\n      opts.invalidateModule(resolveViteId(opts.manifestVirtualImportId))\n    }\n  }\n  return onDirectiveFnsById\n}\n"],"names":["TanStackDirectiveFunctionsPlugin","id","TanStackDirectiveFunctionsPluginEnv"],"mappings":";;;AAiCA,MAAM,QACJ,QAAQ,IAAI,kBACZ,CAAC,QAAQ,yBAAyB,EAAE,SAAS,QAAQ,IAAI,cAAc;AAElE,SAAS,6BAA6B,MAI3C;AACA,QAAM,mBAAgD,CAAC;AACnD,MAAA;AAEJ,QAAM,qBAAqB,gCAAgC;AAAA,IACzD;AAAA,IACA,yBAAyB,KAAK;AAAA,IAC9B,kBAAkB,CAAC,OAAO;AACxB,UAAI,eAAe;AACjB,cAAM,MAAM,cAAc,YAAY,cAAc,EAAE;AACtD,YAAI,KAAK;AACP,cAAI,OAAO;AACT,oBAAQ,KAAK,uBAAuB,KAAK,UAAU,IAAI,EAAE,CAAC,EAAE;AAAA,UAAA;AAEhD,wBAAA,YAAY,iBAAiB,GAAG;AAAA,QAAA;AAAA,MAChD;AAAA,IACF;AAAA,EACF,CACD;AAED,QAAM,YAAY;AAClB,QAAM,iBAAiB;AAEhB,SAAA;AAAA,IACL,QAAQ;AAAA;AAAA;AAAA,MAGNA,0DAAiC;AAAA,QAC/B,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA,gBAAgB,KAAK,OAAO;AAAA,QAC5B,UAAU,KAAK,OAAO;AAAA,QACtB;AAAA,MACD,CAAA;AAAA,IACH;AAAA,IACA,KAAK;AAAA;AAAA,MAEHA,0DAAiC;AAAA,QAC/B,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA,gBAAgB,KAAK,IAAI;AAAA,QACzB,UAAU,KAAK,IAAI;AAAA,QACnB;AAAA,MACD,CAAA;AAAA,IACH;AAAA,IACA,QAAQ;AAAA,MACN;AAAA;AAAA;AAAA;AAAA,QAIE,MAAM;AAAA,QACN,SAAS;AAAA,QACT,gBAAgB,QAAQ;AACN,0BAAA;AAAA,QAClB;AAAA,QACA,UAAU,IAAI;AACR,cAAA,OAAO,KAAK,yBAAyB;AACvC,mBAAO,cAAc,EAAE;AAAA,UAAA;AAGlB,iBAAA;AAAA,QACT;AAAA,QACA,KAAK,IAAI;AACP,cAAI,OAAO,cAAc,KAAK,uBAAuB,GAAG;AAC/C,mBAAA;AAAA,UAAA;AAGT,gBAAM,sBAAsB;AAAA,4BACV,OAAO,QAAQ,gBAAgB,EAC9C;AAAA,YACC,CAAC,CAACC,KAAI,EAAE,MACN,IAAIA,GAAE;AAAA,mCACa,GAAG,YAAY;AAAA,2CACP,KAAK,UAAU,GAAG,iBAAiB,CAAC;AAAA;AAAA,UAAA,EAGlE,KAAK,GAAG,CAAC;AAEL,iBAAA;AAAA,QAAA;AAAA,MAEX;AAAA;AAAA;AAAA;AAAA;AAAA,MAKAD,0DAAiC;AAAA,QAC/B,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA,gBAAgB,KAAK,OAAO;AAAA,QAC5B,UAAU,KAAK,OAAO;AAAA,QACtB;AAAA,MACD,CAAA;AAAA,IAAA;AAAA,EAEL;AACF;AAqBO,SAAS,0BACd,OACe;AACf,QAAM,OAAO;AAAA,IACX,GAAG;AAAA,IACH,QAAQ;AAAA,MACN,GAAG,MAAM;AAAA,MACT,SAAS,MAAM,OAAO,WAAW;AAAA,IACnC;AAAA,IACA,QAAQ;AAAA,MACN,GAAG,MAAM;AAAA,MACT,SAAS,MAAM,OAAO,WAAW;AAAA,IAAA;AAAA,EAErC;AAEA,QAAM,mBAAgD,CAAC;AACnD,MAAA;AAEJ,QAAM,qBAAqB,gCAAgC;AAAA,IACzD;AAAA,IACA,yBAAyB,KAAK;AAAA,IAC9B,kBAAkB,CAAC,OAAO;AACxB,UAAI,cAAc;AAChB,cAAM,MAAM,aAAa,YAAY,cAAc,EAAE;AACrD,YAAI,KAAK;AACP,cAAI,OAAO;AACD,oBAAA;AAAA,cACN,uBAAuB,KAAK,UAAU,IAAI,EAAE,CAAC;AAAA,YAC/C;AAAA,UAAA;AAEW,uBAAA,YAAY,iBAAiB,GAAG;AAAA,QAAA;AAAA,MAC/C;AAAA,IACF;AAAA,EACF,CACD;AAED,QAAM,YAAY;AAClB,QAAM,iBAAiB;AAEhB,SAAA;AAAA;AAAA;AAAA,IAGLE,6DAAoC;AAAA,MAClC;AAAA,MACA;AAAA,MACA;AAAA,MACA,cAAc;AAAA,QACZ,QAAQ;AAAA,UACN,UAAU;AAAA,UACV,gBAAgB,KAAK,OAAO;AAAA,UAC5B,UAAU,KAAK,OAAO;AAAA,UACtB,SAAS,KAAK,OAAO;AAAA,QACvB;AAAA,QACA,QAAQ;AAAA,UACN,UAAU;AAAA,UACV,gBAAgB,KAAK,OAAO;AAAA,UAC5B,UAAU,KAAK,OAAO;AAAA,UACtB,SAAS,KAAK,OAAO;AAAA,QAAA;AAAA,MACvB;AAAA,IACF,CACD;AAAA,IACD;AAAA;AAAA;AAAA;AAAA,MAIE,MAAM;AAAA,MACN,SAAS;AAAA,MACT,gBAAgB,eAAe;AAC7B,uBAAe,cAAc,aAAa,KAAK,OAAO,OAAO;AAC7D,YAAI,CAAC,cAAc;AACjB,gBAAM,IAAI;AAAA,YACR,2CAA2C,KAAK,OAAO,OAAO;AAAA,UAChE;AAAA,QAAA;AAAA,MAEJ;AAAA,MACA,WAAW;AAAA,QACT,QAAQ,EAAE,IAAI,IAAI,OAAO,KAAK,uBAAuB,EAAE;AAAA,QACvD,QAAQ,IAAI;AACV,iBAAO,cAAc,EAAE;AAAA,QAAA;AAAA,MAE3B;AAAA,MACA,MAAM;AAAA,QACJ,QAAQ,EAAE,IAAI,IAAI,OAAO,cAAc,KAAK,uBAAuB,CAAC,EAAE;AAAA,QACtE,UAAU;AACR,cAAI,KAAK,YAAY,SAAS,KAAK,OAAO,SAAS;AAC1C,mBAAA;AAAA,UAAA;AAET,gBAAM,sBAAsB;AAAA,4BACV,OAAO,QAAQ,gBAAgB,EAC9C;AAAA,YACC,CAAC,CAAC,IAAI,EAAE,MACN,IAAI,EAAE;AAAA,mCACa,GAAG,YAAY;AAAA,2CACP,KAAK,UAAU,GAAG,iBAAiB,CAAC;AAAA;AAAA,UAAA,EAGlE,KAAK,GAAG,CAAC;AAEL,iBAAA;AAAA,QAAA;AAAA,MACT;AAAA,IACF;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc,IAAY;AACjC,SAAO,KAAK,EAAE;AAChB;AAEA,SAAS,gCAAgC,MAItC;AACK,QAAA,qBAAqB,CAAC,MAAmC;AAC7D,QAAI,OAAO;AACD,cAAA,KAAK,iCAAiC,CAAC;AAAA,IAAA;AAKjD,UAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,MAC7B,CAAC,QAAQ,EAAE,OAAO,KAAK;AAAA,IACzB;AACI,QAAA,QAAQ,SAAS,GAAG;AAKf,aAAA,OAAO,KAAK,kBAAkB,CAAC;AACtC,UAAI,OAAO;AACD,gBAAA,KAAK,mCAAmC,KAAK,gBAAgB;AAAA,MAAA;AAGvE,WAAK,iBAAiB,cAAc,KAAK,uBAAuB,CAAC;AAAA,IAAA;AAAA,EAErE;AACO,SAAA;AACT;;;"}