@generaltranslation/react-core 11.0.0-odysseus.11 → 11.0.0-odysseus.13
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 +14 -0
- package/dist/hooks/external-store/useSubscribeToTrackedLookups.cjs +2 -0
- package/dist/hooks/external-store/useSubscribeToTrackedLookups.cjs.map +1 -0
- package/dist/hooks/external-store/useSubscribeToTrackedLookups.mjs +2 -0
- package/dist/hooks/external-store/useSubscribeToTrackedLookups.mjs.map +1 -0
- package/dist/hooks/external-store/useTrackedDictionaryObjResolver.cjs +1 -1
- package/dist/hooks/external-store/useTrackedDictionaryObjResolver.cjs.map +1 -1
- package/dist/hooks/external-store/useTrackedDictionaryObjResolver.mjs +1 -1
- package/dist/hooks/external-store/useTrackedDictionaryObjResolver.mjs.map +1 -1
- package/dist/hooks/external-store/useTrackedDictionaryResolver.cjs +1 -1
- package/dist/hooks/external-store/useTrackedDictionaryResolver.cjs.map +1 -1
- package/dist/hooks/external-store/useTrackedDictionaryResolver.mjs +1 -1
- package/dist/hooks/external-store/useTrackedDictionaryResolver.mjs.map +1 -1
- package/dist/hooks/external-store/useTrackedTranslationResolver.cjs +1 -1
- package/dist/hooks/external-store/useTrackedTranslationResolver.cjs.map +1 -1
- package/dist/hooks/external-store/useTrackedTranslationResolver.d.ts.map +1 -1
- package/dist/hooks/external-store/useTrackedTranslationResolver.mjs +1 -1
- package/dist/hooks/external-store/useTrackedTranslationResolver.mjs.map +1 -1
- package/dist/i18n-store/I18nStore.cjs.map +1 -1
- package/dist/i18n-store/I18nStore.d.ts.map +1 -1
- package/dist/i18n-store/I18nStore.mjs.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @generaltranslation/react-core
|
|
2
2
|
|
|
3
|
+
## 11.0.0-odysseus.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [a2b9677]
|
|
8
|
+
- Updated dependencies [41371e0]
|
|
9
|
+
- gt-i18n@1.0.0-odysseus.6
|
|
10
|
+
|
|
11
|
+
## 11.0.0-odysseus.12
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 7be23bc: Share tracked lookup subscription handling across resolver hooks.
|
|
16
|
+
|
|
3
17
|
## 11.0.0-odysseus.11
|
|
4
18
|
|
|
5
19
|
## 11.0.0-odysseus.10
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.cjs`);let e=require(`react`);function t(t,n,r){let i=(0,e.useRef)(0),a=(0,e.useCallback)(e=>n(n=>{t.current.has(r(n))&&(i.current++,e())}),[n,r,t]),o=(0,e.useCallback)(()=>i.current,[]);(0,e.useSyncExternalStore)(a,o,o)}exports.useSubscribeToTrackedLookups=t;
|
|
2
|
+
//# sourceMappingURL=useSubscribeToTrackedLookups.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSubscribeToTrackedLookups.cjs","names":[],"sources":["../../../src/hooks/external-store/useSubscribeToTrackedLookups.ts"],"sourcesContent":["import {\n type RefObject,\n useCallback,\n useRef,\n useSyncExternalStore,\n} from 'react';\nimport type { StoreListener, Unsubscribe } from '../../i18n-store/storeTypes';\n\n/**\n * Subscribe to store events, but only trigger re-renders when the event's\n * lookup is in the tracked keys set. Shared by the tracked translation and\n * dictionary resolvers, which differ only in the store subscribe method and the\n * listener-key function.\n *\n * Remember that we can make no assumptions about when the tracked set gets\n * updated. This is technically not pure, but it is an acceptable trade since it\n * only drives dev translation hot reload.\n */\nexport function useSubscribeToTrackedLookups<L>(\n trackedKeysRef: RefObject<Set<string> | null>,\n subscribeToEvents: (onEvent: (lookup: L) => void) => Unsubscribe,\n getListenerKey: (lookup: L) => string\n) {\n // invalidation counter for triggering updates\n const versionRef = useRef(0);\n const subscribe = useCallback(\n (listener: StoreListener) =>\n subscribeToEvents((lookup) => {\n if (!trackedKeysRef.current!.has(getListenerKey(lookup))) return;\n versionRef.current++;\n listener();\n }),\n [subscribeToEvents, getListenerKey, trackedKeysRef]\n );\n const getSnapshot = useCallback(() => versionRef.current, []);\n\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n"],"mappings":"uEAkBA,SAAgB,EACd,EACA,EACA,EACA,CAEA,IAAM,GAAA,EAAA,EAAA,QAAoB,EAAE,CACtB,GAAA,EAAA,EAAA,aACH,GACC,EAAmB,GAAW,CACvB,EAAe,QAAS,IAAI,EAAe,EAAO,CAAC,GACxD,EAAW,UACX,GAAU,GACV,CACJ,CAAC,EAAmB,EAAgB,EAAe,CACpD,CACK,GAAA,EAAA,EAAA,iBAAgC,EAAW,QAAS,EAAE,CAAC,EAE7D,EAAA,EAAA,sBAAqB,EAAW,EAAa,EAAY"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{useCallback as e,useRef as t,useSyncExternalStore as n}from"react";function r(r,i,a){let o=t(0),s=e(e=>i(t=>{r.current.has(a(t))&&(o.current++,e())}),[i,a,r]),c=e(()=>o.current,[]);n(s,c,c)}export{r as useSubscribeToTrackedLookups};
|
|
2
|
+
//# sourceMappingURL=useSubscribeToTrackedLookups.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSubscribeToTrackedLookups.mjs","names":[],"sources":["../../../src/hooks/external-store/useSubscribeToTrackedLookups.ts"],"sourcesContent":["import {\n type RefObject,\n useCallback,\n useRef,\n useSyncExternalStore,\n} from 'react';\nimport type { StoreListener, Unsubscribe } from '../../i18n-store/storeTypes';\n\n/**\n * Subscribe to store events, but only trigger re-renders when the event's\n * lookup is in the tracked keys set. Shared by the tracked translation and\n * dictionary resolvers, which differ only in the store subscribe method and the\n * listener-key function.\n *\n * Remember that we can make no assumptions about when the tracked set gets\n * updated. This is technically not pure, but it is an acceptable trade since it\n * only drives dev translation hot reload.\n */\nexport function useSubscribeToTrackedLookups<L>(\n trackedKeysRef: RefObject<Set<string> | null>,\n subscribeToEvents: (onEvent: (lookup: L) => void) => Unsubscribe,\n getListenerKey: (lookup: L) => string\n) {\n // invalidation counter for triggering updates\n const versionRef = useRef(0);\n const subscribe = useCallback(\n (listener: StoreListener) =>\n subscribeToEvents((lookup) => {\n if (!trackedKeysRef.current!.has(getListenerKey(lookup))) return;\n versionRef.current++;\n listener();\n }),\n [subscribeToEvents, getListenerKey, trackedKeysRef]\n );\n const getSnapshot = useCallback(() => versionRef.current, []);\n\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n}\n"],"mappings":"0EAkBA,SAAgB,EACd,EACA,EACA,EACA,CAEA,IAAM,EAAa,EAAO,EAAE,CACtB,EAAY,EACf,GACC,EAAmB,GAAW,CACvB,EAAe,QAAS,IAAI,EAAe,EAAO,CAAC,GACxD,EAAW,UACX,GAAU,GACV,CACJ,CAAC,EAAmB,EAAgB,EAAe,CACpD,CACK,EAAc,MAAkB,EAAW,QAAS,EAAE,CAAC,CAE7D,EAAqB,EAAW,EAAa,EAAY"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../i18n-store/useI18nStore.cjs`),t=require(`../utils/missing-translation.cjs`);let
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../i18n-store/useI18nStore.cjs`),t=require(`../utils/missing-translation.cjs`),n=require(`./useSubscribeToTrackedLookups.cjs`);let r=require(`react`),i=require(`gt-i18n/internal`);function a(){let a=e.useDictionariesSnapshot(),o=e.useI18nStore(),s=(0,i.getI18nConfig)().isDevHotReloadEnabled(),c=t.useHandleMissingDictionaryObject(),l=(0,r.useRef)(null);return l.current??=new Set,n.useSubscribeToTrackedLookups(l,o.subscribeToDictionaryObjectEvents,i.getDictionaryListenerKey),(0,r.useCallback)(e=>{let t=(0,i.getDictionaryListenerKey)(e);s&&l.current.add(t);let n=o.getDictionaryObjectSnapshot(e,a);return n==null&&s&&c(e),n},[o,a,s,c])}exports.useTrackedDictionaryObjResolver=a;
|
|
2
2
|
//# sourceMappingURL=useTrackedDictionaryObjResolver.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTrackedDictionaryObjResolver.cjs","names":["useDictionariesSnapshot","useI18nStore","useHandleMissingDictionaryObject"],"sources":["../../../src/hooks/external-store/useTrackedDictionaryObjResolver.ts"],"sourcesContent":["import { getDictionaryListenerKey, getI18nConfig } from 'gt-i18n/internal';\nimport type {\n DictionaryLookup,\n DictionaryObjectSnapshot,\n
|
|
1
|
+
{"version":3,"file":"useTrackedDictionaryObjResolver.cjs","names":["useDictionariesSnapshot","useI18nStore","useHandleMissingDictionaryObject","getDictionaryListenerKey"],"sources":["../../../src/hooks/external-store/useTrackedDictionaryObjResolver.ts"],"sourcesContent":["import { getDictionaryListenerKey, getI18nConfig } from 'gt-i18n/internal';\nimport type {\n DictionaryLookup,\n DictionaryObjectSnapshot,\n} from '../../i18n-store/storeTypes';\nimport {\n useDictionariesSnapshot,\n useI18nStore,\n} from '../../i18n-store/useI18nStore';\nimport { useCallback, useRef } from 'react';\nimport { useHandleMissingDictionaryObject } from '../utils/missing-translation';\nimport { useSubscribeToTrackedLookups } from './useSubscribeToTrackedLookups';\n\nexport type TrackedDictionaryObjResolver = (\n lookup: DictionaryLookup\n) => DictionaryObjectSnapshot;\n\n// TODO: rename to useTrackedDictionaryObjectResolver\nexport function useTrackedDictionaryObjResolver(): TrackedDictionaryObjResolver {\n const dictionariesSnapshot = useDictionariesSnapshot();\n const i18nStore = useI18nStore();\n const devHotReloadEnabled = getI18nConfig().isDevHotReloadEnabled();\n const onMissingDictionaryObj = useHandleMissingDictionaryObject();\n\n const trackedKeysRef = useRef<Set<string> | null>(null);\n if (trackedKeysRef.current == null) {\n trackedKeysRef.current = new Set();\n }\n\n // subscribe to dictionary object updates\n useSubscribeToTrackedLookups(\n trackedKeysRef,\n i18nStore.subscribeToDictionaryObjectEvents,\n getDictionaryListenerKey\n );\n\n // Resolution callback\n return useCallback(\n (lookup: DictionaryLookup) => {\n // Track the lookup for dev hot reload\n const lookupKey = getDictionaryListenerKey(lookup);\n if (devHotReloadEnabled) {\n trackedKeysRef.current!.add(lookupKey);\n }\n\n // Resolve the dictionary entry from the store\n const dictionaryObject = i18nStore.getDictionaryObjectSnapshot(\n lookup,\n dictionariesSnapshot\n );\n\n // Hot reload\n if (dictionaryObject == null && devHotReloadEnabled) {\n onMissingDictionaryObj(lookup);\n }\n\n return dictionaryObject;\n },\n [\n i18nStore,\n dictionariesSnapshot,\n devHotReloadEnabled,\n onMissingDictionaryObj,\n ]\n );\n}\n"],"mappings":"wPAkBA,SAAgB,GAAgE,CAC9E,IAAM,EAAuBA,EAAAA,yBAAyB,CAChD,EAAYC,EAAAA,cAAc,CAC1B,GAAA,EAAA,EAAA,gBAAqC,CAAC,uBAAuB,CAC7D,EAAyBC,EAAAA,kCAAkC,CAE3D,GAAA,EAAA,EAAA,QAA4C,KAAK,CAavD,MAZA,CACE,EAAe,UAAU,IAAI,IAI/B,EAAA,6BACE,EACA,EAAU,kCACVC,EAAAA,yBACD,EAGD,EAAA,EAAA,aACG,GAA6B,CAE5B,IAAM,GAAA,EAAA,EAAA,0BAAqC,EAAO,CAC9C,GACF,EAAe,QAAS,IAAI,EAAU,CAIxC,IAAM,EAAmB,EAAU,4BACjC,EACA,EACD,CAOD,OAJI,GAAoB,MAAQ,GAC9B,EAAuB,EAAO,CAGzB,GAET,CACE,EACA,EACA,EACA,EACD,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useDictionariesSnapshot as e,useI18nStore as t}from"../../i18n-store/useI18nStore.mjs";import{useHandleMissingDictionaryObject as n}from"../utils/missing-translation.mjs";import{
|
|
1
|
+
import{useDictionariesSnapshot as e,useI18nStore as t}from"../../i18n-store/useI18nStore.mjs";import{useHandleMissingDictionaryObject as n}from"../utils/missing-translation.mjs";import{useSubscribeToTrackedLookups as r}from"./useSubscribeToTrackedLookups.mjs";import{useCallback as i,useRef as a}from"react";import{getDictionaryListenerKey as o,getI18nConfig as s}from"gt-i18n/internal";function c(){let c=e(),l=t(),u=s().isDevHotReloadEnabled(),d=n(),f=a(null);return f.current??=new Set,r(f,l.subscribeToDictionaryObjectEvents,o),i(e=>{let t=o(e);u&&f.current.add(t);let n=l.getDictionaryObjectSnapshot(e,c);return n==null&&u&&d(e),n},[l,c,u,d])}export{c as useTrackedDictionaryObjResolver};
|
|
2
2
|
//# sourceMappingURL=useTrackedDictionaryObjResolver.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTrackedDictionaryObjResolver.mjs","names":[],"sources":["../../../src/hooks/external-store/useTrackedDictionaryObjResolver.ts"],"sourcesContent":["import { getDictionaryListenerKey, getI18nConfig } from 'gt-i18n/internal';\nimport type {\n DictionaryLookup,\n DictionaryObjectSnapshot,\n
|
|
1
|
+
{"version":3,"file":"useTrackedDictionaryObjResolver.mjs","names":[],"sources":["../../../src/hooks/external-store/useTrackedDictionaryObjResolver.ts"],"sourcesContent":["import { getDictionaryListenerKey, getI18nConfig } from 'gt-i18n/internal';\nimport type {\n DictionaryLookup,\n DictionaryObjectSnapshot,\n} from '../../i18n-store/storeTypes';\nimport {\n useDictionariesSnapshot,\n useI18nStore,\n} from '../../i18n-store/useI18nStore';\nimport { useCallback, useRef } from 'react';\nimport { useHandleMissingDictionaryObject } from '../utils/missing-translation';\nimport { useSubscribeToTrackedLookups } from './useSubscribeToTrackedLookups';\n\nexport type TrackedDictionaryObjResolver = (\n lookup: DictionaryLookup\n) => DictionaryObjectSnapshot;\n\n// TODO: rename to useTrackedDictionaryObjectResolver\nexport function useTrackedDictionaryObjResolver(): TrackedDictionaryObjResolver {\n const dictionariesSnapshot = useDictionariesSnapshot();\n const i18nStore = useI18nStore();\n const devHotReloadEnabled = getI18nConfig().isDevHotReloadEnabled();\n const onMissingDictionaryObj = useHandleMissingDictionaryObject();\n\n const trackedKeysRef = useRef<Set<string> | null>(null);\n if (trackedKeysRef.current == null) {\n trackedKeysRef.current = new Set();\n }\n\n // subscribe to dictionary object updates\n useSubscribeToTrackedLookups(\n trackedKeysRef,\n i18nStore.subscribeToDictionaryObjectEvents,\n getDictionaryListenerKey\n );\n\n // Resolution callback\n return useCallback(\n (lookup: DictionaryLookup) => {\n // Track the lookup for dev hot reload\n const lookupKey = getDictionaryListenerKey(lookup);\n if (devHotReloadEnabled) {\n trackedKeysRef.current!.add(lookupKey);\n }\n\n // Resolve the dictionary entry from the store\n const dictionaryObject = i18nStore.getDictionaryObjectSnapshot(\n lookup,\n dictionariesSnapshot\n );\n\n // Hot reload\n if (dictionaryObject == null && devHotReloadEnabled) {\n onMissingDictionaryObj(lookup);\n }\n\n return dictionaryObject;\n },\n [\n i18nStore,\n dictionariesSnapshot,\n devHotReloadEnabled,\n onMissingDictionaryObj,\n ]\n );\n}\n"],"mappings":"mYAkBA,SAAgB,GAAgE,CAC9E,IAAM,EAAuB,GAAyB,CAChD,EAAY,GAAc,CAC1B,EAAsB,GAAe,CAAC,uBAAuB,CAC7D,EAAyB,GAAkC,CAE3D,EAAiB,EAA2B,KAAK,CAavD,MAZA,CACE,EAAe,UAAU,IAAI,IAI/B,EACE,EACA,EAAU,kCACV,EACD,CAGM,EACJ,GAA6B,CAE5B,IAAM,EAAY,EAAyB,EAAO,CAC9C,GACF,EAAe,QAAS,IAAI,EAAU,CAIxC,IAAM,EAAmB,EAAU,4BACjC,EACA,EACD,CAOD,OAJI,GAAoB,MAAQ,GAC9B,EAAuB,EAAO,CAGzB,GAET,CACE,EACA,EACA,EACA,EACD,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../i18n-store/useI18nStore.cjs`),t=require(`../utils/missing-translation.cjs`);let
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../i18n-store/useI18nStore.cjs`),t=require(`../utils/missing-translation.cjs`),n=require(`./useSubscribeToTrackedLookups.cjs`);let r=require(`react`),i=require(`gt-i18n/internal`);function a(){let a=e.useDictionariesSnapshot(),o=e.useI18nStore(),s=(0,i.getI18nConfig)().isDevHotReloadEnabled(),c=t.useHandleMissingDictionaryEntry(),l=(0,r.useRef)(null);return l.current??=new Set,n.useSubscribeToTrackedLookups(l,o.subscribeToDictionaryEntryEvents,i.getDictionaryListenerKey),(0,r.useCallback)(e=>{let t=(0,i.getDictionaryListenerKey)(e);s&&l.current.add(t);let n=o.getDictionaryEntrySnapshot(e,a);return n==null&&s&&c(e),n},[o,a,s,c])}exports.useTrackedDictionaryResolver=a;
|
|
2
2
|
//# sourceMappingURL=useTrackedDictionaryResolver.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTrackedDictionaryResolver.cjs","names":["useDictionariesSnapshot","useI18nStore","useHandleMissingDictionaryEntry"],"sources":["../../../src/hooks/external-store/useTrackedDictionaryResolver.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport {\n useDictionariesSnapshot,\n useI18nStore,\n} from '../../i18n-store/useI18nStore';\nimport type {\n DictionaryEntrySnapshot,\n DictionaryLookup,\n
|
|
1
|
+
{"version":3,"file":"useTrackedDictionaryResolver.cjs","names":["useDictionariesSnapshot","useI18nStore","useHandleMissingDictionaryEntry","getDictionaryListenerKey"],"sources":["../../../src/hooks/external-store/useTrackedDictionaryResolver.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport {\n useDictionariesSnapshot,\n useI18nStore,\n} from '../../i18n-store/useI18nStore';\nimport type {\n DictionaryEntrySnapshot,\n DictionaryLookup,\n} from '../../i18n-store/storeTypes';\nimport { getDictionaryListenerKey, getI18nConfig } from 'gt-i18n/internal';\nimport { useHandleMissingDictionaryEntry } from '../utils/missing-translation';\nimport { useSubscribeToTrackedLookups } from './useSubscribeToTrackedLookups';\n\nexport type TrackedDictionaryEntryResolver = (\n lookup: DictionaryLookup\n) => DictionaryEntrySnapshot;\n\n// TODO: rename to useTrackedDictionaryEntryResolver\nexport function useTrackedDictionaryResolver(): TrackedDictionaryEntryResolver {\n const dictionariesSnapshot = useDictionariesSnapshot();\n const i18nStore = useI18nStore();\n const devHotReloadEnabled = getI18nConfig().isDevHotReloadEnabled();\n const onMissingDictionaryEntry = useHandleMissingDictionaryEntry();\n\n const trackedKeysRef = useRef<Set<string> | null>(null);\n if (trackedKeysRef.current == null) {\n trackedKeysRef.current = new Set();\n }\n\n // subscribe to dictionary entry updates\n useSubscribeToTrackedLookups(\n trackedKeysRef,\n i18nStore.subscribeToDictionaryEntryEvents,\n getDictionaryListenerKey\n );\n\n // Resolution callback\n return useCallback(\n (lookup: DictionaryLookup) => {\n // Track the lookup for dev hot reload\n const lookupKey = getDictionaryListenerKey(lookup);\n if (devHotReloadEnabled) {\n trackedKeysRef.current!.add(lookupKey);\n }\n\n // Resolve the dictionary entry from the store\n const dictionaryEntry = i18nStore.getDictionaryEntrySnapshot(\n lookup,\n dictionariesSnapshot\n );\n\n // Hot reload\n if (dictionaryEntry == null && devHotReloadEnabled) {\n onMissingDictionaryEntry(lookup);\n }\n\n return dictionaryEntry;\n },\n [\n i18nStore,\n dictionariesSnapshot,\n devHotReloadEnabled,\n onMissingDictionaryEntry,\n ]\n );\n}\n"],"mappings":"wPAkBA,SAAgB,GAA+D,CAC7E,IAAM,EAAuBA,EAAAA,yBAAyB,CAChD,EAAYC,EAAAA,cAAc,CAC1B,GAAA,EAAA,EAAA,gBAAqC,CAAC,uBAAuB,CAC7D,EAA2BC,EAAAA,iCAAiC,CAE5D,GAAA,EAAA,EAAA,QAA4C,KAAK,CAavD,MAZA,CACE,EAAe,UAAU,IAAI,IAI/B,EAAA,6BACE,EACA,EAAU,iCACVC,EAAAA,yBACD,EAGD,EAAA,EAAA,aACG,GAA6B,CAE5B,IAAM,GAAA,EAAA,EAAA,0BAAqC,EAAO,CAC9C,GACF,EAAe,QAAS,IAAI,EAAU,CAIxC,IAAM,EAAkB,EAAU,2BAChC,EACA,EACD,CAOD,OAJI,GAAmB,MAAQ,GAC7B,EAAyB,EAAO,CAG3B,GAET,CACE,EACA,EACA,EACA,EACD,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useDictionariesSnapshot as e,useI18nStore as t}from"../../i18n-store/useI18nStore.mjs";import{useHandleMissingDictionaryEntry as n}from"../utils/missing-translation.mjs";import{
|
|
1
|
+
import{useDictionariesSnapshot as e,useI18nStore as t}from"../../i18n-store/useI18nStore.mjs";import{useHandleMissingDictionaryEntry as n}from"../utils/missing-translation.mjs";import{useSubscribeToTrackedLookups as r}from"./useSubscribeToTrackedLookups.mjs";import{useCallback as i,useRef as a}from"react";import{getDictionaryListenerKey as o,getI18nConfig as s}from"gt-i18n/internal";function c(){let c=e(),l=t(),u=s().isDevHotReloadEnabled(),d=n(),f=a(null);return f.current??=new Set,r(f,l.subscribeToDictionaryEntryEvents,o),i(e=>{let t=o(e);u&&f.current.add(t);let n=l.getDictionaryEntrySnapshot(e,c);return n==null&&u&&d(e),n},[l,c,u,d])}export{c as useTrackedDictionaryResolver};
|
|
2
2
|
//# sourceMappingURL=useTrackedDictionaryResolver.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTrackedDictionaryResolver.mjs","names":[],"sources":["../../../src/hooks/external-store/useTrackedDictionaryResolver.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport {\n useDictionariesSnapshot,\n useI18nStore,\n} from '../../i18n-store/useI18nStore';\nimport type {\n DictionaryEntrySnapshot,\n DictionaryLookup,\n
|
|
1
|
+
{"version":3,"file":"useTrackedDictionaryResolver.mjs","names":[],"sources":["../../../src/hooks/external-store/useTrackedDictionaryResolver.ts"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport {\n useDictionariesSnapshot,\n useI18nStore,\n} from '../../i18n-store/useI18nStore';\nimport type {\n DictionaryEntrySnapshot,\n DictionaryLookup,\n} from '../../i18n-store/storeTypes';\nimport { getDictionaryListenerKey, getI18nConfig } from 'gt-i18n/internal';\nimport { useHandleMissingDictionaryEntry } from '../utils/missing-translation';\nimport { useSubscribeToTrackedLookups } from './useSubscribeToTrackedLookups';\n\nexport type TrackedDictionaryEntryResolver = (\n lookup: DictionaryLookup\n) => DictionaryEntrySnapshot;\n\n// TODO: rename to useTrackedDictionaryEntryResolver\nexport function useTrackedDictionaryResolver(): TrackedDictionaryEntryResolver {\n const dictionariesSnapshot = useDictionariesSnapshot();\n const i18nStore = useI18nStore();\n const devHotReloadEnabled = getI18nConfig().isDevHotReloadEnabled();\n const onMissingDictionaryEntry = useHandleMissingDictionaryEntry();\n\n const trackedKeysRef = useRef<Set<string> | null>(null);\n if (trackedKeysRef.current == null) {\n trackedKeysRef.current = new Set();\n }\n\n // subscribe to dictionary entry updates\n useSubscribeToTrackedLookups(\n trackedKeysRef,\n i18nStore.subscribeToDictionaryEntryEvents,\n getDictionaryListenerKey\n );\n\n // Resolution callback\n return useCallback(\n (lookup: DictionaryLookup) => {\n // Track the lookup for dev hot reload\n const lookupKey = getDictionaryListenerKey(lookup);\n if (devHotReloadEnabled) {\n trackedKeysRef.current!.add(lookupKey);\n }\n\n // Resolve the dictionary entry from the store\n const dictionaryEntry = i18nStore.getDictionaryEntrySnapshot(\n lookup,\n dictionariesSnapshot\n );\n\n // Hot reload\n if (dictionaryEntry == null && devHotReloadEnabled) {\n onMissingDictionaryEntry(lookup);\n }\n\n return dictionaryEntry;\n },\n [\n i18nStore,\n dictionariesSnapshot,\n devHotReloadEnabled,\n onMissingDictionaryEntry,\n ]\n );\n}\n"],"mappings":"kYAkBA,SAAgB,GAA+D,CAC7E,IAAM,EAAuB,GAAyB,CAChD,EAAY,GAAc,CAC1B,EAAsB,GAAe,CAAC,uBAAuB,CAC7D,EAA2B,GAAiC,CAE5D,EAAiB,EAA2B,KAAK,CAavD,MAZA,CACE,EAAe,UAAU,IAAI,IAI/B,EACE,EACA,EAAU,iCACV,EACD,CAGM,EACJ,GAA6B,CAE5B,IAAM,EAAY,EAAyB,EAAO,CAC9C,GACF,EAAe,QAAS,IAAI,EAAU,CAIxC,IAAM,EAAkB,EAAU,2BAChC,EACA,EACD,CAOD,OAJI,GAAmB,MAAQ,GAC7B,EAAyB,EAAO,CAG3B,GAET,CACE,EACA,EACA,EACA,EACD,CACF"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../condition-store.cjs`),t=require(`../utils.cjs`),n=require(`../../i18n-store/useI18nStore.cjs`),r=require(`../utils/missing-translation.cjs`);let
|
|
1
|
+
require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../condition-store.cjs`),t=require(`../utils.cjs`),n=require(`../../i18n-store/useI18nStore.cjs`),r=require(`../utils/missing-translation.cjs`),i=require(`./useSubscribeToTrackedLookups.cjs`);let a=require(`react`),o=require(`gt-i18n/internal`);function s(e=[]){let t=n.useTranslationsSnapshot(),s=n.useI18nStore(),l=(0,o.getI18nConfig)().isDevHotReloadEnabled(),u=r.useHandleMissingTranslation(),d=(0,a.useRef)(null);return d.current??=new Set,c(e,d),i.useSubscribeToTrackedLookups(d,s.subscribeToTranslationEvents,o.getTranslateListenerKey),(0,a.useCallback)(e=>{let n=(0,o.getTranslateListenerKey)(e);l&&d.current.add(n);let r=s.getTranslateSnapshot(e,t);return r==null&&l&&u(e),r},[s,t,u,l])}function c(r,i){let s=n.useI18nStore(),c=e.useLocale(),l=(0,o.getI18nConfig)().isDevHotReloadEnabled(),u=t.useShouldTranslate(),d=n.useTranslationsSnapshot(),f=(0,a.useMemo)(()=>r?.length>0&&u&&l,[r,u,l]),p=(0,a.useMemo)(()=>f?r.map(({message:e,...t})=>{let n=t.$locale??c,r={locale:n,message:e,options:(0,o.createLookupOptions)(n,t,`ICU`)};return[r,(0,o.getTranslateListenerKey)(r)]}):[],[c,f,r]);f&&p.forEach(([,e])=>{i.current.add(e)}),(0,a.useEffect)(()=>{f&&p.filter(([e])=>s.getTranslateSnapshot(e,d)==null).forEach(([e])=>s.translate(e))},[f,s,p,d])}exports.useTrackedTranslationResolver=s;
|
|
2
2
|
//# sourceMappingURL=useTrackedTranslationResolver.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTrackedTranslationResolver.cjs","names":["useTranslationsSnapshot","useI18nStore","useHandleMissingTranslation","useLocale","useShouldTranslate"],"sources":["../../../src/hooks/external-store/useTrackedTranslationResolver.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"useTrackedTranslationResolver.cjs","names":["useTranslationsSnapshot","useI18nStore","useHandleMissingTranslation","getTranslateListenerKey","useLocale","useShouldTranslate"],"sources":["../../../src/hooks/external-store/useTrackedTranslationResolver.ts"],"sourcesContent":["import { type RefObject, useCallback, useEffect, useMemo, useRef } from 'react';\nimport {\n createLookupOptions,\n getI18nConfig,\n getTranslateListenerKey,\n} from 'gt-i18n/internal';\nimport type { Translation } from 'gt-i18n/types';\nimport type {\n TranslateLookup,\n TranslateSnapshot,\n} from '../../i18n-store/storeTypes';\nimport type { TranslationMetadata } from 'gt-i18n/internal/types';\nimport type { StringFormat } from '@generaltranslation/format';\nimport { useLocale } from '../condition-store';\nimport { useShouldTranslate } from '../utils';\nimport {\n useI18nStore,\n useTranslationsSnapshot,\n} from '../../i18n-store/useI18nStore';\nimport { useHandleMissingTranslation } from '../utils/missing-translation';\nimport { useSubscribeToTrackedLookups } from './useSubscribeToTrackedLookups';\n\n/**\n * Returns the translation, but also triggers a translation if it is not found\n * when dev hot reload is enabled.\n */\nexport type TrackedTranslationResolver = <T extends Translation>(\n lookup: TranslateLookup<T>\n) => TranslateSnapshot<T>;\n\nexport type Message = TranslationMetadata & {\n message: string;\n};\n\n/**\n * NOTE:\n * gt() may be called during render, so tracking intentionally only mutates\n * hook-local refs. This widens the event filter used by our existing\n * useSyncExternalStore subscription, but does not update React state or mutate\n * the translation cache during render.\n *\n * A render that is later aborted may leave behind an extra tracked key. That is\n * acceptable for dev hot reload because the worst case is an unnecessary\n * invalidation for this hook instance, not incorrect rendered output.\n */\n\nexport function useTrackedTranslationResolver(\n messages: Message[] = []\n): TrackedTranslationResolver {\n const translationsSnapshot = useTranslationsSnapshot();\n const i18nStore = useI18nStore();\n const devHotReloadEnabled = getI18nConfig().isDevHotReloadEnabled();\n const onMissingTranslation = useHandleMissingTranslation();\n\n /**\n * Track lookups per hook instance without updating React state during render.\n */\n const trackedKeysRef = useRef<Set<string> | null>(null);\n if (trackedKeysRef.current == null) {\n trackedKeysRef.current = new Set();\n }\n\n // (optimization) Pre-subscribe to compiler-injected lookups\n usePreloadCompilerLookups(messages, trackedKeysRef);\n\n // (tx hot reload) Subscribe to translation updates\n useSubscribeToTrackedLookups(\n trackedKeysRef,\n i18nStore.subscribeToTranslationEvents,\n getTranslateListenerKey\n );\n\n /**\n * Remember that we can make no assumptions about when this cb gets invoked\n * - Resolves translation from lookup\n * - enqueues dev hot reload (if needed)\n */\n return useCallback(\n <T extends Translation>(\n lookup: TranslateLookup<T>\n ): TranslateSnapshot<T> => {\n // Track the lookup for dev hot reload\n const lookupKey = getTranslateListenerKey(lookup);\n if (devHotReloadEnabled) {\n trackedKeysRef.current!.add(lookupKey);\n }\n\n // Resolve the translation from the store\n const translation = i18nStore.getTranslateSnapshot(\n lookup,\n translationsSnapshot\n );\n\n // Trigger a hot reload if the translation is not found\n if (translation == null && devHotReloadEnabled) {\n onMissingTranslation(lookup);\n }\n return translation;\n },\n [i18nStore, translationsSnapshot, onMissingTranslation, devHotReloadEnabled]\n );\n}\n\n/**\n * Pre-subscribe to compiler-injected lookups\n * trigger translations for them\n *\n * This ref mutation is safe because this is translation hot reload only\n * and effects are deterministic\n */\nfunction usePreloadCompilerLookups(\n messages: Message[],\n trackedKeysRef: RefObject<Set<string> | null>\n) {\n const i18nStore = useI18nStore();\n const locale = useLocale();\n const devHotReloadEnabled = getI18nConfig().isDevHotReloadEnabled();\n const shouldTranslate = useShouldTranslate();\n const translationsSnapshot = useTranslationsSnapshot();\n const txHotReloadEnabled = useMemo(() => {\n return messages?.length > 0 && shouldTranslate && devHotReloadEnabled;\n }, [messages, shouldTranslate, devHotReloadEnabled]);\n\n // Precompute as much as we can\n const lookups: [TranslateLookup<string>, string][] = useMemo(() => {\n if (!txHotReloadEnabled) return [];\n return messages.map(({ message, ...options }) => {\n const targetLocale = options.$locale ?? locale;\n const lookupOptions = createLookupOptions<StringFormat>(\n targetLocale,\n options,\n 'ICU'\n );\n const lookup = {\n locale: targetLocale,\n message,\n options: lookupOptions,\n };\n return [lookup, getTranslateListenerKey(lookup)];\n });\n }, [locale, txHotReloadEnabled, messages]);\n\n // Pre-subscribe to the lookups\n if (txHotReloadEnabled) {\n lookups.forEach(([, lookupKey]) => {\n trackedKeysRef.current!.add(lookupKey);\n });\n }\n\n /**\n * Delegate non-pure operations to post commit\n *\n * (Optimization) Trigger a hot reload if the translation is not found\n * for compiler-injected lookups\n *\n * TODO: for use() + suspense strategy, use a Promise.all()\n * TODO: server side translation invocation\n */\n useEffect(() => {\n if (!txHotReloadEnabled) return;\n\n lookups\n .filter(\n ([lookup]) =>\n i18nStore.getTranslateSnapshot(lookup, translationsSnapshot) == null\n )\n .forEach(([lookup]) => i18nStore.translate(lookup));\n }, [txHotReloadEnabled, i18nStore, lookups, translationsSnapshot]);\n}\n"],"mappings":"sTA8CA,SAAgB,EACd,EAAsB,EAAE,CACI,CAC5B,IAAM,EAAuBA,EAAAA,yBAAyB,CAChD,EAAYC,EAAAA,cAAc,CAC1B,GAAA,EAAA,EAAA,gBAAqC,CAAC,uBAAuB,CAC7D,EAAuBC,EAAAA,6BAA6B,CAKpD,GAAA,EAAA,EAAA,QAA4C,KAAK,CAoBvD,MAnBA,CACE,EAAe,UAAU,IAAI,IAI/B,EAA0B,EAAU,EAAe,CAGnD,EAAA,6BACE,EACA,EAAU,6BACVC,EAAAA,wBACD,EAOD,EAAA,EAAA,aAEI,GACyB,CAEzB,IAAM,GAAA,EAAA,EAAA,yBAAoC,EAAO,CAC7C,GACF,EAAe,QAAS,IAAI,EAAU,CAIxC,IAAM,EAAc,EAAU,qBAC5B,EACA,EACD,CAMD,OAHI,GAAe,MAAQ,GACzB,EAAqB,EAAO,CAEvB,GAET,CAAC,EAAW,EAAsB,EAAsB,EAAoB,CAC7E,CAUH,SAAS,EACP,EACA,EACA,CACA,IAAM,EAAYF,EAAAA,cAAc,CAC1B,EAASG,EAAAA,WAAW,CACpB,GAAA,EAAA,EAAA,gBAAqC,CAAC,uBAAuB,CAC7D,EAAkBC,EAAAA,oBAAoB,CACtC,EAAuBL,EAAAA,yBAAyB,CAChD,GAAA,EAAA,EAAA,aACG,GAAU,OAAS,GAAK,GAAmB,EACjD,CAAC,EAAU,EAAiB,EAAoB,CAAC,CAG9C,GAAA,EAAA,EAAA,aACC,EACE,EAAS,KAAK,CAAE,UAAS,GAAG,KAAc,CAC/C,IAAM,EAAe,EAAQ,SAAW,EAMlC,EAAS,CACb,OAAQ,EACR,UACA,SAAA,EAAA,EAAA,qBAPA,EACA,EACA,MAKsB,CACvB,CACD,MAAO,CAAC,GAAA,EAAA,EAAA,yBAAgC,EAAO,CAAC,EAChD,CAd8B,EAAE,CAejC,CAAC,EAAQ,EAAoB,EAAS,CAAC,CAGtC,GACF,EAAQ,SAAS,EAAG,KAAe,CACjC,EAAe,QAAS,IAAI,EAAU,EACtC,EAYJ,EAAA,EAAA,eAAgB,CACT,GAEL,EACG,QACE,CAAC,KACA,EAAU,qBAAqB,EAAQ,EAAqB,EAAI,KACnE,CACA,SAAS,CAAC,KAAY,EAAU,UAAU,EAAO,CAAC,EACpD,CAAC,EAAoB,EAAW,EAAS,EAAqB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTrackedTranslationResolver.d.ts","names":[],"sources":["../../../src/hooks/external-store/useTrackedTranslationResolver.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"useTrackedTranslationResolver.d.ts","names":[],"sources":["../../../src/hooks/external-store/useTrackedTranslationResolver.ts"],"mappings":";;;;KA8BY,OAAA,GAAU,mBAAA;EACpB,OAAA;AAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useLocale as e}from"../condition-store.mjs";import{useShouldTranslate as t}from"../utils.mjs";import{useI18nStore as n,useTranslationsSnapshot as r}from"../../i18n-store/useI18nStore.mjs";import{useHandleMissingTranslation as i}from"../utils/missing-translation.mjs";import{
|
|
1
|
+
import{useLocale as e}from"../condition-store.mjs";import{useShouldTranslate as t}from"../utils.mjs";import{useI18nStore as n,useTranslationsSnapshot as r}from"../../i18n-store/useI18nStore.mjs";import{useHandleMissingTranslation as i}from"../utils/missing-translation.mjs";import{useSubscribeToTrackedLookups as a}from"./useSubscribeToTrackedLookups.mjs";import{useCallback as o,useEffect as s,useMemo as c,useRef as l}from"react";import{createLookupOptions as u,getI18nConfig as d,getTranslateListenerKey as f}from"gt-i18n/internal";function p(e=[]){let t=r(),s=n(),c=d().isDevHotReloadEnabled(),u=i(),p=l(null);return p.current??=new Set,m(e,p),a(p,s.subscribeToTranslationEvents,f),o(e=>{let n=f(e);c&&p.current.add(n);let r=s.getTranslateSnapshot(e,t);return r==null&&c&&u(e),r},[s,t,u,c])}function m(i,a){let o=n(),l=e(),p=d().isDevHotReloadEnabled(),m=t(),h=r(),g=c(()=>i?.length>0&&m&&p,[i,m,p]),_=c(()=>g?i.map(({message:e,...t})=>{let n=t.$locale??l,r={locale:n,message:e,options:u(n,t,`ICU`)};return[r,f(r)]}):[],[l,g,i]);g&&_.forEach(([,e])=>{a.current.add(e)}),s(()=>{g&&_.filter(([e])=>o.getTranslateSnapshot(e,h)==null).forEach(([e])=>o.translate(e))},[g,o,_,h])}export{p as useTrackedTranslationResolver};
|
|
2
2
|
//# sourceMappingURL=useTrackedTranslationResolver.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTrackedTranslationResolver.mjs","names":[],"sources":["../../../src/hooks/external-store/useTrackedTranslationResolver.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"useTrackedTranslationResolver.mjs","names":[],"sources":["../../../src/hooks/external-store/useTrackedTranslationResolver.ts"],"sourcesContent":["import { type RefObject, useCallback, useEffect, useMemo, useRef } from 'react';\nimport {\n createLookupOptions,\n getI18nConfig,\n getTranslateListenerKey,\n} from 'gt-i18n/internal';\nimport type { Translation } from 'gt-i18n/types';\nimport type {\n TranslateLookup,\n TranslateSnapshot,\n} from '../../i18n-store/storeTypes';\nimport type { TranslationMetadata } from 'gt-i18n/internal/types';\nimport type { StringFormat } from '@generaltranslation/format';\nimport { useLocale } from '../condition-store';\nimport { useShouldTranslate } from '../utils';\nimport {\n useI18nStore,\n useTranslationsSnapshot,\n} from '../../i18n-store/useI18nStore';\nimport { useHandleMissingTranslation } from '../utils/missing-translation';\nimport { useSubscribeToTrackedLookups } from './useSubscribeToTrackedLookups';\n\n/**\n * Returns the translation, but also triggers a translation if it is not found\n * when dev hot reload is enabled.\n */\nexport type TrackedTranslationResolver = <T extends Translation>(\n lookup: TranslateLookup<T>\n) => TranslateSnapshot<T>;\n\nexport type Message = TranslationMetadata & {\n message: string;\n};\n\n/**\n * NOTE:\n * gt() may be called during render, so tracking intentionally only mutates\n * hook-local refs. This widens the event filter used by our existing\n * useSyncExternalStore subscription, but does not update React state or mutate\n * the translation cache during render.\n *\n * A render that is later aborted may leave behind an extra tracked key. That is\n * acceptable for dev hot reload because the worst case is an unnecessary\n * invalidation for this hook instance, not incorrect rendered output.\n */\n\nexport function useTrackedTranslationResolver(\n messages: Message[] = []\n): TrackedTranslationResolver {\n const translationsSnapshot = useTranslationsSnapshot();\n const i18nStore = useI18nStore();\n const devHotReloadEnabled = getI18nConfig().isDevHotReloadEnabled();\n const onMissingTranslation = useHandleMissingTranslation();\n\n /**\n * Track lookups per hook instance without updating React state during render.\n */\n const trackedKeysRef = useRef<Set<string> | null>(null);\n if (trackedKeysRef.current == null) {\n trackedKeysRef.current = new Set();\n }\n\n // (optimization) Pre-subscribe to compiler-injected lookups\n usePreloadCompilerLookups(messages, trackedKeysRef);\n\n // (tx hot reload) Subscribe to translation updates\n useSubscribeToTrackedLookups(\n trackedKeysRef,\n i18nStore.subscribeToTranslationEvents,\n getTranslateListenerKey\n );\n\n /**\n * Remember that we can make no assumptions about when this cb gets invoked\n * - Resolves translation from lookup\n * - enqueues dev hot reload (if needed)\n */\n return useCallback(\n <T extends Translation>(\n lookup: TranslateLookup<T>\n ): TranslateSnapshot<T> => {\n // Track the lookup for dev hot reload\n const lookupKey = getTranslateListenerKey(lookup);\n if (devHotReloadEnabled) {\n trackedKeysRef.current!.add(lookupKey);\n }\n\n // Resolve the translation from the store\n const translation = i18nStore.getTranslateSnapshot(\n lookup,\n translationsSnapshot\n );\n\n // Trigger a hot reload if the translation is not found\n if (translation == null && devHotReloadEnabled) {\n onMissingTranslation(lookup);\n }\n return translation;\n },\n [i18nStore, translationsSnapshot, onMissingTranslation, devHotReloadEnabled]\n );\n}\n\n/**\n * Pre-subscribe to compiler-injected lookups\n * trigger translations for them\n *\n * This ref mutation is safe because this is translation hot reload only\n * and effects are deterministic\n */\nfunction usePreloadCompilerLookups(\n messages: Message[],\n trackedKeysRef: RefObject<Set<string> | null>\n) {\n const i18nStore = useI18nStore();\n const locale = useLocale();\n const devHotReloadEnabled = getI18nConfig().isDevHotReloadEnabled();\n const shouldTranslate = useShouldTranslate();\n const translationsSnapshot = useTranslationsSnapshot();\n const txHotReloadEnabled = useMemo(() => {\n return messages?.length > 0 && shouldTranslate && devHotReloadEnabled;\n }, [messages, shouldTranslate, devHotReloadEnabled]);\n\n // Precompute as much as we can\n const lookups: [TranslateLookup<string>, string][] = useMemo(() => {\n if (!txHotReloadEnabled) return [];\n return messages.map(({ message, ...options }) => {\n const targetLocale = options.$locale ?? locale;\n const lookupOptions = createLookupOptions<StringFormat>(\n targetLocale,\n options,\n 'ICU'\n );\n const lookup = {\n locale: targetLocale,\n message,\n options: lookupOptions,\n };\n return [lookup, getTranslateListenerKey(lookup)];\n });\n }, [locale, txHotReloadEnabled, messages]);\n\n // Pre-subscribe to the lookups\n if (txHotReloadEnabled) {\n lookups.forEach(([, lookupKey]) => {\n trackedKeysRef.current!.add(lookupKey);\n });\n }\n\n /**\n * Delegate non-pure operations to post commit\n *\n * (Optimization) Trigger a hot reload if the translation is not found\n * for compiler-injected lookups\n *\n * TODO: for use() + suspense strategy, use a Promise.all()\n * TODO: server side translation invocation\n */\n useEffect(() => {\n if (!txHotReloadEnabled) return;\n\n lookups\n .filter(\n ([lookup]) =>\n i18nStore.getTranslateSnapshot(lookup, translationsSnapshot) == null\n )\n .forEach(([lookup]) => i18nStore.translate(lookup));\n }, [txHotReloadEnabled, i18nStore, lookups, translationsSnapshot]);\n}\n"],"mappings":"uhBA8CA,SAAgB,EACd,EAAsB,EAAE,CACI,CAC5B,IAAM,EAAuB,GAAyB,CAChD,EAAY,GAAc,CAC1B,EAAsB,GAAe,CAAC,uBAAuB,CAC7D,EAAuB,GAA6B,CAKpD,EAAiB,EAA2B,KAAK,CAoBvD,MAnBA,CACE,EAAe,UAAU,IAAI,IAI/B,EAA0B,EAAU,EAAe,CAGnD,EACE,EACA,EAAU,6BACV,EACD,CAOM,EAEH,GACyB,CAEzB,IAAM,EAAY,EAAwB,EAAO,CAC7C,GACF,EAAe,QAAS,IAAI,EAAU,CAIxC,IAAM,EAAc,EAAU,qBAC5B,EACA,EACD,CAMD,OAHI,GAAe,MAAQ,GACzB,EAAqB,EAAO,CAEvB,GAET,CAAC,EAAW,EAAsB,EAAsB,EAAoB,CAC7E,CAUH,SAAS,EACP,EACA,EACA,CACA,IAAM,EAAY,GAAc,CAC1B,EAAS,GAAW,CACpB,EAAsB,GAAe,CAAC,uBAAuB,CAC7D,EAAkB,GAAoB,CACtC,EAAuB,GAAyB,CAChD,EAAqB,MAClB,GAAU,OAAS,GAAK,GAAmB,EACjD,CAAC,EAAU,EAAiB,EAAoB,CAAC,CAG9C,EAA+C,MAC9C,EACE,EAAS,KAAK,CAAE,UAAS,GAAG,KAAc,CAC/C,IAAM,EAAe,EAAQ,SAAW,EAMlC,EAAS,CACb,OAAQ,EACR,UACA,QARoB,EACpB,EACA,EACA,MAKsB,CACvB,CACD,MAAO,CAAC,EAAQ,EAAwB,EAAO,CAAC,EAChD,CAd8B,EAAE,CAejC,CAAC,EAAQ,EAAoB,EAAS,CAAC,CAGtC,GACF,EAAQ,SAAS,EAAG,KAAe,CACjC,EAAe,QAAS,IAAI,EAAU,EACtC,CAYJ,MAAgB,CACT,GAEL,EACG,QACE,CAAC,KACA,EAAU,qBAAqB,EAAQ,EAAqB,EAAI,KACnE,CACA,SAAS,CAAC,KAAY,EAAU,UAAU,EAAO,CAAC,EACpD,CAAC,EAAoB,EAAW,EAAS,EAAqB,CAAC"}
|
|
@@ -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 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,
|
|
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 +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;
|
|
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 +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 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,
|
|
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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@generaltranslation/react-core",
|
|
3
|
-
"version": "11.0.0-odysseus.
|
|
3
|
+
"version": "11.0.0-odysseus.13",
|
|
4
4
|
"description": "A pure React library for internationalization",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"@generaltranslation/format": "0.1.2-odysseus.1",
|
|
15
15
|
"@generaltranslation/supported-locales": "2.1.2-odysseus.4",
|
|
16
16
|
"generaltranslation": "9.0.0-odysseus.4",
|
|
17
|
-
"gt-i18n": "1.0.0-odysseus.
|
|
17
|
+
"gt-i18n": "1.0.0-odysseus.6"
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|