{"version":3,"file":"watcher.cjs","names":["getConfigurationAndFilePath","getAppLogger","colorize","ANSIColor","normalizePath","dirname","existsSync","readFile","transpileTSToCJS","basename","prepareIntlayer","formatPath","fsWatch","resolve","handleContentDeclarationFileMoved","parseContentDeclarationFileName","getFormatFromExtension","extname","writeContentDeclaration","handleAdditionalContentDeclarationFile","handleContentDeclarationFileChange","handleUnlinkedContentDeclarationFile","getConfiguration"],"sources":["../../src/watcher.ts"],"sourcesContent":["import { existsSync, watch as fsWatch } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { basename, dirname, extname, resolve } from 'node:path';\nimport * as ANSIColor from '@intlayer/config/colors';\nimport { transpileTSToCJS } from '@intlayer/config/file';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport {\n  type GetConfigurationOptions,\n  getConfiguration,\n  getConfigurationAndFilePath,\n} from '@intlayer/config/node';\nimport {\n  clearAllCache,\n  clearDiskCacheMemory,\n  clearModuleCache,\n  normalizePath,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { handleAdditionalContentDeclarationFile } from './handleAdditionalContentDeclarationFile';\nimport { handleContentDeclarationFileChange } from './handleContentDeclarationFileChange';\nimport { handleContentDeclarationFileMoved } from './handleContentDeclarationFileMoved';\nimport { handleUnlinkedContentDeclarationFile } from './handleUnlinkedContentDeclarationFile';\nimport { prepareIntlayer } from './prepareIntlayer';\nimport {\n  formatPath,\n  getFormatFromExtension,\n  parseContentDeclarationFileName,\n} from './utils';\nimport { writeContentDeclaration } from './writeContentDeclaration';\n\n// Map to track files that were recently unlinked: oldPath -> { timer, timestamp }\nconst pendingUnlinks = new Map<\n  string,\n  { timer: NodeJS.Timeout; oldPath: string }\n>();\n\n// Array-based sequential task queue — no Promise chain accumulation, no race conditions\nconst taskQueue: (() => Promise<void>)[] = [];\nlet isProcessing = false;\n\nconst processQueue = async () => {\n  if (isProcessing) return;\n  isProcessing = true;\n  while (taskQueue.length > 0) {\n    const task = taskQueue.shift()!;\n    try {\n      await task();\n    } catch (error) {\n      console.error(error);\n    }\n  }\n  isProcessing = false;\n};\n\nconst processEvent = (task: () => Promise<void>) => {\n  taskQueue.push(task);\n  processQueue();\n};\n\ntype WatchOptions = {\n  configuration?: IntlayerConfig;\n  configOptions?: GetConfigurationOptions;\n  skipPrepare?: boolean;\n  persistent?: boolean;\n};\n\n// awaitWriteFinish equivalent: debounce per path until the file is stable\nconst STABILITY_THRESHOLD = 1000;\n\nconst createStabilityDebounce = () => {\n  const pending = new Map<string, NodeJS.Timeout>();\n  return (path: string, handler: () => void) => {\n    const existing = pending.get(path);\n    if (existing) clearTimeout(existing);\n    pending.set(\n      path,\n      setTimeout(() => {\n        pending.delete(path);\n        handler();\n      }, STABILITY_THRESHOLD)\n    );\n  };\n};\n\n// Initialize @parcel/watcher (non-persistent until subscribed)\nexport const watch = async (options?: WatchOptions) => {\n  const { subscribe } = await import('@parcel/watcher');\n\n  const configResult = getConfigurationAndFilePath(options?.configOptions);\n  const configurationFilePath = configResult.configurationFilePath;\n  let configuration: IntlayerConfig =\n    options?.configuration ?? configResult.configuration;\n  const appLogger = getAppLogger(configuration);\n\n  const {\n    watch: isWatchMode,\n    fileExtensions,\n    contentDir,\n    excludedPath,\n  } = configuration.content;\n\n  if (!configuration.content.watch) return;\n\n  appLogger('Watching Intlayer content declarations');\n\n  if (configuration.build.optimize === true) {\n    appLogger(\n      [\n        `Build optimization is forced to ${colorize('true', ANSIColor.GREY)}, but watching is enabled too.`,\n        'It may lead to dev mode performance degradation as well as import errors.',\n        'Its recommended to keep the',\n        colorize('`build.optimized`', ANSIColor.BLUE),\n        'option',\n        colorize('undefined', ANSIColor.GREY),\n        'to get the best dev mode experience',\n      ],\n      {\n        level: 'warn',\n      }\n    );\n  }\n\n  // Strip glob markers from excludedPath entries to get plain segments (e.g. 'node_modules')\n  const excludedSegments = excludedPath.map((segment) =>\n    segment.replace(/^\\*\\*\\//, '').replace(/\\/\\*\\*$/, '')\n  );\n\n  const normalizedConfigPath = configurationFilePath\n    ? normalizePath(configurationFilePath)\n    : null;\n\n  const { mainDir, baseDir } = configuration.system;\n  const normalizedMainDir = normalizePath(mainDir);\n  const normalizedIntlayerDir = normalizePath(dirname(mainDir));\n\n  const subscriptions: { unsubscribe: () => Promise<void> }[] = [];\n\n  const scheduleStable = createStabilityDebounce();\n\n  // ── mainDir watcher (depth 0) ──────────────────────────────────────────────\n  // Detects broken or missing entry-point files inside .intlayer/main\n  if (existsSync(mainDir)) {\n    const mainDirSub = await subscribe(normalizedMainDir, (err, events) => {\n      if (err || isProcessing) return;\n\n      for (const event of events) {\n        const eventPath = normalizePath(event.path);\n        // depth-0 filter: only files directly inside mainDir\n        const rel = eventPath.slice(normalizedMainDir.length + 1);\n        if (!rel || rel.includes('/')) continue;\n        // Temp files written by the bundler (write-then-rename) are build-internal;\n        // their deletion must not trigger a clean rebuild.\n        if (rel.endsWith('.tmp')) continue;\n\n        if (event.type === 'update') {\n          processEvent(async () => {\n            try {\n              // Validate that the regenerated entry point — and the relative\n              // dictionary graph it imports — still resolves, by bundling it\n              // in-memory with esbuild (via the shared, freshness-checked\n              // transpile cache). This replaces a cache-busting dynamic\n              // `import()`, which leaked a permanent record into Node's ESM\n              // registry on every rebuild since that registry is never evicted.\n              const entryCode = await readFile(event.path, 'utf-8');\n              await transpileTSToCJS(entryCode, event.path);\n            } catch {\n              appLogger(\n                `Entry point ${basename(event.path)} failed to load, running clean rebuild...`,\n                { level: 'warn' }\n              );\n              await prepareIntlayer(configuration, {\n                clean: true,\n                forceRun: true,\n              });\n            }\n          });\n        } else if (event.type === 'delete') {\n          processEvent(async () => {\n            appLogger(\n              [\n                'Entry point',\n                formatPath(basename(event.path)),\n                'was removed, running clean rebuild...',\n              ],\n              { level: 'warn' }\n            );\n            await prepareIntlayer(configuration, {\n              clean: true,\n              forceRun: true,\n            });\n          });\n        }\n      }\n    });\n    subscriptions.push(mainDirSub);\n  }\n\n  // ── baseDir watcher (depth 0) — detect .intlayer directory removal ─────────\n  // Native fs.watch is non-recursive and ideal for single-directory depth-0 detection.\n  const intlayerDirName = basename(normalizedIntlayerDir);\n  const fsDirWatcher = fsWatch(\n    baseDir,\n    { persistent: isWatchMode },\n    (eventType, filename) => {\n      if (isProcessing || !filename) return;\n      if (filename !== intlayerDirName) return;\n\n      const fullPath = normalizePath(resolve(baseDir, filename));\n      if (fullPath !== normalizedIntlayerDir) return;\n\n      if (eventType === 'rename' && !existsSync(normalizedIntlayerDir)) {\n        appLogger([\n          formatPath('.intlayer'),\n          'directory removed, running clean rebuild...',\n        ]);\n        processEvent(() =>\n          prepareIntlayer(configuration, { clean: true, forceRun: true })\n        );\n      }\n    }\n  );\n  subscriptions.push({\n    unsubscribe: async () => {\n      fsDirWatcher.close();\n    },\n  });\n\n  // ── main content watcher ───────────────────────────────────────────────────\n  // Ignore patterns for @parcel/watcher (micromatch globs)\n  const ignorePatterns = excludedSegments.map((s) => `**/${s}/**`);\n\n  // Strip trailing slashes so directory matching stays exact. A user-supplied\n  const contentDirs = contentDir\n    .map((dir) => normalizePath(dir).replace(/\\/+$/, ''))\n    .filter(existsSync);\n\n  // Collect unique directories to subscribe to (dirs only, not file paths)\n  const dirsToWatch = new Set<string>(contentDirs);\n  if (normalizedConfigPath) {\n    dirsToWatch.add(normalizePath(dirname(normalizedConfigPath)));\n  }\n\n  const contentHandler = (\n    err: Error | null,\n    events: Array<{ type: string; path: string }>\n  ) => {\n    if (err) {\n      appLogger(`Watcher error: ${err}`, { level: 'error' });\n      appLogger('Restarting watcher');\n      prepareIntlayer(configuration);\n      return;\n    }\n\n    for (const event of events) {\n      const filePath = event.path;\n      const path = normalizePath(filePath);\n\n      const isConfigFile =\n        normalizedConfigPath && path === normalizedConfigPath;\n\n      if (!isConfigFile) {\n        // Must originate from a watched content directory\n        const isInContentDir = contentDirs.some(\n          (d) => path.startsWith(`${d}/`) || path === d\n        );\n        if (!isInContentDir) continue;\n\n        if (excludedSegments.some((segment) => path.includes(`/${segment}`)))\n          continue;\n\n        if (!fileExtensions.some((extension) => path.endsWith(extension)))\n          continue;\n      }\n\n      if (event.type === 'create') {\n        const fileName = basename(filePath);\n\n        // Move detection must happen synchronously before any debounce\n        let isMove = false;\n        let matchedOldPath: string | undefined;\n\n        for (const [oldPath] of pendingUnlinks) {\n          if (basename(oldPath) === fileName) {\n            matchedOldPath = oldPath;\n            break;\n          }\n        }\n\n        if (!matchedOldPath && pendingUnlinks.size === 1) {\n          matchedOldPath = pendingUnlinks.keys().next().value;\n        }\n\n        if (matchedOldPath) {\n          const pending = pendingUnlinks.get(matchedOldPath);\n          if (pending) {\n            clearTimeout(pending.timer);\n            pendingUnlinks.delete(matchedOldPath);\n          }\n          isMove = true;\n          appLogger(`File moved from ${matchedOldPath} to ${filePath}`);\n        }\n\n        if (isMove && matchedOldPath) {\n          processEvent(async () => {\n            await handleContentDeclarationFileMoved(\n              matchedOldPath!,\n              filePath,\n              configuration\n            );\n          });\n        } else {\n          // Debounce: wait for write to finish before reading the file\n          scheduleStable(path, () => {\n            processEvent(async () => {\n              const fileContent = await readFile(filePath, 'utf-8');\n              const isEmpty = fileContent === '';\n\n              if (isEmpty) {\n                const { key, locale } = parseContentDeclarationFileName(\n                  filePath,\n                  configuration\n                );\n\n                // A markdown declaration carries a single locale body, so it\n                // must always state which locale it holds.\n                const isMarkdown =\n                  getFormatFromExtension(extname(filePath)) === 'md';\n                const declaredLocale =\n                  locale ??\n                  (isMarkdown\n                    ? configuration.internationalization.defaultLocale\n                    : undefined);\n\n                await writeContentDeclaration(\n                  {\n                    key,\n                    ...(declaredLocale && { locale: declaredLocale }),\n                    content: {},\n                    filePath,\n                  },\n                  configuration\n                );\n              }\n\n              await handleAdditionalContentDeclarationFile(\n                filePath,\n                configuration\n              );\n            });\n          });\n        }\n      } else if (event.type === 'update') {\n        scheduleStable(path, () => {\n          processEvent(async () => {\n            if (isConfigFile) {\n              appLogger('Configuration file changed, repreparing Intlayer');\n\n              clearModuleCache(filePath);\n              clearAllCache();\n\n              const { configuration: newConfiguration } =\n                getConfigurationAndFilePath(options?.configOptions);\n\n              configuration = options?.configuration ?? newConfiguration;\n\n              await prepareIntlayer(configuration, { clean: false });\n            } else {\n              // Clear module cache for the changed file to avoid stale require() results\n              clearModuleCache(filePath);\n              // Evict in-memory caches so loadContentDeclaration picks up fresh content\n              clearAllCache();\n              clearDiskCacheMemory();\n              await handleContentDeclarationFileChange(filePath, configuration);\n            }\n          });\n        });\n      } else if (event.type === 'delete') {\n        // Delay unlink processing to see if an 'add' event occurs (indicating a move)\n        const timer = setTimeout(async () => {\n          // If timer fires, the file was genuinely removed\n          pendingUnlinks.delete(filePath);\n          processEvent(async () =>\n            handleUnlinkedContentDeclarationFile(filePath, configuration)\n          );\n        }, 200); // 200ms window to catch the 'create' event\n\n        pendingUnlinks.set(filePath, { timer, oldPath: filePath });\n      }\n    }\n  };\n\n  for (const dir of dirsToWatch) {\n    const sub = await subscribe(dir, contentHandler, {\n      ignore: ignorePatterns,\n    });\n\n    subscriptions.push(sub);\n  }\n\n  return subscriptions;\n};\n\nexport const buildAndWatchIntlayer = async (options?: WatchOptions) => {\n  const { skipPrepare, ...rest } = options ?? {};\n  const configuration =\n    options?.configuration ?? getConfiguration(options?.configOptions);\n\n  if (!skipPrepare) {\n    await prepareIntlayer(configuration, { forceRun: true });\n  }\n\n  // Only enter watch mode when the caller explicitly opts in via `persistent`.\n  // `configuration.content.watch` is the dev-mode signal consumed by bundler\n  // plugins (e.g. vite-intlayer's `configureServer`); it must not coerce\n  // `intlayer build` (which passes `persistent: false`) into a persistent\n  // watcher, since that prevents the build command from ever exiting.\n  if (options?.persistent) {\n    await watch({ ...rest, configuration });\n  }\n};\n"],"mappings":"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"}