vanilla-intlayer 8.12.4 → 9.0.0-canary.0
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.
- package/dist/cjs/client/useDictionary.cjs +18 -39
- package/dist/cjs/client/useDictionary.cjs.map +1 -1
- package/dist/cjs/client/useDictionaryDynamic.cjs +70 -38
- package/dist/cjs/client/useDictionaryDynamic.cjs.map +1 -1
- package/dist/cjs/client/useIntlayer.cjs +19 -30
- package/dist/cjs/client/useIntlayer.cjs.map +1 -1
- package/dist/cjs/getDictionary.cjs +8 -1
- package/dist/cjs/getDictionary.cjs.map +1 -1
- package/dist/cjs/getIntlayer.cjs +8 -1
- package/dist/cjs/getIntlayer.cjs.map +1 -1
- package/dist/esm/client/useDictionary.mjs +18 -39
- package/dist/esm/client/useDictionary.mjs.map +1 -1
- package/dist/esm/client/useDictionaryDynamic.mjs +70 -38
- package/dist/esm/client/useDictionaryDynamic.mjs.map +1 -1
- package/dist/esm/client/useIntlayer.mjs +19 -30
- package/dist/esm/client/useIntlayer.mjs.map +1 -1
- package/dist/esm/getDictionary.mjs +8 -1
- package/dist/esm/getDictionary.mjs.map +1 -1
- package/dist/esm/getIntlayer.mjs +8 -1
- package/dist/esm/getIntlayer.mjs.map +1 -1
- package/dist/types/client/useDictionary.d.ts +12 -39
- package/dist/types/client/useDictionary.d.ts.map +1 -1
- package/dist/types/client/useDictionaryDynamic.d.ts +11 -27
- package/dist/types/client/useDictionaryDynamic.d.ts.map +1 -1
- package/dist/types/client/useIntlayer.d.ts +11 -28
- package/dist/types/client/useIntlayer.d.ts.map +1 -1
- package/dist/types/getDictionary.d.ts +8 -3
- package/dist/types/getDictionary.d.ts.map +1 -1
- package/dist/types/getIntlayer.d.ts +7 -2
- package/dist/types/getIntlayer.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -4,50 +4,29 @@ const require_client_installIntlayer = require('./installIntlayer.cjs');
|
|
|
4
4
|
|
|
5
5
|
//#region src/client/useDictionary.ts
|
|
6
6
|
/**
|
|
7
|
-
* Get the
|
|
8
|
-
* subscribe to locale changes via the chainable `.onChange()`
|
|
9
|
-
* mirroring the API of `react-intlayer`.
|
|
7
|
+
* Get the content for a raw dictionary (or qualified dictionary group) and
|
|
8
|
+
* optionally subscribe to locale changes via the chainable `.onChange()`
|
|
9
|
+
* method — mirroring the API of `react-intlayer`.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* or defined inline.
|
|
11
|
+
* The second argument is either a locale or a selector object (`{ item }`,
|
|
12
|
+
* `{ variant }`, `{ id, ...meta }`, optionally combined with `locale`).
|
|
14
13
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* ```ts
|
|
19
|
-
* // React
|
|
20
|
-
* const content = useDictionary(myDict);
|
|
21
|
-
*
|
|
22
|
-
* // Vanilla — identical surface API, opt-in reactivity via .onChange()
|
|
23
|
-
* const content = useDictionary(myDict);
|
|
24
|
-
* const content = useDictionary(myDict).onChange((c) => render(c));
|
|
25
|
-
* ```
|
|
26
|
-
*
|
|
27
|
-
* @param dictionary - The raw dictionary object.
|
|
28
|
-
* @param locale - Optional locale override.
|
|
29
|
-
* @returns The current translated content with an `.onChange()` method.
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* ```ts
|
|
33
|
-
* import myDict from './myDictionary.content';
|
|
34
|
-
* import { installIntlayer, useDictionary } from 'vanilla-intlayer';
|
|
35
|
-
*
|
|
36
|
-
* installIntlayer();
|
|
37
|
-
*
|
|
38
|
-
* const content = useDictionary(myDict).onChange((c) => {
|
|
39
|
-
* document.querySelector('p').textContent = String(c.greeting);
|
|
40
|
-
* });
|
|
41
|
-
*
|
|
42
|
-
* document.querySelector('p').textContent = String(content.greeting);
|
|
43
|
-
* ```
|
|
14
|
+
* @param dictionary - The raw dictionary (or qualified group) object.
|
|
15
|
+
* @param localeOrSelector - Optional locale or selector.
|
|
16
|
+
* @returns The current content with an `.onChange()` method.
|
|
44
17
|
*/
|
|
45
|
-
const useDictionary = (dictionary,
|
|
18
|
+
const useDictionary = (dictionary, localeOrSelector) => {
|
|
46
19
|
const client = require_client_installIntlayer.getIntlayerClient();
|
|
47
|
-
const
|
|
48
|
-
|
|
20
|
+
const isSelector = typeof localeOrSelector === "object" && localeOrSelector !== null;
|
|
21
|
+
const explicitLocale = isSelector ? localeOrSelector.locale : localeOrSelector;
|
|
22
|
+
const read = (locale) => isSelector ? require_getDictionary.getDictionary(dictionary, {
|
|
23
|
+
...localeOrSelector,
|
|
24
|
+
locale
|
|
25
|
+
}) : require_getDictionary.getDictionary(dictionary, locale);
|
|
26
|
+
const content = read(explicitLocale ?? client.locale);
|
|
27
|
+
if (content != null && typeof content === "object") content.onChange = (callback) => {
|
|
49
28
|
client.subscribe((newLocale) => {
|
|
50
|
-
callback(
|
|
29
|
+
callback(read(explicitLocale ?? newLocale));
|
|
51
30
|
});
|
|
52
31
|
return content;
|
|
53
32
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionary.cjs","names":["getIntlayerClient","getDictionary"],"sources":["../../../src/client/useDictionary.ts"],"sourcesContent":["import type {
|
|
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"}
|
|
@@ -3,12 +3,16 @@ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
|
3
3
|
const require_getDictionary = require('../getDictionary.cjs');
|
|
4
4
|
const require_client_installIntlayer = require('./installIntlayer.cjs');
|
|
5
5
|
let _intlayer_config_built = require("@intlayer/config/built");
|
|
6
|
+
let _intlayer_core_dictionaryManipulator = require("@intlayer/core/dictionaryManipulator");
|
|
6
7
|
|
|
7
8
|
//#region src/client/useDictionaryDynamic.ts
|
|
8
9
|
/** Simple in-memory cache shared across all calls in the same page. */
|
|
9
10
|
const cache = /* @__PURE__ */ new Map();
|
|
10
11
|
/** Tracks in-flight loads to avoid duplicate fetches. */
|
|
11
12
|
const inflight = /* @__PURE__ */ new Map();
|
|
13
|
+
/** Resolved-content cache for qualified (collection/variant/meta) keys. */
|
|
14
|
+
const qualifiedCache = /* @__PURE__ */ new Map();
|
|
15
|
+
const qualifiedInflight = /* @__PURE__ */ new Map();
|
|
12
16
|
const loadDictionary = (cacheKey, loader) => {
|
|
13
17
|
if (cache.has(cacheKey)) return Promise.resolve();
|
|
14
18
|
if (inflight.has(cacheKey)) return inflight.get(cacheKey);
|
|
@@ -19,39 +23,78 @@ const loadDictionary = (cacheKey, loader) => {
|
|
|
19
23
|
inflight.set(cacheKey, promise);
|
|
20
24
|
return promise;
|
|
21
25
|
};
|
|
26
|
+
/** Placeholder proxy — safe for any property access while loading. */
|
|
27
|
+
const recursiveProxy = new Proxy(() => {}, {
|
|
28
|
+
get: (_t, prop) => {
|
|
29
|
+
if (prop === Symbol.toPrimitive) return () => "";
|
|
30
|
+
if (prop === "toString") return () => "";
|
|
31
|
+
if (prop === "valueOf") return () => "";
|
|
32
|
+
if (prop === "then") return void 0;
|
|
33
|
+
if (prop === "onChange") return (_cb) => recursiveProxy;
|
|
34
|
+
return recursiveProxy;
|
|
35
|
+
},
|
|
36
|
+
apply: () => recursiveProxy
|
|
37
|
+
});
|
|
22
38
|
/**
|
|
23
|
-
* Dynamically load and transform a
|
|
39
|
+
* Dynamically load and transform a dictionary (plain or qualified).
|
|
24
40
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* content. Subsequent calls for the same locale return immediately from cache.
|
|
41
|
+
* For a qualified loader map (collection / variant / meta record, possibly
|
|
42
|
+
* combined), only the chunk(s) the selector targets are loaded. For a plain
|
|
43
|
+
* loader map, the locale chunk is loaded. The first call returns a placeholder
|
|
44
|
+
* and triggers a background load; the client then notifies subscribers so the
|
|
45
|
+
* render runs again with real content.
|
|
31
46
|
*
|
|
32
|
-
*
|
|
33
|
-
* render, real content after the locale bundle loads.
|
|
34
|
-
*
|
|
35
|
-
* @param dictionaryLoaders - Locale-keyed map of `() => Promise<Dictionary>`.
|
|
47
|
+
* @param dictionaryLoaders - Locale-keyed loader map, or a qualified loader map.
|
|
36
48
|
* @param key - Dictionary key (used for cache namespacing).
|
|
37
|
-
* @param
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```ts
|
|
41
|
-
* import dynDic from '../.intlayer/dynamic_dictionary/app.mjs';
|
|
42
|
-
*
|
|
43
|
-
* const render = () => {
|
|
44
|
-
* const content = useDictionaryDynamic(dynDic, 'app');
|
|
45
|
-
* document.querySelector('h1')!.textContent = String(content.title);
|
|
46
|
-
* };
|
|
47
|
-
*
|
|
48
|
-
* render();
|
|
49
|
-
* getIntlayerClient().subscribe(() => render());
|
|
50
|
-
* ```
|
|
49
|
+
* @param localeOrSelector - Optional locale or selector.
|
|
51
50
|
*/
|
|
52
|
-
const useDictionaryDynamic = (dictionaryLoaders, key,
|
|
51
|
+
const useDictionaryDynamic = (dictionaryLoaders, key, localeOrSelector) => {
|
|
53
52
|
const client = require_client_installIntlayer.getIntlayerClient();
|
|
54
|
-
const
|
|
53
|
+
const defaultLocale = _intlayer_config_built.internationalization.defaultLocale;
|
|
54
|
+
if ((0, _intlayer_core_dictionaryManipulator.isQualifiedDynamicLoaderMap)(dictionaryLoaders)) {
|
|
55
|
+
const loaderMap = dictionaryLoaders;
|
|
56
|
+
const { locale: selectorLocale, selector } = (0, _intlayer_core_dictionaryManipulator.parseDictionarySelector)(localeOrSelector);
|
|
57
|
+
const selectorId = (0, _intlayer_core_dictionaryManipulator.getDictionarySelectorCacheKey)(selector);
|
|
58
|
+
const buildKey = (locale) => `${String(key)}.${locale}.${selectorId}`;
|
|
59
|
+
const resolveContent = (locale) => (0, _intlayer_core_dictionaryManipulator.resolveQualifiedDynamicContentAsync)({
|
|
60
|
+
loaderMap,
|
|
61
|
+
key: String(key),
|
|
62
|
+
locale,
|
|
63
|
+
selector,
|
|
64
|
+
transform: (dictionary) => require_getDictionary.getDictionary(dictionary, locale)
|
|
65
|
+
});
|
|
66
|
+
const currentLocale = selectorLocale ?? client.locale ?? defaultLocale;
|
|
67
|
+
const cacheKey = buildKey(currentLocale);
|
|
68
|
+
const attachOnChange = (content) => {
|
|
69
|
+
if (content != null && typeof content === "object") content.onChange = (callback) => {
|
|
70
|
+
client.subscribe((newLocale) => {
|
|
71
|
+
const locale = selectorLocale ?? newLocale;
|
|
72
|
+
const newKey = buildKey(locale);
|
|
73
|
+
if (qualifiedCache.has(newKey)) {
|
|
74
|
+
callback(qualifiedCache.get(newKey));
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
resolveContent(locale).then((resolved) => {
|
|
78
|
+
qualifiedCache.set(newKey, resolved);
|
|
79
|
+
callback(resolved);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
return content;
|
|
83
|
+
};
|
|
84
|
+
return content;
|
|
85
|
+
};
|
|
86
|
+
if (qualifiedCache.has(cacheKey)) return attachOnChange(qualifiedCache.get(cacheKey));
|
|
87
|
+
if (!qualifiedInflight.has(cacheKey)) {
|
|
88
|
+
const promise = resolveContent(currentLocale).then((resolved) => {
|
|
89
|
+
qualifiedCache.set(cacheKey, resolved);
|
|
90
|
+
qualifiedInflight.delete(cacheKey);
|
|
91
|
+
client.notify();
|
|
92
|
+
});
|
|
93
|
+
qualifiedInflight.set(cacheKey, promise);
|
|
94
|
+
}
|
|
95
|
+
return recursiveProxy;
|
|
96
|
+
}
|
|
97
|
+
const currentLocale = (typeof localeOrSelector === "string" ? localeOrSelector : void 0) ?? client.locale ?? defaultLocale;
|
|
55
98
|
const cacheKey = `${String(key)}.${currentLocale}`;
|
|
56
99
|
const loader = dictionaryLoaders[currentLocale];
|
|
57
100
|
const cached = cache.get(cacheKey);
|
|
@@ -74,17 +117,6 @@ const useDictionaryDynamic = (dictionaryLoaders, key, locale) => {
|
|
|
74
117
|
if (loader) loadDictionary(cacheKey, loader).then(() => {
|
|
75
118
|
client.notify();
|
|
76
119
|
});
|
|
77
|
-
const recursiveProxy = new Proxy(() => {}, {
|
|
78
|
-
get: (_t, prop) => {
|
|
79
|
-
if (prop === Symbol.toPrimitive) return () => "";
|
|
80
|
-
if (prop === "toString") return () => "";
|
|
81
|
-
if (prop === "valueOf") return () => "";
|
|
82
|
-
if (prop === "then") return void 0;
|
|
83
|
-
if (prop === "onChange") return (_cb) => recursiveProxy;
|
|
84
|
-
return recursiveProxy;
|
|
85
|
-
},
|
|
86
|
-
apply: () => recursiveProxy
|
|
87
|
-
});
|
|
88
120
|
return recursiveProxy;
|
|
89
121
|
};
|
|
90
122
|
|
|
@@ -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 type {
|
|
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"}
|
|
@@ -8,28 +8,17 @@ const require_client_installIntlayer = require('./installIntlayer.cjs');
|
|
|
8
8
|
* locale changes via the chainable `.onChange()` method — mirroring the API
|
|
9
9
|
* of `react-intlayer`'s `useIntlayer`.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* The second argument is either a locale or a selector object:
|
|
12
|
+
* - `{ item: 2 }` — collection item (omit `item` to get every item as array)
|
|
13
|
+
* - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)
|
|
14
|
+
* - `{ id: 'prod_abc', ...metaFields }` — meta record
|
|
15
|
+
* - `locale` composes with any selector and overrides the current locale
|
|
15
16
|
*
|
|
16
17
|
* The function returns the current content **directly** (same shape as
|
|
17
|
-
* `getIntlayer(key)`), plus the `.onChange()` helper
|
|
18
|
+
* `getIntlayer(key)`), plus the `.onChange()` helper.
|
|
18
19
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* const content = useIntlayer('app');
|
|
22
|
-
*
|
|
23
|
-
* // Vanilla — identical surface API, opt-in reactivity via .onChange()
|
|
24
|
-
* const content = useIntlayer('app');
|
|
25
|
-
* const content = useIntlayer('app').onChange((c) => render(c));
|
|
26
|
-
* ```
|
|
27
|
-
*
|
|
28
|
-
* For cleanup (e.g. Vite HMR), subscribe via `getIntlayerClient().subscribe()`
|
|
29
|
-
* and hold the returned unsubscribe function.
|
|
30
|
-
*
|
|
31
|
-
* @param key - Dictionary key registered in your intlayer content files.
|
|
32
|
-
* @param locale - Optional locale override (defaults to the current app locale).
|
|
20
|
+
* @param key - Dictionary key registered in your intlayer content files.
|
|
21
|
+
* @param localeOrSelector - Optional locale or selector.
|
|
33
22
|
* @returns The current translated content with an `.onChange()` method.
|
|
34
23
|
*
|
|
35
24
|
* @example
|
|
@@ -38,22 +27,22 @@ const require_client_installIntlayer = require('./installIntlayer.cjs');
|
|
|
38
27
|
*
|
|
39
28
|
* installIntlayer();
|
|
40
29
|
*
|
|
41
|
-
* // Static read (no subscription)
|
|
42
30
|
* const content = useIntlayer('homepage');
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* // Reactive read — onChange is called on every locale change
|
|
46
|
-
* useIntlayer('homepage').onChange((c) => {
|
|
47
|
-
* document.querySelector('h1').textContent = String(c.title);
|
|
48
|
-
* });
|
|
31
|
+
* const faq2 = useIntlayer('faq', { item: 2 });
|
|
49
32
|
* ```
|
|
50
33
|
*/
|
|
51
|
-
const useIntlayer = (key,
|
|
34
|
+
const useIntlayer = (key, localeOrSelector) => {
|
|
52
35
|
const client = require_client_installIntlayer.getIntlayerClient();
|
|
53
|
-
const
|
|
54
|
-
|
|
36
|
+
const isSelector = typeof localeOrSelector === "object" && localeOrSelector !== null;
|
|
37
|
+
const explicitLocale = isSelector ? localeOrSelector.locale : localeOrSelector;
|
|
38
|
+
const read = (locale) => isSelector ? require_getIntlayer.getIntlayer(key, {
|
|
39
|
+
...localeOrSelector,
|
|
40
|
+
locale
|
|
41
|
+
}) : require_getIntlayer.getIntlayer(key, locale);
|
|
42
|
+
const content = read(explicitLocale ?? client.locale);
|
|
43
|
+
if (content != null && typeof content === "object") content.onChange = (callback) => {
|
|
55
44
|
client.subscribe((newLocale) => {
|
|
56
|
-
callback(
|
|
45
|
+
callback(read(explicitLocale ?? newLocale));
|
|
57
46
|
});
|
|
58
47
|
return content;
|
|
59
48
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useIntlayer.cjs","names":["getIntlayerClient","getIntlayer"],"sources":["../../../src/client/useIntlayer.ts"],"sourcesContent":["import type {\n DictionaryKeys,\n
|
|
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"}
|
|
@@ -4,7 +4,14 @@ const require_plugins = require('./plugins.cjs');
|
|
|
4
4
|
let _intlayer_core_interpreter = require("@intlayer/core/interpreter");
|
|
5
5
|
|
|
6
6
|
//#region src/getDictionary.ts
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Transforms a dictionary (or qualified dictionary group) and returns its
|
|
9
|
+
* content for the given locale or selector (`{ item }`, `{ variant }`,
|
|
10
|
+
* `{ id, ...meta }`, optionally combined with `locale`).
|
|
11
|
+
*/
|
|
12
|
+
const getDictionary = (dictionary, localeOrSelector) => {
|
|
13
|
+
return (0, _intlayer_core_interpreter.getDictionary)(dictionary, localeOrSelector, require_plugins.getPlugins(typeof localeOrSelector === "object" && localeOrSelector !== null ? localeOrSelector.locale : localeOrSelector));
|
|
14
|
+
};
|
|
8
15
|
|
|
9
16
|
//#endregion
|
|
10
17
|
exports.getDictionary = getDictionary;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDictionary.cjs","names":["getPlugins"],"sources":["../../src/getDictionary.ts"],"sourcesContent":["import { getDictionary as getDictionaryCore } from '@intlayer/core/interpreter';\nimport type {
|
|
1
|
+
{"version":3,"file":"getDictionary.cjs","names":["getPlugins"],"sources":["../../src/getDictionary.ts"],"sourcesContent":["import { getDictionary as getDictionaryCore } from '@intlayer/core/interpreter';\nimport 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 { type DeepTransformContent, getPlugins } from './plugins';\n\n/**\n * Transforms a dictionary (or qualified dictionary group) and returns its\n * content for the given locale or selector (`{ item }`, `{ variant }`,\n * `{ id, ...meta }`, optionally combined with `locale`).\n */\nexport const getDictionary = <\n const T extends Dictionary | QualifiedDictionaryGroup,\n const A extends\n | LocalesValues\n | DictionarySelectorForGroup<T> = DeclaredLocales,\n>(\n dictionary: T,\n localeOrSelector?: A\n): DeepTransformContent<\n ResolveQualifiedDictionaryContent<T, A>,\n ExtractSelectorLocale<A>\n> => {\n const locale = (\n typeof localeOrSelector === 'object' && localeOrSelector !== null\n ? localeOrSelector.locale\n : localeOrSelector\n ) as LocalesValues | undefined;\n\n return getDictionaryCore(\n dictionary,\n localeOrSelector,\n getPlugins(locale)\n ) as any;\n};\n"],"mappings":";;;;;;;;;;;AAoBA,MAAa,iBAMX,YACA,qBAIG;AAOH,sDACE,YACA,kBACAA,2BARA,OAAO,qBAAqB,YAAY,qBAAqB,OACzD,iBAAiB,SACjB,iBAMc,CACnB"}
|
package/dist/cjs/getIntlayer.cjs
CHANGED
|
@@ -4,7 +4,14 @@ const require_plugins = require('./plugins.cjs');
|
|
|
4
4
|
let _intlayer_core_interpreter = require("@intlayer/core/interpreter");
|
|
5
5
|
|
|
6
6
|
//#region src/getIntlayer.ts
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Picks one dictionary by its key and returns its content for the given
|
|
9
|
+
* locale or selector (`{ item }`, `{ variant }`, `{ id, ...meta }`,
|
|
10
|
+
* optionally combined with `locale`).
|
|
11
|
+
*/
|
|
12
|
+
const getIntlayer = (key, localeOrSelector) => {
|
|
13
|
+
return (0, _intlayer_core_interpreter.getIntlayer)(key, localeOrSelector, require_plugins.getPlugins(typeof localeOrSelector === "object" && localeOrSelector !== null ? localeOrSelector.locale : localeOrSelector));
|
|
14
|
+
};
|
|
8
15
|
|
|
9
16
|
//#endregion
|
|
10
17
|
exports.getIntlayer = getIntlayer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getIntlayer.cjs","names":["getPlugins"],"sources":["../../src/getIntlayer.ts"],"sourcesContent":["import { getIntlayer as getIntlayerCore } from '@intlayer/core/interpreter';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n
|
|
1
|
+
{"version":3,"file":"getIntlayer.cjs","names":["getPlugins"],"sources":["../../src/getIntlayer.ts"],"sourcesContent":["import { getIntlayer as getIntlayerCore } from '@intlayer/core/interpreter';\nimport 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 { type DeepTransformContent, getPlugins } from './plugins';\n\n/**\n * Picks one dictionary by its key and returns its content for the given\n * locale or selector (`{ item }`, `{ variant }`, `{ id, ...meta }`,\n * optionally combined with `locale`).\n */\nexport const getIntlayer = <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<T> = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A\n): DeepTransformContent<\n DictionaryRegistryResult<T, A>,\n ExtractSelectorLocale<A>\n> => {\n const locale = (\n typeof localeOrSelector === 'object' && localeOrSelector !== null\n ? localeOrSelector.locale\n : localeOrSelector\n ) as LocalesValues | undefined;\n\n return getIntlayerCore(key, localeOrSelector, getPlugins(locale)) as any;\n};\n"],"mappings":";;;;;;;;;;;AAiBA,MAAa,eAIX,KACA,qBAIG;AAOH,oDAAuB,KAAK,kBAAkBA,2BAL5C,OAAO,qBAAqB,YAAY,qBAAqB,OACzD,iBAAiB,SACjB,iBAG0D,CAAC"}
|
|
@@ -3,50 +3,29 @@ import { getIntlayerClient } from "./installIntlayer.mjs";
|
|
|
3
3
|
|
|
4
4
|
//#region src/client/useDictionary.ts
|
|
5
5
|
/**
|
|
6
|
-
* Get the
|
|
7
|
-
* subscribe to locale changes via the chainable `.onChange()`
|
|
8
|
-
* mirroring the API of `react-intlayer`.
|
|
6
|
+
* Get the content for a raw dictionary (or qualified dictionary group) and
|
|
7
|
+
* optionally subscribe to locale changes via the chainable `.onChange()`
|
|
8
|
+
* method — mirroring the API of `react-intlayer`.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* or defined inline.
|
|
10
|
+
* The second argument is either a locale or a selector object (`{ item }`,
|
|
11
|
+
* `{ variant }`, `{ id, ...meta }`, optionally combined with `locale`).
|
|
13
12
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* ```ts
|
|
18
|
-
* // React
|
|
19
|
-
* const content = useDictionary(myDict);
|
|
20
|
-
*
|
|
21
|
-
* // Vanilla — identical surface API, opt-in reactivity via .onChange()
|
|
22
|
-
* const content = useDictionary(myDict);
|
|
23
|
-
* const content = useDictionary(myDict).onChange((c) => render(c));
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* @param dictionary - The raw dictionary object.
|
|
27
|
-
* @param locale - Optional locale override.
|
|
28
|
-
* @returns The current translated content with an `.onChange()` method.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```ts
|
|
32
|
-
* import myDict from './myDictionary.content';
|
|
33
|
-
* import { installIntlayer, useDictionary } from 'vanilla-intlayer';
|
|
34
|
-
*
|
|
35
|
-
* installIntlayer();
|
|
36
|
-
*
|
|
37
|
-
* const content = useDictionary(myDict).onChange((c) => {
|
|
38
|
-
* document.querySelector('p').textContent = String(c.greeting);
|
|
39
|
-
* });
|
|
40
|
-
*
|
|
41
|
-
* document.querySelector('p').textContent = String(content.greeting);
|
|
42
|
-
* ```
|
|
13
|
+
* @param dictionary - The raw dictionary (or qualified group) object.
|
|
14
|
+
* @param localeOrSelector - Optional locale or selector.
|
|
15
|
+
* @returns The current content with an `.onChange()` method.
|
|
43
16
|
*/
|
|
44
|
-
const useDictionary = (dictionary,
|
|
17
|
+
const useDictionary = (dictionary, localeOrSelector) => {
|
|
45
18
|
const client = getIntlayerClient();
|
|
46
|
-
const
|
|
47
|
-
|
|
19
|
+
const isSelector = typeof localeOrSelector === "object" && localeOrSelector !== null;
|
|
20
|
+
const explicitLocale = isSelector ? localeOrSelector.locale : localeOrSelector;
|
|
21
|
+
const read = (locale) => isSelector ? getDictionary(dictionary, {
|
|
22
|
+
...localeOrSelector,
|
|
23
|
+
locale
|
|
24
|
+
}) : getDictionary(dictionary, locale);
|
|
25
|
+
const content = read(explicitLocale ?? client.locale);
|
|
26
|
+
if (content != null && typeof content === "object") content.onChange = (callback) => {
|
|
48
27
|
client.subscribe((newLocale) => {
|
|
49
|
-
callback(
|
|
28
|
+
callback(read(explicitLocale ?? newLocale));
|
|
50
29
|
});
|
|
51
30
|
return content;
|
|
52
31
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionary.mjs","names":[],"sources":["../../../src/client/useDictionary.ts"],"sourcesContent":["import type {
|
|
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,12 +1,16 @@
|
|
|
1
1
|
import { getDictionary } from "../getDictionary.mjs";
|
|
2
2
|
import { getIntlayerClient } from "./installIntlayer.mjs";
|
|
3
3
|
import { internationalization } from "@intlayer/config/built";
|
|
4
|
+
import { getDictionarySelectorCacheKey, isQualifiedDynamicLoaderMap, parseDictionarySelector, resolveQualifiedDynamicContentAsync } from "@intlayer/core/dictionaryManipulator";
|
|
4
5
|
|
|
5
6
|
//#region src/client/useDictionaryDynamic.ts
|
|
6
7
|
/** Simple in-memory cache shared across all calls in the same page. */
|
|
7
8
|
const cache = /* @__PURE__ */ new Map();
|
|
8
9
|
/** Tracks in-flight loads to avoid duplicate fetches. */
|
|
9
10
|
const inflight = /* @__PURE__ */ new Map();
|
|
11
|
+
/** Resolved-content cache for qualified (collection/variant/meta) keys. */
|
|
12
|
+
const qualifiedCache = /* @__PURE__ */ new Map();
|
|
13
|
+
const qualifiedInflight = /* @__PURE__ */ new Map();
|
|
10
14
|
const loadDictionary = (cacheKey, loader) => {
|
|
11
15
|
if (cache.has(cacheKey)) return Promise.resolve();
|
|
12
16
|
if (inflight.has(cacheKey)) return inflight.get(cacheKey);
|
|
@@ -17,39 +21,78 @@ const loadDictionary = (cacheKey, loader) => {
|
|
|
17
21
|
inflight.set(cacheKey, promise);
|
|
18
22
|
return promise;
|
|
19
23
|
};
|
|
24
|
+
/** Placeholder proxy — safe for any property access while loading. */
|
|
25
|
+
const recursiveProxy = new Proxy(() => {}, {
|
|
26
|
+
get: (_t, prop) => {
|
|
27
|
+
if (prop === Symbol.toPrimitive) return () => "";
|
|
28
|
+
if (prop === "toString") return () => "";
|
|
29
|
+
if (prop === "valueOf") return () => "";
|
|
30
|
+
if (prop === "then") return void 0;
|
|
31
|
+
if (prop === "onChange") return (_cb) => recursiveProxy;
|
|
32
|
+
return recursiveProxy;
|
|
33
|
+
},
|
|
34
|
+
apply: () => recursiveProxy
|
|
35
|
+
});
|
|
20
36
|
/**
|
|
21
|
-
* Dynamically load and transform a
|
|
37
|
+
* Dynamically load and transform a dictionary (plain or qualified).
|
|
22
38
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* content. Subsequent calls for the same locale return immediately from cache.
|
|
39
|
+
* For a qualified loader map (collection / variant / meta record, possibly
|
|
40
|
+
* combined), only the chunk(s) the selector targets are loaded. For a plain
|
|
41
|
+
* loader map, the locale chunk is loaded. The first call returns a placeholder
|
|
42
|
+
* and triggers a background load; the client then notifies subscribers so the
|
|
43
|
+
* render runs again with real content.
|
|
29
44
|
*
|
|
30
|
-
*
|
|
31
|
-
* render, real content after the locale bundle loads.
|
|
32
|
-
*
|
|
33
|
-
* @param dictionaryLoaders - Locale-keyed map of `() => Promise<Dictionary>`.
|
|
45
|
+
* @param dictionaryLoaders - Locale-keyed loader map, or a qualified loader map.
|
|
34
46
|
* @param key - Dictionary key (used for cache namespacing).
|
|
35
|
-
* @param
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* ```ts
|
|
39
|
-
* import dynDic from '../.intlayer/dynamic_dictionary/app.mjs';
|
|
40
|
-
*
|
|
41
|
-
* const render = () => {
|
|
42
|
-
* const content = useDictionaryDynamic(dynDic, 'app');
|
|
43
|
-
* document.querySelector('h1')!.textContent = String(content.title);
|
|
44
|
-
* };
|
|
45
|
-
*
|
|
46
|
-
* render();
|
|
47
|
-
* getIntlayerClient().subscribe(() => render());
|
|
48
|
-
* ```
|
|
47
|
+
* @param localeOrSelector - Optional locale or selector.
|
|
49
48
|
*/
|
|
50
|
-
const useDictionaryDynamic = (dictionaryLoaders, key,
|
|
49
|
+
const useDictionaryDynamic = (dictionaryLoaders, key, localeOrSelector) => {
|
|
51
50
|
const client = getIntlayerClient();
|
|
52
|
-
const
|
|
51
|
+
const defaultLocale = internationalization.defaultLocale;
|
|
52
|
+
if (isQualifiedDynamicLoaderMap(dictionaryLoaders)) {
|
|
53
|
+
const loaderMap = dictionaryLoaders;
|
|
54
|
+
const { locale: selectorLocale, selector } = parseDictionarySelector(localeOrSelector);
|
|
55
|
+
const selectorId = getDictionarySelectorCacheKey(selector);
|
|
56
|
+
const buildKey = (locale) => `${String(key)}.${locale}.${selectorId}`;
|
|
57
|
+
const resolveContent = (locale) => resolveQualifiedDynamicContentAsync({
|
|
58
|
+
loaderMap,
|
|
59
|
+
key: String(key),
|
|
60
|
+
locale,
|
|
61
|
+
selector,
|
|
62
|
+
transform: (dictionary) => getDictionary(dictionary, locale)
|
|
63
|
+
});
|
|
64
|
+
const currentLocale = selectorLocale ?? client.locale ?? defaultLocale;
|
|
65
|
+
const cacheKey = buildKey(currentLocale);
|
|
66
|
+
const attachOnChange = (content) => {
|
|
67
|
+
if (content != null && typeof content === "object") content.onChange = (callback) => {
|
|
68
|
+
client.subscribe((newLocale) => {
|
|
69
|
+
const locale = selectorLocale ?? newLocale;
|
|
70
|
+
const newKey = buildKey(locale);
|
|
71
|
+
if (qualifiedCache.has(newKey)) {
|
|
72
|
+
callback(qualifiedCache.get(newKey));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
resolveContent(locale).then((resolved) => {
|
|
76
|
+
qualifiedCache.set(newKey, resolved);
|
|
77
|
+
callback(resolved);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
return content;
|
|
81
|
+
};
|
|
82
|
+
return content;
|
|
83
|
+
};
|
|
84
|
+
if (qualifiedCache.has(cacheKey)) return attachOnChange(qualifiedCache.get(cacheKey));
|
|
85
|
+
if (!qualifiedInflight.has(cacheKey)) {
|
|
86
|
+
const promise = resolveContent(currentLocale).then((resolved) => {
|
|
87
|
+
qualifiedCache.set(cacheKey, resolved);
|
|
88
|
+
qualifiedInflight.delete(cacheKey);
|
|
89
|
+
client.notify();
|
|
90
|
+
});
|
|
91
|
+
qualifiedInflight.set(cacheKey, promise);
|
|
92
|
+
}
|
|
93
|
+
return recursiveProxy;
|
|
94
|
+
}
|
|
95
|
+
const currentLocale = (typeof localeOrSelector === "string" ? localeOrSelector : void 0) ?? client.locale ?? defaultLocale;
|
|
53
96
|
const cacheKey = `${String(key)}.${currentLocale}`;
|
|
54
97
|
const loader = dictionaryLoaders[currentLocale];
|
|
55
98
|
const cached = cache.get(cacheKey);
|
|
@@ -72,17 +115,6 @@ const useDictionaryDynamic = (dictionaryLoaders, key, locale) => {
|
|
|
72
115
|
if (loader) loadDictionary(cacheKey, loader).then(() => {
|
|
73
116
|
client.notify();
|
|
74
117
|
});
|
|
75
|
-
const recursiveProxy = new Proxy(() => {}, {
|
|
76
|
-
get: (_t, prop) => {
|
|
77
|
-
if (prop === Symbol.toPrimitive) return () => "";
|
|
78
|
-
if (prop === "toString") return () => "";
|
|
79
|
-
if (prop === "valueOf") return () => "";
|
|
80
|
-
if (prop === "then") return void 0;
|
|
81
|
-
if (prop === "onChange") return (_cb) => recursiveProxy;
|
|
82
|
-
return recursiveProxy;
|
|
83
|
-
},
|
|
84
|
-
apply: () => recursiveProxy
|
|
85
|
-
});
|
|
86
118
|
return recursiveProxy;
|
|
87
119
|
};
|
|
88
120
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryDynamic.mjs","names":[],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type {
|
|
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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"}
|
|
@@ -7,28 +7,17 @@ import { getIntlayerClient } from "./installIntlayer.mjs";
|
|
|
7
7
|
* locale changes via the chainable `.onChange()` method — mirroring the API
|
|
8
8
|
* of `react-intlayer`'s `useIntlayer`.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* The second argument is either a locale or a selector object:
|
|
11
|
+
* - `{ item: 2 }` — collection item (omit `item` to get every item as array)
|
|
12
|
+
* - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)
|
|
13
|
+
* - `{ id: 'prod_abc', ...metaFields }` — meta record
|
|
14
|
+
* - `locale` composes with any selector and overrides the current locale
|
|
14
15
|
*
|
|
15
16
|
* The function returns the current content **directly** (same shape as
|
|
16
|
-
* `getIntlayer(key)`), plus the `.onChange()` helper
|
|
17
|
+
* `getIntlayer(key)`), plus the `.onChange()` helper.
|
|
17
18
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* const content = useIntlayer('app');
|
|
21
|
-
*
|
|
22
|
-
* // Vanilla — identical surface API, opt-in reactivity via .onChange()
|
|
23
|
-
* const content = useIntlayer('app');
|
|
24
|
-
* const content = useIntlayer('app').onChange((c) => render(c));
|
|
25
|
-
* ```
|
|
26
|
-
*
|
|
27
|
-
* For cleanup (e.g. Vite HMR), subscribe via `getIntlayerClient().subscribe()`
|
|
28
|
-
* and hold the returned unsubscribe function.
|
|
29
|
-
*
|
|
30
|
-
* @param key - Dictionary key registered in your intlayer content files.
|
|
31
|
-
* @param locale - Optional locale override (defaults to the current app locale).
|
|
19
|
+
* @param key - Dictionary key registered in your intlayer content files.
|
|
20
|
+
* @param localeOrSelector - Optional locale or selector.
|
|
32
21
|
* @returns The current translated content with an `.onChange()` method.
|
|
33
22
|
*
|
|
34
23
|
* @example
|
|
@@ -37,22 +26,22 @@ import { getIntlayerClient } from "./installIntlayer.mjs";
|
|
|
37
26
|
*
|
|
38
27
|
* installIntlayer();
|
|
39
28
|
*
|
|
40
|
-
* // Static read (no subscription)
|
|
41
29
|
* const content = useIntlayer('homepage');
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* // Reactive read — onChange is called on every locale change
|
|
45
|
-
* useIntlayer('homepage').onChange((c) => {
|
|
46
|
-
* document.querySelector('h1').textContent = String(c.title);
|
|
47
|
-
* });
|
|
30
|
+
* const faq2 = useIntlayer('faq', { item: 2 });
|
|
48
31
|
* ```
|
|
49
32
|
*/
|
|
50
|
-
const useIntlayer = (key,
|
|
33
|
+
const useIntlayer = (key, localeOrSelector) => {
|
|
51
34
|
const client = getIntlayerClient();
|
|
52
|
-
const
|
|
53
|
-
|
|
35
|
+
const isSelector = typeof localeOrSelector === "object" && localeOrSelector !== null;
|
|
36
|
+
const explicitLocale = isSelector ? localeOrSelector.locale : localeOrSelector;
|
|
37
|
+
const read = (locale) => isSelector ? getIntlayer(key, {
|
|
38
|
+
...localeOrSelector,
|
|
39
|
+
locale
|
|
40
|
+
}) : getIntlayer(key, locale);
|
|
41
|
+
const content = read(explicitLocale ?? client.locale);
|
|
42
|
+
if (content != null && typeof content === "object") content.onChange = (callback) => {
|
|
54
43
|
client.subscribe((newLocale) => {
|
|
55
|
-
callback(
|
|
44
|
+
callback(read(explicitLocale ?? newLocale));
|
|
56
45
|
});
|
|
57
46
|
return content;
|
|
58
47
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useIntlayer.mjs","names":[],"sources":["../../../src/client/useIntlayer.ts"],"sourcesContent":["import type {\n DictionaryKeys,\n
|
|
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"}
|
|
@@ -2,7 +2,14 @@ import { getPlugins } from "./plugins.mjs";
|
|
|
2
2
|
import { getDictionary as getDictionary$1 } from "@intlayer/core/interpreter";
|
|
3
3
|
|
|
4
4
|
//#region src/getDictionary.ts
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Transforms a dictionary (or qualified dictionary group) and returns its
|
|
7
|
+
* content for the given locale or selector (`{ item }`, `{ variant }`,
|
|
8
|
+
* `{ id, ...meta }`, optionally combined with `locale`).
|
|
9
|
+
*/
|
|
10
|
+
const getDictionary = (dictionary, localeOrSelector) => {
|
|
11
|
+
return getDictionary$1(dictionary, localeOrSelector, getPlugins(typeof localeOrSelector === "object" && localeOrSelector !== null ? localeOrSelector.locale : localeOrSelector));
|
|
12
|
+
};
|
|
6
13
|
|
|
7
14
|
//#endregion
|
|
8
15
|
export { getDictionary };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDictionary.mjs","names":["getDictionaryCore"],"sources":["../../src/getDictionary.ts"],"sourcesContent":["import { getDictionary as getDictionaryCore } from '@intlayer/core/interpreter';\nimport type {
|
|
1
|
+
{"version":3,"file":"getDictionary.mjs","names":["getDictionaryCore"],"sources":["../../src/getDictionary.ts"],"sourcesContent":["import { getDictionary as getDictionaryCore } from '@intlayer/core/interpreter';\nimport 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 { type DeepTransformContent, getPlugins } from './plugins';\n\n/**\n * Transforms a dictionary (or qualified dictionary group) and returns its\n * content for the given locale or selector (`{ item }`, `{ variant }`,\n * `{ id, ...meta }`, optionally combined with `locale`).\n */\nexport const getDictionary = <\n const T extends Dictionary | QualifiedDictionaryGroup,\n const A extends\n | LocalesValues\n | DictionarySelectorForGroup<T> = DeclaredLocales,\n>(\n dictionary: T,\n localeOrSelector?: A\n): DeepTransformContent<\n ResolveQualifiedDictionaryContent<T, A>,\n ExtractSelectorLocale<A>\n> => {\n const locale = (\n typeof localeOrSelector === 'object' && localeOrSelector !== null\n ? localeOrSelector.locale\n : localeOrSelector\n ) as LocalesValues | undefined;\n\n return getDictionaryCore(\n dictionary,\n localeOrSelector,\n getPlugins(locale)\n ) as any;\n};\n"],"mappings":";;;;;;;;;AAoBA,MAAa,iBAMX,YACA,qBAIG;AAOH,QAAOA,gBACL,YACA,kBACA,WARA,OAAO,qBAAqB,YAAY,qBAAqB,OACzD,iBAAiB,SACjB,iBAMc,CACnB"}
|
package/dist/esm/getIntlayer.mjs
CHANGED
|
@@ -2,7 +2,14 @@ import { getPlugins } from "./plugins.mjs";
|
|
|
2
2
|
import { getIntlayer as getIntlayer$1 } from "@intlayer/core/interpreter";
|
|
3
3
|
|
|
4
4
|
//#region src/getIntlayer.ts
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Picks one dictionary by its key and returns its content for the given
|
|
7
|
+
* locale or selector (`{ item }`, `{ variant }`, `{ id, ...meta }`,
|
|
8
|
+
* optionally combined with `locale`).
|
|
9
|
+
*/
|
|
10
|
+
const getIntlayer = (key, localeOrSelector) => {
|
|
11
|
+
return getIntlayer$1(key, localeOrSelector, getPlugins(typeof localeOrSelector === "object" && localeOrSelector !== null ? localeOrSelector.locale : localeOrSelector));
|
|
12
|
+
};
|
|
6
13
|
|
|
7
14
|
//#endregion
|
|
8
15
|
export { getIntlayer };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getIntlayer.mjs","names":["getIntlayerCore"],"sources":["../../src/getIntlayer.ts"],"sourcesContent":["import { getIntlayer as getIntlayerCore } from '@intlayer/core/interpreter';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n
|
|
1
|
+
{"version":3,"file":"getIntlayer.mjs","names":["getIntlayerCore"],"sources":["../../src/getIntlayer.ts"],"sourcesContent":["import { getIntlayer as getIntlayerCore } from '@intlayer/core/interpreter';\nimport 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 { type DeepTransformContent, getPlugins } from './plugins';\n\n/**\n * Picks one dictionary by its key and returns its content for the given\n * locale or selector (`{ item }`, `{ variant }`, `{ id, ...meta }`,\n * optionally combined with `locale`).\n */\nexport const getIntlayer = <\n const T extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<T> = DeclaredLocales,\n>(\n key: T,\n localeOrSelector?: A\n): DeepTransformContent<\n DictionaryRegistryResult<T, A>,\n ExtractSelectorLocale<A>\n> => {\n const locale = (\n typeof localeOrSelector === 'object' && localeOrSelector !== null\n ? localeOrSelector.locale\n : localeOrSelector\n ) as LocalesValues | undefined;\n\n return getIntlayerCore(key, localeOrSelector, getPlugins(locale)) as any;\n};\n"],"mappings":";;;;;;;;;AAiBA,MAAa,eAIX,KACA,qBAIG;AAOH,QAAOA,cAAgB,KAAK,kBAAkB,WAL5C,OAAO,qBAAqB,YAAY,qBAAqB,OACzD,iBAAiB,SACjB,iBAG0D,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DeepTransformContent } from "../plugins.js";
|
|
2
|
-
import { DeclaredLocales, LocalesValues } from "@intlayer/types/module_augmentation";
|
|
3
|
-
import { Dictionary } from "@intlayer/types/dictionary";
|
|
2
|
+
import { DeclaredLocales, ExtractSelectorLocale, LocalesValues } from "@intlayer/types/module_augmentation";
|
|
3
|
+
import { Dictionary, DictionarySelectorForGroup, QualifiedDictionaryGroup, ResolveQualifiedDictionaryContent } from "@intlayer/types/dictionary";
|
|
4
4
|
|
|
5
5
|
//#region src/client/useDictionary.d.ts
|
|
6
6
|
type WithOnChange<T> = T & {
|
|
@@ -15,48 +15,21 @@ type WithOnChange<T> = T & {
|
|
|
15
15
|
* });
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
|
-
onChange: (callback:
|
|
18
|
+
onChange: (callback: (content: any) => void) => WithOnChange<T>;
|
|
19
19
|
};
|
|
20
20
|
/**
|
|
21
|
-
* Get the
|
|
22
|
-
* subscribe to locale changes via the chainable `.onChange()`
|
|
23
|
-
* mirroring the API of `react-intlayer`.
|
|
21
|
+
* Get the content for a raw dictionary (or qualified dictionary group) and
|
|
22
|
+
* optionally subscribe to locale changes via the chainable `.onChange()`
|
|
23
|
+
* method — mirroring the API of `react-intlayer`.
|
|
24
24
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* or defined inline.
|
|
25
|
+
* The second argument is either a locale or a selector object (`{ item }`,
|
|
26
|
+
* `{ variant }`, `{ id, ...meta }`, optionally combined with `locale`).
|
|
28
27
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* ```ts
|
|
33
|
-
* // React
|
|
34
|
-
* const content = useDictionary(myDict);
|
|
35
|
-
*
|
|
36
|
-
* // Vanilla — identical surface API, opt-in reactivity via .onChange()
|
|
37
|
-
* const content = useDictionary(myDict);
|
|
38
|
-
* const content = useDictionary(myDict).onChange((c) => render(c));
|
|
39
|
-
* ```
|
|
40
|
-
*
|
|
41
|
-
* @param dictionary - The raw dictionary object.
|
|
42
|
-
* @param locale - Optional locale override.
|
|
43
|
-
* @returns The current translated content with an `.onChange()` method.
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* ```ts
|
|
47
|
-
* import myDict from './myDictionary.content';
|
|
48
|
-
* import { installIntlayer, useDictionary } from 'vanilla-intlayer';
|
|
49
|
-
*
|
|
50
|
-
* installIntlayer();
|
|
51
|
-
*
|
|
52
|
-
* const content = useDictionary(myDict).onChange((c) => {
|
|
53
|
-
* document.querySelector('p').textContent = String(c.greeting);
|
|
54
|
-
* });
|
|
55
|
-
*
|
|
56
|
-
* document.querySelector('p').textContent = String(content.greeting);
|
|
57
|
-
* ```
|
|
28
|
+
* @param dictionary - The raw dictionary (or qualified group) object.
|
|
29
|
+
* @param localeOrSelector - Optional locale or selector.
|
|
30
|
+
* @returns The current content with an `.onChange()` method.
|
|
58
31
|
*/
|
|
59
|
-
declare const useDictionary: <const T extends Dictionary, const
|
|
32
|
+
declare const useDictionary: <const T extends Dictionary | QualifiedDictionaryGroup, const A extends LocalesValues | DictionarySelectorForGroup<T> = DeclaredLocales>(dictionary: T, localeOrSelector?: A) => WithOnChange<DeepTransformContent<ResolveQualifiedDictionaryContent<T, A>, ExtractSelectorLocale<A>>>;
|
|
60
33
|
//#endregion
|
|
61
34
|
export { WithOnChange, useDictionary };
|
|
62
35
|
//# sourceMappingURL=useDictionary.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionary.d.ts","names":[],"sources":["../../../src/client/useDictionary.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"useDictionary.d.ts","names":[],"sources":["../../../src/client/useDictionary.ts"],"mappings":";;;;;KAgBY,YAAA,MAAkB,CAAA;;AAA9B;;;;;;;;;;EAYE,QAAA,GAAW,QAAA,GAAW,OAAA,mBAA0B,YAAA,CAAa,CAAA;AAAA;;;;;;AAe/D;;;;;;;cAAa,aAAA,mBACK,UAAA,GAAa,wBAAA,kBAEzB,aAAA,GACA,0BAAA,CAA2B,CAAA,IAAK,eAAA,EAEpC,UAAA,EAAY,CAAA,EACZ,gBAAA,GAAmB,CAAA,KAClB,YAAA,CACD,oBAAA,CACE,iCAAA,CAAkC,CAAA,EAAG,CAAA,GACrC,qBAAA,CAAsB,CAAA"}
|
|
@@ -1,40 +1,24 @@
|
|
|
1
1
|
import { DeepTransformContent } from "../plugins.js";
|
|
2
2
|
import { WithOnChange } from "./useDictionary.js";
|
|
3
|
-
import { DictionaryKeys, LocalesValues, StrictModeLocaleMap } from "@intlayer/types/module_augmentation";
|
|
3
|
+
import { DictionaryKeys, DictionarySelectorForKey, LocalesValues, StrictModeLocaleMap } from "@intlayer/types/module_augmentation";
|
|
4
4
|
import { Dictionary } from "@intlayer/types/dictionary";
|
|
5
|
+
import { QualifiedDynamicLoaderMap } from "@intlayer/core/dictionaryManipulator";
|
|
5
6
|
|
|
6
7
|
//#region src/client/useDictionaryDynamic.d.ts
|
|
7
8
|
/**
|
|
8
|
-
* Dynamically load and transform a
|
|
9
|
+
* Dynamically load and transform a dictionary (plain or qualified).
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* content. Subsequent calls for the same locale return immediately from cache.
|
|
11
|
+
* For a qualified loader map (collection / variant / meta record, possibly
|
|
12
|
+
* combined), only the chunk(s) the selector targets are loaded. For a plain
|
|
13
|
+
* loader map, the locale chunk is loaded. The first call returns a placeholder
|
|
14
|
+
* and triggers a background load; the client then notifies subscribers so the
|
|
15
|
+
* render runs again with real content.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
* render, real content after the locale bundle loads.
|
|
19
|
-
*
|
|
20
|
-
* @param dictionaryLoaders - Locale-keyed map of `() => Promise<Dictionary>`.
|
|
17
|
+
* @param dictionaryLoaders - Locale-keyed loader map, or a qualified loader map.
|
|
21
18
|
* @param key - Dictionary key (used for cache namespacing).
|
|
22
|
-
* @param
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```ts
|
|
26
|
-
* import dynDic from '../.intlayer/dynamic_dictionary/app.mjs';
|
|
27
|
-
*
|
|
28
|
-
* const render = () => {
|
|
29
|
-
* const content = useDictionaryDynamic(dynDic, 'app');
|
|
30
|
-
* document.querySelector('h1')!.textContent = String(content.title);
|
|
31
|
-
* };
|
|
32
|
-
*
|
|
33
|
-
* render();
|
|
34
|
-
* getIntlayerClient().subscribe(() => render());
|
|
35
|
-
* ```
|
|
19
|
+
* @param localeOrSelector - Optional locale or selector.
|
|
36
20
|
*/
|
|
37
|
-
declare const useDictionaryDynamic: <const T extends Dictionary, const K extends DictionaryKeys, const
|
|
21
|
+
declare const useDictionaryDynamic: <const T extends Dictionary, const K extends DictionaryKeys, const A extends LocalesValues | DictionarySelectorForKey<K> = LocalesValues>(dictionaryLoaders: StrictModeLocaleMap<() => Promise<T>> | QualifiedDynamicLoaderMap, key: K, localeOrSelector?: A) => WithOnChange<DeepTransformContent<T["content"]>>;
|
|
38
22
|
//#endregion
|
|
39
23
|
export { useDictionaryDynamic };
|
|
40
24
|
//# sourceMappingURL=useDictionaryDynamic.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryDynamic.d.ts","names":[],"sources":["../../../src/client/useDictionaryDynamic.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useDictionaryDynamic.d.ts","names":[],"sources":["../../../src/client/useDictionaryDynamic.ts"],"mappings":";;;;;;;;;AA2EA;;;;;;;;;;;cAAa,oBAAA,mBACK,UAAA,kBACA,cAAA,kBACA,aAAA,GAAgB,wBAAA,CAAyB,CAAA,IAAK,aAAA,EAE9D,iBAAA,EACI,mBAAA,OAA0B,OAAA,CAAQ,CAAA,KAClC,yBAAA,EACJ,GAAA,EAAK,CAAA,EACL,gBAAA,GAAmB,CAAA,KAClB,YAAA,CAAa,oBAAA,CAAqB,CAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DeepTransformContent } from "../plugins.js";
|
|
2
2
|
import { WithOnChange } from "./useDictionary.js";
|
|
3
|
-
import { DictionaryKeys,
|
|
3
|
+
import { DeclaredLocales, DictionaryKeys, DictionaryRegistryResult, DictionarySelectorForKey, ExtractSelectorLocale, LocalesValues } from "@intlayer/types/module_augmentation";
|
|
4
4
|
|
|
5
5
|
//#region src/client/useIntlayer.d.ts
|
|
6
6
|
/**
|
|
@@ -8,28 +8,17 @@ import { DictionaryKeys, DictionaryRegistryContent, LocalesValues } from "@intla
|
|
|
8
8
|
* locale changes via the chainable `.onChange()` method — mirroring the API
|
|
9
9
|
* of `react-intlayer`'s `useIntlayer`.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* The second argument is either a locale or a selector object:
|
|
12
|
+
* - `{ item: 2 }` — collection item (omit `item` to get every item as array)
|
|
13
|
+
* - `{ variant: 'black-friday' }` — named variant (omit for the `default` one)
|
|
14
|
+
* - `{ id: 'prod_abc', ...metaFields }` — meta record
|
|
15
|
+
* - `locale` composes with any selector and overrides the current locale
|
|
15
16
|
*
|
|
16
17
|
* The function returns the current content **directly** (same shape as
|
|
17
|
-
* `getIntlayer(key)`), plus the `.onChange()` helper
|
|
18
|
+
* `getIntlayer(key)`), plus the `.onChange()` helper.
|
|
18
19
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* const content = useIntlayer('app');
|
|
22
|
-
*
|
|
23
|
-
* // Vanilla — identical surface API, opt-in reactivity via .onChange()
|
|
24
|
-
* const content = useIntlayer('app');
|
|
25
|
-
* const content = useIntlayer('app').onChange((c) => render(c));
|
|
26
|
-
* ```
|
|
27
|
-
*
|
|
28
|
-
* For cleanup (e.g. Vite HMR), subscribe via `getIntlayerClient().subscribe()`
|
|
29
|
-
* and hold the returned unsubscribe function.
|
|
30
|
-
*
|
|
31
|
-
* @param key - Dictionary key registered in your intlayer content files.
|
|
32
|
-
* @param locale - Optional locale override (defaults to the current app locale).
|
|
20
|
+
* @param key - Dictionary key registered in your intlayer content files.
|
|
21
|
+
* @param localeOrSelector - Optional locale or selector.
|
|
33
22
|
* @returns The current translated content with an `.onChange()` method.
|
|
34
23
|
*
|
|
35
24
|
* @example
|
|
@@ -38,17 +27,11 @@ import { DictionaryKeys, DictionaryRegistryContent, LocalesValues } from "@intla
|
|
|
38
27
|
*
|
|
39
28
|
* installIntlayer();
|
|
40
29
|
*
|
|
41
|
-
* // Static read (no subscription)
|
|
42
30
|
* const content = useIntlayer('homepage');
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* // Reactive read — onChange is called on every locale change
|
|
46
|
-
* useIntlayer('homepage').onChange((c) => {
|
|
47
|
-
* document.querySelector('h1').textContent = String(c.title);
|
|
48
|
-
* });
|
|
31
|
+
* const faq2 = useIntlayer('faq', { item: 2 });
|
|
49
32
|
* ```
|
|
50
33
|
*/
|
|
51
|
-
declare const useIntlayer: <const T extends DictionaryKeys>(key: T,
|
|
34
|
+
declare const useIntlayer: <const T extends DictionaryKeys, const A extends LocalesValues | DictionarySelectorForKey<T> = DeclaredLocales>(key: T, localeOrSelector?: A) => WithOnChange<DeepTransformContent<DictionaryRegistryResult<T, A>, ExtractSelectorLocale<A>>>;
|
|
52
35
|
//#endregion
|
|
53
36
|
export { useIntlayer };
|
|
54
37
|
//# sourceMappingURL=useIntlayer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useIntlayer.d.ts","names":[],"sources":["../../../src/client/useIntlayer.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"useIntlayer.d.ts","names":[],"sources":["../../../src/client/useIntlayer.ts"],"mappings":";;;;;;;AA0CA;;;;;;;;;;;;;;;;;;;;;;;;;;cAAa,WAAA,mBACK,cAAA,kBACA,aAAA,GAAgB,wBAAA,CAAyB,CAAA,IAAK,eAAA,EAE9D,GAAA,EAAK,CAAA,EACL,gBAAA,GAAmB,CAAA,KAClB,YAAA,CACD,oBAAA,CAAqB,wBAAA,CAAyB,CAAA,EAAG,CAAA,GAAI,qBAAA,CAAsB,CAAA"}
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { DeepTransformContent } from "./plugins.js";
|
|
2
|
-
import { DeclaredLocales, LocalesValues } from "@intlayer/types/module_augmentation";
|
|
3
|
-
import { Dictionary } from "@intlayer/types/dictionary";
|
|
2
|
+
import { DeclaredLocales, ExtractSelectorLocale, LocalesValues } from "@intlayer/types/module_augmentation";
|
|
3
|
+
import { Dictionary, DictionarySelectorForGroup, QualifiedDictionaryGroup, ResolveQualifiedDictionaryContent } from "@intlayer/types/dictionary";
|
|
4
4
|
|
|
5
5
|
//#region src/getDictionary.d.ts
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Transforms a dictionary (or qualified dictionary group) and returns its
|
|
8
|
+
* content for the given locale or selector (`{ item }`, `{ variant }`,
|
|
9
|
+
* `{ id, ...meta }`, optionally combined with `locale`).
|
|
10
|
+
*/
|
|
11
|
+
declare const getDictionary: <const T extends Dictionary | QualifiedDictionaryGroup, const A extends LocalesValues | DictionarySelectorForGroup<T> = DeclaredLocales>(dictionary: T, localeOrSelector?: A) => DeepTransformContent<ResolveQualifiedDictionaryContent<T, A>, ExtractSelectorLocale<A>>;
|
|
7
12
|
//#endregion
|
|
8
13
|
export { getDictionary };
|
|
9
14
|
//# sourceMappingURL=getDictionary.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDictionary.d.ts","names":[],"sources":["../../src/getDictionary.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"getDictionary.d.ts","names":[],"sources":["../../src/getDictionary.ts"],"mappings":";;;;;;;AAoBA;;;cAAa,aAAA,mBACK,UAAA,GAAa,wBAAA,kBAEzB,aAAA,GACA,0BAAA,CAA2B,CAAA,IAAK,eAAA,EAEpC,UAAA,EAAY,CAAA,EACZ,gBAAA,GAAmB,CAAA,KAClB,oBAAA,CACD,iCAAA,CAAkC,CAAA,EAAG,CAAA,GACrC,qBAAA,CAAsB,CAAA"}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import { DeepTransformContent } from "./plugins.js";
|
|
2
|
-
import { DeclaredLocales, DictionaryKeys,
|
|
2
|
+
import { DeclaredLocales, DictionaryKeys, DictionaryRegistryResult, DictionarySelectorForKey, ExtractSelectorLocale, LocalesValues } from "@intlayer/types/module_augmentation";
|
|
3
3
|
|
|
4
4
|
//#region src/getIntlayer.d.ts
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Picks one dictionary by its key and returns its content for the given
|
|
7
|
+
* locale or selector (`{ item }`, `{ variant }`, `{ id, ...meta }`,
|
|
8
|
+
* optionally combined with `locale`).
|
|
9
|
+
*/
|
|
10
|
+
declare const getIntlayer: <const T extends DictionaryKeys, const A extends LocalesValues | DictionarySelectorForKey<T> = DeclaredLocales>(key: T, localeOrSelector?: A) => DeepTransformContent<DictionaryRegistryResult<T, A>, ExtractSelectorLocale<A>>;
|
|
6
11
|
//#endregion
|
|
7
12
|
export { getIntlayer };
|
|
8
13
|
//# sourceMappingURL=getIntlayer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getIntlayer.d.ts","names":[],"sources":["../../src/getIntlayer.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"getIntlayer.d.ts","names":[],"sources":["../../src/getIntlayer.ts"],"mappings":";;;;;;AAiBA;;;cAAa,WAAA,mBACK,cAAA,kBACA,aAAA,GAAgB,wBAAA,CAAyB,CAAA,IAAK,eAAA,EAE9D,GAAA,EAAK,CAAA,EACL,gBAAA,GAAmB,CAAA,KAClB,oBAAA,CACD,wBAAA,CAAyB,CAAA,EAAG,CAAA,GAC5B,qBAAA,CAAsB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vanilla-intlayer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0-canary.0",
|
|
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,14 +101,14 @@
|
|
|
101
101
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
102
102
|
},
|
|
103
103
|
"dependencies": {
|
|
104
|
-
"@intlayer/api": "
|
|
105
|
-
"@intlayer/config": "
|
|
106
|
-
"@intlayer/core": "
|
|
107
|
-
"@intlayer/editor": "
|
|
108
|
-
"@intlayer/types": "
|
|
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"
|
|
109
109
|
},
|
|
110
110
|
"devDependencies": {
|
|
111
|
-
"@types/node": "25.9.
|
|
111
|
+
"@types/node": "25.9.3",
|
|
112
112
|
"@utils/ts-config": "1.0.4",
|
|
113
113
|
"@utils/ts-config-types": "1.0.4",
|
|
114
114
|
"@utils/tsdown-config": "1.0.4",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
"vitest": "4.1.8"
|
|
119
119
|
},
|
|
120
120
|
"peerDependencies": {
|
|
121
|
-
"intlayer": "
|
|
121
|
+
"intlayer": "9.0.0-canary.0"
|
|
122
122
|
},
|
|
123
123
|
"peerDependenciesMeta": {
|
|
124
124
|
"intlayer": {
|