gt-react 10.19.17 → 10.19.18
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 +9 -0
- package/dist/browser.cjs +462 -639
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +9 -6
- package/dist/browser.d.cts.map +1 -1
- package/dist/browser.d.mts +9 -6
- package/dist/browser.d.mts.map +1 -1
- package/dist/browser.mjs +462 -639
- package/dist/browser.mjs.map +1 -1
- package/dist/macros.cjs +461 -638
- package/dist/macros.cjs.map +1 -1
- package/dist/macros.mjs +461 -638
- package/dist/macros.mjs.map +1 -1
- package/package.json +4 -4
package/dist/macros.mjs
CHANGED
|
@@ -4342,7 +4342,7 @@ function sanitizeJsxChildren(childrenAsObjects) {
|
|
|
4342
4342
|
return Array.isArray(childrenAsObjects) ? childrenAsObjects.map(sanitizeChild) : sanitizeChild(childrenAsObjects);
|
|
4343
4343
|
}
|
|
4344
4344
|
//#endregion
|
|
4345
|
-
//#region ../i18n/dist/versionId-
|
|
4345
|
+
//#region ../i18n/dist/versionId-BTjLA0FZ.mjs
|
|
4346
4346
|
/**
|
|
4347
4347
|
* Throw errors if there are any errors and log warnings if there are any warnings
|
|
4348
4348
|
* @param {ValidationResult[]} results - The results to print
|
|
@@ -4608,83 +4608,269 @@ function routeCreateTranslationLoader({ type, remoteTranslationLoaderParams, loa
|
|
|
4608
4608
|
case "disabled": return createFallbackTranslationLoader();
|
|
4609
4609
|
}
|
|
4610
4610
|
}
|
|
4611
|
-
function
|
|
4612
|
-
|
|
4613
|
-
const
|
|
4614
|
-
return
|
|
4611
|
+
function getDictionaryPath(id) {
|
|
4612
|
+
const path = id ? id.split(".") : [];
|
|
4613
|
+
for (const segment of path) assertSafeDictionaryPathSegment(segment, id);
|
|
4614
|
+
return path;
|
|
4615
4615
|
}
|
|
4616
|
-
function
|
|
4617
|
-
if (
|
|
4618
|
-
|
|
4619
|
-
|
|
4616
|
+
function assertSafeDictionaryPathSegment(segment, path) {
|
|
4617
|
+
if (segment === "__proto__" || segment === "constructor" || segment === "prototype") throw new Error(`Dictionary path "${path}" contains an unsafe segment`);
|
|
4618
|
+
}
|
|
4619
|
+
function isDictionaryObject(value) {
|
|
4620
|
+
return typeof value === "object" && value != null && !Array.isArray(value);
|
|
4621
|
+
}
|
|
4622
|
+
function cloneDictionaryValue(value) {
|
|
4623
|
+
if (value === void 0 || typeof value === "string") return value;
|
|
4624
|
+
return structuredClone(value);
|
|
4625
|
+
}
|
|
4626
|
+
function getDictionaryValueAtPath(dictionary, path) {
|
|
4627
|
+
let current = dictionary;
|
|
4628
|
+
for (const segment of getDictionaryPath(path)) {
|
|
4629
|
+
if (!isDictionaryObject(current)) return;
|
|
4630
|
+
current = current[segment];
|
|
4631
|
+
}
|
|
4632
|
+
return current;
|
|
4633
|
+
}
|
|
4634
|
+
function setDictionaryValueAtPath(dictionary, path, value) {
|
|
4635
|
+
const segments = getDictionaryPath(path);
|
|
4636
|
+
if (isDictionaryObject(value)) assertSafeDictionaryObject(value, path);
|
|
4637
|
+
if (segments.length === 0) {
|
|
4638
|
+
if (isDictionaryObject(value)) replaceDictionary(dictionary, value);
|
|
4639
|
+
return;
|
|
4640
|
+
}
|
|
4641
|
+
let current = dictionary;
|
|
4642
|
+
for (const segment of segments.slice(0, -1)) {
|
|
4643
|
+
const next = current[segment];
|
|
4644
|
+
if (!isDictionaryObject(next)) current[segment] = {};
|
|
4645
|
+
current = current[segment];
|
|
4646
|
+
}
|
|
4647
|
+
const leafSegment = segments[segments.length - 1];
|
|
4648
|
+
current[leafSegment] = value;
|
|
4649
|
+
}
|
|
4650
|
+
function getDictionaryEntry(value) {
|
|
4651
|
+
if (!isDictionaryLeafNode(value)) return;
|
|
4652
|
+
return {
|
|
4653
|
+
entry: Array.isArray(value) ? value[0] : value,
|
|
4654
|
+
options: Array.isArray(value) ? value[1] ?? {} : {}
|
|
4655
|
+
};
|
|
4656
|
+
}
|
|
4657
|
+
function getDictionaryValue(value) {
|
|
4658
|
+
if (Object.keys(value.options).length === 0) return value.entry;
|
|
4659
|
+
return [value.entry, value.options];
|
|
4620
4660
|
}
|
|
4661
|
+
function resolveDictionaryLookupOptions(options) {
|
|
4662
|
+
const { $format, context, ...rest } = options;
|
|
4663
|
+
return {
|
|
4664
|
+
...rest,
|
|
4665
|
+
$format: isStringFormat($format) ? $format : "ICU",
|
|
4666
|
+
...rest.$context === void 0 && typeof context === "string" && { $context: context }
|
|
4667
|
+
};
|
|
4668
|
+
}
|
|
4669
|
+
function isDictionaryLeafNode(value) {
|
|
4670
|
+
if (typeof value === "string") return true;
|
|
4671
|
+
if (!Array.isArray(value) || typeof value[0] !== "string") return false;
|
|
4672
|
+
if (value.length === 1) return true;
|
|
4673
|
+
return value.length === 2 && isDictionaryOptions(value[1]);
|
|
4674
|
+
}
|
|
4675
|
+
function isDictionaryOptions(value) {
|
|
4676
|
+
if (typeof value !== "object" || value == null || Array.isArray(value)) return false;
|
|
4677
|
+
const options = value;
|
|
4678
|
+
return (options.$context === void 0 || typeof options.$context === "string") && (options.$format === void 0 || isStringFormat(options.$format)) && (options.$maxChars === void 0 || typeof options.$maxChars === "number") && (options.context === void 0 || typeof options.context === "string");
|
|
4679
|
+
}
|
|
4680
|
+
function isStringFormat(value) {
|
|
4681
|
+
return value === "ICU" || value === "I18NEXT" || value === "STRING";
|
|
4682
|
+
}
|
|
4683
|
+
function replaceDictionary(target, source) {
|
|
4684
|
+
for (const key of Object.keys(target)) delete target[key];
|
|
4685
|
+
for (const key of Object.keys(source)) target[key] = source[key];
|
|
4686
|
+
}
|
|
4687
|
+
function assertSafeDictionaryObject(dictionary, parentPath = "") {
|
|
4688
|
+
for (const [key, value] of Object.entries(dictionary)) {
|
|
4689
|
+
const path = parentPath ? `${parentPath}.${key}` : key;
|
|
4690
|
+
assertSafeDictionaryPathSegment(key, path);
|
|
4691
|
+
if (isDictionaryObject(value)) assertSafeDictionaryObject(value, path);
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4694
|
+
var DictionarySourceNotFoundError = class extends Error {
|
|
4695
|
+
constructor(id) {
|
|
4696
|
+
super(`I18nManager: source dictionary entry ${id} is not defined`);
|
|
4697
|
+
this.name = "DictionarySourceNotFoundError";
|
|
4698
|
+
}
|
|
4699
|
+
};
|
|
4621
4700
|
/**
|
|
4622
|
-
*
|
|
4623
|
-
*
|
|
4624
|
-
* to invoke the cache miss method when a cache miss occurs.
|
|
4625
|
-
*
|
|
4626
|
-
* TODO: maybe add "OutputValue" as a reflection of "InputKey"
|
|
4701
|
+
* Builds the dictionary value for a requested path by combining existing target
|
|
4702
|
+
* translations with runtime translations of any source leaves that are missing.
|
|
4627
4703
|
*/
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4704
|
+
async function materializeDictionaryValue({ key, sourceValue, targetValue, translateEntry }) {
|
|
4705
|
+
if (getDictionaryEntry(targetValue) !== void 0) return cloneDictionaryValue(targetValue);
|
|
4706
|
+
if (isDictionaryObject(targetValue) && !isDictionaryObject(sourceValue)) return cloneDictionaryValue(targetValue);
|
|
4707
|
+
const sourceEntry = getDictionaryEntry(sourceValue);
|
|
4708
|
+
if (sourceEntry !== void 0) return await translateEntry(key, sourceEntry);
|
|
4709
|
+
if (!isDictionaryObject(sourceValue)) throw new DictionarySourceNotFoundError(key);
|
|
4710
|
+
const targetDictionary = isDictionaryObject(targetValue) ? targetValue : {};
|
|
4711
|
+
const keys = new Set([...Object.keys(sourceValue), ...Object.keys(targetDictionary)]);
|
|
4712
|
+
const entries = await Promise.all(Array.from(keys).map(async (childKey) => {
|
|
4713
|
+
const childPath = key ? `${key}.${childKey}` : childKey;
|
|
4714
|
+
assertSafeDictionaryPathSegment(childKey, childPath);
|
|
4715
|
+
const childSource = sourceValue[childKey];
|
|
4716
|
+
if (childSource === void 0) return [childKey, cloneDictionaryValue(targetDictionary[childKey])];
|
|
4717
|
+
return [childKey, await materializeDictionaryValue({
|
|
4718
|
+
key: childPath,
|
|
4719
|
+
sourceValue: childSource,
|
|
4720
|
+
targetValue: targetDictionary[childKey],
|
|
4721
|
+
translateEntry
|
|
4722
|
+
})];
|
|
4723
|
+
}));
|
|
4724
|
+
return Object.fromEntries(entries);
|
|
4725
|
+
}
|
|
4726
|
+
function cloneDictionaryEntry(entry) {
|
|
4727
|
+
return {
|
|
4728
|
+
entry: entry.entry,
|
|
4729
|
+
options: structuredClone(entry.options)
|
|
4730
|
+
};
|
|
4731
|
+
}
|
|
4732
|
+
var DictionaryCache = class {
|
|
4733
|
+
constructor({ init, lifecycle = {}, runtimeTranslate }) {
|
|
4734
|
+
this.pendingTranslations = /* @__PURE__ */ new Map();
|
|
4735
|
+
this.pendingMaterializations = /* @__PURE__ */ new Map();
|
|
4638
4736
|
this.cache = structuredClone(init);
|
|
4639
|
-
this.
|
|
4640
|
-
this.
|
|
4737
|
+
this.runtimeTranslate = runtimeTranslate;
|
|
4738
|
+
this.lifecycle = lifecycle;
|
|
4641
4739
|
}
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4740
|
+
getEntry(key) {
|
|
4741
|
+
const value = getDictionaryValueAtPath(this.cache, key);
|
|
4742
|
+
const entry = getDictionaryEntry(value);
|
|
4743
|
+
if (entry === void 0) return;
|
|
4744
|
+
const outputEntry = cloneDictionaryEntry(entry);
|
|
4745
|
+
this.lifecycle.onHit?.({
|
|
4746
|
+
inputKey: key,
|
|
4747
|
+
cacheKey: key,
|
|
4748
|
+
cacheValue: value,
|
|
4749
|
+
outputValue: outputEntry
|
|
4750
|
+
});
|
|
4751
|
+
return outputEntry;
|
|
4647
4752
|
}
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4753
|
+
getValue(key) {
|
|
4754
|
+
const value = getDictionaryValueAtPath(this.cache, key);
|
|
4755
|
+
if (value === void 0) return;
|
|
4756
|
+
const outputValue = cloneDictionaryValue(value);
|
|
4757
|
+
this.lifecycle.onDictionaryObjectCacheHit?.({
|
|
4758
|
+
inputKey: key,
|
|
4759
|
+
cacheKey: key,
|
|
4760
|
+
cacheValue: value,
|
|
4761
|
+
outputValue
|
|
4762
|
+
});
|
|
4763
|
+
return outputValue;
|
|
4764
|
+
}
|
|
4765
|
+
setValue(key, value) {
|
|
4766
|
+
setDictionaryValueAtPath(this.cache, key, cloneDictionaryValue(value));
|
|
4654
4767
|
}
|
|
4655
|
-
/**
|
|
4656
|
-
* Get the internal cache
|
|
4657
|
-
* @returns The internal cache
|
|
4658
|
-
*
|
|
4659
|
-
* @internal - used by gt-tanstack-start
|
|
4660
|
-
*/
|
|
4661
4768
|
getInternalCache() {
|
|
4662
|
-
return
|
|
4769
|
+
return cloneDictionaryValue(this.cache);
|
|
4770
|
+
}
|
|
4771
|
+
async materializeValue(key, sourceValue, targetValue = getDictionaryValueAtPath(this.cache, key)) {
|
|
4772
|
+
let materializationPromise = this.pendingMaterializations.get(key);
|
|
4773
|
+
if (!materializationPromise) {
|
|
4774
|
+
materializationPromise = materializeDictionaryValue({
|
|
4775
|
+
key,
|
|
4776
|
+
sourceValue,
|
|
4777
|
+
targetValue,
|
|
4778
|
+
translateEntry: async (entryKey, sourceEntry) => getDictionaryValue(await this.materializeEntry(entryKey, sourceEntry))
|
|
4779
|
+
}).then((value) => {
|
|
4780
|
+
this.setValue(key, value);
|
|
4781
|
+
return value;
|
|
4782
|
+
});
|
|
4783
|
+
this.pendingMaterializations.set(key, materializationPromise);
|
|
4784
|
+
}
|
|
4785
|
+
try {
|
|
4786
|
+
return await materializationPromise;
|
|
4787
|
+
} finally {
|
|
4788
|
+
this.pendingMaterializations.delete(key);
|
|
4789
|
+
}
|
|
4663
4790
|
}
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4791
|
+
async materializeEntry(key, sourceEntry) {
|
|
4792
|
+
let translationPromise = this.pendingTranslations.get(key);
|
|
4793
|
+
if (!translationPromise) {
|
|
4794
|
+
translationPromise = this.runtimeTranslate(key, sourceEntry).then((value) => {
|
|
4795
|
+
setDictionaryValueAtPath(this.cache, key, value);
|
|
4796
|
+
const entry = getDictionaryEntry(value);
|
|
4797
|
+
if (entry === void 0) throw new Error("DictionaryCache materializeEntry did not return a DictionaryEntry");
|
|
4798
|
+
this.lifecycle.onMiss?.({
|
|
4799
|
+
inputKey: key,
|
|
4800
|
+
cacheKey: key,
|
|
4801
|
+
cacheValue: value,
|
|
4802
|
+
outputValue: cloneDictionaryEntry(entry)
|
|
4803
|
+
});
|
|
4804
|
+
return cloneDictionaryEntry(entry);
|
|
4805
|
+
});
|
|
4806
|
+
this.pendingTranslations.set(key, translationPromise);
|
|
4807
|
+
}
|
|
4808
|
+
try {
|
|
4809
|
+
return cloneDictionaryEntry(await translationPromise);
|
|
4810
|
+
} finally {
|
|
4811
|
+
this.pendingTranslations.delete(key);
|
|
4812
|
+
}
|
|
4669
4813
|
}
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4814
|
+
};
|
|
4815
|
+
var ResourceCache = class {
|
|
4816
|
+
constructor({ load, lifecycle = {}, ttl }) {
|
|
4817
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
4818
|
+
this.pendingLoads = /* @__PURE__ */ new Map();
|
|
4819
|
+
this.loadResource = load;
|
|
4820
|
+
this.lifecycle = lifecycle;
|
|
4821
|
+
this.ttl = ttl === null ? -1 : ttl ?? 6e4;
|
|
4822
|
+
}
|
|
4823
|
+
get(key) {
|
|
4824
|
+
const entry = this.cache.get(key);
|
|
4825
|
+
if (!entry || this.isExpired(entry)) return;
|
|
4826
|
+
this.lifecycle.onHit?.({
|
|
4827
|
+
inputKey: key,
|
|
4828
|
+
cacheKey: key,
|
|
4829
|
+
cacheValue: entry,
|
|
4830
|
+
outputValue: entry.value
|
|
4831
|
+
});
|
|
4832
|
+
return entry.value;
|
|
4833
|
+
}
|
|
4834
|
+
set(key, value, { expiresAt = this.getExpiresAt() } = {}) {
|
|
4835
|
+
this.cache.set(key, {
|
|
4836
|
+
expiresAt,
|
|
4837
|
+
value
|
|
4838
|
+
});
|
|
4839
|
+
}
|
|
4840
|
+
async getOrLoad(key) {
|
|
4841
|
+
return this.get(key) ?? await this.load(key);
|
|
4842
|
+
}
|
|
4843
|
+
async load(key) {
|
|
4844
|
+
let loadPromise = this.pendingLoads.get(key);
|
|
4845
|
+
if (!loadPromise) {
|
|
4846
|
+
loadPromise = this.loadResource(key).then((value) => {
|
|
4847
|
+
const entry = {
|
|
4848
|
+
expiresAt: this.getExpiresAt(),
|
|
4849
|
+
value
|
|
4850
|
+
};
|
|
4851
|
+
this.cache.set(key, entry);
|
|
4852
|
+
this.lifecycle.onMiss?.({
|
|
4853
|
+
inputKey: key,
|
|
4854
|
+
cacheKey: key,
|
|
4855
|
+
cacheValue: entry,
|
|
4856
|
+
outputValue: entry.value
|
|
4857
|
+
});
|
|
4858
|
+
return entry;
|
|
4859
|
+
});
|
|
4860
|
+
this.pendingLoads.set(key, loadPromise);
|
|
4861
|
+
}
|
|
4680
4862
|
try {
|
|
4681
|
-
|
|
4682
|
-
this.setCache(cacheKey, value);
|
|
4683
|
-
return value;
|
|
4863
|
+
return (await loadPromise).value;
|
|
4684
4864
|
} finally {
|
|
4685
|
-
|
|
4865
|
+
this.pendingLoads.delete(key);
|
|
4686
4866
|
}
|
|
4687
4867
|
}
|
|
4868
|
+
getExpiresAt() {
|
|
4869
|
+
return this.ttl < 0 ? this.ttl : Date.now() + this.ttl;
|
|
4870
|
+
}
|
|
4871
|
+
isExpired(entry) {
|
|
4872
|
+
return entry.expiresAt > 0 && entry.expiresAt < Date.now();
|
|
4873
|
+
}
|
|
4688
4874
|
};
|
|
4689
4875
|
/**
|
|
4690
4876
|
* Hash a message string
|
|
@@ -4729,20 +4915,22 @@ function normalizeBatchConfig(batchConfig) {
|
|
|
4729
4915
|
* Locale logic is handled at the LocalesCache level. Use a callback function that has the
|
|
4730
4916
|
* locale parameter embedded if you wish to use the locale code.
|
|
4731
4917
|
*/
|
|
4732
|
-
var TranslationsCache = class
|
|
4918
|
+
var TranslationsCache = class {
|
|
4733
4919
|
/**
|
|
4734
4920
|
* Constructor
|
|
4735
4921
|
* @param {Object} params - The parameters for the cache
|
|
4736
4922
|
* @param {Record<Hash, TranslationValue>} params.init - The initial cache
|
|
4737
4923
|
* @param {Function} params.fallback - Get the fallback value for a cache miss
|
|
4738
4924
|
*/
|
|
4739
|
-
constructor({ init, translateMany, lifecycle, batchConfig }) {
|
|
4740
|
-
|
|
4741
|
-
this.
|
|
4742
|
-
this.
|
|
4743
|
-
this.
|
|
4744
|
-
this.
|
|
4745
|
-
this.
|
|
4925
|
+
constructor({ init, translateMany, lifecycle = {}, batchConfig }) {
|
|
4926
|
+
this.pendingTranslations = /* @__PURE__ */ new Map();
|
|
4927
|
+
this.queue = [];
|
|
4928
|
+
this.batchTimer = null;
|
|
4929
|
+
this.activeRequests = 0;
|
|
4930
|
+
this.cache = structuredClone(init);
|
|
4931
|
+
this.translateMany = translateMany;
|
|
4932
|
+
this.batchConfig = normalizeBatchConfig(batchConfig);
|
|
4933
|
+
this.lifecycle = lifecycle;
|
|
4746
4934
|
}
|
|
4747
4935
|
/**
|
|
4748
4936
|
* Get the translation value for a given key
|
|
@@ -4750,10 +4938,11 @@ var TranslationsCache = class extends Cache {
|
|
|
4750
4938
|
* @returns The translation value
|
|
4751
4939
|
*/
|
|
4752
4940
|
get(key) {
|
|
4753
|
-
const
|
|
4754
|
-
|
|
4941
|
+
const cacheKey = this.getCacheKey(key);
|
|
4942
|
+
const value = this.cache[cacheKey];
|
|
4943
|
+
if (value != null) this.lifecycle.onHit?.({
|
|
4755
4944
|
inputKey: key,
|
|
4756
|
-
cacheKey
|
|
4945
|
+
cacheKey,
|
|
4757
4946
|
cacheValue: value,
|
|
4758
4947
|
outputValue: value
|
|
4759
4948
|
});
|
|
@@ -4765,75 +4954,64 @@ var TranslationsCache = class extends Cache {
|
|
|
4765
4954
|
* @returns The translation value
|
|
4766
4955
|
*/
|
|
4767
4956
|
async miss(key) {
|
|
4768
|
-
const
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4957
|
+
const cacheKey = this.getCacheKey(key);
|
|
4958
|
+
let translationPromise = this.pendingTranslations.get(cacheKey);
|
|
4959
|
+
if (!translationPromise) {
|
|
4960
|
+
translationPromise = this.translate(key);
|
|
4961
|
+
this.pendingTranslations.set(cacheKey, translationPromise);
|
|
4962
|
+
}
|
|
4963
|
+
try {
|
|
4964
|
+
const value = await translationPromise;
|
|
4965
|
+
if (value != null) this.lifecycle.onMiss?.({
|
|
4966
|
+
inputKey: key,
|
|
4967
|
+
cacheKey,
|
|
4968
|
+
cacheValue: value,
|
|
4969
|
+
outputValue: value
|
|
4970
|
+
});
|
|
4971
|
+
return value;
|
|
4972
|
+
} finally {
|
|
4973
|
+
this.pendingTranslations.delete(cacheKey);
|
|
4974
|
+
}
|
|
4776
4975
|
}
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
*/
|
|
4782
|
-
genKey(key) {
|
|
4976
|
+
getInternalCache() {
|
|
4977
|
+
return structuredClone(this.cache);
|
|
4978
|
+
}
|
|
4979
|
+
getCacheKey(key) {
|
|
4783
4980
|
return hashMessage(key.message, key.options);
|
|
4784
4981
|
}
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
*/
|
|
4790
|
-
fallback(key) {
|
|
4791
|
-
const translationPromise = this._enqueueTranslation(key);
|
|
4792
|
-
if (this._queue.length >= this._batchConfig.maxBatchSize) this._flushNow();
|
|
4793
|
-
else this._scheduleBatch();
|
|
4982
|
+
translate(key) {
|
|
4983
|
+
const translationPromise = this.enqueueTranslation(key);
|
|
4984
|
+
if (this.queue.length >= this.batchConfig.maxBatchSize) this.flushNow();
|
|
4985
|
+
else this.scheduleBatch();
|
|
4794
4986
|
return translationPromise;
|
|
4795
4987
|
}
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
if (this._batchTimer) {
|
|
4801
|
-
clearTimeout(this._batchTimer);
|
|
4802
|
-
this._batchTimer = null;
|
|
4988
|
+
flushNow() {
|
|
4989
|
+
if (this.batchTimer) {
|
|
4990
|
+
clearTimeout(this.batchTimer);
|
|
4991
|
+
this.batchTimer = null;
|
|
4803
4992
|
}
|
|
4804
|
-
this.
|
|
4805
|
-
}
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
this.
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
* Drain the queue
|
|
4818
|
-
*/
|
|
4819
|
-
_drainQueue() {
|
|
4820
|
-
while (this._queue.length > 0 && this._activeRequests < this._batchConfig.maxConcurrentRequests) {
|
|
4821
|
-
const batch = this._queue.splice(0, this._batchConfig.maxBatchSize);
|
|
4822
|
-
this._sendBatchRequest(batch);
|
|
4993
|
+
this.drainQueue();
|
|
4994
|
+
}
|
|
4995
|
+
scheduleBatch() {
|
|
4996
|
+
if (this.batchTimer) return;
|
|
4997
|
+
this.batchTimer = setTimeout(() => {
|
|
4998
|
+
this.batchTimer = null;
|
|
4999
|
+
this.drainQueue();
|
|
5000
|
+
}, this.batchConfig.batchInterval);
|
|
5001
|
+
}
|
|
5002
|
+
drainQueue() {
|
|
5003
|
+
while (this.queue.length > 0 && this.activeRequests < this.batchConfig.maxConcurrentRequests) {
|
|
5004
|
+
const batch = this.queue.splice(0, this.batchConfig.maxBatchSize);
|
|
5005
|
+
this.sendBatchRequest(batch);
|
|
4823
5006
|
}
|
|
4824
|
-
if (this.
|
|
5007
|
+
if (this.queue.length > 0) this.scheduleBatch();
|
|
4825
5008
|
}
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
* @param {TranslationKey<TranslationValue>} key - The translation key
|
|
4829
|
-
* @returns {Promise<TranslationValue>} The translation promise
|
|
4830
|
-
*/
|
|
4831
|
-
_enqueueTranslation(key) {
|
|
4832
|
-
const hash = this.genKey(key);
|
|
5009
|
+
enqueueTranslation(key) {
|
|
5010
|
+
const hash = this.getCacheKey(key);
|
|
4833
5011
|
const options = key.options;
|
|
4834
5012
|
const metadataOptions = options;
|
|
4835
5013
|
return new Promise((resolve, reject) => {
|
|
4836
|
-
this.
|
|
5014
|
+
this.queue.push({
|
|
4837
5015
|
key: hash,
|
|
4838
5016
|
source: key.message,
|
|
4839
5017
|
metadata: {
|
|
@@ -4848,38 +5026,28 @@ var TranslationsCache = class extends Cache {
|
|
|
4848
5026
|
});
|
|
4849
5027
|
});
|
|
4850
5028
|
}
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
* @param {QueueEntry<TranslationValue>[]} batch - The batch of requests to send
|
|
4854
|
-
*/
|
|
4855
|
-
async _sendBatchRequest(batch) {
|
|
4856
|
-
this._activeRequests++;
|
|
5029
|
+
async sendBatchRequest(batch) {
|
|
5030
|
+
this.activeRequests++;
|
|
4857
5031
|
const requests = convertBatchToTranslateManyParams(batch);
|
|
4858
|
-
const response = await this.
|
|
4859
|
-
if (response) this.
|
|
4860
|
-
this.
|
|
5032
|
+
const response = await this.sendBatchRequestWithErrorHandling(batch, requests);
|
|
5033
|
+
if (response) this.handleTranslationResponse(batch, response);
|
|
5034
|
+
this.activeRequests--;
|
|
4861
5035
|
}
|
|
4862
|
-
|
|
4863
|
-
* Send a translation request with error handling
|
|
4864
|
-
*/
|
|
4865
|
-
async _sendBatchRequestWithErrorHandling(batch, requests) {
|
|
5036
|
+
async sendBatchRequestWithErrorHandling(batch, requests) {
|
|
4866
5037
|
try {
|
|
4867
|
-
return await this.
|
|
5038
|
+
return await this.translateMany(requests);
|
|
4868
5039
|
} catch (error) {
|
|
4869
5040
|
for (const entry of batch) entry.reject(error);
|
|
4870
5041
|
return;
|
|
4871
5042
|
}
|
|
4872
5043
|
}
|
|
4873
|
-
|
|
4874
|
-
* Handle a translation response
|
|
4875
|
-
*/
|
|
4876
|
-
_handleTranslationResponse(batch, response) {
|
|
5044
|
+
handleTranslationResponse(batch, response) {
|
|
4877
5045
|
for (const entry of batch) {
|
|
4878
5046
|
const { key } = entry;
|
|
4879
5047
|
const result = response[key];
|
|
4880
5048
|
if (result && result.success) {
|
|
4881
5049
|
const translation = result.translation;
|
|
4882
|
-
this.
|
|
5050
|
+
this.cache[key] = translation;
|
|
4883
5051
|
entry.resolve(translation);
|
|
4884
5052
|
} else entry.reject(result?.error);
|
|
4885
5053
|
}
|
|
@@ -4897,415 +5065,87 @@ function convertBatchToTranslateManyParams(batch) {
|
|
|
4897
5065
|
return acc;
|
|
4898
5066
|
}, {});
|
|
4899
5067
|
}
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
* @param {CreateTranslateMany} params.createTranslateMany - Factory function for creating a translate many function
|
|
4915
|
-
*/
|
|
4916
|
-
constructor({ init = {}, ttl, batchConfig, loadTranslations, createTranslateMany, lifecycle: { onLocalesCacheHit: onHit, onLocalesCacheMiss: onMiss, onTranslationsCacheHit, onTranslationsCacheMiss } }) {
|
|
4917
|
-
super(init, {
|
|
4918
|
-
onHit,
|
|
4919
|
-
onMiss
|
|
5068
|
+
var LocalesCache = class {
|
|
5069
|
+
constructor({ ttl, batchConfig, defaultLocale, dictionary = {}, loadTranslations, loadDictionary, createTranslateMany, translateDictionaryEntry, lifecycle }) {
|
|
5070
|
+
this.translations = new ResourceCache({
|
|
5071
|
+
ttl,
|
|
5072
|
+
load: async (locale) => new TranslationsCache({
|
|
5073
|
+
init: await loadTranslations(locale),
|
|
5074
|
+
lifecycle: createTranslationsCacheLifecycle(locale, lifecycle),
|
|
5075
|
+
translateMany: createTranslateMany(locale),
|
|
5076
|
+
batchConfig
|
|
5077
|
+
}),
|
|
5078
|
+
lifecycle: {
|
|
5079
|
+
onHit: lifecycle.onLocalesCacheHit,
|
|
5080
|
+
onMiss: lifecycle.onLocalesCacheMiss
|
|
5081
|
+
}
|
|
4920
5082
|
});
|
|
4921
|
-
this.
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
*/
|
|
4934
|
-
get(key) {
|
|
4935
|
-
const entry = this.getCache(key);
|
|
4936
|
-
if (!entry || entry.expiresAt > 0 && entry.expiresAt < Date.now()) return;
|
|
4937
|
-
const value = entry.translationsCache;
|
|
4938
|
-
if (value != null && this.onHit) this.onHit({
|
|
4939
|
-
inputKey: key,
|
|
4940
|
-
cacheKey: this.genKey(key),
|
|
4941
|
-
cacheValue: entry,
|
|
4942
|
-
outputValue: value
|
|
5083
|
+
this.dictionaries = new ResourceCache({
|
|
5084
|
+
ttl,
|
|
5085
|
+
load: async (locale) => createDictionaryCache({
|
|
5086
|
+
locale,
|
|
5087
|
+
dictionary: await loadDictionary(locale),
|
|
5088
|
+
translate: translateDictionaryEntry,
|
|
5089
|
+
lifecycle
|
|
5090
|
+
}),
|
|
5091
|
+
lifecycle: {
|
|
5092
|
+
onHit: lifecycle.onLocalesDictionaryCacheHit,
|
|
5093
|
+
onMiss: lifecycle.onLocalesDictionaryCacheMiss
|
|
5094
|
+
}
|
|
4943
5095
|
});
|
|
4944
|
-
|
|
5096
|
+
this.dictionaries.set(defaultLocale, createDictionaryCache({
|
|
5097
|
+
locale: defaultLocale,
|
|
5098
|
+
dictionary,
|
|
5099
|
+
translate: translateDictionaryEntry,
|
|
5100
|
+
lifecycle
|
|
5101
|
+
}), { expiresAt: -1 });
|
|
4945
5102
|
}
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
* @param key - The locale
|
|
4949
|
-
* @returns The translations cache
|
|
4950
|
-
*/
|
|
4951
|
-
async miss(key) {
|
|
4952
|
-
const cacheValue = await this.missCache(key);
|
|
4953
|
-
const value = cacheValue.translationsCache;
|
|
4954
|
-
if (value != null && this.onMiss) this.onMiss({
|
|
4955
|
-
inputKey: key,
|
|
4956
|
-
cacheKey: this.genKey(key),
|
|
4957
|
-
cacheValue,
|
|
4958
|
-
outputValue: value
|
|
4959
|
-
});
|
|
4960
|
-
return value;
|
|
5103
|
+
getTranslations(locale) {
|
|
5104
|
+
return this.translations.get(locale);
|
|
4961
5105
|
}
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
* @param key - The locale
|
|
4965
|
-
* @returns The cache key
|
|
4966
|
-
*
|
|
4967
|
-
* This is just an identity function, no transformation needed
|
|
4968
|
-
*/
|
|
4969
|
-
genKey(key) {
|
|
4970
|
-
return key;
|
|
5106
|
+
getOrLoadTranslations(locale) {
|
|
5107
|
+
return this.translations.getOrLoad(locale);
|
|
4971
5108
|
}
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
* @param locale - The locale
|
|
4975
|
-
* @returns The cache entry
|
|
4976
|
-
*/
|
|
4977
|
-
async fallback(locale) {
|
|
4978
|
-
return {
|
|
4979
|
-
translationsCache: new TranslationsCache({
|
|
4980
|
-
init: await this._translationLoader(locale),
|
|
4981
|
-
lifecycle: this._createTranslationsCacheLifecycle(locale),
|
|
4982
|
-
translateMany: this._createTranslateMany(locale),
|
|
4983
|
-
batchConfig: this._batchConfig
|
|
4984
|
-
}),
|
|
4985
|
-
expiresAt: this.ttl < 0 ? this.ttl : Date.now() + this.ttl
|
|
4986
|
-
};
|
|
5109
|
+
getDictionary(locale) {
|
|
5110
|
+
return this.dictionaries.get(locale);
|
|
4987
5111
|
}
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
* @param locale - The locale
|
|
4991
|
-
* @returns The translations cache lifecycle
|
|
4992
|
-
*/
|
|
4993
|
-
_createTranslationsCacheLifecycle(locale) {
|
|
4994
|
-
return {
|
|
4995
|
-
onHit: this._onTranslationsCacheHit ? (params) => this._onTranslationsCacheHit({
|
|
4996
|
-
locale,
|
|
4997
|
-
...params
|
|
4998
|
-
}) : void 0,
|
|
4999
|
-
onMiss: this._onTranslationsCacheMiss ? (params) => this._onTranslationsCacheMiss({
|
|
5000
|
-
locale,
|
|
5001
|
-
...params
|
|
5002
|
-
}) : void 0
|
|
5003
|
-
};
|
|
5112
|
+
getOrLoadDictionary(locale) {
|
|
5113
|
+
return this.dictionaries.getOrLoad(locale);
|
|
5004
5114
|
}
|
|
5005
5115
|
};
|
|
5006
|
-
function
|
|
5007
|
-
if (!id) return [];
|
|
5008
|
-
return id.split(".");
|
|
5009
|
-
}
|
|
5010
|
-
function isDictionaryValue(value) {
|
|
5011
|
-
return typeof value === "object" && value != null && !Array.isArray(value);
|
|
5012
|
-
}
|
|
5013
|
-
function getDictionaryEntry(value) {
|
|
5014
|
-
if (!isDictionaryLeafNode(value)) return;
|
|
5116
|
+
function createTranslationsCacheLifecycle(locale, lifecycle) {
|
|
5015
5117
|
return {
|
|
5016
|
-
|
|
5017
|
-
|
|
5118
|
+
onHit: withLocale(locale, lifecycle.onTranslationsCacheHit),
|
|
5119
|
+
onMiss: withLocale(locale, lifecycle.onTranslationsCacheMiss)
|
|
5018
5120
|
};
|
|
5019
5121
|
}
|
|
5020
|
-
function
|
|
5021
|
-
|
|
5022
|
-
return
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
};
|
|
5031
|
-
}
|
|
5032
|
-
function isDictionaryLeafNode(value) {
|
|
5033
|
-
if (typeof value === "string") return true;
|
|
5034
|
-
if (!Array.isArray(value) || typeof value[0] !== "string") return false;
|
|
5035
|
-
if (value.length === 1) return true;
|
|
5036
|
-
return value.length === 2 && isDictionaryOptions(value[1]);
|
|
5037
|
-
}
|
|
5038
|
-
function isDictionaryOptions(value) {
|
|
5039
|
-
if (typeof value !== "object" || value == null || Array.isArray(value)) return false;
|
|
5040
|
-
const options = value;
|
|
5041
|
-
return (options.$context === void 0 || typeof options.$context === "string") && (options.$format === void 0 || isStringFormat(options.$format)) && (options.$maxChars === void 0 || typeof options.$maxChars === "number") && (options.context === void 0 || typeof options.context === "string");
|
|
5042
|
-
}
|
|
5043
|
-
function isStringFormat(value) {
|
|
5044
|
-
return value === "ICU" || value === "I18NEXT" || value === "STRING";
|
|
5122
|
+
function createDictionaryCache({ locale, dictionary, translate, lifecycle }) {
|
|
5123
|
+
const { onDictionaryCacheHit, onDictionaryCacheMiss, onDictionaryObjectCacheHit } = lifecycle;
|
|
5124
|
+
return new DictionaryCache({
|
|
5125
|
+
init: dictionary,
|
|
5126
|
+
runtimeTranslate: (key, sourceEntry) => translate(locale, key, sourceEntry),
|
|
5127
|
+
lifecycle: {
|
|
5128
|
+
onHit: withLocale(locale, onDictionaryCacheHit),
|
|
5129
|
+
onMiss: withLocale(locale, onDictionaryCacheMiss),
|
|
5130
|
+
onDictionaryObjectCacheHit: withLocale(locale, onDictionaryObjectCacheHit)
|
|
5131
|
+
}
|
|
5132
|
+
});
|
|
5045
5133
|
}
|
|
5046
|
-
function
|
|
5047
|
-
|
|
5048
|
-
|
|
5134
|
+
function withLocale(locale, callback) {
|
|
5135
|
+
return callback ? (params) => callback({
|
|
5136
|
+
locale,
|
|
5137
|
+
...params
|
|
5138
|
+
}) : void 0;
|
|
5049
5139
|
}
|
|
5050
|
-
|
|
5051
|
-
constructor(id) {
|
|
5052
|
-
super(`I18nManager: source dictionary entry ${id} is not defined`);
|
|
5053
|
-
this.name = "DictionarySourceNotFoundError";
|
|
5054
|
-
}
|
|
5055
|
-
};
|
|
5056
|
-
/**
|
|
5057
|
-
* A cache for a single locale's dictionary
|
|
5058
|
-
*
|
|
5059
|
-
* Principles:
|
|
5060
|
-
* - This class is language agnostic, and should never store the locale code as a parameter.
|
|
5061
|
-
* Locale logic is handled at the LocalesDictionaryCache level. Use a callback function
|
|
5062
|
-
* that has the locale parameter embedded if you wish to use the locale code.
|
|
5063
|
-
*/
|
|
5064
|
-
var DictionaryCache = class extends Cache {
|
|
5065
|
-
/**
|
|
5066
|
-
* Constructor
|
|
5067
|
-
* @param {Object} params - The parameters for the cache
|
|
5068
|
-
* @param {Dictionary} params.init - The initial cache
|
|
5069
|
-
*/
|
|
5070
|
-
constructor({ init, lifecycle, runtimeTranslate }) {
|
|
5071
|
-
super(init, lifecycle);
|
|
5072
|
-
this._runtimeTranslate = runtimeTranslate;
|
|
5073
|
-
this.onHitObj = lifecycle?.onHitObj;
|
|
5074
|
-
this.onMissObj = lifecycle?.onMissObj;
|
|
5075
|
-
}
|
|
5076
|
-
/**
|
|
5077
|
-
* Get the dictionary value for a given key
|
|
5078
|
-
* @param key - The dictionary key
|
|
5079
|
-
* @returns The dictionary value
|
|
5080
|
-
*/
|
|
5081
|
-
get(key) {
|
|
5082
|
-
const value = this.getCache(key);
|
|
5083
|
-
const entry = getDictionaryEntry(value);
|
|
5084
|
-
if (entry === void 0) return;
|
|
5085
|
-
if (this.onHit) this.onHit({
|
|
5086
|
-
inputKey: key,
|
|
5087
|
-
cacheKey: this.genKey(key),
|
|
5088
|
-
cacheValue: value,
|
|
5089
|
-
outputValue: entry
|
|
5090
|
-
});
|
|
5091
|
-
return entry;
|
|
5092
|
-
}
|
|
5093
|
-
set(key, value) {
|
|
5094
|
-
const dictionaryValue = getDictionaryValue(value);
|
|
5095
|
-
this.setCache(this.genKey(key), dictionaryValue);
|
|
5096
|
-
}
|
|
5097
|
-
getObj(key) {
|
|
5098
|
-
const value = this.getCache(key);
|
|
5099
|
-
if (value === void 0) return;
|
|
5100
|
-
const outputValue = structuredClone(value);
|
|
5101
|
-
if (this.onHitObj) this.onHitObj({
|
|
5102
|
-
inputKey: key,
|
|
5103
|
-
cacheKey: this.genKey(key),
|
|
5104
|
-
cacheValue: value,
|
|
5105
|
-
outputValue
|
|
5106
|
-
});
|
|
5107
|
-
return outputValue;
|
|
5108
|
-
}
|
|
5109
|
-
setObj(key, value) {
|
|
5110
|
-
this.setCache(this.genKey(key), structuredClone(value));
|
|
5111
|
-
}
|
|
5112
|
-
async missObj(key, sourceObject) {
|
|
5113
|
-
const sourceEntry = getDictionaryEntry(sourceObject);
|
|
5114
|
-
if (sourceEntry !== void 0) return getDictionaryValue(await this.miss(key, sourceEntry));
|
|
5115
|
-
if (!isDictionaryValue(sourceObject)) throw new DictionarySourceNotFoundError(key);
|
|
5116
|
-
const translatedEntries = await Promise.all(Object.entries(sourceObject).map(async ([childKey, childSource]) => {
|
|
5117
|
-
const childPath = key ? `${key}.${childKey}` : childKey;
|
|
5118
|
-
return [childKey, await this.missObj(childPath, childSource)];
|
|
5119
|
-
}));
|
|
5120
|
-
const translatedObject = Object.fromEntries(translatedEntries);
|
|
5121
|
-
this.setObj(key, translatedObject);
|
|
5122
|
-
return translatedObject;
|
|
5123
|
-
}
|
|
5124
|
-
/**
|
|
5125
|
-
* Miss the cache
|
|
5126
|
-
* @param key - The dictionary key
|
|
5127
|
-
* @returns The dictionary value
|
|
5128
|
-
*/
|
|
5129
|
-
async miss(key, sourceEntry) {
|
|
5130
|
-
const value = await this.missCache(key, sourceEntry);
|
|
5131
|
-
const entry = getDictionaryEntry(value);
|
|
5132
|
-
if (entry === void 0) throw new Error("DictionaryCache missCache did not return a DictionaryEntry");
|
|
5133
|
-
if (this.onMiss) this.onMiss({
|
|
5134
|
-
inputKey: key,
|
|
5135
|
-
cacheKey: this.genKey(key),
|
|
5136
|
-
cacheValue: value,
|
|
5137
|
-
outputValue: entry
|
|
5138
|
-
});
|
|
5139
|
-
return entry;
|
|
5140
|
-
}
|
|
5141
|
-
/**
|
|
5142
|
-
* Set the value for a key
|
|
5143
|
-
*/
|
|
5144
|
-
setCache(cacheKey, value) {
|
|
5145
|
-
const cache = this.getMutableCache();
|
|
5146
|
-
const dictionaryPath = getDictionaryPath(cacheKey);
|
|
5147
|
-
if (dictionaryPath.length === 0) {
|
|
5148
|
-
if (isDictionaryValue(value)) replaceDictionary(cache, value);
|
|
5149
|
-
return;
|
|
5150
|
-
}
|
|
5151
|
-
let current = cache;
|
|
5152
|
-
for (const key of dictionaryPath.slice(0, -1)) {
|
|
5153
|
-
const next = current[key];
|
|
5154
|
-
if (!isDictionaryValue(next)) current[key] = {};
|
|
5155
|
-
current = current[key];
|
|
5156
|
-
}
|
|
5157
|
-
current[dictionaryPath[dictionaryPath.length - 1]] = value;
|
|
5158
|
-
}
|
|
5159
|
-
/**
|
|
5160
|
-
* Look up the key
|
|
5161
|
-
*/
|
|
5162
|
-
getCache(key) {
|
|
5163
|
-
const dictionaryPath = getDictionaryPath(this.genKey(key));
|
|
5164
|
-
let current = this.getMutableCache();
|
|
5165
|
-
if (dictionaryPath.length === 0) return current;
|
|
5166
|
-
for (const pathSegment of dictionaryPath) {
|
|
5167
|
-
if (!isDictionaryValue(current)) return;
|
|
5168
|
-
current = current[pathSegment];
|
|
5169
|
-
}
|
|
5170
|
-
return current;
|
|
5171
|
-
}
|
|
5172
|
-
/**
|
|
5173
|
-
* Generate a key for the cache
|
|
5174
|
-
* @param key - The dictionary key
|
|
5175
|
-
* @returns The key
|
|
5176
|
-
*/
|
|
5177
|
-
genKey(key) {
|
|
5178
|
-
return key;
|
|
5179
|
-
}
|
|
5180
|
-
/**
|
|
5181
|
-
* Get the fallback value for a cache miss
|
|
5182
|
-
* @param key - The dictionary key
|
|
5183
|
-
* @returns The fallback value
|
|
5184
|
-
*
|
|
5185
|
-
* @throws {Error} - If the fallback is not implemented
|
|
5186
|
-
*/
|
|
5187
|
-
fallback(key, sourceEntry) {
|
|
5188
|
-
return this._runtimeTranslate(key, sourceEntry);
|
|
5189
|
-
}
|
|
5190
|
-
};
|
|
5191
|
-
/**
|
|
5192
|
-
* Cache for looking up dictionaries by locale
|
|
5193
|
-
*/
|
|
5194
|
-
var LocalesDictionaryCache = class extends Cache {
|
|
5195
|
-
/**
|
|
5196
|
-
* Constructor
|
|
5197
|
-
* @param {Object} params - The parameters for the cache
|
|
5198
|
-
* @param {number | null} params.ttl - The time to live for cache entries
|
|
5199
|
-
* @param {DictionaryLoader} params.loadDictionary - The dictionary loader function
|
|
5200
|
-
*/
|
|
5201
|
-
constructor({ ttl, defaultLocale, dictionary = {}, loadDictionary, runtimeTranslate, lifecycle: { onLocalesDictionaryCacheHit: onHit, onLocalesDictionaryCacheMiss: onMiss, onDictionaryCacheHit, onDictionaryCacheMiss, onDictionaryObjectCacheHit } }) {
|
|
5202
|
-
super({}, {
|
|
5203
|
-
onHit,
|
|
5204
|
-
onMiss
|
|
5205
|
-
});
|
|
5206
|
-
this.ttl = DEFAULT_CACHE_EXPIRY_TIME;
|
|
5207
|
-
this.ttl = ttl === null ? -1 : ttl ?? 6e4;
|
|
5208
|
-
this._dictionaryLoader = loadDictionary;
|
|
5209
|
-
this._runtimeTranslate = runtimeTranslate;
|
|
5210
|
-
this._onDictionaryCacheHit = onDictionaryCacheHit;
|
|
5211
|
-
this._onDictionaryCacheMiss = onDictionaryCacheMiss;
|
|
5212
|
-
this._onDictionaryObjectCacheHit = onDictionaryObjectCacheHit;
|
|
5213
|
-
this.setCache(defaultLocale, {
|
|
5214
|
-
dictionaryCache: new DictionaryCache({
|
|
5215
|
-
init: dictionary,
|
|
5216
|
-
runtimeTranslate: this._createDictionaryRuntimeTranslate(defaultLocale),
|
|
5217
|
-
lifecycle: this._createDictionaryCacheLifecycle(defaultLocale)
|
|
5218
|
-
}),
|
|
5219
|
-
expiresAt: -1
|
|
5220
|
-
});
|
|
5221
|
-
}
|
|
5222
|
-
/**
|
|
5223
|
-
* Get the dictionary for a given locale
|
|
5224
|
-
* @param key - The locale
|
|
5225
|
-
* @returns The dictionary
|
|
5226
|
-
*/
|
|
5227
|
-
get(key) {
|
|
5228
|
-
const entry = this.getCache(key);
|
|
5229
|
-
if (!entry || entry.expiresAt > 0 && entry.expiresAt < Date.now()) return;
|
|
5230
|
-
const value = entry.dictionaryCache;
|
|
5231
|
-
if (value != null && this.onHit) this.onHit({
|
|
5232
|
-
inputKey: key,
|
|
5233
|
-
cacheKey: this.genKey(key),
|
|
5234
|
-
cacheValue: entry,
|
|
5235
|
-
outputValue: value
|
|
5236
|
-
});
|
|
5237
|
-
return value;
|
|
5238
|
-
}
|
|
5239
|
-
/**
|
|
5240
|
-
* Miss the cache
|
|
5241
|
-
* @param key - The locale
|
|
5242
|
-
* @returns The dictionary cache
|
|
5243
|
-
*/
|
|
5244
|
-
async miss(key) {
|
|
5245
|
-
const cacheValue = await this.missCache(key);
|
|
5246
|
-
const value = cacheValue.dictionaryCache;
|
|
5247
|
-
if (value != null && this.onMiss) this.onMiss({
|
|
5248
|
-
inputKey: key,
|
|
5249
|
-
cacheKey: this.genKey(key),
|
|
5250
|
-
cacheValue,
|
|
5251
|
-
outputValue: value
|
|
5252
|
-
});
|
|
5253
|
-
return value;
|
|
5254
|
-
}
|
|
5255
|
-
/**
|
|
5256
|
-
* Generate the cache key for a given locale
|
|
5257
|
-
* @param key - The locale
|
|
5258
|
-
* @returns The cache key
|
|
5259
|
-
*
|
|
5260
|
-
* This is just an identity function, no transformation needed
|
|
5261
|
-
*/
|
|
5262
|
-
genKey(key) {
|
|
5263
|
-
return key;
|
|
5264
|
-
}
|
|
5265
|
-
/**
|
|
5266
|
-
* Fallback for a cache miss
|
|
5267
|
-
* @param locale - The locale
|
|
5268
|
-
* @returns The cache entry
|
|
5269
|
-
*/
|
|
5270
|
-
async fallback(locale) {
|
|
5271
|
-
return {
|
|
5272
|
-
dictionaryCache: new DictionaryCache({
|
|
5273
|
-
init: await this._dictionaryLoader(locale),
|
|
5274
|
-
runtimeTranslate: this._createDictionaryRuntimeTranslate(locale),
|
|
5275
|
-
lifecycle: this._createDictionaryCacheLifecycle(locale)
|
|
5276
|
-
}),
|
|
5277
|
-
expiresAt: this.ttl < 0 ? this.ttl : Date.now() + this.ttl
|
|
5278
|
-
};
|
|
5279
|
-
}
|
|
5280
|
-
/**
|
|
5281
|
-
* Create the dictionary cache lifecycle
|
|
5282
|
-
* @param locale - The locale
|
|
5283
|
-
* @returns The dictionary cache lifecycle
|
|
5284
|
-
*/
|
|
5285
|
-
_createDictionaryCacheLifecycle(locale) {
|
|
5286
|
-
return {
|
|
5287
|
-
onHit: this._onDictionaryCacheHit ? (params) => this._onDictionaryCacheHit({
|
|
5288
|
-
locale,
|
|
5289
|
-
...params
|
|
5290
|
-
}) : void 0,
|
|
5291
|
-
onMiss: this._onDictionaryCacheMiss ? (params) => this._onDictionaryCacheMiss({
|
|
5292
|
-
locale,
|
|
5293
|
-
...params
|
|
5294
|
-
}) : void 0,
|
|
5295
|
-
onHitObj: this._onDictionaryObjectCacheHit ? (params) => this._onDictionaryObjectCacheHit({
|
|
5296
|
-
locale,
|
|
5297
|
-
...params
|
|
5298
|
-
}) : void 0
|
|
5299
|
-
};
|
|
5300
|
-
}
|
|
5301
|
-
_createDictionaryRuntimeTranslate(locale) {
|
|
5302
|
-
return (key, sourceEntry) => this._runtimeTranslate(locale, key, sourceEntry);
|
|
5303
|
-
}
|
|
5304
|
-
};
|
|
5140
|
+
const LOCALES_CACHE_HIT_EVENT_NAME = "locales-cache-hit";
|
|
5305
5141
|
const LOCALES_CACHE_MISS_EVENT_NAME = "locales-cache-miss";
|
|
5142
|
+
const TRANSLATIONS_CACHE_HIT_EVENT_NAME = "translations-cache-hit";
|
|
5306
5143
|
const TRANSLATIONS_CACHE_MISS_EVENT_NAME = "translations-cache-miss";
|
|
5144
|
+
const LOCALES_DICTIONARY_CACHE_HIT_EVENT_NAME = "locales-dictionary-cache-hit";
|
|
5307
5145
|
const LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME = "locales-dictionary-cache-miss";
|
|
5146
|
+
const DICTIONARY_CACHE_HIT_EVENT_NAME = "dictionary-cache-hit";
|
|
5308
5147
|
const DICTIONARY_CACHE_MISS_EVENT_NAME = "dictionary-cache-miss";
|
|
5148
|
+
const DICTIONARY_OBJECT_CACHE_HIT_EVENT_NAME = "dictionary-object-cache-hit";
|
|
5309
5149
|
/**
|
|
5310
5150
|
* Maps consumer-facing lifecycle callbacks to internal locales cache lifecycle callbacks.
|
|
5311
5151
|
* The consumer API exposes simplified params (locale, hash, value) while the internal
|
|
@@ -5313,22 +5153,24 @@ const DICTIONARY_CACHE_MISS_EVENT_NAME = "dictionary-cache-miss";
|
|
|
5313
5153
|
*
|
|
5314
5154
|
* @deprecated - move to subscription api instead
|
|
5315
5155
|
*/
|
|
5316
|
-
function createLifecycleCallbacks(emit) {
|
|
5156
|
+
function createLifecycleCallbacks(emit, hasListeners = () => true) {
|
|
5317
5157
|
return {
|
|
5318
5158
|
onLocalesCacheHit: (params) => {
|
|
5319
|
-
|
|
5159
|
+
if (!hasListeners("locales-cache-hit")) return;
|
|
5160
|
+
emit(LOCALES_CACHE_HIT_EVENT_NAME, {
|
|
5320
5161
|
locale: params.inputKey,
|
|
5321
5162
|
translations: params.outputValue.getInternalCache()
|
|
5322
5163
|
});
|
|
5323
5164
|
},
|
|
5324
5165
|
onLocalesCacheMiss: (params) => {
|
|
5166
|
+
if (!hasListeners("locales-cache-miss")) return;
|
|
5325
5167
|
emit(LOCALES_CACHE_MISS_EVENT_NAME, {
|
|
5326
5168
|
locale: params.inputKey,
|
|
5327
5169
|
translations: params.outputValue.getInternalCache()
|
|
5328
5170
|
});
|
|
5329
5171
|
},
|
|
5330
5172
|
onTranslationsCacheHit: (params) => {
|
|
5331
|
-
emit(
|
|
5173
|
+
emit(TRANSLATIONS_CACHE_HIT_EVENT_NAME, {
|
|
5332
5174
|
locale: params.locale,
|
|
5333
5175
|
hash: params.cacheKey,
|
|
5334
5176
|
translation: params.outputValue
|
|
@@ -5342,19 +5184,21 @@ function createLifecycleCallbacks(emit) {
|
|
|
5342
5184
|
});
|
|
5343
5185
|
},
|
|
5344
5186
|
onLocalesDictionaryCacheHit: (params) => {
|
|
5345
|
-
|
|
5187
|
+
if (!hasListeners("locales-dictionary-cache-hit")) return;
|
|
5188
|
+
emit(LOCALES_DICTIONARY_CACHE_HIT_EVENT_NAME, {
|
|
5346
5189
|
locale: params.inputKey,
|
|
5347
5190
|
dictionary: params.outputValue.getInternalCache()
|
|
5348
5191
|
});
|
|
5349
5192
|
},
|
|
5350
5193
|
onLocalesDictionaryCacheMiss: (params) => {
|
|
5194
|
+
if (!hasListeners("locales-dictionary-cache-miss")) return;
|
|
5351
5195
|
emit(LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME, {
|
|
5352
5196
|
locale: params.inputKey,
|
|
5353
5197
|
dictionary: params.outputValue.getInternalCache()
|
|
5354
5198
|
});
|
|
5355
5199
|
},
|
|
5356
5200
|
onDictionaryCacheHit: (params) => {
|
|
5357
|
-
emit(
|
|
5201
|
+
emit(DICTIONARY_CACHE_HIT_EVENT_NAME, {
|
|
5358
5202
|
locale: params.locale,
|
|
5359
5203
|
id: params.cacheKey,
|
|
5360
5204
|
dictionaryEntry: params.outputValue
|
|
@@ -5368,7 +5212,7 @@ function createLifecycleCallbacks(emit) {
|
|
|
5368
5212
|
});
|
|
5369
5213
|
},
|
|
5370
5214
|
onDictionaryObjectCacheHit: (params) => {
|
|
5371
|
-
emit(
|
|
5215
|
+
emit(DICTIONARY_OBJECT_CACHE_HIT_EVENT_NAME, {
|
|
5372
5216
|
locale: params.locale,
|
|
5373
5217
|
id: params.cacheKey,
|
|
5374
5218
|
dictionaryValue: params.outputValue
|
|
@@ -5403,6 +5247,9 @@ var EventEmitter = class {
|
|
|
5403
5247
|
emit(eventName, event) {
|
|
5404
5248
|
this.listeners[eventName]?.forEach((subscriber) => subscriber(event));
|
|
5405
5249
|
}
|
|
5250
|
+
hasListeners(eventName) {
|
|
5251
|
+
return (this.listeners[eventName]?.size ?? 0) > 0;
|
|
5252
|
+
}
|
|
5406
5253
|
};
|
|
5407
5254
|
/**
|
|
5408
5255
|
* Subscribes to the lifecycle callbacks and emits the events to the event emitter
|
|
@@ -5412,7 +5259,7 @@ var EventEmitter = class {
|
|
|
5412
5259
|
* and is only used internally
|
|
5413
5260
|
*/
|
|
5414
5261
|
function subscribeLifecycleCallbacks({ onLocalesCacheHit, onLocalesCacheMiss, onTranslationsCacheHit, onTranslationsCacheMiss, onLocalesDictionaryCacheHit, onLocalesDictionaryCacheMiss, onDictionaryCacheHit, onDictionaryCacheMiss, onDictionaryObjectCacheHit }, subscribe) {
|
|
5415
|
-
if (onLocalesCacheHit) subscribe(
|
|
5262
|
+
if (onLocalesCacheHit) subscribe(LOCALES_CACHE_HIT_EVENT_NAME, (event) => {
|
|
5416
5263
|
onLocalesCacheHit({
|
|
5417
5264
|
...event,
|
|
5418
5265
|
value: event.translations
|
|
@@ -5424,7 +5271,7 @@ function subscribeLifecycleCallbacks({ onLocalesCacheHit, onLocalesCacheMiss, on
|
|
|
5424
5271
|
value: event.translations
|
|
5425
5272
|
});
|
|
5426
5273
|
});
|
|
5427
|
-
if (onTranslationsCacheHit) subscribe(
|
|
5274
|
+
if (onTranslationsCacheHit) subscribe(TRANSLATIONS_CACHE_HIT_EVENT_NAME, (event) => {
|
|
5428
5275
|
onTranslationsCacheHit({
|
|
5429
5276
|
...event,
|
|
5430
5277
|
value: event.translation
|
|
@@ -5436,19 +5283,19 @@ function subscribeLifecycleCallbacks({ onLocalesCacheHit, onLocalesCacheMiss, on
|
|
|
5436
5283
|
value: event.translation
|
|
5437
5284
|
});
|
|
5438
5285
|
});
|
|
5439
|
-
if (onLocalesDictionaryCacheHit) subscribe(
|
|
5286
|
+
if (onLocalesDictionaryCacheHit) subscribe(LOCALES_DICTIONARY_CACHE_HIT_EVENT_NAME, (event) => {
|
|
5440
5287
|
onLocalesDictionaryCacheHit(event);
|
|
5441
5288
|
});
|
|
5442
5289
|
if (onLocalesDictionaryCacheMiss) subscribe(LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME, (event) => {
|
|
5443
5290
|
onLocalesDictionaryCacheMiss(event);
|
|
5444
5291
|
});
|
|
5445
|
-
if (onDictionaryCacheHit) subscribe(
|
|
5292
|
+
if (onDictionaryCacheHit) subscribe(DICTIONARY_CACHE_HIT_EVENT_NAME, (event) => {
|
|
5446
5293
|
onDictionaryCacheHit(event);
|
|
5447
5294
|
});
|
|
5448
5295
|
if (onDictionaryCacheMiss) subscribe(DICTIONARY_CACHE_MISS_EVENT_NAME, (event) => {
|
|
5449
5296
|
onDictionaryCacheMiss(event);
|
|
5450
5297
|
});
|
|
5451
|
-
if (onDictionaryObjectCacheHit) subscribe(
|
|
5298
|
+
if (onDictionaryObjectCacheHit) subscribe(DICTIONARY_OBJECT_CACHE_HIT_EVENT_NAME, (event) => {
|
|
5452
5299
|
onDictionaryObjectCacheHit(event);
|
|
5453
5300
|
});
|
|
5454
5301
|
}
|
|
@@ -5479,26 +5326,32 @@ var I18nManager = class extends EventEmitter {
|
|
|
5479
5326
|
locales: this.config.locales,
|
|
5480
5327
|
customMapping: this.config.customMapping
|
|
5481
5328
|
});
|
|
5482
|
-
const loadTranslations =
|
|
5483
|
-
|
|
5329
|
+
const loadTranslations = routeCreateTranslationLoader({
|
|
5330
|
+
loadTranslations: params.loadTranslations,
|
|
5331
|
+
type: getLoadTranslationsType(params),
|
|
5332
|
+
remoteTranslationLoaderParams: {
|
|
5333
|
+
cacheUrl: params.cacheUrl,
|
|
5334
|
+
projectId: params.projectId,
|
|
5335
|
+
_versionId: params._versionId,
|
|
5336
|
+
_branchId: params._branchId,
|
|
5337
|
+
customMapping: params.customMapping
|
|
5338
|
+
}
|
|
5339
|
+
});
|
|
5340
|
+
const loadDictionary = params.loadDictionary ?? (() => Promise.resolve({}));
|
|
5484
5341
|
const runtimeTranslationTimeout = this.config.runtimeTranslation?.timeout ?? DEFAULT_TRANSLATION_TIMEOUT;
|
|
5485
5342
|
const runtimeTranslationMetadata = this.config.runtimeTranslation?.metadata ?? {};
|
|
5486
5343
|
const createTranslateMany = createTranslateManyFactory(this.getGTClassClean(), runtimeTranslationTimeout, runtimeTranslationMetadata);
|
|
5487
5344
|
subscribeLifecycleCallbacks(params.lifecycle ?? {}, (...args) => this.subscribe(...args));
|
|
5488
|
-
const lifecycle = createLifecycleCallbacks((...args) => this.emit(...args));
|
|
5345
|
+
const lifecycle = createLifecycleCallbacks((...args) => this.emit(...args), (eventName) => this.hasListeners(eventName));
|
|
5489
5346
|
this.localesCache = new LocalesCache({
|
|
5490
|
-
loadTranslations,
|
|
5491
|
-
createTranslateMany,
|
|
5492
|
-
lifecycle,
|
|
5493
|
-
ttl: this.config.cacheExpiryTime,
|
|
5494
|
-
batchConfig: this.config.batchConfig
|
|
5495
|
-
});
|
|
5496
|
-
this.localesDictionaryCache = new LocalesDictionaryCache({
|
|
5497
5347
|
defaultLocale: this.config.defaultLocale,
|
|
5498
5348
|
dictionary: params.dictionary,
|
|
5349
|
+
loadTranslations,
|
|
5499
5350
|
loadDictionary,
|
|
5500
|
-
|
|
5351
|
+
createTranslateMany,
|
|
5352
|
+
translateDictionaryEntry: (locale, id, sourceEntry) => this.translateDictionaryEntry(locale, id, sourceEntry),
|
|
5501
5353
|
ttl: this.config.cacheExpiryTime,
|
|
5354
|
+
batchConfig: this.config.batchConfig,
|
|
5502
5355
|
lifecycle
|
|
5503
5356
|
});
|
|
5504
5357
|
}
|
|
@@ -5570,9 +5423,7 @@ var I18nManager = class extends EventEmitter {
|
|
|
5570
5423
|
try {
|
|
5571
5424
|
const translationLocale = this.resolveCacheLocale(locale);
|
|
5572
5425
|
if (!translationLocale) return {};
|
|
5573
|
-
|
|
5574
|
-
if (!txCache) txCache = await this.localesCache.miss(translationLocale);
|
|
5575
|
-
return txCache.getInternalCache();
|
|
5426
|
+
return (await this.localesCache.getOrLoadTranslations(translationLocale)).getInternalCache();
|
|
5576
5427
|
} catch (error) {
|
|
5577
5428
|
this.handleError(error);
|
|
5578
5429
|
return {};
|
|
@@ -5585,10 +5436,8 @@ var I18nManager = class extends EventEmitter {
|
|
|
5585
5436
|
async loadDictionary(locale) {
|
|
5586
5437
|
try {
|
|
5587
5438
|
const dictionaryLocale = this.resolveCacheLocale(locale);
|
|
5588
|
-
if (!dictionaryLocale) return this.
|
|
5589
|
-
|
|
5590
|
-
if (!dictionaryCache) dictionaryCache = await this.localesDictionaryCache.miss(dictionaryLocale);
|
|
5591
|
-
return dictionaryCache.getInternalCache();
|
|
5439
|
+
if (!dictionaryLocale) return this.getDefaultDictionaryCache()?.getInternalCache() ?? {};
|
|
5440
|
+
return (await this.localesCache.getOrLoadDictionary(dictionaryLocale)).getInternalCache();
|
|
5592
5441
|
} catch (error) {
|
|
5593
5442
|
this.handleError(error);
|
|
5594
5443
|
return {};
|
|
@@ -5599,8 +5448,8 @@ var I18nManager = class extends EventEmitter {
|
|
|
5599
5448
|
*/
|
|
5600
5449
|
lookupDictionary(locale, id) {
|
|
5601
5450
|
try {
|
|
5602
|
-
const dictionaryLocale = this.
|
|
5603
|
-
return this.
|
|
5451
|
+
const dictionaryLocale = this.resolveDictionaryCacheLocale(locale);
|
|
5452
|
+
return this.localesCache.getDictionary(dictionaryLocale)?.getEntry(id);
|
|
5604
5453
|
} catch (error) {
|
|
5605
5454
|
this.handleError(error);
|
|
5606
5455
|
return;
|
|
@@ -5611,8 +5460,8 @@ var I18nManager = class extends EventEmitter {
|
|
|
5611
5460
|
*/
|
|
5612
5461
|
lookupDictionaryObj(locale, id) {
|
|
5613
5462
|
try {
|
|
5614
|
-
const dictionaryLocale = this.
|
|
5615
|
-
return this.
|
|
5463
|
+
const dictionaryLocale = this.resolveDictionaryCacheLocale(locale);
|
|
5464
|
+
return this.localesCache.getDictionary(dictionaryLocale)?.getValue(id);
|
|
5616
5465
|
} catch (error) {
|
|
5617
5466
|
this.handleError(error);
|
|
5618
5467
|
return;
|
|
@@ -5625,19 +5474,10 @@ var I18nManager = class extends EventEmitter {
|
|
|
5625
5474
|
async lookupDictionaryWithFallback(locale, id) {
|
|
5626
5475
|
try {
|
|
5627
5476
|
const dictionaryLocale = this.resolveCacheLocale(locale);
|
|
5628
|
-
if (!dictionaryLocale)
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
}
|
|
5633
|
-
let dictionaryCache = this.localesDictionaryCache.get(dictionaryLocale);
|
|
5634
|
-
if (!dictionaryCache) dictionaryCache = await this.localesDictionaryCache.miss(dictionaryLocale);
|
|
5635
|
-
let dictionaryEntry = dictionaryCache.get(id);
|
|
5636
|
-
if (dictionaryEntry === void 0) {
|
|
5637
|
-
const sourceEntry = this.localesDictionaryCache.get(this.config.defaultLocale)?.get(id);
|
|
5638
|
-
if (sourceEntry === void 0) throw new DictionarySourceNotFoundError(id);
|
|
5639
|
-
dictionaryEntry = await dictionaryCache.miss(id, sourceEntry);
|
|
5640
|
-
}
|
|
5477
|
+
if (!dictionaryLocale) return this.getSourceDictionaryEntry(id);
|
|
5478
|
+
const dictionaryCache = await this.localesCache.getOrLoadDictionary(dictionaryLocale);
|
|
5479
|
+
let dictionaryEntry = dictionaryCache.getEntry(id);
|
|
5480
|
+
if (dictionaryEntry === void 0) dictionaryEntry = await dictionaryCache.materializeEntry(id, this.getSourceDictionaryEntry(id));
|
|
5641
5481
|
return dictionaryEntry;
|
|
5642
5482
|
} catch (error) {
|
|
5643
5483
|
this.handleError(error);
|
|
@@ -5651,25 +5491,41 @@ var I18nManager = class extends EventEmitter {
|
|
|
5651
5491
|
async lookupDictionaryObjWithFallback(locale, id) {
|
|
5652
5492
|
try {
|
|
5653
5493
|
const dictionaryLocale = this.resolveCacheLocale(locale);
|
|
5654
|
-
if (!dictionaryLocale)
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5494
|
+
if (!dictionaryLocale) return this.getSourceDictionaryObject(id);
|
|
5495
|
+
const dictionaryCache = await this.localesCache.getOrLoadDictionary(dictionaryLocale);
|
|
5496
|
+
const targetObject = dictionaryCache.getValue(id);
|
|
5497
|
+
const sourceObject = this.getSourceDictionaryObject(id, { throwOnMissing: false });
|
|
5498
|
+
if (sourceObject === void 0) {
|
|
5499
|
+
if (targetObject !== void 0) return targetObject;
|
|
5500
|
+
throw new DictionarySourceNotFoundError(id);
|
|
5658
5501
|
}
|
|
5659
|
-
|
|
5660
|
-
if (!dictionaryCache) dictionaryCache = await this.localesDictionaryCache.miss(dictionaryLocale);
|
|
5661
|
-
let dictionaryObject = dictionaryCache.getObj(id);
|
|
5662
|
-
if (dictionaryObject === void 0) {
|
|
5663
|
-
const sourceObject = this.localesDictionaryCache.get(this.config.defaultLocale)?.getObj(id);
|
|
5664
|
-
if (sourceObject === void 0) throw new DictionarySourceNotFoundError(id);
|
|
5665
|
-
dictionaryObject = await dictionaryCache.missObj(id, sourceObject);
|
|
5666
|
-
}
|
|
5667
|
-
return dictionaryObject;
|
|
5502
|
+
return await dictionaryCache.materializeValue(id, sourceObject, targetObject);
|
|
5668
5503
|
} catch (error) {
|
|
5669
5504
|
this.handleError(error);
|
|
5670
5505
|
return;
|
|
5671
5506
|
}
|
|
5672
5507
|
}
|
|
5508
|
+
async translateDictionaryEntry(locale, id, sourceEntry) {
|
|
5509
|
+
const translation = await this.lookupTranslationWithFallbackResolved(locale, sourceEntry.entry, resolveDictionaryLookupOptions(sourceEntry.options));
|
|
5510
|
+
if (typeof translation !== "string") throw new Error(`Dictionary entry "${id}" could not be translated into a string. Check the source entry and translation loader output.`);
|
|
5511
|
+
return translation;
|
|
5512
|
+
}
|
|
5513
|
+
getSourceDictionaryEntry(id) {
|
|
5514
|
+
const sourceEntry = this.getDefaultDictionaryCache()?.getEntry(id);
|
|
5515
|
+
if (sourceEntry === void 0) throw new DictionarySourceNotFoundError(id);
|
|
5516
|
+
return sourceEntry;
|
|
5517
|
+
}
|
|
5518
|
+
getSourceDictionaryObject(id, { throwOnMissing = true } = {}) {
|
|
5519
|
+
const sourceObject = this.getDefaultDictionaryCache()?.getValue(id);
|
|
5520
|
+
if (sourceObject === void 0 && throwOnMissing) throw new DictionarySourceNotFoundError(id);
|
|
5521
|
+
return sourceObject;
|
|
5522
|
+
}
|
|
5523
|
+
getDefaultDictionaryCache() {
|
|
5524
|
+
return this.localesCache.getDictionary(this.config.defaultLocale);
|
|
5525
|
+
}
|
|
5526
|
+
resolveDictionaryCacheLocale(locale) {
|
|
5527
|
+
return this.resolveCacheLocale(locale) ?? this.config.defaultLocale;
|
|
5528
|
+
}
|
|
5673
5529
|
/**
|
|
5674
5530
|
* Just lookup a translation
|
|
5675
5531
|
*/
|
|
@@ -5677,7 +5533,7 @@ var I18nManager = class extends EventEmitter {
|
|
|
5677
5533
|
try {
|
|
5678
5534
|
const { translationLocale, options: lookupOptions } = this.resolveLookupParams(locale, options);
|
|
5679
5535
|
if (!translationLocale) return message;
|
|
5680
|
-
const txCache = this.localesCache.
|
|
5536
|
+
const txCache = this.localesCache.getTranslations(translationLocale);
|
|
5681
5537
|
if (!txCache) return void 0;
|
|
5682
5538
|
return txCache.get({
|
|
5683
5539
|
message,
|
|
@@ -5715,9 +5571,7 @@ var I18nManager = class extends EventEmitter {
|
|
|
5715
5571
|
if (!translationLocale) return (message) => message;
|
|
5716
5572
|
const resolvedPrefetchEntries = resolvePrefetchEntriesByLocale(prefetchEntries, translationLocale, (entryLocale) => this.resolveCacheLocale(entryLocale) ?? this.resolveLocale(entryLocale));
|
|
5717
5573
|
if (resolvedPrefetchEntries.length !== prefetchEntries.length) logger_default.warn(`I18nManager: getLookupTranslation(): prefetchEntries must all be the same locale, ignoring all entries that are not for ${translationLocale}`);
|
|
5718
|
-
|
|
5719
|
-
if (!txCache) txCache = await this.localesCache.miss(translationLocale);
|
|
5720
|
-
if (!txCache) return () => void 0;
|
|
5574
|
+
const txCache = await this.localesCache.getOrLoadTranslations(translationLocale);
|
|
5721
5575
|
await Promise.all(resolvedPrefetchEntries.filter((entry) => txCache.get(entry) == null).map((entry) => txCache.miss(entry)));
|
|
5722
5576
|
return (message, options = {}) => {
|
|
5723
5577
|
return txCache.get({
|
|
@@ -5819,8 +5673,7 @@ var I18nManager = class extends EventEmitter {
|
|
|
5819
5673
|
async lookupTranslationWithFallbackResolved(locale, message, options) {
|
|
5820
5674
|
const { translationLocale, options: lookupOptions } = this.resolveLookupParams(locale, options);
|
|
5821
5675
|
if (!translationLocale) return message;
|
|
5822
|
-
|
|
5823
|
-
if (!txCache) txCache = await this.localesCache.miss(translationLocale);
|
|
5676
|
+
const txCache = await this.localesCache.getOrLoadTranslations(translationLocale);
|
|
5824
5677
|
let translation = txCache.get({
|
|
5825
5678
|
message,
|
|
5826
5679
|
options: lookupOptions
|
|
@@ -5832,14 +5685,6 @@ var I18nManager = class extends EventEmitter {
|
|
|
5832
5685
|
return translation;
|
|
5833
5686
|
}
|
|
5834
5687
|
/**
|
|
5835
|
-
* Runtime lookup function for dictionaries
|
|
5836
|
-
*/
|
|
5837
|
-
async dictionaryRuntimeTranslate(locale, id, sourceEntry) {
|
|
5838
|
-
const translation = await this.lookupTranslationWithFallbackResolved(locale, sourceEntry.entry, resolveDictionaryLookupOptions(sourceEntry.options));
|
|
5839
|
-
if (typeof translation !== "string") throw new Error(`Dictionary entry "${id}" could not be translated into a string. Check the source entry and translation loader output.`);
|
|
5840
|
-
return translation;
|
|
5841
|
-
}
|
|
5842
|
-
/**
|
|
5843
5688
|
* A helper function to create a gt class that is locale agnostic
|
|
5844
5689
|
* This is helpful for when our getLocale function is bound to a
|
|
5845
5690
|
* specific context
|
|
@@ -5936,28 +5781,6 @@ function resolvePrefetchEntriesByLocale(prefetchEntries, locale, resolveLocale)
|
|
|
5936
5781
|
}
|
|
5937
5782
|
});
|
|
5938
5783
|
}
|
|
5939
|
-
/**
|
|
5940
|
-
* Helper function for creating a translation loader
|
|
5941
|
-
*/
|
|
5942
|
-
function createTranslationLoader(params) {
|
|
5943
|
-
return routeCreateTranslationLoader({
|
|
5944
|
-
loadTranslations: params.loadTranslations,
|
|
5945
|
-
type: getLoadTranslationsType(params),
|
|
5946
|
-
remoteTranslationLoaderParams: {
|
|
5947
|
-
cacheUrl: params.cacheUrl,
|
|
5948
|
-
projectId: params.projectId,
|
|
5949
|
-
_versionId: params._versionId,
|
|
5950
|
-
_branchId: params._branchId,
|
|
5951
|
-
customMapping: params.customMapping
|
|
5952
|
-
}
|
|
5953
|
-
});
|
|
5954
|
-
}
|
|
5955
|
-
/**
|
|
5956
|
-
* Helper function for creating a dictionary loader
|
|
5957
|
-
*/
|
|
5958
|
-
function createDictionaryLoader(params) {
|
|
5959
|
-
return params.loadDictionary ?? (() => Promise.resolve({}));
|
|
5960
|
-
}
|
|
5961
5784
|
let i18nManager = void 0;
|
|
5962
5785
|
let fallbackDefaultLocale = "en";
|
|
5963
5786
|
let conditionStore = { getLocale: () => fallbackDefaultLocale };
|