@intlayer/chokidar 8.8.0 → 8.9.1

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.
@@ -55,7 +55,7 @@ export default content;
55
55
  ## useIntlayer Hook
56
56
 
57
57
  > [!IMPORTANT]
58
- > In Solid, `useIntlayer` returns an **accessor** function (e.g., `content()`). You must call this function to access the reactive content.
58
+ > In Solid, `useIntlayer` returns reactive content (e.g., `content`). You can access its properties directly.
59
59
 
60
60
  ```tsx
61
61
  import { useIntlayer } from "solid-intlayer";
@@ -67,10 +67,10 @@ const MyComponent = () => {
67
67
  <div>
68
68
  <h1>
69
69
  {/* Return content */}
70
- {content().text}
70
+ {content.text}
71
71
  </h1>
72
72
  {/* Return string (.value) */}
73
- <img src={content().text.value} alt={content().text.value} />
73
+ <img src={content.text.value} alt={content.text.value} />
74
74
  </div>
75
75
  );
76
76
  };
@@ -65,7 +65,11 @@ const loadContentDeclaration = async (path, configuration, bundleFilePath, optio
65
65
  `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';`
66
66
  ].join("\n") }
67
67
  },
68
- aliases: { intlayer: resolvedBundleFilePath }
68
+ aliases: { intlayer: resolvedBundleFilePath },
69
+ preloadGlobals: {
70
+ INTLAYER_FILE_PATH: path,
71
+ INTLAYER_BASE_DIR: configuration.system.baseDir
72
+ }
69
73
  });
70
74
  } catch (error) {
71
75
  console.error(`Error loading content declaration at ${path}:`, error);
@@ -1 +1 @@
1
- {"version":3,"file":"loadContentDeclaration.cjs","names":["getIntlayerBundle","filterInvalidDictionaries","parallelize","processContentDeclaration"],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { loadExternalFile } from '@intlayer/config/file';\nimport {\n cacheDisk,\n getPackageJsonPath,\n getProjectRequire,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { processContentDeclaration } from '../buildIntlayerDictionary/processContentDeclaration';\nimport { filterInvalidDictionaries } from '../filterInvalidDictionaries';\nimport { parallelize } from '../utils/parallelize';\nimport { getIntlayerBundle } from './getIntlayerBundle';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { logTypeScriptErrors } from './logTypeScriptErrors';\n\nexport const formatLocalDictionaries = (\n dictionariesRecord: Record<string, Dictionary>,\n configuration: IntlayerConfig\n): Dictionary[] =>\n Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({\n ...dict,\n location: dict.location ?? configuration.dictionary?.location ?? 'local',\n localId: `${dict.key}::local::${relativePath}`,\n filePath: relativePath,\n }));\n\nexport const ensureIntlayerBundle = async (\n configuration: IntlayerConfig\n): Promise<string> => {\n const { system } = configuration;\n\n const { set, isValid } = cacheDisk(configuration, ['intlayer-bundle'], {\n ttlMs: 1000 * 60 * 60 * 24 * 5, // 5 days\n });\n\n const filePath = join(system.cacheDir, 'intlayer-bundle.cjs');\n const hasIntlayerBundle = await isValid();\n\n if (!hasIntlayerBundle) {\n const intlayerBundle = await getIntlayerBundle(configuration);\n await writeFile(filePath, intlayerBundle);\n await set('ok');\n }\n\n return filePath;\n};\n\ntype LoadContentDeclarationOptions = {\n logError?: boolean;\n};\n\n// Initialize a module-level cache\nlet cachedExternalDeps: string[] | null = null;\n\n// Helper to fetch and cache the dependencies\nconst getExternalDeps = async (baseDir: string): Promise<string[]> => {\n if (cachedExternalDeps) {\n return cachedExternalDeps; // Return instantly on subsequent calls\n }\n\n try {\n const packageJsonPath = getPackageJsonPath(baseDir);\n\n const packageJSON = await readFile(\n packageJsonPath.packageJsonPath,\n 'utf-8'\n );\n const parsedPackages = JSON.parse(packageJSON);\n const allDependencies = Object.keys({\n ...parsedPackages.dependencies,\n ...parsedPackages.devDependencies,\n });\n\n // Specify the ESM packages to bundle\n const esmPackagesToBundle: string[] = [];\n\n const externalDeps = allDependencies.filter(\n (dep) => !esmPackagesToBundle.includes(dep)\n );\n\n externalDeps.push('esbuild');\n\n // Save to cache\n cachedExternalDeps = externalDeps;\n } catch (error) {\n console.warn(\n 'Could not read package.json for externalizing dependencies, fallback to empty array',\n error\n );\n cachedExternalDeps = ['esbuild'];\n }\n\n return cachedExternalDeps;\n};\n\nexport const loadContentDeclaration = async (\n path: string,\n configuration: IntlayerConfig,\n bundleFilePath?: string,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary | undefined> => {\n const { build, system } = configuration;\n\n // Call the cached helper\n const externalDeps = await getExternalDeps(system.baseDir);\n\n const resolvedBundleFilePath =\n bundleFilePath ?? (await ensureIntlayerBundle(configuration));\n\n try {\n const dictionary = await loadExternalFile(path, {\n logError: options?.logError,\n projectRequire: build.require ?? getProjectRequire(),\n buildOptions: {\n packages: undefined, // It fixes the import of ESM packages in the content declaration\n external: externalDeps,\n banner: {\n js: [\n `var __filename = ${JSON.stringify(path)};`,\n `var __dirname = ${JSON.stringify(dirname(path))};`,\n `globalThis.INTLAYER_FILE_PATH = '${path}';`,\n `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';`,\n ].join('\\n'),\n },\n },\n aliases: {\n intlayer: resolvedBundleFilePath,\n },\n });\n\n return dictionary;\n } catch (error) {\n console.error(`Error loading content declaration at ${path}:`, error);\n return undefined;\n }\n};\n\nexport const loadContentDeclarations = async (\n contentDeclarationFilePath: string[],\n configuration: IntlayerConfig,\n onStatusUpdate?: (status: DictionariesStatus[]) => void,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary[]> => {\n const { build, system } = configuration;\n\n // Check for TypeScript warnings before we build\n if (build.checkTypes) {\n logTypeScriptErrors(contentDeclarationFilePath, configuration).catch(\n (e) => {\n console.error('Error during TypeScript validation:', e);\n }\n );\n }\n\n const bundleFilePath = await ensureIntlayerBundle(configuration);\n\n try {\n const dictionariesPromises = contentDeclarationFilePath.map(\n async (path) => {\n const relativePath = relative(system.baseDir, path);\n\n const dictionary = await loadContentDeclaration(\n path,\n configuration,\n bundleFilePath,\n options\n );\n\n return { relativePath, dictionary };\n }\n );\n\n const dictionariesArray = await Promise.all(dictionariesPromises);\n const dictionariesRecord = dictionariesArray.reduce(\n (acc, { relativePath, dictionary }) => {\n if (dictionary) {\n acc[relativePath] = dictionary;\n }\n return acc;\n },\n {} as Record<string, Dictionary>\n );\n\n const contentDeclarations: Dictionary[] = formatLocalDictionaries(\n dictionariesRecord,\n configuration\n ).filter((dictionary) => dictionary.location !== 'remote');\n\n const listFoundDictionaries = contentDeclarations.map((declaration) => ({\n dictionaryKey: declaration.key,\n type: 'local' as const,\n status: 'found' as const,\n }));\n\n onStatusUpdate?.(listFoundDictionaries);\n\n const processedDictionaries = await parallelize(\n contentDeclarations,\n async (contentDeclaration): Promise<Dictionary | undefined> => {\n if (!contentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: contentDeclaration.key,\n type: 'local',\n status: 'building',\n },\n ]);\n\n const processedContentDeclaration = await processContentDeclaration(\n contentDeclaration as Dictionary,\n configuration\n );\n\n if (!processedContentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: processedContentDeclaration.key,\n type: 'local',\n status: 'built',\n },\n ]);\n\n return processedContentDeclaration;\n }\n );\n\n return filterInvalidDictionaries(processedDictionaries, configuration, {\n checkSchema: false,\n });\n } catch {\n console.error('Error loading content declarations');\n }\n\n return [];\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"loadContentDeclaration.cjs","names":["getIntlayerBundle","filterInvalidDictionaries","parallelize","processContentDeclaration"],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { loadExternalFile } from '@intlayer/config/file';\nimport {\n cacheDisk,\n getPackageJsonPath,\n getProjectRequire,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { processContentDeclaration } from '../buildIntlayerDictionary/processContentDeclaration';\nimport { filterInvalidDictionaries } from '../filterInvalidDictionaries';\nimport { parallelize } from '../utils/parallelize';\nimport { getIntlayerBundle } from './getIntlayerBundle';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { logTypeScriptErrors } from './logTypeScriptErrors';\n\nexport const formatLocalDictionaries = (\n dictionariesRecord: Record<string, Dictionary>,\n configuration: IntlayerConfig\n): Dictionary[] =>\n Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({\n ...dict,\n location: dict.location ?? configuration.dictionary?.location ?? 'local',\n localId: `${dict.key}::local::${relativePath}`,\n filePath: relativePath,\n }));\n\nexport const ensureIntlayerBundle = async (\n configuration: IntlayerConfig\n): Promise<string> => {\n const { system } = configuration;\n\n const { set, isValid } = cacheDisk(configuration, ['intlayer-bundle'], {\n ttlMs: 1000 * 60 * 60 * 24 * 5, // 5 days\n });\n\n const filePath = join(system.cacheDir, 'intlayer-bundle.cjs');\n const hasIntlayerBundle = await isValid();\n\n if (!hasIntlayerBundle) {\n const intlayerBundle = await getIntlayerBundle(configuration);\n await writeFile(filePath, intlayerBundle);\n await set('ok');\n }\n\n return filePath;\n};\n\ntype LoadContentDeclarationOptions = {\n logError?: boolean;\n};\n\n// Initialize a module-level cache\nlet cachedExternalDeps: string[] | null = null;\n\n// Helper to fetch and cache the dependencies\nconst getExternalDeps = async (baseDir: string): Promise<string[]> => {\n if (cachedExternalDeps) {\n return cachedExternalDeps; // Return instantly on subsequent calls\n }\n\n try {\n const packageJsonPath = getPackageJsonPath(baseDir);\n\n const packageJSON = await readFile(\n packageJsonPath.packageJsonPath,\n 'utf-8'\n );\n const parsedPackages = JSON.parse(packageJSON);\n const allDependencies = Object.keys({\n ...parsedPackages.dependencies,\n ...parsedPackages.devDependencies,\n });\n\n // Specify the ESM packages to bundle\n const esmPackagesToBundle: string[] = [];\n\n const externalDeps = allDependencies.filter(\n (dep) => !esmPackagesToBundle.includes(dep)\n );\n\n externalDeps.push('esbuild');\n\n // Save to cache\n cachedExternalDeps = externalDeps;\n } catch (error) {\n console.warn(\n 'Could not read package.json for externalizing dependencies, fallback to empty array',\n error\n );\n cachedExternalDeps = ['esbuild'];\n }\n\n return cachedExternalDeps;\n};\n\nexport const loadContentDeclaration = async (\n path: string,\n configuration: IntlayerConfig,\n bundleFilePath?: string,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary | undefined> => {\n const { build, system } = configuration;\n\n // Call the cached helper\n const externalDeps = await getExternalDeps(system.baseDir);\n\n const resolvedBundleFilePath =\n bundleFilePath ?? (await ensureIntlayerBundle(configuration));\n\n try {\n const dictionary = await loadExternalFile(path, {\n logError: options?.logError,\n projectRequire: build.require ?? getProjectRequire(),\n buildOptions: {\n packages: undefined, // It fixes the import of ESM packages in the content declaration\n external: externalDeps,\n banner: {\n js: [\n `var __filename = ${JSON.stringify(path)};`,\n `var __dirname = ${JSON.stringify(dirname(path))};`,\n // Also set on the VM sandbox's globalThis for VM-internal code.\n // External modules (e.g. @intlayer/core's file()) run in the main\n // Node.js context and are handled by preloadGlobals below.\n `globalThis.INTLAYER_FILE_PATH = '${path}';`,\n `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';`,\n ].join('\\n'),\n },\n },\n aliases: {\n intlayer: resolvedBundleFilePath,\n },\n // Temporarily expose these on the main Node.js globalThis so that external\n // modules required inside the VM (e.g. @intlayer/core's file() helper)\n // can resolve relative paths against the correct content declaration path.\n preloadGlobals: {\n INTLAYER_FILE_PATH: path,\n INTLAYER_BASE_DIR: configuration.system.baseDir,\n },\n });\n\n return dictionary;\n } catch (error) {\n console.error(`Error loading content declaration at ${path}:`, error);\n return undefined;\n }\n};\n\nexport const loadContentDeclarations = async (\n contentDeclarationFilePath: string[],\n configuration: IntlayerConfig,\n onStatusUpdate?: (status: DictionariesStatus[]) => void,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary[]> => {\n const { build, system } = configuration;\n\n // Check for TypeScript warnings before we build\n if (build.checkTypes) {\n logTypeScriptErrors(contentDeclarationFilePath, configuration).catch(\n (e) => {\n console.error('Error during TypeScript validation:', e);\n }\n );\n }\n\n const bundleFilePath = await ensureIntlayerBundle(configuration);\n\n try {\n const dictionariesPromises = contentDeclarationFilePath.map(\n async (path) => {\n const relativePath = relative(system.baseDir, path);\n\n const dictionary = await loadContentDeclaration(\n path,\n configuration,\n bundleFilePath,\n options\n );\n\n return { relativePath, dictionary };\n }\n );\n\n const dictionariesArray = await Promise.all(dictionariesPromises);\n const dictionariesRecord = dictionariesArray.reduce(\n (acc, { relativePath, dictionary }) => {\n if (dictionary) {\n acc[relativePath] = dictionary;\n }\n return acc;\n },\n {} as Record<string, Dictionary>\n );\n\n const contentDeclarations: Dictionary[] = formatLocalDictionaries(\n dictionariesRecord,\n configuration\n ).filter((dictionary) => dictionary.location !== 'remote');\n\n const listFoundDictionaries = contentDeclarations.map((declaration) => ({\n dictionaryKey: declaration.key,\n type: 'local' as const,\n status: 'found' as const,\n }));\n\n onStatusUpdate?.(listFoundDictionaries);\n\n const processedDictionaries = await parallelize(\n contentDeclarations,\n async (contentDeclaration): Promise<Dictionary | undefined> => {\n if (!contentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: contentDeclaration.key,\n type: 'local',\n status: 'building',\n },\n ]);\n\n const processedContentDeclaration = await processContentDeclaration(\n contentDeclaration as Dictionary,\n configuration\n );\n\n if (!processedContentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: processedContentDeclaration.key,\n type: 'local',\n status: 'built',\n },\n ]);\n\n return processedContentDeclaration;\n }\n );\n\n return filterInvalidDictionaries(processedDictionaries, configuration, {\n checkSchema: false,\n });\n } catch {\n console.error('Error loading content declarations');\n }\n\n return [];\n};\n"],"mappings":"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"}
@@ -10,44 +10,44 @@ let node_fs_promises = require("node:fs/promises");
10
10
  let node_path = require("node:path");
11
11
  let _intlayer_config_logger = require("@intlayer/config/logger");
12
12
  let _intlayer_config_node = require("@intlayer/config/node");
13
+ let node_fs = require("node:fs");
13
14
  let _intlayer_config_utils = require("@intlayer/config/utils");
14
15
  let _intlayer_config_colors = require("@intlayer/config/colors");
15
16
  _intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
16
- let chokidar = require("chokidar");
17
17
 
18
18
  //#region src/watcher.ts
19
- /** @ts-ignore remove error Module '"chokidar"' has no exported member 'ChokidarOptions' */
20
19
  const pendingUnlinks = /* @__PURE__ */ new Map();
21
- let processingLock = null;
22
- const processEvent = (task) => {
23
- const run = async () => {
24
- while (processingLock) await processingLock;
25
- let resolve;
26
- processingLock = new Promise((r) => {
27
- resolve = r;
28
- });
20
+ const taskQueue = [];
21
+ let isProcessing = false;
22
+ const processQueue = async () => {
23
+ if (isProcessing) return;
24
+ isProcessing = true;
25
+ while (taskQueue.length > 0) {
26
+ const task = taskQueue.shift();
29
27
  try {
30
28
  await task();
31
29
  } catch (error) {
32
30
  console.error(error);
33
- } finally {
34
- processingLock = null;
35
- resolve();
36
31
  }
37
- };
38
- run();
32
+ }
33
+ isProcessing = false;
34
+ };
35
+ const processEvent = (task) => {
36
+ taskQueue.push(task);
37
+ processQueue();
39
38
  };
40
- const watch = (options) => {
39
+ const watch = async (options) => {
40
+ const { watch: chokidarWatch } = await import("chokidar");
41
41
  const configResult = (0, _intlayer_config_node.getConfigurationAndFilePath)(options?.configOptions);
42
42
  const configurationFilePath = configResult.configurationFilePath;
43
43
  let configuration = options?.configuration ?? configResult.configuration;
44
44
  const appLogger = (0, _intlayer_config_logger.getAppLogger)(configuration);
45
- const { watch: isWatchMode, fileExtensions, contentDir } = configuration.content;
46
- const pathsToWatch = [...fileExtensions.flatMap((ext) => contentDir.map((dir) => `${(0, _intlayer_config_utils.normalizePath)(dir)}/**/*${ext}`.replace("//", "/"))), ...configurationFilePath ? [configurationFilePath] : []];
45
+ const { watch: isWatchMode, fileExtensions, contentDir, excludedPath } = configuration.content;
46
+ const pathsToWatch = [...contentDir.map((dir) => (0, _intlayer_config_utils.normalizePath)(dir)).filter(node_fs.existsSync), ...configurationFilePath ? [configurationFilePath] : []];
47
47
  if (!configuration.content.watch) return;
48
48
  appLogger("Watching Intlayer content declarations");
49
49
  if (configuration.build.optimize === true) appLogger([
50
- "Build optimization is forced to true, but watching is enabled too.",
50
+ `Build optimization is forced to ${(0, _intlayer_config_logger.colorize)("true", _intlayer_config_colors.GREY)}, but watching is enabled too.`,
51
51
  "It may lead to dev mode performance degradation as well as import errors.",
52
52
  "Its recommended to keep the",
53
53
  (0, _intlayer_config_logger.colorize)("`build.optimized`", _intlayer_config_colors.BLUE),
@@ -55,19 +55,22 @@ const watch = (options) => {
55
55
  (0, _intlayer_config_logger.colorize)("undefined", _intlayer_config_colors.GREY),
56
56
  "to get the best dev mode experience"
57
57
  ], { level: "warn" });
58
- return (0, chokidar.watch)(pathsToWatch, {
58
+ const excludedSegments = excludedPath.map((segment) => segment.replace(/^\*\*\//, "").replace(/\/\*\*$/, ""));
59
+ const normalizedConfigPath = configurationFilePath ? (0, _intlayer_config_utils.normalizePath)(configurationFilePath) : null;
60
+ return chokidarWatch(pathsToWatch, {
59
61
  persistent: isWatchMode,
60
62
  ignoreInitial: true,
61
63
  awaitWriteFinish: {
62
64
  stabilityThreshold: 1e3,
63
65
  pollInterval: 100
64
66
  },
65
- ignored: [
66
- "**/node_modules/**",
67
- "**/dist/**",
68
- "**/build/**",
69
- "**/.intlayer/**"
70
- ],
67
+ ignored: (filePath, stats) => {
68
+ const path = (0, _intlayer_config_utils.normalizePath)(filePath);
69
+ if (normalizedConfigPath && path === normalizedConfigPath) return false;
70
+ if (excludedSegments.some((segment) => path.includes(`/${segment}`))) return true;
71
+ if (stats?.isFile()) return !fileExtensions.some((extension) => path.endsWith(extension));
72
+ return false;
73
+ },
71
74
  ...options
72
75
  }).on("add", async (filePath) => {
73
76
  const fileName = (0, node_path.basename)(filePath);
@@ -111,6 +114,8 @@ const watch = (options) => {
111
114
  await require_prepareIntlayer.prepareIntlayer(configuration, { clean: false });
112
115
  } else {
113
116
  (0, _intlayer_config_utils.clearModuleCache)(filePath);
117
+ (0, _intlayer_config_utils.clearAllCache)();
118
+ (0, _intlayer_config_utils.clearDiskCacheMemory)();
114
119
  await require_handleContentDeclarationFileChange.handleContentDeclarationFileChange(filePath, configuration);
115
120
  }
116
121
  })).on("unlink", async (filePath) => {
@@ -132,7 +137,7 @@ const buildAndWatchIntlayer = async (options) => {
132
137
  const { skipPrepare, ...rest } = options ?? {};
133
138
  const configuration = options?.configuration ?? (0, _intlayer_config_node.getConfiguration)(options?.configOptions);
134
139
  if (!skipPrepare) await require_prepareIntlayer.prepareIntlayer(configuration, { forceRun: true });
135
- if (configuration.content.watch || options?.persistent) watch({
140
+ if (configuration.content.watch || options?.persistent) await watch({
136
141
  ...rest,
137
142
  configuration
138
143
  });
@@ -1 +1 @@
1
- {"version":3,"file":"watcher.cjs","names":["ANSIColor","handleContentDeclarationFileMoved","writeContentDeclaration","handleAdditionalContentDeclarationFile","prepareIntlayer","handleContentDeclarationFileChange","handleUnlinkedContentDeclarationFile"],"sources":["../../src/watcher.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { basename } from 'node:path';\nimport * as ANSIColor from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n getConfigurationAndFilePath,\n} from '@intlayer/config/node';\nimport {\n clearAllCache,\n clearModuleCache,\n normalizePath,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\n/** @ts-ignore remove error Module '\"chokidar\"' has no exported member 'ChokidarOptions' */\nimport { type ChokidarOptions, watch as chokidarWatch } from 'chokidar';\nimport { handleAdditionalContentDeclarationFile } from './handleAdditionalContentDeclarationFile';\nimport { handleContentDeclarationFileChange } from './handleContentDeclarationFileChange';\nimport { handleContentDeclarationFileMoved } from './handleContentDeclarationFileMoved';\nimport { handleUnlinkedContentDeclarationFile } from './handleUnlinkedContentDeclarationFile';\nimport { prepareIntlayer } from './prepareIntlayer';\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// Mutex-based task queue for sequential file event processing\nlet processingLock: Promise<void> | null = null;\nconst processEvent = (task: () => Promise<void>) => {\n const run = async () => {\n // Wait for the previous task to finish\n while (processingLock) {\n await processingLock;\n }\n\n let resolve: () => void;\n processingLock = new Promise<void>((r) => {\n resolve = r;\n });\n\n try {\n await task();\n } catch (error) {\n console.error(error);\n } finally {\n processingLock = null;\n resolve!();\n }\n };\n\n run();\n};\n\ntype WatchOptions = ChokidarOptions & {\n configuration?: IntlayerConfig;\n configOptions?: GetConfigurationOptions;\n skipPrepare?: boolean;\n};\n\n// Initialize chokidar watcher (non-persistent)\nexport const watch = (options?: WatchOptions) => {\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 } = configuration.content;\n\n const watchedFilesPatternWithPath = fileExtensions.flatMap((ext) =>\n contentDir.map((dir) =>\n `${normalizePath(dir)}/**/*${ext}`.replace('//', '/')\n )\n );\n\n const pathsToWatch = [\n ...watchedFilesPatternWithPath,\n ...(configurationFilePath ? [configurationFilePath] : []),\n ];\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 true, 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 return chokidarWatch(pathsToWatch, {\n persistent: isWatchMode, // Make the watcher persistent\n ignoreInitial: true, // Process existing files\n awaitWriteFinish: {\n stabilityThreshold: 1000,\n pollInterval: 100,\n },\n ignored: [\n '**/node_modules/**',\n '**/dist/**',\n '**/build/**',\n '**/.intlayer/**',\n ],\n ...options,\n })\n .on('add', async (filePath) => {\n const fileName = basename(filePath);\n let isMove = false;\n\n // Check if this Add corresponds to a pending Unlink (Move/Rename detection)\n // Heuristic:\n // - Priority A: Exact basename match (Moved to different folder)\n // - Priority B: Single entry in pendingUnlinks (Renamed file)\n let matchedOldPath: string | undefined;\n\n // Search for basename match\n for (const [oldPath] of pendingUnlinks) {\n if (basename(oldPath) === fileName) {\n matchedOldPath = oldPath;\n break;\n }\n }\n\n // If no basename match, but exactly one file was recently unlinked, assume it's a rename\n if (!matchedOldPath && pendingUnlinks.size === 1) {\n matchedOldPath = pendingUnlinks.keys().next().value;\n }\n\n if (matchedOldPath) {\n // It is a move! Cancel the unlink handler\n const pending = pendingUnlinks.get(matchedOldPath);\n if (pending) {\n clearTimeout(pending.timer);\n pendingUnlinks.delete(matchedOldPath);\n }\n\n isMove = true;\n appLogger(`File moved from ${matchedOldPath} to ${filePath}`);\n }\n\n processEvent(async () => {\n if (isMove && matchedOldPath) {\n await handleContentDeclarationFileMoved(\n matchedOldPath,\n filePath,\n configuration\n );\n } else {\n const fileContent = await readFile(filePath, 'utf-8');\n const isEmpty = fileContent === '';\n\n // Fill template content declaration file if it is empty\n if (isEmpty) {\n const extensionPattern = fileExtensions\n .map((ext) => ext.replace(/\\./g, '\\\\.'))\n .join('|');\n const name = fileName.replace(\n new RegExp(`(${extensionPattern})$`),\n ''\n );\n\n await writeContentDeclaration(\n {\n key: name,\n content: {},\n filePath,\n },\n configuration\n );\n }\n\n await handleAdditionalContentDeclarationFile(filePath, configuration);\n }\n });\n })\n .on('change', async (filePath) =>\n processEvent(async () => {\n if (configurationFilePath && filePath === configurationFilePath) {\n appLogger('Configuration file changed, repreparing Intlayer');\n\n clearModuleCache(configurationFilePath);\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 await handleContentDeclarationFileChange(filePath, configuration);\n }\n })\n )\n .on('unlink', async (filePath) => {\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 'add' event\n\n pendingUnlinks.set(filePath, { timer, oldPath: filePath });\n })\n .on('error', async (error) => {\n appLogger(`Watcher error: ${error}`, {\n level: 'error',\n });\n\n appLogger('Restarting watcher');\n\n await prepareIntlayer(configuration);\n });\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 if (configuration.content.watch || options?.persistent) {\n watch({ ...rest, configuration });\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"watcher.cjs","names":["existsSync","ANSIColor","handleContentDeclarationFileMoved","writeContentDeclaration","handleAdditionalContentDeclarationFile","prepareIntlayer","handleContentDeclarationFileChange","handleUnlinkedContentDeclarationFile"],"sources":["../../src/watcher.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { basename } from 'node:path';\nimport * as ANSIColor from '@intlayer/config/colors';\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 type { ChokidarOptions } from 'chokidar';\nimport { handleAdditionalContentDeclarationFile } from './handleAdditionalContentDeclarationFile';\nimport { handleContentDeclarationFileChange } from './handleContentDeclarationFileChange';\nimport { handleContentDeclarationFileMoved } from './handleContentDeclarationFileMoved';\nimport { handleUnlinkedContentDeclarationFile } from './handleUnlinkedContentDeclarationFile';\nimport { prepareIntlayer } from './prepareIntlayer';\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 = ChokidarOptions & {\n configuration?: IntlayerConfig;\n configOptions?: GetConfigurationOptions;\n skipPrepare?: boolean;\n};\n\n// Initialize chokidar watcher (non-persistent)\nexport const watch = async (options?: WatchOptions) => {\n const { watch: chokidarWatch } = await import('chokidar');\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 // chokidar v5 dropped glob support — use fs to resolve dirs, filter extensions via ignored\n const pathsToWatch = [\n ...contentDir.map((dir) => normalizePath(dir)).filter(existsSync),\n ...(configurationFilePath ? [configurationFilePath] : []),\n ];\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 return chokidarWatch(pathsToWatch, {\n persistent: isWatchMode, // Make the watcher persistent\n ignoreInitial: true, // Process existing files\n awaitWriteFinish: {\n stabilityThreshold: 1000,\n pollInterval: 100,\n },\n ignored: (filePath: string, stats?: import('node:fs').Stats) => {\n const path = normalizePath(filePath);\n\n if (normalizedConfigPath && path === normalizedConfigPath) return false;\n\n if (excludedSegments.some((segment) => path.includes(`/${segment}`)))\n return true;\n\n if (stats?.isFile()) {\n return !fileExtensions.some((extension) => path.endsWith(extension));\n }\n\n return false;\n },\n ...options,\n })\n .on('add', async (filePath) => {\n const fileName = basename(filePath);\n let isMove = false;\n\n // Check if this Add corresponds to a pending Unlink (Move/Rename detection)\n // Heuristic:\n // - Priority A: Exact basename match (Moved to different folder)\n // - Priority B: Single entry in pendingUnlinks (Renamed file)\n let matchedOldPath: string | undefined;\n\n // Search for basename match\n for (const [oldPath] of pendingUnlinks) {\n if (basename(oldPath) === fileName) {\n matchedOldPath = oldPath;\n break;\n }\n }\n\n // If no basename match, but exactly one file was recently unlinked, assume it's a rename\n if (!matchedOldPath && pendingUnlinks.size === 1) {\n matchedOldPath = pendingUnlinks.keys().next().value;\n }\n\n if (matchedOldPath) {\n // It is a move! Cancel the unlink handler\n const pending = pendingUnlinks.get(matchedOldPath);\n if (pending) {\n clearTimeout(pending.timer);\n pendingUnlinks.delete(matchedOldPath);\n }\n\n isMove = true;\n appLogger(`File moved from ${matchedOldPath} to ${filePath}`);\n }\n\n processEvent(async () => {\n if (isMove && matchedOldPath) {\n await handleContentDeclarationFileMoved(\n matchedOldPath,\n filePath,\n configuration\n );\n } else {\n const fileContent = await readFile(filePath, 'utf-8');\n const isEmpty = fileContent === '';\n\n // Fill template content declaration file if it is empty\n if (isEmpty) {\n const extensionPattern = fileExtensions\n .map((ext) => ext.replace(/\\./g, '\\\\.'))\n .join('|');\n const name = fileName.replace(\n new RegExp(`(${extensionPattern})$`),\n ''\n );\n\n await writeContentDeclaration(\n {\n key: name,\n content: {},\n filePath,\n },\n configuration\n );\n }\n\n await handleAdditionalContentDeclarationFile(filePath, configuration);\n }\n });\n })\n .on('change', async (filePath) =>\n processEvent(async () => {\n if (configurationFilePath && filePath === configurationFilePath) {\n appLogger('Configuration file changed, repreparing Intlayer');\n\n clearModuleCache(configurationFilePath);\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 .on('unlink', async (filePath) => {\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 'add' event\n\n pendingUnlinks.set(filePath, { timer, oldPath: filePath });\n })\n .on('error', async (error) => {\n appLogger(`Watcher error: ${error}`, {\n level: 'error',\n });\n\n appLogger('Restarting watcher');\n\n await prepareIntlayer(configuration);\n });\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 if (configuration.content.watch || options?.persistent) {\n await watch({ ...rest, configuration });\n }\n};\n"],"mappings":"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"}
@@ -63,7 +63,11 @@ const loadContentDeclaration = async (path, configuration, bundleFilePath, optio
63
63
  `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';`
64
64
  ].join("\n") }
65
65
  },
66
- aliases: { intlayer: resolvedBundleFilePath }
66
+ aliases: { intlayer: resolvedBundleFilePath },
67
+ preloadGlobals: {
68
+ INTLAYER_FILE_PATH: path,
69
+ INTLAYER_BASE_DIR: configuration.system.baseDir
70
+ }
67
71
  });
68
72
  } catch (error) {
69
73
  console.error(`Error loading content declaration at ${path}:`, error);
@@ -1 +1 @@
1
- {"version":3,"file":"loadContentDeclaration.mjs","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { loadExternalFile } from '@intlayer/config/file';\nimport {\n cacheDisk,\n getPackageJsonPath,\n getProjectRequire,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { processContentDeclaration } from '../buildIntlayerDictionary/processContentDeclaration';\nimport { filterInvalidDictionaries } from '../filterInvalidDictionaries';\nimport { parallelize } from '../utils/parallelize';\nimport { getIntlayerBundle } from './getIntlayerBundle';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { logTypeScriptErrors } from './logTypeScriptErrors';\n\nexport const formatLocalDictionaries = (\n dictionariesRecord: Record<string, Dictionary>,\n configuration: IntlayerConfig\n): Dictionary[] =>\n Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({\n ...dict,\n location: dict.location ?? configuration.dictionary?.location ?? 'local',\n localId: `${dict.key}::local::${relativePath}`,\n filePath: relativePath,\n }));\n\nexport const ensureIntlayerBundle = async (\n configuration: IntlayerConfig\n): Promise<string> => {\n const { system } = configuration;\n\n const { set, isValid } = cacheDisk(configuration, ['intlayer-bundle'], {\n ttlMs: 1000 * 60 * 60 * 24 * 5, // 5 days\n });\n\n const filePath = join(system.cacheDir, 'intlayer-bundle.cjs');\n const hasIntlayerBundle = await isValid();\n\n if (!hasIntlayerBundle) {\n const intlayerBundle = await getIntlayerBundle(configuration);\n await writeFile(filePath, intlayerBundle);\n await set('ok');\n }\n\n return filePath;\n};\n\ntype LoadContentDeclarationOptions = {\n logError?: boolean;\n};\n\n// Initialize a module-level cache\nlet cachedExternalDeps: string[] | null = null;\n\n// Helper to fetch and cache the dependencies\nconst getExternalDeps = async (baseDir: string): Promise<string[]> => {\n if (cachedExternalDeps) {\n return cachedExternalDeps; // Return instantly on subsequent calls\n }\n\n try {\n const packageJsonPath = getPackageJsonPath(baseDir);\n\n const packageJSON = await readFile(\n packageJsonPath.packageJsonPath,\n 'utf-8'\n );\n const parsedPackages = JSON.parse(packageJSON);\n const allDependencies = Object.keys({\n ...parsedPackages.dependencies,\n ...parsedPackages.devDependencies,\n });\n\n // Specify the ESM packages to bundle\n const esmPackagesToBundle: string[] = [];\n\n const externalDeps = allDependencies.filter(\n (dep) => !esmPackagesToBundle.includes(dep)\n );\n\n externalDeps.push('esbuild');\n\n // Save to cache\n cachedExternalDeps = externalDeps;\n } catch (error) {\n console.warn(\n 'Could not read package.json for externalizing dependencies, fallback to empty array',\n error\n );\n cachedExternalDeps = ['esbuild'];\n }\n\n return cachedExternalDeps;\n};\n\nexport const loadContentDeclaration = async (\n path: string,\n configuration: IntlayerConfig,\n bundleFilePath?: string,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary | undefined> => {\n const { build, system } = configuration;\n\n // Call the cached helper\n const externalDeps = await getExternalDeps(system.baseDir);\n\n const resolvedBundleFilePath =\n bundleFilePath ?? (await ensureIntlayerBundle(configuration));\n\n try {\n const dictionary = await loadExternalFile(path, {\n logError: options?.logError,\n projectRequire: build.require ?? getProjectRequire(),\n buildOptions: {\n packages: undefined, // It fixes the import of ESM packages in the content declaration\n external: externalDeps,\n banner: {\n js: [\n `var __filename = ${JSON.stringify(path)};`,\n `var __dirname = ${JSON.stringify(dirname(path))};`,\n `globalThis.INTLAYER_FILE_PATH = '${path}';`,\n `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';`,\n ].join('\\n'),\n },\n },\n aliases: {\n intlayer: resolvedBundleFilePath,\n },\n });\n\n return dictionary;\n } catch (error) {\n console.error(`Error loading content declaration at ${path}:`, error);\n return undefined;\n }\n};\n\nexport const loadContentDeclarations = async (\n contentDeclarationFilePath: string[],\n configuration: IntlayerConfig,\n onStatusUpdate?: (status: DictionariesStatus[]) => void,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary[]> => {\n const { build, system } = configuration;\n\n // Check for TypeScript warnings before we build\n if (build.checkTypes) {\n logTypeScriptErrors(contentDeclarationFilePath, configuration).catch(\n (e) => {\n console.error('Error during TypeScript validation:', e);\n }\n );\n }\n\n const bundleFilePath = await ensureIntlayerBundle(configuration);\n\n try {\n const dictionariesPromises = contentDeclarationFilePath.map(\n async (path) => {\n const relativePath = relative(system.baseDir, path);\n\n const dictionary = await loadContentDeclaration(\n path,\n configuration,\n bundleFilePath,\n options\n );\n\n return { relativePath, dictionary };\n }\n );\n\n const dictionariesArray = await Promise.all(dictionariesPromises);\n const dictionariesRecord = dictionariesArray.reduce(\n (acc, { relativePath, dictionary }) => {\n if (dictionary) {\n acc[relativePath] = dictionary;\n }\n return acc;\n },\n {} as Record<string, Dictionary>\n );\n\n const contentDeclarations: Dictionary[] = formatLocalDictionaries(\n dictionariesRecord,\n configuration\n ).filter((dictionary) => dictionary.location !== 'remote');\n\n const listFoundDictionaries = contentDeclarations.map((declaration) => ({\n dictionaryKey: declaration.key,\n type: 'local' as const,\n status: 'found' as const,\n }));\n\n onStatusUpdate?.(listFoundDictionaries);\n\n const processedDictionaries = await parallelize(\n contentDeclarations,\n async (contentDeclaration): Promise<Dictionary | undefined> => {\n if (!contentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: contentDeclaration.key,\n type: 'local',\n status: 'building',\n },\n ]);\n\n const processedContentDeclaration = await processContentDeclaration(\n contentDeclaration as Dictionary,\n configuration\n );\n\n if (!processedContentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: processedContentDeclaration.key,\n type: 'local',\n status: 'built',\n },\n ]);\n\n return processedContentDeclaration;\n }\n );\n\n return filterInvalidDictionaries(processedDictionaries, configuration, {\n checkSchema: false,\n });\n } catch {\n console.error('Error loading content declarations');\n }\n\n return [];\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"loadContentDeclaration.mjs","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"sourcesContent":["import { readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative } from 'node:path';\nimport { loadExternalFile } from '@intlayer/config/file';\nimport {\n cacheDisk,\n getPackageJsonPath,\n getProjectRequire,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { processContentDeclaration } from '../buildIntlayerDictionary/processContentDeclaration';\nimport { filterInvalidDictionaries } from '../filterInvalidDictionaries';\nimport { parallelize } from '../utils/parallelize';\nimport { getIntlayerBundle } from './getIntlayerBundle';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { logTypeScriptErrors } from './logTypeScriptErrors';\n\nexport const formatLocalDictionaries = (\n dictionariesRecord: Record<string, Dictionary>,\n configuration: IntlayerConfig\n): Dictionary[] =>\n Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({\n ...dict,\n location: dict.location ?? configuration.dictionary?.location ?? 'local',\n localId: `${dict.key}::local::${relativePath}`,\n filePath: relativePath,\n }));\n\nexport const ensureIntlayerBundle = async (\n configuration: IntlayerConfig\n): Promise<string> => {\n const { system } = configuration;\n\n const { set, isValid } = cacheDisk(configuration, ['intlayer-bundle'], {\n ttlMs: 1000 * 60 * 60 * 24 * 5, // 5 days\n });\n\n const filePath = join(system.cacheDir, 'intlayer-bundle.cjs');\n const hasIntlayerBundle = await isValid();\n\n if (!hasIntlayerBundle) {\n const intlayerBundle = await getIntlayerBundle(configuration);\n await writeFile(filePath, intlayerBundle);\n await set('ok');\n }\n\n return filePath;\n};\n\ntype LoadContentDeclarationOptions = {\n logError?: boolean;\n};\n\n// Initialize a module-level cache\nlet cachedExternalDeps: string[] | null = null;\n\n// Helper to fetch and cache the dependencies\nconst getExternalDeps = async (baseDir: string): Promise<string[]> => {\n if (cachedExternalDeps) {\n return cachedExternalDeps; // Return instantly on subsequent calls\n }\n\n try {\n const packageJsonPath = getPackageJsonPath(baseDir);\n\n const packageJSON = await readFile(\n packageJsonPath.packageJsonPath,\n 'utf-8'\n );\n const parsedPackages = JSON.parse(packageJSON);\n const allDependencies = Object.keys({\n ...parsedPackages.dependencies,\n ...parsedPackages.devDependencies,\n });\n\n // Specify the ESM packages to bundle\n const esmPackagesToBundle: string[] = [];\n\n const externalDeps = allDependencies.filter(\n (dep) => !esmPackagesToBundle.includes(dep)\n );\n\n externalDeps.push('esbuild');\n\n // Save to cache\n cachedExternalDeps = externalDeps;\n } catch (error) {\n console.warn(\n 'Could not read package.json for externalizing dependencies, fallback to empty array',\n error\n );\n cachedExternalDeps = ['esbuild'];\n }\n\n return cachedExternalDeps;\n};\n\nexport const loadContentDeclaration = async (\n path: string,\n configuration: IntlayerConfig,\n bundleFilePath?: string,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary | undefined> => {\n const { build, system } = configuration;\n\n // Call the cached helper\n const externalDeps = await getExternalDeps(system.baseDir);\n\n const resolvedBundleFilePath =\n bundleFilePath ?? (await ensureIntlayerBundle(configuration));\n\n try {\n const dictionary = await loadExternalFile(path, {\n logError: options?.logError,\n projectRequire: build.require ?? getProjectRequire(),\n buildOptions: {\n packages: undefined, // It fixes the import of ESM packages in the content declaration\n external: externalDeps,\n banner: {\n js: [\n `var __filename = ${JSON.stringify(path)};`,\n `var __dirname = ${JSON.stringify(dirname(path))};`,\n // Also set on the VM sandbox's globalThis for VM-internal code.\n // External modules (e.g. @intlayer/core's file()) run in the main\n // Node.js context and are handled by preloadGlobals below.\n `globalThis.INTLAYER_FILE_PATH = '${path}';`,\n `globalThis.INTLAYER_BASE_DIR = '${configuration.system.baseDir}';`,\n ].join('\\n'),\n },\n },\n aliases: {\n intlayer: resolvedBundleFilePath,\n },\n // Temporarily expose these on the main Node.js globalThis so that external\n // modules required inside the VM (e.g. @intlayer/core's file() helper)\n // can resolve relative paths against the correct content declaration path.\n preloadGlobals: {\n INTLAYER_FILE_PATH: path,\n INTLAYER_BASE_DIR: configuration.system.baseDir,\n },\n });\n\n return dictionary;\n } catch (error) {\n console.error(`Error loading content declaration at ${path}:`, error);\n return undefined;\n }\n};\n\nexport const loadContentDeclarations = async (\n contentDeclarationFilePath: string[],\n configuration: IntlayerConfig,\n onStatusUpdate?: (status: DictionariesStatus[]) => void,\n options?: LoadContentDeclarationOptions\n): Promise<Dictionary[]> => {\n const { build, system } = configuration;\n\n // Check for TypeScript warnings before we build\n if (build.checkTypes) {\n logTypeScriptErrors(contentDeclarationFilePath, configuration).catch(\n (e) => {\n console.error('Error during TypeScript validation:', e);\n }\n );\n }\n\n const bundleFilePath = await ensureIntlayerBundle(configuration);\n\n try {\n const dictionariesPromises = contentDeclarationFilePath.map(\n async (path) => {\n const relativePath = relative(system.baseDir, path);\n\n const dictionary = await loadContentDeclaration(\n path,\n configuration,\n bundleFilePath,\n options\n );\n\n return { relativePath, dictionary };\n }\n );\n\n const dictionariesArray = await Promise.all(dictionariesPromises);\n const dictionariesRecord = dictionariesArray.reduce(\n (acc, { relativePath, dictionary }) => {\n if (dictionary) {\n acc[relativePath] = dictionary;\n }\n return acc;\n },\n {} as Record<string, Dictionary>\n );\n\n const contentDeclarations: Dictionary[] = formatLocalDictionaries(\n dictionariesRecord,\n configuration\n ).filter((dictionary) => dictionary.location !== 'remote');\n\n const listFoundDictionaries = contentDeclarations.map((declaration) => ({\n dictionaryKey: declaration.key,\n type: 'local' as const,\n status: 'found' as const,\n }));\n\n onStatusUpdate?.(listFoundDictionaries);\n\n const processedDictionaries = await parallelize(\n contentDeclarations,\n async (contentDeclaration): Promise<Dictionary | undefined> => {\n if (!contentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: contentDeclaration.key,\n type: 'local',\n status: 'building',\n },\n ]);\n\n const processedContentDeclaration = await processContentDeclaration(\n contentDeclaration as Dictionary,\n configuration\n );\n\n if (!processedContentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: processedContentDeclaration.key,\n type: 'local',\n status: 'built',\n },\n ]);\n\n return processedContentDeclaration;\n }\n );\n\n return filterInvalidDictionaries(processedDictionaries, configuration, {\n checkSchema: false,\n });\n } catch {\n console.error('Error loading content declarations');\n }\n\n return [];\n};\n"],"mappings":"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"}
@@ -8,43 +8,43 @@ import { readFile } from "node:fs/promises";
8
8
  import { basename } from "node:path";
9
9
  import { colorize, getAppLogger } from "@intlayer/config/logger";
10
10
  import { getConfiguration, getConfigurationAndFilePath } from "@intlayer/config/node";
11
- import { clearAllCache, clearModuleCache, normalizePath } from "@intlayer/config/utils";
11
+ import { existsSync } from "node:fs";
12
+ import { clearAllCache, clearDiskCacheMemory, clearModuleCache, normalizePath } from "@intlayer/config/utils";
12
13
  import * as ANSIColor from "@intlayer/config/colors";
13
- import { watch as watch$1 } from "chokidar";
14
14
 
15
15
  //#region src/watcher.ts
16
- /** @ts-ignore remove error Module '"chokidar"' has no exported member 'ChokidarOptions' */
17
16
  const pendingUnlinks = /* @__PURE__ */ new Map();
18
- let processingLock = null;
19
- const processEvent = (task) => {
20
- const run = async () => {
21
- while (processingLock) await processingLock;
22
- let resolve;
23
- processingLock = new Promise((r) => {
24
- resolve = r;
25
- });
17
+ const taskQueue = [];
18
+ let isProcessing = false;
19
+ const processQueue = async () => {
20
+ if (isProcessing) return;
21
+ isProcessing = true;
22
+ while (taskQueue.length > 0) {
23
+ const task = taskQueue.shift();
26
24
  try {
27
25
  await task();
28
26
  } catch (error) {
29
27
  console.error(error);
30
- } finally {
31
- processingLock = null;
32
- resolve();
33
28
  }
34
- };
35
- run();
29
+ }
30
+ isProcessing = false;
31
+ };
32
+ const processEvent = (task) => {
33
+ taskQueue.push(task);
34
+ processQueue();
36
35
  };
37
- const watch = (options) => {
36
+ const watch = async (options) => {
37
+ const { watch: chokidarWatch } = await import("chokidar");
38
38
  const configResult = getConfigurationAndFilePath(options?.configOptions);
39
39
  const configurationFilePath = configResult.configurationFilePath;
40
40
  let configuration = options?.configuration ?? configResult.configuration;
41
41
  const appLogger = getAppLogger(configuration);
42
- const { watch: isWatchMode, fileExtensions, contentDir } = configuration.content;
43
- const pathsToWatch = [...fileExtensions.flatMap((ext) => contentDir.map((dir) => `${normalizePath(dir)}/**/*${ext}`.replace("//", "/"))), ...configurationFilePath ? [configurationFilePath] : []];
42
+ const { watch: isWatchMode, fileExtensions, contentDir, excludedPath } = configuration.content;
43
+ const pathsToWatch = [...contentDir.map((dir) => normalizePath(dir)).filter(existsSync), ...configurationFilePath ? [configurationFilePath] : []];
44
44
  if (!configuration.content.watch) return;
45
45
  appLogger("Watching Intlayer content declarations");
46
46
  if (configuration.build.optimize === true) appLogger([
47
- "Build optimization is forced to true, but watching is enabled too.",
47
+ `Build optimization is forced to ${colorize("true", ANSIColor.GREY)}, but watching is enabled too.`,
48
48
  "It may lead to dev mode performance degradation as well as import errors.",
49
49
  "Its recommended to keep the",
50
50
  colorize("`build.optimized`", ANSIColor.BLUE),
@@ -52,19 +52,22 @@ const watch = (options) => {
52
52
  colorize("undefined", ANSIColor.GREY),
53
53
  "to get the best dev mode experience"
54
54
  ], { level: "warn" });
55
- return watch$1(pathsToWatch, {
55
+ const excludedSegments = excludedPath.map((segment) => segment.replace(/^\*\*\//, "").replace(/\/\*\*$/, ""));
56
+ const normalizedConfigPath = configurationFilePath ? normalizePath(configurationFilePath) : null;
57
+ return chokidarWatch(pathsToWatch, {
56
58
  persistent: isWatchMode,
57
59
  ignoreInitial: true,
58
60
  awaitWriteFinish: {
59
61
  stabilityThreshold: 1e3,
60
62
  pollInterval: 100
61
63
  },
62
- ignored: [
63
- "**/node_modules/**",
64
- "**/dist/**",
65
- "**/build/**",
66
- "**/.intlayer/**"
67
- ],
64
+ ignored: (filePath, stats) => {
65
+ const path = normalizePath(filePath);
66
+ if (normalizedConfigPath && path === normalizedConfigPath) return false;
67
+ if (excludedSegments.some((segment) => path.includes(`/${segment}`))) return true;
68
+ if (stats?.isFile()) return !fileExtensions.some((extension) => path.endsWith(extension));
69
+ return false;
70
+ },
68
71
  ...options
69
72
  }).on("add", async (filePath) => {
70
73
  const fileName = basename(filePath);
@@ -108,6 +111,8 @@ const watch = (options) => {
108
111
  await prepareIntlayer(configuration, { clean: false });
109
112
  } else {
110
113
  clearModuleCache(filePath);
114
+ clearAllCache();
115
+ clearDiskCacheMemory();
111
116
  await handleContentDeclarationFileChange(filePath, configuration);
112
117
  }
113
118
  })).on("unlink", async (filePath) => {
@@ -129,7 +134,7 @@ const buildAndWatchIntlayer = async (options) => {
129
134
  const { skipPrepare, ...rest } = options ?? {};
130
135
  const configuration = options?.configuration ?? getConfiguration(options?.configOptions);
131
136
  if (!skipPrepare) await prepareIntlayer(configuration, { forceRun: true });
132
- if (configuration.content.watch || options?.persistent) watch({
137
+ if (configuration.content.watch || options?.persistent) await watch({
133
138
  ...rest,
134
139
  configuration
135
140
  });
@@ -1 +1 @@
1
- {"version":3,"file":"watcher.mjs","names":["chokidarWatch"],"sources":["../../src/watcher.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { basename } from 'node:path';\nimport * as ANSIColor from '@intlayer/config/colors';\nimport { colorize, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n getConfigurationAndFilePath,\n} from '@intlayer/config/node';\nimport {\n clearAllCache,\n clearModuleCache,\n normalizePath,\n} from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\n/** @ts-ignore remove error Module '\"chokidar\"' has no exported member 'ChokidarOptions' */\nimport { type ChokidarOptions, watch as chokidarWatch } from 'chokidar';\nimport { handleAdditionalContentDeclarationFile } from './handleAdditionalContentDeclarationFile';\nimport { handleContentDeclarationFileChange } from './handleContentDeclarationFileChange';\nimport { handleContentDeclarationFileMoved } from './handleContentDeclarationFileMoved';\nimport { handleUnlinkedContentDeclarationFile } from './handleUnlinkedContentDeclarationFile';\nimport { prepareIntlayer } from './prepareIntlayer';\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// Mutex-based task queue for sequential file event processing\nlet processingLock: Promise<void> | null = null;\nconst processEvent = (task: () => Promise<void>) => {\n const run = async () => {\n // Wait for the previous task to finish\n while (processingLock) {\n await processingLock;\n }\n\n let resolve: () => void;\n processingLock = new Promise<void>((r) => {\n resolve = r;\n });\n\n try {\n await task();\n } catch (error) {\n console.error(error);\n } finally {\n processingLock = null;\n resolve!();\n }\n };\n\n run();\n};\n\ntype WatchOptions = ChokidarOptions & {\n configuration?: IntlayerConfig;\n configOptions?: GetConfigurationOptions;\n skipPrepare?: boolean;\n};\n\n// Initialize chokidar watcher (non-persistent)\nexport const watch = (options?: WatchOptions) => {\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 } = configuration.content;\n\n const watchedFilesPatternWithPath = fileExtensions.flatMap((ext) =>\n contentDir.map((dir) =>\n `${normalizePath(dir)}/**/*${ext}`.replace('//', '/')\n )\n );\n\n const pathsToWatch = [\n ...watchedFilesPatternWithPath,\n ...(configurationFilePath ? [configurationFilePath] : []),\n ];\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 true, 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 return chokidarWatch(pathsToWatch, {\n persistent: isWatchMode, // Make the watcher persistent\n ignoreInitial: true, // Process existing files\n awaitWriteFinish: {\n stabilityThreshold: 1000,\n pollInterval: 100,\n },\n ignored: [\n '**/node_modules/**',\n '**/dist/**',\n '**/build/**',\n '**/.intlayer/**',\n ],\n ...options,\n })\n .on('add', async (filePath) => {\n const fileName = basename(filePath);\n let isMove = false;\n\n // Check if this Add corresponds to a pending Unlink (Move/Rename detection)\n // Heuristic:\n // - Priority A: Exact basename match (Moved to different folder)\n // - Priority B: Single entry in pendingUnlinks (Renamed file)\n let matchedOldPath: string | undefined;\n\n // Search for basename match\n for (const [oldPath] of pendingUnlinks) {\n if (basename(oldPath) === fileName) {\n matchedOldPath = oldPath;\n break;\n }\n }\n\n // If no basename match, but exactly one file was recently unlinked, assume it's a rename\n if (!matchedOldPath && pendingUnlinks.size === 1) {\n matchedOldPath = pendingUnlinks.keys().next().value;\n }\n\n if (matchedOldPath) {\n // It is a move! Cancel the unlink handler\n const pending = pendingUnlinks.get(matchedOldPath);\n if (pending) {\n clearTimeout(pending.timer);\n pendingUnlinks.delete(matchedOldPath);\n }\n\n isMove = true;\n appLogger(`File moved from ${matchedOldPath} to ${filePath}`);\n }\n\n processEvent(async () => {\n if (isMove && matchedOldPath) {\n await handleContentDeclarationFileMoved(\n matchedOldPath,\n filePath,\n configuration\n );\n } else {\n const fileContent = await readFile(filePath, 'utf-8');\n const isEmpty = fileContent === '';\n\n // Fill template content declaration file if it is empty\n if (isEmpty) {\n const extensionPattern = fileExtensions\n .map((ext) => ext.replace(/\\./g, '\\\\.'))\n .join('|');\n const name = fileName.replace(\n new RegExp(`(${extensionPattern})$`),\n ''\n );\n\n await writeContentDeclaration(\n {\n key: name,\n content: {},\n filePath,\n },\n configuration\n );\n }\n\n await handleAdditionalContentDeclarationFile(filePath, configuration);\n }\n });\n })\n .on('change', async (filePath) =>\n processEvent(async () => {\n if (configurationFilePath && filePath === configurationFilePath) {\n appLogger('Configuration file changed, repreparing Intlayer');\n\n clearModuleCache(configurationFilePath);\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 await handleContentDeclarationFileChange(filePath, configuration);\n }\n })\n )\n .on('unlink', async (filePath) => {\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 'add' event\n\n pendingUnlinks.set(filePath, { timer, oldPath: filePath });\n })\n .on('error', async (error) => {\n appLogger(`Watcher error: ${error}`, {\n level: 'error',\n });\n\n appLogger('Restarting watcher');\n\n await prepareIntlayer(configuration);\n });\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 if (configuration.content.watch || options?.persistent) {\n watch({ ...rest, configuration });\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAyBA,MAAM,iCAAiB,IAAI,KAGxB;AAGH,IAAI,iBAAuC;AAC3C,MAAM,gBAAgB,SAA8B;CAClD,MAAM,MAAM,YAAY;AAEtB,SAAO,eACL,OAAM;EAGR,IAAI;AACJ,mBAAiB,IAAI,SAAe,MAAM;AACxC,aAAU;IACV;AAEF,MAAI;AACF,SAAM,MAAM;WACL,OAAO;AACd,WAAQ,MAAM,MAAM;YACZ;AACR,oBAAiB;AACjB,YAAU;;;AAId,MAAK;;AAUP,MAAa,SAAS,YAA2B;CAC/C,MAAM,eAAe,4BAA4B,SAAS,cAAc;CACxE,MAAM,wBAAwB,aAAa;CAC3C,IAAI,gBACF,SAAS,iBAAiB,aAAa;CACzC,MAAM,YAAY,aAAa,cAAc;CAE7C,MAAM,EACJ,OAAO,aACP,gBACA,eACE,cAAc;CAQlB,MAAM,eAAe,CACnB,GAPkC,eAAe,SAAS,QAC1D,WAAW,KAAK,QACd,GAAG,cAAc,IAAI,CAAC,OAAO,MAAM,QAAQ,MAAM,IAAI,CACtD,CAI6B,EAC9B,GAAI,wBAAwB,CAAC,sBAAsB,GAAG,EAAE,CACzD;AAED,KAAI,CAAC,cAAc,QAAQ,MAAO;AAElC,WAAU,yCAAyC;AAEnD,KAAI,cAAc,MAAM,aAAa,KACnC,WACE;EACE;EACA;EACA;EACA,SAAS,qBAAqB,UAAU,KAAK;EAC7C;EACA,SAAS,aAAa,UAAU,KAAK;EACrC;EACD,EACD,EACE,OAAO,QACR,CACF;AAGH,QAAOA,QAAc,cAAc;EACjC,YAAY;EACZ,eAAe;EACf,kBAAkB;GAChB,oBAAoB;GACpB,cAAc;GACf;EACD,SAAS;GACP;GACA;GACA;GACA;GACD;EACD,GAAG;EACJ,CAAC,CACC,GAAG,OAAO,OAAO,aAAa;EAC7B,MAAM,WAAW,SAAS,SAAS;EACnC,IAAI,SAAS;EAMb,IAAI;AAGJ,OAAK,MAAM,CAAC,YAAY,eACtB,KAAI,SAAS,QAAQ,KAAK,UAAU;AAClC,oBAAiB;AACjB;;AAKJ,MAAI,CAAC,kBAAkB,eAAe,SAAS,EAC7C,kBAAiB,eAAe,MAAM,CAAC,MAAM,CAAC;AAGhD,MAAI,gBAAgB;GAElB,MAAM,UAAU,eAAe,IAAI,eAAe;AAClD,OAAI,SAAS;AACX,iBAAa,QAAQ,MAAM;AAC3B,mBAAe,OAAO,eAAe;;AAGvC,YAAS;AACT,aAAU,mBAAmB,eAAe,MAAM,WAAW;;AAG/D,eAAa,YAAY;AACvB,OAAI,UAAU,eACZ,OAAM,kCACJ,gBACA,UACA,cACD;QACI;AAKL,QAHgB,MADU,SAAS,UAAU,QAAQ,KACrB,IAGnB;KACX,MAAM,mBAAmB,eACtB,KAAK,QAAQ,IAAI,QAAQ,OAAO,MAAM,CAAC,CACvC,KAAK,IAAI;AAMZ,WAAM,wBACJ;MACE,KAPS,SAAS,QACpB,IAAI,OAAO,IAAI,iBAAiB,IAAI,EACpC,GAKW;MACT,SAAS,EAAE;MACX;MACD,EACD,cACD;;AAGH,UAAM,uCAAuC,UAAU,cAAc;;IAEvE;GACF,CACD,GAAG,UAAU,OAAO,aACnB,aAAa,YAAY;AACvB,MAAI,yBAAyB,aAAa,uBAAuB;AAC/D,aAAU,mDAAmD;AAE7D,oBAAiB,sBAAsB;AACvC,kBAAe;GAEf,MAAM,EAAE,eAAe,qBACrB,4BAA4B,SAAS,cAAc;AAErD,mBAAgB,SAAS,iBAAiB;AAE1C,SAAM,gBAAgB,eAAe,EAAE,OAAO,OAAO,CAAC;SACjD;AAEL,oBAAiB,SAAS;AAC1B,SAAM,mCAAmC,UAAU,cAAc;;GAEnE,CACH,CACA,GAAG,UAAU,OAAO,aAAa;EAEhC,MAAM,QAAQ,WAAW,YAAY;AAEnC,kBAAe,OAAO,SAAS;AAC/B,gBAAa,YACX,qCAAqC,UAAU,cAAc,CAC9D;KACA,IAAI;AAEP,iBAAe,IAAI,UAAU;GAAE;GAAO,SAAS;GAAU,CAAC;GAC1D,CACD,GAAG,SAAS,OAAO,UAAU;AAC5B,YAAU,kBAAkB,SAAS,EACnC,OAAO,SACR,CAAC;AAEF,YAAU,qBAAqB;AAE/B,QAAM,gBAAgB,cAAc;GACpC;;AAGN,MAAa,wBAAwB,OAAO,YAA2B;CACrE,MAAM,EAAE,aAAa,GAAG,SAAS,WAAW,EAAE;CAC9C,MAAM,gBACJ,SAAS,iBAAiB,iBAAiB,SAAS,cAAc;AAEpE,KAAI,CAAC,YACH,OAAM,gBAAgB,eAAe,EAAE,UAAU,MAAM,CAAC;AAG1D,KAAI,cAAc,QAAQ,SAAS,SAAS,WAC1C,OAAM;EAAE,GAAG;EAAM;EAAe,CAAC"}
1
+ {"version":3,"file":"watcher.mjs","names":[],"sources":["../../src/watcher.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { basename } from 'node:path';\nimport * as ANSIColor from '@intlayer/config/colors';\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 type { ChokidarOptions } from 'chokidar';\nimport { handleAdditionalContentDeclarationFile } from './handleAdditionalContentDeclarationFile';\nimport { handleContentDeclarationFileChange } from './handleContentDeclarationFileChange';\nimport { handleContentDeclarationFileMoved } from './handleContentDeclarationFileMoved';\nimport { handleUnlinkedContentDeclarationFile } from './handleUnlinkedContentDeclarationFile';\nimport { prepareIntlayer } from './prepareIntlayer';\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 = ChokidarOptions & {\n configuration?: IntlayerConfig;\n configOptions?: GetConfigurationOptions;\n skipPrepare?: boolean;\n};\n\n// Initialize chokidar watcher (non-persistent)\nexport const watch = async (options?: WatchOptions) => {\n const { watch: chokidarWatch } = await import('chokidar');\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 // chokidar v5 dropped glob support — use fs to resolve dirs, filter extensions via ignored\n const pathsToWatch = [\n ...contentDir.map((dir) => normalizePath(dir)).filter(existsSync),\n ...(configurationFilePath ? [configurationFilePath] : []),\n ];\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 return chokidarWatch(pathsToWatch, {\n persistent: isWatchMode, // Make the watcher persistent\n ignoreInitial: true, // Process existing files\n awaitWriteFinish: {\n stabilityThreshold: 1000,\n pollInterval: 100,\n },\n ignored: (filePath: string, stats?: import('node:fs').Stats) => {\n const path = normalizePath(filePath);\n\n if (normalizedConfigPath && path === normalizedConfigPath) return false;\n\n if (excludedSegments.some((segment) => path.includes(`/${segment}`)))\n return true;\n\n if (stats?.isFile()) {\n return !fileExtensions.some((extension) => path.endsWith(extension));\n }\n\n return false;\n },\n ...options,\n })\n .on('add', async (filePath) => {\n const fileName = basename(filePath);\n let isMove = false;\n\n // Check if this Add corresponds to a pending Unlink (Move/Rename detection)\n // Heuristic:\n // - Priority A: Exact basename match (Moved to different folder)\n // - Priority B: Single entry in pendingUnlinks (Renamed file)\n let matchedOldPath: string | undefined;\n\n // Search for basename match\n for (const [oldPath] of pendingUnlinks) {\n if (basename(oldPath) === fileName) {\n matchedOldPath = oldPath;\n break;\n }\n }\n\n // If no basename match, but exactly one file was recently unlinked, assume it's a rename\n if (!matchedOldPath && pendingUnlinks.size === 1) {\n matchedOldPath = pendingUnlinks.keys().next().value;\n }\n\n if (matchedOldPath) {\n // It is a move! Cancel the unlink handler\n const pending = pendingUnlinks.get(matchedOldPath);\n if (pending) {\n clearTimeout(pending.timer);\n pendingUnlinks.delete(matchedOldPath);\n }\n\n isMove = true;\n appLogger(`File moved from ${matchedOldPath} to ${filePath}`);\n }\n\n processEvent(async () => {\n if (isMove && matchedOldPath) {\n await handleContentDeclarationFileMoved(\n matchedOldPath,\n filePath,\n configuration\n );\n } else {\n const fileContent = await readFile(filePath, 'utf-8');\n const isEmpty = fileContent === '';\n\n // Fill template content declaration file if it is empty\n if (isEmpty) {\n const extensionPattern = fileExtensions\n .map((ext) => ext.replace(/\\./g, '\\\\.'))\n .join('|');\n const name = fileName.replace(\n new RegExp(`(${extensionPattern})$`),\n ''\n );\n\n await writeContentDeclaration(\n {\n key: name,\n content: {},\n filePath,\n },\n configuration\n );\n }\n\n await handleAdditionalContentDeclarationFile(filePath, configuration);\n }\n });\n })\n .on('change', async (filePath) =>\n processEvent(async () => {\n if (configurationFilePath && filePath === configurationFilePath) {\n appLogger('Configuration file changed, repreparing Intlayer');\n\n clearModuleCache(configurationFilePath);\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 .on('unlink', async (filePath) => {\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 'add' event\n\n pendingUnlinks.set(filePath, { timer, oldPath: filePath });\n })\n .on('error', async (error) => {\n appLogger(`Watcher error: ${error}`, {\n level: 'error',\n });\n\n appLogger('Restarting watcher');\n\n await prepareIntlayer(configuration);\n });\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 if (configuration.content.watch || options?.persistent) {\n await watch({ ...rest, configuration });\n }\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"loadContentDeclaration.d.ts","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"mappings":";;;;;cAiBa,uBAAA,GACX,kBAAA,EAAoB,MAAA,SAAe,UAAA,GACnC,aAAA,EAAe,cAAA,KACd,UAAA;AAAA,cAQU,oBAAA,GACX,aAAA,EAAe,cAAA,KACd,OAAA;AAAA,KAmBE,6BAAA;EACH,QAAA;AAAA;AAAA,cA+CW,sBAAA,GACX,IAAA,UACA,aAAA,EAAe,cAAA,EACf,cAAA,WACA,OAAA,GAAU,6BAAA,KACT,OAAA,CAAQ,UAAA;AAAA,cAqCE,uBAAA,GACX,0BAAA,YACA,aAAA,EAAe,cAAA,EACf,cAAA,IAAkB,MAAA,EAAQ,kBAAA,aAC1B,OAAA,GAAU,6BAAA,KACT,OAAA,CAAQ,UAAA"}
1
+ {"version":3,"file":"loadContentDeclaration.d.ts","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"mappings":";;;;;cAiBa,uBAAA,GACX,kBAAA,EAAoB,MAAA,SAAe,UAAA,GACnC,aAAA,EAAe,cAAA,KACd,UAAA;AAAA,cAQU,oBAAA,GACX,aAAA,EAAe,cAAA,KACd,OAAA;AAAA,KAmBE,6BAAA;EACH,QAAA;AAAA;AAAA,cA+CW,sBAAA,GACX,IAAA,UACA,aAAA,EAAe,cAAA,EACf,cAAA,WACA,OAAA,GAAU,6BAAA,KACT,OAAA,CAAQ,UAAA;AAAA,cA+CE,uBAAA,GACX,0BAAA,YACA,aAAA,EAAe,cAAA,EACf,cAAA,IAAkB,MAAA,EAAQ,kBAAA,aAC1B,OAAA,GAAU,6BAAA,KACT,OAAA,CAAQ,UAAA"}
@@ -9,7 +9,7 @@ type WatchOptions = ChokidarOptions & {
9
9
  configOptions?: GetConfigurationOptions;
10
10
  skipPrepare?: boolean;
11
11
  };
12
- declare const watch: (options?: WatchOptions) => _$chokidar.FSWatcher;
12
+ declare const watch: (options?: WatchOptions) => Promise<_$chokidar.FSWatcher>;
13
13
  declare const buildAndWatchIntlayer: (options?: WatchOptions) => Promise<void>;
14
14
  //#endregion
15
15
  export { buildAndWatchIntlayer, watch };
@@ -1 +1 @@
1
- {"version":3,"file":"watcher.d.ts","names":[],"sources":["../../src/watcher.ts"],"mappings":";;;;;;KAyDK,YAAA,GAAe,eAAA;EAClB,aAAA,GAAgB,cAAA;EAChB,aAAA,GAAgB,uBAAA;EAChB,WAAA;AAAA;AAAA,cAIW,KAAA,GAAS,OAAA,GAAU,YAAA,KAAY,UAAA,CAAA,SAAA;AAAA,cA8K/B,qBAAA,GAA+B,OAAA,GAAU,YAAA,KAAY,OAAA"}
1
+ {"version":3,"file":"watcher.d.ts","names":[],"sources":["../../src/watcher.ts"],"mappings":";;;;;;KAsDK,YAAA,GAAe,eAAA;EAClB,aAAA,GAAgB,cAAA;EAChB,aAAA,GAAgB,uBAAA;EAChB,WAAA;AAAA;AAAA,cAIW,KAAA,GAAe,OAAA,GAAU,YAAA,KAAY,OAAA,CAAA,UAAA,CAAA,SAAA;AAAA,cA+LrC,qBAAA,GAA+B,OAAA,GAAU,YAAA,KAAY,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/chokidar",
3
- "version": "8.8.0",
3
+ "version": "8.9.1",
4
4
  "private": false,
5
5
  "description": "Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.",
6
6
  "keywords": [
@@ -109,14 +109,14 @@
109
109
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
110
110
  },
111
111
  "dependencies": {
112
- "@intlayer/api": "8.8.0",
113
- "@intlayer/config": "8.8.0",
114
- "@intlayer/core": "8.8.0",
115
- "@intlayer/dictionaries-entry": "8.8.0",
116
- "@intlayer/remote-dictionaries-entry": "8.8.0",
117
- "@intlayer/types": "8.8.0",
118
- "@intlayer/unmerged-dictionaries-entry": "8.8.0",
119
- "chokidar": "3.6.0",
112
+ "@intlayer/api": "8.9.1",
113
+ "@intlayer/config": "8.9.1",
114
+ "@intlayer/core": "8.9.1",
115
+ "@intlayer/dictionaries-entry": "8.9.1",
116
+ "@intlayer/remote-dictionaries-entry": "8.9.1",
117
+ "@intlayer/types": "8.9.1",
118
+ "@intlayer/unmerged-dictionaries-entry": "8.9.1",
119
+ "chokidar": "5.0.0",
120
120
  "defu": "6.1.7",
121
121
  "fast-glob": "3.3.3",
122
122
  "recast": "^0.23.11",
@@ -132,7 +132,7 @@
132
132
  "tsdown": "0.21.10",
133
133
  "typescript": "6.0.3",
134
134
  "vitest": "4.1.5",
135
- "zod": "4.4.2"
135
+ "zod": "4.4.3"
136
136
  },
137
137
  "engines": {
138
138
  "node": ">=14.18"