@generaltranslation/react-core 11.1.12 → 11.1.14

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/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # @generaltranslation/react-core
2
2
 
3
+ ## 11.1.14
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`f2204b9`](https://github.com/generaltranslation/gt/commit/f2204b990278865c54d14d337392930ea1ec31bf), [`b05b470`](https://github.com/generaltranslation/gt/commit/b05b4703fbbfd34a3cbee335c786e2e606346167), [`8d376e2`](https://github.com/generaltranslation/gt/commit/8d376e23c80828dfd8756e2f0fbf0f7725e0f178)]:
8
+ - @generaltranslation/format@0.1.8
9
+ - generaltranslation@9.1.7
10
+ - gt-i18n@1.0.17
11
+
12
+ ## 11.1.7-iris.0
13
+
14
+ ### Patch Changes
15
+
16
+ - 5d8b78a: Migrate the package license from FSL-1.1-ALv2 to MIT.
17
+ - Updated dependencies [f2204b9]
18
+ - Updated dependencies [b05b470]
19
+ - Updated dependencies [5d8b78a]
20
+ - @generaltranslation/format@0.1.5-iris.0
21
+ - generaltranslation@9.1.3-iris.0
22
+ - gt-i18n@1.0.13-iris.0
23
+
24
+ ## 11.1.6-iris.0
25
+
26
+ ### Patch Changes
27
+
28
+ - Updated dependencies [8d376e2]
29
+ - gt-i18n@1.0.12-iris.0
30
+
31
+ ## 11.1.13
32
+
33
+ ### Patch Changes
34
+
35
+ - [#2144](https://github.com/generaltranslation/gt/pull/2144) [`4422032`](https://github.com/generaltranslation/gt/commit/4422032bb5d365aabe095ee1ff103fd5bfdee578) Thanks [@eoinest](https://github.com/eoinest)! - Log runtime translation failures from the i18n store instead of letting them escape as unhandled promise rejections that crash the dev server during SSR
36
+
37
+ - [#2144](https://github.com/generaltranslation/gt/pull/2144) [`4422032`](https://github.com/generaltranslation/gt/commit/4422032bb5d365aabe095ee1ff103fd5bfdee578) Thanks [@eoinest](https://github.com/eoinest)! - Return a snapshot with no entry for the locale, and warn, when `getTranslationsSnapshot()` cannot load translations for that locale, instead of letting the loader error propagate. Selecting a locale whose translation files do not exist yet crashed server route loaders (such as the TanStack Start root loader) with an HTTP 500 in development; content for that locale now renders untranslated. Because the failed locale is omitted rather than hydrated as an empty cache entry, a later lookup retries the loader once translations exist.
38
+
3
39
  ## 11.1.12
4
40
 
5
41
  ## 11.1.11
@@ -1,2 +1,2 @@
1
- const e=require(`../../i18n-cache/singleton-operations.cjs`);async function t(t){let n=await e.getReactI18nCache().loadTranslations(t);return{[t]:n}}exports.getTranslationsSnapshot=t;
1
+ require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../i18n-cache/singleton-operations.cjs`);let t=require(`generaltranslation/internal`);async function n(n){let r=e.getReactI18nCache();try{return{[n]:await r.loadTranslations(n)}}catch(e){return console.warn((0,t.createDiagnosticMessage)({source:`@generaltranslation/react-core`,severity:`Warning`,whatHappened:`Could not load translations for locale "${n}", so content for this locale renders untranslated`,why:`the translation loader failed, usually because translations for this locale have not been generated yet`,fix:`Generate translations for this locale, or check your loadTranslations configuration.`,details:(0,t.formatDiagnosticErrorDetails)(e)})),{}}}exports.getTranslationsSnapshot=n;
2
2
  //# sourceMappingURL=getTranslationsSnapshot.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"getTranslationsSnapshot.cjs","names":["getReactI18nCache"],"sources":["../../../src/functions/helpers/getTranslationsSnapshot.ts"],"sourcesContent":["import { Hash, Locale } from 'gt-i18n/internal/types';\nimport { Translation } from 'gt-i18n/types';\nimport { getReactI18nCache } from '../../i18n-cache/singleton-operations';\n\n/**\n * Returns a promise of serializable cached translations that\n * can be passed to a provider for hydration\n *\n * TODO: perhaps should be moved to /i18n if allowing for type generics\n */\nexport async function getTranslationsSnapshot(\n locale: Locale\n): Promise<Record<Locale, Record<Hash, Translation>>> {\n const i18nCache = getReactI18nCache();\n const translations = await i18nCache.loadTranslations(locale);\n // Only pass translations for the given locale to minimize the size of the snapshot\n return { [locale]: translations };\n}\n"],"mappings":"6DAUA,eAAsB,EACpB,EACoD,CAEpD,IAAM,EAAe,MADHA,EAAAA,mBACkB,CAAC,iBAAiB,EAAO,CAE7D,MAAO,EAAG,GAAS,EAAc"}
1
+ {"version":3,"file":"getTranslationsSnapshot.cjs","names":["getReactI18nCache"],"sources":["../../../src/functions/helpers/getTranslationsSnapshot.ts"],"sourcesContent":["import { Hash, Locale } from 'gt-i18n/internal/types';\nimport { Translation } from 'gt-i18n/types';\nimport {\n createDiagnosticMessage,\n formatDiagnosticErrorDetails,\n} from 'generaltranslation/internal';\nimport { getReactI18nCache } from '../../i18n-cache/singleton-operations';\n\n/**\n * Serializable cached translations for provider hydration; a failed load\n * yields a snapshot with no entry for the locale, so hydration caches nothing\n * and a later lookup retries. TODO: perhaps move to /i18n for type generics\n */\nexport async function getTranslationsSnapshot(\n locale: Locale\n): Promise<Record<Locale, Record<Hash, Translation>>> {\n const i18nCache = getReactI18nCache();\n try {\n return { [locale]: await i18nCache.loadTranslations(locale) };\n } catch (error) {\n console.warn(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Warning',\n whatHappened: `Could not load translations for locale \"${locale}\", so content for this locale renders untranslated`,\n why: 'the translation loader failed, usually because translations for this locale have not been generated yet',\n fix: 'Generate translations for this locale, or check your loadTranslations configuration.',\n details: formatDiagnosticErrorDetails(error),\n })\n );\n return {};\n }\n}\n"],"mappings":"0JAaA,eAAsB,EACpB,EACoD,CACpD,IAAM,EAAYA,EAAAA,mBAAmB,CACrC,GAAI,CACF,MAAO,EAAG,GAAS,MAAM,EAAU,iBAAiB,EAAO,CAAE,OACtD,EAAO,CAWd,OAVA,QAAQ,MAAA,EAAA,EAAA,yBACkB,CACtB,OAAQ,iCACR,SAAU,UACV,aAAc,2CAA2C,EAAO,oDAChE,IAAK,0GACL,IAAK,uFACL,SAAA,EAAA,EAAA,8BAAsC,EAAM,CAC7C,CAAC,CACH,CACM,EAAE"}
@@ -3,10 +3,9 @@ import { Hash, Locale } from "gt-i18n/internal/types";
3
3
 
4
4
  //#region src/functions/helpers/getTranslationsSnapshot.d.ts
5
5
  /**
6
- * Returns a promise of serializable cached translations that
7
- * can be passed to a provider for hydration
8
- *
9
- * TODO: perhaps should be moved to /i18n if allowing for type generics
6
+ * Serializable cached translations for provider hydration; a failed load
7
+ * yields a snapshot with no entry for the locale, so hydration caches nothing
8
+ * and a later lookup retries. TODO: perhaps move to /i18n for type generics
10
9
  */
11
10
  declare function getTranslationsSnapshot(locale: Locale): Promise<Record<Locale, Record<Hash, Translation>>>;
12
11
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"getTranslationsSnapshot.d.ts","names":[],"sources":["../../../src/functions/helpers/getTranslationsSnapshot.ts"],"mappings":";;;;;;AAUA;;;;iBAAsB,uBAAA,CACpB,MAAA,EAAQ,MAAA,GACP,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAQ,MAAA,CAAO,IAAA,EAAM,WAAA"}
1
+ {"version":3,"file":"getTranslationsSnapshot.d.ts","names":[],"sources":["../../../src/functions/helpers/getTranslationsSnapshot.ts"],"mappings":";;;;;;AAaA;;;iBAAsB,uBAAA,CACpB,MAAA,EAAQ,MAAA,GACP,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAQ,MAAA,CAAO,IAAA,EAAM,WAAA"}
@@ -1,2 +1,2 @@
1
- import{getReactI18nCache as e}from"../../i18n-cache/singleton-operations.mjs";async function t(t){let n=await e().loadTranslations(t);return{[t]:n}}export{t as getTranslationsSnapshot};
1
+ import{getReactI18nCache as e}from"../../i18n-cache/singleton-operations.mjs";import{createDiagnosticMessage as t,formatDiagnosticErrorDetails as n}from"generaltranslation/internal";async function r(r){let i=e();try{return{[r]:await i.loadTranslations(r)}}catch(e){return console.warn(t({source:`@generaltranslation/react-core`,severity:`Warning`,whatHappened:`Could not load translations for locale "${r}", so content for this locale renders untranslated`,why:`the translation loader failed, usually because translations for this locale have not been generated yet`,fix:`Generate translations for this locale, or check your loadTranslations configuration.`,details:n(e)})),{}}}export{r as getTranslationsSnapshot};
2
2
  //# sourceMappingURL=getTranslationsSnapshot.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"getTranslationsSnapshot.mjs","names":[],"sources":["../../../src/functions/helpers/getTranslationsSnapshot.ts"],"sourcesContent":["import { Hash, Locale } from 'gt-i18n/internal/types';\nimport { Translation } from 'gt-i18n/types';\nimport { getReactI18nCache } from '../../i18n-cache/singleton-operations';\n\n/**\n * Returns a promise of serializable cached translations that\n * can be passed to a provider for hydration\n *\n * TODO: perhaps should be moved to /i18n if allowing for type generics\n */\nexport async function getTranslationsSnapshot(\n locale: Locale\n): Promise<Record<Locale, Record<Hash, Translation>>> {\n const i18nCache = getReactI18nCache();\n const translations = await i18nCache.loadTranslations(locale);\n // Only pass translations for the given locale to minimize the size of the snapshot\n return { [locale]: translations };\n}\n"],"mappings":"8EAUA,eAAsB,EACpB,EACoD,CAEpD,IAAM,EAAe,MADH,GACkB,CAAC,iBAAiB,EAAO,CAE7D,MAAO,EAAG,GAAS,EAAc"}
1
+ {"version":3,"file":"getTranslationsSnapshot.mjs","names":[],"sources":["../../../src/functions/helpers/getTranslationsSnapshot.ts"],"sourcesContent":["import { Hash, Locale } from 'gt-i18n/internal/types';\nimport { Translation } from 'gt-i18n/types';\nimport {\n createDiagnosticMessage,\n formatDiagnosticErrorDetails,\n} from 'generaltranslation/internal';\nimport { getReactI18nCache } from '../../i18n-cache/singleton-operations';\n\n/**\n * Serializable cached translations for provider hydration; a failed load\n * yields a snapshot with no entry for the locale, so hydration caches nothing\n * and a later lookup retries. TODO: perhaps move to /i18n for type generics\n */\nexport async function getTranslationsSnapshot(\n locale: Locale\n): Promise<Record<Locale, Record<Hash, Translation>>> {\n const i18nCache = getReactI18nCache();\n try {\n return { [locale]: await i18nCache.loadTranslations(locale) };\n } catch (error) {\n console.warn(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Warning',\n whatHappened: `Could not load translations for locale \"${locale}\", so content for this locale renders untranslated`,\n why: 'the translation loader failed, usually because translations for this locale have not been generated yet',\n fix: 'Generate translations for this locale, or check your loadTranslations configuration.',\n details: formatDiagnosticErrorDetails(error),\n })\n );\n return {};\n }\n}\n"],"mappings":"sLAaA,eAAsB,EACpB,EACoD,CACpD,IAAM,EAAY,GAAmB,CACrC,GAAI,CACF,MAAO,EAAG,GAAS,MAAM,EAAU,iBAAiB,EAAO,CAAE,OACtD,EAAO,CAWd,OAVA,QAAQ,KACN,EAAwB,CACtB,OAAQ,iCACR,SAAU,UACV,aAAc,2CAA2C,EAAO,oDAChE,IAAK,0GACL,IAAK,uFACL,QAAS,EAA6B,EAAM,CAC7C,CAAC,CACH,CACM,EAAE"}
@@ -1,2 +1,2 @@
1
- require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../i18n-cache/singleton-operations.cjs`),t=require(`./utils/subscriptions.cjs`),n=require(`./utils/translations.cjs`),r=require(`./utils/dictionaries.cjs`);let i=require(`gt-i18n/internal`);var a=class{translateListeners=new Set;dictionaryEntryListeners=new Set;dictionaryObjectListeners=new Set;constructor(){}updateTranslations=t=>{e.getReactI18nCache().updateTranslations(t)};updateDictionaries=t=>{e.getReactI18nCache().updateDictionaries(t)};translate=async t=>e.getReactI18nCache().lookupTranslationWithFallback(t.locale,t.message,t.options).then(e=>{this.emitTranslateEvent(t)});translateDictionaryEntry=t=>{e.getReactI18nCache().lookupDictionaryWithFallback(t.locale,t.id).then(e=>{this.emitDictionaryEvent(t)})};translateDictionaryObject=t=>{e.getReactI18nCache().lookupDictionaryObjWithFallback(t.locale,t.id).then(e=>{this.emitDictionaryEvent(t)})};subscribeToTranslate=(e,n)=>{let r=(0,i.getTranslateListenerKey)(e);return t.subscribeToSet(this.translateListeners,e=>{(0,i.getTranslateListenerKey)(e)===r&&n()})};subscribeToTranslationEvents=e=>t.subscribeToSet(this.translateListeners,e);subscribeToDictionaryEntryEvents=e=>t.subscribeToSet(this.dictionaryEntryListeners,e);subscribeToDictionaryObjectEvents=e=>t.subscribeToSet(this.dictionaryObjectListeners,e);getTranslateSnapshot=(t,r={})=>n.lookupTranslation(r,t)??e.getReactI18nCache().lookupTranslation(t.locale,t.message,t.options);getDictionaryEntrySnapshot=(t,n={})=>r.lookupDictionaryEntry(n,t)??e.getReactI18nCache().lookupDictionary(t.locale,t.id);getDictionaryObjectSnapshot=(t,n={})=>r.lookupDictionaryObject(n,t)??e.getReactI18nCache().lookupDictionaryObj(t.locale,t.id);emitTranslateEvent(e){this.translateListeners.forEach(t=>t(e))}emitDictionaryEvent(e){this.dictionaryEntryListeners.forEach(t=>t(e)),this.dictionaryObjectListeners.forEach(t=>{t(e)})}};exports.I18nStore=a;
1
+ require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../i18n-cache/singleton-operations.cjs`),t=require(`./utils/subscriptions.cjs`),n=require(`./utils/translations.cjs`),r=require(`./utils/dictionaries.cjs`);let i=require(`gt-i18n/internal`),a=require(`generaltranslation/internal`);function o(e){if(e instanceof Error)return`${e.name}|${e.message}`;if(typeof e==`object`&&e)try{return`object|${JSON.stringify(e)}`}catch{return`object|${String(e)}`}return`${typeof e}|${String(e)}`}var s=class{translateListeners=new Set;dictionaryEntryListeners=new Set;dictionaryObjectListeners=new Set;loggedRuntimeTranslationErrors=new Set;constructor(){}updateTranslations=t=>{e.getReactI18nCache().updateTranslations(t)};updateDictionaries=t=>{e.getReactI18nCache().updateDictionaries(t)};translate=async t=>e.getReactI18nCache().lookupTranslationWithFallback(t.locale,t.message,t.options).then(()=>{this.emitTranslateEvent(t)}).catch(e=>this.logRuntimeTranslationError(e));translateDictionaryEntry=t=>{e.getReactI18nCache().lookupDictionaryWithFallback(t.locale,t.id).then(()=>{this.emitDictionaryEvent(t)}).catch(e=>this.logRuntimeTranslationError(e))};translateDictionaryObject=t=>{e.getReactI18nCache().lookupDictionaryObjWithFallback(t.locale,t.id).then(()=>{this.emitDictionaryEvent(t)}).catch(e=>this.logRuntimeTranslationError(e))};logRuntimeTranslationError(e){let t=(0,a.formatDiagnosticErrorDetails)(e),n=o(e);if(!this.loggedRuntimeTranslationErrors.has(n)){if(this.loggedRuntimeTranslationErrors.add(n),this.loggedRuntimeTranslationErrors.size>100){let e=this.loggedRuntimeTranslationErrors.values().next().value;e!==void 0&&this.loggedRuntimeTranslationErrors.delete(e)}console.error((0,a.createDiagnosticMessage)({source:`@generaltranslation/react-core`,severity:`Error`,whatHappened:`A runtime translation request failed.`,wayOut:`Rendering falls back to untranslated content.`,details:t}))}}subscribeToTranslate=(e,n)=>{let r=(0,i.getTranslateListenerKey)(e);return t.subscribeToSet(this.translateListeners,e=>{(0,i.getTranslateListenerKey)(e)===r&&n()})};subscribeToTranslationEvents=e=>t.subscribeToSet(this.translateListeners,e);subscribeToDictionaryEntryEvents=e=>t.subscribeToSet(this.dictionaryEntryListeners,e);subscribeToDictionaryObjectEvents=e=>t.subscribeToSet(this.dictionaryObjectListeners,e);getTranslateSnapshot=(t,r={})=>n.lookupTranslation(r,t)??e.getReactI18nCache().lookupTranslation(t.locale,t.message,t.options);getDictionaryEntrySnapshot=(t,n={})=>r.lookupDictionaryEntry(n,t)??e.getReactI18nCache().lookupDictionary(t.locale,t.id);getDictionaryObjectSnapshot=(t,n={})=>r.lookupDictionaryObject(n,t)??e.getReactI18nCache().lookupDictionaryObj(t.locale,t.id);emitTranslateEvent(e){this.translateListeners.forEach(t=>t(e))}emitDictionaryEvent(e){this.dictionaryEntryListeners.forEach(t=>t(e)),this.dictionaryObjectListeners.forEach(t=>{t(e)})}};exports.I18nStore=s;
2
2
  //# sourceMappingURL=I18nStore.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"I18nStore.cjs","names":["getReactI18nCache","subscribeToSet","lookupTranslation","lookupDictionaryEntry","lookupDictionaryObject"],"sources":["../../src/i18n-store/I18nStore.ts"],"sourcesContent":["import { getTranslateListenerKey } from 'gt-i18n/internal';\nimport type {\n DictionaryEntrySnapshot,\n DictionaryLookup,\n DictionaryObjectSnapshot,\n StoreListener,\n TranslateEventListener,\n TranslateLookup,\n TranslateSnapshot,\n Unsubscribe,\n} from './storeTypes';\nimport type { Dictionary, Translation } from 'gt-i18n/types';\nimport { subscribeToSet } from './utils/subscriptions';\nimport { Hash, Locale } from 'gt-i18n/internal/types';\nimport { getReactI18nCache } from '../i18n-cache/singleton-operations';\nimport { lookupTranslation } from './utils/translations';\nimport {\n lookupDictionaryEntry,\n lookupDictionaryObject,\n} from './utils/dictionaries';\n\nexport type DictionaryStoreListener = (event: DictionaryLookup) => void;\n\n/**\n * I18nStore gives us the ability to perform client-side updates to translations.\n * Primarily useful for dev hot reload.\n *\n * This is the stateful primitive behind lookup subscriptions and runtime\n * translation requests. It intentionally does not know whether lookups are\n * being served from SPA singletons or SRA provider snapshots; that policy lives\n * in LookupAdapter, not in this store.\n */\nexport class I18nStore {\n // ----- Listener Sets ----- //\n\n private translateListeners = new Set<TranslateEventListener>();\n private dictionaryEntryListeners = new Set<DictionaryStoreListener>();\n private dictionaryObjectListeners = new Set<DictionaryStoreListener>();\n\n /**\n * I18nCache must be already initialized\n */\n constructor() {}\n\n // ========== Translation Updates ========== //\n\n updateTranslations = (\n translations: Record<Locale, Record<Hash, Translation>>\n ): void => {\n getReactI18nCache().updateTranslations(translations);\n };\n\n updateDictionaries = (dictionaries: Record<Locale, Dictionary>): void => {\n getReactI18nCache().updateDictionaries(dictionaries);\n };\n\n // ========== runtime translation ========== //\n\n translate = async <T extends Translation>(\n lookup: TranslateLookup<T>\n ): Promise<void> => {\n return getReactI18nCache()\n .lookupTranslationWithFallback(\n lookup.locale,\n lookup.message,\n lookup.options\n )\n .then((translation) => {\n if (translation == null) {\n // TODO: warn about runtime translation failure\n }\n this.emitTranslateEvent(lookup);\n });\n };\n\n translateDictionaryEntry = (lookup: DictionaryLookup): void => {\n getReactI18nCache()\n .lookupDictionaryWithFallback(lookup.locale, lookup.id)\n .then((dictionaryEntry) => {\n if (dictionaryEntry == null) {\n // TODO: warn about runtime dictionary translation failure\n }\n this.emitDictionaryEvent(lookup);\n });\n };\n\n translateDictionaryObject = (lookup: DictionaryLookup): void => {\n getReactI18nCache()\n .lookupDictionaryObjWithFallback(lookup.locale, lookup.id)\n .then((dictionaryObject) => {\n if (dictionaryObject == null) {\n // TODO: warn about runtime dictionary translation failure\n }\n this.emitDictionaryEvent(lookup);\n });\n };\n\n // ========== UseSyncExternalStore ========== //\n\n // ----- Subscriptions ----- //\n\n // Keep subscription methods as arrow fields so hooks can pass them by\n // reference without losing access to this store instance.\n subscribeToTranslate = <T extends Translation>(\n lookup: TranslateLookup<T>,\n listener: StoreListener\n ): Unsubscribe => {\n const lookupKey = getTranslateListenerKey(lookup);\n const wrappedListener: TranslateEventListener = (lookup) => {\n if (getTranslateListenerKey(lookup) === lookupKey) {\n listener();\n }\n };\n return subscribeToSet(this.translateListeners, wrappedListener);\n };\n\n subscribeToTranslationEvents = (\n listener: TranslateEventListener\n ): Unsubscribe => {\n return subscribeToSet(this.translateListeners, listener);\n };\n\n subscribeToDictionaryEntryEvents = (\n listener: DictionaryStoreListener\n ): Unsubscribe => {\n return subscribeToSet(this.dictionaryEntryListeners, listener);\n };\n\n subscribeToDictionaryObjectEvents = (\n listener: DictionaryStoreListener\n ): Unsubscribe => {\n return subscribeToSet(this.dictionaryObjectListeners, listener);\n };\n\n // ----- Snapshots ----- //\n\n getTranslateSnapshot = <T extends Translation>(\n lookup: TranslateLookup<T>,\n translationsSnapshot: Record<Locale, Record<Hash, Translation>> = {}\n ): TranslateSnapshot<T> => {\n return (\n lookupTranslation(translationsSnapshot, lookup) ??\n getReactI18nCache().lookupTranslation<T>(\n lookup.locale,\n lookup.message,\n lookup.options\n )\n );\n };\n\n getDictionaryEntrySnapshot = (\n lookup: DictionaryLookup,\n dictionariesSnapshot: Record<Locale, Dictionary> = {}\n ): DictionaryEntrySnapshot => {\n return (\n lookupDictionaryEntry(dictionariesSnapshot, lookup) ??\n getReactI18nCache().lookupDictionary(lookup.locale, lookup.id)\n );\n };\n\n getDictionaryObjectSnapshot = (\n lookup: DictionaryLookup,\n dictionariesSnapshot: Record<Locale, Dictionary> = {}\n ): DictionaryObjectSnapshot => {\n return (\n lookupDictionaryObject(dictionariesSnapshot, lookup) ??\n getReactI18nCache().lookupDictionaryObj(lookup.locale, lookup.id)\n );\n };\n\n // ----- Listener Utilities ----- //\n\n private emitTranslateEvent(event: TranslateLookup): void {\n this.translateListeners.forEach((listener) => listener(event));\n }\n\n private emitDictionaryEvent(event: DictionaryLookup): void {\n this.dictionaryEntryListeners.forEach((listener) => listener(event));\n this.dictionaryObjectListeners.forEach((listener) => {\n listener(event);\n });\n }\n}\n"],"mappings":"4PAgCA,IAAa,EAAb,KAAuB,CAGrB,mBAA6B,IAAI,IACjC,yBAAmC,IAAI,IACvC,0BAAoC,IAAI,IAKxC,aAAc,EAId,mBACE,GACS,CACT,EAAA,mBAAmB,CAAC,mBAAmB,EAAa,EAGtD,mBAAsB,GAAmD,CACvE,EAAA,mBAAmB,CAAC,mBAAmB,EAAa,EAKtD,UAAY,KACV,IAEOA,EAAAA,mBAAmB,CACvB,8BACC,EAAO,OACP,EAAO,QACP,EAAO,QACR,CACA,KAAM,GAAgB,CAIrB,KAAK,mBAAmB,EAAO,EAC/B,CAGN,yBAA4B,GAAmC,CAC7D,EAAA,mBAAmB,CAChB,6BAA6B,EAAO,OAAQ,EAAO,GAAG,CACtD,KAAM,GAAoB,CAIzB,KAAK,oBAAoB,EAAO,EAChC,EAGN,0BAA6B,GAAmC,CAC9D,EAAA,mBAAmB,CAChB,gCAAgC,EAAO,OAAQ,EAAO,GAAG,CACzD,KAAM,GAAqB,CAI1B,KAAK,oBAAoB,EAAO,EAChC,EASN,sBACE,EACA,IACgB,CAChB,IAAM,GAAA,EAAA,EAAA,yBAAoC,EAAO,CAMjD,OAAOC,EAAAA,eAAe,KAAK,mBALsB,GAAW,EAC1D,EAAA,EAAA,yBAA4B,EAAO,GAAK,GACtC,GAAU,EAGiD,EAGjE,6BACE,GAEOA,EAAAA,eAAe,KAAK,mBAAoB,EAAS,CAG1D,iCACE,GAEOA,EAAAA,eAAe,KAAK,yBAA0B,EAAS,CAGhE,kCACE,GAEOA,EAAAA,eAAe,KAAK,0BAA2B,EAAS,CAKjE,sBACE,EACA,EAAkE,EAAE,GAGlEC,EAAAA,kBAAkB,EAAsB,EAAO,EAC/CF,EAAAA,mBAAmB,CAAC,kBAClB,EAAO,OACP,EAAO,QACP,EAAO,QACR,CAIL,4BACE,EACA,EAAmD,EAAE,GAGnDG,EAAAA,sBAAsB,EAAsB,EAAO,EACnDH,EAAAA,mBAAmB,CAAC,iBAAiB,EAAO,OAAQ,EAAO,GAAG,CAIlE,6BACE,EACA,EAAmD,EAAE,GAGnDI,EAAAA,uBAAuB,EAAsB,EAAO,EACpDJ,EAAAA,mBAAmB,CAAC,oBAAoB,EAAO,OAAQ,EAAO,GAAG,CAMrE,mBAA2B,EAA8B,CACvD,KAAK,mBAAmB,QAAS,GAAa,EAAS,EAAM,CAAC,CAGhE,oBAA4B,EAA+B,CACzD,KAAK,yBAAyB,QAAS,GAAa,EAAS,EAAM,CAAC,CACpE,KAAK,0BAA0B,QAAS,GAAa,CACnD,EAAS,EAAM,EACf"}
1
+ {"version":3,"file":"I18nStore.cjs","names":["getReactI18nCache","subscribeToSet","lookupTranslation","lookupDictionaryEntry","lookupDictionaryObject"],"sources":["../../src/i18n-store/I18nStore.ts"],"sourcesContent":["import {\n createDiagnosticMessage,\n formatDiagnosticErrorDetails,\n} from 'generaltranslation/internal';\nimport { getTranslateListenerKey } from 'gt-i18n/internal';\nimport type {\n DictionaryEntrySnapshot,\n DictionaryLookup,\n DictionaryObjectSnapshot,\n StoreListener,\n TranslateEventListener,\n TranslateLookup,\n TranslateSnapshot,\n Unsubscribe,\n} from './storeTypes';\nimport type { Dictionary, Translation } from 'gt-i18n/types';\nimport { subscribeToSet } from './utils/subscriptions';\nimport { Hash, Locale } from 'gt-i18n/internal/types';\nimport { getReactI18nCache } from '../i18n-cache/singleton-operations';\nimport { lookupTranslation } from './utils/translations';\nimport {\n lookupDictionaryEntry,\n lookupDictionaryObject,\n} from './utils/dictionaries';\n\nexport type DictionaryStoreListener = (event: DictionaryLookup) => void;\n\nconst MAX_LOGGED_RUNTIME_TRANSLATION_ERRORS = 100;\n\nfunction getRuntimeTranslationErrorDedupeKey(error: unknown): string {\n if (error instanceof Error) {\n return `${error.name}|${error.message}`;\n }\n if (error !== null && typeof error === 'object') {\n try {\n return `object|${JSON.stringify(error)}`;\n } catch {\n return `object|${String(error)}`;\n }\n }\n return `${typeof error}|${String(error)}`;\n}\n\n/**\n * I18nStore gives us the ability to perform client-side updates to translations.\n * Primarily useful for dev hot reload.\n *\n * This is the stateful primitive behind lookup subscriptions and runtime\n * translation requests. It intentionally does not know whether lookups are\n * being served from SPA singletons or SRA provider snapshots; that policy lives\n * in LookupAdapter, not in this store.\n */\nexport class I18nStore {\n // ----- Listener Sets ----- //\n\n private translateListeners = new Set<TranslateEventListener>();\n private dictionaryEntryListeners = new Set<DictionaryStoreListener>();\n private dictionaryObjectListeners = new Set<DictionaryStoreListener>();\n private loggedRuntimeTranslationErrors = new Set<string>();\n\n /**\n * I18nCache must be already initialized\n */\n constructor() {}\n\n // ========== Translation Updates ========== //\n\n updateTranslations = (\n translations: Record<Locale, Record<Hash, Translation>>\n ): void => {\n getReactI18nCache().updateTranslations(translations);\n };\n\n updateDictionaries = (dictionaries: Record<Locale, Dictionary>): void => {\n getReactI18nCache().updateDictionaries(dictionaries);\n };\n\n // ========== runtime translation ========== //\n\n translate = async <T extends Translation>(\n lookup: TranslateLookup<T>\n ): Promise<void> => {\n return getReactI18nCache()\n .lookupTranslationWithFallback(\n lookup.locale,\n lookup.message,\n lookup.options\n )\n .then(() => {\n this.emitTranslateEvent(lookup);\n })\n .catch((error) => this.logRuntimeTranslationError(error));\n };\n\n translateDictionaryEntry = (lookup: DictionaryLookup): void => {\n getReactI18nCache()\n .lookupDictionaryWithFallback(lookup.locale, lookup.id)\n .then(() => {\n this.emitDictionaryEvent(lookup);\n })\n .catch((error) => this.logRuntimeTranslationError(error));\n };\n\n translateDictionaryObject = (lookup: DictionaryLookup): void => {\n getReactI18nCache()\n .lookupDictionaryObjWithFallback(lookup.locale, lookup.id)\n .then(() => {\n this.emitDictionaryEvent(lookup);\n })\n .catch((error) => this.logRuntimeTranslationError(error));\n };\n\n /**\n * Runtime translation runs fire-and-forget, so a rejected request (for\n * example a 401 from an invalid dev API key) is logged here instead of\n * escaping as an unhandled rejection that kills the dev server during SSR.\n * Identical failures log once.\n */\n private logRuntimeTranslationError(error: unknown): void {\n const details = formatDiagnosticErrorDetails(error);\n const dedupeKey = getRuntimeTranslationErrorDedupeKey(error);\n if (this.loggedRuntimeTranslationErrors.has(dedupeKey)) return;\n this.loggedRuntimeTranslationErrors.add(dedupeKey);\n if (\n this.loggedRuntimeTranslationErrors.size >\n MAX_LOGGED_RUNTIME_TRANSLATION_ERRORS\n ) {\n const oldest = this.loggedRuntimeTranslationErrors.values().next().value;\n if (oldest !== undefined) {\n this.loggedRuntimeTranslationErrors.delete(oldest);\n }\n }\n console.error(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Error',\n whatHappened: 'A runtime translation request failed.',\n wayOut: 'Rendering falls back to untranslated content.',\n details,\n })\n );\n }\n\n // ========== UseSyncExternalStore ========== //\n\n // ----- Subscriptions ----- //\n\n // Keep subscription methods as arrow fields so hooks can pass them by\n // reference without losing access to this store instance.\n subscribeToTranslate = <T extends Translation>(\n lookup: TranslateLookup<T>,\n listener: StoreListener\n ): Unsubscribe => {\n const lookupKey = getTranslateListenerKey(lookup);\n const wrappedListener: TranslateEventListener = (lookup) => {\n if (getTranslateListenerKey(lookup) === lookupKey) {\n listener();\n }\n };\n return subscribeToSet(this.translateListeners, wrappedListener);\n };\n\n subscribeToTranslationEvents = (\n listener: TranslateEventListener\n ): Unsubscribe => {\n return subscribeToSet(this.translateListeners, listener);\n };\n\n subscribeToDictionaryEntryEvents = (\n listener: DictionaryStoreListener\n ): Unsubscribe => {\n return subscribeToSet(this.dictionaryEntryListeners, listener);\n };\n\n subscribeToDictionaryObjectEvents = (\n listener: DictionaryStoreListener\n ): Unsubscribe => {\n return subscribeToSet(this.dictionaryObjectListeners, listener);\n };\n\n // ----- Snapshots ----- //\n\n getTranslateSnapshot = <T extends Translation>(\n lookup: TranslateLookup<T>,\n translationsSnapshot: Record<Locale, Record<Hash, Translation>> = {}\n ): TranslateSnapshot<T> => {\n return (\n lookupTranslation(translationsSnapshot, lookup) ??\n getReactI18nCache().lookupTranslation<T>(\n lookup.locale,\n lookup.message,\n lookup.options\n )\n );\n };\n\n getDictionaryEntrySnapshot = (\n lookup: DictionaryLookup,\n dictionariesSnapshot: Record<Locale, Dictionary> = {}\n ): DictionaryEntrySnapshot => {\n return (\n lookupDictionaryEntry(dictionariesSnapshot, lookup) ??\n getReactI18nCache().lookupDictionary(lookup.locale, lookup.id)\n );\n };\n\n getDictionaryObjectSnapshot = (\n lookup: DictionaryLookup,\n dictionariesSnapshot: Record<Locale, Dictionary> = {}\n ): DictionaryObjectSnapshot => {\n return (\n lookupDictionaryObject(dictionariesSnapshot, lookup) ??\n getReactI18nCache().lookupDictionaryObj(lookup.locale, lookup.id)\n );\n };\n\n // ----- Listener Utilities ----- //\n\n private emitTranslateEvent(event: TranslateLookup): void {\n this.translateListeners.forEach((listener) => listener(event));\n }\n\n private emitDictionaryEvent(event: DictionaryLookup): void {\n this.dictionaryEntryListeners.forEach((listener) => listener(event));\n this.dictionaryObjectListeners.forEach((listener) => {\n listener(event);\n });\n }\n}\n"],"mappings":"qSA6BA,SAAS,EAAoC,EAAwB,CACnE,GAAI,aAAiB,MACnB,MAAO,GAAG,EAAM,KAAK,GAAG,EAAM,UAEhC,GAAsB,OAAO,GAAU,UAAnC,EACF,GAAI,CACF,MAAO,UAAU,KAAK,UAAU,EAAM,QAChC,CACN,MAAO,UAAU,OAAO,EAAM,GAGlC,MAAO,GAAG,OAAO,EAAM,GAAG,OAAO,EAAM,GAYzC,IAAa,EAAb,KAAuB,CAGrB,mBAA6B,IAAI,IACjC,yBAAmC,IAAI,IACvC,0BAAoC,IAAI,IACxC,+BAAyC,IAAI,IAK7C,aAAc,EAId,mBACE,GACS,CACT,EAAA,mBAAmB,CAAC,mBAAmB,EAAa,EAGtD,mBAAsB,GAAmD,CACvE,EAAA,mBAAmB,CAAC,mBAAmB,EAAa,EAKtD,UAAY,KACV,IAEOA,EAAAA,mBAAmB,CACvB,8BACC,EAAO,OACP,EAAO,QACP,EAAO,QACR,CACA,SAAW,CACV,KAAK,mBAAmB,EAAO,EAC/B,CACD,MAAO,GAAU,KAAK,2BAA2B,EAAM,CAAC,CAG7D,yBAA4B,GAAmC,CAC7D,EAAA,mBAAmB,CAChB,6BAA6B,EAAO,OAAQ,EAAO,GAAG,CACtD,SAAW,CACV,KAAK,oBAAoB,EAAO,EAChC,CACD,MAAO,GAAU,KAAK,2BAA2B,EAAM,CAAC,EAG7D,0BAA6B,GAAmC,CAC9D,EAAA,mBAAmB,CAChB,gCAAgC,EAAO,OAAQ,EAAO,GAAG,CACzD,SAAW,CACV,KAAK,oBAAoB,EAAO,EAChC,CACD,MAAO,GAAU,KAAK,2BAA2B,EAAM,CAAC,EAS7D,2BAAmC,EAAsB,CACvD,IAAM,GAAA,EAAA,EAAA,8BAAuC,EAAM,CAC7C,EAAY,EAAoC,EAAM,CACxD,SAAK,+BAA+B,IAAI,EAAU,CAEtD,IADA,KAAK,+BAA+B,IAAI,EAAU,CAEhD,KAAK,+BAA+B,KACpC,IACA,CACA,IAAM,EAAS,KAAK,+BAA+B,QAAQ,CAAC,MAAM,CAAC,MAC/D,IAAW,IAAA,IACb,KAAK,+BAA+B,OAAO,EAAO,CAGtD,QAAQ,OAAA,EAAA,EAAA,yBACkB,CACtB,OAAQ,iCACR,SAAU,QACV,aAAc,wCACd,OAAQ,gDACR,UACD,CAAC,CACH,EASH,sBACE,EACA,IACgB,CAChB,IAAM,GAAA,EAAA,EAAA,yBAAoC,EAAO,CAMjD,OAAOC,EAAAA,eAAe,KAAK,mBALsB,GAAW,EAC1D,EAAA,EAAA,yBAA4B,EAAO,GAAK,GACtC,GAAU,EAGiD,EAGjE,6BACE,GAEOA,EAAAA,eAAe,KAAK,mBAAoB,EAAS,CAG1D,iCACE,GAEOA,EAAAA,eAAe,KAAK,yBAA0B,EAAS,CAGhE,kCACE,GAEOA,EAAAA,eAAe,KAAK,0BAA2B,EAAS,CAKjE,sBACE,EACA,EAAkE,EAAE,GAGlEC,EAAAA,kBAAkB,EAAsB,EAAO,EAC/CF,EAAAA,mBAAmB,CAAC,kBAClB,EAAO,OACP,EAAO,QACP,EAAO,QACR,CAIL,4BACE,EACA,EAAmD,EAAE,GAGnDG,EAAAA,sBAAsB,EAAsB,EAAO,EACnDH,EAAAA,mBAAmB,CAAC,iBAAiB,EAAO,OAAQ,EAAO,GAAG,CAIlE,6BACE,EACA,EAAmD,EAAE,GAGnDI,EAAAA,uBAAuB,EAAsB,EAAO,EACpDJ,EAAAA,mBAAmB,CAAC,oBAAoB,EAAO,OAAQ,EAAO,GAAG,CAMrE,mBAA2B,EAA8B,CACvD,KAAK,mBAAmB,QAAS,GAAa,EAAS,EAAM,CAAC,CAGhE,oBAA4B,EAA+B,CACzD,KAAK,yBAAyB,QAAS,GAAa,EAAS,EAAM,CAAC,CACpE,KAAK,0BAA0B,QAAS,GAAa,CACnD,EAAS,EAAM,EACf"}
@@ -17,6 +17,7 @@ declare class I18nStore {
17
17
  private translateListeners;
18
18
  private dictionaryEntryListeners;
19
19
  private dictionaryObjectListeners;
20
+ private loggedRuntimeTranslationErrors;
20
21
  /**
21
22
  * I18nCache must be already initialized
22
23
  */
@@ -26,6 +27,13 @@ declare class I18nStore {
26
27
  translate: <T extends Translation>(lookup: TranslateLookup<T>) => Promise<void>;
27
28
  translateDictionaryEntry: (lookup: DictionaryLookup) => void;
28
29
  translateDictionaryObject: (lookup: DictionaryLookup) => void;
30
+ /**
31
+ * Runtime translation runs fire-and-forget, so a rejected request (for
32
+ * example a 401 from an invalid dev API key) is logged here instead of
33
+ * escaping as an unhandled rejection that kills the dev server during SSR.
34
+ * Identical failures log once.
35
+ */
36
+ private logRuntimeTranslationError;
29
37
  subscribeToTranslate: <T extends Translation>(lookup: TranslateLookup<T>, listener: StoreListener) => Unsubscribe;
30
38
  subscribeToTranslationEvents: (listener: TranslateEventListener) => Unsubscribe;
31
39
  subscribeToDictionaryEntryEvents: (listener: DictionaryStoreListener) => Unsubscribe;
@@ -1 +1 @@
1
- {"version":3,"file":"I18nStore.d.ts","names":[],"sources":["../../src/i18n-store/I18nStore.ts"],"mappings":";;;;;KAqBY,uBAAA,IAA2B,KAAA,EAAO,gBAAA;;AAA9C;;;;;AAWA;;;cAAa,SAAA;EAAA,QAGH,kBAAA;EAAA,QACA,wBAAA;EAAA,QACA,yBAAA;EAUQ;;;;EADhB,kBAAA,GACE,YAAA,EAAc,MAAA,CAAO,MAAA,EAAQ,MAAA,CAAO,IAAA,EAAM,WAAA;EAK5C,kBAAA,GAAsB,YAAA,EAAc,MAAA,CAAO,MAAA,EAAQ,UAAA;EAMnD,SAAA,aAA6B,WAAA,EAC3B,MAAA,EAAQ,eAAA,CAAgB,CAAA,MACvB,OAAA;EAeH,wBAAA,GAA4B,MAAA,EAAQ,gBAAA;EAWpC,yBAAA,GAA6B,MAAA,EAAQ,gBAAA;EAiBrC,oBAAA,aAAkC,WAAA,EAChC,MAAA,EAAQ,eAAA,CAAgB,CAAA,GACxB,QAAA,EAAU,aAAA,KACT,WAAA;EAUH,4BAAA,GACE,QAAA,EAAU,sBAAA,KACT,WAAA;EAIH,gCAAA,GACE,QAAA,EAAU,uBAAA,KACT,WAAA;EAIH,iCAAA,GACE,QAAA,EAAU,uBAAA,KACT,WAAA;EAMH,oBAAA,aAAkC,WAAA,EAChC,MAAA,EAAQ,eAAA,CAAgB,CAAA,GACxB,oBAAA,GAAsB,MAAA,CAAO,MAAA,EAAQ,MAAA,CAAO,IAAA,EAAM,WAAA,OACjD,iBAAA,CAAkB,CAAA;EAWrB,0BAAA,GACE,MAAA,EAAQ,gBAAA,EACR,oBAAA,GAAsB,MAAA,CAAO,MAAA,EAAQ,UAAA,MACpC,uBAAA;EAOH,2BAAA,GACE,MAAA,EAAQ,gBAAA,EACR,oBAAA,GAAsB,MAAA,CAAO,MAAA,EAAQ,UAAA,MACpC,wBAAA;EAAA,QASK,kBAAA;EAAA,QAIA,mBAAA;AAAA"}
1
+ {"version":3,"file":"I18nStore.d.ts","names":[],"sources":["../../src/i18n-store/I18nStore.ts"],"mappings":";;;;;KAyBY,uBAAA,IAA2B,KAAA,EAAO,gBAAA;;AAA9C;;;;;AA2BA;;;cAAa,SAAA;EAAA,QAGH,kBAAA;EAAA,QACA,wBAAA;EAAA,QACA,yBAAA;EAAA,QACA,8BAAA;EAemC;;;;EAN3C,kBAAA,GACE,YAAA,EAAc,MAAA,CAAO,MAAA,EAAQ,MAAA,CAAO,IAAA,EAAM,WAAA;EAK5C,kBAAA,GAAsB,YAAA,EAAc,MAAA,CAAO,MAAA,EAAQ,UAAA;EAMnD,SAAA,aAA6B,WAAA,EAC3B,MAAA,EAAQ,eAAA,CAAgB,CAAA,MACvB,OAAA;EAaH,wBAAA,GAA4B,MAAA,EAAQ,gBAAA;EASpC,yBAAA,GAA6B,MAAA,EAAQ,gBAAA;EA8CH;;;;;;EAAA,QA/B1B,0BAAA;EA+BR,oBAAA,aAAkC,WAAA,EAChC,MAAA,EAAQ,eAAA,CAAgB,CAAA,GACxB,QAAA,EAAU,aAAA,KACT,WAAA;EAUH,4BAAA,GACE,QAAA,EAAU,sBAAA,KACT,WAAA;EAIH,gCAAA,GACE,QAAA,EAAU,uBAAA,KACT,WAAA;EAIH,iCAAA,GACE,QAAA,EAAU,uBAAA,KACT,WAAA;EAMH,oBAAA,aAAkC,WAAA,EAChC,MAAA,EAAQ,eAAA,CAAgB,CAAA,GACxB,oBAAA,GAAsB,MAAA,CAAO,MAAA,EAAQ,MAAA,CAAO,IAAA,EAAM,WAAA,OACjD,iBAAA,CAAkB,CAAA;EAWrB,0BAAA,GACE,MAAA,EAAQ,gBAAA,EACR,oBAAA,GAAsB,MAAA,CAAO,MAAA,EAAQ,UAAA,MACpC,uBAAA;EAOH,2BAAA,GACE,MAAA,EAAQ,gBAAA,EACR,oBAAA,GAAsB,MAAA,CAAO,MAAA,EAAQ,UAAA,MACpC,wBAAA;EAAA,QASK,kBAAA;EAAA,QAIA,mBAAA;AAAA"}
@@ -1,2 +1,2 @@
1
- import{getReactI18nCache as e}from"../i18n-cache/singleton-operations.mjs";import{subscribeToSet as t}from"./utils/subscriptions.mjs";import{lookupTranslation as n}from"./utils/translations.mjs";import{lookupDictionaryEntry as r,lookupDictionaryObject as i}from"./utils/dictionaries.mjs";import{getTranslateListenerKey as a}from"gt-i18n/internal";var o=class{translateListeners=new Set;dictionaryEntryListeners=new Set;dictionaryObjectListeners=new Set;constructor(){}updateTranslations=t=>{e().updateTranslations(t)};updateDictionaries=t=>{e().updateDictionaries(t)};translate=async t=>e().lookupTranslationWithFallback(t.locale,t.message,t.options).then(e=>{this.emitTranslateEvent(t)});translateDictionaryEntry=t=>{e().lookupDictionaryWithFallback(t.locale,t.id).then(e=>{this.emitDictionaryEvent(t)})};translateDictionaryObject=t=>{e().lookupDictionaryObjWithFallback(t.locale,t.id).then(e=>{this.emitDictionaryEvent(t)})};subscribeToTranslate=(e,n)=>{let r=a(e);return t(this.translateListeners,e=>{a(e)===r&&n()})};subscribeToTranslationEvents=e=>t(this.translateListeners,e);subscribeToDictionaryEntryEvents=e=>t(this.dictionaryEntryListeners,e);subscribeToDictionaryObjectEvents=e=>t(this.dictionaryObjectListeners,e);getTranslateSnapshot=(t,r={})=>n(r,t)??e().lookupTranslation(t.locale,t.message,t.options);getDictionaryEntrySnapshot=(t,n={})=>r(n,t)??e().lookupDictionary(t.locale,t.id);getDictionaryObjectSnapshot=(t,n={})=>i(n,t)??e().lookupDictionaryObj(t.locale,t.id);emitTranslateEvent(e){this.translateListeners.forEach(t=>t(e))}emitDictionaryEvent(e){this.dictionaryEntryListeners.forEach(t=>t(e)),this.dictionaryObjectListeners.forEach(t=>{t(e)})}};export{o as I18nStore};
1
+ import{getReactI18nCache as e}from"../i18n-cache/singleton-operations.mjs";import{subscribeToSet as t}from"./utils/subscriptions.mjs";import{lookupTranslation as n}from"./utils/translations.mjs";import{lookupDictionaryEntry as r,lookupDictionaryObject as i}from"./utils/dictionaries.mjs";import{getTranslateListenerKey as a}from"gt-i18n/internal";import{createDiagnosticMessage as o,formatDiagnosticErrorDetails as s}from"generaltranslation/internal";function c(e){if(e instanceof Error)return`${e.name}|${e.message}`;if(typeof e==`object`&&e)try{return`object|${JSON.stringify(e)}`}catch{return`object|${String(e)}`}return`${typeof e}|${String(e)}`}var l=class{translateListeners=new Set;dictionaryEntryListeners=new Set;dictionaryObjectListeners=new Set;loggedRuntimeTranslationErrors=new Set;constructor(){}updateTranslations=t=>{e().updateTranslations(t)};updateDictionaries=t=>{e().updateDictionaries(t)};translate=async t=>e().lookupTranslationWithFallback(t.locale,t.message,t.options).then(()=>{this.emitTranslateEvent(t)}).catch(e=>this.logRuntimeTranslationError(e));translateDictionaryEntry=t=>{e().lookupDictionaryWithFallback(t.locale,t.id).then(()=>{this.emitDictionaryEvent(t)}).catch(e=>this.logRuntimeTranslationError(e))};translateDictionaryObject=t=>{e().lookupDictionaryObjWithFallback(t.locale,t.id).then(()=>{this.emitDictionaryEvent(t)}).catch(e=>this.logRuntimeTranslationError(e))};logRuntimeTranslationError(e){let t=s(e),n=c(e);if(!this.loggedRuntimeTranslationErrors.has(n)){if(this.loggedRuntimeTranslationErrors.add(n),this.loggedRuntimeTranslationErrors.size>100){let e=this.loggedRuntimeTranslationErrors.values().next().value;e!==void 0&&this.loggedRuntimeTranslationErrors.delete(e)}console.error(o({source:`@generaltranslation/react-core`,severity:`Error`,whatHappened:`A runtime translation request failed.`,wayOut:`Rendering falls back to untranslated content.`,details:t}))}}subscribeToTranslate=(e,n)=>{let r=a(e);return t(this.translateListeners,e=>{a(e)===r&&n()})};subscribeToTranslationEvents=e=>t(this.translateListeners,e);subscribeToDictionaryEntryEvents=e=>t(this.dictionaryEntryListeners,e);subscribeToDictionaryObjectEvents=e=>t(this.dictionaryObjectListeners,e);getTranslateSnapshot=(t,r={})=>n(r,t)??e().lookupTranslation(t.locale,t.message,t.options);getDictionaryEntrySnapshot=(t,n={})=>r(n,t)??e().lookupDictionary(t.locale,t.id);getDictionaryObjectSnapshot=(t,n={})=>i(n,t)??e().lookupDictionaryObj(t.locale,t.id);emitTranslateEvent(e){this.translateListeners.forEach(t=>t(e))}emitDictionaryEvent(e){this.dictionaryEntryListeners.forEach(t=>t(e)),this.dictionaryObjectListeners.forEach(t=>{t(e)})}};export{l as I18nStore};
2
2
  //# sourceMappingURL=I18nStore.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"I18nStore.mjs","names":[],"sources":["../../src/i18n-store/I18nStore.ts"],"sourcesContent":["import { getTranslateListenerKey } from 'gt-i18n/internal';\nimport type {\n DictionaryEntrySnapshot,\n DictionaryLookup,\n DictionaryObjectSnapshot,\n StoreListener,\n TranslateEventListener,\n TranslateLookup,\n TranslateSnapshot,\n Unsubscribe,\n} from './storeTypes';\nimport type { Dictionary, Translation } from 'gt-i18n/types';\nimport { subscribeToSet } from './utils/subscriptions';\nimport { Hash, Locale } from 'gt-i18n/internal/types';\nimport { getReactI18nCache } from '../i18n-cache/singleton-operations';\nimport { lookupTranslation } from './utils/translations';\nimport {\n lookupDictionaryEntry,\n lookupDictionaryObject,\n} from './utils/dictionaries';\n\nexport type DictionaryStoreListener = (event: DictionaryLookup) => void;\n\n/**\n * I18nStore gives us the ability to perform client-side updates to translations.\n * Primarily useful for dev hot reload.\n *\n * This is the stateful primitive behind lookup subscriptions and runtime\n * translation requests. It intentionally does not know whether lookups are\n * being served from SPA singletons or SRA provider snapshots; that policy lives\n * in LookupAdapter, not in this store.\n */\nexport class I18nStore {\n // ----- Listener Sets ----- //\n\n private translateListeners = new Set<TranslateEventListener>();\n private dictionaryEntryListeners = new Set<DictionaryStoreListener>();\n private dictionaryObjectListeners = new Set<DictionaryStoreListener>();\n\n /**\n * I18nCache must be already initialized\n */\n constructor() {}\n\n // ========== Translation Updates ========== //\n\n updateTranslations = (\n translations: Record<Locale, Record<Hash, Translation>>\n ): void => {\n getReactI18nCache().updateTranslations(translations);\n };\n\n updateDictionaries = (dictionaries: Record<Locale, Dictionary>): void => {\n getReactI18nCache().updateDictionaries(dictionaries);\n };\n\n // ========== runtime translation ========== //\n\n translate = async <T extends Translation>(\n lookup: TranslateLookup<T>\n ): Promise<void> => {\n return getReactI18nCache()\n .lookupTranslationWithFallback(\n lookup.locale,\n lookup.message,\n lookup.options\n )\n .then((translation) => {\n if (translation == null) {\n // TODO: warn about runtime translation failure\n }\n this.emitTranslateEvent(lookup);\n });\n };\n\n translateDictionaryEntry = (lookup: DictionaryLookup): void => {\n getReactI18nCache()\n .lookupDictionaryWithFallback(lookup.locale, lookup.id)\n .then((dictionaryEntry) => {\n if (dictionaryEntry == null) {\n // TODO: warn about runtime dictionary translation failure\n }\n this.emitDictionaryEvent(lookup);\n });\n };\n\n translateDictionaryObject = (lookup: DictionaryLookup): void => {\n getReactI18nCache()\n .lookupDictionaryObjWithFallback(lookup.locale, lookup.id)\n .then((dictionaryObject) => {\n if (dictionaryObject == null) {\n // TODO: warn about runtime dictionary translation failure\n }\n this.emitDictionaryEvent(lookup);\n });\n };\n\n // ========== UseSyncExternalStore ========== //\n\n // ----- Subscriptions ----- //\n\n // Keep subscription methods as arrow fields so hooks can pass them by\n // reference without losing access to this store instance.\n subscribeToTranslate = <T extends Translation>(\n lookup: TranslateLookup<T>,\n listener: StoreListener\n ): Unsubscribe => {\n const lookupKey = getTranslateListenerKey(lookup);\n const wrappedListener: TranslateEventListener = (lookup) => {\n if (getTranslateListenerKey(lookup) === lookupKey) {\n listener();\n }\n };\n return subscribeToSet(this.translateListeners, wrappedListener);\n };\n\n subscribeToTranslationEvents = (\n listener: TranslateEventListener\n ): Unsubscribe => {\n return subscribeToSet(this.translateListeners, listener);\n };\n\n subscribeToDictionaryEntryEvents = (\n listener: DictionaryStoreListener\n ): Unsubscribe => {\n return subscribeToSet(this.dictionaryEntryListeners, listener);\n };\n\n subscribeToDictionaryObjectEvents = (\n listener: DictionaryStoreListener\n ): Unsubscribe => {\n return subscribeToSet(this.dictionaryObjectListeners, listener);\n };\n\n // ----- Snapshots ----- //\n\n getTranslateSnapshot = <T extends Translation>(\n lookup: TranslateLookup<T>,\n translationsSnapshot: Record<Locale, Record<Hash, Translation>> = {}\n ): TranslateSnapshot<T> => {\n return (\n lookupTranslation(translationsSnapshot, lookup) ??\n getReactI18nCache().lookupTranslation<T>(\n lookup.locale,\n lookup.message,\n lookup.options\n )\n );\n };\n\n getDictionaryEntrySnapshot = (\n lookup: DictionaryLookup,\n dictionariesSnapshot: Record<Locale, Dictionary> = {}\n ): DictionaryEntrySnapshot => {\n return (\n lookupDictionaryEntry(dictionariesSnapshot, lookup) ??\n getReactI18nCache().lookupDictionary(lookup.locale, lookup.id)\n );\n };\n\n getDictionaryObjectSnapshot = (\n lookup: DictionaryLookup,\n dictionariesSnapshot: Record<Locale, Dictionary> = {}\n ): DictionaryObjectSnapshot => {\n return (\n lookupDictionaryObject(dictionariesSnapshot, lookup) ??\n getReactI18nCache().lookupDictionaryObj(lookup.locale, lookup.id)\n );\n };\n\n // ----- Listener Utilities ----- //\n\n private emitTranslateEvent(event: TranslateLookup): void {\n this.translateListeners.forEach((listener) => listener(event));\n }\n\n private emitDictionaryEvent(event: DictionaryLookup): void {\n this.dictionaryEntryListeners.forEach((listener) => listener(event));\n this.dictionaryObjectListeners.forEach((listener) => {\n listener(event);\n });\n }\n}\n"],"mappings":"2VAgCA,IAAa,EAAb,KAAuB,CAGrB,mBAA6B,IAAI,IACjC,yBAAmC,IAAI,IACvC,0BAAoC,IAAI,IAKxC,aAAc,EAId,mBACE,GACS,CACT,GAAmB,CAAC,mBAAmB,EAAa,EAGtD,mBAAsB,GAAmD,CACvE,GAAmB,CAAC,mBAAmB,EAAa,EAKtD,UAAY,KACV,IAEO,GAAmB,CACvB,8BACC,EAAO,OACP,EAAO,QACP,EAAO,QACR,CACA,KAAM,GAAgB,CAIrB,KAAK,mBAAmB,EAAO,EAC/B,CAGN,yBAA4B,GAAmC,CAC7D,GAAmB,CAChB,6BAA6B,EAAO,OAAQ,EAAO,GAAG,CACtD,KAAM,GAAoB,CAIzB,KAAK,oBAAoB,EAAO,EAChC,EAGN,0BAA6B,GAAmC,CAC9D,GAAmB,CAChB,gCAAgC,EAAO,OAAQ,EAAO,GAAG,CACzD,KAAM,GAAqB,CAI1B,KAAK,oBAAoB,EAAO,EAChC,EASN,sBACE,EACA,IACgB,CAChB,IAAM,EAAY,EAAwB,EAAO,CAMjD,OAAO,EAAe,KAAK,mBALsB,GAAW,CACtD,EAAwB,EAAO,GAAK,GACtC,GAAU,EAGiD,EAGjE,6BACE,GAEO,EAAe,KAAK,mBAAoB,EAAS,CAG1D,iCACE,GAEO,EAAe,KAAK,yBAA0B,EAAS,CAGhE,kCACE,GAEO,EAAe,KAAK,0BAA2B,EAAS,CAKjE,sBACE,EACA,EAAkE,EAAE,GAGlE,EAAkB,EAAsB,EAAO,EAC/C,GAAmB,CAAC,kBAClB,EAAO,OACP,EAAO,QACP,EAAO,QACR,CAIL,4BACE,EACA,EAAmD,EAAE,GAGnD,EAAsB,EAAsB,EAAO,EACnD,GAAmB,CAAC,iBAAiB,EAAO,OAAQ,EAAO,GAAG,CAIlE,6BACE,EACA,EAAmD,EAAE,GAGnD,EAAuB,EAAsB,EAAO,EACpD,GAAmB,CAAC,oBAAoB,EAAO,OAAQ,EAAO,GAAG,CAMrE,mBAA2B,EAA8B,CACvD,KAAK,mBAAmB,QAAS,GAAa,EAAS,EAAM,CAAC,CAGhE,oBAA4B,EAA+B,CACzD,KAAK,yBAAyB,QAAS,GAAa,EAAS,EAAM,CAAC,CACpE,KAAK,0BAA0B,QAAS,GAAa,CACnD,EAAS,EAAM,EACf"}
1
+ {"version":3,"file":"I18nStore.mjs","names":[],"sources":["../../src/i18n-store/I18nStore.ts"],"sourcesContent":["import {\n createDiagnosticMessage,\n formatDiagnosticErrorDetails,\n} from 'generaltranslation/internal';\nimport { getTranslateListenerKey } from 'gt-i18n/internal';\nimport type {\n DictionaryEntrySnapshot,\n DictionaryLookup,\n DictionaryObjectSnapshot,\n StoreListener,\n TranslateEventListener,\n TranslateLookup,\n TranslateSnapshot,\n Unsubscribe,\n} from './storeTypes';\nimport type { Dictionary, Translation } from 'gt-i18n/types';\nimport { subscribeToSet } from './utils/subscriptions';\nimport { Hash, Locale } from 'gt-i18n/internal/types';\nimport { getReactI18nCache } from '../i18n-cache/singleton-operations';\nimport { lookupTranslation } from './utils/translations';\nimport {\n lookupDictionaryEntry,\n lookupDictionaryObject,\n} from './utils/dictionaries';\n\nexport type DictionaryStoreListener = (event: DictionaryLookup) => void;\n\nconst MAX_LOGGED_RUNTIME_TRANSLATION_ERRORS = 100;\n\nfunction getRuntimeTranslationErrorDedupeKey(error: unknown): string {\n if (error instanceof Error) {\n return `${error.name}|${error.message}`;\n }\n if (error !== null && typeof error === 'object') {\n try {\n return `object|${JSON.stringify(error)}`;\n } catch {\n return `object|${String(error)}`;\n }\n }\n return `${typeof error}|${String(error)}`;\n}\n\n/**\n * I18nStore gives us the ability to perform client-side updates to translations.\n * Primarily useful for dev hot reload.\n *\n * This is the stateful primitive behind lookup subscriptions and runtime\n * translation requests. It intentionally does not know whether lookups are\n * being served from SPA singletons or SRA provider snapshots; that policy lives\n * in LookupAdapter, not in this store.\n */\nexport class I18nStore {\n // ----- Listener Sets ----- //\n\n private translateListeners = new Set<TranslateEventListener>();\n private dictionaryEntryListeners = new Set<DictionaryStoreListener>();\n private dictionaryObjectListeners = new Set<DictionaryStoreListener>();\n private loggedRuntimeTranslationErrors = new Set<string>();\n\n /**\n * I18nCache must be already initialized\n */\n constructor() {}\n\n // ========== Translation Updates ========== //\n\n updateTranslations = (\n translations: Record<Locale, Record<Hash, Translation>>\n ): void => {\n getReactI18nCache().updateTranslations(translations);\n };\n\n updateDictionaries = (dictionaries: Record<Locale, Dictionary>): void => {\n getReactI18nCache().updateDictionaries(dictionaries);\n };\n\n // ========== runtime translation ========== //\n\n translate = async <T extends Translation>(\n lookup: TranslateLookup<T>\n ): Promise<void> => {\n return getReactI18nCache()\n .lookupTranslationWithFallback(\n lookup.locale,\n lookup.message,\n lookup.options\n )\n .then(() => {\n this.emitTranslateEvent(lookup);\n })\n .catch((error) => this.logRuntimeTranslationError(error));\n };\n\n translateDictionaryEntry = (lookup: DictionaryLookup): void => {\n getReactI18nCache()\n .lookupDictionaryWithFallback(lookup.locale, lookup.id)\n .then(() => {\n this.emitDictionaryEvent(lookup);\n })\n .catch((error) => this.logRuntimeTranslationError(error));\n };\n\n translateDictionaryObject = (lookup: DictionaryLookup): void => {\n getReactI18nCache()\n .lookupDictionaryObjWithFallback(lookup.locale, lookup.id)\n .then(() => {\n this.emitDictionaryEvent(lookup);\n })\n .catch((error) => this.logRuntimeTranslationError(error));\n };\n\n /**\n * Runtime translation runs fire-and-forget, so a rejected request (for\n * example a 401 from an invalid dev API key) is logged here instead of\n * escaping as an unhandled rejection that kills the dev server during SSR.\n * Identical failures log once.\n */\n private logRuntimeTranslationError(error: unknown): void {\n const details = formatDiagnosticErrorDetails(error);\n const dedupeKey = getRuntimeTranslationErrorDedupeKey(error);\n if (this.loggedRuntimeTranslationErrors.has(dedupeKey)) return;\n this.loggedRuntimeTranslationErrors.add(dedupeKey);\n if (\n this.loggedRuntimeTranslationErrors.size >\n MAX_LOGGED_RUNTIME_TRANSLATION_ERRORS\n ) {\n const oldest = this.loggedRuntimeTranslationErrors.values().next().value;\n if (oldest !== undefined) {\n this.loggedRuntimeTranslationErrors.delete(oldest);\n }\n }\n console.error(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Error',\n whatHappened: 'A runtime translation request failed.',\n wayOut: 'Rendering falls back to untranslated content.',\n details,\n })\n );\n }\n\n // ========== UseSyncExternalStore ========== //\n\n // ----- Subscriptions ----- //\n\n // Keep subscription methods as arrow fields so hooks can pass them by\n // reference without losing access to this store instance.\n subscribeToTranslate = <T extends Translation>(\n lookup: TranslateLookup<T>,\n listener: StoreListener\n ): Unsubscribe => {\n const lookupKey = getTranslateListenerKey(lookup);\n const wrappedListener: TranslateEventListener = (lookup) => {\n if (getTranslateListenerKey(lookup) === lookupKey) {\n listener();\n }\n };\n return subscribeToSet(this.translateListeners, wrappedListener);\n };\n\n subscribeToTranslationEvents = (\n listener: TranslateEventListener\n ): Unsubscribe => {\n return subscribeToSet(this.translateListeners, listener);\n };\n\n subscribeToDictionaryEntryEvents = (\n listener: DictionaryStoreListener\n ): Unsubscribe => {\n return subscribeToSet(this.dictionaryEntryListeners, listener);\n };\n\n subscribeToDictionaryObjectEvents = (\n listener: DictionaryStoreListener\n ): Unsubscribe => {\n return subscribeToSet(this.dictionaryObjectListeners, listener);\n };\n\n // ----- Snapshots ----- //\n\n getTranslateSnapshot = <T extends Translation>(\n lookup: TranslateLookup<T>,\n translationsSnapshot: Record<Locale, Record<Hash, Translation>> = {}\n ): TranslateSnapshot<T> => {\n return (\n lookupTranslation(translationsSnapshot, lookup) ??\n getReactI18nCache().lookupTranslation<T>(\n lookup.locale,\n lookup.message,\n lookup.options\n )\n );\n };\n\n getDictionaryEntrySnapshot = (\n lookup: DictionaryLookup,\n dictionariesSnapshot: Record<Locale, Dictionary> = {}\n ): DictionaryEntrySnapshot => {\n return (\n lookupDictionaryEntry(dictionariesSnapshot, lookup) ??\n getReactI18nCache().lookupDictionary(lookup.locale, lookup.id)\n );\n };\n\n getDictionaryObjectSnapshot = (\n lookup: DictionaryLookup,\n dictionariesSnapshot: Record<Locale, Dictionary> = {}\n ): DictionaryObjectSnapshot => {\n return (\n lookupDictionaryObject(dictionariesSnapshot, lookup) ??\n getReactI18nCache().lookupDictionaryObj(lookup.locale, lookup.id)\n );\n };\n\n // ----- Listener Utilities ----- //\n\n private emitTranslateEvent(event: TranslateLookup): void {\n this.translateListeners.forEach((listener) => listener(event));\n }\n\n private emitDictionaryEvent(event: DictionaryLookup): void {\n this.dictionaryEntryListeners.forEach((listener) => listener(event));\n this.dictionaryObjectListeners.forEach((listener) => {\n listener(event);\n });\n }\n}\n"],"mappings":"mcA6BA,SAAS,EAAoC,EAAwB,CACnE,GAAI,aAAiB,MACnB,MAAO,GAAG,EAAM,KAAK,GAAG,EAAM,UAEhC,GAAsB,OAAO,GAAU,UAAnC,EACF,GAAI,CACF,MAAO,UAAU,KAAK,UAAU,EAAM,QAChC,CACN,MAAO,UAAU,OAAO,EAAM,GAGlC,MAAO,GAAG,OAAO,EAAM,GAAG,OAAO,EAAM,GAYzC,IAAa,EAAb,KAAuB,CAGrB,mBAA6B,IAAI,IACjC,yBAAmC,IAAI,IACvC,0BAAoC,IAAI,IACxC,+BAAyC,IAAI,IAK7C,aAAc,EAId,mBACE,GACS,CACT,GAAmB,CAAC,mBAAmB,EAAa,EAGtD,mBAAsB,GAAmD,CACvE,GAAmB,CAAC,mBAAmB,EAAa,EAKtD,UAAY,KACV,IAEO,GAAmB,CACvB,8BACC,EAAO,OACP,EAAO,QACP,EAAO,QACR,CACA,SAAW,CACV,KAAK,mBAAmB,EAAO,EAC/B,CACD,MAAO,GAAU,KAAK,2BAA2B,EAAM,CAAC,CAG7D,yBAA4B,GAAmC,CAC7D,GAAmB,CAChB,6BAA6B,EAAO,OAAQ,EAAO,GAAG,CACtD,SAAW,CACV,KAAK,oBAAoB,EAAO,EAChC,CACD,MAAO,GAAU,KAAK,2BAA2B,EAAM,CAAC,EAG7D,0BAA6B,GAAmC,CAC9D,GAAmB,CAChB,gCAAgC,EAAO,OAAQ,EAAO,GAAG,CACzD,SAAW,CACV,KAAK,oBAAoB,EAAO,EAChC,CACD,MAAO,GAAU,KAAK,2BAA2B,EAAM,CAAC,EAS7D,2BAAmC,EAAsB,CACvD,IAAM,EAAU,EAA6B,EAAM,CAC7C,EAAY,EAAoC,EAAM,CACxD,SAAK,+BAA+B,IAAI,EAAU,CAEtD,IADA,KAAK,+BAA+B,IAAI,EAAU,CAEhD,KAAK,+BAA+B,KACpC,IACA,CACA,IAAM,EAAS,KAAK,+BAA+B,QAAQ,CAAC,MAAM,CAAC,MAC/D,IAAW,IAAA,IACb,KAAK,+BAA+B,OAAO,EAAO,CAGtD,QAAQ,MACN,EAAwB,CACtB,OAAQ,iCACR,SAAU,QACV,aAAc,wCACd,OAAQ,gDACR,UACD,CAAC,CACH,EASH,sBACE,EACA,IACgB,CAChB,IAAM,EAAY,EAAwB,EAAO,CAMjD,OAAO,EAAe,KAAK,mBALsB,GAAW,CACtD,EAAwB,EAAO,GAAK,GACtC,GAAU,EAGiD,EAGjE,6BACE,GAEO,EAAe,KAAK,mBAAoB,EAAS,CAG1D,iCACE,GAEO,EAAe,KAAK,yBAA0B,EAAS,CAGhE,kCACE,GAEO,EAAe,KAAK,0BAA2B,EAAS,CAKjE,sBACE,EACA,EAAkE,EAAE,GAGlE,EAAkB,EAAsB,EAAO,EAC/C,GAAmB,CAAC,kBAClB,EAAO,OACP,EAAO,QACP,EAAO,QACR,CAIL,4BACE,EACA,EAAmD,EAAE,GAGnD,EAAsB,EAAsB,EAAO,EACnD,GAAmB,CAAC,iBAAiB,EAAO,OAAQ,EAAO,GAAG,CAIlE,6BACE,EACA,EAAmD,EAAE,GAGnD,EAAuB,EAAsB,EAAO,EACpD,GAAmB,CAAC,oBAAoB,EAAO,OAAQ,EAAO,GAAG,CAMrE,mBAA2B,EAA8B,CACvD,KAAK,mBAAmB,QAAS,GAAa,EAAS,EAAM,CAAC,CAGhE,oBAA4B,EAA+B,CACzD,KAAK,yBAAyB,QAAS,GAAa,EAAS,EAAM,CAAC,CACpE,KAAK,0BAA0B,QAAS,GAAa,CACnD,EAAS,EAAM,EACf"}
package/dist/pure.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./hooks/utils/getFormatLocales.cjs`),t=require(`./i18n-cache/singleton-operations.cjs`),n=require(`./functions/helpers/getTranslationsSnapshot.cjs`),r=require(`./setup/cookieNames.cjs`),i=require(`./setup/i18nConfig.cjs`),a=require(`./condition-store/singleton-operations.cjs`),o=require(`./functions/translation/t.cjs`),s=require(`./utils/rendering/createRenderPipeline.cjs`),c=require(`./utils/rendering/getDefaultRenderSettings.cjs`),l=require(`./i18n-cache/ReactI18nCache.cjs`),u=require(`./setup/initializeGTSRA.cjs`),d=require(`./i18n-store/singleton-operations.cjs`),f=require(`./i18n-store/I18nStore.cjs`);let p=require(`gt-i18n`),m=require(`gt-i18n/internal`);exports.I18nStore=f.I18nStore,exports.ReactI18nCache=l.ReactI18nCache,Object.defineProperty(exports,`ReadonlyConditionStore`,{enumerable:!0,get:function(){return m.ReadonlyConditionStore}}),exports.createRenderPipeline=s.createRenderPipeline,Object.defineProperty(exports,`declareVar`,{enumerable:!0,get:function(){return p.declareVar}}),Object.defineProperty(exports,`decodeMsg`,{enumerable:!0,get:function(){return p.decodeMsg}}),Object.defineProperty(exports,`decodeOptions`,{enumerable:!0,get:function(){return p.decodeOptions}}),Object.defineProperty(exports,`decodeVars`,{enumerable:!0,get:function(){return p.decodeVars}}),exports.defaultEnableI18nCookieName=r.defaultEnableI18nCookieName,exports.defaultLocaleCookieName=r.defaultLocaleCookieName,exports.defaultRegionCookieName=r.defaultRegionCookieName,exports.defaultResetLocaleCookieName=r.defaultResetLocaleCookieName,Object.defineProperty(exports,`derive`,{enumerable:!0,get:function(){return p.derive}}),Object.defineProperty(exports,`getDefaultLocale`,{enumerable:!0,get:function(){return p.getDefaultLocale}}),exports.getDefaultRenderSettings=c.getDefaultRenderSettings,exports.getFormatLocales=e.getFormatLocales,exports.getI18nConfig=i.getI18nConfig,Object.defineProperty(exports,`getLocaleProperties`,{enumerable:!0,get:function(){return p.getLocaleProperties}}),Object.defineProperty(exports,`getLocales`,{enumerable:!0,get:function(){return p.getLocales}}),exports.getReactI18nCache=t.getReactI18nCache,exports.getReadonlyConditionStore=a.getConditionStore,exports.getTranslationsSnapshot=n.getTranslationsSnapshot,Object.defineProperty(exports,`getVersionId`,{enumerable:!0,get:function(){return p.getVersionId}}),Object.defineProperty(exports,`gtFallback`,{enumerable:!0,get:function(){return p.gtFallback}}),exports.initializeI18nConfig=i.initializeI18nConfig,exports.internalInitializeGTSRA=u.internalInitializeGTSRA,Object.defineProperty(exports,`mFallback`,{enumerable:!0,get:function(){return p.mFallback}}),Object.defineProperty(exports,`msg`,{enumerable:!0,get:function(){return p.msg}}),Object.defineProperty(exports,`resolveCanonicalLocale`,{enumerable:!0,get:function(){return p.resolveCanonicalLocale}}),exports.setI18nStore=d.setI18nStore,exports.setReactI18nCache=t.setReactI18nCache,exports.t=o.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./hooks/utils/getFormatLocales.cjs`),t=require(`./i18n-cache/singleton-operations.cjs`),n=require(`./functions/helpers/getTranslationsSnapshot.cjs`),r=require(`./setup/i18nConfig.cjs`),i=require(`./condition-store/singleton-operations.cjs`),a=require(`./functions/translation/t.cjs`),o=require(`./utils/rendering/createRenderPipeline.cjs`),s=require(`./utils/rendering/getDefaultRenderSettings.cjs`),c=require(`./i18n-cache/ReactI18nCache.cjs`),l=require(`./setup/initializeGTSRA.cjs`),u=require(`./i18n-store/singleton-operations.cjs`),d=require(`./i18n-store/I18nStore.cjs`);let f=require(`gt-i18n`),p=require(`gt-i18n/internal`),m=require(`gt-i18n/internal/cookies`);exports.I18nStore=d.I18nStore,exports.ReactI18nCache=c.ReactI18nCache,Object.defineProperty(exports,`ReadonlyConditionStore`,{enumerable:!0,get:function(){return p.ReadonlyConditionStore}}),exports.createRenderPipeline=o.createRenderPipeline,Object.defineProperty(exports,`declareVar`,{enumerable:!0,get:function(){return f.declareVar}}),Object.defineProperty(exports,`decodeMsg`,{enumerable:!0,get:function(){return f.decodeMsg}}),Object.defineProperty(exports,`decodeOptions`,{enumerable:!0,get:function(){return f.decodeOptions}}),Object.defineProperty(exports,`decodeVars`,{enumerable:!0,get:function(){return f.decodeVars}}),Object.defineProperty(exports,`defaultEnableI18nCookieName`,{enumerable:!0,get:function(){return m.defaultEnableI18nCookieName}}),Object.defineProperty(exports,`defaultLocaleCookieName`,{enumerable:!0,get:function(){return m.defaultLocaleCookieName}}),Object.defineProperty(exports,`defaultRegionCookieName`,{enumerable:!0,get:function(){return m.defaultRegionCookieName}}),Object.defineProperty(exports,`defaultResetLocaleCookieName`,{enumerable:!0,get:function(){return m.defaultResetLocaleCookieName}}),Object.defineProperty(exports,`derive`,{enumerable:!0,get:function(){return f.derive}}),Object.defineProperty(exports,`getDefaultLocale`,{enumerable:!0,get:function(){return f.getDefaultLocale}}),exports.getDefaultRenderSettings=s.getDefaultRenderSettings,exports.getFormatLocales=e.getFormatLocales,exports.getI18nConfig=r.getI18nConfig,Object.defineProperty(exports,`getLocaleProperties`,{enumerable:!0,get:function(){return f.getLocaleProperties}}),Object.defineProperty(exports,`getLocales`,{enumerable:!0,get:function(){return f.getLocales}}),exports.getReactI18nCache=t.getReactI18nCache,exports.getReadonlyConditionStore=i.getConditionStore,exports.getTranslationsSnapshot=n.getTranslationsSnapshot,Object.defineProperty(exports,`getVersionId`,{enumerable:!0,get:function(){return f.getVersionId}}),Object.defineProperty(exports,`gtFallback`,{enumerable:!0,get:function(){return f.gtFallback}}),exports.initializeI18nConfig=r.initializeI18nConfig,exports.internalInitializeGTSRA=l.internalInitializeGTSRA,Object.defineProperty(exports,`mFallback`,{enumerable:!0,get:function(){return f.mFallback}}),Object.defineProperty(exports,`msg`,{enumerable:!0,get:function(){return f.msg}}),Object.defineProperty(exports,`resolveCanonicalLocale`,{enumerable:!0,get:function(){return f.resolveCanonicalLocale}}),exports.setI18nStore=u.setI18nStore,exports.setReactI18nCache=t.setReactI18nCache,exports.t=a.t;
@@ -1,20 +1,2 @@
1
- //#region src/setup/cookieNames.d.ts
2
- /**
3
- * Cookie name for tracking the user's selected locale.
4
- */
5
- declare const defaultLocaleCookieName = "generaltranslation.locale";
6
- /**
7
- * Cookie name for tracking the user's selected region.
8
- */
9
- declare const defaultRegionCookieName = "generaltranslation.region";
10
- /**
11
- * Cookie name for persisting the enableI18n feature flag.
12
- */
13
- declare const defaultEnableI18nCookieName = "generaltranslation.enable-i18n";
14
- /**
15
- * Cookie name for tracking the locale reset.
16
- */
17
- declare const defaultResetLocaleCookieName = "generaltranslation.locale-reset";
18
- //#endregion
19
- export { defaultEnableI18nCookieName, defaultLocaleCookieName, defaultRegionCookieName, defaultResetLocaleCookieName };
20
- //# sourceMappingURL=cookieNames.d.ts.map
1
+ import { defaultEnableI18nCookieName, defaultLocaleCookieName, defaultRegionCookieName, defaultResetLocaleCookieName } from "gt-i18n/internal/cookies";
2
+ export { defaultEnableI18nCookieName, defaultLocaleCookieName, defaultRegionCookieName, defaultResetLocaleCookieName };
@@ -1,2 +1 @@
1
- const e=`generaltranslation.locale`,t=`generaltranslation.region`,n=`generaltranslation.enable-i18n`,r=`generaltranslation.locale-reset`;export{n as defaultEnableI18nCookieName,e as defaultLocaleCookieName,t as defaultRegionCookieName,r as defaultResetLocaleCookieName};
2
- //# sourceMappingURL=cookieNames.mjs.map
1
+ import{defaultEnableI18nCookieName as e,defaultLocaleCookieName as t,defaultRegionCookieName as n,defaultResetLocaleCookieName as r}from"gt-i18n/internal/cookies";export{e as defaultEnableI18nCookieName,t as defaultLocaleCookieName,n as defaultRegionCookieName,r as defaultResetLocaleCookieName};
@@ -1,2 +1,2 @@
1
- require(`../_virtual/_rolldown/runtime.cjs`),require(`./cookieNames.cjs`);let e=require(`gt-i18n/internal`),t=require(`generaltranslation/internal`);const n=`server-render`,r=Symbol.for(`generaltranslation.react-core.ReactI18nConfig`);var i=class extends e.I18nConfig{renderStrategy;localeCookieName;regionCookieName;enableI18nCookieName;constructor(e={},t=n){super(e),c(t),Object.defineProperty(this,r,{value:!0}),this.renderStrategy=t,this.localeCookieName=e.localeCookieName??`generaltranslation.locale`,this.regionCookieName=e.regionCookieName??`generaltranslation.region`,this.enableI18nCookieName=e.enableI18nCookieName??`generaltranslation.enable-i18n`}getRenderStrategy(){return this.renderStrategy}getLocaleCookieName(){return this.localeCookieName}getRegionCookieName(){return this.regionCookieName}getEnableI18nCookieName(){return this.enableI18nCookieName}isIdTaggingEnabled(){return this.runtimeConfig._tagIds===!0}};function a(){let n=(0,e.getI18nConfig)();if(l(n))return n;throw Error((0,t.createDiagnosticMessage)({source:`@generaltranslation/react-core`,severity:`Error`,whatHappened:`Cannot read ReactI18nConfig after base I18nConfig setup.`,why:`the internal I18nConfig singleton was initialized without react-core render strategy support`,fix:`Initialize GT through gt-react or @generaltranslation/react-core/pure.`}))}function o(t){(0,e.setI18nConfig)(t)}function s(e={},t=n){let r=new i(e,t);return o(r),r}function c(e){if(!(e===`SPA`||e===`server-render`))throw Error((0,t.createDiagnosticMessage)({source:`@generaltranslation/react-core`,severity:`Error`,whatHappened:`Invalid React render strategy.`,why:`the render strategy must be "SPA" or "server-render", but received "${String(e)}"`,fix:`Initialize GT through gt-react or pass a valid render strategy.`}))}function l(e){if(e instanceof i)return!0;let t=e;return t[r]===!0&&typeof t.getRenderStrategy==`function`&&typeof t.getLocaleCookieName==`function`&&typeof t.getRegionCookieName==`function`&&typeof t.getEnableI18nCookieName==`function`}exports.getI18nConfig=a,exports.initializeI18nConfig=s;
1
+ require(`../_virtual/_rolldown/runtime.cjs`);let e=require(`gt-i18n/internal`),t=require(`generaltranslation/internal`),n=require(`gt-i18n/internal/cookies`);const r=`server-render`,i=Symbol.for(`generaltranslation.react-core.ReactI18nConfig`);var a=class extends e.I18nConfig{renderStrategy;localeCookieName;regionCookieName;enableI18nCookieName;constructor(e={},t=r){super(e),l(t),Object.defineProperty(this,i,{value:!0}),this.renderStrategy=t,this.localeCookieName=e.localeCookieName??n.defaultLocaleCookieName,this.regionCookieName=e.regionCookieName??n.defaultRegionCookieName,this.enableI18nCookieName=e.enableI18nCookieName??n.defaultEnableI18nCookieName}getRenderStrategy(){return this.renderStrategy}getLocaleCookieName(){return this.localeCookieName}getRegionCookieName(){return this.regionCookieName}getEnableI18nCookieName(){return this.enableI18nCookieName}isIdTaggingEnabled(){return this.runtimeConfig._tagIds===!0}};function o(){let n=(0,e.getI18nConfig)();if(u(n))return n;throw Error((0,t.createDiagnosticMessage)({source:`@generaltranslation/react-core`,severity:`Error`,whatHappened:`Cannot read ReactI18nConfig after base I18nConfig setup.`,why:`the internal I18nConfig singleton was initialized without react-core render strategy support`,fix:`Initialize GT through gt-react or @generaltranslation/react-core/pure.`}))}function s(t){(0,e.setI18nConfig)(t)}function c(e={},t=r){let n=new a(e,t);return s(n),n}function l(e){if(!(e===`SPA`||e===`server-render`))throw Error((0,t.createDiagnosticMessage)({source:`@generaltranslation/react-core`,severity:`Error`,whatHappened:`Invalid React render strategy.`,why:`the render strategy must be "SPA" or "server-render", but received "${String(e)}"`,fix:`Initialize GT through gt-react or pass a valid render strategy.`}))}function u(e){if(e instanceof a)return!0;let t=e;return t[i]===!0&&typeof t.getRenderStrategy==`function`&&typeof t.getLocaleCookieName==`function`&&typeof t.getRegionCookieName==`function`&&typeof t.getEnableI18nCookieName==`function`}exports.getI18nConfig=o,exports.initializeI18nConfig=c;
2
2
  //# sourceMappingURL=i18nConfig.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"i18nConfig.cjs","names":["I18nConfig"],"sources":["../../src/setup/i18nConfig.ts"],"sourcesContent":["import { createDiagnosticMessage } from 'generaltranslation/internal';\nimport {\n getI18nConfig as getBaseI18nConfig,\n I18nConfig,\n setI18nConfig as setBaseI18nConfig,\n} from 'gt-i18n/internal';\nimport type { I18nConfigParams as BaseI18nConfigParams } from 'gt-i18n/internal/types';\nimport {\n defaultEnableI18nCookieName,\n defaultLocaleCookieName,\n defaultRegionCookieName,\n} from './cookieNames';\n\n/**\n * Helps us distinguish behavior for SPA vs server-rendered apps.\n * - server-rendered apps must use context\n * - SPA apps can synchronously access the locale\n */\nexport type RenderStrategy = 'SPA' | 'server-render';\n\ntype CookieNameConfig = {\n localeCookieName?: string;\n regionCookieName?: string;\n enableI18nCookieName?: string;\n};\n\nexport type ReactI18nConfigParams = BaseI18nConfigParams & CookieNameConfig;\n\nconst defaultRenderStrategy: RenderStrategy = 'server-render';\nconst reactI18nConfigBrand = Symbol.for(\n 'generaltranslation.react-core.ReactI18nConfig'\n);\n\nexport class ReactI18nConfig extends I18nConfig {\n private renderStrategy: RenderStrategy;\n private localeCookieName: string;\n private regionCookieName: string;\n private enableI18nCookieName: string;\n\n constructor(\n params: ReactI18nConfigParams = {},\n renderStrategy: RenderStrategy = defaultRenderStrategy\n ) {\n super(params);\n validateRenderStrategy(renderStrategy);\n Object.defineProperty(this, reactI18nConfigBrand, { value: true });\n this.renderStrategy = renderStrategy;\n this.localeCookieName = params.localeCookieName ?? defaultLocaleCookieName;\n this.regionCookieName = params.regionCookieName ?? defaultRegionCookieName;\n this.enableI18nCookieName =\n params.enableI18nCookieName ?? defaultEnableI18nCookieName;\n }\n\n getRenderStrategy(): RenderStrategy {\n return this.renderStrategy;\n }\n\n getLocaleCookieName(): string {\n return this.localeCookieName;\n }\n\n getRegionCookieName(): string {\n return this.regionCookieName;\n }\n\n getEnableI18nCookieName(): string {\n return this.enableI18nCookieName;\n }\n\n /**\n * Opt-in (`_tagIds`): whether `<T>` output should carry its translation hash as\n * a `data-_gt-hash` attribute for tooling. Requires the literal `true`.\n */\n isIdTaggingEnabled(): boolean {\n return this.runtimeConfig._tagIds === true;\n }\n}\n\nexport function getI18nConfig(): ReactI18nConfig {\n const i18nConfig = getBaseI18nConfig();\n if (isReactI18nConfig(i18nConfig)) {\n return i18nConfig;\n }\n throw new Error(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Error',\n whatHappened: 'Cannot read ReactI18nConfig after base I18nConfig setup.',\n why: 'the internal I18nConfig singleton was initialized without react-core render strategy support',\n fix: 'Initialize GT through gt-react or @generaltranslation/react-core/pure.',\n })\n );\n}\n\nexport function setI18nConfig(nextI18nConfig: ReactI18nConfig): void {\n setBaseI18nConfig(nextI18nConfig);\n}\n\nexport function initializeI18nConfig(\n params: ReactI18nConfigParams = {},\n renderStrategy: RenderStrategy = defaultRenderStrategy\n): ReactI18nConfig {\n const nextI18nConfig = new ReactI18nConfig(params, renderStrategy);\n setI18nConfig(nextI18nConfig);\n return nextI18nConfig;\n}\n\nfunction validateRenderStrategy(\n renderStrategy: RenderStrategy\n): asserts renderStrategy is RenderStrategy {\n if (renderStrategy === 'SPA' || renderStrategy === 'server-render') return;\n throw new Error(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Error',\n whatHappened: 'Invalid React render strategy.',\n why: `the render strategy must be \"SPA\" or \"server-render\", but received \"${String(renderStrategy)}\"`,\n fix: 'Initialize GT through gt-react or pass a valid render strategy.',\n })\n );\n}\n\nfunction isReactI18nConfig(\n i18nConfig: I18nConfig\n): i18nConfig is ReactI18nConfig {\n if (i18nConfig instanceof ReactI18nConfig) return true;\n\n const maybeReactI18nConfig = i18nConfig as I18nConfig &\n Record<PropertyKey, unknown>;\n return (\n maybeReactI18nConfig[reactI18nConfigBrand] === true &&\n typeof maybeReactI18nConfig.getRenderStrategy === 'function' &&\n typeof maybeReactI18nConfig.getLocaleCookieName === 'function' &&\n typeof maybeReactI18nConfig.getRegionCookieName === 'function' &&\n typeof maybeReactI18nConfig.getEnableI18nCookieName === 'function'\n );\n}\n"],"mappings":"qJA4BA,MAAM,EAAwC,gBACxC,EAAuB,OAAO,IAClC,gDACD,CAED,IAAa,EAAb,cAAqCA,EAAAA,UAAW,CAC9C,eACA,iBACA,iBACA,qBAEA,YACE,EAAgC,EAAE,CAClC,EAAiC,EACjC,CACA,MAAM,EAAO,CACb,EAAuB,EAAe,CACtC,OAAO,eAAe,KAAM,EAAsB,CAAE,MAAO,GAAM,CAAC,CAClE,KAAK,eAAiB,EACtB,KAAK,iBAAmB,EAAO,kBAAA,4BAC/B,KAAK,iBAAmB,EAAO,kBAAA,4BAC/B,KAAK,qBACH,EAAO,sBAAA,iCAGX,mBAAoC,CAClC,OAAO,KAAK,eAGd,qBAA8B,CAC5B,OAAO,KAAK,iBAGd,qBAA8B,CAC5B,OAAO,KAAK,iBAGd,yBAAkC,CAChC,OAAO,KAAK,qBAOd,oBAA8B,CAC5B,OAAO,KAAK,cAAc,UAAY,KAI1C,SAAgB,GAAiC,CAC/C,IAAM,GAAA,EAAA,EAAA,gBAAgC,CACtC,GAAI,EAAkB,EAAW,CAC/B,OAAO,EAET,MAAU,OAAA,EAAA,EAAA,yBACgB,CACtB,OAAQ,iCACR,SAAU,QACV,aAAc,2DACd,IAAK,+FACL,IAAK,yEACN,CAAC,CACH,CAGH,SAAgB,EAAc,EAAuC,EACnE,EAAA,EAAA,eAAkB,EAAe,CAGnC,SAAgB,EACd,EAAgC,EAAE,CAClC,EAAiC,EAChB,CACjB,IAAM,EAAiB,IAAI,EAAgB,EAAQ,EAAe,CAElE,OADA,EAAc,EAAe,CACtB,EAGT,SAAS,EACP,EAC0C,CACtC,SAAmB,OAAS,IAAmB,iBACnD,MAAU,OAAA,EAAA,EAAA,yBACgB,CACtB,OAAQ,iCACR,SAAU,QACV,aAAc,iCACd,IAAK,uEAAuE,OAAO,EAAe,CAAC,GACnG,IAAK,kEACN,CAAC,CACH,CAGH,SAAS,EACP,EAC+B,CAC/B,GAAI,aAAsB,EAAiB,MAAO,GAElD,IAAM,EAAuB,EAE7B,OACE,EAAqB,KAA0B,IAC/C,OAAO,EAAqB,mBAAsB,YAClD,OAAO,EAAqB,qBAAwB,YACpD,OAAO,EAAqB,qBAAwB,YACpD,OAAO,EAAqB,yBAA4B"}
1
+ {"version":3,"file":"i18nConfig.cjs","names":["I18nConfig","defaultLocaleCookieName","defaultRegionCookieName","defaultEnableI18nCookieName"],"sources":["../../src/setup/i18nConfig.ts"],"sourcesContent":["import { createDiagnosticMessage } from 'generaltranslation/internal';\nimport {\n getI18nConfig as getBaseI18nConfig,\n I18nConfig,\n setI18nConfig as setBaseI18nConfig,\n} from 'gt-i18n/internal';\nimport type { I18nConfigParams as BaseI18nConfigParams } from 'gt-i18n/internal/types';\nimport {\n defaultEnableI18nCookieName,\n defaultLocaleCookieName,\n defaultRegionCookieName,\n} from './cookieNames';\n\n/**\n * Helps us distinguish behavior for SPA vs server-rendered apps.\n * - server-rendered apps must use context\n * - SPA apps can synchronously access the locale\n */\nexport type RenderStrategy = 'SPA' | 'server-render';\n\ntype CookieNameConfig = {\n localeCookieName?: string;\n regionCookieName?: string;\n enableI18nCookieName?: string;\n};\n\nexport type ReactI18nConfigParams = BaseI18nConfigParams & CookieNameConfig;\n\nconst defaultRenderStrategy: RenderStrategy = 'server-render';\nconst reactI18nConfigBrand = Symbol.for(\n 'generaltranslation.react-core.ReactI18nConfig'\n);\n\nexport class ReactI18nConfig extends I18nConfig {\n private renderStrategy: RenderStrategy;\n private localeCookieName: string;\n private regionCookieName: string;\n private enableI18nCookieName: string;\n\n constructor(\n params: ReactI18nConfigParams = {},\n renderStrategy: RenderStrategy = defaultRenderStrategy\n ) {\n super(params);\n validateRenderStrategy(renderStrategy);\n Object.defineProperty(this, reactI18nConfigBrand, { value: true });\n this.renderStrategy = renderStrategy;\n this.localeCookieName = params.localeCookieName ?? defaultLocaleCookieName;\n this.regionCookieName = params.regionCookieName ?? defaultRegionCookieName;\n this.enableI18nCookieName =\n params.enableI18nCookieName ?? defaultEnableI18nCookieName;\n }\n\n getRenderStrategy(): RenderStrategy {\n return this.renderStrategy;\n }\n\n getLocaleCookieName(): string {\n return this.localeCookieName;\n }\n\n getRegionCookieName(): string {\n return this.regionCookieName;\n }\n\n getEnableI18nCookieName(): string {\n return this.enableI18nCookieName;\n }\n\n /**\n * Opt-in (`_tagIds`): whether `<T>` output should carry its translation hash as\n * a `data-_gt-hash` attribute for tooling. Requires the literal `true`.\n */\n isIdTaggingEnabled(): boolean {\n return this.runtimeConfig._tagIds === true;\n }\n}\n\nexport function getI18nConfig(): ReactI18nConfig {\n const i18nConfig = getBaseI18nConfig();\n if (isReactI18nConfig(i18nConfig)) {\n return i18nConfig;\n }\n throw new Error(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Error',\n whatHappened: 'Cannot read ReactI18nConfig after base I18nConfig setup.',\n why: 'the internal I18nConfig singleton was initialized without react-core render strategy support',\n fix: 'Initialize GT through gt-react or @generaltranslation/react-core/pure.',\n })\n );\n}\n\nexport function setI18nConfig(nextI18nConfig: ReactI18nConfig): void {\n setBaseI18nConfig(nextI18nConfig);\n}\n\nexport function initializeI18nConfig(\n params: ReactI18nConfigParams = {},\n renderStrategy: RenderStrategy = defaultRenderStrategy\n): ReactI18nConfig {\n const nextI18nConfig = new ReactI18nConfig(params, renderStrategy);\n setI18nConfig(nextI18nConfig);\n return nextI18nConfig;\n}\n\nfunction validateRenderStrategy(\n renderStrategy: RenderStrategy\n): asserts renderStrategy is RenderStrategy {\n if (renderStrategy === 'SPA' || renderStrategy === 'server-render') return;\n throw new Error(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Error',\n whatHappened: 'Invalid React render strategy.',\n why: `the render strategy must be \"SPA\" or \"server-render\", but received \"${String(renderStrategy)}\"`,\n fix: 'Initialize GT through gt-react or pass a valid render strategy.',\n })\n );\n}\n\nfunction isReactI18nConfig(\n i18nConfig: I18nConfig\n): i18nConfig is ReactI18nConfig {\n if (i18nConfig instanceof ReactI18nConfig) return true;\n\n const maybeReactI18nConfig = i18nConfig as I18nConfig &\n Record<PropertyKey, unknown>;\n return (\n maybeReactI18nConfig[reactI18nConfigBrand] === true &&\n typeof maybeReactI18nConfig.getRenderStrategy === 'function' &&\n typeof maybeReactI18nConfig.getLocaleCookieName === 'function' &&\n typeof maybeReactI18nConfig.getRegionCookieName === 'function' &&\n typeof maybeReactI18nConfig.getEnableI18nCookieName === 'function'\n );\n}\n"],"mappings":"8JA4BA,MAAM,EAAwC,gBACxC,EAAuB,OAAO,IAClC,gDACD,CAED,IAAa,EAAb,cAAqCA,EAAAA,UAAW,CAC9C,eACA,iBACA,iBACA,qBAEA,YACE,EAAgC,EAAE,CAClC,EAAiC,EACjC,CACA,MAAM,EAAO,CACb,EAAuB,EAAe,CACtC,OAAO,eAAe,KAAM,EAAsB,CAAE,MAAO,GAAM,CAAC,CAClE,KAAK,eAAiB,EACtB,KAAK,iBAAmB,EAAO,kBAAoBC,EAAAA,wBACnD,KAAK,iBAAmB,EAAO,kBAAoBC,EAAAA,wBACnD,KAAK,qBACH,EAAO,sBAAwBC,EAAAA,4BAGnC,mBAAoC,CAClC,OAAO,KAAK,eAGd,qBAA8B,CAC5B,OAAO,KAAK,iBAGd,qBAA8B,CAC5B,OAAO,KAAK,iBAGd,yBAAkC,CAChC,OAAO,KAAK,qBAOd,oBAA8B,CAC5B,OAAO,KAAK,cAAc,UAAY,KAI1C,SAAgB,GAAiC,CAC/C,IAAM,GAAA,EAAA,EAAA,gBAAgC,CACtC,GAAI,EAAkB,EAAW,CAC/B,OAAO,EAET,MAAU,OAAA,EAAA,EAAA,yBACgB,CACtB,OAAQ,iCACR,SAAU,QACV,aAAc,2DACd,IAAK,+FACL,IAAK,yEACN,CAAC,CACH,CAGH,SAAgB,EAAc,EAAuC,EACnE,EAAA,EAAA,eAAkB,EAAe,CAGnC,SAAgB,EACd,EAAgC,EAAE,CAClC,EAAiC,EAChB,CACjB,IAAM,EAAiB,IAAI,EAAgB,EAAQ,EAAe,CAElE,OADA,EAAc,EAAe,CACtB,EAGT,SAAS,EACP,EAC0C,CACtC,SAAmB,OAAS,IAAmB,iBACnD,MAAU,OAAA,EAAA,EAAA,yBACgB,CACtB,OAAQ,iCACR,SAAU,QACV,aAAc,iCACd,IAAK,uEAAuE,OAAO,EAAe,CAAC,GACnG,IAAK,kEACN,CAAC,CACH,CAGH,SAAS,EACP,EAC+B,CAC/B,GAAI,aAAsB,EAAiB,MAAO,GAElD,IAAM,EAAuB,EAE7B,OACE,EAAqB,KAA0B,IAC/C,OAAO,EAAqB,mBAAsB,YAClD,OAAO,EAAqB,qBAAwB,YACpD,OAAO,EAAqB,qBAAwB,YACpD,OAAO,EAAqB,yBAA4B"}
@@ -1,2 +1,2 @@
1
- import"./cookieNames.mjs";import{I18nConfig as e,getI18nConfig as t,setI18nConfig as n}from"gt-i18n/internal";import{createDiagnosticMessage as r}from"generaltranslation/internal";const i=`server-render`,a=Symbol.for(`generaltranslation.react-core.ReactI18nConfig`);var o=class extends e{renderStrategy;localeCookieName;regionCookieName;enableI18nCookieName;constructor(e={},t=i){super(e),u(t),Object.defineProperty(this,a,{value:!0}),this.renderStrategy=t,this.localeCookieName=e.localeCookieName??`generaltranslation.locale`,this.regionCookieName=e.regionCookieName??`generaltranslation.region`,this.enableI18nCookieName=e.enableI18nCookieName??`generaltranslation.enable-i18n`}getRenderStrategy(){return this.renderStrategy}getLocaleCookieName(){return this.localeCookieName}getRegionCookieName(){return this.regionCookieName}getEnableI18nCookieName(){return this.enableI18nCookieName}isIdTaggingEnabled(){return this.runtimeConfig._tagIds===!0}};function s(){let e=t();if(d(e))return e;throw Error(r({source:`@generaltranslation/react-core`,severity:`Error`,whatHappened:`Cannot read ReactI18nConfig after base I18nConfig setup.`,why:`the internal I18nConfig singleton was initialized without react-core render strategy support`,fix:`Initialize GT through gt-react or @generaltranslation/react-core/pure.`}))}function c(e){n(e)}function l(e={},t=i){let n=new o(e,t);return c(n),n}function u(e){if(!(e===`SPA`||e===`server-render`))throw Error(r({source:`@generaltranslation/react-core`,severity:`Error`,whatHappened:`Invalid React render strategy.`,why:`the render strategy must be "SPA" or "server-render", but received "${String(e)}"`,fix:`Initialize GT through gt-react or pass a valid render strategy.`}))}function d(e){if(e instanceof o)return!0;let t=e;return t[a]===!0&&typeof t.getRenderStrategy==`function`&&typeof t.getLocaleCookieName==`function`&&typeof t.getRegionCookieName==`function`&&typeof t.getEnableI18nCookieName==`function`}export{s as getI18nConfig,l as initializeI18nConfig};
1
+ import{defaultEnableI18nCookieName as e,defaultLocaleCookieName as t,defaultRegionCookieName as n}from"./cookieNames.mjs";import{I18nConfig as r,getI18nConfig as i,setI18nConfig as a}from"gt-i18n/internal";import{createDiagnosticMessage as o}from"generaltranslation/internal";const s=`server-render`,c=Symbol.for(`generaltranslation.react-core.ReactI18nConfig`);var l=class extends r{renderStrategy;localeCookieName;regionCookieName;enableI18nCookieName;constructor(r={},i=s){super(r),p(i),Object.defineProperty(this,c,{value:!0}),this.renderStrategy=i,this.localeCookieName=r.localeCookieName??t,this.regionCookieName=r.regionCookieName??n,this.enableI18nCookieName=r.enableI18nCookieName??e}getRenderStrategy(){return this.renderStrategy}getLocaleCookieName(){return this.localeCookieName}getRegionCookieName(){return this.regionCookieName}getEnableI18nCookieName(){return this.enableI18nCookieName}isIdTaggingEnabled(){return this.runtimeConfig._tagIds===!0}};function u(){let e=i();if(m(e))return e;throw Error(o({source:`@generaltranslation/react-core`,severity:`Error`,whatHappened:`Cannot read ReactI18nConfig after base I18nConfig setup.`,why:`the internal I18nConfig singleton was initialized without react-core render strategy support`,fix:`Initialize GT through gt-react or @generaltranslation/react-core/pure.`}))}function d(e){a(e)}function f(e={},t=s){let n=new l(e,t);return d(n),n}function p(e){if(!(e===`SPA`||e===`server-render`))throw Error(o({source:`@generaltranslation/react-core`,severity:`Error`,whatHappened:`Invalid React render strategy.`,why:`the render strategy must be "SPA" or "server-render", but received "${String(e)}"`,fix:`Initialize GT through gt-react or pass a valid render strategy.`}))}function m(e){if(e instanceof l)return!0;let t=e;return t[c]===!0&&typeof t.getRenderStrategy==`function`&&typeof t.getLocaleCookieName==`function`&&typeof t.getRegionCookieName==`function`&&typeof t.getEnableI18nCookieName==`function`}export{u as getI18nConfig,f as initializeI18nConfig};
2
2
  //# sourceMappingURL=i18nConfig.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"i18nConfig.mjs","names":["getI18nConfig","getBaseI18nConfig","setI18nConfig"],"sources":["../../src/setup/i18nConfig.ts"],"sourcesContent":["import { createDiagnosticMessage } from 'generaltranslation/internal';\nimport {\n getI18nConfig as getBaseI18nConfig,\n I18nConfig,\n setI18nConfig as setBaseI18nConfig,\n} from 'gt-i18n/internal';\nimport type { I18nConfigParams as BaseI18nConfigParams } from 'gt-i18n/internal/types';\nimport {\n defaultEnableI18nCookieName,\n defaultLocaleCookieName,\n defaultRegionCookieName,\n} from './cookieNames';\n\n/**\n * Helps us distinguish behavior for SPA vs server-rendered apps.\n * - server-rendered apps must use context\n * - SPA apps can synchronously access the locale\n */\nexport type RenderStrategy = 'SPA' | 'server-render';\n\ntype CookieNameConfig = {\n localeCookieName?: string;\n regionCookieName?: string;\n enableI18nCookieName?: string;\n};\n\nexport type ReactI18nConfigParams = BaseI18nConfigParams & CookieNameConfig;\n\nconst defaultRenderStrategy: RenderStrategy = 'server-render';\nconst reactI18nConfigBrand = Symbol.for(\n 'generaltranslation.react-core.ReactI18nConfig'\n);\n\nexport class ReactI18nConfig extends I18nConfig {\n private renderStrategy: RenderStrategy;\n private localeCookieName: string;\n private regionCookieName: string;\n private enableI18nCookieName: string;\n\n constructor(\n params: ReactI18nConfigParams = {},\n renderStrategy: RenderStrategy = defaultRenderStrategy\n ) {\n super(params);\n validateRenderStrategy(renderStrategy);\n Object.defineProperty(this, reactI18nConfigBrand, { value: true });\n this.renderStrategy = renderStrategy;\n this.localeCookieName = params.localeCookieName ?? defaultLocaleCookieName;\n this.regionCookieName = params.regionCookieName ?? defaultRegionCookieName;\n this.enableI18nCookieName =\n params.enableI18nCookieName ?? defaultEnableI18nCookieName;\n }\n\n getRenderStrategy(): RenderStrategy {\n return this.renderStrategy;\n }\n\n getLocaleCookieName(): string {\n return this.localeCookieName;\n }\n\n getRegionCookieName(): string {\n return this.regionCookieName;\n }\n\n getEnableI18nCookieName(): string {\n return this.enableI18nCookieName;\n }\n\n /**\n * Opt-in (`_tagIds`): whether `<T>` output should carry its translation hash as\n * a `data-_gt-hash` attribute for tooling. Requires the literal `true`.\n */\n isIdTaggingEnabled(): boolean {\n return this.runtimeConfig._tagIds === true;\n }\n}\n\nexport function getI18nConfig(): ReactI18nConfig {\n const i18nConfig = getBaseI18nConfig();\n if (isReactI18nConfig(i18nConfig)) {\n return i18nConfig;\n }\n throw new Error(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Error',\n whatHappened: 'Cannot read ReactI18nConfig after base I18nConfig setup.',\n why: 'the internal I18nConfig singleton was initialized without react-core render strategy support',\n fix: 'Initialize GT through gt-react or @generaltranslation/react-core/pure.',\n })\n );\n}\n\nexport function setI18nConfig(nextI18nConfig: ReactI18nConfig): void {\n setBaseI18nConfig(nextI18nConfig);\n}\n\nexport function initializeI18nConfig(\n params: ReactI18nConfigParams = {},\n renderStrategy: RenderStrategy = defaultRenderStrategy\n): ReactI18nConfig {\n const nextI18nConfig = new ReactI18nConfig(params, renderStrategy);\n setI18nConfig(nextI18nConfig);\n return nextI18nConfig;\n}\n\nfunction validateRenderStrategy(\n renderStrategy: RenderStrategy\n): asserts renderStrategy is RenderStrategy {\n if (renderStrategy === 'SPA' || renderStrategy === 'server-render') return;\n throw new Error(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Error',\n whatHappened: 'Invalid React render strategy.',\n why: `the render strategy must be \"SPA\" or \"server-render\", but received \"${String(renderStrategy)}\"`,\n fix: 'Initialize GT through gt-react or pass a valid render strategy.',\n })\n );\n}\n\nfunction isReactI18nConfig(\n i18nConfig: I18nConfig\n): i18nConfig is ReactI18nConfig {\n if (i18nConfig instanceof ReactI18nConfig) return true;\n\n const maybeReactI18nConfig = i18nConfig as I18nConfig &\n Record<PropertyKey, unknown>;\n return (\n maybeReactI18nConfig[reactI18nConfigBrand] === true &&\n typeof maybeReactI18nConfig.getRenderStrategy === 'function' &&\n typeof maybeReactI18nConfig.getLocaleCookieName === 'function' &&\n typeof maybeReactI18nConfig.getRegionCookieName === 'function' &&\n typeof maybeReactI18nConfig.getEnableI18nCookieName === 'function'\n );\n}\n"],"mappings":"oLA4BA,MAAM,EAAwC,gBACxC,EAAuB,OAAO,IAClC,gDACD,CAED,IAAa,EAAb,cAAqC,CAAW,CAC9C,eACA,iBACA,iBACA,qBAEA,YACE,EAAgC,EAAE,CAClC,EAAiC,EACjC,CACA,MAAM,EAAO,CACb,EAAuB,EAAe,CACtC,OAAO,eAAe,KAAM,EAAsB,CAAE,MAAO,GAAM,CAAC,CAClE,KAAK,eAAiB,EACtB,KAAK,iBAAmB,EAAO,kBAAA,4BAC/B,KAAK,iBAAmB,EAAO,kBAAA,4BAC/B,KAAK,qBACH,EAAO,sBAAA,iCAGX,mBAAoC,CAClC,OAAO,KAAK,eAGd,qBAA8B,CAC5B,OAAO,KAAK,iBAGd,qBAA8B,CAC5B,OAAO,KAAK,iBAGd,yBAAkC,CAChC,OAAO,KAAK,qBAOd,oBAA8B,CAC5B,OAAO,KAAK,cAAc,UAAY,KAI1C,SAAgBA,GAAiC,CAC/C,IAAM,EAAaC,GAAmB,CACtC,GAAI,EAAkB,EAAW,CAC/B,OAAO,EAET,MAAU,MACR,EAAwB,CACtB,OAAQ,iCACR,SAAU,QACV,aAAc,2DACd,IAAK,+FACL,IAAK,yEACN,CAAC,CACH,CAGH,SAAgBC,EAAc,EAAuC,CACnE,EAAkB,EAAe,CAGnC,SAAgB,EACd,EAAgC,EAAE,CAClC,EAAiC,EAChB,CACjB,IAAM,EAAiB,IAAI,EAAgB,EAAQ,EAAe,CAElE,OADA,EAAc,EAAe,CACtB,EAGT,SAAS,EACP,EAC0C,CACtC,SAAmB,OAAS,IAAmB,iBACnD,MAAU,MACR,EAAwB,CACtB,OAAQ,iCACR,SAAU,QACV,aAAc,iCACd,IAAK,uEAAuE,OAAO,EAAe,CAAC,GACnG,IAAK,kEACN,CAAC,CACH,CAGH,SAAS,EACP,EAC+B,CAC/B,GAAI,aAAsB,EAAiB,MAAO,GAElD,IAAM,EAAuB,EAE7B,OACE,EAAqB,KAA0B,IAC/C,OAAO,EAAqB,mBAAsB,YAClD,OAAO,EAAqB,qBAAwB,YACpD,OAAO,EAAqB,qBAAwB,YACpD,OAAO,EAAqB,yBAA4B"}
1
+ {"version":3,"file":"i18nConfig.mjs","names":["getI18nConfig","getBaseI18nConfig","setI18nConfig"],"sources":["../../src/setup/i18nConfig.ts"],"sourcesContent":["import { createDiagnosticMessage } from 'generaltranslation/internal';\nimport {\n getI18nConfig as getBaseI18nConfig,\n I18nConfig,\n setI18nConfig as setBaseI18nConfig,\n} from 'gt-i18n/internal';\nimport type { I18nConfigParams as BaseI18nConfigParams } from 'gt-i18n/internal/types';\nimport {\n defaultEnableI18nCookieName,\n defaultLocaleCookieName,\n defaultRegionCookieName,\n} from './cookieNames';\n\n/**\n * Helps us distinguish behavior for SPA vs server-rendered apps.\n * - server-rendered apps must use context\n * - SPA apps can synchronously access the locale\n */\nexport type RenderStrategy = 'SPA' | 'server-render';\n\ntype CookieNameConfig = {\n localeCookieName?: string;\n regionCookieName?: string;\n enableI18nCookieName?: string;\n};\n\nexport type ReactI18nConfigParams = BaseI18nConfigParams & CookieNameConfig;\n\nconst defaultRenderStrategy: RenderStrategy = 'server-render';\nconst reactI18nConfigBrand = Symbol.for(\n 'generaltranslation.react-core.ReactI18nConfig'\n);\n\nexport class ReactI18nConfig extends I18nConfig {\n private renderStrategy: RenderStrategy;\n private localeCookieName: string;\n private regionCookieName: string;\n private enableI18nCookieName: string;\n\n constructor(\n params: ReactI18nConfigParams = {},\n renderStrategy: RenderStrategy = defaultRenderStrategy\n ) {\n super(params);\n validateRenderStrategy(renderStrategy);\n Object.defineProperty(this, reactI18nConfigBrand, { value: true });\n this.renderStrategy = renderStrategy;\n this.localeCookieName = params.localeCookieName ?? defaultLocaleCookieName;\n this.regionCookieName = params.regionCookieName ?? defaultRegionCookieName;\n this.enableI18nCookieName =\n params.enableI18nCookieName ?? defaultEnableI18nCookieName;\n }\n\n getRenderStrategy(): RenderStrategy {\n return this.renderStrategy;\n }\n\n getLocaleCookieName(): string {\n return this.localeCookieName;\n }\n\n getRegionCookieName(): string {\n return this.regionCookieName;\n }\n\n getEnableI18nCookieName(): string {\n return this.enableI18nCookieName;\n }\n\n /**\n * Opt-in (`_tagIds`): whether `<T>` output should carry its translation hash as\n * a `data-_gt-hash` attribute for tooling. Requires the literal `true`.\n */\n isIdTaggingEnabled(): boolean {\n return this.runtimeConfig._tagIds === true;\n }\n}\n\nexport function getI18nConfig(): ReactI18nConfig {\n const i18nConfig = getBaseI18nConfig();\n if (isReactI18nConfig(i18nConfig)) {\n return i18nConfig;\n }\n throw new Error(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Error',\n whatHappened: 'Cannot read ReactI18nConfig after base I18nConfig setup.',\n why: 'the internal I18nConfig singleton was initialized without react-core render strategy support',\n fix: 'Initialize GT through gt-react or @generaltranslation/react-core/pure.',\n })\n );\n}\n\nexport function setI18nConfig(nextI18nConfig: ReactI18nConfig): void {\n setBaseI18nConfig(nextI18nConfig);\n}\n\nexport function initializeI18nConfig(\n params: ReactI18nConfigParams = {},\n renderStrategy: RenderStrategy = defaultRenderStrategy\n): ReactI18nConfig {\n const nextI18nConfig = new ReactI18nConfig(params, renderStrategy);\n setI18nConfig(nextI18nConfig);\n return nextI18nConfig;\n}\n\nfunction validateRenderStrategy(\n renderStrategy: RenderStrategy\n): asserts renderStrategy is RenderStrategy {\n if (renderStrategy === 'SPA' || renderStrategy === 'server-render') return;\n throw new Error(\n createDiagnosticMessage({\n source: '@generaltranslation/react-core',\n severity: 'Error',\n whatHappened: 'Invalid React render strategy.',\n why: `the render strategy must be \"SPA\" or \"server-render\", but received \"${String(renderStrategy)}\"`,\n fix: 'Initialize GT through gt-react or pass a valid render strategy.',\n })\n );\n}\n\nfunction isReactI18nConfig(\n i18nConfig: I18nConfig\n): i18nConfig is ReactI18nConfig {\n if (i18nConfig instanceof ReactI18nConfig) return true;\n\n const maybeReactI18nConfig = i18nConfig as I18nConfig &\n Record<PropertyKey, unknown>;\n return (\n maybeReactI18nConfig[reactI18nConfigBrand] === true &&\n typeof maybeReactI18nConfig.getRenderStrategy === 'function' &&\n typeof maybeReactI18nConfig.getLocaleCookieName === 'function' &&\n typeof maybeReactI18nConfig.getRegionCookieName === 'function' &&\n typeof maybeReactI18nConfig.getEnableI18nCookieName === 'function'\n );\n}\n"],"mappings":"oRA4BA,MAAM,EAAwC,gBACxC,EAAuB,OAAO,IAClC,gDACD,CAED,IAAa,EAAb,cAAqC,CAAW,CAC9C,eACA,iBACA,iBACA,qBAEA,YACE,EAAgC,EAAE,CAClC,EAAiC,EACjC,CACA,MAAM,EAAO,CACb,EAAuB,EAAe,CACtC,OAAO,eAAe,KAAM,EAAsB,CAAE,MAAO,GAAM,CAAC,CAClE,KAAK,eAAiB,EACtB,KAAK,iBAAmB,EAAO,kBAAoB,EACnD,KAAK,iBAAmB,EAAO,kBAAoB,EACnD,KAAK,qBACH,EAAO,sBAAwB,EAGnC,mBAAoC,CAClC,OAAO,KAAK,eAGd,qBAA8B,CAC5B,OAAO,KAAK,iBAGd,qBAA8B,CAC5B,OAAO,KAAK,iBAGd,yBAAkC,CAChC,OAAO,KAAK,qBAOd,oBAA8B,CAC5B,OAAO,KAAK,cAAc,UAAY,KAI1C,SAAgBA,GAAiC,CAC/C,IAAM,EAAaC,GAAmB,CACtC,GAAI,EAAkB,EAAW,CAC/B,OAAO,EAET,MAAU,MACR,EAAwB,CACtB,OAAQ,iCACR,SAAU,QACV,aAAc,2DACd,IAAK,+FACL,IAAK,yEACN,CAAC,CACH,CAGH,SAAgBC,EAAc,EAAuC,CACnE,EAAkB,EAAe,CAGnC,SAAgB,EACd,EAAgC,EAAE,CAClC,EAAiC,EAChB,CACjB,IAAM,EAAiB,IAAI,EAAgB,EAAQ,EAAe,CAElE,OADA,EAAc,EAAe,CACtB,EAGT,SAAS,EACP,EAC0C,CACtC,SAAmB,OAAS,IAAmB,iBACnD,MAAU,MACR,EAAwB,CACtB,OAAQ,iCACR,SAAU,QACV,aAAc,iCACd,IAAK,uEAAuE,OAAO,EAAe,CAAC,GACnG,IAAK,kEACN,CAAC,CACH,CAGH,SAAS,EACP,EAC+B,CAC/B,GAAI,aAAsB,EAAiB,MAAO,GAElD,IAAM,EAAuB,EAE7B,OACE,EAAqB,KAA0B,IAC/C,OAAO,EAAqB,mBAAsB,YAClD,OAAO,EAAqB,qBAAwB,YACpD,OAAO,EAAqB,qBAAwB,YACpD,OAAO,EAAqB,yBAA4B"}
@@ -1 +1 @@
1
- {"version":3,"file":"renderPreparedT.shared.cjs","names":["Fragment","idTaggingEnabled"],"sources":["../../../src/utils/rendering/renderPreparedT.shared.ts"],"sourcesContent":["import type { RenderDefaultChildrenArgs } from './renderDefaultChildren.shared';\nimport type { RenderTranslatedChildrenArgs } from './renderTranslatedChildren.shared';\nimport type { JsxChildren } from 'generaltranslation/types';\nimport {\n cloneElement,\n createElement,\n Fragment,\n isValidElement,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { TaggedChildren } from '../types';\nimport { idTaggingEnabled } from '../translation/resolveTagHash';\n\n// Opt-in id-tagging: when a `hash` is provided, the translation hash is exposed\n// on the DOM as `data-_gt-hash` so tooling can map a rendered node back to its\n// published translation.\n//\n// Span injection is kept to the minimum necessary: when the <T> renders a single\n// host element we put the attribute directly on THAT element (no wrapper), so <T>\n// keeps copying the source 1:1. Only when there is no element to carry it — bare\n// text, a fragment, or a component root — do we inject a layout-neutral span\n// (`display: contents`, so it generates no box and children lay out as before).\n//\n// DOM-only: skipped on React Native (there is no `span`/DOM attribute analog).\n// The rest of this module stays platform-agnostic; this is a runtime guard, not a\n// native import.\nconst TAG_STYLE = { display: 'contents' } as const;\n// Canonical React Native detection (RN sets navigator.product = 'ReactNative').\n// False in the browser AND in Node SSR/RSC, so the span is still emitted server-\n// side (where the harvest reads it).\nconst IS_REACT_NATIVE =\n (globalThis as { navigator?: { product?: string } }).navigator?.product ===\n 'ReactNative';\n\n// Whether a rendered node produces NO DOM — so id-tagging must leave it untouched\n// (wrapping it in a hash span would create an empty <span>, altering :empty/child\n// structure and injecting an invalid span under restricted parents). Covers the\n// scalar non-renderers (null / undefined / booleans / ''), arrays whose every\n// element renders nothing (`items.map(...)` over an empty list, `[null, false]`,\n// nested empties — TaggedChildren accepts arrays), and empty React fragments.\n// NB: 0 and NaN DO render text, so they are intentionally NOT treated as empty.\nfunction rendersNothing(node: ReactNode): boolean {\n if (node == null || typeof node === 'boolean' || node === '') return true;\n if (Array.isArray(node)) return !node.some((n) => !rendersNothing(n));\n if (isValidElement(node) && node.type === Fragment) {\n const children = (node.props as { children?: ReactNode }).children;\n return children == null || rendersNothing(children);\n }\n return false;\n}\n\n// Opt-in id-tagging (powers RRWeb localized replay / in-context tooling): expose\n// the translation hash on the DOM as `data-_gt-hash`. Factored out of the render\n// path so it's clear this whole block is dedicated to id-tagging, not core <T>\n// behavior. Called only when a `hash` was produced (see resolveTagHash).\nfunction applyIdTag(rendered: ReactNode, hash: string): ReactNode {\n // `hash` is only produced when tagging is on, but re-assert the config here so a\n // stray hash can never inject DOM; and never on React Native (no span/DOM attr\n // analog — IS_REACT_NATIVE is checked first so the config isn't read there).\n if (IS_REACT_NATIVE || !idTaggingEnabled()) return rendered;\n // Single host element (e.g. `<T><td>…</td></T>`) → annotate it directly, no\n // wrapper. Valid wherever the element itself is valid — including inside\n // <tr>/<select>/<ul> — and avoids the span entirely.\n if (isValidElement(rendered) && typeof rendered.type === 'string') {\n return cloneElement(rendered as ReactElement<Record<string, unknown>>, {\n 'data-_gt-hash': hash,\n });\n }\n // Output that renders no DOM stays no-DOM: an empty <span data-_gt-hash> would\n // change :empty/child structure and inject an (invalid, under restricted\n // parents) span even for an empty branch.\n if (rendersNothing(rendered)) return rendered;\n // No element to carry the attribute (bare text / fragment / component root) →\n // wrap in a layout-neutral span. This is the only case that injects one.\n return createElement(\n 'span',\n { 'data-_gt-hash': hash, style: TAG_STYLE },\n rendered\n );\n}\n\n// Shared rendering logic. The child renderers are injected so the RSC code path\n// never statically imports the hook-based variable components, and so the\n// pipeline can build them once and share them. This module must stay free of\n// hook/context imports so it can be reached from the components-rsc entrypoint.\n\ntype RenderPreparedTParams = {\n taggedSourceChildren: TaggedChildren;\n targetJsxChildren: JsxChildren | null | undefined;\n locale: string;\n defaultLocale: string;\n enableI18n: boolean;\n shouldTranslate: boolean;\n // The translation hash for this <T> (see resolveTagHash) — the same key the\n // published-translation cache/CDN is keyed by. Set only when id-tagging is\n // enabled; when undefined the output is rendered untouched. Presence of `hash`\n // is the single signal to tag (there is no separate boolean).\n hash?: string;\n};\n\nfunction createRenderPreparedT({\n renderDefaultChildren,\n renderTranslatedChildren,\n}: {\n renderDefaultChildren: (args: RenderDefaultChildrenArgs) => ReactNode;\n renderTranslatedChildren: (args: RenderTranslatedChildrenArgs) => ReactNode;\n}): (args: RenderPreparedTParams) => ReactNode {\n function renderPreparedT({\n taggedSourceChildren,\n targetJsxChildren,\n locale,\n defaultLocale,\n enableI18n,\n shouldTranslate,\n hash,\n }: RenderPreparedTParams): ReactNode {\n const rendered =\n !shouldTranslate || targetJsxChildren == null\n ? renderSource({\n taggedSourceChildren,\n defaultLocale,\n enableI18n,\n })\n : renderTarget({\n taggedSourceChildren,\n targetJsxChildren,\n locales: [locale, defaultLocale],\n enableI18n,\n });\n\n // Opt-in id-tagging is entirely handled by applyIdTag; `hash` presence is the\n // enable signal (produced by resolveTagHash only when tagging is on).\n return hash ? applyIdTag(rendered, hash) : rendered;\n }\n\n function renderSource({\n taggedSourceChildren,\n defaultLocale,\n enableI18n,\n }: {\n taggedSourceChildren: TaggedChildren;\n defaultLocale: string;\n enableI18n: boolean;\n }): ReactNode {\n return renderDefaultChildren({\n children: taggedSourceChildren,\n defaultLocale,\n enableI18n,\n });\n }\n\n function renderTarget({\n taggedSourceChildren,\n targetJsxChildren,\n locales,\n enableI18n,\n }: {\n taggedSourceChildren: TaggedChildren;\n targetJsxChildren: JsxChildren;\n locales: string[];\n enableI18n: boolean;\n }): ReactNode {\n return renderTranslatedChildren({\n source: taggedSourceChildren,\n target: targetJsxChildren,\n locales,\n enableI18n,\n });\n }\n\n return renderPreparedT;\n}\n\nexport { createRenderPreparedT };\nexport type { RenderPreparedTParams };\n"],"mappings":"4HA2BA,MAAM,EAAY,CAAE,QAAS,WAAY,CAInC,EACH,WAAoD,WAAW,UAChE,cASF,SAAS,EAAe,EAA0B,CAChD,GAAI,GAAQ,MAAQ,OAAO,GAAS,WAAa,IAAS,GAAI,MAAO,GACrE,GAAI,MAAM,QAAQ,EAAK,CAAE,MAAO,CAAC,EAAK,KAAM,GAAM,CAAC,EAAe,EAAE,CAAC,CACrE,IAAA,EAAA,EAAA,gBAAmB,EAAK,EAAI,EAAK,OAASA,EAAAA,SAAU,CAClD,IAAM,EAAY,EAAK,MAAmC,SAC1D,OAAO,GAAY,MAAQ,EAAe,EAAS,CAErD,MAAO,GAOT,SAAS,EAAW,EAAqB,EAAyB,CAmBhE,OAfI,GAAmB,CAACC,EAAAA,kBAAkB,CAAS,GAInD,EAAA,EAAA,gBAAmB,EAAS,EAAI,OAAO,EAAS,MAAS,UACvD,EAAA,EAAA,cAAoB,EAAmD,CACrE,gBAAiB,EAClB,CAAC,CAKA,EAAe,EAAS,CAAS,GAGrC,EAAA,EAAA,eACE,OACA,CAAE,gBAAiB,EAAM,MAAO,EAAW,CAC3C,EACD,CAsBH,SAAS,EAAsB,CAC7B,wBACA,4BAI6C,CAC7C,SAAS,EAAgB,CACvB,uBACA,oBACA,SACA,gBACA,aACA,kBACA,QACmC,CACnC,IAAM,EACJ,CAAC,GAAmB,GAAqB,KACrC,EAAa,CACX,uBACA,gBACA,aACD,CAAC,CACF,EAAa,CACX,uBACA,oBACA,QAAS,CAAC,EAAQ,EAAc,CAChC,aACD,CAAC,CAIR,OAAO,EAAO,EAAW,EAAU,EAAK,CAAG,EAG7C,SAAS,EAAa,CACpB,uBACA,gBACA,cAKY,CACZ,OAAO,EAAsB,CAC3B,SAAU,EACV,gBACA,aACD,CAAC,CAGJ,SAAS,EAAa,CACpB,uBACA,oBACA,UACA,cAMY,CACZ,OAAO,EAAyB,CAC9B,OAAQ,EACR,OAAQ,EACR,UACA,aACD,CAAC,CAGJ,OAAO"}
1
+ {"version":3,"file":"renderPreparedT.shared.cjs","names":["Fragment","idTaggingEnabled"],"sources":["../../../src/utils/rendering/renderPreparedT.shared.ts"],"sourcesContent":["import type { RenderDefaultChildrenArgs } from './renderDefaultChildren.shared';\nimport type { RenderTranslatedChildrenArgs } from './renderTranslatedChildren.shared';\nimport type { JsxChildren } from 'generaltranslation/types';\nimport {\n cloneElement,\n createElement,\n Fragment,\n isValidElement,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { TaggedChildren } from '../types';\nimport { idTaggingEnabled } from '../translation/resolveTagHash';\n\n// Opt-in id-tagging: when a `hash` is provided, the translation hash is exposed\n// on the DOM as `data-_gt-hash` so tooling can map a rendered node back to its\n// published translation.\n//\n// Span injection is kept to the minimum necessary: when the <T> renders a single\n// host element we put the attribute directly on THAT element (no wrapper), so <T>\n// keeps copying the source 1:1. Only when there is no element to carry it — bare\n// text, a fragment, or a component root — do we inject a layout-neutral span\n// (`display: contents`, so it generates no box and children lay out as before).\n//\n// DOM-only: skipped on React Native (there is no `span`/DOM attribute analog).\n// The rest of this module stays platform-agnostic; this is a runtime guard, not a\n// native import.\nconst TAG_STYLE = { display: 'contents' } as const;\n// Canonical React Native detection (RN sets navigator.product = 'ReactNative').\n// False in the browser AND in Node SSR/RSC, so the span is still emitted server-\n// side (where the harvest reads it).\nconst IS_REACT_NATIVE =\n (globalThis as { navigator?: { product?: string } }).navigator?.product ===\n 'ReactNative';\n\n// Whether a rendered node produces NO DOM — so id-tagging must leave it untouched\n// (wrapping it in a hash span would create an empty <span>, altering :empty/child\n// structure and injecting an invalid span under restricted parents). Covers the\n// scalar non-renderers (null / undefined / booleans / ''), arrays whose every\n// element renders nothing (`items.map(...)` over an empty list, `[null, false]`,\n// nested empties — TaggedChildren accepts arrays), and empty React fragments.\n// NB: 0 and NaN DO render text, so they are intentionally NOT treated as empty.\nfunction rendersNothing(node: ReactNode): boolean {\n if (node == null || typeof node === 'boolean' || node === '') return true;\n if (Array.isArray(node)) return !node.some((n) => !rendersNothing(n));\n if (isValidElement(node) && node.type === Fragment) {\n const children = (node.props as { children?: ReactNode }).children;\n return children == null || rendersNothing(children);\n }\n return false;\n}\n\n// Opt-in id-tagging (powers RRWeb localized replay / in-context tooling): expose\n// the translation hash on the DOM as `data-_gt-hash`. Factored out of the render\n// path so it's clear this whole block is dedicated to id-tagging, not core <T>\n// behavior. Called only when a `hash` was produced (see resolveTagHash).\nfunction applyIdTag(rendered: ReactNode, hash: string): ReactNode {\n // `hash` is only produced when tagging is on, but re-assert the config here so a\n // stray hash can never inject DOM; and never on React Native (no span/DOM attr\n // analog — IS_REACT_NATIVE is checked first so the config isn't read there).\n if (IS_REACT_NATIVE || !idTaggingEnabled()) return rendered;\n // Single host element (e.g. `<T><td>…</td></T>`) → annotate it directly, no\n // wrapper. Valid wherever the element itself is valid — including inside\n // <tr>/<select>/<ul> — and avoids the span entirely.\n if (isValidElement(rendered) && typeof rendered.type === 'string') {\n return cloneElement(rendered as ReactElement<Record<string, unknown>>, {\n 'data-_gt-hash': hash,\n });\n }\n // Output that renders no DOM stays no-DOM: an empty <span data-_gt-hash> would\n // change :empty/child structure and inject an (invalid, under restricted\n // parents) span even for an empty branch.\n if (rendersNothing(rendered)) return rendered;\n // No element to carry the attribute (bare text / fragment / component root) →\n // wrap in a layout-neutral span. This is the only case that injects one.\n return createElement(\n 'span',\n { 'data-_gt-hash': hash, style: TAG_STYLE },\n rendered\n );\n}\n\n// Shared rendering logic. The child renderers are injected so the RSC code path\n// never statically imports the hook-based variable components, and so the\n// pipeline can build them once and share them. This module must stay free of\n// hook/context imports so it can be reached from the components-rsc entrypoint.\n\ntype RenderPreparedTParams = {\n taggedSourceChildren: TaggedChildren;\n targetJsxChildren: JsxChildren | null | undefined;\n locale: string;\n defaultLocale: string;\n enableI18n: boolean;\n shouldTranslate: boolean;\n // The translation hash for this <T> (see resolveTagHash) — the same key the\n // published-translation cache/CDN is keyed by. Set only when id-tagging is\n // enabled; when undefined the output is rendered untouched. Presence of `hash`\n // is the single signal to tag (there is no separate boolean).\n hash?: string;\n};\n\nfunction createRenderPreparedT({\n renderDefaultChildren,\n renderTranslatedChildren,\n}: {\n renderDefaultChildren: (args: RenderDefaultChildrenArgs) => ReactNode;\n renderTranslatedChildren: (args: RenderTranslatedChildrenArgs) => ReactNode;\n}): (args: RenderPreparedTParams) => ReactNode {\n function renderPreparedT({\n taggedSourceChildren,\n targetJsxChildren,\n locale,\n defaultLocale,\n enableI18n,\n shouldTranslate,\n hash,\n }: RenderPreparedTParams): ReactNode {\n const rendered =\n !shouldTranslate || targetJsxChildren == null\n ? renderSource({\n taggedSourceChildren,\n defaultLocale,\n enableI18n,\n })\n : renderTarget({\n taggedSourceChildren,\n targetJsxChildren,\n locales: [locale, defaultLocale],\n enableI18n,\n });\n\n // Opt-in id-tagging is entirely handled by applyIdTag; `hash` presence is the\n // enable signal (produced by resolveTagHash only when tagging is on).\n return hash ? applyIdTag(rendered, hash) : rendered;\n }\n\n function renderSource({\n taggedSourceChildren,\n defaultLocale,\n enableI18n,\n }: {\n taggedSourceChildren: TaggedChildren;\n defaultLocale: string;\n enableI18n: boolean;\n }): ReactNode {\n return renderDefaultChildren({\n children: taggedSourceChildren,\n defaultLocale,\n enableI18n,\n });\n }\n\n function renderTarget({\n taggedSourceChildren,\n targetJsxChildren,\n locales,\n enableI18n,\n }: {\n taggedSourceChildren: TaggedChildren;\n targetJsxChildren: JsxChildren;\n locales: string[];\n enableI18n: boolean;\n }): ReactNode {\n return renderTranslatedChildren({\n source: taggedSourceChildren,\n // The shared persisted wire also admits empty-rendering boolean/null\n // values. The outer null check and existing renderer fallback own those\n // cases; this narrower internal renderer type describes its recursive\n // element/string grammar without changing React runtime behavior.\n target: targetJsxChildren as RenderTranslatedChildrenArgs['target'],\n locales,\n enableI18n,\n });\n }\n\n return renderPreparedT;\n}\n\nexport { createRenderPreparedT };\nexport type { RenderPreparedTParams };\n"],"mappings":"4HA2BA,MAAM,EAAY,CAAE,QAAS,WAAY,CAInC,EACH,WAAoD,WAAW,UAChE,cASF,SAAS,EAAe,EAA0B,CAChD,GAAI,GAAQ,MAAQ,OAAO,GAAS,WAAa,IAAS,GAAI,MAAO,GACrE,GAAI,MAAM,QAAQ,EAAK,CAAE,MAAO,CAAC,EAAK,KAAM,GAAM,CAAC,EAAe,EAAE,CAAC,CACrE,IAAA,EAAA,EAAA,gBAAmB,EAAK,EAAI,EAAK,OAASA,EAAAA,SAAU,CAClD,IAAM,EAAY,EAAK,MAAmC,SAC1D,OAAO,GAAY,MAAQ,EAAe,EAAS,CAErD,MAAO,GAOT,SAAS,EAAW,EAAqB,EAAyB,CAmBhE,OAfI,GAAmB,CAACC,EAAAA,kBAAkB,CAAS,GAInD,EAAA,EAAA,gBAAmB,EAAS,EAAI,OAAO,EAAS,MAAS,UACvD,EAAA,EAAA,cAAoB,EAAmD,CACrE,gBAAiB,EAClB,CAAC,CAKA,EAAe,EAAS,CAAS,GAGrC,EAAA,EAAA,eACE,OACA,CAAE,gBAAiB,EAAM,MAAO,EAAW,CAC3C,EACD,CAsBH,SAAS,EAAsB,CAC7B,wBACA,4BAI6C,CAC7C,SAAS,EAAgB,CACvB,uBACA,oBACA,SACA,gBACA,aACA,kBACA,QACmC,CACnC,IAAM,EACJ,CAAC,GAAmB,GAAqB,KACrC,EAAa,CACX,uBACA,gBACA,aACD,CAAC,CACF,EAAa,CACX,uBACA,oBACA,QAAS,CAAC,EAAQ,EAAc,CAChC,aACD,CAAC,CAIR,OAAO,EAAO,EAAW,EAAU,EAAK,CAAG,EAG7C,SAAS,EAAa,CACpB,uBACA,gBACA,cAKY,CACZ,OAAO,EAAsB,CAC3B,SAAU,EACV,gBACA,aACD,CAAC,CAGJ,SAAS,EAAa,CACpB,uBACA,oBACA,UACA,cAMY,CACZ,OAAO,EAAyB,CAC9B,OAAQ,EAKR,OAAQ,EACR,UACA,aACD,CAAC,CAGJ,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"renderPreparedT.shared.mjs","names":[],"sources":["../../../src/utils/rendering/renderPreparedT.shared.ts"],"sourcesContent":["import type { RenderDefaultChildrenArgs } from './renderDefaultChildren.shared';\nimport type { RenderTranslatedChildrenArgs } from './renderTranslatedChildren.shared';\nimport type { JsxChildren } from 'generaltranslation/types';\nimport {\n cloneElement,\n createElement,\n Fragment,\n isValidElement,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { TaggedChildren } from '../types';\nimport { idTaggingEnabled } from '../translation/resolveTagHash';\n\n// Opt-in id-tagging: when a `hash` is provided, the translation hash is exposed\n// on the DOM as `data-_gt-hash` so tooling can map a rendered node back to its\n// published translation.\n//\n// Span injection is kept to the minimum necessary: when the <T> renders a single\n// host element we put the attribute directly on THAT element (no wrapper), so <T>\n// keeps copying the source 1:1. Only when there is no element to carry it — bare\n// text, a fragment, or a component root — do we inject a layout-neutral span\n// (`display: contents`, so it generates no box and children lay out as before).\n//\n// DOM-only: skipped on React Native (there is no `span`/DOM attribute analog).\n// The rest of this module stays platform-agnostic; this is a runtime guard, not a\n// native import.\nconst TAG_STYLE = { display: 'contents' } as const;\n// Canonical React Native detection (RN sets navigator.product = 'ReactNative').\n// False in the browser AND in Node SSR/RSC, so the span is still emitted server-\n// side (where the harvest reads it).\nconst IS_REACT_NATIVE =\n (globalThis as { navigator?: { product?: string } }).navigator?.product ===\n 'ReactNative';\n\n// Whether a rendered node produces NO DOM — so id-tagging must leave it untouched\n// (wrapping it in a hash span would create an empty <span>, altering :empty/child\n// structure and injecting an invalid span under restricted parents). Covers the\n// scalar non-renderers (null / undefined / booleans / ''), arrays whose every\n// element renders nothing (`items.map(...)` over an empty list, `[null, false]`,\n// nested empties — TaggedChildren accepts arrays), and empty React fragments.\n// NB: 0 and NaN DO render text, so they are intentionally NOT treated as empty.\nfunction rendersNothing(node: ReactNode): boolean {\n if (node == null || typeof node === 'boolean' || node === '') return true;\n if (Array.isArray(node)) return !node.some((n) => !rendersNothing(n));\n if (isValidElement(node) && node.type === Fragment) {\n const children = (node.props as { children?: ReactNode }).children;\n return children == null || rendersNothing(children);\n }\n return false;\n}\n\n// Opt-in id-tagging (powers RRWeb localized replay / in-context tooling): expose\n// the translation hash on the DOM as `data-_gt-hash`. Factored out of the render\n// path so it's clear this whole block is dedicated to id-tagging, not core <T>\n// behavior. Called only when a `hash` was produced (see resolveTagHash).\nfunction applyIdTag(rendered: ReactNode, hash: string): ReactNode {\n // `hash` is only produced when tagging is on, but re-assert the config here so a\n // stray hash can never inject DOM; and never on React Native (no span/DOM attr\n // analog — IS_REACT_NATIVE is checked first so the config isn't read there).\n if (IS_REACT_NATIVE || !idTaggingEnabled()) return rendered;\n // Single host element (e.g. `<T><td>…</td></T>`) → annotate it directly, no\n // wrapper. Valid wherever the element itself is valid — including inside\n // <tr>/<select>/<ul> — and avoids the span entirely.\n if (isValidElement(rendered) && typeof rendered.type === 'string') {\n return cloneElement(rendered as ReactElement<Record<string, unknown>>, {\n 'data-_gt-hash': hash,\n });\n }\n // Output that renders no DOM stays no-DOM: an empty <span data-_gt-hash> would\n // change :empty/child structure and inject an (invalid, under restricted\n // parents) span even for an empty branch.\n if (rendersNothing(rendered)) return rendered;\n // No element to carry the attribute (bare text / fragment / component root) →\n // wrap in a layout-neutral span. This is the only case that injects one.\n return createElement(\n 'span',\n { 'data-_gt-hash': hash, style: TAG_STYLE },\n rendered\n );\n}\n\n// Shared rendering logic. The child renderers are injected so the RSC code path\n// never statically imports the hook-based variable components, and so the\n// pipeline can build them once and share them. This module must stay free of\n// hook/context imports so it can be reached from the components-rsc entrypoint.\n\ntype RenderPreparedTParams = {\n taggedSourceChildren: TaggedChildren;\n targetJsxChildren: JsxChildren | null | undefined;\n locale: string;\n defaultLocale: string;\n enableI18n: boolean;\n shouldTranslate: boolean;\n // The translation hash for this <T> (see resolveTagHash) — the same key the\n // published-translation cache/CDN is keyed by. Set only when id-tagging is\n // enabled; when undefined the output is rendered untouched. Presence of `hash`\n // is the single signal to tag (there is no separate boolean).\n hash?: string;\n};\n\nfunction createRenderPreparedT({\n renderDefaultChildren,\n renderTranslatedChildren,\n}: {\n renderDefaultChildren: (args: RenderDefaultChildrenArgs) => ReactNode;\n renderTranslatedChildren: (args: RenderTranslatedChildrenArgs) => ReactNode;\n}): (args: RenderPreparedTParams) => ReactNode {\n function renderPreparedT({\n taggedSourceChildren,\n targetJsxChildren,\n locale,\n defaultLocale,\n enableI18n,\n shouldTranslate,\n hash,\n }: RenderPreparedTParams): ReactNode {\n const rendered =\n !shouldTranslate || targetJsxChildren == null\n ? renderSource({\n taggedSourceChildren,\n defaultLocale,\n enableI18n,\n })\n : renderTarget({\n taggedSourceChildren,\n targetJsxChildren,\n locales: [locale, defaultLocale],\n enableI18n,\n });\n\n // Opt-in id-tagging is entirely handled by applyIdTag; `hash` presence is the\n // enable signal (produced by resolveTagHash only when tagging is on).\n return hash ? applyIdTag(rendered, hash) : rendered;\n }\n\n function renderSource({\n taggedSourceChildren,\n defaultLocale,\n enableI18n,\n }: {\n taggedSourceChildren: TaggedChildren;\n defaultLocale: string;\n enableI18n: boolean;\n }): ReactNode {\n return renderDefaultChildren({\n children: taggedSourceChildren,\n defaultLocale,\n enableI18n,\n });\n }\n\n function renderTarget({\n taggedSourceChildren,\n targetJsxChildren,\n locales,\n enableI18n,\n }: {\n taggedSourceChildren: TaggedChildren;\n targetJsxChildren: JsxChildren;\n locales: string[];\n enableI18n: boolean;\n }): ReactNode {\n return renderTranslatedChildren({\n source: taggedSourceChildren,\n target: targetJsxChildren,\n locales,\n enableI18n,\n });\n }\n\n return renderPreparedT;\n}\n\nexport { createRenderPreparedT };\nexport type { RenderPreparedTParams };\n"],"mappings":"+JA2BA,MAAM,EAAY,CAAE,QAAS,WAAY,CAInC,EACH,WAAoD,WAAW,UAChE,cASF,SAAS,EAAe,EAA0B,CAChD,GAAI,GAAQ,MAAQ,OAAO,GAAS,WAAa,IAAS,GAAI,MAAO,GACrE,GAAI,MAAM,QAAQ,EAAK,CAAE,MAAO,CAAC,EAAK,KAAM,GAAM,CAAC,EAAe,EAAE,CAAC,CACrE,GAAI,EAAe,EAAK,EAAI,EAAK,OAAS,EAAU,CAClD,IAAM,EAAY,EAAK,MAAmC,SAC1D,OAAO,GAAY,MAAQ,EAAe,EAAS,CAErD,MAAO,GAOT,SAAS,EAAW,EAAqB,EAAyB,CAmBhE,OAfI,GAAmB,CAAC,GAAkB,CAAS,EAI/C,EAAe,EAAS,EAAI,OAAO,EAAS,MAAS,SAChD,EAAa,EAAmD,CACrE,gBAAiB,EAClB,CAAC,CAKA,EAAe,EAAS,CAAS,EAG9B,EACL,OACA,CAAE,gBAAiB,EAAM,MAAO,EAAW,CAC3C,EACD,CAsBH,SAAS,EAAsB,CAC7B,wBACA,4BAI6C,CAC7C,SAAS,EAAgB,CACvB,uBACA,oBACA,SACA,gBACA,aACA,kBACA,QACmC,CACnC,IAAM,EACJ,CAAC,GAAmB,GAAqB,KACrC,EAAa,CACX,uBACA,gBACA,aACD,CAAC,CACF,EAAa,CACX,uBACA,oBACA,QAAS,CAAC,EAAQ,EAAc,CAChC,aACD,CAAC,CAIR,OAAO,EAAO,EAAW,EAAU,EAAK,CAAG,EAG7C,SAAS,EAAa,CACpB,uBACA,gBACA,cAKY,CACZ,OAAO,EAAsB,CAC3B,SAAU,EACV,gBACA,aACD,CAAC,CAGJ,SAAS,EAAa,CACpB,uBACA,oBACA,UACA,cAMY,CACZ,OAAO,EAAyB,CAC9B,OAAQ,EACR,OAAQ,EACR,UACA,aACD,CAAC,CAGJ,OAAO"}
1
+ {"version":3,"file":"renderPreparedT.shared.mjs","names":[],"sources":["../../../src/utils/rendering/renderPreparedT.shared.ts"],"sourcesContent":["import type { RenderDefaultChildrenArgs } from './renderDefaultChildren.shared';\nimport type { RenderTranslatedChildrenArgs } from './renderTranslatedChildren.shared';\nimport type { JsxChildren } from 'generaltranslation/types';\nimport {\n cloneElement,\n createElement,\n Fragment,\n isValidElement,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport type { TaggedChildren } from '../types';\nimport { idTaggingEnabled } from '../translation/resolveTagHash';\n\n// Opt-in id-tagging: when a `hash` is provided, the translation hash is exposed\n// on the DOM as `data-_gt-hash` so tooling can map a rendered node back to its\n// published translation.\n//\n// Span injection is kept to the minimum necessary: when the <T> renders a single\n// host element we put the attribute directly on THAT element (no wrapper), so <T>\n// keeps copying the source 1:1. Only when there is no element to carry it — bare\n// text, a fragment, or a component root — do we inject a layout-neutral span\n// (`display: contents`, so it generates no box and children lay out as before).\n//\n// DOM-only: skipped on React Native (there is no `span`/DOM attribute analog).\n// The rest of this module stays platform-agnostic; this is a runtime guard, not a\n// native import.\nconst TAG_STYLE = { display: 'contents' } as const;\n// Canonical React Native detection (RN sets navigator.product = 'ReactNative').\n// False in the browser AND in Node SSR/RSC, so the span is still emitted server-\n// side (where the harvest reads it).\nconst IS_REACT_NATIVE =\n (globalThis as { navigator?: { product?: string } }).navigator?.product ===\n 'ReactNative';\n\n// Whether a rendered node produces NO DOM — so id-tagging must leave it untouched\n// (wrapping it in a hash span would create an empty <span>, altering :empty/child\n// structure and injecting an invalid span under restricted parents). Covers the\n// scalar non-renderers (null / undefined / booleans / ''), arrays whose every\n// element renders nothing (`items.map(...)` over an empty list, `[null, false]`,\n// nested empties — TaggedChildren accepts arrays), and empty React fragments.\n// NB: 0 and NaN DO render text, so they are intentionally NOT treated as empty.\nfunction rendersNothing(node: ReactNode): boolean {\n if (node == null || typeof node === 'boolean' || node === '') return true;\n if (Array.isArray(node)) return !node.some((n) => !rendersNothing(n));\n if (isValidElement(node) && node.type === Fragment) {\n const children = (node.props as { children?: ReactNode }).children;\n return children == null || rendersNothing(children);\n }\n return false;\n}\n\n// Opt-in id-tagging (powers RRWeb localized replay / in-context tooling): expose\n// the translation hash on the DOM as `data-_gt-hash`. Factored out of the render\n// path so it's clear this whole block is dedicated to id-tagging, not core <T>\n// behavior. Called only when a `hash` was produced (see resolveTagHash).\nfunction applyIdTag(rendered: ReactNode, hash: string): ReactNode {\n // `hash` is only produced when tagging is on, but re-assert the config here so a\n // stray hash can never inject DOM; and never on React Native (no span/DOM attr\n // analog — IS_REACT_NATIVE is checked first so the config isn't read there).\n if (IS_REACT_NATIVE || !idTaggingEnabled()) return rendered;\n // Single host element (e.g. `<T><td>…</td></T>`) → annotate it directly, no\n // wrapper. Valid wherever the element itself is valid — including inside\n // <tr>/<select>/<ul> — and avoids the span entirely.\n if (isValidElement(rendered) && typeof rendered.type === 'string') {\n return cloneElement(rendered as ReactElement<Record<string, unknown>>, {\n 'data-_gt-hash': hash,\n });\n }\n // Output that renders no DOM stays no-DOM: an empty <span data-_gt-hash> would\n // change :empty/child structure and inject an (invalid, under restricted\n // parents) span even for an empty branch.\n if (rendersNothing(rendered)) return rendered;\n // No element to carry the attribute (bare text / fragment / component root) →\n // wrap in a layout-neutral span. This is the only case that injects one.\n return createElement(\n 'span',\n { 'data-_gt-hash': hash, style: TAG_STYLE },\n rendered\n );\n}\n\n// Shared rendering logic. The child renderers are injected so the RSC code path\n// never statically imports the hook-based variable components, and so the\n// pipeline can build them once and share them. This module must stay free of\n// hook/context imports so it can be reached from the components-rsc entrypoint.\n\ntype RenderPreparedTParams = {\n taggedSourceChildren: TaggedChildren;\n targetJsxChildren: JsxChildren | null | undefined;\n locale: string;\n defaultLocale: string;\n enableI18n: boolean;\n shouldTranslate: boolean;\n // The translation hash for this <T> (see resolveTagHash) — the same key the\n // published-translation cache/CDN is keyed by. Set only when id-tagging is\n // enabled; when undefined the output is rendered untouched. Presence of `hash`\n // is the single signal to tag (there is no separate boolean).\n hash?: string;\n};\n\nfunction createRenderPreparedT({\n renderDefaultChildren,\n renderTranslatedChildren,\n}: {\n renderDefaultChildren: (args: RenderDefaultChildrenArgs) => ReactNode;\n renderTranslatedChildren: (args: RenderTranslatedChildrenArgs) => ReactNode;\n}): (args: RenderPreparedTParams) => ReactNode {\n function renderPreparedT({\n taggedSourceChildren,\n targetJsxChildren,\n locale,\n defaultLocale,\n enableI18n,\n shouldTranslate,\n hash,\n }: RenderPreparedTParams): ReactNode {\n const rendered =\n !shouldTranslate || targetJsxChildren == null\n ? renderSource({\n taggedSourceChildren,\n defaultLocale,\n enableI18n,\n })\n : renderTarget({\n taggedSourceChildren,\n targetJsxChildren,\n locales: [locale, defaultLocale],\n enableI18n,\n });\n\n // Opt-in id-tagging is entirely handled by applyIdTag; `hash` presence is the\n // enable signal (produced by resolveTagHash only when tagging is on).\n return hash ? applyIdTag(rendered, hash) : rendered;\n }\n\n function renderSource({\n taggedSourceChildren,\n defaultLocale,\n enableI18n,\n }: {\n taggedSourceChildren: TaggedChildren;\n defaultLocale: string;\n enableI18n: boolean;\n }): ReactNode {\n return renderDefaultChildren({\n children: taggedSourceChildren,\n defaultLocale,\n enableI18n,\n });\n }\n\n function renderTarget({\n taggedSourceChildren,\n targetJsxChildren,\n locales,\n enableI18n,\n }: {\n taggedSourceChildren: TaggedChildren;\n targetJsxChildren: JsxChildren;\n locales: string[];\n enableI18n: boolean;\n }): ReactNode {\n return renderTranslatedChildren({\n source: taggedSourceChildren,\n // The shared persisted wire also admits empty-rendering boolean/null\n // values. The outer null check and existing renderer fallback own those\n // cases; this narrower internal renderer type describes its recursive\n // element/string grammar without changing React runtime behavior.\n target: targetJsxChildren as RenderTranslatedChildrenArgs['target'],\n locales,\n enableI18n,\n });\n }\n\n return renderPreparedT;\n}\n\nexport { createRenderPreparedT };\nexport type { RenderPreparedTParams };\n"],"mappings":"+JA2BA,MAAM,EAAY,CAAE,QAAS,WAAY,CAInC,EACH,WAAoD,WAAW,UAChE,cASF,SAAS,EAAe,EAA0B,CAChD,GAAI,GAAQ,MAAQ,OAAO,GAAS,WAAa,IAAS,GAAI,MAAO,GACrE,GAAI,MAAM,QAAQ,EAAK,CAAE,MAAO,CAAC,EAAK,KAAM,GAAM,CAAC,EAAe,EAAE,CAAC,CACrE,GAAI,EAAe,EAAK,EAAI,EAAK,OAAS,EAAU,CAClD,IAAM,EAAY,EAAK,MAAmC,SAC1D,OAAO,GAAY,MAAQ,EAAe,EAAS,CAErD,MAAO,GAOT,SAAS,EAAW,EAAqB,EAAyB,CAmBhE,OAfI,GAAmB,CAAC,GAAkB,CAAS,EAI/C,EAAe,EAAS,EAAI,OAAO,EAAS,MAAS,SAChD,EAAa,EAAmD,CACrE,gBAAiB,EAClB,CAAC,CAKA,EAAe,EAAS,CAAS,EAG9B,EACL,OACA,CAAE,gBAAiB,EAAM,MAAO,EAAW,CAC3C,EACD,CAsBH,SAAS,EAAsB,CAC7B,wBACA,4BAI6C,CAC7C,SAAS,EAAgB,CACvB,uBACA,oBACA,SACA,gBACA,aACA,kBACA,QACmC,CACnC,IAAM,EACJ,CAAC,GAAmB,GAAqB,KACrC,EAAa,CACX,uBACA,gBACA,aACD,CAAC,CACF,EAAa,CACX,uBACA,oBACA,QAAS,CAAC,EAAQ,EAAc,CAChC,aACD,CAAC,CAIR,OAAO,EAAO,EAAW,EAAU,EAAK,CAAG,EAG7C,SAAS,EAAa,CACpB,uBACA,gBACA,cAKY,CACZ,OAAO,EAAsB,CAC3B,SAAU,EACV,gBACA,aACD,CAAC,CAGJ,SAAS,EAAa,CACpB,uBACA,oBACA,UACA,cAMY,CACZ,OAAO,EAAyB,CAC9B,OAAQ,EAKR,OAAQ,EACR,UACA,aACD,CAAC,CAGJ,OAAO"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@generaltranslation/react-core",
3
- "version": "11.1.12",
3
+ "version": "11.1.14",
4
4
  "description": "A pure React library for internationalization",
5
5
  "files": [
6
6
  "dist",
@@ -11,9 +11,9 @@
11
11
  "react": ">=18.0.0"
12
12
  },
13
13
  "dependencies": {
14
- "@generaltranslation/format": "0.1.7",
15
- "generaltranslation": "9.1.6",
16
- "gt-i18n": "1.0.16"
14
+ "@generaltranslation/format": "0.1.8",
15
+ "generaltranslation": "9.1.7",
16
+ "gt-i18n": "1.0.17"
17
17
  },
18
18
  "repository": {
19
19
  "type": "git",
@@ -1,2 +0,0 @@
1
- exports.defaultEnableI18nCookieName=`generaltranslation.enable-i18n`,exports.defaultLocaleCookieName=`generaltranslation.locale`,exports.defaultRegionCookieName=`generaltranslation.region`,exports.defaultResetLocaleCookieName=`generaltranslation.locale-reset`;
2
- //# sourceMappingURL=cookieNames.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cookieNames.cjs","names":[],"sources":["../../src/setup/cookieNames.ts"],"sourcesContent":["// Dependency-free module: these constants are imported by size-constrained\n// consumers (e.g. gt-next's edge middleware), which must not pull in the\n// ReactI18nConfig class or its gt-i18n imports.\n\n/**\n * Cookie name for tracking the user's selected locale.\n */\nexport const defaultLocaleCookieName = 'generaltranslation.locale';\n\n/**\n * Cookie name for tracking the user's selected region.\n */\nexport const defaultRegionCookieName = 'generaltranslation.region';\n\n/**\n * Cookie name for persisting the enableI18n feature flag.\n */\nexport const defaultEnableI18nCookieName = 'generaltranslation.enable-i18n';\n\n/**\n * Cookie name for tracking the locale reset.\n */\nexport const defaultResetLocaleCookieName = 'generaltranslation.locale-reset';\n"],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"cookieNames.d.ts","names":[],"sources":["../../src/setup/cookieNames.ts"],"mappings":";;AAOA;;cAAa,uBAAA;;;AAKb;cAAa,uBAAA;;;;cAKA,2BAAA;;;;cAKA,4BAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"cookieNames.mjs","names":[],"sources":["../../src/setup/cookieNames.ts"],"sourcesContent":["// Dependency-free module: these constants are imported by size-constrained\n// consumers (e.g. gt-next's edge middleware), which must not pull in the\n// ReactI18nConfig class or its gt-i18n imports.\n\n/**\n * Cookie name for tracking the user's selected locale.\n */\nexport const defaultLocaleCookieName = 'generaltranslation.locale';\n\n/**\n * Cookie name for tracking the user's selected region.\n */\nexport const defaultRegionCookieName = 'generaltranslation.region';\n\n/**\n * Cookie name for persisting the enableI18n feature flag.\n */\nexport const defaultEnableI18nCookieName = 'generaltranslation.enable-i18n';\n\n/**\n * Cookie name for tracking the locale reset.\n */\nexport const defaultResetLocaleCookieName = 'generaltranslation.locale-reset';\n"],"mappings":"AAOA,MAAa,EAA0B,4BAK1B,EAA0B,4BAK1B,EAA8B,iCAK9B,EAA+B"}