react-intlayer 9.3.2 → 9.4.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/README.md +1 -1
- package/dist/cjs/analytics/useAnalytics.cjs +4 -4
- package/dist/cjs/analytics/useAnalytics.cjs.map +1 -1
- package/dist/cjs/client/useDictionaryDynamic.cjs +2 -0
- package/dist/cjs/client/useDictionaryDynamic.cjs.map +1 -1
- package/dist/cjs/client/useLoadDynamic.cjs +32 -5
- package/dist/cjs/client/useLoadDynamic.cjs.map +1 -1
- package/dist/cjs/server/IntlayerServerProvider.cjs +28 -0
- package/dist/cjs/server/IntlayerServerProvider.cjs.map +1 -1
- package/dist/cjs/server/index.cjs +5 -0
- package/dist/cjs/server/serverContext.cjs.map +1 -1
- package/dist/esm/analytics/useAnalytics.mjs +4 -4
- package/dist/esm/analytics/useAnalytics.mjs.map +1 -1
- package/dist/esm/client/useDictionaryDynamic.mjs +3 -1
- package/dist/esm/client/useDictionaryDynamic.mjs.map +1 -1
- package/dist/esm/client/useLoadDynamic.mjs +32 -6
- package/dist/esm/client/useLoadDynamic.mjs.map +1 -1
- package/dist/esm/server/IntlayerServerProvider.mjs +27 -1
- package/dist/esm/server/IntlayerServerProvider.mjs.map +1 -1
- package/dist/esm/server/index.mjs +3 -2
- package/dist/esm/server/serverContext.mjs.map +1 -1
- package/dist/types/analytics/useAnalytics.d.ts +4 -4
- package/dist/types/client/useDictionaryDynamic.d.ts.map +1 -1
- package/dist/types/client/useLoadDynamic.d.ts +21 -1
- package/dist/types/client/useLoadDynamic.d.ts.map +1 -1
- package/dist/types/server/IntlayerServerProvider.d.ts +26 -29
- package/dist/types/server/IntlayerServerProvider.d.ts.map +1 -1
- package/dist/types/server/index.d.ts +3 -2
- package/dist/types/server/serverContext.d.ts +1 -1
- package/dist/types/server/serverContext.d.ts.map +1 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -327,4 +327,4 @@ Contribute on [GitHub](https://github.com/aymericzip/intlayer), [GitLab](https:/
|
|
|
327
327
|
|
|
328
328
|
If you like Intlayer, give us a ⭐ on GitHub. It helps others discover the project! [See why GitHub Stars matter](https://github.com/aymericzip/intlayer/blob/main/CONTRIBUTING.md#why-github-stars-matter-).
|
|
329
329
|
|
|
330
|
-
[](https://star-history.dera.page/#aymericzip/intlayer&Date)
|
|
@@ -12,10 +12,10 @@ let _intlayer_analytics_isEnabled = require("@intlayer/analytics/isEnabled");
|
|
|
12
12
|
* and keeps it aware of the current locale.
|
|
13
13
|
*
|
|
14
14
|
* Mirrors {@link useEditor}: the module is loaded via a dynamic `import()` so it
|
|
15
|
-
* ships as its own async chunk, off the critical rendering path. Apps that
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* time.
|
|
15
|
+
* ships as its own async chunk, off the critical rendering path. Apps that opt
|
|
16
|
+
* out (`analytics.enabled !== true`), or that never install
|
|
17
|
+
* `@intlayer/analytics`, pay nothing — the whole body is guarded by
|
|
18
|
+
* `INTLAYER_ANALYTICS_ENABLED` and dead-code-eliminated at build time.
|
|
19
19
|
*/
|
|
20
20
|
const useAnalytics = () => {
|
|
21
21
|
const { locale } = (0, react.useContext)(require_client_IntlayerProvider.IntlayerClientContext) ?? {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAnalytics.cjs","names":["useContext","IntlayerClientContext","useRef","isEnabled"],"sources":["../../../src/analytics/useAnalytics.tsx"],"sourcesContent":["'use client';\n\nimport type { AnalyticsClient } from '@intlayer/analytics';\nimport { isEnabled } from '@intlayer/analytics/isEnabled';\nimport { useContext, useEffect, useRef } from 'react';\nimport { IntlayerClientContext } from '../client/IntlayerProvider';\nimport { setExposureSink } from './exposureSink';\n\n/**\n * Initializes the Intlayer analytics client singleton when analytics is enabled\n * and keeps it aware of the current locale.\n *\n * Mirrors {@link useEditor}: the module is loaded via a dynamic `import()` so it\n * ships as its own async chunk, off the critical rendering path. Apps that\n *
|
|
1
|
+
{"version":3,"file":"useAnalytics.cjs","names":["useContext","IntlayerClientContext","useRef","isEnabled"],"sources":["../../../src/analytics/useAnalytics.tsx"],"sourcesContent":["'use client';\n\nimport type { AnalyticsClient } from '@intlayer/analytics';\nimport { isEnabled } from '@intlayer/analytics/isEnabled';\nimport { useContext, useEffect, useRef } from 'react';\nimport { IntlayerClientContext } from '../client/IntlayerProvider';\nimport { setExposureSink } from './exposureSink';\n\n/**\n * Initializes the Intlayer analytics client singleton when analytics is enabled\n * and keeps it aware of the current locale.\n *\n * Mirrors {@link useEditor}: the module is loaded via a dynamic `import()` so it\n * ships as its own async chunk, off the critical rendering path. Apps that opt\n * out (`analytics.enabled !== true`), or that never install\n * `@intlayer/analytics`, pay nothing — the whole body is guarded by\n * `INTLAYER_ANALYTICS_ENABLED` and dead-code-eliminated at build time.\n */\nexport const useAnalytics = () => {\n const { locale } = useContext(IntlayerClientContext) ?? {};\n const clientRef = useRef<AnalyticsClient | null>(null);\n\n useEffect(() => {\n if (process.env.INTLAYER_ANALYTICS_ENABLED === 'false' || !isEnabled) {\n return;\n }\n\n let cancelled = false;\n // Tracks whether initAnalyticsClient actually ran, so cleanup never calls\n // stopAnalyticsClient for an init that was cancelled — that would decrement\n // the shared reference count once too many and could stop a client another\n // provider still uses.\n let initialized = false;\n\n import('@intlayer/analytics')\n .then(({ initAnalyticsClient, buildContentExposure }) => {\n if (cancelled) return;\n\n const client = initAnalyticsClient();\n initialized = true;\n clientRef.current = client;\n\n if (locale) client.setLocale(locale);\n client.trackPageView({ reason: 'initial' });\n\n // Route node-level exposures (from the interpreter plugins) into the\n // client. Serialization happens here, off the hot render path.\n setExposureSink((input) =>\n client.trackContentExposure(buildContentExposure(input))\n );\n })\n .catch(() => {\n /* chunk failed to load — analytics stays a no-op */\n });\n\n return () => {\n cancelled = true;\n clientRef.current = null;\n setExposureSink(null);\n import('@intlayer/analytics')\n .then(({ stopAnalyticsClient }) => {\n if (initialized) stopAnalyticsClient();\n })\n .catch(() => {});\n };\n // Run once on mount; locale updates are handled by the effect below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (!locale || !clientRef.current) return;\n\n clientRef.current.setLocale(locale);\n clientRef.current.trackPageView({ reason: 'locale_change' });\n }, [locale]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,MAAa,qBAAqB;CAChC,MAAM,EAAE,eAAWA,kBAAWC,qDAAqB,KAAK,CAAC;CACzD,MAAM,gBAAYC,cAA+B,IAAI;CAErD,2BAAgB;EACd,IAAI,QAAQ,IAAI,+BAA+B,WAAW,CAACC,yCACzD;EAGF,IAAI,YAAY;EAKhB,IAAI,cAAc;EAElB,OAAO,sBAAsB,CAC1B,MAAM,EAAE,qBAAqB,2BAA2B;GACvD,IAAI,WAAW;GAEf,MAAM,SAAS,oBAAoB;GACnC,cAAc;GACd,UAAU,UAAU;GAEpB,IAAI,QAAQ,OAAO,UAAU,MAAM;GACnC,OAAO,cAAc,EAAE,QAAQ,UAAU,CAAC;GAI1C,gDAAiB,UACf,OAAO,qBAAqB,qBAAqB,KAAK,CAAC,CACzD;EACF,CAAC,CAAC,CACD,YAAY,CAEb,CAAC;EAEH,aAAa;GACX,YAAY;GACZ,UAAU,UAAU;GACpB,+CAAgB,IAAI;GACpB,OAAO,sBAAsB,CAC1B,MAAM,EAAE,0BAA0B;IACjC,IAAI,aAAa,oBAAoB;GACvC,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;EACnB;CAGF,GAAG,CAAC,CAAC;CAEL,2BAAgB;EACd,IAAI,CAAC,UAAU,CAAC,UAAU,SAAS;EAEnC,UAAU,QAAQ,UAAU,MAAM;EAClC,UAAU,QAAQ,cAAc,EAAE,QAAQ,gBAAgB,CAAC;CAC7D,GAAG,CAAC,MAAM,CAAC;AACb"}
|
|
@@ -40,6 +40,8 @@ const useDictionaryDynamic = (dictionaryPromise, key, localeOrSelector) => {
|
|
|
40
40
|
loadChunk: (cacheKey, promise) => require_client_useLoadDynamic.useLoadDynamic(cacheKey, promise),
|
|
41
41
|
transform: (dictionary) => require_getDictionary.getDictionary(dictionary, localeTarget)
|
|
42
42
|
});
|
|
43
|
+
const preloadedDictionary = (0, _intlayer_core_dictionaryManipulator.getPreloadedDictionary)(dictionaryPromise, localeTarget);
|
|
44
|
+
if (preloadedDictionary) return require_getDictionary.getDictionary(preloadedDictionary, localeTarget);
|
|
43
45
|
const plainLoaders = dictionaryPromise;
|
|
44
46
|
const dictionary = require_client_useLoadDynamic.useLoadDynamic(`${String(key)}.${localeTarget}`, plainLoaders[localeTarget]?.());
|
|
45
47
|
return require_getDictionary.getDictionary(dictionary, localeTarget);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryDynamic.cjs","names":["useContext","IntlayerClientContext","parseDictionarySelector","resolveDictionaryArgument","internationalization","isQualifiedDynamicLoaderMap","resolveQualifiedDynamicContent","loadDynamicChunk","getDictionary"],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["'use client';\n\nimport { internationalization } from '@intlayer/config/built';\nimport {\n isQualifiedDynamicLoaderMap,\n parseDictionarySelector,\n type QualifiedDynamicLoaderMap,\n resolveDictionaryArgument,\n resolveQualifiedDynamicContent,\n} from '@intlayer/core/dictionaryManipulator';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionarySelectorForKey,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useContext } from 'react';\nimport { getDictionary } from '../getDictionary';\nimport { IntlayerClientContext } from './IntlayerProvider';\n// `useLoadDynamic` is a suspender cache, not a React hook — aliased to a\n// non-hook name so it can be invoked in loops / conditionally (e.g. when a\n// collection loads several chunks at once).\nimport { useLoadDynamic as loadDynamicChunk } from './useLoadDynamic';\n\n/**\n * Client-side hook that lazily loads a dictionary and returns its content.\n *\n * The dictionary entry is either a plain dynamic loader map\n * (`locale → loader`) or a qualified one (`locale → qualifierId → loader`,\n * tagged with the qualifier dimension). For qualified maps, only the chunk(s)\n * the selector targets are loaded; the resolution mirrors static mode.\n *\n * If the locale is not provided (directly or through the selector), the client\n * context locale is used.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<K> = DeclaredLocales,\n>(\n dictionaryPromise:\n | StrictModeLocaleMap<() => Promise<T>>\n | QualifiedDynamicLoaderMap,\n key: K,\n localeOrSelector?: A\n) => {\n const { locale: currentLocale, variant: contextVariant } =\n useContext(IntlayerClientContext) ?? {};\n\n const { locale: selectorLocale, selector } =\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false'\n ? parseDictionarySelector<LocalesValues>(\n // Layers the provider's ambient variant under the call-site argument\n // before the chunk walk, so only the targeted chunk is loaded.\n resolveDictionaryArgument({\n localeOrSelector,\n contextLocale: currentLocale,\n contextVariant,\n dictionaryKey: String(key),\n })\n )\n : {\n locale: localeOrSelector as LocalesValues | undefined,\n selector: undefined,\n };\n\n const localeTarget =\n selectorLocale ?? currentLocale ?? internationalization.defaultLocale;\n\n if (\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false' &&\n isQualifiedDynamicLoaderMap(dictionaryPromise)\n ) {\n return resolveQualifiedDynamicContent({\n loaderMap: dictionaryPromise,\n key: String(key),\n locale: localeTarget,\n selector,\n loadChunk: (cacheKey, promise) => loadDynamicChunk(cacheKey, promise),\n transform: (dictionary) => getDictionary(dictionary, localeTarget),\n });\n }\n\n const plainLoaders = dictionaryPromise as StrictModeLocaleMap<\n () => Promise<T>\n >;\n\n const dictionary = loadDynamicChunk<T>(\n `${String(key)}.${localeTarget}`,\n plainLoaders[localeTarget as keyof typeof plainLoaders]?.() as Promise<T>\n );\n\n return getDictionary(dictionary, localeTarget);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"useDictionaryDynamic.cjs","names":["useContext","IntlayerClientContext","parseDictionarySelector","resolveDictionaryArgument","internationalization","isQualifiedDynamicLoaderMap","resolveQualifiedDynamicContent","loadDynamicChunk","getDictionary","getPreloadedDictionary"],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["'use client';\n\nimport { internationalization } from '@intlayer/config/built';\nimport {\n getPreloadedDictionary,\n isQualifiedDynamicLoaderMap,\n parseDictionarySelector,\n type QualifiedDynamicLoaderMap,\n resolveDictionaryArgument,\n resolveQualifiedDynamicContent,\n} from '@intlayer/core/dictionaryManipulator';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionarySelectorForKey,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useContext } from 'react';\nimport { getDictionary } from '../getDictionary';\nimport { IntlayerClientContext } from './IntlayerProvider';\n// `useLoadDynamic` is a suspender cache, not a React hook — aliased to a\n// non-hook name so it can be invoked in loops / conditionally (e.g. when a\n// collection loads several chunks at once).\nimport { useLoadDynamic as loadDynamicChunk } from './useLoadDynamic';\n\n/**\n * Client-side hook that lazily loads a dictionary and returns its content.\n *\n * The dictionary entry is either a plain dynamic loader map\n * (`locale → loader`) or a qualified one (`locale → qualifierId → loader`,\n * tagged with the qualifier dimension). For qualified maps, only the chunk(s)\n * the selector targets are loaded; the resolution mirrors static mode.\n *\n * If the locale is not provided (directly or through the selector), the client\n * context locale is used.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<K> = DeclaredLocales,\n>(\n dictionaryPromise:\n | StrictModeLocaleMap<() => Promise<T>>\n | QualifiedDynamicLoaderMap,\n key: K,\n localeOrSelector?: A\n) => {\n const { locale: currentLocale, variant: contextVariant } =\n useContext(IntlayerClientContext) ?? {};\n\n const { locale: selectorLocale, selector } =\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false'\n ? parseDictionarySelector<LocalesValues>(\n // Layers the provider's ambient variant under the call-site argument\n // before the chunk walk, so only the targeted chunk is loaded.\n resolveDictionaryArgument({\n localeOrSelector,\n contextLocale: currentLocale,\n contextVariant,\n dictionaryKey: String(key),\n })\n )\n : {\n locale: localeOrSelector as LocalesValues | undefined,\n selector: undefined,\n };\n\n const localeTarget =\n selectorLocale ?? currentLocale ?? internationalization.defaultLocale;\n\n if (\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false' &&\n isQualifiedDynamicLoaderMap(dictionaryPromise)\n ) {\n return resolveQualifiedDynamicContent({\n loaderMap: dictionaryPromise,\n key: String(key),\n locale: localeTarget,\n selector,\n loadChunk: (cacheKey, promise) => loadDynamicChunk(cacheKey, promise),\n transform: (dictionary) => getDictionary(dictionary, localeTarget),\n });\n }\n\n // A build-tool plugin may have started this locale's chunk while the entry\n // point itself was evaluating, in which case the content is already here and\n // reading it must not go through the suspender — see `getPreloadedDictionary`.\n const preloadedDictionary = getPreloadedDictionary(\n dictionaryPromise,\n localeTarget\n );\n if (preloadedDictionary) {\n return getDictionary(preloadedDictionary as T, localeTarget);\n }\n\n const plainLoaders = dictionaryPromise as StrictModeLocaleMap<\n () => Promise<T>\n >;\n\n const dictionary = loadDynamicChunk<T>(\n `${String(key)}.${localeTarget}`,\n plainLoaders[localeTarget as keyof typeof plainLoaders]?.() as Promise<T>\n );\n\n return getDictionary(dictionary, localeTarget);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAsCA,MAAa,wBAKX,mBAGA,KACA,qBACG;CACH,MAAM,EAAE,QAAQ,eAAe,SAAS,uBACtCA,kBAAWC,qDAAqB,KAAK,CAAC;CAExC,MAAM,EAAE,QAAQ,gBAAgB,aAC9B,QAAQ,IAAI,iCAAiC,cACzCC,kEAGEC,gEAA0B;EACxB;EACA,eAAe;EACf;EACA,eAAe,OAAO,GAAG;CAC3B,CAAC,CACH,IACA;EACE,QAAQ;EACR,UAAU;CACZ;CAEN,MAAM,eACJ,kBAAkB,iBAAiBC,4CAAqB;CAE1D,IACE,QAAQ,IAAI,iCAAiC,eAC7CC,kEAA4B,iBAAiB,GAE7C,WAAOC,qEAA+B;EACpC,WAAW;EACX,KAAK,OAAO,GAAG;EACf,QAAQ;EACR;EACA,YAAY,UAAU,YAAYC,6CAAiB,UAAU,OAAO;EACpE,YAAY,eAAeC,oCAAc,YAAY,YAAY;CACnE,CAAC;CAMH,MAAM,0BAAsBC,6DAC1B,mBACA,YACF;CACA,IAAI,qBACF,OAAOD,oCAAc,qBAA0B,YAAY;CAG7D,MAAM,eAAe;CAIrB,MAAM,aAAaD,6CACjB,GAAG,OAAO,GAAG,EAAE,GAAG,gBAClB,aAAa,aAA0C,GAAG,CAC5D;CAEA,OAAOC,oCAAc,YAAY,YAAY;AAC/C"}
|
|
@@ -10,18 +10,45 @@ const createSuspender = (promise) => {
|
|
|
10
10
|
status = "error";
|
|
11
11
|
result = e;
|
|
12
12
|
});
|
|
13
|
-
return {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
return {
|
|
14
|
+
settled: suspender,
|
|
15
|
+
read() {
|
|
16
|
+
if (status === "pending") throw suspender;
|
|
17
|
+
if (status === "error") throw result;
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
18
21
|
};
|
|
19
22
|
const cache = /* @__PURE__ */ new Map();
|
|
20
23
|
const useLoadDynamic = (key, promise) => {
|
|
21
24
|
if (!cache.has(key)) cache.set(key, createSuspender(promise));
|
|
22
25
|
return cache.get(key).read();
|
|
23
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* Fills the same cache {@link useLoadDynamic} reads, ahead of render.
|
|
29
|
+
*
|
|
30
|
+
* A component that reads a dictionary during render suspends whenever the entry
|
|
31
|
+
* is still `pending`, and the nearest boundary shows its fallback. Awaiting this
|
|
32
|
+
* before the render — in a router loader, or during app startup — makes that
|
|
33
|
+
* read synchronous, so no boundary ever falls back.
|
|
34
|
+
*
|
|
35
|
+
* Handing over an already-resolved promise is not enough on its own:
|
|
36
|
+
* {@link createSuspender} only leaves `pending` inside a `.then` callback, so
|
|
37
|
+
* the first read would still suspend for one microtask. Awaiting the returned
|
|
38
|
+
* promise resolves that race, because the callback registered by
|
|
39
|
+
* `createSuspender` runs before this one.
|
|
40
|
+
*
|
|
41
|
+
* @param key - Cache key, identical to the one the later read uses.
|
|
42
|
+
* @param loader - Invoked only when the key is not cached yet, so preloading a
|
|
43
|
+
* dictionary twice never issues a second request.
|
|
44
|
+
* @returns A promise that settles — never rejects — once the entry is readable.
|
|
45
|
+
*/
|
|
46
|
+
const preloadDynamic = (key, loader) => {
|
|
47
|
+
if (!cache.has(key)) cache.set(key, createSuspender(loader()));
|
|
48
|
+
return cache.get(key).settled;
|
|
49
|
+
};
|
|
24
50
|
|
|
25
51
|
//#endregion
|
|
52
|
+
exports.preloadDynamic = preloadDynamic;
|
|
26
53
|
exports.useLoadDynamic = useLoadDynamic;
|
|
27
54
|
//# sourceMappingURL=useLoadDynamic.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLoadDynamic.cjs","names":[],"sources":["../../../src/client/useLoadDynamic.ts"],"sourcesContent":["type Status = 'pending' | 'success' | 'error';\n\nconst createSuspender = <T>(promise: Promise<T>) => {\n let status: Status = 'pending';\n let result: T;\n const suspender = promise.then(\n (r) => {\n status = 'success';\n result = r;\n },\n (e) => {\n status = 'error';\n result = e as any;\n }\n );\n\n return {\n read() {\n if (status === 'pending') throw suspender;\n if (status === 'error') throw result;\n return result!;\n },\n };\n};\n\nconst cache = new Map<string,
|
|
1
|
+
{"version":3,"file":"useLoadDynamic.cjs","names":[],"sources":["../../../src/client/useLoadDynamic.ts"],"sourcesContent":["type Status = 'pending' | 'success' | 'error';\n\ntype Suspender<T> = {\n /**\n * Settles once the entry has left `pending`, never rejecting. Awaiting it\n * guarantees a subsequent {@link Suspender.read} returns without suspending.\n */\n settled: Promise<void>;\n read: () => T;\n};\n\nconst createSuspender = <T>(promise: Promise<T>): Suspender<T> => {\n let status: Status = 'pending';\n let result: T;\n const suspender = promise.then(\n (r) => {\n status = 'success';\n result = r;\n },\n (e) => {\n status = 'error';\n result = e as any;\n }\n );\n\n return {\n settled: suspender,\n read() {\n if (status === 'pending') throw suspender;\n if (status === 'error') throw result;\n return result!;\n },\n };\n};\n\nconst cache = new Map<string, Suspender<unknown>>();\n\nexport const useLoadDynamic = <T>(key: string, promise: Promise<T>): T => {\n if (!cache.has(key)) {\n cache.set(key, createSuspender(promise));\n }\n\n return (cache.get(key)! as Suspender<T>).read() as T;\n};\n\n/**\n * Fills the same cache {@link useLoadDynamic} reads, ahead of render.\n *\n * A component that reads a dictionary during render suspends whenever the entry\n * is still `pending`, and the nearest boundary shows its fallback. Awaiting this\n * before the render — in a router loader, or during app startup — makes that\n * read synchronous, so no boundary ever falls back.\n *\n * Handing over an already-resolved promise is not enough on its own:\n * {@link createSuspender} only leaves `pending` inside a `.then` callback, so\n * the first read would still suspend for one microtask. Awaiting the returned\n * promise resolves that race, because the callback registered by\n * `createSuspender` runs before this one.\n *\n * @param key - Cache key, identical to the one the later read uses.\n * @param loader - Invoked only when the key is not cached yet, so preloading a\n * dictionary twice never issues a second request.\n * @returns A promise that settles — never rejects — once the entry is readable.\n */\nexport const preloadDynamic = <T>(\n key: string,\n loader: () => Promise<T>\n): Promise<void> => {\n if (!cache.has(key)) {\n cache.set(key, createSuspender(loader()) as Suspender<unknown>);\n }\n\n return cache.get(key)!.settled;\n};\n"],"mappings":";;AAWA,MAAM,mBAAsB,YAAsC;CAChE,IAAI,SAAiB;CACrB,IAAI;CACJ,MAAM,YAAY,QAAQ,MACvB,MAAM;EACL,SAAS;EACT,SAAS;CACX,IACC,MAAM;EACL,SAAS;EACT,SAAS;CACX,CACF;CAEA,OAAO;EACL,SAAS;EACT,OAAO;GACL,IAAI,WAAW,WAAW,MAAM;GAChC,IAAI,WAAW,SAAS,MAAM;GAC9B,OAAO;EACT;CACF;AACF;AAEA,MAAM,wBAAQ,IAAI,IAAgC;AAElD,MAAa,kBAAqB,KAAa,YAA2B;CACxE,IAAI,CAAC,MAAM,IAAI,GAAG,GAChB,MAAM,IAAI,KAAK,gBAAgB,OAAO,CAAC;CAGzC,OAAQ,MAAM,IAAI,GAAG,CAAC,CAAmB,KAAK;AAChD;;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,kBACX,KACA,WACkB;CAClB,IAAI,CAAC,MAAM,IAAI,GAAG,GAChB,MAAM,IAAI,KAAK,gBAAgB,OAAO,CAAC,CAAuB;CAGhE,OAAO,MAAM,IAAI,GAAG,CAAC,CAAE;AACzB"}
|
|
@@ -25,6 +25,32 @@ const useIntlayer = () => require_server_serverContext.getServerContext(Intlayer
|
|
|
25
25
|
*/
|
|
26
26
|
const locale = require_server_serverContext.getServerContext(IntlayerServerContext);
|
|
27
27
|
/**
|
|
28
|
+
* Seeds the request-scoped server context locale imperatively — the equivalent
|
|
29
|
+
* of mounting {@link IntlayerServerProvider} without wrapping the tree.
|
|
30
|
+
*
|
|
31
|
+
* Useful in pages that must stay statically rendered while no ambient
|
|
32
|
+
* request-derived locale source is static-safe (Next.js < 16):
|
|
33
|
+
*
|
|
34
|
+
* ```tsx
|
|
35
|
+
* const Page = async ({ params }) => {
|
|
36
|
+
* const { locale } = await params;
|
|
37
|
+
* setLocale(locale);
|
|
38
|
+
* return <PageContent />;
|
|
39
|
+
* };
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
const setLocale = (locale) => {
|
|
43
|
+
IntlayerServerContext._storage().value = locale;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Seeds the request-scoped ambient variant imperatively — the equivalent of
|
|
47
|
+
* the `variant` prop of {@link IntlayerServerProvider} without wrapping the
|
|
48
|
+
* tree. See that prop for the accepted shapes.
|
|
49
|
+
*/
|
|
50
|
+
const setVariant = (variant) => {
|
|
51
|
+
IntlayerServerVariantContext._storage().value = variant;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
28
54
|
* Provider that store the current locale on the server side
|
|
29
55
|
*/
|
|
30
56
|
const IntlayerServerProvider = ({ children, locale = defaultLocale, variant }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(IntlayerServerContext.Provider, {
|
|
@@ -40,5 +66,7 @@ exports.IntlayerServerContext = IntlayerServerContext;
|
|
|
40
66
|
exports.IntlayerServerProvider = IntlayerServerProvider;
|
|
41
67
|
exports.IntlayerServerVariantContext = IntlayerServerVariantContext;
|
|
42
68
|
exports.locale = locale;
|
|
69
|
+
exports.setLocale = setLocale;
|
|
70
|
+
exports.setVariant = setVariant;
|
|
43
71
|
exports.useIntlayer = useIntlayer;
|
|
44
72
|
//# sourceMappingURL=IntlayerServerProvider.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntlayerServerProvider.cjs","names":["internationalization","createServerContext","getServerContext"],"sources":["../../../src/server/IntlayerServerProvider.tsx"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type {\n LocalesValues,\n ProviderVariant,\n} from '@intlayer/types/module_augmentation';\n\nimport type { FC, PropsWithChildren } from 'react';\nimport { createServerContext, getServerContext } from './serverContext';\n\nconst { defaultLocale } = internationalization ?? {};\n\n/**\n * Context that store the current locale on the server side\n */\nexport const IntlayerServerContext =\n createServerContext<LocalesValues>(defaultLocale);\n\n/**\n * Context that stores the ambient variant on the server side.\n *\n * Kept separate from {@link IntlayerServerContext} so the locale context keeps\n * its plain `LocalesValues` shape for the packages already reading it.\n */\nexport const IntlayerServerVariantContext =\n createServerContext<ProviderVariant>(undefined);\n\n/**\n * Hook that provides the current locale\n */\nexport const useIntlayer = () => getServerContext(IntlayerServerContext);\n\n/**\n * Get the current locale\n */\nexport const locale = getServerContext(IntlayerServerContext);\n\nexport type IntlayerServerProviderProps = PropsWithChildren & {\n locale?: LocalesValues;\n /**\n * Ambient variant applied to every dictionary read below this provider — for\n * a dimension resolved once per request (tenant, school type, plan tier…).\n *\n * Accepts a name (`'school1'`), an ordered preference chain\n * (`['school1', 'default']`), or a per-key map\n * (`{ key1: 'school1', default: 'base' }`). A call-site selector wins.\n */\n variant?: ProviderVariant;\n};\n\n/**\n * Provider that store the current locale on the server side\n */\nexport const IntlayerServerProvider: FC<IntlayerServerProviderProps> = ({\n children,\n locale = defaultLocale,\n variant,\n}) => (\n <IntlayerServerContext.Provider value={locale}>\n <IntlayerServerVariantContext.Provider value={variant}>\n {children}\n </IntlayerServerVariantContext.Provider>\n </IntlayerServerContext.Provider>\n);\n"],"mappings":";;;;;;AASA,MAAM,EAAE,kBAAkBA,+CAAwB,CAAC;;;;AAKnD,MAAa,wBACXC,iDAAmC,aAAa;;;;;;;AAQlD,MAAa,+BACXA,iDAAqC,MAAS;;;;AAKhD,MAAa,oBAAoBC,8CAAiB,qBAAqB;;;;AAKvE,MAAa,SAASA,8CAAiB,qBAAqB;;;;
|
|
1
|
+
{"version":3,"file":"IntlayerServerProvider.cjs","names":["internationalization","createServerContext","getServerContext"],"sources":["../../../src/server/IntlayerServerProvider.tsx"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type {\n LocalesValues,\n ProviderVariant,\n} from '@intlayer/types/module_augmentation';\n\nimport type { FC, PropsWithChildren } from 'react';\nimport { createServerContext, getServerContext } from './serverContext';\n\nconst { defaultLocale } = internationalization ?? {};\n\n/**\n * Context that store the current locale on the server side\n */\nexport const IntlayerServerContext =\n createServerContext<LocalesValues>(defaultLocale);\n\n/**\n * Context that stores the ambient variant on the server side.\n *\n * Kept separate from {@link IntlayerServerContext} so the locale context keeps\n * its plain `LocalesValues` shape for the packages already reading it.\n */\nexport const IntlayerServerVariantContext =\n createServerContext<ProviderVariant>(undefined);\n\n/**\n * Hook that provides the current locale\n */\nexport const useIntlayer = () => getServerContext(IntlayerServerContext);\n\n/**\n * Get the current locale\n */\nexport const locale = getServerContext(IntlayerServerContext);\n\n/**\n * Seeds the request-scoped server context locale imperatively — the equivalent\n * of mounting {@link IntlayerServerProvider} without wrapping the tree.\n *\n * Useful in pages that must stay statically rendered while no ambient\n * request-derived locale source is static-safe (Next.js < 16):\n *\n * ```tsx\n * const Page = async ({ params }) => {\n * const { locale } = await params;\n * setLocale(locale);\n * return <PageContent />;\n * };\n * ```\n */\nexport const setLocale = (locale: LocalesValues): void => {\n IntlayerServerContext._storage().value = locale;\n};\n\n/**\n * Seeds the request-scoped ambient variant imperatively — the equivalent of\n * the `variant` prop of {@link IntlayerServerProvider} without wrapping the\n * tree. See that prop for the accepted shapes.\n */\nexport const setVariant = (variant: ProviderVariant): void => {\n IntlayerServerVariantContext._storage().value = variant;\n};\n\nexport type IntlayerServerProviderProps = PropsWithChildren & {\n locale?: LocalesValues;\n /**\n * Ambient variant applied to every dictionary read below this provider — for\n * a dimension resolved once per request (tenant, school type, plan tier…).\n *\n * Accepts a name (`'school1'`), an ordered preference chain\n * (`['school1', 'default']`), or a per-key map\n * (`{ key1: 'school1', default: 'base' }`). A call-site selector wins.\n */\n variant?: ProviderVariant;\n};\n\n/**\n * Provider that store the current locale on the server side\n */\nexport const IntlayerServerProvider: FC<IntlayerServerProviderProps> = ({\n children,\n locale = defaultLocale,\n variant,\n}) => (\n <IntlayerServerContext.Provider value={locale}>\n <IntlayerServerVariantContext.Provider value={variant}>\n {children}\n </IntlayerServerVariantContext.Provider>\n </IntlayerServerContext.Provider>\n);\n"],"mappings":";;;;;;AASA,MAAM,EAAE,kBAAkBA,+CAAwB,CAAC;;;;AAKnD,MAAa,wBACXC,iDAAmC,aAAa;;;;;;;AAQlD,MAAa,+BACXA,iDAAqC,MAAS;;;;AAKhD,MAAa,oBAAoBC,8CAAiB,qBAAqB;;;;AAKvE,MAAa,SAASA,8CAAiB,qBAAqB;;;;;;;;;;;;;;;;AAiB5D,MAAa,aAAa,WAAgC;CACxD,sBAAsB,SAAS,CAAC,CAAC,QAAQ;AAC3C;;;;;;AAOA,MAAa,cAAc,YAAmC;CAC5D,6BAA6B,SAAS,CAAC,CAAC,QAAQ;AAClD;;;;AAkBA,MAAa,0BAA2D,EACtE,UACA,SAAS,eACT,cAEA,2CAAC,sBAAsB,UAAvB;CAAgC,OAAO;WACrC,2CAAC,6BAA6B,UAA9B;EAAuC,OAAO;EAC3C;CACoC;AACT"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_server_serverContext = require('./serverContext.cjs');
|
|
2
3
|
const require_server_IntlayerServerProvider = require('./IntlayerServerProvider.cjs');
|
|
3
4
|
const require_server_t = require('./t.cjs');
|
|
4
5
|
const require_server_useI18n = require('./useI18n.cjs');
|
|
@@ -12,7 +13,11 @@ const require_server_format_useIntl = require('./format/useIntl.cjs');
|
|
|
12
13
|
|
|
13
14
|
exports.IntlayerServer = require_server_IntlayerServerProvider.IntlayerServerContext;
|
|
14
15
|
exports.IntlayerServerProvider = require_server_IntlayerServerProvider.IntlayerServerProvider;
|
|
16
|
+
exports.IntlayerServerVariantContext = require_server_IntlayerServerProvider.IntlayerServerVariantContext;
|
|
17
|
+
exports.getServerContext = require_server_serverContext.getServerContext;
|
|
15
18
|
exports.locale = require_server_IntlayerServerProvider.locale;
|
|
19
|
+
exports.setLocale = require_server_IntlayerServerProvider.setLocale;
|
|
20
|
+
exports.setVariant = require_server_IntlayerServerProvider.setVariant;
|
|
16
21
|
exports.t = require_server_t.t;
|
|
17
22
|
exports.useDictionary = require_server_useDictionary.useDictionary;
|
|
18
23
|
exports.useDictionaryAsync = require_server_useDictionaryAsync.useDictionaryAsync;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverContext.cjs","names":[],"sources":["../../../src/server/serverContext.tsx"],"sourcesContent":["/**\n * Creates a new datastore for a given server context.\n * Attempts to closely mimic the `createContext` API.\n *\n * @example\n * const IntlayerServer = createServerContext<string | null>(null);\n *\n * <IntlayerServer value={locale}>\n * {children}\n * </IntlayerServer>\n */\nimport react, { type FC, type PropsWithChildren, type ReactNode } from 'react';\n\ntype CacheType<T> = () => { value: T | undefined };\n\nconst cacheFallback = () => () => ({ value: undefined });\n\nexport const createServerContext = <T,>(defaultValue?: T): ServerContext<T> => {\n throwInClient();\n\n /** @ts-ignore remove error Property 'cache' does not exist on type 'typeof React'. */\n const cache = react.cache<CacheType<T>> ?? cacheFallback;\n\n const getCache = cache(() => ({\n value: undefined,\n }));\n\n const Provider: FC<PropsWithChildren<{ value?: T }>> = ({\n children,\n value,\n }) => {\n getCache().value = value;\n return children;\n };\n\n const ServerContext = Provider as ServerContext<T>;\n ServerContext.Provider = Provider;\n ServerContext.Consumer = (props) => {\n const store = getCache();\n return props.children(store ? store.value : defaultValue);\n };\n ServerContext._storage = getCache;\n ServerContext._defaultValue = defaultValue;\n\n return ServerContext;\n};\n\n/**\n * Fetches a value present in a given server context.\n * Attempts to closely mimic the `useContext` API.\n *\n * @example\n * getServerContext(IntlayerServer);\n */\nexport const getServerContext = <T,>({\n _storage,\n _defaultValue,\n}: ServerContext<T>) => {\n // throwInClient();\n const store = _storage();\n if (!store) return _defaultValue;\n return store.value;\n};\n\
|
|
1
|
+
{"version":3,"file":"serverContext.cjs","names":[],"sources":["../../../src/server/serverContext.tsx"],"sourcesContent":["/**\n * Creates a new datastore for a given server context.\n * Attempts to closely mimic the `createContext` API.\n *\n * @example\n * const IntlayerServer = createServerContext<string | null>(null);\n *\n * <IntlayerServer value={locale}>\n * {children}\n * </IntlayerServer>\n */\nimport react, { type FC, type PropsWithChildren, type ReactNode } from 'react';\n\ntype CacheType<T> = () => { value: T | undefined };\n\nconst cacheFallback = () => () => ({ value: undefined });\n\nexport const createServerContext = <T,>(defaultValue?: T): ServerContext<T> => {\n throwInClient();\n\n /** @ts-ignore remove error Property 'cache' does not exist on type 'typeof React'. */\n const cache = react.cache<CacheType<T>> ?? cacheFallback;\n\n const getCache = cache(() => ({\n value: undefined,\n }));\n\n const Provider: FC<PropsWithChildren<{ value?: T }>> = ({\n children,\n value,\n }) => {\n getCache().value = value;\n return children;\n };\n\n const ServerContext = Provider as ServerContext<T>;\n ServerContext.Provider = Provider;\n ServerContext.Consumer = (props) => {\n const store = getCache();\n return props.children(store ? store.value : defaultValue);\n };\n ServerContext._storage = getCache;\n ServerContext._defaultValue = defaultValue;\n\n return ServerContext;\n};\n\n/**\n * Fetches a value present in a given server context.\n * Attempts to closely mimic the `useContext` API.\n *\n * @example\n * getServerContext(IntlayerServer);\n */\nexport const getServerContext = <T,>({\n _storage,\n _defaultValue,\n}: ServerContext<T>) => {\n // throwInClient();\n const store = _storage();\n if (!store) return _defaultValue;\n return store.value;\n};\n\nexport type ServerContext<T> = FC<PropsWithChildren<{ value?: T }>> & {\n Provider: FC<PropsWithChildren<{ value?: T }>>;\n Consumer: FC<\n PropsWithChildren<{ children: (context: T | undefined) => ReactNode }>\n >;\n _storage: () => { value: T | undefined };\n _defaultValue: T | undefined;\n};\n\n/**\n * Throws if called within a client component environment.\n * Useful to help prevent mistakes.\n */\nconst throwInClient = (): undefined | never => {\n // If window.document is defined we're in a client component\n if (typeof window !== 'undefined') {\n throw new Error(`createServerContext only works in Server Components`);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AAeA,MAAM,6BAA6B,EAAE,OAAO,OAAU;AAEtD,MAAa,uBAA2B,iBAAuC;CAC7E,cAAc;CAKd,MAAM,YAFQ,cAAM,SAAuB,cAErB,QAAQ,EAC5B,OAAO,OACT,EAAE;CAEF,MAAM,YAAkD,EACtD,UACA,YACI;EACJ,SAAS,CAAC,CAAC,QAAQ;EACnB,OAAO;CACT;CAEA,MAAM,gBAAgB;CACtB,cAAc,WAAW;CACzB,cAAc,YAAY,UAAU;EAClC,MAAM,QAAQ,SAAS;EACvB,OAAO,MAAM,SAAS,QAAQ,MAAM,QAAQ,YAAY;CAC1D;CACA,cAAc,WAAW;CACzB,cAAc,gBAAgB;CAE9B,OAAO;AACT;;;;;;;;AASA,MAAa,oBAAwB,EACnC,UACA,oBACsB;CAEtB,MAAM,QAAQ,SAAS;CACvB,IAAI,CAAC,OAAO,OAAO;CACnB,OAAO,MAAM;AACf;;;;;AAeA,MAAM,sBAAyC;CAE7C,IAAI,OAAO,WAAW,aACpB,MAAM,IAAI,MAAM,qDAAqD;AAEzE"}
|
|
@@ -11,10 +11,10 @@ import { isEnabled } from "@intlayer/analytics/isEnabled";
|
|
|
11
11
|
* and keeps it aware of the current locale.
|
|
12
12
|
*
|
|
13
13
|
* Mirrors {@link useEditor}: the module is loaded via a dynamic `import()` so it
|
|
14
|
-
* ships as its own async chunk, off the critical rendering path. Apps that
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* time.
|
|
14
|
+
* ships as its own async chunk, off the critical rendering path. Apps that opt
|
|
15
|
+
* out (`analytics.enabled !== true`), or that never install
|
|
16
|
+
* `@intlayer/analytics`, pay nothing — the whole body is guarded by
|
|
17
|
+
* `INTLAYER_ANALYTICS_ENABLED` and dead-code-eliminated at build time.
|
|
18
18
|
*/
|
|
19
19
|
const useAnalytics = () => {
|
|
20
20
|
const { locale } = useContext(IntlayerClientContext) ?? {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAnalytics.mjs","names":[],"sources":["../../../src/analytics/useAnalytics.tsx"],"sourcesContent":["'use client';\n\nimport type { AnalyticsClient } from '@intlayer/analytics';\nimport { isEnabled } from '@intlayer/analytics/isEnabled';\nimport { useContext, useEffect, useRef } from 'react';\nimport { IntlayerClientContext } from '../client/IntlayerProvider';\nimport { setExposureSink } from './exposureSink';\n\n/**\n * Initializes the Intlayer analytics client singleton when analytics is enabled\n * and keeps it aware of the current locale.\n *\n * Mirrors {@link useEditor}: the module is loaded via a dynamic `import()` so it\n * ships as its own async chunk, off the critical rendering path. Apps that\n *
|
|
1
|
+
{"version":3,"file":"useAnalytics.mjs","names":[],"sources":["../../../src/analytics/useAnalytics.tsx"],"sourcesContent":["'use client';\n\nimport type { AnalyticsClient } from '@intlayer/analytics';\nimport { isEnabled } from '@intlayer/analytics/isEnabled';\nimport { useContext, useEffect, useRef } from 'react';\nimport { IntlayerClientContext } from '../client/IntlayerProvider';\nimport { setExposureSink } from './exposureSink';\n\n/**\n * Initializes the Intlayer analytics client singleton when analytics is enabled\n * and keeps it aware of the current locale.\n *\n * Mirrors {@link useEditor}: the module is loaded via a dynamic `import()` so it\n * ships as its own async chunk, off the critical rendering path. Apps that opt\n * out (`analytics.enabled !== true`), or that never install\n * `@intlayer/analytics`, pay nothing — the whole body is guarded by\n * `INTLAYER_ANALYTICS_ENABLED` and dead-code-eliminated at build time.\n */\nexport const useAnalytics = () => {\n const { locale } = useContext(IntlayerClientContext) ?? {};\n const clientRef = useRef<AnalyticsClient | null>(null);\n\n useEffect(() => {\n if (process.env.INTLAYER_ANALYTICS_ENABLED === 'false' || !isEnabled) {\n return;\n }\n\n let cancelled = false;\n // Tracks whether initAnalyticsClient actually ran, so cleanup never calls\n // stopAnalyticsClient for an init that was cancelled — that would decrement\n // the shared reference count once too many and could stop a client another\n // provider still uses.\n let initialized = false;\n\n import('@intlayer/analytics')\n .then(({ initAnalyticsClient, buildContentExposure }) => {\n if (cancelled) return;\n\n const client = initAnalyticsClient();\n initialized = true;\n clientRef.current = client;\n\n if (locale) client.setLocale(locale);\n client.trackPageView({ reason: 'initial' });\n\n // Route node-level exposures (from the interpreter plugins) into the\n // client. Serialization happens here, off the hot render path.\n setExposureSink((input) =>\n client.trackContentExposure(buildContentExposure(input))\n );\n })\n .catch(() => {\n /* chunk failed to load — analytics stays a no-op */\n });\n\n return () => {\n cancelled = true;\n clientRef.current = null;\n setExposureSink(null);\n import('@intlayer/analytics')\n .then(({ stopAnalyticsClient }) => {\n if (initialized) stopAnalyticsClient();\n })\n .catch(() => {});\n };\n // Run once on mount; locale updates are handled by the effect below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (!locale || !clientRef.current) return;\n\n clientRef.current.setLocale(locale);\n clientRef.current.trackPageView({ reason: 'locale_change' });\n }, [locale]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAkBA,MAAa,qBAAqB;CAChC,MAAM,EAAE,WAAW,WAAW,qBAAqB,KAAK,CAAC;CACzD,MAAM,YAAY,OAA+B,IAAI;CAErD,gBAAgB;EACd,IAAI,QAAQ,IAAI,+BAA+B,WAAW,CAAC,WACzD;EAGF,IAAI,YAAY;EAKhB,IAAI,cAAc;EAElB,OAAO,sBAAsB,CAC1B,MAAM,EAAE,qBAAqB,2BAA2B;GACvD,IAAI,WAAW;GAEf,MAAM,SAAS,oBAAoB;GACnC,cAAc;GACd,UAAU,UAAU;GAEpB,IAAI,QAAQ,OAAO,UAAU,MAAM;GACnC,OAAO,cAAc,EAAE,QAAQ,UAAU,CAAC;GAI1C,iBAAiB,UACf,OAAO,qBAAqB,qBAAqB,KAAK,CAAC,CACzD;EACF,CAAC,CAAC,CACD,YAAY,CAEb,CAAC;EAEH,aAAa;GACX,YAAY;GACZ,UAAU,UAAU;GACpB,gBAAgB,IAAI;GACpB,OAAO,sBAAsB,CAC1B,MAAM,EAAE,0BAA0B;IACjC,IAAI,aAAa,oBAAoB;GACvC,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;EACnB;CAGF,GAAG,CAAC,CAAC;CAEL,gBAAgB;EACd,IAAI,CAAC,UAAU,CAAC,UAAU,SAAS;EAEnC,UAAU,QAAQ,UAAU,MAAM;EAClC,UAAU,QAAQ,cAAc,EAAE,QAAQ,gBAAgB,CAAC;CAC7D,GAAG,CAAC,MAAM,CAAC;AACb"}
|
|
@@ -5,7 +5,7 @@ import { getDictionary } from "../getDictionary.mjs";
|
|
|
5
5
|
import { IntlayerClientContext } from "./IntlayerProvider.mjs";
|
|
6
6
|
import { internationalization } from "@intlayer/config/built";
|
|
7
7
|
import { useContext } from "react";
|
|
8
|
-
import { isQualifiedDynamicLoaderMap, parseDictionarySelector, resolveDictionaryArgument, resolveQualifiedDynamicContent } from "@intlayer/core/dictionaryManipulator";
|
|
8
|
+
import { getPreloadedDictionary, isQualifiedDynamicLoaderMap, parseDictionarySelector, resolveDictionaryArgument, resolveQualifiedDynamicContent } from "@intlayer/core/dictionaryManipulator";
|
|
9
9
|
|
|
10
10
|
//#region src/client/useDictionaryDynamic.ts
|
|
11
11
|
/**
|
|
@@ -39,6 +39,8 @@ const useDictionaryDynamic = (dictionaryPromise, key, localeOrSelector) => {
|
|
|
39
39
|
loadChunk: (cacheKey, promise) => useLoadDynamic(cacheKey, promise),
|
|
40
40
|
transform: (dictionary) => getDictionary(dictionary, localeTarget)
|
|
41
41
|
});
|
|
42
|
+
const preloadedDictionary = getPreloadedDictionary(dictionaryPromise, localeTarget);
|
|
43
|
+
if (preloadedDictionary) return getDictionary(preloadedDictionary, localeTarget);
|
|
42
44
|
const plainLoaders = dictionaryPromise;
|
|
43
45
|
const dictionary = useLoadDynamic(`${String(key)}.${localeTarget}`, plainLoaders[localeTarget]?.());
|
|
44
46
|
return getDictionary(dictionary, localeTarget);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDictionaryDynamic.mjs","names":["loadDynamicChunk"],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["'use client';\n\nimport { internationalization } from '@intlayer/config/built';\nimport {\n isQualifiedDynamicLoaderMap,\n parseDictionarySelector,\n type QualifiedDynamicLoaderMap,\n resolveDictionaryArgument,\n resolveQualifiedDynamicContent,\n} from '@intlayer/core/dictionaryManipulator';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionarySelectorForKey,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useContext } from 'react';\nimport { getDictionary } from '../getDictionary';\nimport { IntlayerClientContext } from './IntlayerProvider';\n// `useLoadDynamic` is a suspender cache, not a React hook — aliased to a\n// non-hook name so it can be invoked in loops / conditionally (e.g. when a\n// collection loads several chunks at once).\nimport { useLoadDynamic as loadDynamicChunk } from './useLoadDynamic';\n\n/**\n * Client-side hook that lazily loads a dictionary and returns its content.\n *\n * The dictionary entry is either a plain dynamic loader map\n * (`locale → loader`) or a qualified one (`locale → qualifierId → loader`,\n * tagged with the qualifier dimension). For qualified maps, only the chunk(s)\n * the selector targets are loaded; the resolution mirrors static mode.\n *\n * If the locale is not provided (directly or through the selector), the client\n * context locale is used.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<K> = DeclaredLocales,\n>(\n dictionaryPromise:\n | StrictModeLocaleMap<() => Promise<T>>\n | QualifiedDynamicLoaderMap,\n key: K,\n localeOrSelector?: A\n) => {\n const { locale: currentLocale, variant: contextVariant } =\n useContext(IntlayerClientContext) ?? {};\n\n const { locale: selectorLocale, selector } =\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false'\n ? parseDictionarySelector<LocalesValues>(\n // Layers the provider's ambient variant under the call-site argument\n // before the chunk walk, so only the targeted chunk is loaded.\n resolveDictionaryArgument({\n localeOrSelector,\n contextLocale: currentLocale,\n contextVariant,\n dictionaryKey: String(key),\n })\n )\n : {\n locale: localeOrSelector as LocalesValues | undefined,\n selector: undefined,\n };\n\n const localeTarget =\n selectorLocale ?? currentLocale ?? internationalization.defaultLocale;\n\n if (\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false' &&\n isQualifiedDynamicLoaderMap(dictionaryPromise)\n ) {\n return resolveQualifiedDynamicContent({\n loaderMap: dictionaryPromise,\n key: String(key),\n locale: localeTarget,\n selector,\n loadChunk: (cacheKey, promise) => loadDynamicChunk(cacheKey, promise),\n transform: (dictionary) => getDictionary(dictionary, localeTarget),\n });\n }\n\n const plainLoaders = dictionaryPromise as StrictModeLocaleMap<\n () => Promise<T>\n >;\n\n const dictionary = loadDynamicChunk<T>(\n `${String(key)}.${localeTarget}`,\n plainLoaders[localeTarget as keyof typeof plainLoaders]?.() as Promise<T>\n );\n\n return getDictionary(dictionary, localeTarget);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"useDictionaryDynamic.mjs","names":["loadDynamicChunk"],"sources":["../../../src/client/useDictionaryDynamic.ts"],"sourcesContent":["'use client';\n\nimport { internationalization } from '@intlayer/config/built';\nimport {\n getPreloadedDictionary,\n isQualifiedDynamicLoaderMap,\n parseDictionarySelector,\n type QualifiedDynamicLoaderMap,\n resolveDictionaryArgument,\n resolveQualifiedDynamicContent,\n} from '@intlayer/core/dictionaryManipulator';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport type {\n DeclaredLocales,\n DictionaryKeys,\n DictionarySelectorForKey,\n LocalesValues,\n StrictModeLocaleMap,\n} from '@intlayer/types/module_augmentation';\nimport { useContext } from 'react';\nimport { getDictionary } from '../getDictionary';\nimport { IntlayerClientContext } from './IntlayerProvider';\n// `useLoadDynamic` is a suspender cache, not a React hook — aliased to a\n// non-hook name so it can be invoked in loops / conditionally (e.g. when a\n// collection loads several chunks at once).\nimport { useLoadDynamic as loadDynamicChunk } from './useLoadDynamic';\n\n/**\n * Client-side hook that lazily loads a dictionary and returns its content.\n *\n * The dictionary entry is either a plain dynamic loader map\n * (`locale → loader`) or a qualified one (`locale → qualifierId → loader`,\n * tagged with the qualifier dimension). For qualified maps, only the chunk(s)\n * the selector targets are loaded; the resolution mirrors static mode.\n *\n * If the locale is not provided (directly or through the selector), the client\n * context locale is used.\n */\nexport const useDictionaryDynamic = <\n const T extends Dictionary,\n const K extends DictionaryKeys,\n const A extends LocalesValues | DictionarySelectorForKey<K> = DeclaredLocales,\n>(\n dictionaryPromise:\n | StrictModeLocaleMap<() => Promise<T>>\n | QualifiedDynamicLoaderMap,\n key: K,\n localeOrSelector?: A\n) => {\n const { locale: currentLocale, variant: contextVariant } =\n useContext(IntlayerClientContext) ?? {};\n\n const { locale: selectorLocale, selector } =\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false'\n ? parseDictionarySelector<LocalesValues>(\n // Layers the provider's ambient variant under the call-site argument\n // before the chunk walk, so only the targeted chunk is loaded.\n resolveDictionaryArgument({\n localeOrSelector,\n contextLocale: currentLocale,\n contextVariant,\n dictionaryKey: String(key),\n })\n )\n : {\n locale: localeOrSelector as LocalesValues | undefined,\n selector: undefined,\n };\n\n const localeTarget =\n selectorLocale ?? currentLocale ?? internationalization.defaultLocale;\n\n if (\n process.env.INTLAYER_DICTIONARY_SELECTOR !== 'false' &&\n isQualifiedDynamicLoaderMap(dictionaryPromise)\n ) {\n return resolveQualifiedDynamicContent({\n loaderMap: dictionaryPromise,\n key: String(key),\n locale: localeTarget,\n selector,\n loadChunk: (cacheKey, promise) => loadDynamicChunk(cacheKey, promise),\n transform: (dictionary) => getDictionary(dictionary, localeTarget),\n });\n }\n\n // A build-tool plugin may have started this locale's chunk while the entry\n // point itself was evaluating, in which case the content is already here and\n // reading it must not go through the suspender — see `getPreloadedDictionary`.\n const preloadedDictionary = getPreloadedDictionary(\n dictionaryPromise,\n localeTarget\n );\n if (preloadedDictionary) {\n return getDictionary(preloadedDictionary as T, localeTarget);\n }\n\n const plainLoaders = dictionaryPromise as StrictModeLocaleMap<\n () => Promise<T>\n >;\n\n const dictionary = loadDynamicChunk<T>(\n `${String(key)}.${localeTarget}`,\n plainLoaders[localeTarget as keyof typeof plainLoaders]?.() as Promise<T>\n );\n\n return getDictionary(dictionary, localeTarget);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsCA,MAAa,wBAKX,mBAGA,KACA,qBACG;CACH,MAAM,EAAE,QAAQ,eAAe,SAAS,mBACtC,WAAW,qBAAqB,KAAK,CAAC;CAExC,MAAM,EAAE,QAAQ,gBAAgB,aAC9B,QAAQ,IAAI,iCAAiC,UACzC,wBAGE,0BAA0B;EACxB;EACA,eAAe;EACf;EACA,eAAe,OAAO,GAAG;CAC3B,CAAC,CACH,IACA;EACE,QAAQ;EACR,UAAU;CACZ;CAEN,MAAM,eACJ,kBAAkB,iBAAiB,qBAAqB;CAE1D,IACE,QAAQ,IAAI,iCAAiC,WAC7C,4BAA4B,iBAAiB,GAE7C,OAAO,+BAA+B;EACpC,WAAW;EACX,KAAK,OAAO,GAAG;EACf,QAAQ;EACR;EACA,YAAY,UAAU,YAAYA,eAAiB,UAAU,OAAO;EACpE,YAAY,eAAe,cAAc,YAAY,YAAY;CACnE,CAAC;CAMH,MAAM,sBAAsB,uBAC1B,mBACA,YACF;CACA,IAAI,qBACF,OAAO,cAAc,qBAA0B,YAAY;CAG7D,MAAM,eAAe;CAIrB,MAAM,aAAaA,eACjB,GAAG,OAAO,GAAG,EAAE,GAAG,gBAClB,aAAa,aAA0C,GAAG,CAC5D;CAEA,OAAO,cAAc,YAAY,YAAY;AAC/C"}
|
|
@@ -9,18 +9,44 @@ const createSuspender = (promise) => {
|
|
|
9
9
|
status = "error";
|
|
10
10
|
result = e;
|
|
11
11
|
});
|
|
12
|
-
return {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
return {
|
|
13
|
+
settled: suspender,
|
|
14
|
+
read() {
|
|
15
|
+
if (status === "pending") throw suspender;
|
|
16
|
+
if (status === "error") throw result;
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
17
20
|
};
|
|
18
21
|
const cache = /* @__PURE__ */ new Map();
|
|
19
22
|
const useLoadDynamic = (key, promise) => {
|
|
20
23
|
if (!cache.has(key)) cache.set(key, createSuspender(promise));
|
|
21
24
|
return cache.get(key).read();
|
|
22
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Fills the same cache {@link useLoadDynamic} reads, ahead of render.
|
|
28
|
+
*
|
|
29
|
+
* A component that reads a dictionary during render suspends whenever the entry
|
|
30
|
+
* is still `pending`, and the nearest boundary shows its fallback. Awaiting this
|
|
31
|
+
* before the render — in a router loader, or during app startup — makes that
|
|
32
|
+
* read synchronous, so no boundary ever falls back.
|
|
33
|
+
*
|
|
34
|
+
* Handing over an already-resolved promise is not enough on its own:
|
|
35
|
+
* {@link createSuspender} only leaves `pending` inside a `.then` callback, so
|
|
36
|
+
* the first read would still suspend for one microtask. Awaiting the returned
|
|
37
|
+
* promise resolves that race, because the callback registered by
|
|
38
|
+
* `createSuspender` runs before this one.
|
|
39
|
+
*
|
|
40
|
+
* @param key - Cache key, identical to the one the later read uses.
|
|
41
|
+
* @param loader - Invoked only when the key is not cached yet, so preloading a
|
|
42
|
+
* dictionary twice never issues a second request.
|
|
43
|
+
* @returns A promise that settles — never rejects — once the entry is readable.
|
|
44
|
+
*/
|
|
45
|
+
const preloadDynamic = (key, loader) => {
|
|
46
|
+
if (!cache.has(key)) cache.set(key, createSuspender(loader()));
|
|
47
|
+
return cache.get(key).settled;
|
|
48
|
+
};
|
|
23
49
|
|
|
24
50
|
//#endregion
|
|
25
|
-
export { useLoadDynamic };
|
|
51
|
+
export { preloadDynamic, useLoadDynamic };
|
|
26
52
|
//# sourceMappingURL=useLoadDynamic.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLoadDynamic.mjs","names":[],"sources":["../../../src/client/useLoadDynamic.ts"],"sourcesContent":["type Status = 'pending' | 'success' | 'error';\n\nconst createSuspender = <T>(promise: Promise<T>) => {\n let status: Status = 'pending';\n let result: T;\n const suspender = promise.then(\n (r) => {\n status = 'success';\n result = r;\n },\n (e) => {\n status = 'error';\n result = e as any;\n }\n );\n\n return {\n read() {\n if (status === 'pending') throw suspender;\n if (status === 'error') throw result;\n return result!;\n },\n };\n};\n\nconst cache = new Map<string,
|
|
1
|
+
{"version":3,"file":"useLoadDynamic.mjs","names":[],"sources":["../../../src/client/useLoadDynamic.ts"],"sourcesContent":["type Status = 'pending' | 'success' | 'error';\n\ntype Suspender<T> = {\n /**\n * Settles once the entry has left `pending`, never rejecting. Awaiting it\n * guarantees a subsequent {@link Suspender.read} returns without suspending.\n */\n settled: Promise<void>;\n read: () => T;\n};\n\nconst createSuspender = <T>(promise: Promise<T>): Suspender<T> => {\n let status: Status = 'pending';\n let result: T;\n const suspender = promise.then(\n (r) => {\n status = 'success';\n result = r;\n },\n (e) => {\n status = 'error';\n result = e as any;\n }\n );\n\n return {\n settled: suspender,\n read() {\n if (status === 'pending') throw suspender;\n if (status === 'error') throw result;\n return result!;\n },\n };\n};\n\nconst cache = new Map<string, Suspender<unknown>>();\n\nexport const useLoadDynamic = <T>(key: string, promise: Promise<T>): T => {\n if (!cache.has(key)) {\n cache.set(key, createSuspender(promise));\n }\n\n return (cache.get(key)! as Suspender<T>).read() as T;\n};\n\n/**\n * Fills the same cache {@link useLoadDynamic} reads, ahead of render.\n *\n * A component that reads a dictionary during render suspends whenever the entry\n * is still `pending`, and the nearest boundary shows its fallback. Awaiting this\n * before the render — in a router loader, or during app startup — makes that\n * read synchronous, so no boundary ever falls back.\n *\n * Handing over an already-resolved promise is not enough on its own:\n * {@link createSuspender} only leaves `pending` inside a `.then` callback, so\n * the first read would still suspend for one microtask. Awaiting the returned\n * promise resolves that race, because the callback registered by\n * `createSuspender` runs before this one.\n *\n * @param key - Cache key, identical to the one the later read uses.\n * @param loader - Invoked only when the key is not cached yet, so preloading a\n * dictionary twice never issues a second request.\n * @returns A promise that settles — never rejects — once the entry is readable.\n */\nexport const preloadDynamic = <T>(\n key: string,\n loader: () => Promise<T>\n): Promise<void> => {\n if (!cache.has(key)) {\n cache.set(key, createSuspender(loader()) as Suspender<unknown>);\n }\n\n return cache.get(key)!.settled;\n};\n"],"mappings":";AAWA,MAAM,mBAAsB,YAAsC;CAChE,IAAI,SAAiB;CACrB,IAAI;CACJ,MAAM,YAAY,QAAQ,MACvB,MAAM;EACL,SAAS;EACT,SAAS;CACX,IACC,MAAM;EACL,SAAS;EACT,SAAS;CACX,CACF;CAEA,OAAO;EACL,SAAS;EACT,OAAO;GACL,IAAI,WAAW,WAAW,MAAM;GAChC,IAAI,WAAW,SAAS,MAAM;GAC9B,OAAO;EACT;CACF;AACF;AAEA,MAAM,wBAAQ,IAAI,IAAgC;AAElD,MAAa,kBAAqB,KAAa,YAA2B;CACxE,IAAI,CAAC,MAAM,IAAI,GAAG,GAChB,MAAM,IAAI,KAAK,gBAAgB,OAAO,CAAC;CAGzC,OAAQ,MAAM,IAAI,GAAG,CAAC,CAAmB,KAAK;AAChD;;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,kBACX,KACA,WACkB;CAClB,IAAI,CAAC,MAAM,IAAI,GAAG,GAChB,MAAM,IAAI,KAAK,gBAAgB,OAAO,CAAC,CAAuB;CAGhE,OAAO,MAAM,IAAI,GAAG,CAAC,CAAE;AACzB"}
|
|
@@ -24,6 +24,32 @@ const useIntlayer = () => getServerContext(IntlayerServerContext);
|
|
|
24
24
|
*/
|
|
25
25
|
const locale = getServerContext(IntlayerServerContext);
|
|
26
26
|
/**
|
|
27
|
+
* Seeds the request-scoped server context locale imperatively — the equivalent
|
|
28
|
+
* of mounting {@link IntlayerServerProvider} without wrapping the tree.
|
|
29
|
+
*
|
|
30
|
+
* Useful in pages that must stay statically rendered while no ambient
|
|
31
|
+
* request-derived locale source is static-safe (Next.js < 16):
|
|
32
|
+
*
|
|
33
|
+
* ```tsx
|
|
34
|
+
* const Page = async ({ params }) => {
|
|
35
|
+
* const { locale } = await params;
|
|
36
|
+
* setLocale(locale);
|
|
37
|
+
* return <PageContent />;
|
|
38
|
+
* };
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
const setLocale = (locale) => {
|
|
42
|
+
IntlayerServerContext._storage().value = locale;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Seeds the request-scoped ambient variant imperatively — the equivalent of
|
|
46
|
+
* the `variant` prop of {@link IntlayerServerProvider} without wrapping the
|
|
47
|
+
* tree. See that prop for the accepted shapes.
|
|
48
|
+
*/
|
|
49
|
+
const setVariant = (variant) => {
|
|
50
|
+
IntlayerServerVariantContext._storage().value = variant;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
27
53
|
* Provider that store the current locale on the server side
|
|
28
54
|
*/
|
|
29
55
|
const IntlayerServerProvider = ({ children, locale = defaultLocale, variant }) => /* @__PURE__ */ jsx(IntlayerServerContext.Provider, {
|
|
@@ -35,5 +61,5 @@ const IntlayerServerProvider = ({ children, locale = defaultLocale, variant }) =
|
|
|
35
61
|
});
|
|
36
62
|
|
|
37
63
|
//#endregion
|
|
38
|
-
export { IntlayerServerContext, IntlayerServerProvider, IntlayerServerVariantContext, locale, useIntlayer };
|
|
64
|
+
export { IntlayerServerContext, IntlayerServerProvider, IntlayerServerVariantContext, locale, setLocale, setVariant, useIntlayer };
|
|
39
65
|
//# sourceMappingURL=IntlayerServerProvider.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntlayerServerProvider.mjs","names":[],"sources":["../../../src/server/IntlayerServerProvider.tsx"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type {\n LocalesValues,\n ProviderVariant,\n} from '@intlayer/types/module_augmentation';\n\nimport type { FC, PropsWithChildren } from 'react';\nimport { createServerContext, getServerContext } from './serverContext';\n\nconst { defaultLocale } = internationalization ?? {};\n\n/**\n * Context that store the current locale on the server side\n */\nexport const IntlayerServerContext =\n createServerContext<LocalesValues>(defaultLocale);\n\n/**\n * Context that stores the ambient variant on the server side.\n *\n * Kept separate from {@link IntlayerServerContext} so the locale context keeps\n * its plain `LocalesValues` shape for the packages already reading it.\n */\nexport const IntlayerServerVariantContext =\n createServerContext<ProviderVariant>(undefined);\n\n/**\n * Hook that provides the current locale\n */\nexport const useIntlayer = () => getServerContext(IntlayerServerContext);\n\n/**\n * Get the current locale\n */\nexport const locale = getServerContext(IntlayerServerContext);\n\nexport type IntlayerServerProviderProps = PropsWithChildren & {\n locale?: LocalesValues;\n /**\n * Ambient variant applied to every dictionary read below this provider — for\n * a dimension resolved once per request (tenant, school type, plan tier…).\n *\n * Accepts a name (`'school1'`), an ordered preference chain\n * (`['school1', 'default']`), or a per-key map\n * (`{ key1: 'school1', default: 'base' }`). A call-site selector wins.\n */\n variant?: ProviderVariant;\n};\n\n/**\n * Provider that store the current locale on the server side\n */\nexport const IntlayerServerProvider: FC<IntlayerServerProviderProps> = ({\n children,\n locale = defaultLocale,\n variant,\n}) => (\n <IntlayerServerContext.Provider value={locale}>\n <IntlayerServerVariantContext.Provider value={variant}>\n {children}\n </IntlayerServerVariantContext.Provider>\n </IntlayerServerContext.Provider>\n);\n"],"mappings":";;;;;AASA,MAAM,EAAE,kBAAkB,wBAAwB,CAAC;;;;AAKnD,MAAa,wBACX,oBAAmC,aAAa;;;;;;;AAQlD,MAAa,+BACX,oBAAqC,MAAS;;;;AAKhD,MAAa,oBAAoB,iBAAiB,qBAAqB;;;;AAKvE,MAAa,SAAS,iBAAiB,qBAAqB;;;;
|
|
1
|
+
{"version":3,"file":"IntlayerServerProvider.mjs","names":[],"sources":["../../../src/server/IntlayerServerProvider.tsx"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type {\n LocalesValues,\n ProviderVariant,\n} from '@intlayer/types/module_augmentation';\n\nimport type { FC, PropsWithChildren } from 'react';\nimport { createServerContext, getServerContext } from './serverContext';\n\nconst { defaultLocale } = internationalization ?? {};\n\n/**\n * Context that store the current locale on the server side\n */\nexport const IntlayerServerContext =\n createServerContext<LocalesValues>(defaultLocale);\n\n/**\n * Context that stores the ambient variant on the server side.\n *\n * Kept separate from {@link IntlayerServerContext} so the locale context keeps\n * its plain `LocalesValues` shape for the packages already reading it.\n */\nexport const IntlayerServerVariantContext =\n createServerContext<ProviderVariant>(undefined);\n\n/**\n * Hook that provides the current locale\n */\nexport const useIntlayer = () => getServerContext(IntlayerServerContext);\n\n/**\n * Get the current locale\n */\nexport const locale = getServerContext(IntlayerServerContext);\n\n/**\n * Seeds the request-scoped server context locale imperatively — the equivalent\n * of mounting {@link IntlayerServerProvider} without wrapping the tree.\n *\n * Useful in pages that must stay statically rendered while no ambient\n * request-derived locale source is static-safe (Next.js < 16):\n *\n * ```tsx\n * const Page = async ({ params }) => {\n * const { locale } = await params;\n * setLocale(locale);\n * return <PageContent />;\n * };\n * ```\n */\nexport const setLocale = (locale: LocalesValues): void => {\n IntlayerServerContext._storage().value = locale;\n};\n\n/**\n * Seeds the request-scoped ambient variant imperatively — the equivalent of\n * the `variant` prop of {@link IntlayerServerProvider} without wrapping the\n * tree. See that prop for the accepted shapes.\n */\nexport const setVariant = (variant: ProviderVariant): void => {\n IntlayerServerVariantContext._storage().value = variant;\n};\n\nexport type IntlayerServerProviderProps = PropsWithChildren & {\n locale?: LocalesValues;\n /**\n * Ambient variant applied to every dictionary read below this provider — for\n * a dimension resolved once per request (tenant, school type, plan tier…).\n *\n * Accepts a name (`'school1'`), an ordered preference chain\n * (`['school1', 'default']`), or a per-key map\n * (`{ key1: 'school1', default: 'base' }`). A call-site selector wins.\n */\n variant?: ProviderVariant;\n};\n\n/**\n * Provider that store the current locale on the server side\n */\nexport const IntlayerServerProvider: FC<IntlayerServerProviderProps> = ({\n children,\n locale = defaultLocale,\n variant,\n}) => (\n <IntlayerServerContext.Provider value={locale}>\n <IntlayerServerVariantContext.Provider value={variant}>\n {children}\n </IntlayerServerVariantContext.Provider>\n </IntlayerServerContext.Provider>\n);\n"],"mappings":";;;;;AASA,MAAM,EAAE,kBAAkB,wBAAwB,CAAC;;;;AAKnD,MAAa,wBACX,oBAAmC,aAAa;;;;;;;AAQlD,MAAa,+BACX,oBAAqC,MAAS;;;;AAKhD,MAAa,oBAAoB,iBAAiB,qBAAqB;;;;AAKvE,MAAa,SAAS,iBAAiB,qBAAqB;;;;;;;;;;;;;;;;AAiB5D,MAAa,aAAa,WAAgC;CACxD,sBAAsB,SAAS,CAAC,CAAC,QAAQ;AAC3C;;;;;;AAOA,MAAa,cAAc,YAAmC;CAC5D,6BAA6B,SAAS,CAAC,CAAC,QAAQ;AAClD;;;;AAkBA,MAAa,0BAA2D,EACtE,UACA,SAAS,eACT,cAEA,oBAAC,sBAAsB,UAAvB;CAAgC,OAAO;WACrC,oBAAC,6BAA6B,UAA9B;EAAuC,OAAO;EAC3C;CACoC;AACT"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getServerContext } from "./serverContext.mjs";
|
|
2
|
+
import { IntlayerServerContext, IntlayerServerProvider, IntlayerServerVariantContext, locale, setLocale, setVariant } from "./IntlayerServerProvider.mjs";
|
|
2
3
|
import { t } from "./t.mjs";
|
|
3
4
|
import { useI18n } from "./useI18n.mjs";
|
|
4
5
|
import { useIntlayer } from "./useIntlayer.mjs";
|
|
@@ -9,4 +10,4 @@ import { useLoadDynamic } from "./useLoadDynamic.mjs";
|
|
|
9
10
|
import { useDictionaryDynamic } from "./useDictionaryDynamic.mjs";
|
|
10
11
|
import { useIntl } from "./format/useIntl.mjs";
|
|
11
12
|
|
|
12
|
-
export { IntlayerServerContext as IntlayerServer, IntlayerServerProvider, locale, t, useDictionary, useDictionaryAsync, useDictionaryDynamic, useI18n, useIntl, useIntlayer, useLoadDynamic, useLocale };
|
|
13
|
+
export { IntlayerServerContext as IntlayerServer, IntlayerServerProvider, IntlayerServerVariantContext, getServerContext, locale, setLocale, setVariant, t, useDictionary, useDictionaryAsync, useDictionaryDynamic, useI18n, useIntl, useIntlayer, useLoadDynamic, useLocale };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverContext.mjs","names":[],"sources":["../../../src/server/serverContext.tsx"],"sourcesContent":["/**\n * Creates a new datastore for a given server context.\n * Attempts to closely mimic the `createContext` API.\n *\n * @example\n * const IntlayerServer = createServerContext<string | null>(null);\n *\n * <IntlayerServer value={locale}>\n * {children}\n * </IntlayerServer>\n */\nimport react, { type FC, type PropsWithChildren, type ReactNode } from 'react';\n\ntype CacheType<T> = () => { value: T | undefined };\n\nconst cacheFallback = () => () => ({ value: undefined });\n\nexport const createServerContext = <T,>(defaultValue?: T): ServerContext<T> => {\n throwInClient();\n\n /** @ts-ignore remove error Property 'cache' does not exist on type 'typeof React'. */\n const cache = react.cache<CacheType<T>> ?? cacheFallback;\n\n const getCache = cache(() => ({\n value: undefined,\n }));\n\n const Provider: FC<PropsWithChildren<{ value?: T }>> = ({\n children,\n value,\n }) => {\n getCache().value = value;\n return children;\n };\n\n const ServerContext = Provider as ServerContext<T>;\n ServerContext.Provider = Provider;\n ServerContext.Consumer = (props) => {\n const store = getCache();\n return props.children(store ? store.value : defaultValue);\n };\n ServerContext._storage = getCache;\n ServerContext._defaultValue = defaultValue;\n\n return ServerContext;\n};\n\n/**\n * Fetches a value present in a given server context.\n * Attempts to closely mimic the `useContext` API.\n *\n * @example\n * getServerContext(IntlayerServer);\n */\nexport const getServerContext = <T,>({\n _storage,\n _defaultValue,\n}: ServerContext<T>) => {\n // throwInClient();\n const store = _storage();\n if (!store) return _defaultValue;\n return store.value;\n};\n\
|
|
1
|
+
{"version":3,"file":"serverContext.mjs","names":[],"sources":["../../../src/server/serverContext.tsx"],"sourcesContent":["/**\n * Creates a new datastore for a given server context.\n * Attempts to closely mimic the `createContext` API.\n *\n * @example\n * const IntlayerServer = createServerContext<string | null>(null);\n *\n * <IntlayerServer value={locale}>\n * {children}\n * </IntlayerServer>\n */\nimport react, { type FC, type PropsWithChildren, type ReactNode } from 'react';\n\ntype CacheType<T> = () => { value: T | undefined };\n\nconst cacheFallback = () => () => ({ value: undefined });\n\nexport const createServerContext = <T,>(defaultValue?: T): ServerContext<T> => {\n throwInClient();\n\n /** @ts-ignore remove error Property 'cache' does not exist on type 'typeof React'. */\n const cache = react.cache<CacheType<T>> ?? cacheFallback;\n\n const getCache = cache(() => ({\n value: undefined,\n }));\n\n const Provider: FC<PropsWithChildren<{ value?: T }>> = ({\n children,\n value,\n }) => {\n getCache().value = value;\n return children;\n };\n\n const ServerContext = Provider as ServerContext<T>;\n ServerContext.Provider = Provider;\n ServerContext.Consumer = (props) => {\n const store = getCache();\n return props.children(store ? store.value : defaultValue);\n };\n ServerContext._storage = getCache;\n ServerContext._defaultValue = defaultValue;\n\n return ServerContext;\n};\n\n/**\n * Fetches a value present in a given server context.\n * Attempts to closely mimic the `useContext` API.\n *\n * @example\n * getServerContext(IntlayerServer);\n */\nexport const getServerContext = <T,>({\n _storage,\n _defaultValue,\n}: ServerContext<T>) => {\n // throwInClient();\n const store = _storage();\n if (!store) return _defaultValue;\n return store.value;\n};\n\nexport type ServerContext<T> = FC<PropsWithChildren<{ value?: T }>> & {\n Provider: FC<PropsWithChildren<{ value?: T }>>;\n Consumer: FC<\n PropsWithChildren<{ children: (context: T | undefined) => ReactNode }>\n >;\n _storage: () => { value: T | undefined };\n _defaultValue: T | undefined;\n};\n\n/**\n * Throws if called within a client component environment.\n * Useful to help prevent mistakes.\n */\nconst throwInClient = (): undefined | never => {\n // If window.document is defined we're in a client component\n if (typeof window !== 'undefined') {\n throw new Error(`createServerContext only works in Server Components`);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;AAeA,MAAM,6BAA6B,EAAE,OAAO,OAAU;AAEtD,MAAa,uBAA2B,iBAAuC;CAC7E,cAAc;CAKd,MAAM,YAFQ,MAAM,SAAuB,cAErB,QAAQ,EAC5B,OAAO,OACT,EAAE;CAEF,MAAM,YAAkD,EACtD,UACA,YACI;EACJ,SAAS,CAAC,CAAC,QAAQ;EACnB,OAAO;CACT;CAEA,MAAM,gBAAgB;CACtB,cAAc,WAAW;CACzB,cAAc,YAAY,UAAU;EAClC,MAAM,QAAQ,SAAS;EACvB,OAAO,MAAM,SAAS,QAAQ,MAAM,QAAQ,YAAY;CAC1D;CACA,cAAc,WAAW;CACzB,cAAc,gBAAgB;CAE9B,OAAO;AACT;;;;;;;;AASA,MAAa,oBAAwB,EACnC,UACA,oBACsB;CAEtB,MAAM,QAAQ,SAAS;CACvB,IAAI,CAAC,OAAO,OAAO;CACnB,OAAO,MAAM;AACf;;;;;AAeA,MAAM,sBAAyC;CAE7C,IAAI,OAAO,WAAW,aACpB,MAAM,IAAI,MAAM,qDAAqD;AAEzE"}
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* and keeps it aware of the current locale.
|
|
5
5
|
*
|
|
6
6
|
* Mirrors {@link useEditor}: the module is loaded via a dynamic `import()` so it
|
|
7
|
-
* ships as its own async chunk, off the critical rendering path. Apps that
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* time.
|
|
7
|
+
* ships as its own async chunk, off the critical rendering path. Apps that opt
|
|
8
|
+
* out (`analytics.enabled !== true`), or that never install
|
|
9
|
+
* `@intlayer/analytics`, pay nothing — the whole body is guarded by
|
|
10
|
+
* `INTLAYER_ANALYTICS_ENABLED` and dead-code-eliminated at build time.
|
|
11
11
|
*/
|
|
12
12
|
declare const useAnalytics: () => void;
|
|
13
13
|
//#endregion
|
|
@@ -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":";;;;;;;;;;;;;;;cAsCa,6BACL,UAAU,kBACV,UAAU,sBACV,UAAU,gBAAgB,yBAAyB,KAAK,iBAAe,mBAGzE,0BAA0B,QAAQ,MAClC,2BAAyB,KACxB,GAAC,mBACa"}
|
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
//#region src/client/useLoadDynamic.d.ts
|
|
2
2
|
declare const useLoadDynamic: <T>(key: string, promise: Promise<T>) => T;
|
|
3
|
+
/**
|
|
4
|
+
* Fills the same cache {@link useLoadDynamic} reads, ahead of render.
|
|
5
|
+
*
|
|
6
|
+
* A component that reads a dictionary during render suspends whenever the entry
|
|
7
|
+
* is still `pending`, and the nearest boundary shows its fallback. Awaiting this
|
|
8
|
+
* before the render — in a router loader, or during app startup — makes that
|
|
9
|
+
* read synchronous, so no boundary ever falls back.
|
|
10
|
+
*
|
|
11
|
+
* Handing over an already-resolved promise is not enough on its own:
|
|
12
|
+
* {@link createSuspender} only leaves `pending` inside a `.then` callback, so
|
|
13
|
+
* the first read would still suspend for one microtask. Awaiting the returned
|
|
14
|
+
* promise resolves that race, because the callback registered by
|
|
15
|
+
* `createSuspender` runs before this one.
|
|
16
|
+
*
|
|
17
|
+
* @param key - Cache key, identical to the one the later read uses.
|
|
18
|
+
* @param loader - Invoked only when the key is not cached yet, so preloading a
|
|
19
|
+
* dictionary twice never issues a second request.
|
|
20
|
+
* @returns A promise that settles — never rejects — once the entry is readable.
|
|
21
|
+
*/
|
|
22
|
+
declare const preloadDynamic: <T>(key: string, loader: () => Promise<T>) => Promise<void>;
|
|
3
23
|
//#endregion
|
|
4
|
-
export { useLoadDynamic };
|
|
24
|
+
export { preloadDynamic, useLoadDynamic };
|
|
5
25
|
//# sourceMappingURL=useLoadDynamic.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLoadDynamic.d.ts","names":[],"sources":["../../../src/client/useLoadDynamic.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"useLoadDynamic.d.ts","names":[],"sources":["../../../src/client/useLoadDynamic.ts"],"mappings":";cAqCa,iBAAkB,GAAC,aAAa,SAAW,QAAQ,OAAK;;;;;;;;;;;;;;;;;;;;cA2BxD,iBAAkB,GAAC,aACnB,cACG,QAAQ,OACrB"}
|
|
@@ -1,43 +1,18 @@
|
|
|
1
|
+
import { ServerContext } from "./serverContext.js";
|
|
1
2
|
import { LocalesValues, ProviderVariant } from "@intlayer/types/module_augmentation";
|
|
2
3
|
import { FC, PropsWithChildren } from "react";
|
|
3
4
|
//#region src/server/IntlayerServerProvider.d.ts
|
|
4
5
|
/**
|
|
5
6
|
* Context that store the current locale on the server side
|
|
6
7
|
*/
|
|
7
|
-
declare const IntlayerServerContext:
|
|
8
|
-
value?: LocalesValues;
|
|
9
|
-
}>> & {
|
|
10
|
-
Provider: FC<PropsWithChildren<{
|
|
11
|
-
value?: LocalesValues;
|
|
12
|
-
}>>;
|
|
13
|
-
Consumer: FC<PropsWithChildren<{
|
|
14
|
-
children: (context: LocalesValues) => import("react").ReactNode;
|
|
15
|
-
}>>;
|
|
16
|
-
_storage: () => {
|
|
17
|
-
value: LocalesValues;
|
|
18
|
-
};
|
|
19
|
-
_defaultValue: LocalesValues;
|
|
20
|
-
};
|
|
8
|
+
declare const IntlayerServerContext: ServerContext<LocalesValues>;
|
|
21
9
|
/**
|
|
22
10
|
* Context that stores the ambient variant on the server side.
|
|
23
11
|
*
|
|
24
12
|
* Kept separate from {@link IntlayerServerContext} so the locale context keeps
|
|
25
13
|
* its plain `LocalesValues` shape for the packages already reading it.
|
|
26
14
|
*/
|
|
27
|
-
declare const IntlayerServerVariantContext:
|
|
28
|
-
value?: ProviderVariant;
|
|
29
|
-
}>> & {
|
|
30
|
-
Provider: FC<PropsWithChildren<{
|
|
31
|
-
value?: ProviderVariant;
|
|
32
|
-
}>>;
|
|
33
|
-
Consumer: FC<PropsWithChildren<{
|
|
34
|
-
children: (context: ProviderVariant) => import("react").ReactNode;
|
|
35
|
-
}>>;
|
|
36
|
-
_storage: () => {
|
|
37
|
-
value: ProviderVariant;
|
|
38
|
-
};
|
|
39
|
-
_defaultValue: ProviderVariant;
|
|
40
|
-
};
|
|
15
|
+
declare const IntlayerServerVariantContext: ServerContext<ProviderVariant>;
|
|
41
16
|
/**
|
|
42
17
|
* Hook that provides the current locale
|
|
43
18
|
*/
|
|
@@ -46,6 +21,28 @@ declare const useIntlayer: () => LocalesValues;
|
|
|
46
21
|
* Get the current locale
|
|
47
22
|
*/
|
|
48
23
|
declare const locale: LocalesValues;
|
|
24
|
+
/**
|
|
25
|
+
* Seeds the request-scoped server context locale imperatively — the equivalent
|
|
26
|
+
* of mounting {@link IntlayerServerProvider} without wrapping the tree.
|
|
27
|
+
*
|
|
28
|
+
* Useful in pages that must stay statically rendered while no ambient
|
|
29
|
+
* request-derived locale source is static-safe (Next.js < 16):
|
|
30
|
+
*
|
|
31
|
+
* ```tsx
|
|
32
|
+
* const Page = async ({ params }) => {
|
|
33
|
+
* const { locale } = await params;
|
|
34
|
+
* setLocale(locale);
|
|
35
|
+
* return <PageContent />;
|
|
36
|
+
* };
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
declare const setLocale: (locale: LocalesValues) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Seeds the request-scoped ambient variant imperatively — the equivalent of
|
|
42
|
+
* the `variant` prop of {@link IntlayerServerProvider} without wrapping the
|
|
43
|
+
* tree. See that prop for the accepted shapes.
|
|
44
|
+
*/
|
|
45
|
+
declare const setVariant: (variant: ProviderVariant) => void;
|
|
49
46
|
type IntlayerServerProviderProps = PropsWithChildren & {
|
|
50
47
|
locale?: LocalesValues;
|
|
51
48
|
/**
|
|
@@ -63,5 +60,5 @@ type IntlayerServerProviderProps = PropsWithChildren & {
|
|
|
63
60
|
*/
|
|
64
61
|
declare const IntlayerServerProvider: FC<IntlayerServerProviderProps>;
|
|
65
62
|
//#endregion
|
|
66
|
-
export { IntlayerServerContext, IntlayerServerProvider, IntlayerServerProviderProps, IntlayerServerVariantContext, locale, useIntlayer };
|
|
63
|
+
export { IntlayerServerContext, IntlayerServerProvider, IntlayerServerProviderProps, IntlayerServerVariantContext, locale, setLocale, setVariant, useIntlayer };
|
|
67
64
|
//# sourceMappingURL=IntlayerServerProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntlayerServerProvider.d.ts","names":[],"sources":["../../../src/server/IntlayerServerProvider.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"IntlayerServerProvider.d.ts","names":[],"sources":["../../../src/server/IntlayerServerProvider.tsx"],"mappings":";;;;;;;cAca,uBAAqB,cAAA;;;;;;;cASrB,8BAA4B,cAAA;;;;cAM5B,mBAAW;;;;cAKX,QAAM;;;;;;;;;;;;;;;;cAiBN,YAAS,QAAY;;;;;;cASrB,aAAU,SAAa;KAIxB,8BAA8B;EACxC,SAAS;;;;;;;;;EAST,UAAU;;;;;cAMC,wBAAwB,GAAG"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ServerContext, getServerContext } from "./serverContext.js";
|
|
2
|
+
import { IntlayerServerContext, IntlayerServerProvider, IntlayerServerProviderProps, IntlayerServerVariantContext, locale, setLocale, setVariant } from "./IntlayerServerProvider.js";
|
|
2
3
|
import { useIntl } from "./format/useIntl.js";
|
|
3
4
|
import { t } from "./t.js";
|
|
4
5
|
import { useDictionary } from "./useDictionary.js";
|
|
@@ -8,4 +9,4 @@ import { useI18n } from "./useI18n.js";
|
|
|
8
9
|
import { useIntlayer } from "./useIntlayer.js";
|
|
9
10
|
import { useLoadDynamic } from "./useLoadDynamic.js";
|
|
10
11
|
import { useLocale } from "./useLocale.js";
|
|
11
|
-
export { IntlayerServerContext as IntlayerServer, IntlayerServerProvider, type IntlayerServerProviderProps, locale, t, useDictionary, useDictionaryAsync, useDictionaryDynamic, useI18n, useIntl, useIntlayer, useLoadDynamic, useLocale };
|
|
12
|
+
export { IntlayerServerContext as IntlayerServer, IntlayerServerProvider, type IntlayerServerProviderProps, IntlayerServerVariantContext, type ServerContext, getServerContext, locale, setLocale, setVariant, t, useDictionary, useDictionaryAsync, useDictionaryDynamic, useI18n, useIntl, useIntlayer, useLoadDynamic, useLocale };
|
|
@@ -24,5 +24,5 @@ type ServerContext<T> = FC<PropsWithChildren<{
|
|
|
24
24
|
_defaultValue: T | undefined;
|
|
25
25
|
};
|
|
26
26
|
//#endregion
|
|
27
|
-
export { createServerContext, getServerContext };
|
|
27
|
+
export { ServerContext, createServerContext, getServerContext };
|
|
28
28
|
//# sourceMappingURL=serverContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serverContext.d.ts","names":[],"sources":["../../../src/server/serverContext.tsx"],"mappings":";;cAiBa,sBAAuB,GAAC,eAAkB,MAAI,cAAc;;;;;;;;cAqC5D,mBAAoB,KAAC,UAAA,iBAG/B,cAAc,OAAE;
|
|
1
|
+
{"version":3,"file":"serverContext.d.ts","names":[],"sources":["../../../src/server/serverContext.tsx"],"mappings":";;cAiBa,sBAAuB,GAAC,eAAkB,MAAI,cAAc;;;;;;;;cAqC5D,mBAAoB,KAAC,UAAA,iBAG/B,cAAc,OAAE;KAOP,cAAc,KAAK,GAAG;EAAoB,QAAQ;;EAC5D,UAAU,GAAG;IAAoB,QAAQ;;EACzC,UAAU,GACR;IAAoB,WAAW,SAAS,kBAAkB;;EAE5D;IAAkB,OAAO;;EACzB,eAAe"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-intlayer",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.4.0-canary.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Easily internationalize i18n your React applications with type-safe multilingual content management.",
|
|
6
6
|
"keywords": [
|
|
@@ -132,12 +132,12 @@
|
|
|
132
132
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
133
133
|
},
|
|
134
134
|
"dependencies": {
|
|
135
|
-
"@intlayer/api": "9.
|
|
136
|
-
"@intlayer/config": "9.
|
|
137
|
-
"@intlayer/core": "9.
|
|
138
|
-
"@intlayer/dictionaries-entry": "9.
|
|
139
|
-
"@intlayer/editor": "9.
|
|
140
|
-
"@intlayer/types": "9.
|
|
135
|
+
"@intlayer/api": "9.4.0-canary.0",
|
|
136
|
+
"@intlayer/config": "9.4.0-canary.0",
|
|
137
|
+
"@intlayer/core": "9.4.0-canary.0",
|
|
138
|
+
"@intlayer/dictionaries-entry": "9.4.0-canary.0",
|
|
139
|
+
"@intlayer/editor": "9.4.0-canary.0",
|
|
140
|
+
"@intlayer/types": "9.4.0-canary.0"
|
|
141
141
|
},
|
|
142
142
|
"devDependencies": {
|
|
143
143
|
"@craco/types": "7.1.0",
|
|
@@ -151,14 +151,14 @@
|
|
|
151
151
|
"rimraf": "6.1.3",
|
|
152
152
|
"tsdown": "0.22.14",
|
|
153
153
|
"typescript": "7.0.2",
|
|
154
|
-
"vitest": "4.1.
|
|
154
|
+
"vitest": "4.1.11"
|
|
155
155
|
},
|
|
156
156
|
"peerDependencies": {
|
|
157
157
|
"react": ">=16.0.0",
|
|
158
158
|
"react-dom": ">=16.0.0"
|
|
159
159
|
},
|
|
160
160
|
"optionalDependencies": {
|
|
161
|
-
"@intlayer/analytics": "9.
|
|
161
|
+
"@intlayer/analytics": "9.4.0-canary.0"
|
|
162
162
|
},
|
|
163
163
|
"engines": {
|
|
164
164
|
"node": ">=14.18"
|