{"version":3,"file":"index.mjs","names":[],"sources":["../src/plugin.ts"],"sourcesContent":["import type { ContractEmitResult } from '@prisma-next/cli/control-api';\nimport { disposeEmitQueue, executeContractEmit } from '@prisma-next/cli/control-api';\nimport { loadConfig } from '@prisma-next/config-loader';\nimport { getEmittedArtifactPaths } from '@prisma-next/emitter';\nimport { extname, resolve } from 'pathe';\nimport type { Plugin, ViteDevServer } from 'vite';\nimport type { PrismaVitePluginOptions } from './types';\n\nconst PLUGIN_NAME = 'prisma-vite-plugin-contract-emit';\nconst DEFAULT_DEBOUNCE_MS = 150;\nconst DEFAULT_CONFIG_PATH = 'prisma-next.config.ts';\nconst MODULE_GRAPH_EXTENSIONS = new Set([\n  '.js',\n  '.jsx',\n  '.mjs',\n  '.cjs',\n  '.ts',\n  '.tsx',\n  '.mts',\n  '.cts',\n]);\n\n/**\n * Creates a Vite plugin that automatically emits Prisma Next contract artifacts.\n *\n * The plugin resolves watched files from contract source provider metadata,\n * re-emitting contract artifacts on changes with debounce while serializing\n * overlapping emits into a single follow-up run.\n *\n * @param configPath - Path to prisma-next.config.ts (relative or absolute). Defaults to 'prisma-next.config.ts'\n * @param options - Optional plugin configuration\n * @returns Vite plugin\n *\n * @example\n * ```ts\n * import { defineConfig } from 'vite';\n * import { prismaVitePlugin } from '@prisma-next/vite-plugin-contract-emit';\n *\n * // Use default config path\n * export default defineConfig({\n *   plugins: [prismaVitePlugin()],\n * });\n *\n * // Or specify a custom path\n * export default defineConfig({\n *   plugins: [prismaVitePlugin('custom/prisma-next.config.ts')],\n * });\n * ```\n */\nexport function prismaVitePlugin(\n  configPath: string = DEFAULT_CONFIG_PATH,\n  options?: PrismaVitePluginOptions,\n): Plugin {\n  const debounceMs = options?.debounceMs ?? DEFAULT_DEBOUNCE_MS;\n  const logLevel = options?.logLevel ?? 'info';\n\n  let absoluteConfigPath: string;\n  const watchedFiles = new Set<string>();\n  // Vite watches the project root, so writes to emitted artifacts can still surface as change\n  // events even when those files are excluded from watchedFiles.\n  const ignoredOutputFiles = new Set<string>();\n  // Output JSON paths whose serialization queue this plugin instance owns. Disposed on cleanup\n  // so long-lived dev sessions don't accumulate per-process queue state across config edits.\n  const ownedOutputJsonPaths = new Set<string>();\n  let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n  let lifecycleAbortController = new AbortController();\n  let server: ViteDevServer | null = null;\n  let isEmitInFlight = false;\n  let hasQueuedEmit = false;\n  let queuedEmitNeedsWatchedFileRefresh = false;\n  let didWarnConfigWatchFallback = false;\n\n  function log(message: string, level: 'info' | 'debug' = 'info') {\n    if (logLevel === 'silent') return;\n    if (level === 'debug' && logLevel !== 'debug') return;\n    console.log(`[${PLUGIN_NAME}] ${message}`);\n  }\n\n  function logError(message: string, error?: unknown) {\n    if (logLevel === 'silent') return;\n    const errorMessage = error instanceof Error ? error.message : error ? String(error) : '';\n    console.error(`[${PLUGIN_NAME}] ${message}${errorMessage ? ` ${errorMessage}` : ''}`);\n    if (error instanceof Error && error.stack && logLevel === 'debug') {\n      console.error(error.stack);\n    }\n  }\n\n  function logWarning(message: string) {\n    if (logLevel === 'silent') return;\n    console.warn(`[${PLUGIN_NAME}] ${message}`);\n  }\n\n  function handleTrackedFileChange(file: string) {\n    const normalized = resolve(file);\n    if (ignoredOutputFiles.has(normalized)) {\n      log(`Ignoring emitted artifact update: ${normalized}`, 'debug');\n      return;\n    }\n\n    if (watchedFiles.has(normalized)) {\n      log(`Detected change: ${normalized}`, 'debug');\n      scheduleEmit();\n    }\n  }\n\n  async function emitContract({\n    refreshWatchedFiles = true,\n  }: {\n    refreshWatchedFiles?: boolean;\n  } = {}): Promise<ContractEmitResult | null> {\n    const signal = lifecycleAbortController.signal;\n\n    try {\n      if (server && refreshWatchedFiles) {\n        await updateWatchedFiles(server);\n      }\n\n      const result = await executeContractEmit({\n        configPath: absoluteConfigPath,\n        signal,\n      });\n\n      log(`Emitted contract (storageHash: ${result.storageHash.slice(0, 8)}...)`);\n      log(`  → ${result.files.json}`, 'debug');\n      log(`  → ${result.files.dts}`, 'debug');\n\n      if (server) {\n        server.moduleGraph.onFileChange(result.files.json);\n        server.moduleGraph.onFileChange(result.files.dts);\n      }\n\n      if (server && !hasQueuedEmit) {\n        server.ws.send({ type: 'full-reload' });\n      } else if (hasQueuedEmit) {\n        log('Skipped full reload because a newer emit is queued', 'debug');\n      }\n\n      return result;\n    } catch (error) {\n      // Ignore cancellation - check signal first, then error name\n      if (signal.aborted || (error instanceof Error && error.name === 'AbortError')) {\n        log('Emit cancelled', 'debug');\n        return null;\n      }\n\n      logError('Contract emit failed:', error);\n\n      // Send error to Vite overlay\n      if (server) {\n        const errorMessage = error instanceof Error ? error.message : String(error);\n        const errorStack = error instanceof Error ? error.stack : undefined;\n        server.ws.send({\n          type: 'error',\n          err: {\n            message: `[prisma-next] ${errorMessage}`,\n            stack: errorStack ?? '',\n            plugin: PLUGIN_NAME,\n          },\n        });\n      }\n\n      return null;\n    }\n  }\n\n  async function drainQueuedEmits(): Promise<void> {\n    if (isEmitInFlight || lifecycleAbortController.signal.aborted) {\n      return;\n    }\n\n    isEmitInFlight = true;\n\n    try {\n      while (hasQueuedEmit && !lifecycleAbortController.signal.aborted) {\n        const refreshWatchedFiles = queuedEmitNeedsWatchedFileRefresh;\n        hasQueuedEmit = false;\n        queuedEmitNeedsWatchedFileRefresh = false;\n\n        await emitContract({ refreshWatchedFiles });\n      }\n    } finally {\n      isEmitInFlight = false;\n    }\n  }\n\n  function requestEmit({\n    refreshWatchedFiles = true,\n  }: {\n    refreshWatchedFiles?: boolean;\n  } = {}): Promise<void> {\n    if (lifecycleAbortController.signal.aborted) {\n      return Promise.resolve();\n    }\n\n    hasQueuedEmit = true;\n    queuedEmitNeedsWatchedFileRefresh ||= refreshWatchedFiles;\n\n    if (isEmitInFlight) {\n      log('Queued follow-up emit while another emit is running', 'debug');\n      return Promise.resolve();\n    }\n\n    return drainQueuedEmits();\n  }\n\n  function scheduleEmit() {\n    if (debounceTimer) {\n      clearTimeout(debounceTimer);\n    }\n    debounceTimer = setTimeout(() => {\n      debounceTimer = null;\n      void requestEmit();\n    }, debounceMs);\n  }\n\n  function resolveContractOutputFiles(contractOutput: string | undefined): Set<string> {\n    if (contractOutput === undefined) {\n      return new Set();\n    }\n    const { jsonPath, dtsPath } = getEmittedArtifactPaths(contractOutput);\n    ownedOutputJsonPaths.add(jsonPath);\n    return new Set<string>([jsonPath, dtsPath]);\n  }\n\n  function isModuleGraphRoot(filePath: string): boolean {\n    return MODULE_GRAPH_EXTENSIONS.has(extname(filePath));\n  }\n\n  async function collectModuleGraphFiles(\n    viteServer: ViteDevServer,\n    roots: readonly string[],\n  ): Promise<Set<string>> {\n    const files = new Set<string>();\n    const uniqueRoots = [...new Set(roots)];\n\n    for (const root of uniqueRoots) {\n      try {\n        await viteServer.ssrLoadModule(root);\n      } catch (error) {\n        if (root === absoluteConfigPath) {\n          logError('Failed to load config module graph root:', error);\n        } else {\n          log(`Skipped module-graph root after load failure: ${root}`, 'debug');\n        }\n      }\n    }\n\n    try {\n      const visited = new Set<string>();\n      const queue = [...uniqueRoots];\n\n      while (queue.length > 0) {\n        const current = queue.shift();\n        if (current === undefined || visited.has(current)) continue;\n        visited.add(current);\n\n        const mod = viteServer.moduleGraph.getModuleById(current);\n        if (!mod) continue;\n\n        // Add file to watched set if it's a file path\n        if (mod.file) {\n          files.add(mod.file);\n        }\n\n        // Add imported modules to queue\n        for (const imported of mod.importedModules) {\n          if (imported.id && !visited.has(imported.id)) {\n            queue.push(imported.id);\n          }\n        }\n      }\n    } catch (error) {\n      logError('Failed to collect watched files:', error);\n    }\n\n    return files;\n  }\n\n  async function resolveWatchedFiles(viteServer: ViteDevServer): Promise<Set<string>> {\n    const previousWatchedFiles = new Set(watchedFiles);\n    const previousIgnoredOutputFiles = new Set(ignoredOutputFiles);\n    ignoredOutputFiles.clear();\n\n    try {\n      const config = await loadConfig(absoluteConfigPath);\n      didWarnConfigWatchFallback = false;\n      const contract = config.contract;\n\n      if (!contract) {\n        return new Set([absoluteConfigPath]);\n      }\n\n      const files = new Set<string>([absoluteConfigPath]);\n      const inputs = contract.source.inputs ?? [];\n      for (const outputFile of resolveContractOutputFiles(contract.output)) {\n        ignoredOutputFiles.add(outputFile);\n      }\n\n      const moduleGraphRoots = [absoluteConfigPath];\n      for (const input of inputs) {\n        if (!ignoredOutputFiles.has(input)) {\n          files.add(input);\n        }\n        if (isModuleGraphRoot(input)) {\n          moduleGraphRoots.push(input);\n        }\n      }\n\n      for (const file of await collectModuleGraphFiles(viteServer, moduleGraphRoots)) {\n        if (!ignoredOutputFiles.has(file)) {\n          files.add(file);\n        }\n      }\n\n      return files;\n    } catch (error) {\n      if (previousIgnoredOutputFiles.size > 0) {\n        for (const outputFile of previousIgnoredOutputFiles) {\n          ignoredOutputFiles.add(outputFile);\n        }\n      }\n      if (!didWarnConfigWatchFallback) {\n        didWarnConfigWatchFallback = true;\n        const reason = error instanceof Error ? ` ${error.message}` : '';\n        const watchScope =\n          previousWatchedFiles.size > 0\n            ? `Watching the previous dependency set plus ${absoluteConfigPath}`\n            : `Watching only ${absoluteConfigPath}`;\n        logWarning(\n          `${watchScope} because Prisma Next config inputs could not be resolved.${reason} Contract watch coverage is partial.`,\n        );\n      }\n      if (previousWatchedFiles.size > 0) {\n        previousWatchedFiles.add(absoluteConfigPath);\n        return previousWatchedFiles;\n      }\n      return new Set([absoluteConfigPath]);\n    }\n  }\n\n  async function updateWatchedFiles(viteServer: ViteDevServer): Promise<void> {\n    const newWatchedFiles = await resolveWatchedFiles(viteServer);\n\n    // Find files to add and remove\n    const toAdd: string[] = [];\n    const toRemove: string[] = [];\n\n    for (const file of newWatchedFiles) {\n      if (!watchedFiles.has(file)) {\n        toAdd.push(file);\n      }\n    }\n\n    for (const file of watchedFiles) {\n      if (!newWatchedFiles.has(file)) {\n        toRemove.push(file);\n      }\n    }\n\n    // Update the watcher\n    for (const file of toAdd) {\n      viteServer.watcher.add(file);\n    }\n    for (const file of toRemove) {\n      viteServer.watcher.unwatch(file);\n    }\n\n    // Replace the watched files set\n    watchedFiles.clear();\n    for (const file of newWatchedFiles) {\n      watchedFiles.add(file);\n    }\n\n    if (toAdd.length > 0 || toRemove.length > 0) {\n      log(`Updated watched files: +${toAdd.length} -${toRemove.length}`, 'debug');\n    }\n  }\n\n  return {\n    name: PLUGIN_NAME,\n\n    configResolved(config) {\n      // Resolve config path to absolute path based on Vite root\n      absoluteConfigPath = resolve(config.root, configPath);\n      log(`Config path: ${absoluteConfigPath}`, 'debug');\n    },\n\n    async configureServer(viteServer) {\n      server = viteServer;\n      lifecycleAbortController = new AbortController();\n      isEmitInFlight = false;\n      hasQueuedEmit = false;\n      queuedEmitNeedsWatchedFileRefresh = false;\n      const onTrackedWatcherEvent = (file: string) => {\n        handleTrackedFileChange(file);\n      };\n\n      // Register close hook to clean up timers and abort in-flight work.\n      const cleanup = () => {\n        if (debounceTimer) {\n          clearTimeout(debounceTimer);\n          debounceTimer = null;\n        }\n        hasQueuedEmit = false;\n        queuedEmitNeedsWatchedFileRefresh = false;\n        lifecycleAbortController.abort();\n        viteServer.watcher.off?.('change', onTrackedWatcherEvent);\n        viteServer.watcher.off?.('add', onTrackedWatcherEvent);\n        viteServer.watcher.off?.('unlink', onTrackedWatcherEvent);\n        ignoredOutputFiles.clear();\n        for (const outputJsonPath of ownedOutputJsonPaths) {\n          disposeEmitQueue(outputJsonPath);\n        }\n        ownedOutputJsonPaths.clear();\n        didWarnConfigWatchFallback = false;\n        server = null;\n        watchedFiles.clear();\n        log('Server closed, cleaned up resources', 'debug');\n      };\n\n      // Register cleanup on server close via httpServer or watcher\n      viteServer.httpServer?.on('close', cleanup);\n      viteServer.watcher?.on?.('close', cleanup);\n      viteServer.watcher.on('change', onTrackedWatcherEvent);\n      viteServer.watcher.on('add', onTrackedWatcherEvent);\n      viteServer.watcher.on('unlink', onTrackedWatcherEvent);\n\n      const initialWatchedFiles = await resolveWatchedFiles(viteServer);\n\n      // Collect files to watch from provider metadata\n      for (const file of initialWatchedFiles) {\n        watchedFiles.add(file);\n      }\n\n      // Add all dependency files to Vite's watcher\n      for (const file of watchedFiles) {\n        viteServer.watcher.add(file);\n      }\n\n      // Error if no files are being watched - this indicates a configuration problem\n      if (watchedFiles.size === 0) {\n        const errorMessage =\n          `No files are being watched. The config file \"${absoluteConfigPath}\" could not be loaded ` +\n          'or has no dependencies. HMR for contract changes will not work.';\n        logError(errorMessage);\n        viteServer.ws.send({\n          type: 'error',\n          err: {\n            message: `[prisma-next] ${errorMessage}`,\n            stack: '',\n            plugin: PLUGIN_NAME,\n          },\n        });\n      } else {\n        log(`Watching ${watchedFiles.size} files`, 'debug');\n        if (logLevel === 'debug') {\n          for (const file of watchedFiles) {\n            log(`  ${file}`, 'debug');\n          }\n        }\n      }\n\n      // Initial emit on server start\n      await requestEmit({ refreshWatchedFiles: false });\n    },\n\n    handleHotUpdate(ctx) {\n      handleTrackedFileChange(ctx.file);\n    },\n  };\n}\n"],"mappings":"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"}