gt-i18n 0.9.2 → 0.9.3
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 +11 -0
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/internal.cjs +1 -1
- package/dist/internal.mjs +1 -1
- package/dist/{versionId-B2xfz6jP.mjs → versionId-BkJZGHXr.mjs} +36 -17
- package/dist/versionId-BkJZGHXr.mjs.map +1 -0
- package/dist/{versionId-BZf-o3gk.cjs → versionId-C4WMCH8U.cjs} +35 -16
- package/dist/versionId-C4WMCH8U.cjs.map +1 -0
- package/package.json +4 -4
- package/dist/versionId-B2xfz6jP.mjs.map +0 -1
- package/dist/versionId-BZf-o3gk.cjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# gt-i18n
|
|
2
2
|
|
|
3
|
+
## 0.9.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1419](https://github.com/generaltranslation/gt/pull/1419) [`a877a2a`](https://github.com/generaltranslation/gt/commit/a877a2a5bd5ca47b199c6caf53a6d60d96e3a300) Thanks [@bgub](https://github.com/bgub)! - Improve diagnostic messages and package-local diagnostic formatting.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`bb3624e`](https://github.com/generaltranslation/gt/commit/bb3624e58546c334c04370a1f5a262238bd040fa), [`a877a2a`](https://github.com/generaltranslation/gt/commit/a877a2a5bd5ca47b199c6caf53a6d60d96e3a300)]:
|
|
10
|
+
- @generaltranslation/format@0.1.1
|
|
11
|
+
- generaltranslation@8.2.15
|
|
12
|
+
- @generaltranslation/supported-locales@2.0.73
|
|
13
|
+
|
|
3
14
|
## 0.9.2
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_isEncodedTranslationOptions = require("./isEncodedTranslationOptions-eqrZWcmP.cjs");
|
|
3
|
-
const require_versionId = require("./versionId-
|
|
3
|
+
const require_versionId = require("./versionId-C4WMCH8U.cjs");
|
|
4
4
|
const require_mFallback = require("./mFallback-DSBMUg3c.cjs");
|
|
5
5
|
let generaltranslation_internal = require("generaltranslation/internal");
|
|
6
6
|
let _generaltranslation_format = require("@generaltranslation/format");
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as extractVariables, i as createInterpolationFailureMessage, n as decodeOptions, o as logger_default } from "./isEncodedTranslationOptions-BOwWa_-J.mjs";
|
|
2
|
-
import { E as hashMessage, a as getLocales, d as resolveStringContentWithFallback, i as getLocaleProperties, m as getCurrentLocale, n as getDefaultLocale, r as getLocale, t as getVersionId } from "./versionId-
|
|
2
|
+
import { E as hashMessage, a as getLocales, d as resolveStringContentWithFallback, i as getLocaleProperties, m as getCurrentLocale, n as getDefaultLocale, r as getLocale, t as getVersionId } from "./versionId-BkJZGHXr.mjs";
|
|
3
3
|
import { n as gtFallback, r as decodeMsg, t as mFallback } from "./mFallback-pqVm9wDk.mjs";
|
|
4
4
|
import { VAR_IDENTIFIER, declareStatic, declareVar, decodeVars, derive, encode, libraryDefaultLocale } from "generaltranslation/internal";
|
|
5
5
|
import { formatMessage } from "@generaltranslation/format";
|
package/dist/internal.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_isEncodedTranslationOptions = require("./isEncodedTranslationOptions-eqrZWcmP.cjs");
|
|
3
|
-
const require_versionId = require("./versionId-
|
|
3
|
+
const require_versionId = require("./versionId-C4WMCH8U.cjs");
|
|
4
4
|
let generaltranslation_internal = require("generaltranslation/internal");
|
|
5
5
|
let _generaltranslation_format = require("@generaltranslation/format");
|
|
6
6
|
//#region src/translation-functions/internal/getGT.ts
|
package/dist/internal.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as extractVariables, n as decodeOptions, r as interpolateIcuMessage, t as isEncodedTranslationOptions } from "./isEncodedTranslationOptions-BOwWa_-J.mjs";
|
|
2
|
-
import { C as getDictionaryEntry, S as TRANSLATIONS_CACHE_MISS_EVENT_NAME, T as resolveDictionaryLookupOptions, _ as setI18nManager, a as getLocales, b as LOCALES_CACHE_MISS_EVENT_NAME, c as resolveJsxWithFallback, d as resolveStringContentWithFallback, f as resolveStringContentWithRuntimeFallback, g as setConditionStore, h as getI18nManager, i as getLocaleProperties, l as resolveJsxWithRuntimeFallback, m as getCurrentLocale, n as getDefaultLocale, o as createLookupOptions, p as interpolateMessage, r as getLocale, s as resolveJsx, t as getVersionId, u as resolveStringContent, v as I18nManager, w as isDictionaryValue, x as LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME, y as DICTIONARY_CACHE_MISS_EVENT_NAME } from "./versionId-
|
|
2
|
+
import { C as getDictionaryEntry, S as TRANSLATIONS_CACHE_MISS_EVENT_NAME, T as resolveDictionaryLookupOptions, _ as setI18nManager, a as getLocales, b as LOCALES_CACHE_MISS_EVENT_NAME, c as resolveJsxWithFallback, d as resolveStringContentWithFallback, f as resolveStringContentWithRuntimeFallback, g as setConditionStore, h as getI18nManager, i as getLocaleProperties, l as resolveJsxWithRuntimeFallback, m as getCurrentLocale, n as getDefaultLocale, o as createLookupOptions, p as interpolateMessage, r as getLocale, s as resolveJsx, t as getVersionId, u as resolveStringContent, v as I18nManager, w as isDictionaryValue, x as LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME, y as DICTIONARY_CACHE_MISS_EVENT_NAME } from "./versionId-BkJZGHXr.mjs";
|
|
3
3
|
import { libraryDefaultLocale } from "generaltranslation/internal";
|
|
4
4
|
import { LocaleConfig } from "@generaltranslation/format";
|
|
5
5
|
//#region src/translation-functions/internal/getGT.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { o as logger_default, r as interpolateIcuMessage } from "./isEncodedTranslationOptions-BOwWa_-J.mjs";
|
|
2
|
-
import { defaultCacheUrl, defaultRuntimeApiUrl, indexVars, libraryDefaultLocale } from "generaltranslation/internal";
|
|
2
|
+
import { createDiagnosticMessage, defaultCacheUrl, defaultRuntimeApiUrl, indexVars, libraryDefaultLocale } from "generaltranslation/internal";
|
|
3
3
|
import { LocaleConfig, formatCutoff, isValidLocale, resolveCanonicalLocale, standardizeLocale } from "@generaltranslation/format";
|
|
4
4
|
import { GT } from "generaltranslation";
|
|
5
5
|
import { hashSource } from "generaltranslation/id";
|
|
@@ -53,9 +53,9 @@ function getLoadTranslationsType(config) {
|
|
|
53
53
|
* Requirements:
|
|
54
54
|
* - REMOTE:
|
|
55
55
|
* - GT_REMOTE:
|
|
56
|
-
* - projectId is
|
|
56
|
+
* - projectId is needed
|
|
57
57
|
* - CUSTOM:
|
|
58
|
-
* - loadTranslations is
|
|
58
|
+
* - loadTranslations is needed
|
|
59
59
|
* - DISABLED:
|
|
60
60
|
* - no requirements
|
|
61
61
|
*/
|
|
@@ -67,13 +67,19 @@ function validateLoadTranslations(params) {
|
|
|
67
67
|
case "gt-remote":
|
|
68
68
|
if (!projectId) results.push({
|
|
69
69
|
type: "warning",
|
|
70
|
-
message:
|
|
70
|
+
message: createDiagnosticMessage({
|
|
71
|
+
whatHappened: "Loading translations from a remote store needs a projectId",
|
|
72
|
+
fix: "Add projectId to the I18nManager config or disable remote translation loading"
|
|
73
|
+
})
|
|
71
74
|
});
|
|
72
75
|
break;
|
|
73
76
|
case "custom":
|
|
74
77
|
if (!loadTranslations) results.push({
|
|
75
78
|
type: "error",
|
|
76
|
-
message:
|
|
79
|
+
message: createDiagnosticMessage({
|
|
80
|
+
whatHappened: "Custom translation loading needs loadTranslations",
|
|
81
|
+
fix: "Provide a loadTranslations function or disable custom translation loading"
|
|
82
|
+
})
|
|
77
83
|
});
|
|
78
84
|
break;
|
|
79
85
|
case "disabled": break;
|
|
@@ -88,8 +94,9 @@ function validateLoadTranslations(params) {
|
|
|
88
94
|
* @returns The runtime translation type
|
|
89
95
|
*/
|
|
90
96
|
function getTranslationApiType(params) {
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
const usesDefaultRuntimeUrl = params.runtimeUrl === void 0 || params.runtimeUrl === defaultRuntimeApiUrl;
|
|
98
|
+
if (usesDefaultRuntimeUrl && params.projectId && (params.devApiKey || params.apiKey)) return "gt";
|
|
99
|
+
else if (params.runtimeUrl && !usesDefaultRuntimeUrl) return "custom";
|
|
93
100
|
else return "disabled";
|
|
94
101
|
}
|
|
95
102
|
//#endregion
|
|
@@ -107,8 +114,8 @@ function getTranslationApiType(params) {
|
|
|
107
114
|
* Requirements:
|
|
108
115
|
* - CUSTOM:
|
|
109
116
|
* - GT:
|
|
110
|
-
* - projectId is
|
|
111
|
-
* - devApiKey or apiKey is
|
|
117
|
+
* - projectId is needed
|
|
118
|
+
* - devApiKey or apiKey is needed
|
|
112
119
|
* - DISABLED:
|
|
113
120
|
* - no requirements
|
|
114
121
|
*
|
|
@@ -121,11 +128,17 @@ function validateTranslationApi(params) {
|
|
|
121
128
|
case "gt":
|
|
122
129
|
if (!params.projectId) results.push({
|
|
123
130
|
type: "warning",
|
|
124
|
-
message:
|
|
131
|
+
message: createDiagnosticMessage({
|
|
132
|
+
whatHappened: "Runtime translation needs a projectId",
|
|
133
|
+
fix: "Add projectId to the I18nManager config or disable runtime translation"
|
|
134
|
+
})
|
|
125
135
|
});
|
|
126
136
|
if (!params.devApiKey && !params.apiKey) results.push({
|
|
127
137
|
type: "warning",
|
|
128
|
-
message:
|
|
138
|
+
message: createDiagnosticMessage({
|
|
139
|
+
whatHappened: "Runtime translation needs devApiKey or apiKey",
|
|
140
|
+
fix: "Add credentials to the I18nManager config or disable runtime translation"
|
|
141
|
+
})
|
|
129
142
|
});
|
|
130
143
|
break;
|
|
131
144
|
case "disabled": break;
|
|
@@ -158,7 +171,10 @@ function validateLocales(params) {
|
|
|
158
171
|
new Set([...defaultLocale ? [defaultLocale] : [], ...locales || []]).forEach((locale) => {
|
|
159
172
|
if (!isValidLocale(locale, customMapping)) results.push({
|
|
160
173
|
type: "error",
|
|
161
|
-
message:
|
|
174
|
+
message: createDiagnosticMessage({
|
|
175
|
+
whatHappened: `Locale "${locale}" is not valid`,
|
|
176
|
+
fix: "Use a valid BCP 47 locale code or add a custom mapping"
|
|
177
|
+
})
|
|
162
178
|
});
|
|
163
179
|
});
|
|
164
180
|
return results;
|
|
@@ -175,7 +191,10 @@ function validateDictionary(params) {
|
|
|
175
191
|
const results = [];
|
|
176
192
|
if (params.loadDictionary && !params.dictionary) results.push({
|
|
177
193
|
type: "error",
|
|
178
|
-
message:
|
|
194
|
+
message: createDiagnosticMessage({
|
|
195
|
+
whatHappened: "loadDictionary needs a source dictionary",
|
|
196
|
+
fix: "Provide dictionary so the default locale has source content"
|
|
197
|
+
})
|
|
179
198
|
});
|
|
180
199
|
return results;
|
|
181
200
|
}
|
|
@@ -1483,7 +1502,7 @@ var I18nManager = class extends EventEmitter {
|
|
|
1483
1502
|
}
|
|
1484
1503
|
resolveLocale(locale) {
|
|
1485
1504
|
const resolvedLocale = this.localeConfig.determineLocale(locale);
|
|
1486
|
-
if (!this.localeConfig.isValidLocale(locale) || !resolvedLocale) throw new Error(`
|
|
1505
|
+
if (!this.localeConfig.isValidLocale(locale) || !resolvedLocale) throw new Error(`Locale "${locale}" is not valid. Use a valid BCP 47 locale code or add a custom mapping.`);
|
|
1487
1506
|
return resolvedLocale;
|
|
1488
1507
|
}
|
|
1489
1508
|
/**
|
|
@@ -1530,7 +1549,7 @@ var I18nManager = class extends EventEmitter {
|
|
|
1530
1549
|
*/
|
|
1531
1550
|
async dictionaryRuntimeTranslate(locale, id, sourceEntry) {
|
|
1532
1551
|
const translation = await this.lookupTranslationWithFallbackResolved(locale, sourceEntry.entry, resolveDictionaryLookupOptions(sourceEntry.options));
|
|
1533
|
-
if (typeof translation !== "string") throw new Error(`
|
|
1552
|
+
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.`);
|
|
1534
1553
|
return translation;
|
|
1535
1554
|
}
|
|
1536
1555
|
/**
|
|
@@ -1665,7 +1684,7 @@ let conditionStore = fallbackConditionStore;
|
|
|
1665
1684
|
*/
|
|
1666
1685
|
function getI18nManager() {
|
|
1667
1686
|
if (!i18nManager) {
|
|
1668
|
-
logger_default.warn("getI18nManager():
|
|
1687
|
+
logger_default.warn("getI18nManager(): I18nManager was not initialized. Falling back to the default locale until initializeGT() configures translations.");
|
|
1669
1688
|
i18nManager = new I18nManager({
|
|
1670
1689
|
defaultLocale: libraryDefaultLocale,
|
|
1671
1690
|
locales: [libraryDefaultLocale]
|
|
@@ -1888,4 +1907,4 @@ function getVersionId() {
|
|
|
1888
1907
|
//#endregion
|
|
1889
1908
|
export { getDictionaryEntry as C, hashMessage as E, TRANSLATIONS_CACHE_MISS_EVENT_NAME as S, resolveDictionaryLookupOptions as T, setI18nManager as _, getLocales as a, LOCALES_CACHE_MISS_EVENT_NAME as b, resolveJsxWithFallback as c, resolveStringContentWithFallback as d, resolveStringContentWithRuntimeFallback as f, setConditionStore as g, getI18nManager as h, getLocaleProperties as i, resolveJsxWithRuntimeFallback as l, getCurrentLocale as m, getDefaultLocale as n, createLookupOptions as o, interpolateMessage as p, getLocale as r, resolveJsx as s, getVersionId as t, resolveStringContent as u, I18nManager as v, isDictionaryValue as w, LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME as x, DICTIONARY_CACHE_MISS_EVENT_NAME as y };
|
|
1890
1909
|
|
|
1891
|
-
//# sourceMappingURL=versionId-
|
|
1910
|
+
//# sourceMappingURL=versionId-BkJZGHXr.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versionId-BkJZGHXr.mjs","names":[],"sources":["../src/i18n-manager/validation/publishValidationResults.ts","../src/i18n-manager/utils/getLoadTranslationsType.ts","../src/i18n-manager/validation/config-validation/validateLoadTranslations.ts","../src/i18n-manager/utils/getTranslationApiType.ts","../src/i18n-manager/validation/config-validation/validateTranslationApi.ts","../src/i18n-manager/utils/getGTServicesEnabled.ts","../src/i18n-manager/validation/config-validation/validateLocales.ts","../src/i18n-manager/validation/config-validation/validateDictionary.ts","../src/i18n-manager/validation/validateConfig.ts","../src/i18n-manager/translations-manager/utils/createTranslateMany.ts","../src/i18n-manager/translations-manager/translations-loaders/createRemoteTranslationLoader.ts","../src/i18n-manager/translations-manager/translations-loaders/createFallbackTranslationLoader.ts","../src/i18n-manager/translations-manager/translations-loaders/routeCreateTranslationLoader.ts","../src/i18n-manager/translations-manager/Cache.ts","../src/utils/hashMessage.ts","../src/i18n-manager/translations-manager/TranslationsCache.ts","../src/i18n-manager/translations-manager/utils/constants.ts","../src/i18n-manager/translations-manager/LocalesCache.ts","../src/i18n-manager/translations-manager/utils/dictionary-helpers.ts","../src/i18n-manager/translations-manager/utils/DictionarySourceNotFoundError.ts","../src/i18n-manager/translations-manager/DictionaryCache.ts","../src/i18n-manager/translations-manager/LocalesDictionaryCache.ts","../src/i18n-manager/event-subscription/types.ts","../src/i18n-manager/lifecycle-hooks/createLifecycleCallbacks.ts","../src/i18n-manager/event-subscription/EventEmitter.ts","../src/i18n-manager/lifecycle-hooks/subscribeLifecycleCallbacks.ts","../src/i18n-manager/I18nManager.ts","../src/i18n-manager/singleton-operations.ts","../src/translation-functions/utils/interpolation/interpolateStringMessage.ts","../src/translation-functions/utils/interpolation/interpolateMessage.ts","../src/translation-functions/internal/helpers.ts","../src/helpers/locale.ts","../src/helpers/versionId.ts"],"sourcesContent":["import { ValidationResult } from './types';\nimport logger from '../../logs/logger';\n\n/**\n * Throw errors if there are any errors and log warnings if there are any warnings\n * @param {ValidationResult[]} results - The results to print\n * @param {string} [prefix] - The prefix to add to the results\n * @param {boolean} [throwOnError] - Whether to throw an error if there are any errors\n *\n * TODO: dedupe messages\n * TODO: logging system\n */\nexport function publishValidationResults(\n results: ValidationResult[],\n prefix: string = '',\n throwOnError: boolean = true\n): void {\n // Log the results\n results.forEach((result) => {\n switch (result.type) {\n case 'error':\n logger.error(prefix + result.message);\n break;\n case 'warning':\n logger.warn(prefix + result.message);\n break;\n }\n });\n\n // Throw if there are any errors\n if (throwOnError && results.some((result) => result.type === 'error')) {\n throw new Error('Validation errors occurred');\n }\n}\n","import { TranslationsLoader } from '../translations-manager/translations-loaders/types';\nimport { defaultCacheUrl } from 'generaltranslation/internal';\n\n/**\n * Loader translations type\n * - GT_REMOTE: use the default remote store URL {@link defaultCacheUrl}\n * - REMOTE: use a custom remote store URL\n * - CUSTOM: use a custom translations loader\n * - DISABLED: no translations loading\n */\nexport enum LoadTranslationsType {\n GT_REMOTE = 'gt-remote',\n REMOTE = 'remote',\n CUSTOM = 'custom',\n DISABLED = 'disabled',\n}\n\n/**\n * Based on the configurtion return the load translations type\n *\n * cacheUrl = null means disabled\n */\nexport function getLoadTranslationsType(config: {\n projectId?: string;\n cacheUrl?: string | null;\n loadTranslations?: TranslationsLoader;\n}): LoadTranslationsType {\n if (config.loadTranslations) {\n return LoadTranslationsType.CUSTOM;\n } else if (config.cacheUrl) {\n return LoadTranslationsType.REMOTE;\n } else if (\n (config.cacheUrl === undefined || config.cacheUrl === defaultCacheUrl) &&\n config.projectId\n ) {\n return LoadTranslationsType.GT_REMOTE;\n } else {\n return LoadTranslationsType.DISABLED;\n }\n}\n","import { TranslationsLoader } from '../../translations-manager/translations-loaders/types';\nimport { LoadTranslationsType } from '../../utils/getLoadTranslationsType';\nimport { getLoadTranslationsType } from '../../utils/getLoadTranslationsType';\nimport { ValidationResult } from '../types';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\n\n/**\n * Load translation configuration\n *\n * Types of load translations:\n * - GT_REMOTE: use the default remote store URL {@link defaultCacheUrl}\n * - REMOTE: use a custom remote store URL\n * - CUSTOM: use a custom translations loader\n * - DISABLED: no translations loading\n *\n * Requirements:\n * - REMOTE:\n * - GT_REMOTE:\n * - projectId is needed\n * - CUSTOM:\n * - loadTranslations is needed\n * - DISABLED:\n * - no requirements\n */\nexport function validateLoadTranslations(params: {\n projectId?: string;\n cacheUrl?: string | null;\n loadTranslations?: TranslationsLoader;\n}): ValidationResult[] {\n const results: ValidationResult[] = [];\n const { projectId, loadTranslations } = params;\n\n const loadTranslationsType = getLoadTranslationsType(params);\n switch (loadTranslationsType) {\n case LoadTranslationsType.REMOTE:\n case LoadTranslationsType.GT_REMOTE:\n if (!projectId) {\n results.push({\n type: 'warning',\n message: createDiagnosticMessage({\n whatHappened:\n 'Loading translations from a remote store needs a projectId',\n fix: 'Add projectId to the I18nManager config or disable remote translation loading',\n }),\n });\n }\n break;\n case LoadTranslationsType.CUSTOM:\n if (!loadTranslations) {\n results.push({\n type: 'error',\n message: createDiagnosticMessage({\n whatHappened: 'Custom translation loading needs loadTranslations',\n fix: 'Provide a loadTranslations function or disable custom translation loading',\n }),\n });\n }\n break;\n case LoadTranslationsType.DISABLED:\n break;\n }\n\n return results;\n}\n","import { defaultRuntimeApiUrl } from 'generaltranslation/internal';\n\n/**\n * Runtime API translation type\n * - GT: use the default runtime API URL {@link defaultRuntimeApiUrl}\n * - CUSTOM: use a custom runtime API URL\n * - DISABLED: no runtime API translation\n */\nexport enum TranslationApiType {\n GT = 'gt',\n CUSTOM = 'custom',\n DISABLED = 'disabled',\n}\n\n/**\n * Based on the configurtion return the runtime translation type\n * @param params - The parameters to validate\n * @returns The runtime translation type\n */\nexport function getTranslationApiType(params: {\n projectId?: string;\n devApiKey?: string;\n apiKey?: string;\n runtimeUrl?: string | null;\n}): TranslationApiType {\n const usesDefaultRuntimeUrl =\n params.runtimeUrl === undefined ||\n params.runtimeUrl === defaultRuntimeApiUrl;\n\n if (\n usesDefaultRuntimeUrl &&\n params.projectId &&\n (params.devApiKey || params.apiKey)\n ) {\n return TranslationApiType.GT;\n } else if (params.runtimeUrl && !usesDefaultRuntimeUrl) {\n return TranslationApiType.CUSTOM;\n } else {\n return TranslationApiType.DISABLED;\n }\n}\n","import { ValidationResult } from '../types';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\nimport {\n TranslationApiType,\n getTranslationApiType,\n} from '../../utils/getTranslationApiType';\n\n/**\n * Validate the translation API configuration\n * @param params - The parameters to validate\n * @returns The validation results\n *\n * Types of translation API:\n * - GT: use the default runtime API URL {@link defaultRuntimeApiUrl}\n * - CUSTOM: use a custom runtime API URL\n * - DISABLED: no runtime API translation\n *\n * Requirements:\n * - CUSTOM:\n * - GT:\n * - projectId is needed\n * - devApiKey or apiKey is needed\n * - DISABLED:\n * - no requirements\n *\n * TODO: reject dev api key in production\n */\nexport function validateTranslationApi(params: {\n projectId?: string;\n devApiKey?: string;\n apiKey?: string;\n runtimeUrl?: string | null;\n}): ValidationResult[] {\n const results: ValidationResult[] = [];\n\n const translationApiType = getTranslationApiType(params);\n\n switch (translationApiType) {\n case TranslationApiType.CUSTOM:\n case TranslationApiType.GT:\n if (!params.projectId) {\n results.push({\n type: 'warning',\n message: createDiagnosticMessage({\n whatHappened: 'Runtime translation needs a projectId',\n fix: 'Add projectId to the I18nManager config or disable runtime translation',\n }),\n });\n }\n if (!params.devApiKey && !params.apiKey) {\n results.push({\n type: 'warning',\n message: createDiagnosticMessage({\n whatHappened: 'Runtime translation needs devApiKey or apiKey',\n fix: 'Add credentials to the I18nManager config or disable runtime translation',\n }),\n });\n }\n break;\n case TranslationApiType.DISABLED:\n break;\n }\n return results;\n}\n","import {\n getLoadTranslationsType,\n LoadTranslationsType,\n} from './getLoadTranslationsType';\nimport {\n getTranslationApiType,\n TranslationApiType,\n} from './getTranslationApiType';\n\n/**\n * Returns true if GT services are enabled\n * @param config - The configuration\n * @returns True if GT services are enabled\n */\nexport function getGTServicesEnabled(config: {\n projectId?: string;\n devApiKey?: string;\n apiKey?: string;\n cacheUrl?: string | null;\n runtimeUrl?: string | null;\n}): boolean {\n return (\n getLoadTranslationsType(config) === LoadTranslationsType.GT_REMOTE ||\n getTranslationApiType(config) === TranslationApiType.GT\n );\n}\n","import { isValidLocale } from '@generaltranslation/format';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\nimport { getGTServicesEnabled } from '../../utils/getGTServicesEnabled';\nimport { ValidationResult } from '../types';\nimport type { CustomMapping } from '@generaltranslation/format/types';\n\n/**\n * Validate the locales configuration\n * @param params - The parameters to validate\n * @returns The validation results\n *\n * Only apply if using GT services\n */\nexport function validateLocales(params: {\n projectId?: string;\n devApiKey?: string;\n apiKey?: string;\n defaultLocale?: string;\n locales?: string[];\n customMapping?: CustomMapping;\n cacheUrl?: string | null;\n runtimeUrl?: string | null;\n}): ValidationResult[] {\n const results: ValidationResult[] = [];\n if (!getGTServicesEnabled(params)) {\n return results;\n }\n const { defaultLocale, locales, customMapping } = params;\n\n const localesToValidate = new Set([\n ...(defaultLocale ? [defaultLocale] : []),\n ...(locales || []),\n ]);\n\n localesToValidate.forEach((locale) => {\n if (!isValidLocale(locale, customMapping)) {\n results.push({\n type: 'error',\n message: createDiagnosticMessage({\n whatHappened: `Locale \"${locale}\" is not valid`,\n fix: 'Use a valid BCP 47 locale code or add a custom mapping',\n }),\n });\n }\n });\n\n return results;\n}\n","import type { DictionaryLoader } from '../../translations-manager/LocalesDictionaryCache';\nimport type { Dictionary } from '../../translations-manager/DictionaryCache';\nimport type { ValidationResult } from '../types';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\n\n/**\n * Dictionary configuration\n *\n * Requirements:\n * - loadDictionary requires dictionary so the default locale always has a source dictionary\n */\nexport function validateDictionary(params: {\n dictionary?: Dictionary;\n loadDictionary?: DictionaryLoader;\n}): ValidationResult[] {\n const results: ValidationResult[] = [];\n\n if (params.loadDictionary && !params.dictionary) {\n results.push({\n type: 'error',\n message: createDiagnosticMessage({\n whatHappened: 'loadDictionary needs a source dictionary',\n fix: 'Provide dictionary so the default locale has source content',\n }),\n });\n }\n\n return results;\n}\n","import { ValidationResult } from './types';\nimport { I18nManagerConstructorParams } from '../types';\nimport { validateLoadTranslations } from './config-validation/validateLoadTranslations';\nimport { validateTranslationApi } from './config-validation/validateTranslationApi';\nimport { validateLocales } from './config-validation/validateLocales';\nimport { validateDictionary } from './config-validation/validateDictionary';\nimport type { Translation } from '../translations-manager/utils/types/translation-data';\n\n/**\n * Validate the configuration\n * @param config - The configuration to validate\n * @returns The validation results\n */\nexport function validateConfig<TranslationValue extends Translation>(\n config: I18nManagerConstructorParams<TranslationValue>\n): ValidationResult[] {\n const results: ValidationResult[] = [];\n\n results.push(...validateLoadTranslations(config));\n results.push(...validateTranslationApi(config));\n results.push(...validateLocales(config));\n results.push(...validateDictionary(config));\n\n return results;\n}\n","import type { RuntimeTranslateManyOptions } from 'generaltranslation/internal';\nimport type { Locale } from '../LocalesCache';\nimport type { TranslateMany } from '../TranslationsCache';\n\ntype TranslateManyClient = {\n translateMany(\n sources: Parameters<TranslateMany>[0],\n options: { targetLocale: string } & RuntimeTranslateManyOptions,\n timeout?: number\n ): ReturnType<TranslateMany>;\n};\n\n/**\n * CreateTranslateMany function type\n */\nexport type CreateTranslateMany = (locale: Locale) => TranslateMany;\n\n/**\n * Create a translate many function\n * @param locale - The locale\n * @returns The translate many function\n */\nexport function createTranslateManyFactory(\n gtInstance: TranslateManyClient,\n timeout?: number,\n metadata: RuntimeTranslateManyOptions = {}\n): CreateTranslateMany {\n return (locale) => (sources) =>\n gtInstance.translateMany(\n sources,\n { ...metadata, targetLocale: locale },\n timeout\n );\n}\n","import { resolveCanonicalLocale } from '@generaltranslation/format';\nimport { TranslationsLoader } from './types';\nimport { defaultCacheUrl } from 'generaltranslation/internal';\nimport { Translation } from '../utils/types/translation-data';\nimport type { CustomMapping } from '@generaltranslation/format/types';\n\n/**\n * Parameters for the createRemoteTranslationLoader function\n * @param cacheUrl - The cache url\n * @param projectId - The project id\n * @param _versionId - The version id\n * @param _branchId - The branch id\n */\nexport type CreateRemoteTranslationLoaderParams = {\n cacheUrl?: string;\n projectId: string;\n _versionId?: string;\n _branchId?: string;\n customMapping?: CustomMapping;\n};\n\n/**\n * Creates a translations loader function that loads translations from a remote store (CDN or other)\n * @param params - The parameters for the createRemoteTranslationLoader function\n * @returns A translations loader function\n *\n * TODO: validate projectId, cacheUrl, _versionId, _branchId\n */\nexport function createRemoteTranslationLoader(\n params: CreateRemoteTranslationLoaderParams\n): TranslationsLoader {\n // Get url\n const unlocalizedUrl = generateUrl(params);\n\n // define loader function (error handled by wrapper)\n const loader: TranslationsLoader = async (locale: string) => {\n // Standardize locale\n locale = resolveCanonicalLocale(locale, params.customMapping);\n const url = unlocalizedUrl.replace('[locale]', locale);\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to load translations from ${url}`);\n }\n return (await response.json()) as Record<string, Translation>;\n };\n\n return loader;\n}\n\n// ===== HELPER FUNCTIONS ===== //\n\n/**\n * Generate a URL for a translations file\n */\nfunction generateUrl(params: CreateRemoteTranslationLoaderParams): string {\n const {\n cacheUrl = defaultCacheUrl,\n projectId,\n _versionId,\n _branchId,\n } = params;\n\n // Generate version id segment and branch id query\n const versionIdSegment = _versionId ? `/${_versionId}` : '';\n const branchIdQuery = _branchId ? `?branchId=${_branchId}` : '';\n\n // Generate URL\n const url =\n `${cacheUrl}/${projectId}/[locale]` + versionIdSegment + branchIdQuery;\n\n return url;\n}\n","import { TranslationsLoader } from './types';\n\n/**\n * Creates a fallback translations loader function that loads translations from a fallback source\n * @returns A translations loader function\n */\nexport function createFallbackTranslationLoader(): TranslationsLoader {\n const loader: TranslationsLoader = async (_locale: string) => {\n return {};\n };\n\n return loader;\n}\n","import type { CustomMapping } from '@generaltranslation/format/types';\nimport { TranslationsLoader } from './types';\nimport { LoadTranslationsType } from '../../utils/getLoadTranslationsType';\nimport logger from '../../../logs/logger';\nimport { createRemoteTranslationLoader } from './createRemoteTranslationLoader';\nimport { createFallbackTranslationLoader } from './createFallbackTranslationLoader';\n\n/**\n * Creates a translation loader function that loads translations from a remote store (CDN or other)\n * @param params - The parameters for the createTranslationLoader function\n * @param params.type - The type of translation loader to create\n * @param params.remoteTranslationLoaderParams - The parameters for the remote translation loader\n * @param params.loadTranslations - The custom translations loader function\n * @returns A translation loader function\n */\nexport function routeCreateTranslationLoader({\n type,\n remoteTranslationLoaderParams,\n loadTranslations,\n}: {\n type: LoadTranslationsType;\n remoteTranslationLoaderParams: {\n cacheUrl?: string | null;\n projectId?: string;\n _versionId?: string;\n _branchId?: string;\n customMapping?: CustomMapping;\n };\n loadTranslations?: TranslationsLoader;\n}): TranslationsLoader {\n if (type === LoadTranslationsType.DISABLED) {\n // TODO: move this warning to validation layer\n logger.warn(\n 'I18nManager: No translation loader found. No translations will be loaded.'\n );\n }\n\n const { cacheUrl, projectId, _versionId, _branchId, customMapping } =\n remoteTranslationLoaderParams;\n\n switch (type) {\n case LoadTranslationsType.REMOTE:\n case LoadTranslationsType.GT_REMOTE:\n return createRemoteTranslationLoader({\n cacheUrl: cacheUrl as string | undefined,\n projectId: projectId || '',\n _versionId,\n _branchId,\n customMapping,\n });\n case LoadTranslationsType.CUSTOM:\n return loadTranslations!;\n case LoadTranslationsType.DISABLED:\n return createFallbackTranslationLoader();\n }\n}\n","import type {\n LifecycleCallback,\n LifecycleParam,\n} from '../lifecycle-hooks/types';\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (value == null || typeof value !== 'object') return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction copyCacheValue<CacheValue>(value: CacheValue): CacheValue {\n if (Array.isArray(value)) return [...value] as CacheValue;\n if (isPlainObject(value)) return { ...value } as CacheValue;\n return value;\n}\n\n/**\n * Cache class\n * This is designed in such a way that it is the responsibility of the client\n * to invoke the cache miss method when a cache miss occurs.\n *\n * TODO: maybe add \"OutputValue\" as a reflection of \"InputKey\"\n */\nabstract class Cache<\n InputKey,\n CacheKey extends string,\n CacheValue,\n OutputValue extends unknown,\n MissArgs extends [InputKey, ...unknown[]] = [InputKey],\n> {\n /**\n * Cache of items\n */\n private cache: Record<CacheKey, CacheValue> = {} as Record<\n CacheKey,\n CacheValue\n >;\n\n /**\n * Promise cache for inflight fallbacks\n */\n private fallbackPromises: Partial<Record<CacheKey, Promise<CacheValue>>> =\n {} as Record<CacheKey, Promise<CacheValue>>;\n\n /**\n * Lifecycle callbacks - invoked in implementation of the abstract methods\n * - onHit: invoked when a cache hit occurs\n * - onMiss: invoked when a cache miss occurs\n */\n protected onHit?: LifecycleCallback<\n InputKey,\n CacheKey,\n CacheValue,\n OutputValue\n >;\n protected onMiss?: LifecycleCallback<\n InputKey,\n CacheKey,\n CacheValue,\n OutputValue\n >;\n\n /**\n * Constructor\n * @param {Object} params - The parameters for the cache\n * @param {Record<CacheKey, CacheValue>} params.init - The initial cache\n * @param {CacheLifecycle} [lifecycle] - Optional lifecycle callbacks\n */\n constructor(\n init: Record<CacheKey, CacheValue>,\n lifecycle?: LifecycleParam<InputKey, CacheKey, CacheValue, OutputValue>\n ) {\n this.cache = structuredClone(init);\n this.onHit = lifecycle?.onHit;\n this.onMiss = lifecycle?.onMiss;\n }\n\n /**\n * Set the value for a key\n */\n protected setCache(cacheKey: CacheKey, value: CacheValue): void {\n this.cache[cacheKey] = value;\n }\n\n /**\n * Look up the key\n */\n protected getCache(key: InputKey): CacheValue | undefined {\n const cacheKey = this.genKey(key);\n return this.cache[cacheKey];\n }\n\n /**\n * Get the internal cache\n * @returns The internal cache\n *\n * @internal - used by gt-tanstack-start\n */\n public getInternalCache(): Record<CacheKey, CacheValue> {\n return Object.fromEntries(\n Object.entries(this.cache).map(([key, value]) => [\n key,\n copyCacheValue(value as CacheValue),\n ])\n ) as Record<CacheKey, CacheValue>;\n }\n\n /**\n * Get the mutable cache for subclasses that need custom read/write behavior.\n */\n protected getMutableCache(): Record<CacheKey, CacheValue> {\n return this.cache;\n }\n\n /**\n * Fallback to the value from the fallback function on a cache miss\n * @important assumes that the fallback error handling done upstream\n */\n protected async missCache(...args: MissArgs): Promise<CacheValue> {\n // Check for inflight fallback\n const key = args[0];\n const cacheKey = this.genKey(key);\n if (this.fallbackPromises[cacheKey] !== undefined) {\n return await this.fallbackPromises[cacheKey];\n }\n\n // Add to inflight fallback cache\n const fallbackPromise = this.fallback(...args);\n this.fallbackPromises[cacheKey] = fallbackPromise;\n\n // Wait for fallback to complete\n try {\n // Wait for fallback to complete\n const value = await fallbackPromise;\n\n // Update cache\n this.setCache(cacheKey, value);\n return value;\n } finally {\n delete this.fallbackPromises[cacheKey];\n }\n }\n\n // ===== Abstract Methods ===== //\n\n /**\n * Customizable helper function that calculates the cache key from an input key\n */\n protected abstract genKey(key: InputKey): CacheKey;\n\n /**\n * Get the fallback value for a cache miss\n */\n protected abstract fallback(...args: MissArgs): Promise<CacheValue>;\n\n /**\n * Lookup a value in the cache\n */\n public abstract get(key: InputKey): OutputValue | undefined;\n\n /**\n * Miss the cache\n */\n public abstract miss(...args: MissArgs): Promise<OutputValue>;\n}\n\nexport { Cache };\n","import { hashSource } from 'generaltranslation/id';\nimport { indexVars } from 'generaltranslation/internal';\nimport { LookupOptions } from '../translation-functions/types/options';\nimport { Translation } from '../types';\nimport type { IcuMessage } from '@generaltranslation/format/types';\n\n/**\n * Hash a message string\n */\nexport function hashMessage<T extends Translation>(\n message: T,\n options: LookupOptions\n): string {\n const metadataOptions = options as {\n $_hash?: string;\n $context?: string;\n $id?: string;\n $maxChars?: number;\n };\n if (metadataOptions.$_hash != null) {\n return metadataOptions.$_hash;\n }\n\n return hashSource({\n source:\n options.$format === 'ICU' ? indexVars(message as IcuMessage) : message,\n ...(metadataOptions.$context && { context: metadataOptions.$context }),\n ...(metadataOptions.$id && { id: metadataOptions.$id }),\n ...(metadataOptions.$maxChars != null && {\n maxChars: Math.abs(metadataOptions.$maxChars),\n }),\n dataFormat: options.$format,\n });\n}\n","import { LookupOptions } from '../../translation-functions/types/options';\nimport { Cache } from './Cache';\nimport type { LifecycleParam } from '../lifecycle-hooks/types';\nimport { Translation } from './utils/types/translation-data';\nimport { hashMessage } from '../../utils/hashMessage';\nimport type { Content } from '@generaltranslation/format/types';\nimport type {\n EntryMetadata,\n TranslateManyEntry,\n TranslationResult,\n} from 'generaltranslation/types';\n\n// See gt-next\nconst MAX_BATCH_SIZE = 25;\nconst MAX_CONCURRENT_REQUESTS = 100;\nconst BATCH_INTERVAL = 50;\n\nexport type TranslationBatchConfig = {\n maxConcurrentRequests?: number;\n maxBatchSize?: number;\n batchInterval?: number;\n};\n\nconst DEFAULT_BATCH_CONFIG: Required<TranslationBatchConfig> = {\n maxConcurrentRequests: MAX_CONCURRENT_REQUESTS,\n maxBatchSize: MAX_BATCH_SIZE,\n batchInterval: BATCH_INTERVAL,\n};\n\nfunction getPositiveValue(value: number | undefined, defaultValue: number) {\n if (value === undefined || !Number.isFinite(value) || value <= 0) {\n return defaultValue;\n }\n return value;\n}\n\nfunction getPositiveInteger(value: number | undefined, defaultValue: number) {\n if (value === undefined || !Number.isFinite(value)) return defaultValue;\n const integer = Math.trunc(value);\n return integer > 0 ? integer : defaultValue;\n}\n\nfunction normalizeBatchConfig(\n batchConfig?: TranslationBatchConfig\n): Required<TranslationBatchConfig> {\n return {\n maxConcurrentRequests: getPositiveInteger(\n batchConfig?.maxConcurrentRequests,\n DEFAULT_BATCH_CONFIG.maxConcurrentRequests\n ),\n maxBatchSize: getPositiveInteger(\n batchConfig?.maxBatchSize,\n DEFAULT_BATCH_CONFIG.maxBatchSize\n ),\n batchInterval: getPositiveValue(\n batchConfig?.batchInterval,\n DEFAULT_BATCH_CONFIG.batchInterval\n ),\n };\n}\n\n/**\n * InputKey type for lookups\n * @typedef {Object} TranslationKey\n * @property {TranslationValue} message - The message from the source\n * @property {LookupOptions} options - The options for the translation\n */\nexport type TranslationKey<TranslationValue extends Translation> = {\n message: TranslationValue;\n options: LookupOptions;\n};\n\n/**\n * Just a way to be more explicit about what \"hash\" is\n */\nexport type Hash = string;\n\n/**\n * A queue entry for batching, used to also handle reject and resolve\n */\ntype QueueEntry<TranslationValue extends Translation> = {\n key: Hash;\n source: TranslationValue;\n metadata: EntryMetadata;\n resolve: (value: Translation) => void;\n reject: (reason?: unknown) => void;\n};\n\n/**\n * TranslateMany call signature\n */\nexport type TranslateMany = (\n sources: Record<Hash, TranslateManyEntry>\n) => Promise<Record<string, TranslationResult>>;\n\n/**\n * A cache for a single locale's translations\n *\n * Principles:\n * - This class is language agnostic, and should never store the locale code as a parameter.\n * Locale logic is handled at the LocalesCache level. Use a callback function that has the\n * locale parameter embedded if you wish to use the locale code.\n */\nexport class TranslationsCache<\n TranslationValue extends Translation,\n> extends Cache<\n TranslationKey<TranslationValue>,\n Hash,\n TranslationValue,\n TranslationValue\n> {\n /**\n * Queue of translation requests\n */\n private _queue: Array<QueueEntry<TranslationValue>> = [];\n\n /**\n * Timer for batching\n */\n private _batchTimer: ReturnType<typeof setTimeout> | null = null;\n\n /**\n * Number of active requests\n */\n private _activeRequests = 0;\n\n private _batchConfig: Required<TranslationBatchConfig>;\n\n /**\n * Translate many function\n */\n private _translateMany: TranslateMany;\n\n /**\n * Constructor\n * @param {Object} params - The parameters for the cache\n * @param {Record<Hash, TranslationValue>} params.init - The initial cache\n * @param {Function} params.fallback - Get the fallback value for a cache miss\n */\n constructor({\n init,\n translateMany,\n lifecycle,\n batchConfig,\n }: {\n init: Record<Hash, TranslationValue>;\n translateMany: TranslateMany;\n batchConfig?: TranslationBatchConfig;\n lifecycle: LifecycleParam<\n TranslationKey<TranslationValue>,\n Hash,\n TranslationValue,\n TranslationValue\n >;\n }) {\n super(init, lifecycle);\n this._translateMany = translateMany;\n this._batchConfig = normalizeBatchConfig(batchConfig);\n }\n\n /**\n * Get the translation value for a given key\n * @param key - The translation key\n * @returns The translation value\n */\n public get<T extends TranslationValue>(\n key: TranslationKey<T>\n ): T | undefined {\n const value = this.getCache(key) as T | undefined;\n if (value != null && this.onHit) {\n this.onHit({\n inputKey: key,\n cacheKey: this.genKey(key),\n cacheValue: value,\n outputValue: value,\n });\n }\n return value;\n }\n\n /**\n * Miss the cache\n * @param key - The translation key\n * @returns The translation value\n */\n public async miss<T extends TranslationValue>(\n key: TranslationKey<T>\n ): Promise<T> {\n const value = await this.missCache(key);\n if (value != null && this.onMiss) {\n this.onMiss({\n inputKey: key,\n cacheKey: this.genKey(key),\n cacheValue: value,\n outputValue: value,\n });\n }\n return value as T;\n }\n\n /**\n * Generate a key for the cache\n * @param key - The translation key\n * @returns The key\n */\n protected genKey(key: TranslationKey<TranslationValue>): Hash {\n return hashMessage(key.message, key.options);\n }\n\n /**\n * Get the fallback value for a cache miss\n * @param key - The translation key\n * @returns The fallback value\n */\n protected fallback(\n key: TranslationKey<TranslationValue>\n ): Promise<TranslationValue> {\n // Add translation request to queue\n const translationPromise = this._enqueueTranslation(key);\n\n // If batch is full, flush now\n if (this._queue.length >= this._batchConfig.maxBatchSize) {\n this._flushNow();\n } else {\n this._scheduleBatch();\n }\n\n return translationPromise;\n }\n\n // ===== PRIVATE METHODS ===== //\n\n // --- QUEUE MANAGEMENT --- //\n\n /**\n * Flush the queue now\n */\n private _flushNow(): void {\n if (this._batchTimer) {\n clearTimeout(this._batchTimer);\n this._batchTimer = null;\n }\n this._drainQueue();\n }\n\n /**\n * Schedule a batch of translations\n */\n private _scheduleBatch(): void {\n if (this._batchTimer) return; // already scheduled\n this._batchTimer = setTimeout(() => {\n this._batchTimer = null;\n this._drainQueue();\n }, this._batchConfig.batchInterval);\n }\n\n /**\n * Drain the queue\n */\n private _drainQueue(): void {\n while (\n this._queue.length > 0 &&\n this._activeRequests < this._batchConfig.maxConcurrentRequests\n ) {\n const batch = this._queue.splice(0, this._batchConfig.maxBatchSize);\n this._sendBatchRequest(batch);\n }\n // If items remain (hit concurrency limit), schedule again\n if (this._queue.length > 0) {\n this._scheduleBatch();\n }\n }\n\n /**\n * Enqueue translation request and return a promise that resolves when the translation is ready\n * @param {TranslationKey<TranslationValue>} key - The translation key\n * @returns {Promise<TranslationValue>} The translation promise\n */\n private _enqueueTranslation(\n key: TranslationKey<TranslationValue>\n ): Promise<TranslationValue> {\n const hash = this.genKey(key);\n const options = key.options;\n const metadataOptions = options as {\n $context?: string;\n $id?: string;\n $maxChars?: number;\n };\n return new Promise<TranslationValue>((resolve, reject) => {\n this._queue.push({\n key: hash,\n source: key.message,\n metadata: {\n hash,\n ...(metadataOptions.$context && {\n context: metadataOptions.$context,\n }),\n ...(metadataOptions.$id && { id: metadataOptions.$id }),\n ...(metadataOptions.$maxChars != null && {\n maxChars: Math.abs(metadataOptions.$maxChars),\n }),\n dataFormat: options.$format,\n },\n resolve: (value) => resolve(value as TranslationValue),\n reject,\n });\n });\n }\n\n // --- SEND REQUESTS --- //\n\n /**\n * Send a batch request for translations\n * @param {QueueEntry<TranslationValue>[]} batch - The batch of requests to send\n */\n private async _sendBatchRequest(\n batch: QueueEntry<TranslationValue>[]\n ): Promise<void> {\n this._activeRequests++;\n\n const requests = convertBatchToTranslateManyParams(batch);\n const response = await this._sendBatchRequestWithErrorHandling(\n batch,\n requests\n );\n if (response) {\n this._handleTranslationResponse(batch, response);\n }\n\n this._activeRequests--;\n }\n\n /**\n * Send a translation request with error handling\n */\n private async _sendBatchRequestWithErrorHandling(\n batch: QueueEntry<TranslationValue>[],\n requests: Record<Hash, TranslateManyEntry>\n ): Promise<ReturnType<TranslateMany> | undefined> {\n try {\n return await this._translateMany(requests);\n } catch (error) {\n for (const entry of batch) {\n entry.reject(error);\n }\n return undefined;\n }\n }\n\n /**\n * Handle a translation response\n */\n private _handleTranslationResponse(\n batch: QueueEntry<TranslationValue>[],\n response: Awaited<ReturnType<TranslateMany>>\n ): void {\n for (const entry of batch) {\n const { key } = entry;\n const result = response[key];\n if (result && result.success) {\n const translation = result.translation as TranslationValue;\n this.setCache(key, translation);\n entry.resolve(translation);\n } else {\n entry.reject(result?.error);\n }\n }\n }\n}\n\n/**\n * Convert a TranslationKey to a TranslateManyEntry\n */\nfunction convertBatchToTranslateManyParams<\n TranslationValue extends Translation,\n>(batch: QueueEntry<TranslationValue>[]): Record<Hash, TranslateManyEntry> {\n return batch.reduce<Record<Hash, TranslateManyEntry>>((acc, entry) => {\n acc[entry.key] = {\n source: entry.source as Content,\n metadata: entry.metadata,\n };\n return acc;\n }, {});\n}\n","/**\n * Default cache expiry time in milliseconds\n */\nexport const DEFAULT_CACHE_EXPIRY_TIME = 60_000; // 60 sec\n","import { Cache } from './Cache';\nimport { Hash, TranslationKey, TranslationsCache } from './TranslationsCache';\nimport type { TranslationBatchConfig } from './TranslationsCache';\nimport { Translation } from './utils/types/translation-data';\nimport { DEFAULT_CACHE_EXPIRY_TIME } from './utils/constants';\nimport { CreateTranslateMany } from './utils/createTranslateMany';\nimport type {\n LifecycleParam,\n LocalesCacheLifecycleCallbacks,\n TranslationsCacheLifecycleCallback,\n} from '../lifecycle-hooks/types';\n\n/**\n * Just being explicit about the purpose of this type\n */\nexport type Locale = string;\n\n/**\n * Cache entry\n * @typedef {Object} CacheEntry\n * @property {number} expiresAt - The time at which the cache entry expires.\n * @property {TranslationsCache<TranslationValue>} translationsCache - The translations cache for the locale.\n */\nexport type CacheEntry<TranslationValue extends Translation> = {\n expiresAt: number;\n translationsCache: TranslationsCache<TranslationValue>;\n};\n\n/**\n * Safe translations loader function type\n * @returns A promise that resolves to a mapping of strings to {@link Translation}\n * TODO: rename this because we are no longer doing try/catch around the translation loader\n */\nexport type SafeTranslationsLoader<TranslationValue extends Translation> = (\n locale: string\n) => Promise<Record<Hash, TranslationValue>>;\n\n/**\n * Cache for looking up translations by locale\n */\nexport class LocalesCache<TranslationValue extends Translation> extends Cache<\n Locale,\n Locale,\n CacheEntry<TranslationValue>,\n CacheEntry<TranslationValue>['translationsCache']\n> {\n /**\n * Translation loader function\n */\n private _translationLoader: SafeTranslationsLoader<TranslationValue>;\n\n /**\n * Translate many function\n */\n private _createTranslateMany: CreateTranslateMany;\n\n /**\n * Time to live for cache entries\n */\n private ttl: number = DEFAULT_CACHE_EXPIRY_TIME;\n\n private _batchConfig?: TranslationBatchConfig;\n\n /**\n * Translations cache lifecycle callbacks (locale embedded)\n */\n private _onTranslationsCacheHit?: TranslationsCacheLifecycleCallback<TranslationValue>;\n private _onTranslationsCacheMiss?: TranslationsCacheLifecycleCallback<TranslationValue>;\n\n /**\n * Constructor\n * @param {Object} params - The parameters for the cache\n * @param {Record<string, CacheEntry<TranslationValue>>} params.init - The initial cache\n * @param {number | null} params.ttl - The time to live for cache entries\n * @param {SafeTranslationsLoader<TranslationValue>} params.loadTranslations - The translation loader function\n * @param {CreateTranslateMany} params.createTranslateMany - Factory function for creating a translate many function\n */\n constructor({\n init = {},\n ttl,\n batchConfig,\n loadTranslations,\n createTranslateMany,\n lifecycle: {\n onLocalesCacheHit: onHit,\n onLocalesCacheMiss: onMiss,\n onTranslationsCacheHit,\n onTranslationsCacheMiss,\n },\n }: {\n init?: Record<string, CacheEntry<TranslationValue>>;\n ttl?: number | null;\n batchConfig?: TranslationBatchConfig;\n createTranslateMany: CreateTranslateMany;\n loadTranslations: SafeTranslationsLoader<TranslationValue>;\n lifecycle: LocalesCacheLifecycleCallbacks<TranslationValue>;\n }) {\n super(init, { onHit, onMiss });\n\n // Set time to live\n this.ttl = ttl === null ? -1 : (ttl ?? DEFAULT_CACHE_EXPIRY_TIME);\n\n this._translationLoader = loadTranslations;\n this._createTranslateMany = createTranslateMany;\n this._batchConfig = batchConfig;\n this._onTranslationsCacheHit = onTranslationsCacheHit;\n this._onTranslationsCacheMiss = onTranslationsCacheMiss;\n }\n\n /**\n * Get the translations for a given locale\n * @param key - The locale\n * @returns The translations\n */\n public get(\n key: Locale\n ): CacheEntry<TranslationValue>['translationsCache'] | undefined {\n // Get the cache entry\n const entry = this.getCache(key);\n if (!entry || (entry.expiresAt > 0 && entry.expiresAt < Date.now())) {\n return undefined;\n }\n const value = entry.translationsCache;\n\n // Life cycle callback\n if (value != null && this.onHit) {\n this.onHit({\n inputKey: key,\n cacheKey: this.genKey(key),\n cacheValue: entry,\n outputValue: value,\n });\n }\n\n return value;\n }\n\n /**\n * Miss the cache\n * @param key - The locale\n * @returns The translations cache\n */\n public async miss(\n key: Locale\n ): Promise<CacheEntry<TranslationValue>['translationsCache']> {\n // Miss the cache\n const cacheValue = await this.missCache(key);\n\n // Life cycle callback\n const value = cacheValue.translationsCache;\n if (value != null && this.onMiss) {\n this.onMiss({\n inputKey: key,\n cacheKey: this.genKey(key),\n cacheValue: cacheValue,\n outputValue: value,\n });\n }\n\n return value;\n }\n\n /**\n * Generate the cache key for a given locale\n * @param key - The locale\n * @returns The cache key\n *\n * This is just an identity function, no transformation needed\n */\n protected genKey(key: Locale): Locale {\n return key;\n }\n\n /**\n * Fallback for a cache miss\n * @param locale - The locale\n * @returns The cache entry\n */\n protected async fallback(\n locale: Locale\n ): Promise<CacheEntry<TranslationValue>> {\n // Fetch translations\n const translationsPromise = this._translationLoader(locale);\n\n // Cache the translations and expiry timestamp\n const translationsCache = new TranslationsCache<TranslationValue>({\n init: await translationsPromise,\n lifecycle: this._createTranslationsCacheLifecycle(locale),\n translateMany: this._createTranslateMany(locale),\n batchConfig: this._batchConfig,\n });\n const expiresAt = this.ttl < 0 ? this.ttl : Date.now() + this.ttl;\n\n return { translationsCache, expiresAt };\n }\n\n // ===== PRIVATE METHODS ===== //\n\n /**\n * Create the translations cache lifecycle\n * @param locale - The locale\n * @returns The translations cache lifecycle\n */\n private _createTranslationsCacheLifecycle(\n locale: Locale\n ): LifecycleParam<\n TranslationKey<TranslationValue>,\n Hash,\n TranslationValue,\n TranslationValue\n > {\n return {\n onHit: this._onTranslationsCacheHit\n ? (params) =>\n this._onTranslationsCacheHit!({\n locale,\n ...params,\n })\n : undefined,\n onMiss: this._onTranslationsCacheMiss\n ? (params) =>\n this._onTranslationsCacheMiss!({\n locale,\n ...params,\n })\n : undefined,\n };\n }\n}\n","import type {\n Dictionary,\n DictionaryEntry,\n DictionaryLeaf,\n DictionaryPath,\n DictionaryValue,\n} from './types/dictionary';\nimport type {\n DictionaryLookupOptions,\n DictionaryOptions,\n} from '../../../translation-functions/types/options';\n\nexport function getDictionaryPath(id: DictionaryPath): string[] {\n if (!id) {\n return [];\n }\n return id.split('.');\n}\n\nexport function isDictionaryValue(value: unknown): value is Dictionary {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n}\n\nexport function getDictionaryEntry(\n value: DictionaryValue | undefined\n): DictionaryEntry | undefined {\n if (!isDictionaryLeafNode(value)) {\n return undefined;\n }\n return {\n entry: Array.isArray(value) ? value[0] : value,\n options: Array.isArray(value) ? (value[1] ?? {}) : {},\n };\n}\n\nexport function getDictionaryValue(value: DictionaryEntry): DictionaryValue {\n if (Object.keys(value.options).length === 0) {\n return value.entry;\n }\n return [value.entry, value.options];\n}\n\nexport function resolveDictionaryLookupOptions(\n options: DictionaryEntry['options']\n): DictionaryLookupOptions {\n const { $format, ...rest } = options;\n return {\n ...rest,\n $format: isStringFormat($format) ? $format : 'ICU',\n ...(rest.$context === undefined &&\n typeof rest.context === 'string' && { $context: rest.context }),\n };\n}\n\nfunction isDictionaryLeafNode(value: unknown): value is DictionaryLeaf {\n if (typeof value === 'string') {\n return true;\n }\n if (!Array.isArray(value) || typeof value[0] !== 'string') {\n return false;\n }\n if (value.length === 1) {\n return true;\n }\n return value.length === 2 && isDictionaryOptions(value[1]);\n}\n\nexport function isDictionaryEntry(value: unknown): value is DictionaryEntry {\n if (!isDictionaryValue(value)) {\n return false;\n }\n\n return typeof value.entry === 'string' && isDictionaryOptions(value.options);\n}\n\nfunction isDictionaryOptions(value: unknown): value is DictionaryOptions {\n if (typeof value !== 'object' || value == null || Array.isArray(value)) {\n return false;\n }\n\n const options = value as Record<string, unknown>;\n return (\n (options.$context === undefined || typeof options.$context === 'string') &&\n (options.$format === undefined || isStringFormat(options.$format)) &&\n (options.$maxChars === undefined ||\n typeof options.$maxChars === 'number') &&\n (options.context === undefined || typeof options.context === 'string')\n );\n}\n\nfunction isStringFormat(\n value: unknown\n): value is DictionaryLookupOptions['$format'] {\n return value === 'ICU' || value === 'I18NEXT' || value === 'STRING';\n}\n\nexport function replaceDictionary(\n target: Dictionary,\n source: Dictionary\n): void {\n for (const key of Object.keys(target)) {\n delete target[key];\n }\n Object.assign(target, source);\n}\n","export class DictionarySourceNotFoundError extends Error {\n constructor(id: string) {\n super(`I18nManager: source dictionary entry ${id} is not defined`);\n this.name = 'DictionarySourceNotFoundError';\n }\n}\n","import { Cache } from './Cache';\nimport {\n getDictionaryEntry,\n getDictionaryPath,\n getDictionaryValue,\n isDictionaryValue,\n replaceDictionary,\n} from './utils/dictionary-helpers';\nimport type {\n LifecycleCallback,\n LifecycleParam,\n} from '../lifecycle-hooks/types';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryPath,\n DictionaryValue,\n} from './utils/types/dictionary';\nimport { DictionarySourceNotFoundError } from './utils/DictionarySourceNotFoundError';\nexport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryLeaf,\n DictionaryObject,\n DictionaryOptions,\n DictionaryPath,\n DictionaryValue,\n} from './utils/types/dictionary';\n\nexport type DictionaryRuntimeTranslate = (\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n) => Promise<string>;\n\nexport type DictionaryObjectLifecycleParam = {\n onHitObj?: LifecycleCallback<\n DictionaryKey,\n DictionaryPath,\n DictionaryValue,\n DictionaryValue\n >;\n onMissObj?: LifecycleCallback<\n DictionaryKey,\n DictionaryPath,\n DictionaryValue,\n DictionaryValue\n >;\n};\n\n/**\n * A cache for a single locale's dictionary\n *\n * Principles:\n * - This class is language agnostic, and should never store the locale code as a parameter.\n * Locale logic is handled at the LocalesDictionaryCache level. Use a callback function\n * that has the locale parameter embedded if you wish to use the locale code.\n */\nexport class DictionaryCache extends Cache<\n DictionaryKey,\n DictionaryPath,\n DictionaryValue,\n DictionaryEntry,\n [DictionaryKey, DictionaryEntry]\n> {\n private _runtimeTranslate: DictionaryRuntimeTranslate;\n private onHitObj?: DictionaryObjectLifecycleParam['onHitObj'];\n // TODO: Wire this when object miss handling is introduced.\n private onMissObj?: DictionaryObjectLifecycleParam['onMissObj'];\n\n /**\n * Constructor\n * @param {Object} params - The parameters for the cache\n * @param {Dictionary} params.init - The initial cache\n */\n constructor({\n init,\n lifecycle,\n runtimeTranslate,\n }: {\n init: Dictionary;\n runtimeTranslate: DictionaryRuntimeTranslate;\n lifecycle?: LifecycleParam<\n DictionaryKey,\n DictionaryPath,\n DictionaryValue,\n DictionaryEntry\n > &\n DictionaryObjectLifecycleParam;\n }) {\n super(init, lifecycle);\n this._runtimeTranslate = runtimeTranslate;\n this.onHitObj = lifecycle?.onHitObj;\n this.onMissObj = lifecycle?.onMissObj;\n }\n\n /**\n * Get the dictionary value for a given key\n * @param key - The dictionary key\n * @returns The dictionary value\n */\n public get(key: DictionaryKey): DictionaryEntry | undefined {\n const value = this.getCache(key);\n const entry = getDictionaryEntry(value);\n if (entry === undefined) {\n return undefined;\n }\n\n if (this.onHit) {\n this.onHit({\n inputKey: key,\n cacheKey: this.genKey(key),\n cacheValue: value as DictionaryValue,\n outputValue: entry,\n });\n }\n return entry;\n }\n\n public set(key: DictionaryKey, value: DictionaryEntry): void {\n const dictionaryValue = getDictionaryValue(value);\n this.setCache(this.genKey(key), dictionaryValue);\n }\n\n public getObj(key: DictionaryKey): DictionaryValue | undefined {\n const value = this.getCache(key);\n if (value === undefined) {\n return undefined;\n }\n const outputValue = structuredClone(value);\n\n if (this.onHitObj) {\n this.onHitObj({\n inputKey: key,\n cacheKey: this.genKey(key),\n cacheValue: value as DictionaryValue,\n outputValue,\n });\n }\n return outputValue;\n }\n\n public setObj(key: DictionaryKey, value: DictionaryValue): void {\n this.setCache(this.genKey(key), structuredClone(value));\n }\n\n public async missObj(\n key: DictionaryKey,\n sourceObject: DictionaryValue\n ): Promise<DictionaryValue> {\n const sourceEntry = getDictionaryEntry(sourceObject);\n if (sourceEntry !== undefined) {\n const entry = await this.miss(key, sourceEntry);\n return getDictionaryValue(entry);\n }\n\n if (!isDictionaryValue(sourceObject)) {\n throw new DictionarySourceNotFoundError(key);\n }\n\n const translatedEntries = await Promise.all(\n Object.entries(sourceObject).map(async ([childKey, childSource]) => {\n const childPath = key ? `${key}.${childKey}` : childKey;\n return [childKey, await this.missObj(childPath, childSource)] as const;\n })\n );\n const translatedObject = Object.fromEntries(\n translatedEntries\n ) as Dictionary;\n this.setObj(key, translatedObject);\n return translatedObject;\n }\n\n /**\n * Miss the cache\n * @param key - The dictionary key\n * @returns The dictionary value\n */\n public async miss(\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n ): Promise<DictionaryEntry> {\n const value = await this.missCache(key, sourceEntry);\n const entry = getDictionaryEntry(value);\n if (entry === undefined) {\n // Never will happen\n throw new Error(\n 'DictionaryCache missCache did not return a DictionaryEntry'\n );\n }\n if (this.onMiss) {\n this.onMiss({\n inputKey: key,\n cacheKey: this.genKey(key),\n cacheValue: value,\n outputValue: entry,\n });\n }\n return entry;\n }\n\n /**\n * Set the value for a key\n */\n protected setCache(cacheKey: DictionaryPath, value: DictionaryValue): void {\n const cache = this.getMutableCache() as Dictionary;\n const dictionaryPath = getDictionaryPath(cacheKey);\n\n if (dictionaryPath.length === 0) {\n if (isDictionaryValue(value)) {\n replaceDictionary(cache, value);\n }\n return;\n }\n\n let current = cache;\n for (const key of dictionaryPath.slice(0, -1)) {\n const next = current[key];\n if (!isDictionaryValue(next)) {\n current[key] = {};\n }\n current = current[key] as Dictionary;\n }\n\n current[dictionaryPath[dictionaryPath.length - 1]] = value;\n }\n\n /**\n * Look up the key\n */\n protected getCache(key: DictionaryKey): DictionaryValue | undefined {\n const dictionaryPath = getDictionaryPath(this.genKey(key));\n let current: DictionaryValue = this.getMutableCache() as Dictionary;\n\n if (dictionaryPath.length === 0) {\n return current;\n }\n\n for (const pathSegment of dictionaryPath) {\n if (!isDictionaryValue(current)) {\n return undefined;\n }\n current = current[pathSegment];\n }\n\n return current;\n }\n\n /**\n * Generate a key for the cache\n * @param key - The dictionary key\n * @returns The key\n */\n protected genKey(key: DictionaryKey): DictionaryPath {\n return key;\n }\n\n /**\n * Get the fallback value for a cache miss\n * @param key - The dictionary key\n * @returns The fallback value\n *\n * @throws {Error} - If the fallback is not implemented\n */\n protected fallback(\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n ): Promise<DictionaryValue> {\n return this._runtimeTranslate(key, sourceEntry);\n }\n}\n","import { Cache } from './Cache';\nimport { DictionaryCache } from './DictionaryCache';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryObjectLifecycleParam,\n DictionaryPath,\n DictionaryRuntimeTranslate,\n DictionaryValue,\n} from './DictionaryCache';\nimport { DEFAULT_CACHE_EXPIRY_TIME } from './utils/constants';\nimport type {\n DictionaryCacheLifecycleCallback,\n DictionaryObjectCacheLifecycleCallback,\n LocalesDictionaryCacheLifecycleCallbacks,\n LifecycleParam,\n} from '../lifecycle-hooks/types';\nimport type { Locale } from './LocalesCache';\n\n/**\n * Cache entry\n * @typedef {Object} DictionaryCacheEntry\n * @property {number} expiresAt - The time at which the cache entry expires.\n * @property {DictionaryCache} dictionaryCache - The dictionary cache for the locale.\n */\nexport type DictionaryCacheEntry = {\n expiresAt: number;\n dictionaryCache: DictionaryCache;\n};\n\n/**\n * Dictionary loader function type\n */\nexport type DictionaryLoader = (locale: string) => Promise<Dictionary>;\n\nexport type LocalesDictionaryRuntimeTranslate = (\n locale: Locale,\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n) => Promise<string>;\n\n/**\n * Cache for looking up dictionaries by locale\n */\nexport class LocalesDictionaryCache extends Cache<\n Locale,\n Locale,\n DictionaryCacheEntry,\n DictionaryCacheEntry['dictionaryCache']\n> {\n /**\n * Dictionary loader function\n */\n private _dictionaryLoader: DictionaryLoader;\n\n private _runtimeTranslate: LocalesDictionaryRuntimeTranslate;\n\n /**\n * Time to live for cache entries\n */\n private ttl: number = DEFAULT_CACHE_EXPIRY_TIME;\n\n /**\n * Dictionary cache lifecycle callbacks (locale embedded)\n */\n private _onDictionaryCacheHit?: DictionaryCacheLifecycleCallback;\n private _onDictionaryCacheMiss?: DictionaryCacheLifecycleCallback;\n private _onDictionaryObjectCacheHit?: DictionaryObjectCacheLifecycleCallback;\n\n /**\n * Constructor\n * @param {Object} params - The parameters for the cache\n * @param {number | null} params.ttl - The time to live for cache entries\n * @param {DictionaryLoader} params.loadDictionary - The dictionary loader function\n */\n constructor({\n ttl,\n defaultLocale,\n dictionary = {},\n loadDictionary,\n runtimeTranslate,\n lifecycle: {\n onLocalesDictionaryCacheHit: onHit,\n onLocalesDictionaryCacheMiss: onMiss,\n onDictionaryCacheHit,\n onDictionaryCacheMiss,\n onDictionaryObjectCacheHit,\n },\n }: {\n ttl?: number | null;\n defaultLocale: Locale;\n dictionary?: Dictionary;\n loadDictionary: DictionaryLoader;\n runtimeTranslate: LocalesDictionaryRuntimeTranslate;\n lifecycle: LocalesDictionaryCacheLifecycleCallbacks;\n }) {\n super({}, { onHit, onMiss });\n\n // Set time to live\n this.ttl = ttl === null ? -1 : (ttl ?? DEFAULT_CACHE_EXPIRY_TIME);\n\n this._dictionaryLoader = loadDictionary;\n this._runtimeTranslate = runtimeTranslate;\n this._onDictionaryCacheHit = onDictionaryCacheHit;\n this._onDictionaryCacheMiss = onDictionaryCacheMiss;\n this._onDictionaryObjectCacheHit = onDictionaryObjectCacheHit;\n\n // The default locale dictionary is always available.\n this.setCache(defaultLocale, {\n dictionaryCache: new DictionaryCache({\n init: dictionary,\n runtimeTranslate: this._createDictionaryRuntimeTranslate(defaultLocale),\n lifecycle: this._createDictionaryCacheLifecycle(defaultLocale),\n }),\n expiresAt: -1,\n });\n }\n\n /**\n * Get the dictionary for a given locale\n * @param key - The locale\n * @returns The dictionary\n */\n public get(key: Locale): DictionaryCacheEntry['dictionaryCache'] | undefined {\n // Get the cache entry\n const entry = this.getCache(key);\n if (!entry || (entry.expiresAt > 0 && entry.expiresAt < Date.now())) {\n return undefined;\n }\n const value = entry.dictionaryCache;\n\n // Life cycle callback\n if (value != null && this.onHit) {\n this.onHit({\n inputKey: key,\n cacheKey: this.genKey(key),\n cacheValue: entry,\n outputValue: value,\n });\n }\n\n return value;\n }\n\n /**\n * Miss the cache\n * @param key - The locale\n * @returns The dictionary cache\n */\n public async miss(\n key: Locale\n ): Promise<DictionaryCacheEntry['dictionaryCache']> {\n // Miss the cache\n const cacheValue = await this.missCache(key);\n\n // Life cycle callback\n const value = cacheValue.dictionaryCache;\n if (value != null && this.onMiss) {\n this.onMiss({\n inputKey: key,\n cacheKey: this.genKey(key),\n cacheValue: cacheValue,\n outputValue: value,\n });\n }\n\n return value;\n }\n\n /**\n * Generate the cache key for a given locale\n * @param key - The locale\n * @returns The cache key\n *\n * This is just an identity function, no transformation needed\n */\n protected genKey(key: Locale): Locale {\n return key;\n }\n\n /**\n * Fallback for a cache miss\n * @param locale - The locale\n * @returns The cache entry\n */\n protected async fallback(locale: Locale): Promise<DictionaryCacheEntry> {\n // Fetch dictionary\n const dictionaryPromise = this._dictionaryLoader(locale);\n\n // Cache the dictionary and expiry timestamp\n const dictionaryCache = new DictionaryCache({\n init: await dictionaryPromise,\n runtimeTranslate: this._createDictionaryRuntimeTranslate(locale),\n lifecycle: this._createDictionaryCacheLifecycle(locale),\n });\n const expiresAt = this.ttl < 0 ? this.ttl : Date.now() + this.ttl;\n\n return { dictionaryCache, expiresAt };\n }\n\n // ===== PRIVATE METHODS ===== //\n\n /**\n * Create the dictionary cache lifecycle\n * @param locale - The locale\n * @returns The dictionary cache lifecycle\n */\n private _createDictionaryCacheLifecycle(\n locale: Locale\n ): LifecycleParam<\n DictionaryKey,\n DictionaryPath,\n DictionaryValue,\n DictionaryEntry\n > &\n DictionaryObjectLifecycleParam {\n return {\n onHit: this._onDictionaryCacheHit\n ? (params) =>\n this._onDictionaryCacheHit!({\n locale,\n ...params,\n })\n : undefined,\n onMiss: this._onDictionaryCacheMiss\n ? (params) =>\n this._onDictionaryCacheMiss!({\n locale,\n ...params,\n })\n : undefined,\n onHitObj: this._onDictionaryObjectCacheHit\n ? (params) =>\n this._onDictionaryObjectCacheHit!({\n locale,\n ...params,\n })\n : undefined,\n };\n }\n\n private _createDictionaryRuntimeTranslate(\n locale: Locale\n ): DictionaryRuntimeTranslate {\n return (key, sourceEntry) =>\n this._runtimeTranslate(locale, key, sourceEntry);\n }\n}\n","import type { Translation } from '../translations-manager/utils/types/translation-data';\nimport type { Hash } from '../translations-manager/TranslationsCache';\nimport type { Locale } from '../translations-manager/LocalesCache';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryPath,\n DictionaryValue,\n} from '../translations-manager/DictionaryCache';\n\nexport type EventName = string;\n\nexport type BaseEvent = Record<EventName, unknown>;\n\nexport type Listener<\n Events extends BaseEvent,\n EventName extends keyof Events = keyof Events,\n> = (event: Events[EventName]) => void;\n\nexport type ListenerStore<Events extends BaseEvent> = Partial<{\n [EventName in keyof Events]: Set<Listener<Events, EventName>>;\n}>;\n\nexport const LOCALES_CACHE_MISS_EVENT_NAME = 'locales-cache-miss';\nexport const TRANSLATIONS_CACHE_MISS_EVENT_NAME = 'translations-cache-miss';\nexport const LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME =\n 'locales-dictionary-cache-miss';\nexport const DICTIONARY_CACHE_MISS_EVENT_NAME = 'dictionary-cache-miss';\n\n/**\n * A base event for the I18nManagers\n * @prop {locales-cache-hit} - Emitted when a locale cache hit occurs\n * @prop {locales-cache-miss} - Emitted when a locale cache miss occurs\n * @prop {translations-cache-hit} - Emitted when a translations cache hit occurs\n * @prop {translations-cache-miss} - Emitted when a translations cache miss occurs\n * @prop {locales-dictionary-cache-hit} - Emitted when a locales dictionary cache hit occurs\n * @prop {locales-dictionary-cache-miss} - Emitted when a locales dictionary cache miss occurs\n * @prop {dictionary-cache-hit} - Emitted when a dictionary cache hit occurs\n * @prop {dictionary-cache-miss} - Emitted when a dictionary cache miss occurs\n * @prop {dictionary-object-cache-hit} - Emitted when a dictionary object cache hit occurs\n */\nexport type I18nEvents<TranslationValue extends Translation> = BaseEvent & {\n 'locales-cache-hit': {\n locale: Locale;\n translations: Record<Hash, TranslationValue>;\n };\n [LOCALES_CACHE_MISS_EVENT_NAME]: {\n locale: Locale;\n translations: Record<Hash, TranslationValue>;\n };\n 'translations-cache-hit': {\n locale: Locale;\n hash: Hash;\n translation: TranslationValue;\n };\n [TRANSLATIONS_CACHE_MISS_EVENT_NAME]: {\n locale: Locale;\n hash: Hash;\n translation: TranslationValue;\n };\n 'locales-dictionary-cache-hit': {\n locale: Locale;\n dictionary: Dictionary;\n };\n [LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME]: {\n locale: Locale;\n dictionary: Dictionary;\n };\n 'dictionary-cache-hit': {\n locale: Locale;\n id: DictionaryPath;\n dictionaryEntry: DictionaryEntry;\n };\n [DICTIONARY_CACHE_MISS_EVENT_NAME]: {\n locale: Locale;\n id: DictionaryPath;\n dictionaryEntry: DictionaryEntry;\n };\n 'dictionary-object-cache-hit': {\n locale: Locale;\n id: DictionaryPath;\n dictionaryValue: DictionaryValue;\n };\n};\n","import { EventEmitter } from '../event-subscription/EventEmitter';\nimport {\n DICTIONARY_CACHE_MISS_EVENT_NAME,\n LOCALES_CACHE_MISS_EVENT_NAME,\n LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME,\n TRANSLATIONS_CACHE_MISS_EVENT_NAME,\n} from '../event-subscription/types';\nimport type { Translation } from '../translations-manager/utils/types/translation-data';\nimport type { I18nManagerCacheLifecycleCallbacks } from './types';\nimport type { I18nEvents } from '../event-subscription/types';\n/**\n * Maps consumer-facing lifecycle callbacks to internal locales cache lifecycle callbacks.\n * The consumer API exposes simplified params (locale, hash, value) while the internal\n * API uses the full cache lifecycle params (inputKey, cacheKey, cacheValue, outputValue).\n *\n * @deprecated - move to subscription api instead\n */\nexport function createLifecycleCallbacks<TranslationValue extends Translation>(\n emit: EventEmitter<I18nEvents<TranslationValue>>['emit']\n): I18nManagerCacheLifecycleCallbacks<TranslationValue> {\n return {\n onLocalesCacheHit: (params) => {\n emit('locales-cache-hit', {\n locale: params.inputKey,\n translations: params.outputValue.getInternalCache(),\n });\n },\n onLocalesCacheMiss: (params) => {\n emit(LOCALES_CACHE_MISS_EVENT_NAME, {\n locale: params.inputKey,\n translations: params.outputValue.getInternalCache(),\n });\n },\n onTranslationsCacheHit: (params) => {\n emit('translations-cache-hit', {\n locale: params.locale,\n hash: params.cacheKey,\n translation: params.outputValue,\n });\n },\n onTranslationsCacheMiss: (params) => {\n emit(TRANSLATIONS_CACHE_MISS_EVENT_NAME, {\n locale: params.locale,\n hash: params.cacheKey,\n translation: params.outputValue,\n });\n },\n onLocalesDictionaryCacheHit: (params) => {\n emit('locales-dictionary-cache-hit', {\n locale: params.inputKey,\n dictionary: params.outputValue.getInternalCache(),\n });\n },\n onLocalesDictionaryCacheMiss: (params) => {\n emit(LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME, {\n locale: params.inputKey,\n dictionary: params.outputValue.getInternalCache(),\n });\n },\n onDictionaryCacheHit: (params) => {\n emit('dictionary-cache-hit', {\n locale: params.locale,\n id: params.cacheKey,\n dictionaryEntry: params.outputValue,\n });\n },\n onDictionaryCacheMiss: (params) => {\n emit(DICTIONARY_CACHE_MISS_EVENT_NAME, {\n locale: params.locale,\n id: params.cacheKey,\n dictionaryEntry: params.outputValue,\n });\n },\n onDictionaryObjectCacheHit: (params) => {\n emit('dictionary-object-cache-hit', {\n locale: params.locale,\n id: params.cacheKey,\n dictionaryValue: params.outputValue,\n });\n },\n };\n}\n","import type { BaseEvent, Listener, ListenerStore } from './types';\n\n/**\n * Base class for event emitters\n */\nexport class EventEmitter<Events extends BaseEvent> {\n /**\n * Events map\n */\n protected listeners: ListenerStore<Events> = {};\n\n private getOrCreateListeners<EventName extends keyof Events>(\n eventName: EventName\n ): Set<Listener<Events, EventName>> {\n if (!this.listeners[eventName]) {\n this.listeners[eventName] = new Set();\n }\n return this.listeners[eventName]!;\n }\n\n /**\n * Subscribe to an event, returns an unsubscribe function\n */\n public subscribe<EventName extends keyof Events>(\n eventName: EventName,\n listener: Listener<Events, EventName>\n ) {\n const set = this.getOrCreateListeners(eventName);\n set.add(listener);\n return () => {\n set.delete(listener);\n };\n }\n\n /**\n * Emit an event\n */\n protected emit<EventName extends keyof Events>(\n eventName: EventName,\n event: Events[EventName]\n ) {\n this.listeners[eventName]?.forEach((subscriber) => subscriber(event));\n }\n}\n","import { EventEmitter } from '../event-subscription/EventEmitter';\nimport {\n DICTIONARY_CACHE_MISS_EVENT_NAME,\n LOCALES_CACHE_MISS_EVENT_NAME,\n LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME,\n TRANSLATIONS_CACHE_MISS_EVENT_NAME,\n} from '../event-subscription/types';\nimport type { Translation } from '../translations-manager/utils/types/translation-data';\nimport type { LifecycleCallbacks } from './types';\nimport type { I18nEvents } from '../event-subscription/types';\n\n/**\n * Subscribes to the lifecycle callbacks and emits the events to the event emitter\n * @deprecated - move to subscription api instead\n *\n * NOTE: we do not have to worry about unsubscribe here as this is a deprecated api\n * and is only used internally\n */\nexport function subscribeLifecycleCallbacks<\n TranslationValue extends Translation,\n>(\n {\n onLocalesCacheHit,\n onLocalesCacheMiss,\n onTranslationsCacheHit,\n onTranslationsCacheMiss,\n onLocalesDictionaryCacheHit,\n onLocalesDictionaryCacheMiss,\n onDictionaryCacheHit,\n onDictionaryCacheMiss,\n onDictionaryObjectCacheHit,\n }: LifecycleCallbacks<TranslationValue>,\n subscribe: EventEmitter<I18nEvents<TranslationValue>>['subscribe']\n) {\n if (onLocalesCacheHit) {\n subscribe('locales-cache-hit', (event) => {\n onLocalesCacheHit({\n ...event,\n value: event.translations,\n });\n });\n }\n if (onLocalesCacheMiss) {\n subscribe(LOCALES_CACHE_MISS_EVENT_NAME, (event) => {\n onLocalesCacheMiss({\n ...event,\n value: event.translations,\n });\n });\n }\n if (onTranslationsCacheHit) {\n subscribe('translations-cache-hit', (event) => {\n onTranslationsCacheHit({\n ...event,\n value: event.translation,\n });\n });\n }\n if (onTranslationsCacheMiss) {\n subscribe(TRANSLATIONS_CACHE_MISS_EVENT_NAME, (event) => {\n onTranslationsCacheMiss({\n ...event,\n value: event.translation,\n });\n });\n }\n if (onLocalesDictionaryCacheHit) {\n subscribe('locales-dictionary-cache-hit', (event) => {\n onLocalesDictionaryCacheHit(event);\n });\n }\n if (onLocalesDictionaryCacheMiss) {\n subscribe(LOCALES_DICTIONARY_CACHE_MISS_EVENT_NAME, (event) => {\n onLocalesDictionaryCacheMiss(event);\n });\n }\n if (onDictionaryCacheHit) {\n subscribe('dictionary-cache-hit', (event) => {\n onDictionaryCacheHit(event);\n });\n }\n if (onDictionaryCacheMiss) {\n subscribe(DICTIONARY_CACHE_MISS_EVENT_NAME, (event) => {\n onDictionaryCacheMiss(event);\n });\n }\n if (onDictionaryObjectCacheHit) {\n subscribe('dictionary-object-cache-hit', (event) => {\n onDictionaryObjectCacheHit(event);\n });\n }\n}\n","import { publishValidationResults } from './validation/publishValidationResults';\nimport logger from '../logs/logger';\nimport { I18nManagerConfig, I18nManagerConstructorParams } from './types';\nimport { validateConfig } from './validation/validateConfig';\nimport { Translation } from './translations-manager/utils/types/translation-data';\nimport { libraryDefaultLocale } from 'generaltranslation/internal';\nimport { GT } from 'generaltranslation';\nimport { LocaleConfig, standardizeLocale } from '@generaltranslation/format';\nimport type { CustomMapping } from '@generaltranslation/format/types';\nimport { LookupOptions } from '../translation-functions/types/options';\nimport { getGTServicesEnabled } from './utils/getGTServicesEnabled';\nimport {\n SafeTranslationsLoader,\n TranslationsLoader,\n} from './translations-manager/translations-loaders/types';\nimport { createTranslateManyFactory } from './translations-manager/utils/createTranslateMany';\nimport { routeCreateTranslationLoader } from './translations-manager/translations-loaders/routeCreateTranslationLoader';\nimport { getLoadTranslationsType } from './utils/getLoadTranslationsType';\nimport { Locale, LocalesCache } from './translations-manager/LocalesCache';\nimport { Hash } from './translations-manager/TranslationsCache';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryObject,\n} from './translations-manager/DictionaryCache';\nimport { resolveDictionaryLookupOptions } from './translations-manager/utils/dictionary-helpers';\nimport { LocalesDictionaryCache } from './translations-manager/LocalesDictionaryCache';\nimport type { DictionaryLoader } from './translations-manager/LocalesDictionaryCache';\nimport { DictionarySourceNotFoundError } from './translations-manager/utils/DictionarySourceNotFoundError';\nimport { createLifecycleCallbacks } from './lifecycle-hooks/createLifecycleCallbacks';\nimport { EventEmitter } from './event-subscription/EventEmitter';\nimport { subscribeLifecycleCallbacks } from './lifecycle-hooks/subscribeLifecycleCallbacks';\nimport { TRANSLATIONS_CACHE_MISS_EVENT_NAME } from './event-subscription/types';\nimport type { I18nEvents } from './event-subscription/types';\n\n/**\n * Default translation timeout in milliseconds for a runtime translation request\n */\nconst DEFAULT_TRANSLATION_TIMEOUT = 12_000; // 12 seconds\n\n/**\n * A translation resolver is a function that synchronously resolves a translation\n * @template U - The type of the translation (default: Translation)\n * @param {U} message - The message to get the translation for\n * @param {LookupOptions} [options] - The options for the translation\n * @returns {U | undefined} The translation for the given message and options or undefined if the translation is not found\n */\ntype TranslationResolver<U extends Translation = Translation> = <\n T extends U = U,\n>(\n message: T,\n options?: LookupOptions\n) => T | undefined;\n\n/**\n * A prefetch entry is an entry that we want to prefetch during the async period\n * @template TranslationType - The type of the translation\n * @param {TranslationType} message - The message to prefetch\n * @param {LookupOptions} options - The options for the prefetch\n * @returns {PrefetchEntry<TranslationType>} The prefetch entry\n */\ntype PrefetchEntry<TranslationType extends Translation> = {\n message: TranslationType;\n options: LookupOptions;\n};\n\n/**\n * Class for managing translation functionality\n * @template TranslationValue - The type of the translation that will be cached\n */\nclass I18nManager<\n TranslationValue extends Translation = Translation,\n> extends EventEmitter<I18nEvents<TranslationValue>> {\n protected config: I18nManagerConfig;\n\n /**\n * Cache for translations\n */\n private localesCache: LocalesCache<TranslationValue>;\n\n /**\n * Cache for dictionaries\n */\n private localesDictionaryCache: LocalesDictionaryCache;\n\n /**\n * Runtime-safe locale and formatting helpers\n */\n private localeConfig: LocaleConfig;\n\n /**\n * Creates an instance of I18nManager.\n * TODO: resolve gtConfig from just file path\n * @param params - The parameters for the I18nManager constructor\n * @param params.config - The configuration for the I18nManager\n */\n constructor(params: I18nManagerConstructorParams<TranslationValue>) {\n super();\n\n // Validation\n const validationResults = validateConfig(params);\n publishValidationResults(validationResults, 'I18nManager: ');\n\n // Setup\n this.config = standardizeConfig(params);\n this.localeConfig = new LocaleConfig({\n defaultLocale: this.config.defaultLocale,\n locales: this.config.locales,\n customMapping: this.config.customMapping,\n });\n // Create cache miss handlers\n const loadTranslations = createTranslationLoader<TranslationValue>(params);\n const loadDictionary = createDictionaryLoader(params);\n const runtimeTranslationTimeout =\n this.config.runtimeTranslation?.timeout ?? DEFAULT_TRANSLATION_TIMEOUT;\n const runtimeTranslationMetadata =\n this.config.runtimeTranslation?.metadata ?? {};\n const createTranslateMany = createTranslateManyFactory(\n this.getGTClassClean(),\n runtimeTranslationTimeout,\n runtimeTranslationMetadata\n );\n\n // Subscribe lifecycle callbacks\n subscribeLifecycleCallbacks(params.lifecycle ?? {}, (...args) =>\n this.subscribe(...args)\n );\n\n const lifecycle = createLifecycleCallbacks<TranslationValue>((...args) =>\n this.emit(...args)\n );\n\n // Setup translations cache\n this.localesCache = new LocalesCache<TranslationValue>({\n loadTranslations,\n createTranslateMany,\n lifecycle,\n ttl: this.config.cacheExpiryTime,\n batchConfig: this.config.batchConfig,\n });\n\n // Setup dictionary cache\n this.localesDictionaryCache = new LocalesDictionaryCache({\n defaultLocale: this.config.defaultLocale,\n dictionary: params.dictionary,\n loadDictionary,\n runtimeTranslate: (locale, id, sourceEntry) =>\n this.dictionaryRuntimeTranslate(locale, id, sourceEntry),\n ttl: this.config.cacheExpiryTime,\n lifecycle,\n });\n }\n\n // ========== Subscribers and Emitters ========== //\n\n /**\n * Subscribes to a change in a translation entry (eg a runtime translation)\n * @param listener - The subscriber function\n * @param locale - The locale of the translation entry\n * @param hash - The hash of the translation entry\n * @returns An unsubscribe function\n *\n * Pair this with {@link lookupTranslation} to get the translation entry\n */\n subscribeToTranslationsCacheMiss(\n listener: (\n event: I18nEvents<TranslationValue>[typeof TRANSLATIONS_CACHE_MISS_EVENT_NAME]\n ) => void,\n locale: Locale,\n hash: Hash\n ) {\n return this.subscribe(TRANSLATIONS_CACHE_MISS_EVENT_NAME, (event) => {\n if (event.locale !== locale || event.hash !== hash) {\n return;\n }\n listener(event);\n });\n }\n\n // ========== Getters and Setters ========== //\n\n /**\n * Get the default locale\n */\n getDefaultLocale(): string {\n return this.config.defaultLocale;\n }\n\n /**\n * Get the locales\n */\n getLocales(): string[] {\n return this.config.locales;\n }\n\n /**\n * Get the custom locale mapping\n */\n getCustomMapping(): CustomMapping {\n return this.config.customMapping;\n }\n\n /**\n * Get the version ID\n */\n getVersionId(): string | undefined {\n return this.config._versionId;\n }\n\n /**\n * Get a gt class instance\n * @param locale - The locale to bind to the GT instance. When omitted, the GT instance is locale agnostic.\n * TODO: keep a cache to avoid creating new instances unnecessarily\n */\n getGTClass(locale?: string): GT {\n return this.getGTClassClean(\n locale ? this.resolveLocale(locale) : undefined\n );\n }\n\n /**\n * Is translation enabled?\n */\n isTranslationEnabled(): boolean {\n return this.config.enableI18n;\n }\n\n // ========== Translation Loading ========== //\n\n /**\n * Get the translation loader function\n * @deprecated wrap a cb around loadTranslations instead\n */\n getTranslationLoader(): TranslationsLoader {\n return (locale: string) => this.loadTranslations(locale);\n }\n\n // ========== Translation Resolution ========== //\n\n // ----- New Operations ----- //\n\n /**\n * Loads in translations for a given locale\n * Edge case usage: access the translations object directly\n */\n async loadTranslations(\n locale: string\n ): Promise<Record<Hash, TranslationValue>> {\n try {\n // Validate\n const translationLocale = this.resolveCacheLocale(locale);\n if (!translationLocale) {\n return {};\n }\n\n // Get the locale cache\n let txCache = this.localesCache.get(translationLocale);\n if (!txCache) txCache = await this.localesCache.miss(translationLocale);\n\n // Get the translations\n const translations = txCache.getInternalCache();\n return translations;\n } catch (error) {\n this.handleError(error);\n return {};\n }\n }\n\n /**\n * Loads in the dictionary for a given locale\n * Edge case usage: access the dictionary object directly\n */\n async loadDictionary(locale: string): Promise<Dictionary> {\n try {\n // Validate\n const dictionaryLocale = this.resolveCacheLocale(locale);\n if (!dictionaryLocale) {\n return (\n this.localesDictionaryCache\n .get(this.config.defaultLocale)\n ?.getInternalCache() ?? {}\n );\n }\n\n // Get the locale dictionary cache\n let dictionaryCache = this.localesDictionaryCache.get(dictionaryLocale);\n if (!dictionaryCache) {\n dictionaryCache =\n await this.localesDictionaryCache.miss(dictionaryLocale);\n }\n\n // Get the dictionary\n const dictionary = dictionaryCache.getInternalCache();\n return dictionary;\n } catch (error) {\n this.handleError(error);\n return {};\n }\n }\n\n /**\n * Look up a dictionary entry\n */\n lookupDictionary(locale: string, id: string): DictionaryEntry | undefined {\n try {\n const dictionaryLocale =\n this.resolveCacheLocale(locale) ?? this.config.defaultLocale;\n const dictionaryEntry = this.localesDictionaryCache\n .get(dictionaryLocale)\n ?.get(id);\n\n return dictionaryEntry;\n } catch (error) {\n this.handleError(error);\n return undefined;\n }\n }\n\n /**\n * Look up a dictionary entry or subtree\n */\n lookupDictionaryObj(\n locale: string,\n id: string\n ): DictionaryObject | undefined {\n try {\n const dictionaryLocale =\n this.resolveCacheLocale(locale) ?? this.config.defaultLocale;\n return this.localesDictionaryCache.get(dictionaryLocale)?.getObj(id);\n } catch (error) {\n this.handleError(error);\n return undefined;\n }\n }\n\n /**\n * Look up a dictionary entry\n * If it's not found, use the fallback (runtime translate)\n */\n async lookupDictionaryWithFallback(\n locale: string,\n id: string\n ): Promise<DictionaryEntry | undefined> {\n try {\n const dictionaryLocale = this.resolveCacheLocale(locale);\n if (!dictionaryLocale) {\n const sourceEntry = this.localesDictionaryCache\n .get(this.config.defaultLocale)\n ?.get(id);\n if (sourceEntry === undefined) {\n throw new DictionarySourceNotFoundError(id);\n }\n return sourceEntry;\n }\n\n let dictionaryCache = this.localesDictionaryCache.get(dictionaryLocale);\n if (!dictionaryCache) {\n dictionaryCache =\n await this.localesDictionaryCache.miss(dictionaryLocale);\n }\n\n let dictionaryEntry = dictionaryCache.get(id);\n if (dictionaryEntry === undefined) {\n const sourceEntry = this.localesDictionaryCache\n .get(this.config.defaultLocale)\n ?.get(id);\n if (sourceEntry === undefined) {\n throw new DictionarySourceNotFoundError(id);\n }\n dictionaryEntry = await dictionaryCache.miss(id, sourceEntry);\n }\n return dictionaryEntry;\n } catch (error) {\n this.handleError(error);\n return undefined;\n }\n }\n\n /**\n * Look up a dictionary entry or subtree\n * If it's not found, use the fallback (runtime translate)\n */\n async lookupDictionaryObjWithFallback(\n locale: string,\n id: string\n ): Promise<DictionaryObject | undefined> {\n try {\n const dictionaryLocale = this.resolveCacheLocale(locale);\n if (!dictionaryLocale) {\n const sourceObject = this.localesDictionaryCache\n .get(this.config.defaultLocale)\n ?.getObj(id);\n if (sourceObject === undefined) {\n throw new DictionarySourceNotFoundError(id);\n }\n return sourceObject;\n }\n\n let dictionaryCache = this.localesDictionaryCache.get(dictionaryLocale);\n if (!dictionaryCache) {\n dictionaryCache =\n await this.localesDictionaryCache.miss(dictionaryLocale);\n }\n\n let dictionaryObject = dictionaryCache.getObj(id);\n if (dictionaryObject === undefined) {\n const sourceObject = this.localesDictionaryCache\n .get(this.config.defaultLocale)\n ?.getObj(id);\n if (sourceObject === undefined) {\n throw new DictionarySourceNotFoundError(id);\n }\n dictionaryObject = await dictionaryCache.missObj(id, sourceObject);\n }\n return dictionaryObject;\n } catch (error) {\n this.handleError(error);\n return undefined;\n }\n }\n\n /**\n * Just lookup a translation\n */\n lookupTranslation<T extends TranslationValue = TranslationValue>(\n locale: string,\n message: T,\n options: LookupOptions\n ): T | undefined {\n try {\n // Validate\n const { translationLocale, options: lookupOptions } =\n this.resolveLookupParams(locale, options);\n\n // Early return if in default locale\n if (!translationLocale) {\n return message;\n }\n\n // Get the locale cache\n const txCache = this.localesCache.get(translationLocale);\n if (!txCache) return undefined;\n\n // Get the translation\n return txCache.get({ message, options: lookupOptions });\n } catch (error) {\n this.handleError(error);\n return undefined;\n }\n }\n\n /**\n * Look up a translation\n * If it's not found, use the fallback (runtime translate)\n */\n async lookupTranslationWithFallback<\n T extends TranslationValue = TranslationValue,\n >(\n locale: string,\n message: T,\n options: LookupOptions\n ): Promise<T | undefined> {\n try {\n return await this.lookupTranslationWithFallbackResolved(\n locale,\n message,\n options\n );\n } catch (error) {\n this.handleError(error);\n return undefined;\n }\n }\n\n /**\n * Saves a current lookup translation function immune to expiry\n * Useful for operations involving lookup callbacks like useGT()\n * @param locale - The locale to get the lookup translation for\n * @param prefetchEntries - Any entries we want to prefetch during the async period\n * @returns A lookup translation function\n *\n * @important prefetchEntries must all be the same locale\n */\n async getLookupTranslation(\n locale: string,\n prefetchEntries: {\n message: TranslationValue;\n options: LookupOptions;\n }[] = []\n ): Promise<TranslationResolver<TranslationValue>> {\n try {\n // Validate\n const translationLocale = this.resolveCacheLocale(locale);\n\n // Early return if i18n is disabled or default locale\n if (!translationLocale) {\n return (message) => message;\n }\n\n // Invariant: all prefetchEntries must be the same locale\n const resolvedPrefetchEntries = resolvePrefetchEntriesByLocale(\n prefetchEntries,\n translationLocale,\n (entryLocale) =>\n this.resolveCacheLocale(entryLocale) ??\n this.resolveLocale(entryLocale)\n );\n if (resolvedPrefetchEntries.length !== prefetchEntries.length) {\n logger.warn(\n `I18nManager: getLookupTranslation(): prefetchEntries must all be the same locale, ignoring all entries that are not for ${translationLocale}`\n );\n }\n\n // Get Locale Cache\n let txCache = this.localesCache.get(translationLocale);\n if (!txCache) txCache = await this.localesCache.miss(translationLocale);\n if (!txCache) return () => undefined;\n\n // Prefetch any entries during async block\n await Promise.all(\n resolvedPrefetchEntries\n .filter((entry) => txCache.get(entry) == null)\n .map((entry) => txCache.miss(entry))\n );\n\n // Create translation resolver\n return (message, options: LookupOptions = {} as LookupOptions) => {\n // Calculate hash\n return txCache.get({\n message,\n options: this.resolveLookupOptions(options),\n });\n };\n } catch (error) {\n this.handleError(error);\n return (message) => message;\n }\n }\n\n // ----- Sync Operations ----- //\n\n /**\n * Get the translations (error on unloaded translations)\n * @param {string} message - The message to get the translation for\n * @param {LookupOptions} [options] - The options for the translation\n * @returns {TranslationValue | undefined} The translation for the given message and options synchronously\n * @deprecated use lookupTranslation instead\n */\n resolveTranslationSync = <T extends TranslationValue = TranslationValue>(\n locale: string,\n message: T,\n options: LookupOptions\n ) => {\n return this.lookupTranslation(locale, message, options);\n };\n\n // ----- Async Operations ----- //\n\n /**\n * Get the translations\n * @deprecated use loadTranslations instead\n */\n async getTranslations(\n locale: string\n ): Promise<Record<Hash, TranslationValue>> {\n try {\n return this.loadTranslations(locale);\n } catch (error) {\n this.handleError(error);\n return {};\n }\n }\n\n /**\n * Get translation for a given locale and message\n *\n * @param {string} locale - The locale to get the translation for\n * @returns A function that resolves the translations for a given message and options synchronously\n *\n * Note: we can assume that the translation is a string because we are passing a string\n *\n * @deprecated use getLookupTranslation instead\n */\n async getTranslationResolver(\n locale: string\n ): Promise<TranslationResolver<TranslationValue>> {\n return this.getLookupTranslation(locale);\n }\n\n // ========== Metadata ========== //\n\n /**\n * Returns true if translation is required\n * @param {string} locale - The user's locale\n * @returns {boolean} True if translation is required, otherwise false\n */\n requiresTranslation(locale: string): boolean {\n const defaultLocale = this.getDefaultLocale();\n const locales = this.getLocales();\n return (\n this.isTranslationEnabled() &&\n this.localeConfig.requiresTranslation(locale, defaultLocale, locales)\n );\n }\n\n /**\n * Returns true if dialect translation is required\n * @param {string} locale - The user's locale\n * @returns {boolean} True if dialect translation is required, otherwise false\n */\n requiresDialectTranslation(locale: string): boolean {\n const defaultLocale = this.getDefaultLocale();\n return (\n this.requiresTranslation(locale) &&\n this.localeConfig.isSameLanguage(defaultLocale, locale)\n );\n }\n\n /**\n * Handle errors\n * Soft error in production, throw in development\n */\n private handleError(error: unknown) {\n if (error instanceof DictionarySourceNotFoundError) {\n throw error;\n }\n\n switch (this.config.environment) {\n case 'development':\n throw error;\n case 'production':\n default:\n logger.error('I18nManager: ' + error);\n break;\n }\n }\n\n private resolveLocale(locale: string) {\n const resolvedLocale = this.localeConfig.determineLocale(locale);\n if (!this.localeConfig.isValidLocale(locale) || !resolvedLocale) {\n throw new Error(\n `Locale \"${locale}\" is not valid. Use a valid BCP 47 locale code or add a custom mapping.`\n );\n }\n return resolvedLocale;\n }\n\n /**\n * Resolve the locale key used to load/read locale caches.\n * Returns undefined when the requested locale can use source content.\n */\n private resolveCacheLocale(locale: string) {\n const resolvedLocale = this.resolveLocale(locale);\n if (this.requiresTranslation(resolvedLocale)) {\n return resolvedLocale;\n }\n\n const aliasLocale = this.localeConfig.resolveAliasLocale(\n standardizeLocale(locale)\n );\n if (this.requiresTranslation(aliasLocale)) {\n return aliasLocale;\n }\n\n return undefined;\n }\n\n private resolveLookupParams(locale: string, options: LookupOptions) {\n const translationLocale = this.resolveCacheLocale(locale);\n return {\n translationLocale,\n options: translationLocale\n ? this.resolveLookupOptions(options, translationLocale)\n : options,\n };\n }\n\n private resolveLookupOptions(\n options: LookupOptions = {} as LookupOptions,\n translationLocale?: string\n ) {\n if (!options.$locale) {\n return options;\n }\n return {\n ...options,\n $locale:\n translationLocale ??\n this.resolveCacheLocale(options.$locale) ??\n this.resolveLocale(options.$locale),\n };\n }\n\n private async lookupTranslationWithFallbackResolved<\n T extends TranslationValue = TranslationValue,\n >(locale: string, message: T, options: LookupOptions): Promise<T> {\n const { translationLocale, options: lookupOptions } =\n this.resolveLookupParams(locale, options);\n\n if (!translationLocale) {\n return message;\n }\n\n let txCache = this.localesCache.get(translationLocale);\n if (!txCache) txCache = await this.localesCache.miss(translationLocale);\n\n let translation = txCache.get({ message, options: lookupOptions });\n if (translation == null) {\n translation = await txCache.miss({ message, options: lookupOptions });\n }\n return translation;\n }\n\n /**\n * Runtime lookup function for dictionaries\n */\n private async dictionaryRuntimeTranslate(\n locale: Locale,\n id: DictionaryKey,\n sourceEntry: DictionaryEntry\n ): Promise<string> {\n // Runtime translation\n const translation = await this.lookupTranslationWithFallbackResolved(\n locale,\n sourceEntry.entry as TranslationValue,\n resolveDictionaryLookupOptions(sourceEntry.options)\n );\n if (typeof translation !== 'string') {\n throw new Error(\n `Dictionary entry \"${id}\" could not be translated into a string. Check the source entry and translation loader output.`\n );\n }\n\n return translation;\n }\n\n /**\n * A helper function to create a gt class that is locale agnostic\n * This is helpful for when our getLocale function is bound to a\n * specific context\n */\n private getGTClassClean(locale?: string) {\n return new GT({\n sourceLocale: this.config.defaultLocale,\n targetLocale: locale,\n // GT validates approved locales before constructing its LocaleConfig, so\n // pass canonical locales here while preserving alias target locales.\n locales: Array.from(\n new Set(\n this.config.locales.map((locale) =>\n this.localeConfig.resolveCanonicalLocale(locale)\n )\n )\n ),\n customMapping: this.config.customMapping,\n projectId: this.config.projectId,\n baseUrl: this.config.runtimeUrl || undefined,\n apiKey: this.config.apiKey,\n devApiKey: this.config.devApiKey,\n });\n }\n}\n\nexport { I18nManager };\n\n// ===== Helper Functions ===== //\n\n/**\n * Standardize the config\n * @param config - The config to standardize\n * @returns The standardized config\n */\nfunction standardizeConfig<TranslationValue extends Translation>(\n config: I18nManagerConstructorParams<TranslationValue>\n) {\n const gtServicesEnabled = getGTServicesEnabled(config);\n\n const dedupedLocales = dedupeLocales({\n defaultLocale: config.defaultLocale || libraryDefaultLocale,\n locales: config.locales || [libraryDefaultLocale],\n customMapping: config.customMapping,\n });\n\n return {\n environment: config.environment || 'production',\n enableI18n: config.enableI18n !== undefined ? config.enableI18n : true,\n projectId: config.projectId,\n devApiKey: config.devApiKey,\n apiKey: config.apiKey,\n runtimeUrl: config.runtimeUrl,\n cacheExpiryTime: config.cacheExpiryTime,\n batchConfig: config.batchConfig,\n runtimeTranslation: config.runtimeTranslation,\n _versionId: config._versionId,\n ...(gtServicesEnabled\n ? standardizeLocales(dedupedLocales)\n : dedupedLocales),\n };\n}\n\n/**\n * Dedupe locales and add defaultLocale\n */\nfunction dedupeLocales({\n defaultLocale,\n locales,\n customMapping,\n}: {\n defaultLocale: string;\n locales: string[];\n customMapping?: CustomMapping;\n}) {\n return {\n defaultLocale,\n locales: Array.from(new Set([defaultLocale, ...locales])),\n customMapping: customMapping || {},\n };\n}\n\n/**\n * Standardize all locales in config\n * Only apply if using GT services\n */\nfunction standardizeLocales(config: {\n defaultLocale: string;\n locales: string[];\n customMapping: CustomMapping;\n}) {\n // Sanitize defaultLocale and locales\n const defaultLocale = standardizeLocale(config.defaultLocale);\n const locales = config.locales.map((locale) => {\n const mappedLocale =\n typeof config.customMapping?.[locale] === 'string'\n ? config.customMapping?.[locale]\n : config.customMapping?.[locale]?.code;\n if (mappedLocale) {\n return locale;\n } else {\n return standardizeLocale(locale);\n }\n });\n\n // Sanitize customMapping\n const customMapping = Object.fromEntries(\n Object.entries(config.customMapping || {}).map(([key, value]) => [\n key,\n typeof value === 'string'\n ? standardizeLocale(value)\n : {\n ...value,\n ...(value.code ? { code: standardizeLocale(value.code) } : {}),\n },\n ])\n );\n\n return {\n defaultLocale,\n locales,\n customMapping,\n };\n}\n\n/**\n * Resolve prefetch entry locales and keep entries matching the active locale.\n * @template TranslationType - The type of the translation\n * @param {PrefetchEntry<TranslationType>[]} prefetchEntries - The prefetch entries to filter\n * @param {string} locale - The locale to filter by\n * @returns {PrefetchEntry<TranslationType>[]} The filtered prefetch entries\n */\nfunction resolvePrefetchEntriesByLocale<TranslationType extends Translation>(\n prefetchEntries: PrefetchEntry<TranslationType>[],\n locale: string,\n resolveLocale: (locale: string) => string\n) {\n return prefetchEntries.flatMap((entry) => {\n const entryLocale = entry.options.$locale;\n if (entryLocale == null) return [entry];\n\n try {\n const resolvedLocale = resolveLocale(entryLocale);\n if (resolvedLocale !== locale) return [];\n return [\n {\n message: entry.message,\n options: {\n ...entry.options,\n $locale: resolvedLocale,\n },\n },\n ];\n } catch {\n return [];\n }\n });\n}\n\n/**\n * Helper function for creating a translation loader\n */\nfunction createTranslationLoader<TranslationType extends Translation>(\n params: I18nManagerConstructorParams<TranslationType>\n) {\n return routeCreateTranslationLoader({\n loadTranslations: params.loadTranslations,\n type: getLoadTranslationsType(params),\n remoteTranslationLoaderParams: {\n cacheUrl: params.cacheUrl,\n projectId: params.projectId,\n _versionId: params._versionId,\n _branchId: params._branchId,\n customMapping: params.customMapping,\n },\n }) as SafeTranslationsLoader<TranslationType>;\n}\n\n/**\n * Helper function for creating a dictionary loader\n */\nfunction createDictionaryLoader<TranslationType extends Translation>(\n params: I18nManagerConstructorParams<TranslationType>\n): DictionaryLoader {\n return params.loadDictionary ?? (() => Promise.resolve({}));\n}\n","import { libraryDefaultLocale } from 'generaltranslation/internal';\nimport { I18nManager } from './I18nManager';\nimport logger from '../logs/logger';\nimport { Translation } from './translations-manager/utils/types/translation-data';\nimport type { ConditionStore } from './types';\n\n// Singleton instance of I18nManager\nlet i18nManager: I18nManager | undefined = undefined;\nlet fallbackDefaultLocale: string = libraryDefaultLocale;\n// Used before wrapper runtimes install a condition store; tracks the active manager default.\nconst fallbackConditionStore: ConditionStore = {\n getLocale: () => fallbackDefaultLocale,\n};\nlet conditionStore: ConditionStore = fallbackConditionStore;\n\n/**\n * Get the singleton instance of I18nManager\n * @returns The singleton instance of I18nManager\n * @template U - The type of the translation that will be cached\n */\nexport function getI18nManager<U extends Translation = Translation>():\n | I18nManager<U>\n | I18nManager<Translation> {\n if (!i18nManager) {\n logger.warn(\n 'getI18nManager(): I18nManager was not initialized. Falling back to the default locale until initializeGT() configures translations.'\n );\n i18nManager = new I18nManager({\n defaultLocale: libraryDefaultLocale,\n locales: [libraryDefaultLocale],\n });\n }\n return i18nManager;\n}\n\n/**\n * Resolve the current locale from the configured runtime condition source.\n */\nexport function getCurrentLocale(): string {\n return conditionStore.getLocale();\n}\n\n/**\n * Configure the runtime condition source.\n */\nexport function setConditionStore(nextConditionStore: ConditionStore): void {\n conditionStore = nextConditionStore;\n}\n\n/**\n * Reset the runtime condition source to the active manager's default-locale fallback.\n */\nfunction resetConditionStore(): void {\n conditionStore = fallbackConditionStore;\n}\n\n/**\n * Configure the singleton instance of I18nManager\n * @param config - The configuration for the I18nManager\n *\n * Wrapper libraries will export a configure function that will call this function.\n */\nexport function setI18nManager<TranslationValue extends Translation>(\n i18nManagerInstance: I18nManager<TranslationValue>\n): void {\n i18nManager = i18nManagerInstance as unknown as I18nManager;\n fallbackDefaultLocale = i18nManagerInstance.getDefaultLocale();\n resetConditionStore();\n}\n","import { formatCutoff } from '@generaltranslation/format';\nimport { InlineTranslationOptions } from '../../types/options';\n\n/**\n * String interpolation function\n */\nexport function interpolateStringMessage(\n encodedMsg: string,\n options: InlineTranslationOptions\n): string {\n const cutoffMessage = formatCutoff(encodedMsg, {\n locales: options.$locale ?? options.$_locales,\n maxChars: options.$maxChars,\n });\n return cutoffMessage;\n}\n","import {\n InlineTranslationOptions,\n NormalizedLookupOptions,\n} from '../../types/options';\nimport { interpolateIcuMessage } from './interpolateIcuMessage';\nimport { interpolateStringMessage } from './interpolateStringMessage';\nimport type { StringFormat } from '@generaltranslation/format/types';\n\n/**\n * Options for string interpolation\n * @internal\n */\nexport type InterpolationOptions = NormalizedLookupOptions<StringFormat>;\n\n/**\n * Interpolation router function for all {@link StringFormat} types\n */\nexport function interpolateMessage({\n source,\n target,\n options,\n sourceLocale,\n}: {\n source: string;\n target?: string;\n options: InterpolationOptions;\n sourceLocale?: string;\n}): string {\n // Format translation\n if (target != null) {\n return routeInterpolation(target, {\n $_fallback: source,\n ...options,\n });\n }\n\n // Format source\n // Missing translations format the source with the source locale, not the target locale.\n // TODO: Consider formatting dates, numbers, etc. with the target locale while keeping plurals in the source locale.\n return routeInterpolation(source, getSourceOptions(options, sourceLocale));\n}\n\n// ----- HELPERS ----- //\n\n/**\n * Route to appropriate formatting function\n */\nfunction routeInterpolation(\n content: string,\n options: InlineTranslationOptions\n): string {\n switch (options.$format ?? 'STRING') {\n case 'ICU':\n return interpolateIcuMessage(content, options);\n case 'I18NEXT':\n case 'STRING':\n return interpolateStringMessage(content, options);\n default:\n // e.g. $format: 'NONE'\n return content;\n }\n}\n\nfunction getSourceOptions(\n options: InterpolationOptions,\n sourceLocale?: string\n): InterpolationOptions {\n if (!sourceLocale) return options;\n return {\n ...options,\n $locale: sourceLocale,\n };\n}\n","import { getI18nManager } from '../../i18n-manager/singleton-operations';\nimport { NormalizedLookupOptions, ResolutionOptions } from '../types/options';\nimport { interpolateMessage } from '../utils/interpolation/interpolateMessage';\nimport type {\n DataFormat,\n JsxChildren,\n StringContent,\n StringFormat,\n} from '@generaltranslation/format/types';\n\n// ----- JSX TRANSLATION FUNCTIONS ----- //\n\n/**\n * Just do a simple lookup of the translation\n */\nexport function resolveJsx(\n locale: string,\n content: JsxChildren,\n options: ResolutionOptions<'JSX'> = {}\n): JsxChildren | undefined {\n const i18nManager = getI18nManager();\n const lookupOptions = createLookupOptions(locale, options, 'JSX');\n const translation = i18nManager.lookupTranslation(\n lookupOptions.$locale,\n content,\n lookupOptions\n );\n return translation;\n}\n\n/**\n * Lookup translation, fallback to source\n */\nexport function resolveJsxWithFallback(\n locale: string,\n content: JsxChildren,\n options: ResolutionOptions<'JSX'> = {}\n): JsxChildren {\n const translation = resolveJsx(locale, content, options);\n return translation ?? content;\n}\n\n/**\n * Lookup translation\n * fallback to runtime translate\n * Fallback to source\n */\nexport async function resolveJsxWithRuntimeFallback(\n locale: string,\n content: JsxChildren,\n options: ResolutionOptions<'JSX'> = {}\n): Promise<JsxChildren> {\n const i18nManager = getI18nManager();\n const lookupOptions = createLookupOptions(locale, options, 'JSX');\n const translation = await i18nManager.lookupTranslationWithFallback(\n lookupOptions.$locale,\n content,\n lookupOptions\n );\n return translation ?? content;\n}\n\n// ----- STRING CONTENT TRANSLATION FUNCTIONS ----- //\n\n/**\n * Just do a simple lookup of the translation\n * And interpolate\n */\nexport function resolveStringContent(\n locale: string,\n content: StringContent,\n options: ResolutionOptions<StringFormat> = {}\n): StringContent | undefined {\n const i18nManager = getI18nManager();\n const lookupOptions = createLookupOptions(locale, options, 'STRING');\n const translation = i18nManager.lookupTranslation(\n lookupOptions.$locale,\n content,\n lookupOptions\n );\n if (translation == null) return undefined;\n return interpolateMessage({\n source: content,\n target: translation,\n options: lookupOptions,\n sourceLocale: i18nManager.getDefaultLocale(),\n });\n}\n\n/**\n * Lookup translation, fallback to source\n */\nexport function resolveStringContentWithFallback(\n locale: string,\n content: StringContent,\n options: ResolutionOptions<StringFormat> = {}\n): StringContent {\n const i18nManager = getI18nManager();\n const lookupOptions = createLookupOptions(locale, options, 'STRING');\n const translation = i18nManager.lookupTranslation(\n lookupOptions.$locale,\n content,\n lookupOptions\n );\n return interpolateMessage({\n source: content,\n target: translation,\n options: lookupOptions,\n sourceLocale: i18nManager.getDefaultLocale(),\n });\n}\n\n/**\n * Lookup translation\n * fallback to runtime translate\n * Fallback to source\n */\nexport async function resolveStringContentWithRuntimeFallback(\n locale: string,\n content: StringContent,\n options: ResolutionOptions<StringFormat> = {}\n): Promise<StringContent> {\n const i18nManager = getI18nManager();\n const lookupOptions = createLookupOptions(locale, options, 'STRING');\n const translation = await i18nManager.lookupTranslationWithFallback(\n lookupOptions.$locale,\n content,\n lookupOptions\n );\n return interpolateMessage({\n source: content,\n target: translation,\n options: lookupOptions,\n sourceLocale: i18nManager.getDefaultLocale(),\n });\n}\n/**\n * Add the default format to caller-provided lookup options.\n */\nexport function createLookupOptions<T extends DataFormat>(\n locale: string,\n options: ResolutionOptions<T>,\n defaultFormat: T\n): NormalizedLookupOptions<T> {\n return {\n ...options,\n $format: (options.$format ?? defaultFormat) as T,\n $locale: locale,\n };\n}\n","import {\n getCurrentLocale,\n getI18nManager,\n} from '../i18n-manager/singleton-operations';\n\n/**\n * Get the current locale\n * @returns The current locale\n *\n * @example\n * const locale = getLocale();\n * console.log(locale); // 'en-US'\n */\nexport function getLocale() {\n return getCurrentLocale();\n}\n\n/**\n * Get the configured locales\n * @returns The configured locales\n *\n * @example\n * const locales = getLocales();\n * console.log(locales); // ['en-US', 'es-ES']\n */\nexport function getLocales() {\n const i18nManager = getI18nManager();\n return i18nManager.getLocales();\n}\n\n/**\n * Get the default locale\n * @returns The default locale\n *\n * @example\n * const defaultLocale = getDefaultLocale();\n * console.log(defaultLocale); // 'en-US'\n */\nexport function getDefaultLocale() {\n const i18nManager = getI18nManager();\n return i18nManager.getDefaultLocale();\n}\n\n/**\n * Get the locale properties\n * @param {string} [locale] - The locale to get the properties for. When not provided, uses the current locale.\n * @returns The locale properties\n *\n * @example\n * const localeProperties = getLocaleProperties();\n *\n * @example\n * const localeProperties = getLocaleProperties('en-US');\n */\nexport function getLocaleProperties(locale = getCurrentLocale()) {\n const i18nManager = getI18nManager();\n const gtInstance = i18nManager.getGTClass();\n return gtInstance.getLocaleProperties(locale);\n}\n","import { getI18nManager } from '../i18n-manager/singleton-operations';\n\n/**\n * Get the version ID for the current source\n * @returns The version ID, if set\n *\n * @example\n * const versionId = getVersionId();\n * console.log(versionId); // 'abc123'\n */\nexport function getVersionId() {\n const i18nManager = getI18nManager();\n return i18nManager.getVersionId();\n}\n"],"mappings":"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"}
|