{"version":3,"file":"watch-mode.mjs","sources":["../../../../src/lib/routing/discovery/watch-mode.ts"],"sourcesContent":["/**\n * @file Watch Mode for Route Discovery\n * @description Provides hot-reloading route discovery for development environments.\n * Monitors file system changes and triggers incremental route updates.\n *\n * @module @/lib/routing/discovery/watch-mode\n *\n * This module provides:\n * - File system watching for route changes\n * - Debounced change processing\n * - Incremental route updates\n * - HMR integration hooks\n * - Development server integration\n *\n * @example\n * ```typescript\n * import { WatchMode, createWatchMode } from '@/lib/routing/discovery/watch-mode';\n *\n * const watcher = createWatchMode({\n *   rootDir: process.cwd(),\n *   onRoutesChanged: (routes) => {\n *     console.log('Routes updated:', routes.length);\n *   },\n * });\n *\n * await watcher.start();\n * // ... later\n * await watcher.stop();\n * ```\n */\n\nimport {\n  DiscoveryEngine,\n  type DiscoveryResult,\n  type DiscoveryEngineConfig,\n} from './discovery-engine';\nimport type { TransformedRoute } from './route-transformer';\nimport { isProd } from '@/lib/core/config/env-helper';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Watch mode configuration\n */\nexport interface WatchModeConfig {\n  /** Root directory to watch */\n  readonly rootDir: string;\n  /** Directories to watch (relative to rootDir) */\n  readonly watchPaths?: readonly string[];\n  /** File extensions to watch */\n  readonly extensions?: readonly string[];\n  /** Patterns to ignore */\n  readonly ignorePatterns?: readonly string[];\n  /** Debounce delay in milliseconds */\n  readonly debounceMs?: number;\n  /** Enable verbose logging */\n  readonly verbose?: boolean;\n  /** Discovery engine configuration */\n  readonly discovery?: Partial<DiscoveryEngineConfig>;\n  /** Called when routes change */\n  readonly onRoutesChanged?: (routes: readonly TransformedRoute[], result: DiscoveryResult) => void;\n  /** Called when a file is added */\n  readonly onFileAdded?: (filePath: string) => void;\n  /** Called when a file is removed */\n  readonly onFileRemoved?: (filePath: string) => void;\n  /** Called when a file is changed */\n  readonly onFileChanged?: (filePath: string) => void;\n  /** Called when an error occurs */\n  readonly onError?: (error: Error) => void;\n  /** Feature flag for watch mode */\n  readonly featureFlag?: string;\n}\n\n/**\n * File change event\n */\nexport interface FileChangeEvent {\n  /** Change type */\n  readonly type: 'add' | 'change' | 'unlink';\n  /** Absolute file path */\n  readonly path: string;\n  /** Relative path from root */\n  readonly relativePath: string;\n  /** Timestamp of change */\n  readonly timestamp: number;\n}\n\n/**\n * Watch mode state\n */\nexport type WatchModeState = 'stopped' | 'starting' | 'running' | 'stopping' | 'error';\n\n/**\n * Watch mode statistics\n */\nexport interface WatchModeStats {\n  /** Total files watched */\n  readonly filesWatched: number;\n  /** Directories watched */\n  readonly directoriesWatched: number;\n  /** Total changes processed */\n  readonly changesProcessed: number;\n  /** Total rediscoveries performed */\n  readonly rediscoveries: number;\n  /** Average rediscovery time (ms) */\n  readonly avgRediscoveryMs: number;\n  /** Watch mode uptime (ms) */\n  readonly uptimeMs: number;\n  /** Last change timestamp */\n  readonly lastChangeAt: number | null;\n  /** Last rediscovery timestamp */\n  readonly lastRediscoveryAt: number | null;\n}\n\n/**\n * Watcher interface (abstraction over fs.watch/chokidar)\n */\ninterface FileWatcher {\n  on(event: 'add', handler: (path: string) => void): this;\n  on(event: 'change', handler: (path: string) => void): this;\n  on(event: 'unlink', handler: (path: string) => void): this;\n  on(event: 'error', handler: (error: Error) => void): this;\n  on(event: 'ready', handler: () => void): this;\n  close(): Promise<void>;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/**\n * Default watch mode configuration\n */\nexport const DEFAULT_WATCH_MODE_CONFIG: Partial<WatchModeConfig> = {\n  watchPaths: ['src/routes', 'src/pages', 'src/app'],\n  extensions: ['.tsx', '.ts', '.jsx', '.js'],\n  ignorePatterns: [\n    '**/node_modules/**',\n    '**/.git/**',\n    '**/*.test.*',\n    '**/*.spec.*',\n    '**/__tests__/**',\n  ],\n  debounceMs: 100,\n  verbose: false,\n};\n\n// =============================================================================\n// WatchMode Class\n// =============================================================================\n\n/**\n * Watch mode for hot-reloading route discovery\n *\n * @example\n * ```typescript\n * const watcher = new WatchMode({\n *   rootDir: '/project',\n *   onRoutesChanged: (routes) => {\n *     // Update your router with new routes\n *     router.replaceRoutes(routes);\n *   },\n * });\n *\n * await watcher.start();\n * ```\n */\nexport class WatchMode {\n  private readonly config: WatchModeConfig;\n  private readonly engine: DiscoveryEngine;\n  private watcher: FileWatcher | null = null;\n  private state: WatchModeState = 'stopped';\n  private pendingChanges: FileChangeEvent[] = [];\n  private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n  private startedAt: number | null = null;\n  private stats: {\n    changesProcessed: number;\n    rediscoveries: number;\n    totalRediscoveryMs: number;\n    lastChangeAt: number | null;\n    lastRediscoveryAt: number | null;\n  } = {\n    changesProcessed: 0,\n    rediscoveries: 0,\n    totalRediscoveryMs: 0,\n    lastChangeAt: null,\n    lastRediscoveryAt: null,\n  };\n\n  constructor(config: WatchModeConfig) {\n    this.config = {\n      ...DEFAULT_WATCH_MODE_CONFIG,\n      ...config,\n    };\n\n    this.engine = new DiscoveryEngine({\n      rootDir: config.rootDir,\n      ...config.discovery,\n    });\n  }\n\n  /**\n   * Get current watch mode state\n   */\n  getState(): WatchModeState {\n    return this.state;\n  }\n\n  /**\n   * Get watch mode statistics\n   */\n  getStats(): WatchModeStats {\n    return {\n      filesWatched: 0, // Would be populated by actual watcher\n      directoriesWatched: this.config.watchPaths?.length ?? 0,\n      changesProcessed: this.stats.changesProcessed,\n      rediscoveries: this.stats.rediscoveries,\n      avgRediscoveryMs: (this.stats.rediscoveries !== null && this.stats.rediscoveries !== undefined && this.stats.rediscoveries > 0)\n        ? this.stats.totalRediscoveryMs / this.stats.rediscoveries\n        : 0,\n      uptimeMs: (this.startedAt != null && this.startedAt !== 0) ? Date.now() - this.startedAt : 0,\n      lastChangeAt: this.stats.lastChangeAt,\n      lastRediscoveryAt: this.stats.lastRediscoveryAt,\n    };\n  }\n\n  /**\n   * Start watching for file changes\n   *\n   * @returns Initial discovery result\n   */\n  async start(): Promise<DiscoveryResult> {\n    if (this.state !== 'stopped') {\n      throw new Error(`Cannot start watch mode in state: ${this.state}`);\n    }\n\n    this.state = 'starting';\n    this.startedAt = Date.now();\n\n    try {\n      // Perform initial discovery\n      const initialResult = await this.engine.discover();\n\n      // Start file watcher\n      await this.startWatcher();\n\n      this.state = 'running';\n      this.log('Watch mode started');\n\n      return initialResult;\n    } catch (error) {\n      this.state = 'error';\n      this.config.onError?.(error as Error);\n      throw error;\n    }\n  }\n\n  /**\n   * Stop watching for file changes\n   */\n  async stop(): Promise<void> {\n    if (this.state !== 'running') {\n      return;\n    }\n\n    this.state = 'stopping';\n\n    // Clear debounce timer\n    if (this.debounceTimer) {\n      clearTimeout(this.debounceTimer);\n      this.debounceTimer = null;\n    }\n\n    // Stop watcher\n    if (this.watcher) {\n      await this.watcher.close();\n      this.watcher = null;\n    }\n\n    this.state = 'stopped';\n    this.startedAt = null;\n    this.log('Watch mode stopped');\n  }\n\n  /**\n   * Trigger an immediate rediscovery\n   *\n   * @param forceRefresh - Skip cache\n   * @returns Discovery result\n   */\n  async rediscover(forceRefresh = true): Promise<DiscoveryResult> {\n    return this.performRediscovery(forceRefresh);\n  }\n\n  /**\n   * Get the underlying discovery engine\n   */\n  getEngine(): DiscoveryEngine {\n    return this.engine;\n  }\n\n  /**\n   * Start the file system watcher\n   */\n  private async startWatcher(): Promise<void> {\n    // Dynamic import for Node.js fs module\n    const path = await import('path');\n    const { watch } = await import('fs');\n\n    // Build watch paths\n    const watchPaths = (this.config.watchPaths ?? []).map(p =>\n      path.resolve(this.config.rootDir, p)\n    );\n\n    // Create a simple watcher wrapper\n    // In production, you'd use chokidar for better cross-platform support\n    const watchers: ReturnType<typeof watch>[] = [];\n\n    const wrapperWatcher: FileWatcher = {\n      on(event: 'add' | 'change' | 'unlink' | 'error' | 'ready', handler: ((path: string) => void) | ((error: Error) => void) | (() => void)): FileWatcher {\n        // Store handlers for manual dispatch\n        if (event === 'ready') {\n          // Immediately ready with fs.watch\n          setTimeout(() => (handler as () => void)(), 0);\n        }\n        return this;\n      },\n      close: async () => {\n        for (const w of watchers) {\n          w.close();\n        }\n        return Promise.resolve();\n      },\n    };\n\n    // Watch each path\n    for (const watchPath of watchPaths) {\n      try {\n        const fsWatcher = watch(\n          watchPath,\n          { recursive: true },\n          (eventType: string, filename: string | null) => {\n            if (filename === null || filename === undefined || filename === '') return;\n\n            const fullPath = path.join(watchPath, filename);\n            const relativePath = path.relative(this.config.rootDir, fullPath);\n\n            // Check extension\n            const ext = path.extname(filename);\n            if (this.config.extensions?.includes(ext) !== true) {\n              return;\n            }\n\n            // Check ignore patterns\n            if (this.shouldIgnore(relativePath)) {\n              return;\n            }\n\n            // Map event type\n            const changeType = eventType === 'rename' ? 'add' : 'change';\n\n            this.handleFileChange({\n              type: changeType,\n              path: fullPath,\n              relativePath,\n              timestamp: Date.now(),\n            });\n          }\n        );\n\n        watchers.push(fsWatcher);\n      } catch (error) {\n        this.log(`Failed to watch ${watchPath}: ${(error as Error).message}`);\n      }\n    }\n\n    this.watcher = wrapperWatcher;\n  }\n\n  /**\n   * Check if a path should be ignored\n   */\n  private shouldIgnore(relativePath: string): boolean {\n    const patterns = this.config.ignorePatterns ?? [];\n\n    for (const pattern of patterns) {\n      // Simple glob matching\n      const regexStr = pattern\n        .replace(/\\*\\*/g, '.*')\n        .replace(/\\*/g, '[^/]*')\n        .replace(/\\?/g, '.');\n\n      const regex = new RegExp(regexStr);\n      if (regex.test(relativePath)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  /**\n   * Handle a file change event\n   */\n  private handleFileChange(event: FileChangeEvent): void {\n    this.stats.changesProcessed++;\n    this.stats.lastChangeAt = event.timestamp;\n\n    this.pendingChanges.push(event);\n    this.log(`File ${event.type}: ${event.relativePath}`);\n\n    // Notify handlers\n    switch (event.type) {\n      case 'add':\n        this.config.onFileAdded?.(event.path);\n        break;\n      case 'change':\n        this.config.onFileChanged?.(event.path);\n        break;\n      case 'unlink':\n        this.config.onFileRemoved?.(event.path);\n        break;\n    }\n\n    // Debounce rediscovery\n    this.scheduleRediscovery();\n  }\n\n  /**\n   * Schedule a debounced rediscovery\n   */\n  private scheduleRediscovery(): void {\n    if (this.debounceTimer) {\n      clearTimeout(this.debounceTimer);\n    }\n\n    this.debounceTimer = setTimeout(() => {\n      this.performRediscovery().catch((error) => {\n        this.config.onError?.(error as Error);\n      });\n    }, this.config.debounceMs);\n  }\n\n  /**\n   * Perform route rediscovery\n   */\n  private async performRediscovery(forceRefresh = true): Promise<DiscoveryResult> {\n    const startTime = Date.now();\n\n    try {\n      this.engine.clearCache();\n      const result = await this.engine.discover(forceRefresh);\n\n      const duration = Date.now() - startTime;\n      this.stats.rediscoveries++;\n      this.stats.totalRediscoveryMs += duration;\n      this.stats.lastRediscoveryAt = Date.now();\n\n      this.log(`Rediscovery completed in ${duration}ms (${result.routes.length} routes)`);\n\n      // Clear pending changes\n      this.pendingChanges = [];\n\n      // Notify handler\n      this.config.onRoutesChanged?.(result.routes, result);\n\n      return result;\n    } catch (error) {\n      this.log(`Rediscovery failed: ${(error as Error).message}`);\n      throw error;\n    }\n  }\n\n  /**\n   * Log a message if verbose mode is enabled\n   */\n  private log(message: string): void {\n    if (this.config.verbose === true) {\n      console.info(`[WatchMode] ${message}`);\n    }\n  }\n}\n\n// =============================================================================\n// Factory Functions\n// =============================================================================\n\n/**\n * Create a new WatchMode instance\n *\n * @param config - Watch mode configuration\n * @returns Configured WatchMode instance\n */\nexport function createWatchMode(config: WatchModeConfig): WatchMode {\n  return new WatchMode(config);\n}\n\n// =============================================================================\n// HMR Integration\n// =============================================================================\n\n/**\n * HMR update handler type\n */\nexport type HMRUpdateHandler = (routes: readonly TransformedRoute[]) => void;\n\n/**\n * Create an HMR-compatible route updater\n *\n * @param updateHandler - Function to call when routes update\n * @returns Object with HMR lifecycle methods\n *\n * @example\n * ```typescript\n * const hmr = createHMRUpdater((routes) => {\n *   // Update your router\n *   router.replaceRoutes(routes);\n * });\n *\n * // In your Vite plugin or webpack config\n * if (import.meta.hot) {\n *   import.meta.hot.accept('./routes', hmr.accept);\n *   import.meta.hot.dispose(hmr.dispose);\n * }\n * ```\n */\nexport function createHMRUpdater(updateHandler: HMRUpdateHandler): {\n  accept: (newModule: { routes: readonly TransformedRoute[] }) => void;\n  dispose: () => void;\n  prune: () => void;\n} {\n  return {\n    accept: (newModule) => {\n      if (newModule?.routes !== undefined && newModule.routes !== null) {\n        updateHandler(newModule.routes);\n      }\n    },\n    dispose: () => {\n      // Cleanup if needed\n    },\n    prune: () => {\n      // Cleanup stale modules if needed\n    },\n  };\n}\n\n// =============================================================================\n// Development Server Integration\n// =============================================================================\n\n/**\n * Vite plugin configuration for route discovery watch mode\n */\nexport interface VitePluginConfig {\n  /** Root directory */\n  readonly rootDir?: string;\n  /** Watch mode configuration */\n  readonly watchMode?: Partial<WatchModeConfig>;\n  /** Enable in production (not recommended) */\n  readonly enableInProduction?: boolean;\n}\n\n/**\n * Create a Vite plugin configuration for watch mode\n *\n * @param config - Plugin configuration\n * @returns Vite plugin object\n *\n * @example\n * ```typescript\n * // vite.config.ts\n * import { createVitePlugin } from '@/lib/routing/discovery/watch-mode';\n *\n * export default defineConfig({\n *   plugins: [\n *     createVitePlugin({\n *       rootDir: process.cwd(),\n *     }),\n *   ],\n * });\n * ```\n */\nexport function createVitePlugin(config: VitePluginConfig = {}): {\n  name: string;\n  configureServer?: (server: unknown) => void;\n} {\n  return {\n    name: 'route-discovery-watch',\n    configureServer: (_server: unknown) => {\n      // In a real implementation, this would integrate with Vite's dev server\n      // to provide HMR updates when routes change\n\n      if (config.enableInProduction === false && isProd()) {\n        return;\n      }\n\n      // Initialize watch mode\n      const watcher = new WatchMode({\n        rootDir: config.rootDir ?? process.cwd(),\n        ...config.watchMode,\n        onRoutesChanged: (_routes, _result) => {\n          // In real implementation, trigger HMR update\n          // server.ws.send({ type: 'custom', event: 'routes-updated', data: routes });\n        },\n      });\n\n      // Start watching\n      watcher.start().catch(console.error);\n    },\n  };\n}\n\n// =============================================================================\n// Singleton Instance\n// =============================================================================\n\nlet defaultWatcher: WatchMode | null = null;\n\n/**\n * Get or create the default watch mode instance\n *\n * @param config - Configuration (required on first call)\n * @returns WatchMode instance\n */\nexport function getWatchMode(config?: WatchModeConfig): WatchMode {\n  if (!defaultWatcher && config) {\n    defaultWatcher = new WatchMode(config);\n  }\n  if (!defaultWatcher) {\n    throw new Error('Watch mode not initialized. Call with config first.');\n  }\n  return defaultWatcher;\n}\n\n/**\n * Initialize the default watch mode\n *\n * @param config - Watch mode configuration\n */\nexport function initWatchMode(config: WatchModeConfig): void {\n  defaultWatcher = new WatchMode(config);\n}\n\n/**\n * Reset the default watch mode\n */\nexport async function resetWatchMode(): Promise<void> {\n  if (defaultWatcher) {\n    await defaultWatcher.stop();\n    defaultWatcher = null;\n  }\n}\n"],"names":["DEFAULT_WATCH_MODE_CONFIG","WatchMode","config","DiscoveryEngine","initialResult","error","forceRefresh","path","watch","watchPaths","p","watchers","wrapperWatcher","event","handler","w","watchPath","fsWatcher","eventType","filename","fullPath","relativePath","ext","changeType","patterns","pattern","regexStr","startTime","result","duration","message","createWatchMode","defaultWatcher","getWatchMode","initWatchMode","resetWatchMode"],"mappings":"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"}