vanilla-intlayer 9.0.0-canary.0 → 9.0.0-canary.2

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.
@@ -17,7 +17,7 @@ const require_client_installIntlayer = require('./installIntlayer.cjs');
17
17
  */
18
18
  const useDictionary = (dictionary, localeOrSelector) => {
19
19
  const client = require_client_installIntlayer.getIntlayerClient();
20
- const isSelector = typeof localeOrSelector === "object" && localeOrSelector !== null;
20
+ const isSelector = process.env["INTLAYER_DICTIONARY_SELECTOR"] !== "false" && typeof localeOrSelector === "object" && localeOrSelector !== null;
21
21
  const explicitLocale = isSelector ? localeOrSelector.locale : localeOrSelector;
22
22
  const read = (locale) => isSelector ? require_getDictionary.getDictionary(dictionary, {
23
23
  ...localeOrSelector,
@@ -1 +1 @@
1
- {"version":3,"file":"useDictionary.cjs","names":["getIntlayerClient","getDictionary"],"sources":["../../../src/client/useDictionary.ts"],"sourcesContent":["import type {\n Dictionary,\n DictionarySelector,\n DictionarySelectorForGroup,\n QualifiedDictionaryGroup,\n ResolveQualifiedDictionaryContent,\n} from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { getDictionary } from '../getDictionary';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\n\nexport type WithOnChange<T> = T & {\n /**\n * Subscribe to locale changes. The callback receives the fresh content\n * whenever the active locale changes. Returns the content object itself\n * for convenient one-liner patterns:\n *\n * ```ts\n * const content = useDictionary(myDict).onChange((c) => {\n * document.querySelector('p')!.textContent = String(c.greeting);\n * });\n * ```\n */\n onChange: (callback: (content: any) => void) => WithOnChange<T>;\n};\n\n/**\n * Get the content for a raw dictionary (or qualified dictionary group) and\n * optionally subscribe to locale changes via the chainable `.onChange()`\n * method — mirroring the API of `react-intlayer`.\n *\n * The second argument is either a locale or a selector object (`{ item }`,\n * `{ variant }`, `{ id, ...meta }`, optionally combined with `locale`).\n *\n * @param dictionary - The raw dictionary (or qualified group) object.\n * @param localeOrSelector - Optional locale or selector.\n * @returns The current content with an `.onChange()` method.\n */\nexport const useDictionary = <\n const T extends Dictionary | QualifiedDictionaryGroup,\n const A extends\n | LocalesValues\n | DictionarySelectorForGroup<T> = DeclaredLocales,\n>(\n dictionary: T,\n localeOrSelector?: A\n): WithOnChange<\n DeepTransformContent<\n ResolveQualifiedDictionaryContent<T, A>,\n ExtractSelectorLocale<A>\n >\n> => {\n const client = getIntlayerClient();\n\n const isSelector =\n typeof localeOrSelector === 'object' && localeOrSelector !== null;\n const explicitLocale = isSelector\n ? (localeOrSelector as DictionarySelector).locale\n : (localeOrSelector as LocalesValues | undefined);\n\n const read = (locale: LocalesValues | undefined) =>\n isSelector\n ? getDictionary(dictionary, {\n ...(localeOrSelector as DictionarySelector),\n locale,\n } as A)\n : getDictionary(dictionary, locale as A);\n\n const content = read(explicitLocale ?? client.locale) as WithOnChange<any>;\n\n // A selector can resolve to null/array; only objects carry `.onChange`.\n if (content != null && typeof content === 'object') {\n content.onChange = (callback) => {\n client.subscribe((newLocale) => {\n callback(read(explicitLocale ?? newLocale));\n });\n return content;\n };\n }\n\n return content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AA2CA,MAAa,iBAMX,YACA,qBAMG;CACH,MAAM,SAASA,kDAAmB;CAElC,MAAM,aACJ,OAAO,qBAAqB,YAAY,qBAAqB;CAC/D,MAAM,iBAAiB,aAClB,iBAAwC,SACxC;CAEL,MAAM,QAAQ,WACZ,aACIC,oCAAc,YAAY;EACxB,GAAI;EACJ;EACD,CAAM,GACPA,oCAAc,YAAY,OAAY;CAE5C,MAAM,UAAU,KAAK,kBAAkB,OAAO,OAAO;AAGrD,KAAI,WAAW,QAAQ,OAAO,YAAY,SACxC,SAAQ,YAAY,aAAa;AAC/B,SAAO,WAAW,cAAc;AAC9B,YAAS,KAAK,kBAAkB,UAAU,CAAC;IAC3C;AACF,SAAO;;AAIX,QAAO"}
1
+ {"version":3,"file":"useDictionary.cjs","names":["getIntlayerClient","getDictionary"],"sources":["../../../src/client/useDictionary.ts"],"sourcesContent":["import type {\n Dictionary,\n DictionarySelector,\n DictionarySelectorForGroup,\n QualifiedDictionaryGroup,\n ResolveQualifiedDictionaryContent,\n} from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { getDictionary } from '../getDictionary';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\n\nexport type WithOnChange<T> = T & {\n /**\n * Subscribe to locale changes. The callback receives the fresh content\n * whenever the active locale changes. Returns the content object itself\n * for convenient one-liner patterns:\n *\n * ```ts\n * const content = useDictionary(myDict).onChange((c) => {\n * document.querySelector('p')!.textContent = String(c.greeting);\n * });\n * ```\n */\n onChange: (callback: (content: any) => void) => WithOnChange<T>;\n};\n\n/**\n * Get the content for a raw dictionary (or qualified dictionary group) and\n * optionally subscribe to locale changes via the chainable `.onChange()`\n * method — mirroring the API of `react-intlayer`.\n *\n * The second argument is either a locale or a selector object (`{ item }`,\n * `{ variant }`, `{ id, ...meta }`, optionally combined with `locale`).\n *\n * @param dictionary - The raw dictionary (or qualified group) object.\n * @param localeOrSelector - Optional locale or selector.\n * @returns The current content with an `.onChange()` method.\n */\nexport const useDictionary = <\n const T extends Dictionary | QualifiedDictionaryGroup,\n const A extends\n | LocalesValues\n | DictionarySelectorForGroup<T> = DeclaredLocales,\n>(\n dictionary: T,\n localeOrSelector?: A\n): WithOnChange<\n DeepTransformContent<\n ResolveQualifiedDictionaryContent<T, A>,\n ExtractSelectorLocale<A>\n >\n> => {\n const client = getIntlayerClient();\n\n const isSelector =\n process.env['INTLAYER_DICTIONARY_SELECTOR'] !== 'false' &&\n typeof localeOrSelector === 'object' &&\n localeOrSelector !== null;\n const explicitLocale = isSelector\n ? (localeOrSelector as DictionarySelector).locale\n : (localeOrSelector as LocalesValues | undefined);\n\n const read = (locale: LocalesValues | undefined) =>\n isSelector\n ? getDictionary(dictionary, {\n ...(localeOrSelector as DictionarySelector),\n locale,\n } as A)\n : getDictionary(dictionary, locale as A);\n\n const content = read(explicitLocale ?? client.locale) as WithOnChange<any>;\n\n // A selector can resolve to null/array; only objects carry `.onChange`.\n if (content != null && typeof content === 'object') {\n content.onChange = (callback) => {\n client.subscribe((newLocale) => {\n callback(read(explicitLocale ?? newLocale));\n });\n return content;\n };\n }\n\n return content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AA2CA,MAAa,iBAMX,YACA,qBAMG;CACH,MAAM,SAASA,kDAAmB;CAElC,MAAM,aACJ,QAAQ,IAAI,oCAAoC,WAChD,OAAO,qBAAqB,YAC5B,qBAAqB;CACvB,MAAM,iBAAiB,aAClB,iBAAwC,SACxC;CAEL,MAAM,QAAQ,WACZ,aACIC,oCAAc,YAAY;EACxB,GAAI;EACJ;EACD,CAAM,GACPA,oCAAc,YAAY,OAAY;CAE5C,MAAM,UAAU,KAAK,kBAAkB,OAAO,OAAO;AAGrD,KAAI,WAAW,QAAQ,OAAO,YAAY,SACxC,SAAQ,YAAY,aAAa;AAC/B,SAAO,WAAW,cAAc;AAC9B,YAAS,KAAK,kBAAkB,UAAU,CAAC;IAC3C;AACF,SAAO;;AAIX,QAAO"}
@@ -51,7 +51,7 @@ const recursiveProxy = new Proxy(() => {}, {
51
51
  const useDictionaryDynamic = (dictionaryLoaders, key, localeOrSelector) => {
52
52
  const client = require_client_installIntlayer.getIntlayerClient();
53
53
  const defaultLocale = _intlayer_config_built.internationalization.defaultLocale;
54
- if ((0, _intlayer_core_dictionaryManipulator.isQualifiedDynamicLoaderMap)(dictionaryLoaders)) {
54
+ if (process.env["INTLAYER_DICTIONARY_SELECTOR"] !== "false" && (0, _intlayer_core_dictionaryManipulator.isQualifiedDynamicLoaderMap)(dictionaryLoaders)) {
55
55
  const loaderMap = dictionaryLoaders;
56
56
  const { locale: selectorLocale, selector } = (0, _intlayer_core_dictionaryManipulator.parseDictionarySelector)(localeOrSelector);
57
57
  const selectorId = (0, _intlayer_core_dictionaryManipulator.getDictionarySelectorCacheKey)(selector);
@@ -1 +1 @@
1
- {"version":3,"file":"useDictionaryDynamic.cjs","names":["getIntlayerClient","internationalization","getDictionary"],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport {\n getDictionarySelectorCacheKey,\n isQualifiedDynamicLoaderMap,\n parseDictionarySelector,\n type QualifiedDynamicLoaderMap,\n resolveQualifiedDynamicContentAsync,\n} from '@intlayer/core/dictionaryManipulator';\nimport type {\n Dictionary,\n DictionarySelector,\n} from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n DictionarySelectorForKey,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { getDictionary } from '../getDictionary';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\nimport type { WithOnChange } from './useDictionary';\n\n/** Simple in-memory cache shared across all calls in the same page. */\nconst cache = new Map<string, Dictionary>();\n\n/** Tracks in-flight loads to avoid duplicate fetches. */\nconst inflight = new Map<string, Promise<void>>();\n\n/** Resolved-content cache for qualified (collection/variant/meta) keys. */\nconst qualifiedCache = new Map<string, unknown>();\nconst qualifiedInflight = new Map<string, Promise<void>>();\n\nconst loadDictionary = <T extends Dictionary>(\n cacheKey: string,\n loader: () => Promise<T>\n): Promise<void> => {\n if (cache.has(cacheKey)) return Promise.resolve();\n if (inflight.has(cacheKey)) return inflight.get(cacheKey)!;\n\n const promise = loader().then((dictionary) => {\n cache.set(cacheKey, dictionary);\n inflight.delete(cacheKey);\n });\n\n inflight.set(cacheKey, promise);\n return promise;\n};\n\n/** Placeholder proxy — safe for any property access while loading. */\nconst recursiveProxy: any = new Proxy(() => {}, {\n get: (_t, prop) => {\n if (prop === Symbol.toPrimitive) return () => '';\n if (prop === 'toString') return () => '';\n if (prop === 'valueOf') return () => '';\n if (prop === 'then') return undefined; // not a Promise\n if (prop === 'onChange') return (_cb: any) => recursiveProxy;\n return recursiveProxy;\n },\n apply: () => recursiveProxy,\n});\n\n/**\n * Dynamically load and transform a dictionary (plain or qualified).\n *\n * For a qualified loader map (collection / variant / meta record, possibly\n * combined), only the chunk(s) the selector targets are loaded. For a plain\n * loader map, the locale chunk is loaded. The first call returns a placeholder\n * and triggers a background load; the client then notifies subscribers so the\n * render runs again with real content.\n *\n * @param dictionaryLoaders - Locale-keyed loader map, or a qualified loader map.\n * @param key - Dictionary key (used for cache namespacing).\n * @param localeOrSelector - Optional locale or selector.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<K> = LocalesValues,\n>(\n dictionaryLoaders:\n | StrictModeLocaleMap<() => Promise<T>>\n | QualifiedDynamicLoaderMap,\n key: K,\n localeOrSelector?: A\n): WithOnChange<DeepTransformContent<T['content']>> => {\n const client = getIntlayerClient();\n const defaultLocale = internationalization.defaultLocale;\n\n // --- Qualified loader map (collection / variant / meta record) ---\n if (isQualifiedDynamicLoaderMap(dictionaryLoaders)) {\n const loaderMap = dictionaryLoaders;\n const { locale: selectorLocale, selector } =\n parseDictionarySelector<LocalesValues>(localeOrSelector);\n const selectorId = getDictionarySelectorCacheKey(selector);\n\n const buildKey = (locale: string) =>\n `${String(key)}.${locale}.${selectorId}`;\n const resolveContent = (locale: LocalesValues) =>\n resolveQualifiedDynamicContentAsync({\n loaderMap,\n key: String(key),\n locale,\n selector,\n transform: (dictionary) => getDictionary(dictionary, locale),\n });\n\n const currentLocale = (selectorLocale ??\n client.locale ??\n defaultLocale) as LocalesValues;\n const cacheKey = buildKey(currentLocale);\n\n const attachOnChange = (content: any) => {\n if (content != null && typeof content === 'object') {\n content.onChange = (callback: (c: any) => void) => {\n client.subscribe((newLocale) => {\n const locale = (selectorLocale ?? newLocale) as LocalesValues;\n const newKey = buildKey(locale);\n\n if (qualifiedCache.has(newKey)) {\n callback(qualifiedCache.get(newKey));\n return;\n }\n\n resolveContent(locale).then((resolved) => {\n qualifiedCache.set(newKey, resolved);\n callback(resolved);\n });\n });\n return content;\n };\n }\n return content;\n };\n\n if (qualifiedCache.has(cacheKey)) {\n return attachOnChange(qualifiedCache.get(cacheKey)) as any;\n }\n\n if (!qualifiedInflight.has(cacheKey)) {\n const promise = resolveContent(currentLocale).then((resolved) => {\n qualifiedCache.set(cacheKey, resolved);\n qualifiedInflight.delete(cacheKey);\n client.notify();\n });\n qualifiedInflight.set(cacheKey, promise);\n }\n\n return recursiveProxy;\n }\n\n // --- Plain locale-keyed loader map ---\n const locale =\n typeof localeOrSelector === 'string'\n ? (localeOrSelector as LocalesValues)\n : undefined;\n const currentLocale = (locale ?? client.locale ?? defaultLocale) as A;\n\n const cacheKey = `${String(key)}.${currentLocale}`;\n const loader = (dictionaryLoaders as Record<string, () => Promise<T>>)[\n currentLocale as string\n ];\n\n // --- Cache hit: return real content synchronously ---\n const cached = cache.get(cacheKey);\n if (cached) {\n const content = getDictionary(cached, currentLocale) as WithOnChange<\n DeepTransformContent<T['content']>\n >;\n\n content.onChange = (callback) => {\n // Re-fire whenever content reloads (locale change → new cache entry).\n client.subscribe((newLocale) => {\n const newKey = `${String(key)}.${newLocale}`;\n const newLoader = (\n dictionaryLoaders as Record<string, () => Promise<T>>\n )[newLocale];\n\n if (!newLoader) return;\n\n loadDictionary(newKey, newLoader).then(() => {\n const dict = cache.get(newKey);\n if (dict) {\n callback(getDictionary(dict, newLocale as A) as any);\n }\n });\n });\n\n return content;\n };\n\n return content;\n }\n\n // --- Cache miss: kick off background load, then notify to re-render ---\n if (loader) {\n loadDictionary(cacheKey, loader).then(() => {\n client.notify();\n });\n }\n\n return recursiveProxy;\n};\n"],"mappings":";;;;;;;;;AAwBA,MAAM,wBAAQ,IAAI,KAAyB;;AAG3C,MAAM,2BAAW,IAAI,KAA4B;;AAGjD,MAAM,iCAAiB,IAAI,KAAsB;AACjD,MAAM,oCAAoB,IAAI,KAA4B;AAE1D,MAAM,kBACJ,UACA,WACkB;AAClB,KAAI,MAAM,IAAI,SAAS,CAAE,QAAO,QAAQ,SAAS;AACjD,KAAI,SAAS,IAAI,SAAS,CAAE,QAAO,SAAS,IAAI,SAAS;CAEzD,MAAM,UAAU,QAAQ,CAAC,MAAM,eAAe;AAC5C,QAAM,IAAI,UAAU,WAAW;AAC/B,WAAS,OAAO,SAAS;GACzB;AAEF,UAAS,IAAI,UAAU,QAAQ;AAC/B,QAAO;;;AAIT,MAAM,iBAAsB,IAAI,YAAY,IAAI;CAC9C,MAAM,IAAI,SAAS;AACjB,MAAI,SAAS,OAAO,YAAa,cAAa;AAC9C,MAAI,SAAS,WAAY,cAAa;AACtC,MAAI,SAAS,UAAW,cAAa;AACrC,MAAI,SAAS,OAAQ,QAAO;AAC5B,MAAI,SAAS,WAAY,SAAQ,QAAa;AAC9C,SAAO;;CAET,aAAa;CACd,CAAC;;;;;;;;;;;;;;AAeF,MAAa,wBAKX,mBAGA,KACA,qBACqD;CACrD,MAAM,SAASA,kDAAmB;CAClC,MAAM,gBAAgBC,4CAAqB;AAG3C,2EAAgC,kBAAkB,EAAE;EAClD,MAAM,YAAY;EAClB,MAAM,EAAE,QAAQ,gBAAgB,+EACS,iBAAiB;EAC1D,MAAM,qFAA2C,SAAS;EAE1D,MAAM,YAAY,WAChB,GAAG,OAAO,IAAI,CAAC,GAAG,OAAO,GAAG;EAC9B,MAAM,kBAAkB,yFACc;GAClC;GACA,KAAK,OAAO,IAAI;GAChB;GACA;GACA,YAAY,eAAeC,oCAAc,YAAY,OAAO;GAC7D,CAAC;EAEJ,MAAM,gBAAiB,kBACrB,OAAO,UACP;EACF,MAAM,WAAW,SAAS,cAAc;EAExC,MAAM,kBAAkB,YAAiB;AACvC,OAAI,WAAW,QAAQ,OAAO,YAAY,SACxC,SAAQ,YAAY,aAA+B;AACjD,WAAO,WAAW,cAAc;KAC9B,MAAM,SAAU,kBAAkB;KAClC,MAAM,SAAS,SAAS,OAAO;AAE/B,SAAI,eAAe,IAAI,OAAO,EAAE;AAC9B,eAAS,eAAe,IAAI,OAAO,CAAC;AACpC;;AAGF,oBAAe,OAAO,CAAC,MAAM,aAAa;AACxC,qBAAe,IAAI,QAAQ,SAAS;AACpC,eAAS,SAAS;OAClB;MACF;AACF,WAAO;;AAGX,UAAO;;AAGT,MAAI,eAAe,IAAI,SAAS,CAC9B,QAAO,eAAe,eAAe,IAAI,SAAS,CAAC;AAGrD,MAAI,CAAC,kBAAkB,IAAI,SAAS,EAAE;GACpC,MAAM,UAAU,eAAe,cAAc,CAAC,MAAM,aAAa;AAC/D,mBAAe,IAAI,UAAU,SAAS;AACtC,sBAAkB,OAAO,SAAS;AAClC,WAAO,QAAQ;KACf;AACF,qBAAkB,IAAI,UAAU,QAAQ;;AAG1C,SAAO;;CAQT,MAAM,iBAHJ,OAAO,qBAAqB,WACvB,mBACD,WAC2B,OAAO,UAAU;CAElD,MAAM,WAAW,GAAG,OAAO,IAAI,CAAC,GAAG;CACnC,MAAM,SAAU,kBACd;CAIF,MAAM,SAAS,MAAM,IAAI,SAAS;AAClC,KAAI,QAAQ;EACV,MAAM,UAAUA,oCAAc,QAAQ,cAAc;AAIpD,UAAQ,YAAY,aAAa;AAE/B,UAAO,WAAW,cAAc;IAC9B,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,GAAG;IACjC,MAAM,YACJ,kBACA;AAEF,QAAI,CAAC,UAAW;AAEhB,mBAAe,QAAQ,UAAU,CAAC,WAAW;KAC3C,MAAM,OAAO,MAAM,IAAI,OAAO;AAC9B,SAAI,KACF,UAASA,oCAAc,MAAM,UAAe,CAAQ;MAEtD;KACF;AAEF,UAAO;;AAGT,SAAO;;AAIT,KAAI,OACF,gBAAe,UAAU,OAAO,CAAC,WAAW;AAC1C,SAAO,QAAQ;GACf;AAGJ,QAAO"}
1
+ {"version":3,"file":"useDictionaryDynamic.cjs","names":["getIntlayerClient","internationalization","getDictionary"],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport {\n getDictionarySelectorCacheKey,\n isQualifiedDynamicLoaderMap,\n parseDictionarySelector,\n type QualifiedDynamicLoaderMap,\n resolveQualifiedDynamicContentAsync,\n} from '@intlayer/core/dictionaryManipulator';\nimport type {\n Dictionary,\n DictionarySelector,\n} from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n DictionarySelectorForKey,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { getDictionary } from '../getDictionary';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\nimport type { WithOnChange } from './useDictionary';\n\n/** Simple in-memory cache shared across all calls in the same page. */\nconst cache = new Map<string, Dictionary>();\n\n/** Tracks in-flight loads to avoid duplicate fetches. */\nconst inflight = new Map<string, Promise<void>>();\n\n/** Resolved-content cache for qualified (collection/variant/meta) keys. */\nconst qualifiedCache = new Map<string, unknown>();\nconst qualifiedInflight = new Map<string, Promise<void>>();\n\nconst loadDictionary = <T extends Dictionary>(\n cacheKey: string,\n loader: () => Promise<T>\n): Promise<void> => {\n if (cache.has(cacheKey)) return Promise.resolve();\n if (inflight.has(cacheKey)) return inflight.get(cacheKey)!;\n\n const promise = loader().then((dictionary) => {\n cache.set(cacheKey, dictionary);\n inflight.delete(cacheKey);\n });\n\n inflight.set(cacheKey, promise);\n return promise;\n};\n\n/** Placeholder proxy — safe for any property access while loading. */\nconst recursiveProxy: any = new Proxy(() => {}, {\n get: (_t, prop) => {\n if (prop === Symbol.toPrimitive) return () => '';\n if (prop === 'toString') return () => '';\n if (prop === 'valueOf') return () => '';\n if (prop === 'then') return undefined; // not a Promise\n if (prop === 'onChange') return (_cb: any) => recursiveProxy;\n return recursiveProxy;\n },\n apply: () => recursiveProxy,\n});\n\n/**\n * Dynamically load and transform a dictionary (plain or qualified).\n *\n * For a qualified loader map (collection / variant / meta record, possibly\n * combined), only the chunk(s) the selector targets are loaded. For a plain\n * loader map, the locale chunk is loaded. The first call returns a placeholder\n * and triggers a background load; the client then notifies subscribers so the\n * render runs again with real content.\n *\n * @param dictionaryLoaders - Locale-keyed loader map, or a qualified loader map.\n * @param key - Dictionary key (used for cache namespacing).\n * @param localeOrSelector - Optional locale or selector.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<K> = LocalesValues,\n>(\n dictionaryLoaders:\n | StrictModeLocaleMap<() => Promise<T>>\n | QualifiedDynamicLoaderMap,\n key: K,\n localeOrSelector?: A\n): WithOnChange<DeepTransformContent<T['content']>> => {\n const client = getIntlayerClient();\n const defaultLocale = internationalization.defaultLocale;\n\n // --- Qualified loader map (collection / variant / meta record) ---\n if (\n process.env['INTLAYER_DICTIONARY_SELECTOR'] !== 'false' &&\n isQualifiedDynamicLoaderMap(dictionaryLoaders)\n ) {\n const loaderMap = dictionaryLoaders;\n const { locale: selectorLocale, selector } =\n parseDictionarySelector<LocalesValues>(localeOrSelector);\n const selectorId = getDictionarySelectorCacheKey(selector);\n\n const buildKey = (locale: string) =>\n `${String(key)}.${locale}.${selectorId}`;\n const resolveContent = (locale: LocalesValues) =>\n resolveQualifiedDynamicContentAsync({\n loaderMap,\n key: String(key),\n locale,\n selector,\n transform: (dictionary) => getDictionary(dictionary, locale),\n });\n\n const currentLocale = (selectorLocale ??\n client.locale ??\n defaultLocale) as LocalesValues;\n const cacheKey = buildKey(currentLocale);\n\n const attachOnChange = (content: any) => {\n if (content != null && typeof content === 'object') {\n content.onChange = (callback: (c: any) => void) => {\n client.subscribe((newLocale) => {\n const locale = (selectorLocale ?? newLocale) as LocalesValues;\n const newKey = buildKey(locale);\n\n if (qualifiedCache.has(newKey)) {\n callback(qualifiedCache.get(newKey));\n return;\n }\n\n resolveContent(locale).then((resolved) => {\n qualifiedCache.set(newKey, resolved);\n callback(resolved);\n });\n });\n return content;\n };\n }\n return content;\n };\n\n if (qualifiedCache.has(cacheKey)) {\n return attachOnChange(qualifiedCache.get(cacheKey)) as any;\n }\n\n if (!qualifiedInflight.has(cacheKey)) {\n const promise = resolveContent(currentLocale).then((resolved) => {\n qualifiedCache.set(cacheKey, resolved);\n qualifiedInflight.delete(cacheKey);\n client.notify();\n });\n qualifiedInflight.set(cacheKey, promise);\n }\n\n return recursiveProxy;\n }\n\n // --- Plain locale-keyed loader map ---\n const locale =\n typeof localeOrSelector === 'string'\n ? (localeOrSelector as LocalesValues)\n : undefined;\n const currentLocale = (locale ?? client.locale ?? defaultLocale) as A;\n\n const cacheKey = `${String(key)}.${currentLocale}`;\n const loader = (dictionaryLoaders as Record<string, () => Promise<T>>)[\n currentLocale as string\n ];\n\n // --- Cache hit: return real content synchronously ---\n const cached = cache.get(cacheKey);\n if (cached) {\n const content = getDictionary(cached, currentLocale) as WithOnChange<\n DeepTransformContent<T['content']>\n >;\n\n content.onChange = (callback) => {\n // Re-fire whenever content reloads (locale change → new cache entry).\n client.subscribe((newLocale) => {\n const newKey = `${String(key)}.${newLocale}`;\n const newLoader = (\n dictionaryLoaders as Record<string, () => Promise<T>>\n )[newLocale];\n\n if (!newLoader) return;\n\n loadDictionary(newKey, newLoader).then(() => {\n const dict = cache.get(newKey);\n if (dict) {\n callback(getDictionary(dict, newLocale as A) as any);\n }\n });\n });\n\n return content;\n };\n\n return content;\n }\n\n // --- Cache miss: kick off background load, then notify to re-render ---\n if (loader) {\n loadDictionary(cacheKey, loader).then(() => {\n client.notify();\n });\n }\n\n return recursiveProxy;\n};\n"],"mappings":"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"}
@@ -33,7 +33,7 @@ const require_client_installIntlayer = require('./installIntlayer.cjs');
33
33
  */
34
34
  const useIntlayer = (key, localeOrSelector) => {
35
35
  const client = require_client_installIntlayer.getIntlayerClient();
36
- const isSelector = typeof localeOrSelector === "object" && localeOrSelector !== null;
36
+ const isSelector = process.env["INTLAYER_DICTIONARY_SELECTOR"] !== "false" && typeof localeOrSelector === "object" && localeOrSelector !== null;
37
37
  const explicitLocale = isSelector ? localeOrSelector.locale : localeOrSelector;
38
38
  const read = (locale) => isSelector ? require_getIntlayer.getIntlayer(key, {
39
39
  ...localeOrSelector,
@@ -1 +1 @@
1
- {"version":3,"file":"useIntlayer.cjs","names":["getIntlayerClient","getIntlayer"],"sources":["../../../src/client/useIntlayer.ts"],"sourcesContent":["import type { DictionarySelector } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryResult,\n DictionarySelectorForKey,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { getIntlayer } from '../getIntlayer';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\nimport type { WithOnChange } from './useDictionary';\n\n/**\n * Get the translated content for the given key and optionally subscribe to\n * locale changes via the chainable `.onChange()` method — mirroring the API\n * of `react-intlayer`'s `useIntlayer`.\n *\n * The second argument is either a locale or a selector object:\n * - `{ item: 2 }` — collection item (omit `item` to get every item as array)\n * - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)\n * - `{ id: 'prod_abc', ...metaFields }` — meta record\n * - `locale` composes with any selector and overrides the current locale\n *\n * The function returns the current content **directly** (same shape as\n * `getIntlayer(key)`), plus the `.onChange()` helper.\n *\n * @param key - Dictionary key registered in your intlayer content files.\n * @param localeOrSelector - Optional locale or selector.\n * @returns The current translated content with an `.onChange()` method.\n *\n * @example\n * ```ts\n * import { installIntlayer, useIntlayer } from 'vanilla-intlayer';\n *\n * installIntlayer();\n *\n * const content = useIntlayer('homepage');\n * const faq2 = useIntlayer('faq', { item: 2 });\n * ```\n */\nexport const useIntlayer = <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<T> = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A\n): WithOnChange<\n DeepTransformContent<DictionaryRegistryResult<T, A>, ExtractSelectorLocale<A>>\n> => {\n const client = getIntlayerClient();\n\n const isSelector =\n typeof localeOrSelector === 'object' && localeOrSelector !== null;\n const explicitLocale = isSelector\n ? (localeOrSelector as DictionarySelector).locale\n : (localeOrSelector as LocalesValues | undefined);\n\n const read = (locale: LocalesValues | undefined) =>\n isSelector\n ? getIntlayer(key, {\n ...(localeOrSelector as DictionarySelector),\n locale,\n } as A)\n : getIntlayer(key, locale as A);\n\n const content = read(explicitLocale ?? client.locale) as WithOnChange<any>;\n\n // A selector can resolve to null/array; only objects carry `.onChange`.\n if (content != null && typeof content === 'object') {\n content.onChange = (callback) => {\n client.subscribe((newLocale) => {\n callback(read(explicitLocale ?? newLocale));\n });\n return content;\n };\n }\n\n return content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,MAAa,eAIX,KACA,qBAGG;CACH,MAAM,SAASA,kDAAmB;CAElC,MAAM,aACJ,OAAO,qBAAqB,YAAY,qBAAqB;CAC/D,MAAM,iBAAiB,aAClB,iBAAwC,SACxC;CAEL,MAAM,QAAQ,WACZ,aACIC,gCAAY,KAAK;EACf,GAAI;EACJ;EACD,CAAM,GACPA,gCAAY,KAAK,OAAY;CAEnC,MAAM,UAAU,KAAK,kBAAkB,OAAO,OAAO;AAGrD,KAAI,WAAW,QAAQ,OAAO,YAAY,SACxC,SAAQ,YAAY,aAAa;AAC/B,SAAO,WAAW,cAAc;AAC9B,YAAS,KAAK,kBAAkB,UAAU,CAAC;IAC3C;AACF,SAAO;;AAIX,QAAO"}
1
+ {"version":3,"file":"useIntlayer.cjs","names":["getIntlayerClient","getIntlayer"],"sources":["../../../src/client/useIntlayer.ts"],"sourcesContent":["import type { DictionarySelector } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryResult,\n DictionarySelectorForKey,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { getIntlayer } from '../getIntlayer';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\nimport type { WithOnChange } from './useDictionary';\n\n/**\n * Get the translated content for the given key and optionally subscribe to\n * locale changes via the chainable `.onChange()` method — mirroring the API\n * of `react-intlayer`'s `useIntlayer`.\n *\n * The second argument is either a locale or a selector object:\n * - `{ item: 2 }` — collection item (omit `item` to get every item as array)\n * - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)\n * - `{ id: 'prod_abc', ...metaFields }` — meta record\n * - `locale` composes with any selector and overrides the current locale\n *\n * The function returns the current content **directly** (same shape as\n * `getIntlayer(key)`), plus the `.onChange()` helper.\n *\n * @param key - Dictionary key registered in your intlayer content files.\n * @param localeOrSelector - Optional locale or selector.\n * @returns The current translated content with an `.onChange()` method.\n *\n * @example\n * ```ts\n * import { installIntlayer, useIntlayer } from 'vanilla-intlayer';\n *\n * installIntlayer();\n *\n * const content = useIntlayer('homepage');\n * const faq2 = useIntlayer('faq', { item: 2 });\n * ```\n */\nexport const useIntlayer = <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<T> = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A\n): WithOnChange<\n DeepTransformContent<DictionaryRegistryResult<T, A>, ExtractSelectorLocale<A>>\n> => {\n const client = getIntlayerClient();\n\n const isSelector =\n process.env['INTLAYER_DICTIONARY_SELECTOR'] !== 'false' &&\n typeof localeOrSelector === 'object' &&\n localeOrSelector !== null;\n const explicitLocale = isSelector\n ? (localeOrSelector as DictionarySelector).locale\n : (localeOrSelector as LocalesValues | undefined);\n\n const read = (locale: LocalesValues | undefined) =>\n isSelector\n ? getIntlayer(key, {\n ...(localeOrSelector as DictionarySelector),\n locale,\n } as A)\n : getIntlayer(key, locale as A);\n\n const content = read(explicitLocale ?? client.locale) as WithOnChange<any>;\n\n // A selector can resolve to null/array; only objects carry `.onChange`.\n if (content != null && typeof content === 'object') {\n content.onChange = (callback) => {\n client.subscribe((newLocale) => {\n callback(read(explicitLocale ?? newLocale));\n });\n return content;\n };\n }\n\n return content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,MAAa,eAIX,KACA,qBAGG;CACH,MAAM,SAASA,kDAAmB;CAElC,MAAM,aACJ,QAAQ,IAAI,oCAAoC,WAChD,OAAO,qBAAqB,YAC5B,qBAAqB;CACvB,MAAM,iBAAiB,aAClB,iBAAwC,SACxC;CAEL,MAAM,QAAQ,WACZ,aACIC,gCAAY,KAAK;EACf,GAAI;EACJ;EACD,CAAM,GACPA,gCAAY,KAAK,OAAY;CAEnC,MAAM,UAAU,KAAK,kBAAkB,OAAO,OAAO;AAGrD,KAAI,WAAW,QAAQ,OAAO,YAAY,SACxC,SAAQ,YAAY,aAAa;AAC/B,SAAO,WAAW,cAAc;AAC9B,YAAS,KAAK,kBAAkB,UAAU,CAAC;IAC3C;AACF,SAAO;;AAIX,QAAO"}
@@ -16,7 +16,7 @@ import { getIntlayerClient } from "./installIntlayer.mjs";
16
16
  */
17
17
  const useDictionary = (dictionary, localeOrSelector) => {
18
18
  const client = getIntlayerClient();
19
- const isSelector = typeof localeOrSelector === "object" && localeOrSelector !== null;
19
+ const isSelector = process.env["INTLAYER_DICTIONARY_SELECTOR"] !== "false" && typeof localeOrSelector === "object" && localeOrSelector !== null;
20
20
  const explicitLocale = isSelector ? localeOrSelector.locale : localeOrSelector;
21
21
  const read = (locale) => isSelector ? getDictionary(dictionary, {
22
22
  ...localeOrSelector,
@@ -1 +1 @@
1
- {"version":3,"file":"useDictionary.mjs","names":[],"sources":["../../../src/client/useDictionary.ts"],"sourcesContent":["import type {\n Dictionary,\n DictionarySelector,\n DictionarySelectorForGroup,\n QualifiedDictionaryGroup,\n ResolveQualifiedDictionaryContent,\n} from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { getDictionary } from '../getDictionary';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\n\nexport type WithOnChange<T> = T & {\n /**\n * Subscribe to locale changes. The callback receives the fresh content\n * whenever the active locale changes. Returns the content object itself\n * for convenient one-liner patterns:\n *\n * ```ts\n * const content = useDictionary(myDict).onChange((c) => {\n * document.querySelector('p')!.textContent = String(c.greeting);\n * });\n * ```\n */\n onChange: (callback: (content: any) => void) => WithOnChange<T>;\n};\n\n/**\n * Get the content for a raw dictionary (or qualified dictionary group) and\n * optionally subscribe to locale changes via the chainable `.onChange()`\n * method — mirroring the API of `react-intlayer`.\n *\n * The second argument is either a locale or a selector object (`{ item }`,\n * `{ variant }`, `{ id, ...meta }`, optionally combined with `locale`).\n *\n * @param dictionary - The raw dictionary (or qualified group) object.\n * @param localeOrSelector - Optional locale or selector.\n * @returns The current content with an `.onChange()` method.\n */\nexport const useDictionary = <\n const T extends Dictionary | QualifiedDictionaryGroup,\n const A extends\n | LocalesValues\n | DictionarySelectorForGroup<T> = DeclaredLocales,\n>(\n dictionary: T,\n localeOrSelector?: A\n): WithOnChange<\n DeepTransformContent<\n ResolveQualifiedDictionaryContent<T, A>,\n ExtractSelectorLocale<A>\n >\n> => {\n const client = getIntlayerClient();\n\n const isSelector =\n typeof localeOrSelector === 'object' && localeOrSelector !== null;\n const explicitLocale = isSelector\n ? (localeOrSelector as DictionarySelector).locale\n : (localeOrSelector as LocalesValues | undefined);\n\n const read = (locale: LocalesValues | undefined) =>\n isSelector\n ? getDictionary(dictionary, {\n ...(localeOrSelector as DictionarySelector),\n locale,\n } as A)\n : getDictionary(dictionary, locale as A);\n\n const content = read(explicitLocale ?? client.locale) as WithOnChange<any>;\n\n // A selector can resolve to null/array; only objects carry `.onChange`.\n if (content != null && typeof content === 'object') {\n content.onChange = (callback) => {\n client.subscribe((newLocale) => {\n callback(read(explicitLocale ?? newLocale));\n });\n return content;\n };\n }\n\n return content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AA2CA,MAAa,iBAMX,YACA,qBAMG;CACH,MAAM,SAAS,mBAAmB;CAElC,MAAM,aACJ,OAAO,qBAAqB,YAAY,qBAAqB;CAC/D,MAAM,iBAAiB,aAClB,iBAAwC,SACxC;CAEL,MAAM,QAAQ,WACZ,aACI,cAAc,YAAY;EACxB,GAAI;EACJ;EACD,CAAM,GACP,cAAc,YAAY,OAAY;CAE5C,MAAM,UAAU,KAAK,kBAAkB,OAAO,OAAO;AAGrD,KAAI,WAAW,QAAQ,OAAO,YAAY,SACxC,SAAQ,YAAY,aAAa;AAC/B,SAAO,WAAW,cAAc;AAC9B,YAAS,KAAK,kBAAkB,UAAU,CAAC;IAC3C;AACF,SAAO;;AAIX,QAAO"}
1
+ {"version":3,"file":"useDictionary.mjs","names":[],"sources":["../../../src/client/useDictionary.ts"],"sourcesContent":["import type {\n Dictionary,\n DictionarySelector,\n DictionarySelectorForGroup,\n QualifiedDictionaryGroup,\n ResolveQualifiedDictionaryContent,\n} from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { getDictionary } from '../getDictionary';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\n\nexport type WithOnChange<T> = T & {\n /**\n * Subscribe to locale changes. The callback receives the fresh content\n * whenever the active locale changes. Returns the content object itself\n * for convenient one-liner patterns:\n *\n * ```ts\n * const content = useDictionary(myDict).onChange((c) => {\n * document.querySelector('p')!.textContent = String(c.greeting);\n * });\n * ```\n */\n onChange: (callback: (content: any) => void) => WithOnChange<T>;\n};\n\n/**\n * Get the content for a raw dictionary (or qualified dictionary group) and\n * optionally subscribe to locale changes via the chainable `.onChange()`\n * method — mirroring the API of `react-intlayer`.\n *\n * The second argument is either a locale or a selector object (`{ item }`,\n * `{ variant }`, `{ id, ...meta }`, optionally combined with `locale`).\n *\n * @param dictionary - The raw dictionary (or qualified group) object.\n * @param localeOrSelector - Optional locale or selector.\n * @returns The current content with an `.onChange()` method.\n */\nexport const useDictionary = <\n const T extends Dictionary | QualifiedDictionaryGroup,\n const A extends\n | LocalesValues\n | DictionarySelectorForGroup<T> = DeclaredLocales,\n>(\n dictionary: T,\n localeOrSelector?: A\n): WithOnChange<\n DeepTransformContent<\n ResolveQualifiedDictionaryContent<T, A>,\n ExtractSelectorLocale<A>\n >\n> => {\n const client = getIntlayerClient();\n\n const isSelector =\n process.env['INTLAYER_DICTIONARY_SELECTOR'] !== 'false' &&\n typeof localeOrSelector === 'object' &&\n localeOrSelector !== null;\n const explicitLocale = isSelector\n ? (localeOrSelector as DictionarySelector).locale\n : (localeOrSelector as LocalesValues | undefined);\n\n const read = (locale: LocalesValues | undefined) =>\n isSelector\n ? getDictionary(dictionary, {\n ...(localeOrSelector as DictionarySelector),\n locale,\n } as A)\n : getDictionary(dictionary, locale as A);\n\n const content = read(explicitLocale ?? client.locale) as WithOnChange<any>;\n\n // A selector can resolve to null/array; only objects carry `.onChange`.\n if (content != null && typeof content === 'object') {\n content.onChange = (callback) => {\n client.subscribe((newLocale) => {\n callback(read(explicitLocale ?? newLocale));\n });\n return content;\n };\n }\n\n return content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AA2CA,MAAa,iBAMX,YACA,qBAMG;CACH,MAAM,SAAS,mBAAmB;CAElC,MAAM,aACJ,QAAQ,IAAI,oCAAoC,WAChD,OAAO,qBAAqB,YAC5B,qBAAqB;CACvB,MAAM,iBAAiB,aAClB,iBAAwC,SACxC;CAEL,MAAM,QAAQ,WACZ,aACI,cAAc,YAAY;EACxB,GAAI;EACJ;EACD,CAAM,GACP,cAAc,YAAY,OAAY;CAE5C,MAAM,UAAU,KAAK,kBAAkB,OAAO,OAAO;AAGrD,KAAI,WAAW,QAAQ,OAAO,YAAY,SACxC,SAAQ,YAAY,aAAa;AAC/B,SAAO,WAAW,cAAc;AAC9B,YAAS,KAAK,kBAAkB,UAAU,CAAC;IAC3C;AACF,SAAO;;AAIX,QAAO"}
@@ -49,7 +49,7 @@ const recursiveProxy = new Proxy(() => {}, {
49
49
  const useDictionaryDynamic = (dictionaryLoaders, key, localeOrSelector) => {
50
50
  const client = getIntlayerClient();
51
51
  const defaultLocale = internationalization.defaultLocale;
52
- if (isQualifiedDynamicLoaderMap(dictionaryLoaders)) {
52
+ if (process.env["INTLAYER_DICTIONARY_SELECTOR"] !== "false" && isQualifiedDynamicLoaderMap(dictionaryLoaders)) {
53
53
  const loaderMap = dictionaryLoaders;
54
54
  const { locale: selectorLocale, selector } = parseDictionarySelector(localeOrSelector);
55
55
  const selectorId = getDictionarySelectorCacheKey(selector);
@@ -1 +1 @@
1
- {"version":3,"file":"useDictionaryDynamic.mjs","names":[],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport {\n getDictionarySelectorCacheKey,\n isQualifiedDynamicLoaderMap,\n parseDictionarySelector,\n type QualifiedDynamicLoaderMap,\n resolveQualifiedDynamicContentAsync,\n} from '@intlayer/core/dictionaryManipulator';\nimport type {\n Dictionary,\n DictionarySelector,\n} from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n DictionarySelectorForKey,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { getDictionary } from '../getDictionary';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\nimport type { WithOnChange } from './useDictionary';\n\n/** Simple in-memory cache shared across all calls in the same page. */\nconst cache = new Map<string, Dictionary>();\n\n/** Tracks in-flight loads to avoid duplicate fetches. */\nconst inflight = new Map<string, Promise<void>>();\n\n/** Resolved-content cache for qualified (collection/variant/meta) keys. */\nconst qualifiedCache = new Map<string, unknown>();\nconst qualifiedInflight = new Map<string, Promise<void>>();\n\nconst loadDictionary = <T extends Dictionary>(\n cacheKey: string,\n loader: () => Promise<T>\n): Promise<void> => {\n if (cache.has(cacheKey)) return Promise.resolve();\n if (inflight.has(cacheKey)) return inflight.get(cacheKey)!;\n\n const promise = loader().then((dictionary) => {\n cache.set(cacheKey, dictionary);\n inflight.delete(cacheKey);\n });\n\n inflight.set(cacheKey, promise);\n return promise;\n};\n\n/** Placeholder proxy — safe for any property access while loading. */\nconst recursiveProxy: any = new Proxy(() => {}, {\n get: (_t, prop) => {\n if (prop === Symbol.toPrimitive) return () => '';\n if (prop === 'toString') return () => '';\n if (prop === 'valueOf') return () => '';\n if (prop === 'then') return undefined; // not a Promise\n if (prop === 'onChange') return (_cb: any) => recursiveProxy;\n return recursiveProxy;\n },\n apply: () => recursiveProxy,\n});\n\n/**\n * Dynamically load and transform a dictionary (plain or qualified).\n *\n * For a qualified loader map (collection / variant / meta record, possibly\n * combined), only the chunk(s) the selector targets are loaded. For a plain\n * loader map, the locale chunk is loaded. The first call returns a placeholder\n * and triggers a background load; the client then notifies subscribers so the\n * render runs again with real content.\n *\n * @param dictionaryLoaders - Locale-keyed loader map, or a qualified loader map.\n * @param key - Dictionary key (used for cache namespacing).\n * @param localeOrSelector - Optional locale or selector.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<K> = LocalesValues,\n>(\n dictionaryLoaders:\n | StrictModeLocaleMap<() => Promise<T>>\n | QualifiedDynamicLoaderMap,\n key: K,\n localeOrSelector?: A\n): WithOnChange<DeepTransformContent<T['content']>> => {\n const client = getIntlayerClient();\n const defaultLocale = internationalization.defaultLocale;\n\n // --- Qualified loader map (collection / variant / meta record) ---\n if (isQualifiedDynamicLoaderMap(dictionaryLoaders)) {\n const loaderMap = dictionaryLoaders;\n const { locale: selectorLocale, selector } =\n parseDictionarySelector<LocalesValues>(localeOrSelector);\n const selectorId = getDictionarySelectorCacheKey(selector);\n\n const buildKey = (locale: string) =>\n `${String(key)}.${locale}.${selectorId}`;\n const resolveContent = (locale: LocalesValues) =>\n resolveQualifiedDynamicContentAsync({\n loaderMap,\n key: String(key),\n locale,\n selector,\n transform: (dictionary) => getDictionary(dictionary, locale),\n });\n\n const currentLocale = (selectorLocale ??\n client.locale ??\n defaultLocale) as LocalesValues;\n const cacheKey = buildKey(currentLocale);\n\n const attachOnChange = (content: any) => {\n if (content != null && typeof content === 'object') {\n content.onChange = (callback: (c: any) => void) => {\n client.subscribe((newLocale) => {\n const locale = (selectorLocale ?? newLocale) as LocalesValues;\n const newKey = buildKey(locale);\n\n if (qualifiedCache.has(newKey)) {\n callback(qualifiedCache.get(newKey));\n return;\n }\n\n resolveContent(locale).then((resolved) => {\n qualifiedCache.set(newKey, resolved);\n callback(resolved);\n });\n });\n return content;\n };\n }\n return content;\n };\n\n if (qualifiedCache.has(cacheKey)) {\n return attachOnChange(qualifiedCache.get(cacheKey)) as any;\n }\n\n if (!qualifiedInflight.has(cacheKey)) {\n const promise = resolveContent(currentLocale).then((resolved) => {\n qualifiedCache.set(cacheKey, resolved);\n qualifiedInflight.delete(cacheKey);\n client.notify();\n });\n qualifiedInflight.set(cacheKey, promise);\n }\n\n return recursiveProxy;\n }\n\n // --- Plain locale-keyed loader map ---\n const locale =\n typeof localeOrSelector === 'string'\n ? (localeOrSelector as LocalesValues)\n : undefined;\n const currentLocale = (locale ?? client.locale ?? defaultLocale) as A;\n\n const cacheKey = `${String(key)}.${currentLocale}`;\n const loader = (dictionaryLoaders as Record<string, () => Promise<T>>)[\n currentLocale as string\n ];\n\n // --- Cache hit: return real content synchronously ---\n const cached = cache.get(cacheKey);\n if (cached) {\n const content = getDictionary(cached, currentLocale) as WithOnChange<\n DeepTransformContent<T['content']>\n >;\n\n content.onChange = (callback) => {\n // Re-fire whenever content reloads (locale change → new cache entry).\n client.subscribe((newLocale) => {\n const newKey = `${String(key)}.${newLocale}`;\n const newLoader = (\n dictionaryLoaders as Record<string, () => Promise<T>>\n )[newLocale];\n\n if (!newLoader) return;\n\n loadDictionary(newKey, newLoader).then(() => {\n const dict = cache.get(newKey);\n if (dict) {\n callback(getDictionary(dict, newLocale as A) as any);\n }\n });\n });\n\n return content;\n };\n\n return content;\n }\n\n // --- Cache miss: kick off background load, then notify to re-render ---\n if (loader) {\n loadDictionary(cacheKey, loader).then(() => {\n client.notify();\n });\n }\n\n return recursiveProxy;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"useDictionaryDynamic.mjs","names":[],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport {\n getDictionarySelectorCacheKey,\n isQualifiedDynamicLoaderMap,\n parseDictionarySelector,\n type QualifiedDynamicLoaderMap,\n resolveQualifiedDynamicContentAsync,\n} from '@intlayer/core/dictionaryManipulator';\nimport type {\n Dictionary,\n DictionarySelector,\n} from '@intlayer/types/dictionary';\nimport type {\n DictionaryKeys,\n DictionarySelectorForKey,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { getDictionary } from '../getDictionary';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\nimport type { WithOnChange } from './useDictionary';\n\n/** Simple in-memory cache shared across all calls in the same page. */\nconst cache = new Map<string, Dictionary>();\n\n/** Tracks in-flight loads to avoid duplicate fetches. */\nconst inflight = new Map<string, Promise<void>>();\n\n/** Resolved-content cache for qualified (collection/variant/meta) keys. */\nconst qualifiedCache = new Map<string, unknown>();\nconst qualifiedInflight = new Map<string, Promise<void>>();\n\nconst loadDictionary = <T extends Dictionary>(\n cacheKey: string,\n loader: () => Promise<T>\n): Promise<void> => {\n if (cache.has(cacheKey)) return Promise.resolve();\n if (inflight.has(cacheKey)) return inflight.get(cacheKey)!;\n\n const promise = loader().then((dictionary) => {\n cache.set(cacheKey, dictionary);\n inflight.delete(cacheKey);\n });\n\n inflight.set(cacheKey, promise);\n return promise;\n};\n\n/** Placeholder proxy — safe for any property access while loading. */\nconst recursiveProxy: any = new Proxy(() => {}, {\n get: (_t, prop) => {\n if (prop === Symbol.toPrimitive) return () => '';\n if (prop === 'toString') return () => '';\n if (prop === 'valueOf') return () => '';\n if (prop === 'then') return undefined; // not a Promise\n if (prop === 'onChange') return (_cb: any) => recursiveProxy;\n return recursiveProxy;\n },\n apply: () => recursiveProxy,\n});\n\n/**\n * Dynamically load and transform a dictionary (plain or qualified).\n *\n * For a qualified loader map (collection / variant / meta record, possibly\n * combined), only the chunk(s) the selector targets are loaded. For a plain\n * loader map, the locale chunk is loaded. The first call returns a placeholder\n * and triggers a background load; the client then notifies subscribers so the\n * render runs again with real content.\n *\n * @param dictionaryLoaders - Locale-keyed loader map, or a qualified loader map.\n * @param key - Dictionary key (used for cache namespacing).\n * @param localeOrSelector - Optional locale or selector.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<K> = LocalesValues,\n>(\n dictionaryLoaders:\n | StrictModeLocaleMap<() => Promise<T>>\n | QualifiedDynamicLoaderMap,\n key: K,\n localeOrSelector?: A\n): WithOnChange<DeepTransformContent<T['content']>> => {\n const client = getIntlayerClient();\n const defaultLocale = internationalization.defaultLocale;\n\n // --- Qualified loader map (collection / variant / meta record) ---\n if (\n process.env['INTLAYER_DICTIONARY_SELECTOR'] !== 'false' &&\n isQualifiedDynamicLoaderMap(dictionaryLoaders)\n ) {\n const loaderMap = dictionaryLoaders;\n const { locale: selectorLocale, selector } =\n parseDictionarySelector<LocalesValues>(localeOrSelector);\n const selectorId = getDictionarySelectorCacheKey(selector);\n\n const buildKey = (locale: string) =>\n `${String(key)}.${locale}.${selectorId}`;\n const resolveContent = (locale: LocalesValues) =>\n resolveQualifiedDynamicContentAsync({\n loaderMap,\n key: String(key),\n locale,\n selector,\n transform: (dictionary) => getDictionary(dictionary, locale),\n });\n\n const currentLocale = (selectorLocale ??\n client.locale ??\n defaultLocale) as LocalesValues;\n const cacheKey = buildKey(currentLocale);\n\n const attachOnChange = (content: any) => {\n if (content != null && typeof content === 'object') {\n content.onChange = (callback: (c: any) => void) => {\n client.subscribe((newLocale) => {\n const locale = (selectorLocale ?? newLocale) as LocalesValues;\n const newKey = buildKey(locale);\n\n if (qualifiedCache.has(newKey)) {\n callback(qualifiedCache.get(newKey));\n return;\n }\n\n resolveContent(locale).then((resolved) => {\n qualifiedCache.set(newKey, resolved);\n callback(resolved);\n });\n });\n return content;\n };\n }\n return content;\n };\n\n if (qualifiedCache.has(cacheKey)) {\n return attachOnChange(qualifiedCache.get(cacheKey)) as any;\n }\n\n if (!qualifiedInflight.has(cacheKey)) {\n const promise = resolveContent(currentLocale).then((resolved) => {\n qualifiedCache.set(cacheKey, resolved);\n qualifiedInflight.delete(cacheKey);\n client.notify();\n });\n qualifiedInflight.set(cacheKey, promise);\n }\n\n return recursiveProxy;\n }\n\n // --- Plain locale-keyed loader map ---\n const locale =\n typeof localeOrSelector === 'string'\n ? (localeOrSelector as LocalesValues)\n : undefined;\n const currentLocale = (locale ?? client.locale ?? defaultLocale) as A;\n\n const cacheKey = `${String(key)}.${currentLocale}`;\n const loader = (dictionaryLoaders as Record<string, () => Promise<T>>)[\n currentLocale as string\n ];\n\n // --- Cache hit: return real content synchronously ---\n const cached = cache.get(cacheKey);\n if (cached) {\n const content = getDictionary(cached, currentLocale) as WithOnChange<\n DeepTransformContent<T['content']>\n >;\n\n content.onChange = (callback) => {\n // Re-fire whenever content reloads (locale change → new cache entry).\n client.subscribe((newLocale) => {\n const newKey = `${String(key)}.${newLocale}`;\n const newLoader = (\n dictionaryLoaders as Record<string, () => Promise<T>>\n )[newLocale];\n\n if (!newLoader) return;\n\n loadDictionary(newKey, newLoader).then(() => {\n const dict = cache.get(newKey);\n if (dict) {\n callback(getDictionary(dict, newLocale as A) as any);\n }\n });\n });\n\n return content;\n };\n\n return content;\n }\n\n // --- Cache miss: kick off background load, then notify to re-render ---\n if (loader) {\n loadDictionary(cacheKey, loader).then(() => {\n client.notify();\n });\n }\n\n return recursiveProxy;\n};\n"],"mappings":"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"}
@@ -32,7 +32,7 @@ import { getIntlayerClient } from "./installIntlayer.mjs";
32
32
  */
33
33
  const useIntlayer = (key, localeOrSelector) => {
34
34
  const client = getIntlayerClient();
35
- const isSelector = typeof localeOrSelector === "object" && localeOrSelector !== null;
35
+ const isSelector = process.env["INTLAYER_DICTIONARY_SELECTOR"] !== "false" && typeof localeOrSelector === "object" && localeOrSelector !== null;
36
36
  const explicitLocale = isSelector ? localeOrSelector.locale : localeOrSelector;
37
37
  const read = (locale) => isSelector ? getIntlayer(key, {
38
38
  ...localeOrSelector,
@@ -1 +1 @@
1
- {"version":3,"file":"useIntlayer.mjs","names":[],"sources":["../../../src/client/useIntlayer.ts"],"sourcesContent":["import type { DictionarySelector } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryResult,\n DictionarySelectorForKey,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { getIntlayer } from '../getIntlayer';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\nimport type { WithOnChange } from './useDictionary';\n\n/**\n * Get the translated content for the given key and optionally subscribe to\n * locale changes via the chainable `.onChange()` method — mirroring the API\n * of `react-intlayer`'s `useIntlayer`.\n *\n * The second argument is either a locale or a selector object:\n * - `{ item: 2 }` — collection item (omit `item` to get every item as array)\n * - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)\n * - `{ id: 'prod_abc', ...metaFields }` — meta record\n * - `locale` composes with any selector and overrides the current locale\n *\n * The function returns the current content **directly** (same shape as\n * `getIntlayer(key)`), plus the `.onChange()` helper.\n *\n * @param key - Dictionary key registered in your intlayer content files.\n * @param localeOrSelector - Optional locale or selector.\n * @returns The current translated content with an `.onChange()` method.\n *\n * @example\n * ```ts\n * import { installIntlayer, useIntlayer } from 'vanilla-intlayer';\n *\n * installIntlayer();\n *\n * const content = useIntlayer('homepage');\n * const faq2 = useIntlayer('faq', { item: 2 });\n * ```\n */\nexport const useIntlayer = <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<T> = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A\n): WithOnChange<\n DeepTransformContent<DictionaryRegistryResult<T, A>, ExtractSelectorLocale<A>>\n> => {\n const client = getIntlayerClient();\n\n const isSelector =\n typeof localeOrSelector === 'object' && localeOrSelector !== null;\n const explicitLocale = isSelector\n ? (localeOrSelector as DictionarySelector).locale\n : (localeOrSelector as LocalesValues | undefined);\n\n const read = (locale: LocalesValues | undefined) =>\n isSelector\n ? getIntlayer(key, {\n ...(localeOrSelector as DictionarySelector),\n locale,\n } as A)\n : getIntlayer(key, locale as A);\n\n const content = read(explicitLocale ?? client.locale) as WithOnChange<any>;\n\n // A selector can resolve to null/array; only objects carry `.onChange`.\n if (content != null && typeof content === 'object') {\n content.onChange = (callback) => {\n client.subscribe((newLocale) => {\n callback(read(explicitLocale ?? newLocale));\n });\n return content;\n };\n }\n\n return content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,MAAa,eAIX,KACA,qBAGG;CACH,MAAM,SAAS,mBAAmB;CAElC,MAAM,aACJ,OAAO,qBAAqB,YAAY,qBAAqB;CAC/D,MAAM,iBAAiB,aAClB,iBAAwC,SACxC;CAEL,MAAM,QAAQ,WACZ,aACI,YAAY,KAAK;EACf,GAAI;EACJ;EACD,CAAM,GACP,YAAY,KAAK,OAAY;CAEnC,MAAM,UAAU,KAAK,kBAAkB,OAAO,OAAO;AAGrD,KAAI,WAAW,QAAQ,OAAO,YAAY,SACxC,SAAQ,YAAY,aAAa;AAC/B,SAAO,WAAW,cAAc;AAC9B,YAAS,KAAK,kBAAkB,UAAU,CAAC;IAC3C;AACF,SAAO;;AAIX,QAAO"}
1
+ {"version":3,"file":"useIntlayer.mjs","names":[],"sources":["../../../src/client/useIntlayer.ts"],"sourcesContent":["import type { DictionarySelector } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionaryRegistryResult,\n DictionarySelectorForKey,\n ExtractSelectorLocale,\n LocalesValues,\n} from '@intlayer/types/module_augmentation';\nimport { getIntlayer } from '../getIntlayer';\nimport type { DeepTransformContent } from '../plugins';\nimport { getIntlayerClient } from './installIntlayer';\nimport type { WithOnChange } from './useDictionary';\n\n/**\n * Get the translated content for the given key and optionally subscribe to\n * locale changes via the chainable `.onChange()` method — mirroring the API\n * of `react-intlayer`'s `useIntlayer`.\n *\n * The second argument is either a locale or a selector object:\n * - `{ item: 2 }` — collection item (omit `item` to get every item as array)\n * - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)\n * - `{ id: 'prod_abc', ...metaFields }` — meta record\n * - `locale` composes with any selector and overrides the current locale\n *\n * The function returns the current content **directly** (same shape as\n * `getIntlayer(key)`), plus the `.onChange()` helper.\n *\n * @param key - Dictionary key registered in your intlayer content files.\n * @param localeOrSelector - Optional locale or selector.\n * @returns The current translated content with an `.onChange()` method.\n *\n * @example\n * ```ts\n * import { installIntlayer, useIntlayer } from 'vanilla-intlayer';\n *\n * installIntlayer();\n *\n * const content = useIntlayer('homepage');\n * const faq2 = useIntlayer('faq', { item: 2 });\n * ```\n */\nexport const useIntlayer = <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<T> = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A\n): WithOnChange<\n DeepTransformContent<DictionaryRegistryResult<T, A>, ExtractSelectorLocale<A>>\n> => {\n const client = getIntlayerClient();\n\n const isSelector =\n process.env['INTLAYER_DICTIONARY_SELECTOR'] !== 'false' &&\n typeof localeOrSelector === 'object' &&\n localeOrSelector !== null;\n const explicitLocale = isSelector\n ? (localeOrSelector as DictionarySelector).locale\n : (localeOrSelector as LocalesValues | undefined);\n\n const read = (locale: LocalesValues | undefined) =>\n isSelector\n ? getIntlayer(key, {\n ...(localeOrSelector as DictionarySelector),\n locale,\n } as A)\n : getIntlayer(key, locale as A);\n\n const content = read(explicitLocale ?? client.locale) as WithOnChange<any>;\n\n // A selector can resolve to null/array; only objects carry `.onChange`.\n if (content != null && typeof content === 'object') {\n content.onChange = (callback) => {\n client.subscribe((newLocale) => {\n callback(read(explicitLocale ?? newLocale));\n });\n return content;\n };\n }\n\n return content;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,MAAa,eAIX,KACA,qBAGG;CACH,MAAM,SAAS,mBAAmB;CAElC,MAAM,aACJ,QAAQ,IAAI,oCAAoC,WAChD,OAAO,qBAAqB,YAC5B,qBAAqB;CACvB,MAAM,iBAAiB,aAClB,iBAAwC,SACxC;CAEL,MAAM,QAAQ,WACZ,aACI,YAAY,KAAK;EACf,GAAI;EACJ;EACD,CAAM,GACP,YAAY,KAAK,OAAY;CAEnC,MAAM,UAAU,KAAK,kBAAkB,OAAO,OAAO;AAGrD,KAAI,WAAW,QAAQ,OAAO,YAAY,SACxC,SAAQ,YAAY,aAAa;AAC/B,SAAO,WAAW,cAAc;AAC9B,YAAS,KAAK,kBAAkB,UAAU,CAAC;IAC3C;AACF,SAAO;;AAIX,QAAO"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vanilla-intlayer",
3
- "version": "9.0.0-canary.0",
3
+ "version": "9.0.0-canary.2",
4
4
  "private": false,
5
5
  "description": "Easily internationalize i18n your Vanilla JS, HTML, and PHP applications with type-safe multilingual content management.",
6
6
  "keywords": [
@@ -101,11 +101,11 @@
101
101
  "typecheck": "tsc --noEmit --project tsconfig.types.json"
102
102
  },
103
103
  "dependencies": {
104
- "@intlayer/api": "9.0.0-canary.0",
105
- "@intlayer/config": "9.0.0-canary.0",
106
- "@intlayer/core": "9.0.0-canary.0",
107
- "@intlayer/editor": "9.0.0-canary.0",
108
- "@intlayer/types": "9.0.0-canary.0"
104
+ "@intlayer/api": "9.0.0-canary.2",
105
+ "@intlayer/config": "9.0.0-canary.2",
106
+ "@intlayer/core": "9.0.0-canary.2",
107
+ "@intlayer/editor": "9.0.0-canary.2",
108
+ "@intlayer/types": "9.0.0-canary.2"
109
109
  },
110
110
  "devDependencies": {
111
111
  "@types/node": "25.9.3",
@@ -115,10 +115,10 @@
115
115
  "rimraf": "6.1.3",
116
116
  "tsdown": "0.21.10",
117
117
  "typescript": "6.0.3",
118
- "vitest": "4.1.8"
118
+ "vitest": "4.1.9"
119
119
  },
120
120
  "peerDependencies": {
121
- "intlayer": "9.0.0-canary.0"
121
+ "intlayer": "9.0.0-canary.2"
122
122
  },
123
123
  "peerDependenciesMeta": {
124
124
  "intlayer": {