gt-i18n 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # gt-i18n
2
2
 
3
+ ## 1.0.6
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1901](https://github.com/generaltranslation/gt/pull/1901) [`8836fbd`](https://github.com/generaltranslation/gt/commit/8836fbda088b5192b2eaa8e2109a724256458bc2) Thanks [@ErnestM1234](https://github.com/ErnestM1234)! - Forward the top-level `modelProvider` configuration to runtime translation requests while allowing explicit runtime metadata to override it.
8
+
9
+ - Updated dependencies [[`5d93858`](https://github.com/generaltranslation/gt/commit/5d9385872eb041af0991fc273d5eddd7a032e584), [`5721267`](https://github.com/generaltranslation/gt/commit/57212672a595c8c8578366636767bcbfe8ab6e57), [`8b9b440`](https://github.com/generaltranslation/gt/commit/8b9b4404b703b552b9aa327dc0ae85fce584c97c)]:
10
+ - generaltranslation@9.0.2
11
+
12
+ ## 1.0.5
13
+
14
+ ### Patch Changes
15
+
16
+ - Updated dependencies [[`3ad93f8`](https://github.com/generaltranslation/gt/commit/3ad93f89da099ef345b707bf37db425662d87e2a)]:
17
+ - generaltranslation@9.0.1
18
+
3
19
  ## 1.0.4
4
20
 
5
21
  ### Patch Changes
@@ -106,6 +106,7 @@ type I18nCacheConfig = {
106
106
  devApiKey?: string;
107
107
  apiKey?: string;
108
108
  runtimeUrl?: string | null;
109
+ modelProvider?: string;
109
110
  /**
110
111
  * Locale cache TTL in milliseconds. Undefined uses the default TTL, null
111
112
  * disables expiry, and a number sets an explicit TTL.
@@ -235,4 +236,4 @@ declare class WritableConditionStore extends ReadonlyConditionStore implements W
235
236
  }
236
237
  //#endregion
237
238
  export { Hash as _, I18nConfig as a, AsyncReadonlyConditionStoreInterface as c, I18nCacheConstructorParams as d, LocaleResolverConfig as f, TranslationsLoader as g, WritableConditionStoreInterface as h, ReadonlyConditionStoreParams as i, DictionaryConfig as l, ScopedConditionStoreInterface as m, WritableConditionStoreParams as n, I18nConfigParams as o, ReadonlyConditionStoreInterface as p, ReadonlyConditionStore as r, LocaleCandidates as s, WritableConditionStore as t, I18nCacheConfig as u, Locale as v, GTConfig as y };
238
- //# sourceMappingURL=WritableConditionStore-Y7klxD29.d.mts.map
239
+ //# sourceMappingURL=WritableConditionStore-BUblH4YU.d.mts.map
@@ -107,6 +107,7 @@ type I18nCacheConfig = {
107
107
  devApiKey?: string;
108
108
  apiKey?: string;
109
109
  runtimeUrl?: string | null;
110
+ modelProvider?: string;
110
111
  /**
111
112
  * Locale cache TTL in milliseconds. Undefined uses the default TTL, null
112
113
  * disables expiry, and a number sets an explicit TTL.
@@ -236,4 +237,4 @@ declare class WritableConditionStore extends ReadonlyConditionStore implements W
236
237
  }
237
238
  //#endregion
238
239
  export { Hash as _, I18nConfig as a, AsyncReadonlyConditionStoreInterface as c, I18nCacheConstructorParams as d, LocaleResolverConfig as f, TranslationsLoader as g, WritableConditionStoreInterface as h, ReadonlyConditionStoreParams as i, DictionaryConfig as l, ScopedConditionStoreInterface as m, WritableConditionStoreParams as n, I18nConfigParams as o, ReadonlyConditionStoreInterface as p, ReadonlyConditionStore as r, LocaleCandidates as s, WritableConditionStore as t, I18nCacheConfig as u, Locale as v, GTConfig as y };
239
- //# sourceMappingURL=WritableConditionStore-7OwoOSxr.d.cts.map
240
+ //# sourceMappingURL=WritableConditionStore-ekDSlgJ7.d.cts.map
@@ -1,4 +1,4 @@
1
1
  import { a as JsxTranslationOptions, c as NormalizedLookupOptions, d as TranslationOptions, f as TranslationVariables, i as GTTranslationOptions, l as RuntimeTranslationOptions, n as DictionaryLookupOptions, o as LookupOptions, r as EncodedTranslationOptions, s as LookupOptionsFor, t as DictionaryEntryOptions, u as TranslationMetadata } from "./options-BXeFwN0R.cjs";
2
- import { _ as Hash, c as AsyncReadonlyConditionStoreInterface, d as I18nCacheConstructorParams, f as LocaleResolverConfig, g as TranslationsLoader, h as WritableConditionStoreInterface, i as ReadonlyConditionStoreParams, l as DictionaryConfig, m as ScopedConditionStoreInterface, n as WritableConditionStoreParams, o as I18nConfigParams, p as ReadonlyConditionStoreInterface, s as LocaleCandidates, u as I18nCacheConfig, v as Locale, y as GTConfig } from "./WritableConditionStore-7OwoOSxr.cjs";
2
+ import { _ as Hash, c as AsyncReadonlyConditionStoreInterface, d as I18nCacheConstructorParams, f as LocaleResolverConfig, g as TranslationsLoader, h as WritableConditionStoreInterface, i as ReadonlyConditionStoreParams, l as DictionaryConfig, m as ScopedConditionStoreInterface, n as WritableConditionStoreParams, o as I18nConfigParams, p as ReadonlyConditionStoreInterface, s as LocaleCandidates, u as I18nCacheConfig, v as Locale, y as GTConfig } from "./WritableConditionStore-ekDSlgJ7.cjs";
3
3
  import { a as DictionaryLeaf, c as DictionaryValue, i as DictionaryKey, n as Dictionary, o as DictionaryObject, r as DictionaryEntry, s as DictionaryPath, t as DictionaryLoader } from "./DictionaryCache-DjAdDNiM.cjs";
4
4
  export { type AsyncReadonlyConditionStoreInterface, type Dictionary, type DictionaryConfig, type DictionaryEntry, DictionaryEntryOptions, type DictionaryKey, type DictionaryLeaf, type DictionaryLoader, DictionaryLookupOptions, type DictionaryObject, type DictionaryPath, type DictionaryValue, EncodedTranslationOptions, type GTConfig, GTTranslationOptions, type Hash, type I18nCacheConfig, type I18nCacheConstructorParams, type I18nConfigParams, JsxTranslationOptions, type Locale, type LocaleCandidates, type LocaleResolverConfig, LookupOptions, LookupOptionsFor, NormalizedLookupOptions, type ReadonlyConditionStoreInterface, type ReadonlyConditionStoreParams, RuntimeTranslationOptions, type ScopedConditionStoreInterface, TranslationMetadata, TranslationOptions, TranslationVariables, type TranslationsLoader, type WritableConditionStoreInterface, type WritableConditionStoreParams };
@@ -1,4 +1,4 @@
1
1
  import { a as JsxTranslationOptions, c as NormalizedLookupOptions, d as TranslationOptions, f as TranslationVariables, i as GTTranslationOptions, l as RuntimeTranslationOptions, n as DictionaryLookupOptions, o as LookupOptions, r as EncodedTranslationOptions, s as LookupOptionsFor, t as DictionaryEntryOptions, u as TranslationMetadata } from "./options-DDUyXaLT.mjs";
2
- import { _ as Hash, c as AsyncReadonlyConditionStoreInterface, d as I18nCacheConstructorParams, f as LocaleResolverConfig, g as TranslationsLoader, h as WritableConditionStoreInterface, i as ReadonlyConditionStoreParams, l as DictionaryConfig, m as ScopedConditionStoreInterface, n as WritableConditionStoreParams, o as I18nConfigParams, p as ReadonlyConditionStoreInterface, s as LocaleCandidates, u as I18nCacheConfig, v as Locale, y as GTConfig } from "./WritableConditionStore-Y7klxD29.mjs";
2
+ import { _ as Hash, c as AsyncReadonlyConditionStoreInterface, d as I18nCacheConstructorParams, f as LocaleResolverConfig, g as TranslationsLoader, h as WritableConditionStoreInterface, i as ReadonlyConditionStoreParams, l as DictionaryConfig, m as ScopedConditionStoreInterface, n as WritableConditionStoreParams, o as I18nConfigParams, p as ReadonlyConditionStoreInterface, s as LocaleCandidates, u as I18nCacheConfig, v as Locale, y as GTConfig } from "./WritableConditionStore-BUblH4YU.mjs";
3
3
  import { a as DictionaryLeaf, c as DictionaryValue, i as DictionaryKey, n as Dictionary, o as DictionaryObject, r as DictionaryEntry, s as DictionaryPath, t as DictionaryLoader } from "./DictionaryCache-B7oTBs5W.mjs";
4
4
  export { type AsyncReadonlyConditionStoreInterface, type Dictionary, type DictionaryConfig, type DictionaryEntry, DictionaryEntryOptions, type DictionaryKey, type DictionaryLeaf, type DictionaryLoader, DictionaryLookupOptions, type DictionaryObject, type DictionaryPath, type DictionaryValue, EncodedTranslationOptions, type GTConfig, GTTranslationOptions, type Hash, type I18nCacheConfig, type I18nCacheConstructorParams, type I18nConfigParams, JsxTranslationOptions, type Locale, type LocaleCandidates, type LocaleResolverConfig, LookupOptions, LookupOptionsFor, NormalizedLookupOptions, type ReadonlyConditionStoreInterface, type ReadonlyConditionStoreParams, RuntimeTranslationOptions, type ScopedConditionStoreInterface, TranslationMetadata, TranslationOptions, TranslationVariables, type TranslationsLoader, type WritableConditionStoreInterface, type WritableConditionStoreParams };
package/dist/internal.cjs CHANGED
@@ -851,6 +851,7 @@ var I18nCache = class {
851
851
  devApiKey: params.devApiKey,
852
852
  apiKey: params.apiKey,
853
853
  runtimeUrl: params.runtimeUrl,
854
+ modelProvider: params.modelProvider,
854
855
  cacheExpiryTime: params.cacheExpiryTime,
855
856
  batchConfig: params.batchConfig,
856
857
  runtimeTranslation: params.runtimeTranslation,
@@ -867,7 +868,10 @@ var I18nCache = class {
867
868
  }
868
869
  });
869
870
  const loadDictionary = params.loadDictionary ?? (() => Promise.resolve({}));
870
- this.createTranslateMany = createTranslateManyFactory(require_versionId.getI18nConfig().getGTClass(), this.config.runtimeTranslation?.timeout ?? DEFAULT_TRANSLATION_TIMEOUT, this.config.runtimeTranslation?.metadata ?? {});
871
+ this.createTranslateMany = createTranslateManyFactory(require_versionId.getI18nConfig().getGTClass(), this.config.runtimeTranslation?.timeout ?? DEFAULT_TRANSLATION_TIMEOUT, {
872
+ ...this.config.modelProvider && { modelProvider: this.config.modelProvider },
873
+ ...this.config.runtimeTranslation?.metadata
874
+ });
871
875
  const ttl = this.config.cacheExpiryTime;
872
876
  this.translations = new ResourceCache({
873
877
  ttl,
@@ -1 +1 @@
1
- {"version":3,"file":"internal.cjs","names":["getWritableConditionStore","getI18nCache","getI18nConfig","createLookupOptions","interpolateMessage","getWritableConditionStore","decodeOptions","isEncodedTranslationOptions","createLookupOptions","extractVariables","interpolateMessage","getWritableConditionStore","getI18nCache","getI18nConfig","getWritableConditionStore","resolveStringContentWithRuntimeFallback","prefetchStringContentWithRuntimeFallback","getI18nConfig","resolveJsxWithRuntimeFallback","getLocale","defaultCacheUrl","getI18nConfig","hashMessage","getLoadTranslationsType","getI18nConfig","getRuntimeEnvironment","defaultRuntimeApiUrl","getI18nConfig","getI18nConfig","hashMessage"],"sources":["../src/translation-functions/internal/getGT.ts","../src/translation-functions/internal/getMessages.ts","../src/translation-functions/internal/renderDictionaryEntry.ts","../src/i18n-cache/translations-manager/utils/dictionary-helpers.ts","../src/translation-functions/internal/renderDictionaryObject.ts","../src/translation-functions/internal/getTranslations.ts","../src/translation-functions/internal/tx.ts","../src/translation-functions/internal/runtime-translate.ts","../src/i18n-cache/translations-manager/utils/createTranslateMany.ts","../src/i18n-cache/translations-manager/translations-loaders/createRemoteTranslationLoader.ts","../src/i18n-cache/translations-manager/translations-loaders/routeCreateTranslationLoader.ts","../src/i18n-cache/translations-manager/utils/constants.ts","../src/i18n-cache/translations-manager/utils/dedupePending.ts","../src/i18n-cache/translations-manager/ResourceCache.ts","../src/i18n-cache/translations-manager/TranslationsCache.ts","../src/i18n-cache/translations-manager/utils/DictionarySourceNotFoundError.ts","../src/i18n-cache/translations-manager/utils/materialize-dictionary.ts","../src/i18n-cache/translations-manager/DictionaryCache.ts","../src/i18n-cache/I18nCache.ts","../src/condition-store/ReadonlyConditionStore.ts","../src/condition-store/WritableConditionStore.ts","../src/utils/listenerKeys.ts","../src/utils/request.ts"],"sourcesContent":["import { getI18nCache } from '../../i18n-cache/singleton-operations';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { GTTranslationOptions, TranslationMetadata } from '../types/options';\nimport { GTFunctionType } from '../types/functions';\nimport { interpolateMessage } from '../utils/interpolation/interpolateMessage';\nimport { createLookupOptions } from './helpers';\nimport type { StringFormat } from '@generaltranslation/format/types';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\nexport type Message = TranslationMetadata & {\n message: string;\n};\n\n/**\n * Returns the gt function that registers a string at build time and resolves its translation at runtime.\n * @returns A promise of the gt function\n *\n * @example\n * const gt = await getGT();\n * const greeting = gt('Hello, world!');\n */\nexport async function getGT(_messages?: Message[]): Promise<GTFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getGTInternal({ locale, enableI18n }, _messages);\n}\n\n/**\n * Condition store agnostic getGT function\n */\nexport async function getGTInternal(\n {\n locale,\n enableI18n,\n }: {\n locale: string;\n enableI18n: boolean;\n },\n _messages?: Message[]\n): Promise<GTFunctionType> {\n // Get the translation resolver\n const i18nCache = getI18nCache();\n const sourceLocale = getI18nConfig().getDefaultLocale();\n // Statically gated so bundlers can drop dev hot-reload work from\n // production builds.\n const devHotReloadEnabled =\n process.env.NODE_ENV !== 'production' &&\n getI18nConfig().isDevHotReloadEnabled();\n const lookupTranslation = await i18nCache.getLookupTranslation(\n enableI18n ? locale : sourceLocale\n );\n\n // dev hot reload translate compiler injected lookups\n if (devHotReloadEnabled && lookupTranslation.prefetchEntries) {\n await lookupTranslation.prefetchEntries(\n _messages?.map(({ message, ...options }) => ({\n message,\n options: {\n $format: 'ICU',\n ...options,\n },\n })) ?? []\n );\n }\n\n /**\n * Registers a message at build time and resolves its translation at runtime.\n * @param {string} message - The message to translate\n * @param {GTTranslationOptions} options - The options for the translation\n * @returns The translated message\n *\n * @example\n * // Simple translation without interpolation\n * const gt = await getGT();\n * const greeting = gt('Hello, world!');\n *\n * @example\n * // Translation with interpolation\n * const gt = await getGT();\n * const welcome = gt('Hello, {name}!', { name: 'Alice' });\n */\n const gt: GTFunctionType = (\n message: string,\n options: GTTranslationOptions = {}\n ) => {\n const targetLocale = enableI18n\n ? (options.$locale ?? locale)\n : getI18nConfig().getDefaultLocale();\n const lookupOptions = createLookupOptions<StringFormat>(\n targetLocale,\n options,\n 'ICU'\n );\n\n // Lookup translation\n const translation = lookupTranslation(message, lookupOptions);\n\n // Dev hot reload (fire and forget, will be available in a later lookup)\n if (devHotReloadEnabled && translation == null) {\n void i18nCache\n .lookupTranslationWithFallback(\n lookupOptions.$locale,\n message,\n lookupOptions\n )\n .catch(() => {});\n }\n\n // Format result\n return interpolateMessage({\n source: message,\n target: translation,\n options: lookupOptions,\n sourceLocale,\n });\n };\n\n return gt;\n}\n","import { GTTranslationOptions } from '../types/options';\nimport { decodeOptions } from '../msg/decodeOptions';\nimport { isEncodedTranslationOptions } from '../utils/isEncodedTranslationOptions';\nimport { getGTInternal } from './getGT';\nimport { MFunctionType } from '../types/functions';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\n/**\n * Returns the m function that resolves a registered message to its translation.\n * @returns A promise of the m function\n *\n * @example\n * // Registration\n * const registeredMessage = msg('Hello, world!');\n *\n * // Resolution\n * const m = await getMessages();\n * const greeting = m(registeredMessage);\n */\nexport async function getMessages(): Promise<MFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getMessagesInternal({ locale, enableI18n });\n}\n\n/**\n * Condition store agnostic getMessages function\n */\nexport async function getMessagesInternal({\n locale,\n enableI18n,\n}: {\n locale: string;\n enableI18n: boolean;\n}): Promise<MFunctionType> {\n // Get the gt function\n const gt = await getGTInternal({ locale, enableI18n });\n\n /**\n * Resolves a registered message to its translation.\n * @param {string | null | undefined} encodedMsg - The encoded message to decode and interpolate.\n * @param {GTTranslationOptions} options - The options to interpolate.\n * @returns - The decoded and interpolated message.\n *\n * @example\n * // Simple message without interpolation\n * const m = await getMessages();\n * const greeting = m(msg('Hello, world!'));\n *\n * @example\n * // Message with interpolation\n * const m = await getMessages();\n * const welcome = m(msg('Welcome, {user}!'), { user: 'Alice' });\n */\n const m: MFunctionType = <T extends string | null | undefined>(\n encodedMsg: T,\n options: GTTranslationOptions = {}\n ): T extends string ? string : T => {\n // Return if the encoded message is null or undefined\n if (encodedMsg == null) return encodedMsg as T extends string ? string : T;\n\n // Get any encoded options\n const decodedOptions = decodeOptions(encodedMsg) ?? {};\n\n // Return early if string already interpolated eg: mFallback(msg('Hello, {name}!', { name: 'Brian' }))\n if (isEncodedTranslationOptions(decodedOptions)) {\n return gt(decodedOptions.$_source, decodedOptions) as T extends string\n ? string\n : T;\n }\n\n // Use gt to interpolate\n // Separate from decoded options to match behavior in @gt/react-core\n return gt(encodedMsg, options) as T extends string ? string : T;\n };\n\n return m;\n}\n","import { createLookupOptions } from './helpers';\nimport { extractVariables } from '../../utils/extractVariables';\nimport { interpolateMessage } from '../utils/interpolation/interpolateMessage';\nimport type {\n DictionaryLookupOptions,\n TranslationVariables,\n} from '../types/options';\nimport type { DictionaryEntry } from '../../i18n-cache/translations-manager/DictionaryCache';\nimport type { StringFormat } from '@generaltranslation/format/types';\n\nexport function renderDictionaryEntry({\n sourceLocale,\n targetLocale,\n sourceEntry,\n target,\n dictionaryOptions,\n options = {},\n}: {\n sourceLocale: string;\n targetLocale: string;\n sourceEntry: DictionaryEntry;\n target: string | undefined;\n dictionaryOptions: DictionaryLookupOptions;\n options?: TranslationVariables;\n}): string {\n const lookupOptions = createLookupOptions<StringFormat>(\n targetLocale,\n {\n ...dictionaryOptions,\n ...extractVariables(options),\n },\n dictionaryOptions.$format\n );\n\n return interpolateMessage({\n source: sourceEntry.entry,\n target,\n options: lookupOptions,\n sourceLocale,\n });\n}\n","import type {\n Dictionary,\n DictionaryEntry,\n DictionaryLeaf,\n DictionaryPath,\n DictionaryValue,\n} from './types/dictionary';\nimport type {\n DictionaryEntryOptions,\n DictionaryLookupOptions,\n} from '../../../translation-functions/types/options';\n\nfunction getDictionaryPath(id: DictionaryPath): string[] {\n const path = id ? id.split('.') : [];\n for (const segment of path) {\n assertSafeDictionaryPathSegment(segment, id);\n }\n return path;\n}\n\nexport function assertSafeDictionaryPathSegment(\n segment: string,\n path: DictionaryPath\n): void {\n if (\n segment === '__proto__' ||\n segment === 'constructor' ||\n segment === 'prototype'\n ) {\n throw new Error(`Dictionary path \"${path}\" contains an unsafe segment`);\n }\n}\n\nexport function isDictionaryValue(value: unknown): value is Dictionary {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n}\n\nexport function cloneDictionaryValue<Value extends DictionaryValue | undefined>(\n value: Value\n): Value {\n if (value === undefined || typeof value === 'string') {\n return value;\n }\n return structuredClone(value) as Value;\n}\n\nexport function getDictionaryValueAtPath(\n dictionary: Dictionary,\n path: DictionaryPath\n): DictionaryValue | undefined {\n let current: DictionaryValue = dictionary;\n\n for (const segment of getDictionaryPath(path)) {\n if (!isDictionaryValue(current)) {\n return undefined;\n }\n current = current[segment];\n }\n\n return current;\n}\n\nexport function setDictionaryValueAtPath(\n dictionary: Dictionary,\n path: DictionaryPath,\n value: DictionaryValue\n): void {\n const segments = getDictionaryPath(path);\n if (isDictionaryValue(value)) {\n assertSafeDictionaryObject(value, path);\n }\n\n if (segments.length === 0) {\n if (isDictionaryValue(value)) {\n replaceDictionary(dictionary, value);\n }\n return;\n }\n\n let current = dictionary;\n for (const segment of segments.slice(0, -1)) {\n const next = current[segment];\n if (!isDictionaryValue(next)) {\n current[segment] = {} as Dictionary;\n }\n current = current[segment] as Dictionary;\n }\n\n const leafSegment = segments[segments.length - 1];\n current[leafSegment] = 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 };\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 && isDictionaryLeafOptions(value[1]);\n}\n\nfunction isDictionaryLeafOptions(\n value: unknown\n): value is DictionaryEntryOptions {\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 || typeof options.$maxChars === 'number')\n );\n}\n\nfunction isStringFormat(\n value: unknown\n): value is DictionaryLookupOptions['$format'] {\n return value === 'ICU' || value === 'I18NEXT' || value === 'STRING';\n}\n\nfunction replaceDictionary(target: Dictionary, source: Dictionary): void {\n for (const key of Object.keys(target)) {\n delete target[key];\n }\n for (const key of Object.keys(source)) {\n target[key] = source[key];\n }\n}\n\nfunction assertSafeDictionaryObject(\n dictionary: Dictionary,\n parentPath = ''\n): void {\n for (const [key, value] of Object.entries(dictionary)) {\n const path = parentPath ? `${parentPath}.${key}` : key;\n assertSafeDictionaryPathSegment(key, path);\n if (isDictionaryValue(value)) {\n assertSafeDictionaryObject(value, path);\n }\n }\n}\n","import {\n getDictionaryEntry,\n isDictionaryValue,\n resolveDictionaryLookupOptions,\n} from '../../i18n-cache/translations-manager/utils/dictionary-helpers';\nimport type { DictionaryObjectTranslation } from '../types/functions';\nimport type { DictionaryLookupOptions } from '../types/options';\nimport type {\n DictionaryEntry,\n DictionaryValue,\n} from '../../i18n-cache/translations-manager/DictionaryCache';\n\nexport function renderDictionaryObject({\n sourceObject,\n targetObject,\n translate,\n}: {\n sourceObject: DictionaryValue | undefined;\n targetObject: DictionaryValue | undefined;\n translate?: (\n sourceEntry: DictionaryEntry,\n dictionaryOptions: DictionaryLookupOptions\n ) => string | undefined;\n}): DictionaryObjectTranslation {\n const targetEntry = getDictionaryEntry(targetObject);\n if (targetEntry !== undefined) {\n return targetEntry.entry;\n }\n\n if (isDictionaryValue(targetObject)) {\n if (!isDictionaryValue(sourceObject)) {\n return renderDictionaryObject({\n sourceObject: targetObject,\n targetObject: undefined,\n translate,\n });\n }\n\n return renderDictionaryObjectChildren({\n sourceObject,\n targetObject,\n translate,\n });\n }\n\n const sourceEntry = getDictionaryEntry(sourceObject);\n if (sourceEntry !== undefined) {\n const dictionaryOptions = resolveDictionaryLookupOptions(\n sourceEntry.options\n );\n return translate?.(sourceEntry, dictionaryOptions) ?? sourceEntry.entry;\n }\n\n if (isDictionaryValue(sourceObject)) {\n return renderDictionaryObjectChildren({\n sourceObject,\n targetObject: undefined,\n translate,\n });\n }\n\n throw new Error('Dictionary object cannot be rendered');\n}\n\nfunction renderDictionaryObjectChildren({\n sourceObject,\n targetObject,\n translate,\n}: {\n sourceObject: DictionaryValue;\n targetObject: DictionaryValue | undefined;\n translate?: (\n sourceEntry: DictionaryEntry,\n dictionaryOptions: DictionaryLookupOptions\n ) => string | undefined;\n}): DictionaryObjectTranslation {\n if (!isDictionaryValue(sourceObject)) {\n return renderDictionaryObject({ sourceObject, targetObject, translate });\n }\n\n const result: Record<string, DictionaryObjectTranslation> = {};\n const keys = new Set([\n ...Object.keys(sourceObject),\n ...(isDictionaryValue(targetObject) ? Object.keys(targetObject) : []),\n ]);\n\n for (const key of Array.from(keys)) {\n const renderedChild = renderDictionaryObject({\n sourceObject: sourceObject[key],\n targetObject: isDictionaryValue(targetObject)\n ? targetObject[key]\n : undefined,\n translate,\n });\n if (renderedChild !== undefined) {\n result[key] = renderedChild;\n }\n }\n\n return result;\n}\n","import { getI18nCache } from '../../i18n-cache/singleton-operations';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { TranslationVariables } from '../types/options';\nimport { TFunctionType } from '../types/functions';\nimport { renderDictionaryEntry } from './renderDictionaryEntry';\nimport { renderDictionaryObject } from './renderDictionaryObject';\nimport { resolveDictionaryLookupOptions } from '../../i18n-cache/translations-manager/utils/dictionary-helpers';\nimport type { DictionaryObjectTranslation } from '../types/functions';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\n/**\n * Returns the t function that translates a dictionary entry based on its id and options.\n * @returns A promise of the t function\n * @important Must be used inside of a request context\n *\n * @example\n * const t = await getTranslations();\n * const title = await t('page.title');\n */\nexport async function getTranslations(rootId?: string): Promise<TFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getTranslationsInternal({ locale, enableI18n, rootId });\n}\n\n/**\n * Condition store agnostic getTranslations function\n */\nexport async function getTranslationsInternal({\n locale,\n enableI18n,\n rootId,\n}: {\n locale: string;\n enableI18n: boolean;\n rootId?: string;\n}): Promise<TFunctionType> {\n const i18nCache = getI18nCache();\n const sourceLocale = getI18nConfig().getDefaultLocale();\n const targetLocale = enableI18n ? locale : sourceLocale;\n const [sourceDictionary, targetDictionary, lookupTranslation] =\n await Promise.all([\n i18nCache.getLookupDictionary(sourceLocale),\n i18nCache.getLookupDictionary(targetLocale),\n i18nCache.getLookupTranslation(targetLocale),\n ]);\n const {\n lookupDictionary: lookupSourceDictionary,\n lookupDictionaryObj: lookupSourceDictionaryObj,\n } = sourceDictionary;\n const {\n lookupDictionary: lookupTargetDictionary,\n lookupDictionaryObj: lookupTargetDictionaryObj,\n } = targetDictionary;\n\n /**\n * Dictionary resolution\n * @param {string} id - The id of the translation to translate.\n * @param {TranslationVariables} options - The variables for interpolation.\n * @returns {string} The translated message.\n *\n * @example\n * // Simple dictionary lookup without interpolation\n * const t = await getTranslations();\n * const title = t('page.title');\n *\n * @example\n * // Dictionary lookup with interpolation\n * const t = await getTranslations();\n * const greeting = t('user.greeting', { name: 'Bob' });\n */\n const t = ((id: string, options: TranslationVariables = {}): string => {\n id = getId(rootId, id);\n const sourceEntry = lookupSourceDictionary(id);\n if (sourceEntry === undefined) {\n throw new Error(`Dictionary entry ${id} cannot be found`);\n }\n const targetEntry = lookupTargetDictionary(id);\n const dictionaryOptions = resolveDictionaryLookupOptions(\n sourceEntry.options\n );\n const target =\n targetEntry?.entry ??\n lookupTranslation(sourceEntry.entry, dictionaryOptions);\n return renderDictionaryEntry({\n sourceLocale,\n targetLocale: targetLocale,\n sourceEntry,\n target,\n dictionaryOptions,\n options,\n });\n }) as TFunctionType;\n\n /**\n * Returns a subtree of the dictionary object translation based on its id.\n * @param {string} id - The id of the translation to translate.\n * @returns The translated object.\n *\n * @example\n * const t = await getTranslations();\n * const greetings = t.obj('greetings');\n * console.log(greetings);\n * // { greeting1: 'Hello', greeting2: 'Hi' }\n */\n t.obj = (id: string): DictionaryObjectTranslation => {\n id = getId(rootId, id);\n const sourceObject = lookupSourceDictionaryObj(id);\n if (sourceObject === undefined) {\n throw new Error(`Dictionary entry ${id} cannot be found`);\n }\n const targetObject = lookupTargetDictionaryObj(id);\n return renderDictionaryObject({\n sourceObject,\n targetObject,\n translate: (sourceEntry, dictionaryOptions) =>\n lookupTranslation(sourceEntry.entry, dictionaryOptions),\n });\n };\n\n return t;\n}\n\nfunction getId(prefix: string | undefined, suffix: string): string {\n return prefix ? `${prefix}.${suffix}` : suffix;\n}\n","import { RuntimeTranslationOptions } from '../types/options';\nimport type { StringFormat } from '@generaltranslation/format/types';\nimport {\n prefetchStringContentWithRuntimeFallback,\n resolveStringContentWithRuntimeFallback,\n} from './helpers';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\ntype RuntimeTranslationOptionsWithFormat = Omit<\n RuntimeTranslationOptions,\n '$format'\n> & {\n $format?: StringFormat;\n};\n\n/**\n * Translates a message at runtime.\n * @param {string} message - The message to translate.\n * @param {RuntimeTranslationOptions} options - The options for the translation.\n * @returns {Promise<string>} The translated message.\n *\n * @example\n * // Simple runtime translation without interpolation\n * const status = await tx('Processing complete', { $locale: 'es-MX' });\n *\n * @example\n * // Runtime translation with interpolation\n * const progress = await tx(`Processing ${status}`, { $locale: 'es-MX' });\n */\nexport async function tx(\n content: string,\n options: RuntimeTranslationOptionsWithFormat = {}\n): Promise<string> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n\n return txInternal({ locale, enableI18n, content, options });\n}\n\n/**\n * Condition store agnostic tx function\n */\nexport async function txInternal({\n locale,\n enableI18n,\n content,\n options,\n}: {\n locale: string;\n enableI18n: boolean;\n content: string;\n options: RuntimeTranslationOptionsWithFormat;\n}): Promise<string> {\n const targetLocale = getTargetLocale({ locale, enableI18n, options });\n return resolveStringContentWithRuntimeFallback(targetLocale, content, {\n $format: 'STRING',\n ...options,\n });\n}\n\n/**\n * Registers a message for runtime translation without interpolating the\n * result. For compiler-injected prefetch calls: their return value is\n * discarded and variable values only exist at the render-time call site, so\n * interpolating here would fail for any message with placeholders.\n */\nexport async function txPrefetch(\n content: string,\n options: RuntimeTranslationOptionsWithFormat = {}\n): Promise<void> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n const targetLocale = getTargetLocale({ locale, enableI18n, options });\n await prefetchStringContentWithRuntimeFallback(targetLocale, content, {\n $format: 'STRING',\n ...options,\n });\n}\n\nfunction getTargetLocale({\n locale,\n enableI18n,\n options,\n}: {\n locale: string;\n enableI18n: boolean;\n options: RuntimeTranslationOptionsWithFormat;\n}): string {\n return enableI18n\n ? typeof options.$locale === 'string'\n ? options.$locale\n : locale\n : getI18nConfig().getDefaultLocale();\n}\n","import type {\n JsxChildren,\n StringFormat,\n} from '@generaltranslation/format/types';\nimport { getLocale } from '../../helpers/locale';\nimport type {\n JsxTranslationOptions,\n RuntimeTranslationOptions,\n} from '../types/options';\nimport { resolveJsxWithRuntimeFallback } from './helpers';\nimport { txPrefetch } from './tx';\n\ntype RuntimeStringTranslationOptions = Omit<\n RuntimeTranslationOptions,\n '$format'\n> & {\n $format?: StringFormat;\n};\n\ntype RuntimeJsxTranslationOptions = JsxTranslationOptions & {\n $locale?: string;\n};\n\nexport const GtInternalRuntimeTranslateString = (\n content: string,\n options: RuntimeStringTranslationOptions = {}\n) => {\n // Prefetch/registration only — the compiler-injected call discards the\n // result, and variable values are unavailable here, so the translation\n // must not be interpolated.\n return txPrefetch(content, { $format: 'ICU', ...options });\n};\n\nexport const GtInternalRuntimeTranslateJsx = (\n content: JsxChildren,\n options: RuntimeJsxTranslationOptions = {}\n) => {\n const locale = options.$locale ?? getLocale();\n return resolveJsxWithRuntimeFallback(locale, content, {\n $format: 'JSX',\n ...options,\n });\n};\n","import type { RuntimeTranslateManyOptions } from 'generaltranslation/internal';\nimport type { Locale } from '../TranslationsCache';\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';\nimport { LoadTranslationsType } from '../../utils/getLoadTranslationsType';\nimport logger from '../../../logs/logger';\nimport { createRemoteTranslationLoader } from './createRemoteTranslationLoader';\nimport { getI18nConfig } from '../../../i18n-config/singleton-operations';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\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 };\n loadTranslations?: TranslationsLoader;\n}): TranslationsLoader {\n const { cacheUrl, projectId, _versionId, _branchId } =\n remoteTranslationLoaderParams;\n\n // Warnings are deferred to loader invocation: translations may be provided\n // externally via updateTranslations() (eg streamed from a server), in which\n // case the loader is never invoked and the warnings do not apply\n switch (type) {\n case LoadTranslationsType.REMOTE:\n case LoadTranslationsType.GT_REMOTE:\n // Only reachable for REMOTE: GT_REMOTE requires a projectId\n if (!projectId) {\n return createWarnOnceTranslationLoader(\n createDiagnosticMessage({\n whatHappened:\n 'Loading translations from a remote store needs a projectId. No translations will be loaded.',\n fix: 'Add projectId to the I18nCache config, or set cacheUrl to null to disable translation loading',\n })\n );\n }\n return createRemoteTranslationLoader({\n cacheUrl: cacheUrl as string | undefined,\n projectId,\n _versionId,\n _branchId,\n customMapping: getI18nConfig().getCustomMapping(),\n });\n case LoadTranslationsType.CUSTOM:\n return loadTranslations!;\n case LoadTranslationsType.DISABLED:\n // cacheUrl: null is an explicit opt-out of translation loading\n if (cacheUrl === null) {\n return async () => ({});\n }\n return createWarnOnceTranslationLoader(\n createDiagnosticMessage({\n whatHappened:\n 'No translation loader found. No translations will be loaded.',\n fix: 'Add projectId to the I18nCache config (to load from the GT remote store), provide a loadTranslations function, or set cacheUrl to null to disable translation loading',\n })\n );\n }\n}\n\n/**\n * Loads no translations and logs a warning once on first invocation\n */\nfunction createWarnOnceTranslationLoader(warning: string): TranslationsLoader {\n let warned = false;\n return async (_locale: string) => {\n if (!warned) {\n warned = true;\n logger.warn('I18nCache: ' + warning);\n }\n return {};\n };\n}\n","/**\n * Default cache expiry time in milliseconds\n */\nexport const DEFAULT_CACHE_EXPIRY_TIME = 60_000; // 60 sec\n","/**\n * Share one in-flight promise per key: concurrent callers for the same key\n * await the same promise, and the pending entry is cleared once it settles.\n */\nexport async function dedupePending<Key, Value>(\n pending: Map<Key, Promise<Value>>,\n key: Key,\n create: () => Promise<Value>\n): Promise<Value> {\n let promise = pending.get(key);\n if (!promise) {\n promise = create();\n pending.set(key, promise);\n }\n\n try {\n return await promise;\n } finally {\n pending.delete(key);\n }\n}\n","import { DEFAULT_CACHE_EXPIRY_TIME } from './utils/constants';\nimport { dedupePending } from './utils/dedupePending';\n\nexport type ResourceCacheEntry<Value> = {\n expiresAt: number;\n value: Value;\n};\n\nexport class ResourceCache<Key extends string, Value> {\n private cache = new Map<Key, ResourceCacheEntry<Value>>();\n private pendingLoads = new Map<Key, Promise<Value>>();\n private loadResource: (key: Key) => Promise<Value>;\n private ttl: number;\n\n constructor({\n load,\n ttl,\n }: {\n load: (key: Key) => Promise<Value>;\n ttl?: number | null;\n }) {\n this.loadResource = load;\n this.ttl = ttl === null ? -1 : (ttl ?? DEFAULT_CACHE_EXPIRY_TIME);\n }\n\n public get(key: Key): Value | undefined {\n const entry = this.cache.get(key);\n if (!entry || this.isExpired(entry)) {\n return undefined;\n }\n\n return entry.value;\n }\n\n public set(\n key: Key,\n value: Value,\n { expiresAt = this.getExpiresAt() }: { expiresAt?: number } = {}\n ): void {\n this.cache.set(key, {\n expiresAt,\n value,\n });\n }\n\n public async getOrLoad(key: Key): Promise<Value> {\n return this.get(key) ?? (await this.load(key));\n }\n\n private load(key: Key): Promise<Value> {\n return dedupePending(this.pendingLoads, key, () =>\n // The entry expiry is computed when the load resolves, not when it starts\n this.loadResource(key).then((value) => {\n this.set(key, value);\n return value;\n })\n );\n }\n\n private getExpiresAt(): number {\n // Avoid Date.now() for Next.js Cache Components; Next handles caching.\n return this.ttl <= 0 ? this.ttl : Date.now() + this.ttl;\n }\n\n private isExpired(entry: ResourceCacheEntry<Value>): boolean {\n // Avoid Date.now() for Next.js Cache Components; Next handles caching.\n if (entry.expiresAt === 0) return true;\n return entry.expiresAt > 0 && entry.expiresAt < Date.now();\n }\n}\n","import { LookupOptions } from '../../translation-functions/types/options';\nimport { Translation } from './utils/types/translation-data';\nimport { hashMessage } from '../../utils/hashMessage';\nimport { dedupePending } from './utils/dedupePending';\nimport type { Content } from '@generaltranslation/format/types';\nimport type {\n EntryMetadata,\n TranslateManyEntry,\n TranslationResult,\n} from 'generaltranslation/types';\n\nexport type TranslationBatchConfig = {\n maxConcurrentRequests?: number;\n maxBatchSize?: number;\n batchInterval?: number;\n};\n\n// See gt-next\nconst DEFAULT_BATCH_CONFIG: Required<TranslationBatchConfig> = {\n maxConcurrentRequests: 100,\n maxBatchSize: 25,\n batchInterval: 50,\n};\n\nfunction getPositiveValue(\n value: number | undefined,\n defaultValue: number,\n integer = false\n) {\n if (value === undefined || !Number.isFinite(value)) return defaultValue;\n const resolved = integer ? Math.trunc(value) : value;\n return resolved > 0 ? resolved : defaultValue;\n}\n\nfunction normalizeBatchConfig(\n batchConfig?: TranslationBatchConfig\n): Required<TranslationBatchConfig> {\n return {\n maxConcurrentRequests: getPositiveValue(\n batchConfig?.maxConcurrentRequests,\n DEFAULT_BATCH_CONFIG.maxConcurrentRequests,\n true\n ),\n maxBatchSize: getPositiveValue(\n batchConfig?.maxBatchSize,\n DEFAULT_BATCH_CONFIG.maxBatchSize,\n true\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 * Just being explicit about the purpose of this type\n */\nexport type Locale = string;\n\n/**\n * Called when a translation is resolved through a runtime cache miss.\n * Locale is handled by the I18nCache that owns this cache, so it is not\n * passed here.\n */\nexport type TranslationsCacheMissCallback<\n TranslationValue extends Translation,\n> = (hash: Hash, translation: TranslationValue) => void;\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 by the owning I18nCache. Use a callback function that has the\n * locale parameter embedded if you wish to use the locale code.\n */\nexport class TranslationsCache<TranslationValue extends Translation> {\n private cache: Record<Hash, TranslationValue>;\n private pendingTranslations = new Map<Hash, Promise<TranslationValue>>();\n private queue: Array<QueueEntry<TranslationValue>> = [];\n private batchTimer: ReturnType<typeof setTimeout> | null = null;\n private activeRequests = 0;\n private batchConfig: Required<TranslationBatchConfig>;\n private translateMany: TranslateMany;\n private onMiss?: TranslationsCacheMissCallback<TranslationValue>;\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 onMiss,\n batchConfig,\n }: {\n init: Record<Hash, TranslationValue>;\n translateMany: TranslateMany;\n batchConfig?: TranslationBatchConfig;\n onMiss?: TranslationsCacheMissCallback<TranslationValue>;\n }) {\n this.cache = structuredClone(init);\n this.translateMany = translateMany;\n this.batchConfig = normalizeBatchConfig(batchConfig);\n this.onMiss = onMiss;\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 cacheKey = this.getCacheKey(key);\n return this.cache[cacheKey] as T | undefined;\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 cacheKey = this.getCacheKey(key);\n const value = await dedupePending(this.pendingTranslations, cacheKey, () =>\n this.translate(key)\n );\n if (value != null) {\n this.onMiss?.(cacheKey, value);\n }\n return value as T;\n }\n\n public getInternalCache(): Record<Hash, TranslationValue> {\n return structuredClone(this.cache);\n }\n\n private getCacheKey(key: TranslationKey<TranslationValue>): Hash {\n return hashMessage(key.message, key.options);\n }\n\n private translate(\n key: TranslationKey<TranslationValue>\n ): Promise<TranslationValue> {\n const translationPromise = this.enqueueTranslation(key);\n\n if (this.queue.length >= this.batchConfig.maxBatchSize) {\n this.flushNow();\n } else {\n this.scheduleBatch();\n }\n\n return translationPromise;\n }\n\n public update(translations: Record<Hash, TranslationValue>): void {\n this.cache = { ...this.cache, ...translations };\n }\n\n private flushNow(): void {\n if (this.batchTimer) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n this.drainQueue();\n }\n\n private scheduleBatch(): void {\n if (this.batchTimer) return;\n this.batchTimer = setTimeout(() => {\n this.batchTimer = null;\n this.drainQueue();\n }, this.batchConfig.batchInterval);\n }\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\n if (this.queue.length > 0) {\n this.scheduleBatch();\n }\n }\n\n private enqueueTranslation(\n key: TranslationKey<TranslationValue>\n ): Promise<TranslationValue> {\n const hash = this.getCacheKey(key);\n const options = key.options;\n const metadataOptions = options as {\n $context?: string;\n $id?: string;\n $maxChars?: number;\n $requiresReview?: boolean;\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 // The hash is review-aware; the request metadata must carry the\n // same intent so the platform records it on anything it persists\n ...(metadataOptions.$requiresReview === true && {\n requiresReview: true,\n }),\n dataFormat: options.$format,\n },\n resolve: (value) => resolve(value as TranslationValue),\n reject,\n });\n });\n }\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 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 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.cache[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","export class DictionarySourceNotFoundError extends Error {\n constructor(id: string) {\n super(`I18nCache: source dictionary entry ${id} is not defined`);\n this.name = 'DictionarySourceNotFoundError';\n }\n}\n","import { DictionarySourceNotFoundError } from './DictionarySourceNotFoundError';\nimport {\n assertSafeDictionaryPathSegment,\n cloneDictionaryValue,\n getDictionaryEntry,\n isDictionaryValue,\n} from './dictionary-helpers';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryValue,\n} from './types/dictionary';\n\nexport type TranslateDictionaryEntry = (\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n) => Promise<DictionaryValue>;\n\n/**\n * Builds the dictionary value for a requested path by combining existing target\n * translations with runtime translations of any source leaves that are missing.\n */\nexport async function materializeDictionaryValue({\n key,\n sourceValue,\n targetValue,\n translateEntry,\n}: {\n key: DictionaryKey;\n sourceValue: DictionaryValue;\n targetValue: DictionaryValue | undefined;\n translateEntry: TranslateDictionaryEntry;\n}): Promise<DictionaryValue> {\n if (getDictionaryEntry(targetValue) !== undefined) {\n return cloneDictionaryValue(targetValue as DictionaryValue);\n }\n\n if (isDictionaryValue(targetValue) && !isDictionaryValue(sourceValue)) {\n return cloneDictionaryValue(targetValue);\n }\n\n const sourceEntry = getDictionaryEntry(sourceValue);\n if (sourceEntry !== undefined) {\n return await translateEntry(key, sourceEntry);\n }\n\n if (!isDictionaryValue(sourceValue)) {\n throw new DictionarySourceNotFoundError(key);\n }\n\n const targetDictionary = isDictionaryValue(targetValue) ? targetValue : {};\n const keys = new Set([\n ...Object.keys(sourceValue),\n ...Object.keys(targetDictionary),\n ]);\n const entries = await Promise.all(\n Array.from(keys).map(async (childKey) => {\n const childPath = key ? `${key}.${childKey}` : childKey;\n assertSafeDictionaryPathSegment(childKey, childPath);\n\n const childSource = sourceValue[childKey];\n if (childSource === undefined) {\n return [\n childKey,\n cloneDictionaryValue(targetDictionary[childKey]),\n ] as const;\n }\n\n return [\n childKey,\n await materializeDictionaryValue({\n key: childPath,\n sourceValue: childSource,\n targetValue: targetDictionary[childKey],\n translateEntry,\n }),\n ] as const;\n })\n );\n\n return Object.fromEntries(entries) as Dictionary;\n}\n","import {\n cloneDictionaryValue,\n getDictionaryEntry,\n getDictionaryValue,\n getDictionaryValueAtPath,\n isDictionaryValue,\n setDictionaryValueAtPath,\n} from './utils/dictionary-helpers';\nimport { materializeDictionaryValue } from './utils/materialize-dictionary';\nimport { dedupePending } from './utils/dedupePending';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryPath,\n DictionaryValue,\n} from './utils/types/dictionary';\nexport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryLeaf,\n DictionaryObject,\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 DictionaryLoader = (locale: string) => Promise<Dictionary>;\n\nfunction cloneDictionaryEntry(entry: DictionaryEntry): DictionaryEntry {\n return {\n entry: entry.entry,\n options: structuredClone(entry.options),\n };\n}\n\nexport class DictionaryCache {\n private cache: Dictionary;\n private pendingTranslations = new Map<\n DictionaryKey,\n Promise<DictionaryEntry>\n >();\n private pendingMaterializations = new Map<\n DictionaryKey,\n Promise<DictionaryValue>\n >();\n private runtimeTranslate: DictionaryRuntimeTranslate;\n\n constructor({\n init,\n runtimeTranslate,\n }: {\n init: Dictionary;\n runtimeTranslate: DictionaryRuntimeTranslate;\n }) {\n this.cache = structuredClone(init);\n this.runtimeTranslate = runtimeTranslate;\n }\n\n public getEntry(key: DictionaryKey): DictionaryEntry | undefined {\n const value = getDictionaryValueAtPath(this.cache, key);\n const entry = getDictionaryEntry(value);\n if (entry === undefined) {\n return undefined;\n }\n return cloneDictionaryEntry(entry);\n }\n\n public getValue(key: DictionaryKey): DictionaryValue | undefined {\n const value = getDictionaryValueAtPath(this.cache, key);\n if (value === undefined) {\n return undefined;\n }\n return cloneDictionaryValue(value);\n }\n\n public setValue(key: DictionaryKey, value: DictionaryValue): void {\n setDictionaryValueAtPath(this.cache, key, cloneDictionaryValue(value));\n }\n\n public getInternalCache(): Dictionary {\n return cloneDictionaryValue(this.cache);\n }\n\n public update(dictionary: Dictionary): void {\n mergeDictionary(this.cache, dictionary);\n }\n\n public async materializeValue(\n key: DictionaryKey,\n sourceValue: DictionaryValue,\n targetValue = getDictionaryValueAtPath(this.cache, key)\n ): Promise<DictionaryValue> {\n return dedupePending(this.pendingMaterializations, key, () =>\n materializeDictionaryValue({\n key,\n sourceValue,\n targetValue,\n translateEntry: async (entryKey, sourceEntry) =>\n getDictionaryValue(\n await this.materializeEntry(entryKey, sourceEntry)\n ),\n }).then((value) => {\n this.setValue(key, value);\n return value;\n })\n );\n }\n\n public async materializeEntry(\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n ): Promise<DictionaryEntry> {\n return cloneDictionaryEntry(\n await dedupePending(this.pendingTranslations, key, () =>\n this.runtimeTranslate(key, sourceEntry).then((value) => {\n setDictionaryValueAtPath(this.cache, key, value);\n const entry = getDictionaryEntry(value);\n if (entry === undefined) {\n // Never will happen\n throw new Error(\n 'DictionaryCache materializeEntry did not return a DictionaryEntry'\n );\n }\n return cloneDictionaryEntry(entry);\n })\n )\n );\n }\n}\n\nfunction mergeDictionary(target: Dictionary, source: Dictionary): void {\n for (const [key, value] of Object.entries(source)) {\n const targetValue = target[key];\n if (isDictionaryValue(targetValue) && isDictionaryValue(value)) {\n mergeDictionary(targetValue, value);\n } else {\n target[key] = cloneDictionaryValue(value);\n }\n }\n}\n","import logger from '../logs/logger';\nimport { I18nCacheConfig, I18nCacheConstructorParams } from './types';\nimport {\n createDiagnosticMessage,\n defaultRuntimeApiUrl,\n} from 'generaltranslation/internal';\nimport { Translation } from './translations-manager/utils/types/translation-data';\nimport { LookupOptions } from '../translation-functions/types/options';\nimport { SafeTranslationsLoader } from './translations-manager/translations-loaders/types';\nimport {\n createTranslateManyFactory,\n type CreateTranslateMany,\n} from './translations-manager/utils/createTranslateMany';\nimport { routeCreateTranslationLoader } from './translations-manager/translations-loaders/routeCreateTranslationLoader';\nimport { getLoadTranslationsType } from './utils/getLoadTranslationsType';\nimport { ResourceCache } from './translations-manager/ResourceCache';\nimport { TranslationsCache } from './translations-manager/TranslationsCache';\nimport type { Hash, Locale } from './translations-manager/TranslationsCache';\nimport { DictionaryCache } from './translations-manager/DictionaryCache';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryObject,\n} from './translations-manager/DictionaryCache';\nimport { resolveDictionaryLookupOptions } from './translations-manager/utils/dictionary-helpers';\nimport { DictionarySourceNotFoundError } from './translations-manager/utils/DictionarySourceNotFoundError';\nimport { getRuntimeEnvironment } from '../utils/getRuntimeEnvironment';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\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\ntype DictionaryResolver = (id: string) => DictionaryEntry | undefined;\n\ntype DictionaryObjResolver = (id: string) => DictionaryObject | undefined;\n\ntype DictionaryResolvers = {\n lookupDictionary: DictionaryResolver;\n lookupDictionaryObj: DictionaryObjResolver;\n};\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 * Callback function to prefetch entries during the async period\n */\ntype PrefetchEntriesType<TranslationType extends Translation> = (\n prefetchEntries: PrefetchEntry<TranslationType>[]\n) => Promise<void>;\n\n/**\n * Event fired when a runtime translation resolves a cache miss\n */\nexport type TranslationsCacheMissEvent<\n TranslationValue extends Translation = Translation,\n> = {\n locale: Locale;\n hash: Hash;\n translation: TranslationValue;\n};\n\n/**\n * Class for managing translation functionality\n * @template TranslationValue - The type of the translation that will be cached\n */\nclass I18nCache<TranslationValue extends Translation = Translation> {\n protected config: I18nCacheConfig;\n\n /**\n * Single dev hot-reload listener for runtime-translation cache misses.\n * Subclasses that add cache-miss behavior should wrap any existing listener\n * instead of overwriting it.\n */\n protected onTranslationsCacheMiss?: (\n event: TranslationsCacheMissEvent<TranslationValue>\n ) => void;\n\n /**\n * Locale-keyed caches for translations and dictionaries\n */\n private translations: ResourceCache<\n Locale,\n TranslationsCache<TranslationValue>\n >;\n private dictionaries: ResourceCache<Locale, DictionaryCache>;\n\n /**\n * Creates a locale-bound translateMany for runtime translation\n */\n private createTranslateMany: CreateTranslateMany;\n\n /**\n * Creates an instance of I18nCache.\n * TODO: resolve gtConfig from just file path\n * @param params - The parameters for the I18nCache constructor\n * @param params.config - The configuration for the I18nCache\n */\n constructor(params: I18nCacheConstructorParams) {\n // Validation\n validateCacheParams(params);\n\n this.config = {\n projectId: params.projectId,\n devApiKey: params.devApiKey,\n apiKey: params.apiKey,\n runtimeUrl: params.runtimeUrl,\n cacheExpiryTime: params.cacheExpiryTime,\n batchConfig: params.batchConfig,\n runtimeTranslation: params.runtimeTranslation,\n _versionId: params._versionId,\n };\n\n // Create cache miss handlers\n const loadTranslations = 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 },\n }) as SafeTranslationsLoader<TranslationValue>;\n const loadDictionary = params.loadDictionary ?? (() => Promise.resolve({}));\n this.createTranslateMany = createTranslateManyFactory(\n getI18nConfig().getGTClass(),\n this.config.runtimeTranslation?.timeout ?? DEFAULT_TRANSLATION_TIMEOUT,\n this.config.runtimeTranslation?.metadata ?? {}\n );\n\n // Setup locale-keyed caches\n const ttl = this.config.cacheExpiryTime;\n this.translations = new ResourceCache<\n Locale,\n TranslationsCache<TranslationValue>\n >({\n ttl,\n load: async (locale) =>\n this.createTranslationsCache(locale, await loadTranslations(locale)),\n });\n this.dictionaries = new ResourceCache<Locale, DictionaryCache>({\n ttl,\n load: async (locale) =>\n this.createDictionaryCache(locale, await loadDictionary(locale)),\n });\n\n // The default locale's source dictionary is provided synchronously and\n // never expires\n const defaultLocale = getI18nConfig().getDefaultLocale();\n this.dictionaries.set(\n defaultLocale,\n this.createDictionaryCache(defaultLocale, params.dictionary ?? {}),\n { expiresAt: -1 }\n );\n }\n\n // ========== Cache Factories ========== //\n\n private createTranslationsCache(\n locale: Locale,\n init: Record<Hash, TranslationValue>\n ): TranslationsCache<TranslationValue> {\n return new TranslationsCache<TranslationValue>({\n init,\n translateMany: this.createTranslateMany(locale),\n batchConfig: this.config.batchConfig,\n onMiss: (hash, translation) =>\n this.onTranslationsCacheMiss?.({ locale, hash, translation }),\n });\n }\n\n private createDictionaryCache(\n locale: Locale,\n init: Dictionary\n ): DictionaryCache {\n return new DictionaryCache({\n init,\n runtimeTranslate: (id, sourceEntry) =>\n this.translateDictionaryEntry(locale, id, sourceEntry),\n });\n }\n\n // ========== Getters and Setters ========== //\n\n /**\n * Get the version ID\n */\n getVersionId(): string | undefined {\n return this.config._versionId;\n }\n\n // ========== Translation Updates ========== //\n\n updateTranslations(\n translationsSnapshot: Record<Locale, Record<Hash, TranslationValue>>\n ): void {\n for (const locale in translationsSnapshot) {\n const txCache = this.translations.get(locale);\n if (txCache) {\n txCache.update(translationsSnapshot[locale]);\n } else {\n this.translations.set(\n locale,\n this.createTranslationsCache(locale, translationsSnapshot[locale])\n );\n }\n }\n }\n\n updateDictionaries(dictionarySnapshot: Record<Locale, Dictionary>): void {\n for (const locale in dictionarySnapshot) {\n const dictionaryCache = this.dictionaries.get(locale);\n if (dictionaryCache) {\n dictionaryCache.update(dictionarySnapshot[locale]);\n } else {\n this.dictionaries.set(\n locale,\n this.createDictionaryCache(locale, dictionarySnapshot[locale])\n );\n }\n }\n }\n\n // ========== Translation Resolution ========== //\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 return this.guardAsync({}, async () => {\n // Validate\n const translationLocale = this._resolveCacheLocale(locale);\n if (!translationLocale) {\n return {};\n }\n\n const txCache = await this.translations.getOrLoad(translationLocale);\n\n // Get the translations\n return txCache.getInternalCache();\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 return this.guardAsync({}, async () => {\n // Validate\n const dictionaryLocale = this._resolveCacheLocale(locale);\n if (!dictionaryLocale) {\n return this.getDefaultDictionaryCache()?.getInternalCache() ?? {};\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n\n return dictionaryCache.getInternalCache();\n });\n }\n\n /**\n * Look up a dictionary entry\n */\n lookupDictionary(locale: string, id: string): DictionaryEntry | undefined {\n return this.guard(undefined, () =>\n this.dictionaries\n .get(this.resolveDictionaryCacheLocale(locale))\n ?.getEntry(id)\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 return this.guard(undefined, () =>\n this.dictionaries\n .get(this.resolveDictionaryCacheLocale(locale))\n ?.getValue(id)\n );\n }\n\n async getLookupDictionary(locale: string): Promise<DictionaryResolvers> {\n return this.guardAsync<DictionaryResolvers>(\n {\n lookupDictionary: () => undefined,\n lookupDictionaryObj: () => undefined,\n },\n async () => {\n const asyncBoundaryLocale = this._resolveCacheLocale(locale);\n const asyncBoundaryDictionaryCache = asyncBoundaryLocale\n ? await this.dictionaries.getOrLoad(asyncBoundaryLocale)\n : this.getDefaultDictionaryCache();\n\n return {\n lookupDictionary: (id) => asyncBoundaryDictionaryCache?.getEntry(id),\n lookupDictionaryObj: (id) =>\n asyncBoundaryDictionaryCache?.getValue(id),\n };\n }\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 return this.guardAsync(undefined, async () => {\n const dictionaryLocale = this._resolveCacheLocale(locale);\n if (!dictionaryLocale) {\n return this.getSourceDictionaryEntry(id);\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n\n return (\n dictionaryCache.getEntry(id) ??\n (await dictionaryCache.materializeEntry(\n id,\n this.getSourceDictionaryEntry(id)\n ))\n );\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 return this.guardAsync(undefined, async () => {\n const dictionaryLocale = this._resolveCacheLocale(locale);\n\n if (!dictionaryLocale) {\n return this.getSourceDictionaryObject(id);\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n const targetObject = dictionaryCache.getValue(id);\n const sourceObject = this.getSourceDictionaryObject(id, {\n throwOnMissing: false,\n });\n if (sourceObject === undefined) {\n if (targetObject !== undefined) {\n return targetObject;\n }\n throw new DictionarySourceNotFoundError(id);\n }\n\n return await dictionaryCache.materializeValue(\n id,\n sourceObject,\n targetObject\n );\n });\n }\n\n private async translateDictionaryEntry(\n locale: Locale,\n id: string,\n sourceEntry: DictionaryEntry\n ): Promise<string> {\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 return translation;\n }\n\n private getSourceDictionaryEntry(id: string): DictionaryEntry {\n const sourceEntry = this.getDefaultDictionaryCache()?.getEntry(id);\n if (sourceEntry === undefined) {\n throw new DictionarySourceNotFoundError(id);\n }\n return sourceEntry;\n }\n\n private getSourceDictionaryObject(\n id: string,\n { throwOnMissing = true }: { throwOnMissing?: boolean } = {}\n ): DictionaryObject | undefined {\n const sourceObject = this.getDefaultDictionaryCache()?.getValue(id);\n if (sourceObject === undefined && throwOnMissing) {\n throw new DictionarySourceNotFoundError(id);\n }\n return sourceObject;\n }\n\n private getDefaultDictionaryCache() {\n return this.dictionaries.get(getI18nConfig().getDefaultLocale());\n }\n\n private resolveDictionaryCacheLocale(locale: string): Locale {\n return (\n this._resolveCacheLocale(locale) ?? getI18nConfig().getDefaultLocale()\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 return this.guard<T | undefined>(undefined, () => {\n // Validate\n const { translationLocale, options: lookupOptions } =\n this.resolveLookupParams(locale, options);\n\n // Early return if in default locale\n if (!translationLocale) return message;\n\n // Get the translation from the locale cache\n return this.translations\n .get(translationLocale)\n ?.get({ message, options: lookupOptions });\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 return this.guardAsync<T | undefined>(undefined, () =>\n this.lookupTranslationWithFallbackResolved(locale, message, options)\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 * @returns A lookup translation function\n *\n * @important prefetchEntries must all be the same locale\n */\n async getLookupTranslation(locale: string): Promise<\n TranslationResolver<TranslationValue> & {\n prefetchEntries?: PrefetchEntriesType<TranslationValue>;\n }\n > {\n return this.guardAsync<TranslationResolver<TranslationValue>>(\n (message) => message,\n async () => {\n // Locale used for the async load\n const asyncBoundaryLocale = this._resolveCacheLocale(locale);\n\n // Early return if i18n is disabled or default locale\n if (!asyncBoundaryLocale) {\n return (message) => message;\n }\n\n const asyncBoundaryTxCache =\n await this.translations.getOrLoad(asyncBoundaryLocale);\n\n // Prefetch any entries during async block (dev hot reload only)\n const prefetchEntries = async (\n prefetchEntries: {\n message: TranslationValue;\n options: LookupOptions;\n }[] = []\n ) => {\n if (\n process.env.NODE_ENV !== 'production' &&\n getI18nConfig().isDevHotReloadEnabled()\n ) {\n // Invariant: all prefetchEntries must be the same locale\n // TODO: investigate why we have made this an invariant, we may be able to drop this requirement\n const resolvedPrefetchEntries = resolvePrefetchEntriesByLocale(\n prefetchEntries,\n asyncBoundaryLocale,\n (entryLocale) =>\n this._resolveCacheLocale(entryLocale) ??\n this._resolveLocale(entryLocale)\n );\n if (resolvedPrefetchEntries.length !== prefetchEntries.length) {\n logger.warn(\n `I18nCache: getLookupTranslation(): prefetchEntries must all be the same locale, ignoring all entries that are not for ${asyncBoundaryLocale}`\n );\n }\n\n await Promise.allSettled(\n resolvedPrefetchEntries\n .filter((entry) => asyncBoundaryTxCache.get(entry) == null)\n .map((entry) => asyncBoundaryTxCache.miss(entry))\n );\n }\n };\n\n // Create translation resolver\n const lookupTranslation: TranslationResolver<TranslationValue> = (\n message,\n lookupOptions: LookupOptions = {} as LookupOptions\n ) =>\n this.guard(undefined, () => {\n const { translationLocale, options } = this.resolveLookupParams(\n lookupOptions.$locale ?? asyncBoundaryLocale,\n lookupOptions\n );\n\n // Default locale, return the message\n if (!translationLocale) return message;\n\n // Request locale overriden, to attempt a synchronous lookup if an alternate locale is requested\n const txCache =\n translationLocale === asyncBoundaryLocale\n ? asyncBoundaryTxCache\n : this.translations.get(translationLocale);\n\n // Get the translation\n return txCache?.get({ message, options });\n });\n\n Object.assign(lookupTranslation, { prefetchEntries });\n return lookupTranslation;\n }\n );\n }\n\n // ========== Error Handling ========== //\n\n /**\n * Run a lookup, routing errors through handleError (log in production,\n * throw in development) and returning the fallback once handled.\n */\n private guard<T>(fallback: T, fn: () => T): T {\n try {\n return fn();\n } catch (error) {\n this.handleError(error);\n return fallback;\n }\n }\n\n private async guardAsync<T>(fallback: T, fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n this.handleError(error);\n return fallback;\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 (getRuntimeEnvironment()) {\n case 'development':\n throw error;\n case 'production':\n default:\n logger.error('I18nCache: ' + error);\n break;\n }\n }\n\n private _resolveLocale(locale: string) {\n const i18nConfig = getI18nConfig();\n const resolvedLocale = i18nConfig.determineLocale(locale);\n if (!i18nConfig.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 const i18nConfig = getI18nConfig();\n if (i18nConfig.requiresTranslation(resolvedLocale)) {\n return resolvedLocale;\n }\n\n const aliasLocale = i18nConfig.resolveAliasLocale(\n i18nConfig.standardizeLocale(locale)\n );\n if (i18nConfig.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 ): LookupOptions {\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 const txCache = await this.translations.getOrLoad(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\nexport { I18nCache };\n\n// ===== Helper Functions ===== //\n\n/**\n * Validate constructor params: log warnings for suspicious configs and throw\n * on hard misconfigurations.\n */\nfunction validateCacheParams(params: I18nCacheConstructorParams): void {\n // Runtime translation against a custom API URL still needs GT credentials\n if (params.runtimeUrl && params.runtimeUrl !== defaultRuntimeApiUrl) {\n if (!params.projectId) {\n logger.warn(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'Runtime translation needs a projectId',\n fix: 'Add projectId to the I18nCache config or disable runtime translation',\n })\n );\n }\n if (!params.devApiKey && !params.apiKey) {\n logger.warn(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'Runtime translation needs devApiKey or apiKey',\n fix: 'Add credentials to the I18nCache config or disable runtime translation',\n })\n );\n }\n }\n\n // loadDictionary requires dictionary so the default locale always has a\n // source dictionary\n if (params.loadDictionary && !params.dictionary) {\n logger.error(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'loadDictionary needs a source dictionary',\n fix: 'Provide dictionary so the default locale has source content',\n })\n );\n throw new Error('Validation errors occurred');\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","import type { ReadonlyConditionStoreInterface as ReadonlyConditionStoreContract } from '../i18n-cache/types';\nimport type { LocaleCandidates } from '../i18n-config/I18nConfig';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\n\nexport type ReadonlyConditionStoreParams = {\n locale: LocaleCandidates;\n region?: string;\n enableI18n?: boolean;\n};\n\nexport class ReadonlyConditionStore implements ReadonlyConditionStoreContract {\n protected locale: string;\n protected region?: string;\n protected enableI18n: boolean;\n\n constructor({\n locale,\n region,\n enableI18n = true,\n }: ReadonlyConditionStoreParams) {\n this.locale = getI18nConfig().resolveSupportedLocale(locale);\n this.region = region;\n this.enableI18n = enableI18n;\n }\n\n getLocale = (): string => {\n return this.locale;\n };\n\n getRegion = (): string | undefined => {\n return this.region;\n };\n\n getEnableI18n = (): boolean => {\n return this.enableI18n;\n };\n\n // --- no-op methods --- //\n\n setLocale = (locale: LocaleCandidates): void => {};\n\n setRegion = (region: string | undefined): void => {};\n\n setEnableI18n = (enableI18n: boolean): void => {};\n}\n","import type { WritableConditionStoreInterface } from '../i18n-cache/types';\nimport type { LocaleCandidates } from '../i18n-config/I18nConfig';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\nimport {\n ReadonlyConditionStore,\n type ReadonlyConditionStoreParams,\n} from './ReadonlyConditionStore';\n\nexport type WritableConditionStoreParams = ReadonlyConditionStoreParams;\n\nexport class WritableConditionStore\n extends ReadonlyConditionStore\n implements WritableConditionStoreInterface\n{\n setLocale = (locale: LocaleCandidates): void => {\n this.locale = getI18nConfig().resolveSupportedLocale(locale);\n };\n\n setRegion = (region: string | undefined): void => {\n this.region = region;\n };\n\n setEnableI18n = (enableI18n: boolean): void => {\n this.enableI18n = enableI18n;\n };\n}\n","import type { LookupOptions } from '../translation-functions/types/options';\nimport type { Translation } from '../types';\nimport { hashMessage } from './hashMessage';\n\nexport type TranslateListenerLookup<T extends Translation = Translation> =\n | {\n locale: string;\n message: T;\n options: LookupOptions;\n }\n | {\n locale: string;\n hash: string;\n };\n\nexport type DictionaryListenerLookup = {\n locale: string;\n id: string;\n};\n\nexport function getTranslateListenerKey<T extends Translation>(\n lookup: TranslateListenerLookup<T>\n): string {\n const hash =\n 'hash' in lookup\n ? lookup.hash\n : hashMessage(lookup.message, lookup.options);\n return `${lookup.locale}:${hash}`;\n}\n\nexport function getDictionaryListenerKey({\n locale,\n id,\n}: DictionaryListenerLookup): string {\n return `${locale}:${id}`;\n}\n","type HeaderValue = string | string[] | null | undefined;\n\n/**\n * Parse an Accept-Language header into locale candidates by preference.\n */\nexport function parseAcceptLanguage(header: HeaderValue): string[] {\n const headerValues = Array.isArray(header) ? header : [header];\n\n return headerValues\n .flatMap((value) => value?.split(',') ?? [])\n .map((entry, index) => {\n const [locale = '', ...parameters] = entry\n .split(';')\n .map((value) => value.trim());\n const qualityParameter = parameters.find((parameter) =>\n parameter.toLowerCase().startsWith('q=')\n );\n const quality = Number(qualityParameter?.slice(2) ?? 1);\n return { locale, quality, index };\n })\n .filter(\n ({ locale, quality }) =>\n locale !== '' && locale !== '*' && quality > 0 && quality <= 1\n )\n .sort((a, b) => b.quality - a.quality || a.index - b.index)\n .map(({ locale }) => locale);\n}\n\n/**\n * Read and decode a value from a Cookie header or document.cookie string.\n */\nexport function getCookieValue(\n cookieHeader: string | null | undefined,\n cookieName: string\n): string | undefined {\n const prefix = `${cookieName}=`;\n const cookie = cookieHeader\n ?.split(';')\n .map((value) => value.trim())\n .find((value) => value.startsWith(prefix));\n if (!cookie) return undefined;\n\n const value = cookie.slice(prefix.length);\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"internal.cjs","names":["getWritableConditionStore","getI18nCache","getI18nConfig","createLookupOptions","interpolateMessage","getWritableConditionStore","decodeOptions","isEncodedTranslationOptions","createLookupOptions","extractVariables","interpolateMessage","getWritableConditionStore","getI18nCache","getI18nConfig","getWritableConditionStore","resolveStringContentWithRuntimeFallback","prefetchStringContentWithRuntimeFallback","getI18nConfig","resolveJsxWithRuntimeFallback","getLocale","defaultCacheUrl","getI18nConfig","hashMessage","getLoadTranslationsType","getI18nConfig","getRuntimeEnvironment","defaultRuntimeApiUrl","getI18nConfig","getI18nConfig","hashMessage"],"sources":["../src/translation-functions/internal/getGT.ts","../src/translation-functions/internal/getMessages.ts","../src/translation-functions/internal/renderDictionaryEntry.ts","../src/i18n-cache/translations-manager/utils/dictionary-helpers.ts","../src/translation-functions/internal/renderDictionaryObject.ts","../src/translation-functions/internal/getTranslations.ts","../src/translation-functions/internal/tx.ts","../src/translation-functions/internal/runtime-translate.ts","../src/i18n-cache/translations-manager/utils/createTranslateMany.ts","../src/i18n-cache/translations-manager/translations-loaders/createRemoteTranslationLoader.ts","../src/i18n-cache/translations-manager/translations-loaders/routeCreateTranslationLoader.ts","../src/i18n-cache/translations-manager/utils/constants.ts","../src/i18n-cache/translations-manager/utils/dedupePending.ts","../src/i18n-cache/translations-manager/ResourceCache.ts","../src/i18n-cache/translations-manager/TranslationsCache.ts","../src/i18n-cache/translations-manager/utils/DictionarySourceNotFoundError.ts","../src/i18n-cache/translations-manager/utils/materialize-dictionary.ts","../src/i18n-cache/translations-manager/DictionaryCache.ts","../src/i18n-cache/I18nCache.ts","../src/condition-store/ReadonlyConditionStore.ts","../src/condition-store/WritableConditionStore.ts","../src/utils/listenerKeys.ts","../src/utils/request.ts"],"sourcesContent":["import { getI18nCache } from '../../i18n-cache/singleton-operations';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { GTTranslationOptions, TranslationMetadata } from '../types/options';\nimport { GTFunctionType } from '../types/functions';\nimport { interpolateMessage } from '../utils/interpolation/interpolateMessage';\nimport { createLookupOptions } from './helpers';\nimport type { StringFormat } from '@generaltranslation/format/types';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\nexport type Message = TranslationMetadata & {\n message: string;\n};\n\n/**\n * Returns the gt function that registers a string at build time and resolves its translation at runtime.\n * @returns A promise of the gt function\n *\n * @example\n * const gt = await getGT();\n * const greeting = gt('Hello, world!');\n */\nexport async function getGT(_messages?: Message[]): Promise<GTFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getGTInternal({ locale, enableI18n }, _messages);\n}\n\n/**\n * Condition store agnostic getGT function\n */\nexport async function getGTInternal(\n {\n locale,\n enableI18n,\n }: {\n locale: string;\n enableI18n: boolean;\n },\n _messages?: Message[]\n): Promise<GTFunctionType> {\n // Get the translation resolver\n const i18nCache = getI18nCache();\n const sourceLocale = getI18nConfig().getDefaultLocale();\n // Statically gated so bundlers can drop dev hot-reload work from\n // production builds.\n const devHotReloadEnabled =\n process.env.NODE_ENV !== 'production' &&\n getI18nConfig().isDevHotReloadEnabled();\n const lookupTranslation = await i18nCache.getLookupTranslation(\n enableI18n ? locale : sourceLocale\n );\n\n // dev hot reload translate compiler injected lookups\n if (devHotReloadEnabled && lookupTranslation.prefetchEntries) {\n await lookupTranslation.prefetchEntries(\n _messages?.map(({ message, ...options }) => ({\n message,\n options: {\n $format: 'ICU',\n ...options,\n },\n })) ?? []\n );\n }\n\n /**\n * Registers a message at build time and resolves its translation at runtime.\n * @param {string} message - The message to translate\n * @param {GTTranslationOptions} options - The options for the translation\n * @returns The translated message\n *\n * @example\n * // Simple translation without interpolation\n * const gt = await getGT();\n * const greeting = gt('Hello, world!');\n *\n * @example\n * // Translation with interpolation\n * const gt = await getGT();\n * const welcome = gt('Hello, {name}!', { name: 'Alice' });\n */\n const gt: GTFunctionType = (\n message: string,\n options: GTTranslationOptions = {}\n ) => {\n const targetLocale = enableI18n\n ? (options.$locale ?? locale)\n : getI18nConfig().getDefaultLocale();\n const lookupOptions = createLookupOptions<StringFormat>(\n targetLocale,\n options,\n 'ICU'\n );\n\n // Lookup translation\n const translation = lookupTranslation(message, lookupOptions);\n\n // Dev hot reload (fire and forget, will be available in a later lookup)\n if (devHotReloadEnabled && translation == null) {\n void i18nCache\n .lookupTranslationWithFallback(\n lookupOptions.$locale,\n message,\n lookupOptions\n )\n .catch(() => {});\n }\n\n // Format result\n return interpolateMessage({\n source: message,\n target: translation,\n options: lookupOptions,\n sourceLocale,\n });\n };\n\n return gt;\n}\n","import { GTTranslationOptions } from '../types/options';\nimport { decodeOptions } from '../msg/decodeOptions';\nimport { isEncodedTranslationOptions } from '../utils/isEncodedTranslationOptions';\nimport { getGTInternal } from './getGT';\nimport { MFunctionType } from '../types/functions';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\n/**\n * Returns the m function that resolves a registered message to its translation.\n * @returns A promise of the m function\n *\n * @example\n * // Registration\n * const registeredMessage = msg('Hello, world!');\n *\n * // Resolution\n * const m = await getMessages();\n * const greeting = m(registeredMessage);\n */\nexport async function getMessages(): Promise<MFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getMessagesInternal({ locale, enableI18n });\n}\n\n/**\n * Condition store agnostic getMessages function\n */\nexport async function getMessagesInternal({\n locale,\n enableI18n,\n}: {\n locale: string;\n enableI18n: boolean;\n}): Promise<MFunctionType> {\n // Get the gt function\n const gt = await getGTInternal({ locale, enableI18n });\n\n /**\n * Resolves a registered message to its translation.\n * @param {string | null | undefined} encodedMsg - The encoded message to decode and interpolate.\n * @param {GTTranslationOptions} options - The options to interpolate.\n * @returns - The decoded and interpolated message.\n *\n * @example\n * // Simple message without interpolation\n * const m = await getMessages();\n * const greeting = m(msg('Hello, world!'));\n *\n * @example\n * // Message with interpolation\n * const m = await getMessages();\n * const welcome = m(msg('Welcome, {user}!'), { user: 'Alice' });\n */\n const m: MFunctionType = <T extends string | null | undefined>(\n encodedMsg: T,\n options: GTTranslationOptions = {}\n ): T extends string ? string : T => {\n // Return if the encoded message is null or undefined\n if (encodedMsg == null) return encodedMsg as T extends string ? string : T;\n\n // Get any encoded options\n const decodedOptions = decodeOptions(encodedMsg) ?? {};\n\n // Return early if string already interpolated eg: mFallback(msg('Hello, {name}!', { name: 'Brian' }))\n if (isEncodedTranslationOptions(decodedOptions)) {\n return gt(decodedOptions.$_source, decodedOptions) as T extends string\n ? string\n : T;\n }\n\n // Use gt to interpolate\n // Separate from decoded options to match behavior in @gt/react-core\n return gt(encodedMsg, options) as T extends string ? string : T;\n };\n\n return m;\n}\n","import { createLookupOptions } from './helpers';\nimport { extractVariables } from '../../utils/extractVariables';\nimport { interpolateMessage } from '../utils/interpolation/interpolateMessage';\nimport type {\n DictionaryLookupOptions,\n TranslationVariables,\n} from '../types/options';\nimport type { DictionaryEntry } from '../../i18n-cache/translations-manager/DictionaryCache';\nimport type { StringFormat } from '@generaltranslation/format/types';\n\nexport function renderDictionaryEntry({\n sourceLocale,\n targetLocale,\n sourceEntry,\n target,\n dictionaryOptions,\n options = {},\n}: {\n sourceLocale: string;\n targetLocale: string;\n sourceEntry: DictionaryEntry;\n target: string | undefined;\n dictionaryOptions: DictionaryLookupOptions;\n options?: TranslationVariables;\n}): string {\n const lookupOptions = createLookupOptions<StringFormat>(\n targetLocale,\n {\n ...dictionaryOptions,\n ...extractVariables(options),\n },\n dictionaryOptions.$format\n );\n\n return interpolateMessage({\n source: sourceEntry.entry,\n target,\n options: lookupOptions,\n sourceLocale,\n });\n}\n","import type {\n Dictionary,\n DictionaryEntry,\n DictionaryLeaf,\n DictionaryPath,\n DictionaryValue,\n} from './types/dictionary';\nimport type {\n DictionaryEntryOptions,\n DictionaryLookupOptions,\n} from '../../../translation-functions/types/options';\n\nfunction getDictionaryPath(id: DictionaryPath): string[] {\n const path = id ? id.split('.') : [];\n for (const segment of path) {\n assertSafeDictionaryPathSegment(segment, id);\n }\n return path;\n}\n\nexport function assertSafeDictionaryPathSegment(\n segment: string,\n path: DictionaryPath\n): void {\n if (\n segment === '__proto__' ||\n segment === 'constructor' ||\n segment === 'prototype'\n ) {\n throw new Error(`Dictionary path \"${path}\" contains an unsafe segment`);\n }\n}\n\nexport function isDictionaryValue(value: unknown): value is Dictionary {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n}\n\nexport function cloneDictionaryValue<Value extends DictionaryValue | undefined>(\n value: Value\n): Value {\n if (value === undefined || typeof value === 'string') {\n return value;\n }\n return structuredClone(value) as Value;\n}\n\nexport function getDictionaryValueAtPath(\n dictionary: Dictionary,\n path: DictionaryPath\n): DictionaryValue | undefined {\n let current: DictionaryValue = dictionary;\n\n for (const segment of getDictionaryPath(path)) {\n if (!isDictionaryValue(current)) {\n return undefined;\n }\n current = current[segment];\n }\n\n return current;\n}\n\nexport function setDictionaryValueAtPath(\n dictionary: Dictionary,\n path: DictionaryPath,\n value: DictionaryValue\n): void {\n const segments = getDictionaryPath(path);\n if (isDictionaryValue(value)) {\n assertSafeDictionaryObject(value, path);\n }\n\n if (segments.length === 0) {\n if (isDictionaryValue(value)) {\n replaceDictionary(dictionary, value);\n }\n return;\n }\n\n let current = dictionary;\n for (const segment of segments.slice(0, -1)) {\n const next = current[segment];\n if (!isDictionaryValue(next)) {\n current[segment] = {} as Dictionary;\n }\n current = current[segment] as Dictionary;\n }\n\n const leafSegment = segments[segments.length - 1];\n current[leafSegment] = 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 };\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 && isDictionaryLeafOptions(value[1]);\n}\n\nfunction isDictionaryLeafOptions(\n value: unknown\n): value is DictionaryEntryOptions {\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 || typeof options.$maxChars === 'number')\n );\n}\n\nfunction isStringFormat(\n value: unknown\n): value is DictionaryLookupOptions['$format'] {\n return value === 'ICU' || value === 'I18NEXT' || value === 'STRING';\n}\n\nfunction replaceDictionary(target: Dictionary, source: Dictionary): void {\n for (const key of Object.keys(target)) {\n delete target[key];\n }\n for (const key of Object.keys(source)) {\n target[key] = source[key];\n }\n}\n\nfunction assertSafeDictionaryObject(\n dictionary: Dictionary,\n parentPath = ''\n): void {\n for (const [key, value] of Object.entries(dictionary)) {\n const path = parentPath ? `${parentPath}.${key}` : key;\n assertSafeDictionaryPathSegment(key, path);\n if (isDictionaryValue(value)) {\n assertSafeDictionaryObject(value, path);\n }\n }\n}\n","import {\n getDictionaryEntry,\n isDictionaryValue,\n resolveDictionaryLookupOptions,\n} from '../../i18n-cache/translations-manager/utils/dictionary-helpers';\nimport type { DictionaryObjectTranslation } from '../types/functions';\nimport type { DictionaryLookupOptions } from '../types/options';\nimport type {\n DictionaryEntry,\n DictionaryValue,\n} from '../../i18n-cache/translations-manager/DictionaryCache';\n\nexport function renderDictionaryObject({\n sourceObject,\n targetObject,\n translate,\n}: {\n sourceObject: DictionaryValue | undefined;\n targetObject: DictionaryValue | undefined;\n translate?: (\n sourceEntry: DictionaryEntry,\n dictionaryOptions: DictionaryLookupOptions\n ) => string | undefined;\n}): DictionaryObjectTranslation {\n const targetEntry = getDictionaryEntry(targetObject);\n if (targetEntry !== undefined) {\n return targetEntry.entry;\n }\n\n if (isDictionaryValue(targetObject)) {\n if (!isDictionaryValue(sourceObject)) {\n return renderDictionaryObject({\n sourceObject: targetObject,\n targetObject: undefined,\n translate,\n });\n }\n\n return renderDictionaryObjectChildren({\n sourceObject,\n targetObject,\n translate,\n });\n }\n\n const sourceEntry = getDictionaryEntry(sourceObject);\n if (sourceEntry !== undefined) {\n const dictionaryOptions = resolveDictionaryLookupOptions(\n sourceEntry.options\n );\n return translate?.(sourceEntry, dictionaryOptions) ?? sourceEntry.entry;\n }\n\n if (isDictionaryValue(sourceObject)) {\n return renderDictionaryObjectChildren({\n sourceObject,\n targetObject: undefined,\n translate,\n });\n }\n\n throw new Error('Dictionary object cannot be rendered');\n}\n\nfunction renderDictionaryObjectChildren({\n sourceObject,\n targetObject,\n translate,\n}: {\n sourceObject: DictionaryValue;\n targetObject: DictionaryValue | undefined;\n translate?: (\n sourceEntry: DictionaryEntry,\n dictionaryOptions: DictionaryLookupOptions\n ) => string | undefined;\n}): DictionaryObjectTranslation {\n if (!isDictionaryValue(sourceObject)) {\n return renderDictionaryObject({ sourceObject, targetObject, translate });\n }\n\n const result: Record<string, DictionaryObjectTranslation> = {};\n const keys = new Set([\n ...Object.keys(sourceObject),\n ...(isDictionaryValue(targetObject) ? Object.keys(targetObject) : []),\n ]);\n\n for (const key of Array.from(keys)) {\n const renderedChild = renderDictionaryObject({\n sourceObject: sourceObject[key],\n targetObject: isDictionaryValue(targetObject)\n ? targetObject[key]\n : undefined,\n translate,\n });\n if (renderedChild !== undefined) {\n result[key] = renderedChild;\n }\n }\n\n return result;\n}\n","import { getI18nCache } from '../../i18n-cache/singleton-operations';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { TranslationVariables } from '../types/options';\nimport { TFunctionType } from '../types/functions';\nimport { renderDictionaryEntry } from './renderDictionaryEntry';\nimport { renderDictionaryObject } from './renderDictionaryObject';\nimport { resolveDictionaryLookupOptions } from '../../i18n-cache/translations-manager/utils/dictionary-helpers';\nimport type { DictionaryObjectTranslation } from '../types/functions';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\n/**\n * Returns the t function that translates a dictionary entry based on its id and options.\n * @returns A promise of the t function\n * @important Must be used inside of a request context\n *\n * @example\n * const t = await getTranslations();\n * const title = await t('page.title');\n */\nexport async function getTranslations(rootId?: string): Promise<TFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getTranslationsInternal({ locale, enableI18n, rootId });\n}\n\n/**\n * Condition store agnostic getTranslations function\n */\nexport async function getTranslationsInternal({\n locale,\n enableI18n,\n rootId,\n}: {\n locale: string;\n enableI18n: boolean;\n rootId?: string;\n}): Promise<TFunctionType> {\n const i18nCache = getI18nCache();\n const sourceLocale = getI18nConfig().getDefaultLocale();\n const targetLocale = enableI18n ? locale : sourceLocale;\n const [sourceDictionary, targetDictionary, lookupTranslation] =\n await Promise.all([\n i18nCache.getLookupDictionary(sourceLocale),\n i18nCache.getLookupDictionary(targetLocale),\n i18nCache.getLookupTranslation(targetLocale),\n ]);\n const {\n lookupDictionary: lookupSourceDictionary,\n lookupDictionaryObj: lookupSourceDictionaryObj,\n } = sourceDictionary;\n const {\n lookupDictionary: lookupTargetDictionary,\n lookupDictionaryObj: lookupTargetDictionaryObj,\n } = targetDictionary;\n\n /**\n * Dictionary resolution\n * @param {string} id - The id of the translation to translate.\n * @param {TranslationVariables} options - The variables for interpolation.\n * @returns {string} The translated message.\n *\n * @example\n * // Simple dictionary lookup without interpolation\n * const t = await getTranslations();\n * const title = t('page.title');\n *\n * @example\n * // Dictionary lookup with interpolation\n * const t = await getTranslations();\n * const greeting = t('user.greeting', { name: 'Bob' });\n */\n const t = ((id: string, options: TranslationVariables = {}): string => {\n id = getId(rootId, id);\n const sourceEntry = lookupSourceDictionary(id);\n if (sourceEntry === undefined) {\n throw new Error(`Dictionary entry ${id} cannot be found`);\n }\n const targetEntry = lookupTargetDictionary(id);\n const dictionaryOptions = resolveDictionaryLookupOptions(\n sourceEntry.options\n );\n const target =\n targetEntry?.entry ??\n lookupTranslation(sourceEntry.entry, dictionaryOptions);\n return renderDictionaryEntry({\n sourceLocale,\n targetLocale: targetLocale,\n sourceEntry,\n target,\n dictionaryOptions,\n options,\n });\n }) as TFunctionType;\n\n /**\n * Returns a subtree of the dictionary object translation based on its id.\n * @param {string} id - The id of the translation to translate.\n * @returns The translated object.\n *\n * @example\n * const t = await getTranslations();\n * const greetings = t.obj('greetings');\n * console.log(greetings);\n * // { greeting1: 'Hello', greeting2: 'Hi' }\n */\n t.obj = (id: string): DictionaryObjectTranslation => {\n id = getId(rootId, id);\n const sourceObject = lookupSourceDictionaryObj(id);\n if (sourceObject === undefined) {\n throw new Error(`Dictionary entry ${id} cannot be found`);\n }\n const targetObject = lookupTargetDictionaryObj(id);\n return renderDictionaryObject({\n sourceObject,\n targetObject,\n translate: (sourceEntry, dictionaryOptions) =>\n lookupTranslation(sourceEntry.entry, dictionaryOptions),\n });\n };\n\n return t;\n}\n\nfunction getId(prefix: string | undefined, suffix: string): string {\n return prefix ? `${prefix}.${suffix}` : suffix;\n}\n","import { RuntimeTranslationOptions } from '../types/options';\nimport type { StringFormat } from '@generaltranslation/format/types';\nimport {\n prefetchStringContentWithRuntimeFallback,\n resolveStringContentWithRuntimeFallback,\n} from './helpers';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\ntype RuntimeTranslationOptionsWithFormat = Omit<\n RuntimeTranslationOptions,\n '$format'\n> & {\n $format?: StringFormat;\n};\n\n/**\n * Translates a message at runtime.\n * @param {string} message - The message to translate.\n * @param {RuntimeTranslationOptions} options - The options for the translation.\n * @returns {Promise<string>} The translated message.\n *\n * @example\n * // Simple runtime translation without interpolation\n * const status = await tx('Processing complete', { $locale: 'es-MX' });\n *\n * @example\n * // Runtime translation with interpolation\n * const progress = await tx(`Processing ${status}`, { $locale: 'es-MX' });\n */\nexport async function tx(\n content: string,\n options: RuntimeTranslationOptionsWithFormat = {}\n): Promise<string> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n\n return txInternal({ locale, enableI18n, content, options });\n}\n\n/**\n * Condition store agnostic tx function\n */\nexport async function txInternal({\n locale,\n enableI18n,\n content,\n options,\n}: {\n locale: string;\n enableI18n: boolean;\n content: string;\n options: RuntimeTranslationOptionsWithFormat;\n}): Promise<string> {\n const targetLocale = getTargetLocale({ locale, enableI18n, options });\n return resolveStringContentWithRuntimeFallback(targetLocale, content, {\n $format: 'STRING',\n ...options,\n });\n}\n\n/**\n * Registers a message for runtime translation without interpolating the\n * result. For compiler-injected prefetch calls: their return value is\n * discarded and variable values only exist at the render-time call site, so\n * interpolating here would fail for any message with placeholders.\n */\nexport async function txPrefetch(\n content: string,\n options: RuntimeTranslationOptionsWithFormat = {}\n): Promise<void> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n const targetLocale = getTargetLocale({ locale, enableI18n, options });\n await prefetchStringContentWithRuntimeFallback(targetLocale, content, {\n $format: 'STRING',\n ...options,\n });\n}\n\nfunction getTargetLocale({\n locale,\n enableI18n,\n options,\n}: {\n locale: string;\n enableI18n: boolean;\n options: RuntimeTranslationOptionsWithFormat;\n}): string {\n return enableI18n\n ? typeof options.$locale === 'string'\n ? options.$locale\n : locale\n : getI18nConfig().getDefaultLocale();\n}\n","import type {\n JsxChildren,\n StringFormat,\n} from '@generaltranslation/format/types';\nimport { getLocale } from '../../helpers/locale';\nimport type {\n JsxTranslationOptions,\n RuntimeTranslationOptions,\n} from '../types/options';\nimport { resolveJsxWithRuntimeFallback } from './helpers';\nimport { txPrefetch } from './tx';\n\ntype RuntimeStringTranslationOptions = Omit<\n RuntimeTranslationOptions,\n '$format'\n> & {\n $format?: StringFormat;\n};\n\ntype RuntimeJsxTranslationOptions = JsxTranslationOptions & {\n $locale?: string;\n};\n\nexport const GtInternalRuntimeTranslateString = (\n content: string,\n options: RuntimeStringTranslationOptions = {}\n) => {\n // Prefetch/registration only — the compiler-injected call discards the\n // result, and variable values are unavailable here, so the translation\n // must not be interpolated.\n return txPrefetch(content, { $format: 'ICU', ...options });\n};\n\nexport const GtInternalRuntimeTranslateJsx = (\n content: JsxChildren,\n options: RuntimeJsxTranslationOptions = {}\n) => {\n const locale = options.$locale ?? getLocale();\n return resolveJsxWithRuntimeFallback(locale, content, {\n $format: 'JSX',\n ...options,\n });\n};\n","import type { RuntimeTranslateManyOptions } from 'generaltranslation/internal';\nimport type { Locale } from '../TranslationsCache';\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';\nimport { LoadTranslationsType } from '../../utils/getLoadTranslationsType';\nimport logger from '../../../logs/logger';\nimport { createRemoteTranslationLoader } from './createRemoteTranslationLoader';\nimport { getI18nConfig } from '../../../i18n-config/singleton-operations';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\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 };\n loadTranslations?: TranslationsLoader;\n}): TranslationsLoader {\n const { cacheUrl, projectId, _versionId, _branchId } =\n remoteTranslationLoaderParams;\n\n // Warnings are deferred to loader invocation: translations may be provided\n // externally via updateTranslations() (eg streamed from a server), in which\n // case the loader is never invoked and the warnings do not apply\n switch (type) {\n case LoadTranslationsType.REMOTE:\n case LoadTranslationsType.GT_REMOTE:\n // Only reachable for REMOTE: GT_REMOTE requires a projectId\n if (!projectId) {\n return createWarnOnceTranslationLoader(\n createDiagnosticMessage({\n whatHappened:\n 'Loading translations from a remote store needs a projectId. No translations will be loaded.',\n fix: 'Add projectId to the I18nCache config, or set cacheUrl to null to disable translation loading',\n })\n );\n }\n return createRemoteTranslationLoader({\n cacheUrl: cacheUrl as string | undefined,\n projectId,\n _versionId,\n _branchId,\n customMapping: getI18nConfig().getCustomMapping(),\n });\n case LoadTranslationsType.CUSTOM:\n return loadTranslations!;\n case LoadTranslationsType.DISABLED:\n // cacheUrl: null is an explicit opt-out of translation loading\n if (cacheUrl === null) {\n return async () => ({});\n }\n return createWarnOnceTranslationLoader(\n createDiagnosticMessage({\n whatHappened:\n 'No translation loader found. No translations will be loaded.',\n fix: 'Add projectId to the I18nCache config (to load from the GT remote store), provide a loadTranslations function, or set cacheUrl to null to disable translation loading',\n })\n );\n }\n}\n\n/**\n * Loads no translations and logs a warning once on first invocation\n */\nfunction createWarnOnceTranslationLoader(warning: string): TranslationsLoader {\n let warned = false;\n return async (_locale: string) => {\n if (!warned) {\n warned = true;\n logger.warn('I18nCache: ' + warning);\n }\n return {};\n };\n}\n","/**\n * Default cache expiry time in milliseconds\n */\nexport const DEFAULT_CACHE_EXPIRY_TIME = 60_000; // 60 sec\n","/**\n * Share one in-flight promise per key: concurrent callers for the same key\n * await the same promise, and the pending entry is cleared once it settles.\n */\nexport async function dedupePending<Key, Value>(\n pending: Map<Key, Promise<Value>>,\n key: Key,\n create: () => Promise<Value>\n): Promise<Value> {\n let promise = pending.get(key);\n if (!promise) {\n promise = create();\n pending.set(key, promise);\n }\n\n try {\n return await promise;\n } finally {\n pending.delete(key);\n }\n}\n","import { DEFAULT_CACHE_EXPIRY_TIME } from './utils/constants';\nimport { dedupePending } from './utils/dedupePending';\n\nexport type ResourceCacheEntry<Value> = {\n expiresAt: number;\n value: Value;\n};\n\nexport class ResourceCache<Key extends string, Value> {\n private cache = new Map<Key, ResourceCacheEntry<Value>>();\n private pendingLoads = new Map<Key, Promise<Value>>();\n private loadResource: (key: Key) => Promise<Value>;\n private ttl: number;\n\n constructor({\n load,\n ttl,\n }: {\n load: (key: Key) => Promise<Value>;\n ttl?: number | null;\n }) {\n this.loadResource = load;\n this.ttl = ttl === null ? -1 : (ttl ?? DEFAULT_CACHE_EXPIRY_TIME);\n }\n\n public get(key: Key): Value | undefined {\n const entry = this.cache.get(key);\n if (!entry || this.isExpired(entry)) {\n return undefined;\n }\n\n return entry.value;\n }\n\n public set(\n key: Key,\n value: Value,\n { expiresAt = this.getExpiresAt() }: { expiresAt?: number } = {}\n ): void {\n this.cache.set(key, {\n expiresAt,\n value,\n });\n }\n\n public async getOrLoad(key: Key): Promise<Value> {\n return this.get(key) ?? (await this.load(key));\n }\n\n private load(key: Key): Promise<Value> {\n return dedupePending(this.pendingLoads, key, () =>\n // The entry expiry is computed when the load resolves, not when it starts\n this.loadResource(key).then((value) => {\n this.set(key, value);\n return value;\n })\n );\n }\n\n private getExpiresAt(): number {\n // Avoid Date.now() for Next.js Cache Components; Next handles caching.\n return this.ttl <= 0 ? this.ttl : Date.now() + this.ttl;\n }\n\n private isExpired(entry: ResourceCacheEntry<Value>): boolean {\n // Avoid Date.now() for Next.js Cache Components; Next handles caching.\n if (entry.expiresAt === 0) return true;\n return entry.expiresAt > 0 && entry.expiresAt < Date.now();\n }\n}\n","import { LookupOptions } from '../../translation-functions/types/options';\nimport { Translation } from './utils/types/translation-data';\nimport { hashMessage } from '../../utils/hashMessage';\nimport { dedupePending } from './utils/dedupePending';\nimport type { Content } from '@generaltranslation/format/types';\nimport type {\n EntryMetadata,\n TranslateManyEntry,\n TranslationResult,\n} from 'generaltranslation/types';\n\nexport type TranslationBatchConfig = {\n maxConcurrentRequests?: number;\n maxBatchSize?: number;\n batchInterval?: number;\n};\n\n// See gt-next\nconst DEFAULT_BATCH_CONFIG: Required<TranslationBatchConfig> = {\n maxConcurrentRequests: 100,\n maxBatchSize: 25,\n batchInterval: 50,\n};\n\nfunction getPositiveValue(\n value: number | undefined,\n defaultValue: number,\n integer = false\n) {\n if (value === undefined || !Number.isFinite(value)) return defaultValue;\n const resolved = integer ? Math.trunc(value) : value;\n return resolved > 0 ? resolved : defaultValue;\n}\n\nfunction normalizeBatchConfig(\n batchConfig?: TranslationBatchConfig\n): Required<TranslationBatchConfig> {\n return {\n maxConcurrentRequests: getPositiveValue(\n batchConfig?.maxConcurrentRequests,\n DEFAULT_BATCH_CONFIG.maxConcurrentRequests,\n true\n ),\n maxBatchSize: getPositiveValue(\n batchConfig?.maxBatchSize,\n DEFAULT_BATCH_CONFIG.maxBatchSize,\n true\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 * Just being explicit about the purpose of this type\n */\nexport type Locale = string;\n\n/**\n * Called when a translation is resolved through a runtime cache miss.\n * Locale is handled by the I18nCache that owns this cache, so it is not\n * passed here.\n */\nexport type TranslationsCacheMissCallback<\n TranslationValue extends Translation,\n> = (hash: Hash, translation: TranslationValue) => void;\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 by the owning I18nCache. Use a callback function that has the\n * locale parameter embedded if you wish to use the locale code.\n */\nexport class TranslationsCache<TranslationValue extends Translation> {\n private cache: Record<Hash, TranslationValue>;\n private pendingTranslations = new Map<Hash, Promise<TranslationValue>>();\n private queue: Array<QueueEntry<TranslationValue>> = [];\n private batchTimer: ReturnType<typeof setTimeout> | null = null;\n private activeRequests = 0;\n private batchConfig: Required<TranslationBatchConfig>;\n private translateMany: TranslateMany;\n private onMiss?: TranslationsCacheMissCallback<TranslationValue>;\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 onMiss,\n batchConfig,\n }: {\n init: Record<Hash, TranslationValue>;\n translateMany: TranslateMany;\n batchConfig?: TranslationBatchConfig;\n onMiss?: TranslationsCacheMissCallback<TranslationValue>;\n }) {\n this.cache = structuredClone(init);\n this.translateMany = translateMany;\n this.batchConfig = normalizeBatchConfig(batchConfig);\n this.onMiss = onMiss;\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 cacheKey = this.getCacheKey(key);\n return this.cache[cacheKey] as T | undefined;\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 cacheKey = this.getCacheKey(key);\n const value = await dedupePending(this.pendingTranslations, cacheKey, () =>\n this.translate(key)\n );\n if (value != null) {\n this.onMiss?.(cacheKey, value);\n }\n return value as T;\n }\n\n public getInternalCache(): Record<Hash, TranslationValue> {\n return structuredClone(this.cache);\n }\n\n private getCacheKey(key: TranslationKey<TranslationValue>): Hash {\n return hashMessage(key.message, key.options);\n }\n\n private translate(\n key: TranslationKey<TranslationValue>\n ): Promise<TranslationValue> {\n const translationPromise = this.enqueueTranslation(key);\n\n if (this.queue.length >= this.batchConfig.maxBatchSize) {\n this.flushNow();\n } else {\n this.scheduleBatch();\n }\n\n return translationPromise;\n }\n\n public update(translations: Record<Hash, TranslationValue>): void {\n this.cache = { ...this.cache, ...translations };\n }\n\n private flushNow(): void {\n if (this.batchTimer) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n this.drainQueue();\n }\n\n private scheduleBatch(): void {\n if (this.batchTimer) return;\n this.batchTimer = setTimeout(() => {\n this.batchTimer = null;\n this.drainQueue();\n }, this.batchConfig.batchInterval);\n }\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\n if (this.queue.length > 0) {\n this.scheduleBatch();\n }\n }\n\n private enqueueTranslation(\n key: TranslationKey<TranslationValue>\n ): Promise<TranslationValue> {\n const hash = this.getCacheKey(key);\n const options = key.options;\n const metadataOptions = options as {\n $context?: string;\n $id?: string;\n $maxChars?: number;\n $requiresReview?: boolean;\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 // The hash is review-aware; the request metadata must carry the\n // same intent so the platform records it on anything it persists\n ...(metadataOptions.$requiresReview === true && {\n requiresReview: true,\n }),\n dataFormat: options.$format,\n },\n resolve: (value) => resolve(value as TranslationValue),\n reject,\n });\n });\n }\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 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 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.cache[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","export class DictionarySourceNotFoundError extends Error {\n constructor(id: string) {\n super(`I18nCache: source dictionary entry ${id} is not defined`);\n this.name = 'DictionarySourceNotFoundError';\n }\n}\n","import { DictionarySourceNotFoundError } from './DictionarySourceNotFoundError';\nimport {\n assertSafeDictionaryPathSegment,\n cloneDictionaryValue,\n getDictionaryEntry,\n isDictionaryValue,\n} from './dictionary-helpers';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryValue,\n} from './types/dictionary';\n\nexport type TranslateDictionaryEntry = (\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n) => Promise<DictionaryValue>;\n\n/**\n * Builds the dictionary value for a requested path by combining existing target\n * translations with runtime translations of any source leaves that are missing.\n */\nexport async function materializeDictionaryValue({\n key,\n sourceValue,\n targetValue,\n translateEntry,\n}: {\n key: DictionaryKey;\n sourceValue: DictionaryValue;\n targetValue: DictionaryValue | undefined;\n translateEntry: TranslateDictionaryEntry;\n}): Promise<DictionaryValue> {\n if (getDictionaryEntry(targetValue) !== undefined) {\n return cloneDictionaryValue(targetValue as DictionaryValue);\n }\n\n if (isDictionaryValue(targetValue) && !isDictionaryValue(sourceValue)) {\n return cloneDictionaryValue(targetValue);\n }\n\n const sourceEntry = getDictionaryEntry(sourceValue);\n if (sourceEntry !== undefined) {\n return await translateEntry(key, sourceEntry);\n }\n\n if (!isDictionaryValue(sourceValue)) {\n throw new DictionarySourceNotFoundError(key);\n }\n\n const targetDictionary = isDictionaryValue(targetValue) ? targetValue : {};\n const keys = new Set([\n ...Object.keys(sourceValue),\n ...Object.keys(targetDictionary),\n ]);\n const entries = await Promise.all(\n Array.from(keys).map(async (childKey) => {\n const childPath = key ? `${key}.${childKey}` : childKey;\n assertSafeDictionaryPathSegment(childKey, childPath);\n\n const childSource = sourceValue[childKey];\n if (childSource === undefined) {\n return [\n childKey,\n cloneDictionaryValue(targetDictionary[childKey]),\n ] as const;\n }\n\n return [\n childKey,\n await materializeDictionaryValue({\n key: childPath,\n sourceValue: childSource,\n targetValue: targetDictionary[childKey],\n translateEntry,\n }),\n ] as const;\n })\n );\n\n return Object.fromEntries(entries) as Dictionary;\n}\n","import {\n cloneDictionaryValue,\n getDictionaryEntry,\n getDictionaryValue,\n getDictionaryValueAtPath,\n isDictionaryValue,\n setDictionaryValueAtPath,\n} from './utils/dictionary-helpers';\nimport { materializeDictionaryValue } from './utils/materialize-dictionary';\nimport { dedupePending } from './utils/dedupePending';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryPath,\n DictionaryValue,\n} from './utils/types/dictionary';\nexport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryLeaf,\n DictionaryObject,\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 DictionaryLoader = (locale: string) => Promise<Dictionary>;\n\nfunction cloneDictionaryEntry(entry: DictionaryEntry): DictionaryEntry {\n return {\n entry: entry.entry,\n options: structuredClone(entry.options),\n };\n}\n\nexport class DictionaryCache {\n private cache: Dictionary;\n private pendingTranslations = new Map<\n DictionaryKey,\n Promise<DictionaryEntry>\n >();\n private pendingMaterializations = new Map<\n DictionaryKey,\n Promise<DictionaryValue>\n >();\n private runtimeTranslate: DictionaryRuntimeTranslate;\n\n constructor({\n init,\n runtimeTranslate,\n }: {\n init: Dictionary;\n runtimeTranslate: DictionaryRuntimeTranslate;\n }) {\n this.cache = structuredClone(init);\n this.runtimeTranslate = runtimeTranslate;\n }\n\n public getEntry(key: DictionaryKey): DictionaryEntry | undefined {\n const value = getDictionaryValueAtPath(this.cache, key);\n const entry = getDictionaryEntry(value);\n if (entry === undefined) {\n return undefined;\n }\n return cloneDictionaryEntry(entry);\n }\n\n public getValue(key: DictionaryKey): DictionaryValue | undefined {\n const value = getDictionaryValueAtPath(this.cache, key);\n if (value === undefined) {\n return undefined;\n }\n return cloneDictionaryValue(value);\n }\n\n public setValue(key: DictionaryKey, value: DictionaryValue): void {\n setDictionaryValueAtPath(this.cache, key, cloneDictionaryValue(value));\n }\n\n public getInternalCache(): Dictionary {\n return cloneDictionaryValue(this.cache);\n }\n\n public update(dictionary: Dictionary): void {\n mergeDictionary(this.cache, dictionary);\n }\n\n public async materializeValue(\n key: DictionaryKey,\n sourceValue: DictionaryValue,\n targetValue = getDictionaryValueAtPath(this.cache, key)\n ): Promise<DictionaryValue> {\n return dedupePending(this.pendingMaterializations, key, () =>\n materializeDictionaryValue({\n key,\n sourceValue,\n targetValue,\n translateEntry: async (entryKey, sourceEntry) =>\n getDictionaryValue(\n await this.materializeEntry(entryKey, sourceEntry)\n ),\n }).then((value) => {\n this.setValue(key, value);\n return value;\n })\n );\n }\n\n public async materializeEntry(\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n ): Promise<DictionaryEntry> {\n return cloneDictionaryEntry(\n await dedupePending(this.pendingTranslations, key, () =>\n this.runtimeTranslate(key, sourceEntry).then((value) => {\n setDictionaryValueAtPath(this.cache, key, value);\n const entry = getDictionaryEntry(value);\n if (entry === undefined) {\n // Never will happen\n throw new Error(\n 'DictionaryCache materializeEntry did not return a DictionaryEntry'\n );\n }\n return cloneDictionaryEntry(entry);\n })\n )\n );\n }\n}\n\nfunction mergeDictionary(target: Dictionary, source: Dictionary): void {\n for (const [key, value] of Object.entries(source)) {\n const targetValue = target[key];\n if (isDictionaryValue(targetValue) && isDictionaryValue(value)) {\n mergeDictionary(targetValue, value);\n } else {\n target[key] = cloneDictionaryValue(value);\n }\n }\n}\n","import logger from '../logs/logger';\nimport { I18nCacheConfig, I18nCacheConstructorParams } from './types';\nimport {\n createDiagnosticMessage,\n defaultRuntimeApiUrl,\n} from 'generaltranslation/internal';\nimport { Translation } from './translations-manager/utils/types/translation-data';\nimport { LookupOptions } from '../translation-functions/types/options';\nimport { SafeTranslationsLoader } from './translations-manager/translations-loaders/types';\nimport {\n createTranslateManyFactory,\n type CreateTranslateMany,\n} from './translations-manager/utils/createTranslateMany';\nimport { routeCreateTranslationLoader } from './translations-manager/translations-loaders/routeCreateTranslationLoader';\nimport { getLoadTranslationsType } from './utils/getLoadTranslationsType';\nimport { ResourceCache } from './translations-manager/ResourceCache';\nimport { TranslationsCache } from './translations-manager/TranslationsCache';\nimport type { Hash, Locale } from './translations-manager/TranslationsCache';\nimport { DictionaryCache } from './translations-manager/DictionaryCache';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryObject,\n} from './translations-manager/DictionaryCache';\nimport { resolveDictionaryLookupOptions } from './translations-manager/utils/dictionary-helpers';\nimport { DictionarySourceNotFoundError } from './translations-manager/utils/DictionarySourceNotFoundError';\nimport { getRuntimeEnvironment } from '../utils/getRuntimeEnvironment';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\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\ntype DictionaryResolver = (id: string) => DictionaryEntry | undefined;\n\ntype DictionaryObjResolver = (id: string) => DictionaryObject | undefined;\n\ntype DictionaryResolvers = {\n lookupDictionary: DictionaryResolver;\n lookupDictionaryObj: DictionaryObjResolver;\n};\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 * Callback function to prefetch entries during the async period\n */\ntype PrefetchEntriesType<TranslationType extends Translation> = (\n prefetchEntries: PrefetchEntry<TranslationType>[]\n) => Promise<void>;\n\n/**\n * Event fired when a runtime translation resolves a cache miss\n */\nexport type TranslationsCacheMissEvent<\n TranslationValue extends Translation = Translation,\n> = {\n locale: Locale;\n hash: Hash;\n translation: TranslationValue;\n};\n\n/**\n * Class for managing translation functionality\n * @template TranslationValue - The type of the translation that will be cached\n */\nclass I18nCache<TranslationValue extends Translation = Translation> {\n protected config: I18nCacheConfig;\n\n /**\n * Single dev hot-reload listener for runtime-translation cache misses.\n * Subclasses that add cache-miss behavior should wrap any existing listener\n * instead of overwriting it.\n */\n protected onTranslationsCacheMiss?: (\n event: TranslationsCacheMissEvent<TranslationValue>\n ) => void;\n\n /**\n * Locale-keyed caches for translations and dictionaries\n */\n private translations: ResourceCache<\n Locale,\n TranslationsCache<TranslationValue>\n >;\n private dictionaries: ResourceCache<Locale, DictionaryCache>;\n\n /**\n * Creates a locale-bound translateMany for runtime translation\n */\n private createTranslateMany: CreateTranslateMany;\n\n /**\n * Creates an instance of I18nCache.\n * TODO: resolve gtConfig from just file path\n * @param params - The parameters for the I18nCache constructor\n * @param params.config - The configuration for the I18nCache\n */\n constructor(params: I18nCacheConstructorParams) {\n // Validation\n validateCacheParams(params);\n\n this.config = {\n projectId: params.projectId,\n devApiKey: params.devApiKey,\n apiKey: params.apiKey,\n runtimeUrl: params.runtimeUrl,\n modelProvider: params.modelProvider,\n cacheExpiryTime: params.cacheExpiryTime,\n batchConfig: params.batchConfig,\n runtimeTranslation: params.runtimeTranslation,\n _versionId: params._versionId,\n };\n\n // Create cache miss handlers\n const loadTranslations = 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 },\n }) as SafeTranslationsLoader<TranslationValue>;\n const loadDictionary = params.loadDictionary ?? (() => Promise.resolve({}));\n this.createTranslateMany = createTranslateManyFactory(\n getI18nConfig().getGTClass(),\n this.config.runtimeTranslation?.timeout ?? DEFAULT_TRANSLATION_TIMEOUT,\n {\n ...(this.config.modelProvider && {\n modelProvider: this.config.modelProvider,\n }),\n ...this.config.runtimeTranslation?.metadata,\n }\n );\n\n // Setup locale-keyed caches\n const ttl = this.config.cacheExpiryTime;\n this.translations = new ResourceCache<\n Locale,\n TranslationsCache<TranslationValue>\n >({\n ttl,\n load: async (locale) =>\n this.createTranslationsCache(locale, await loadTranslations(locale)),\n });\n this.dictionaries = new ResourceCache<Locale, DictionaryCache>({\n ttl,\n load: async (locale) =>\n this.createDictionaryCache(locale, await loadDictionary(locale)),\n });\n\n // The default locale's source dictionary is provided synchronously and\n // never expires\n const defaultLocale = getI18nConfig().getDefaultLocale();\n this.dictionaries.set(\n defaultLocale,\n this.createDictionaryCache(defaultLocale, params.dictionary ?? {}),\n { expiresAt: -1 }\n );\n }\n\n // ========== Cache Factories ========== //\n\n private createTranslationsCache(\n locale: Locale,\n init: Record<Hash, TranslationValue>\n ): TranslationsCache<TranslationValue> {\n return new TranslationsCache<TranslationValue>({\n init,\n translateMany: this.createTranslateMany(locale),\n batchConfig: this.config.batchConfig,\n onMiss: (hash, translation) =>\n this.onTranslationsCacheMiss?.({ locale, hash, translation }),\n });\n }\n\n private createDictionaryCache(\n locale: Locale,\n init: Dictionary\n ): DictionaryCache {\n return new DictionaryCache({\n init,\n runtimeTranslate: (id, sourceEntry) =>\n this.translateDictionaryEntry(locale, id, sourceEntry),\n });\n }\n\n // ========== Getters and Setters ========== //\n\n /**\n * Get the version ID\n */\n getVersionId(): string | undefined {\n return this.config._versionId;\n }\n\n // ========== Translation Updates ========== //\n\n updateTranslations(\n translationsSnapshot: Record<Locale, Record<Hash, TranslationValue>>\n ): void {\n for (const locale in translationsSnapshot) {\n const txCache = this.translations.get(locale);\n if (txCache) {\n txCache.update(translationsSnapshot[locale]);\n } else {\n this.translations.set(\n locale,\n this.createTranslationsCache(locale, translationsSnapshot[locale])\n );\n }\n }\n }\n\n updateDictionaries(dictionarySnapshot: Record<Locale, Dictionary>): void {\n for (const locale in dictionarySnapshot) {\n const dictionaryCache = this.dictionaries.get(locale);\n if (dictionaryCache) {\n dictionaryCache.update(dictionarySnapshot[locale]);\n } else {\n this.dictionaries.set(\n locale,\n this.createDictionaryCache(locale, dictionarySnapshot[locale])\n );\n }\n }\n }\n\n // ========== Translation Resolution ========== //\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 return this.guardAsync({}, async () => {\n // Validate\n const translationLocale = this._resolveCacheLocale(locale);\n if (!translationLocale) {\n return {};\n }\n\n const txCache = await this.translations.getOrLoad(translationLocale);\n\n // Get the translations\n return txCache.getInternalCache();\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 return this.guardAsync({}, async () => {\n // Validate\n const dictionaryLocale = this._resolveCacheLocale(locale);\n if (!dictionaryLocale) {\n return this.getDefaultDictionaryCache()?.getInternalCache() ?? {};\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n\n return dictionaryCache.getInternalCache();\n });\n }\n\n /**\n * Look up a dictionary entry\n */\n lookupDictionary(locale: string, id: string): DictionaryEntry | undefined {\n return this.guard(undefined, () =>\n this.dictionaries\n .get(this.resolveDictionaryCacheLocale(locale))\n ?.getEntry(id)\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 return this.guard(undefined, () =>\n this.dictionaries\n .get(this.resolveDictionaryCacheLocale(locale))\n ?.getValue(id)\n );\n }\n\n async getLookupDictionary(locale: string): Promise<DictionaryResolvers> {\n return this.guardAsync<DictionaryResolvers>(\n {\n lookupDictionary: () => undefined,\n lookupDictionaryObj: () => undefined,\n },\n async () => {\n const asyncBoundaryLocale = this._resolveCacheLocale(locale);\n const asyncBoundaryDictionaryCache = asyncBoundaryLocale\n ? await this.dictionaries.getOrLoad(asyncBoundaryLocale)\n : this.getDefaultDictionaryCache();\n\n return {\n lookupDictionary: (id) => asyncBoundaryDictionaryCache?.getEntry(id),\n lookupDictionaryObj: (id) =>\n asyncBoundaryDictionaryCache?.getValue(id),\n };\n }\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 return this.guardAsync(undefined, async () => {\n const dictionaryLocale = this._resolveCacheLocale(locale);\n if (!dictionaryLocale) {\n return this.getSourceDictionaryEntry(id);\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n\n return (\n dictionaryCache.getEntry(id) ??\n (await dictionaryCache.materializeEntry(\n id,\n this.getSourceDictionaryEntry(id)\n ))\n );\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 return this.guardAsync(undefined, async () => {\n const dictionaryLocale = this._resolveCacheLocale(locale);\n\n if (!dictionaryLocale) {\n return this.getSourceDictionaryObject(id);\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n const targetObject = dictionaryCache.getValue(id);\n const sourceObject = this.getSourceDictionaryObject(id, {\n throwOnMissing: false,\n });\n if (sourceObject === undefined) {\n if (targetObject !== undefined) {\n return targetObject;\n }\n throw new DictionarySourceNotFoundError(id);\n }\n\n return await dictionaryCache.materializeValue(\n id,\n sourceObject,\n targetObject\n );\n });\n }\n\n private async translateDictionaryEntry(\n locale: Locale,\n id: string,\n sourceEntry: DictionaryEntry\n ): Promise<string> {\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 return translation;\n }\n\n private getSourceDictionaryEntry(id: string): DictionaryEntry {\n const sourceEntry = this.getDefaultDictionaryCache()?.getEntry(id);\n if (sourceEntry === undefined) {\n throw new DictionarySourceNotFoundError(id);\n }\n return sourceEntry;\n }\n\n private getSourceDictionaryObject(\n id: string,\n { throwOnMissing = true }: { throwOnMissing?: boolean } = {}\n ): DictionaryObject | undefined {\n const sourceObject = this.getDefaultDictionaryCache()?.getValue(id);\n if (sourceObject === undefined && throwOnMissing) {\n throw new DictionarySourceNotFoundError(id);\n }\n return sourceObject;\n }\n\n private getDefaultDictionaryCache() {\n return this.dictionaries.get(getI18nConfig().getDefaultLocale());\n }\n\n private resolveDictionaryCacheLocale(locale: string): Locale {\n return (\n this._resolveCacheLocale(locale) ?? getI18nConfig().getDefaultLocale()\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 return this.guard<T | undefined>(undefined, () => {\n // Validate\n const { translationLocale, options: lookupOptions } =\n this.resolveLookupParams(locale, options);\n\n // Early return if in default locale\n if (!translationLocale) return message;\n\n // Get the translation from the locale cache\n return this.translations\n .get(translationLocale)\n ?.get({ message, options: lookupOptions });\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 return this.guardAsync<T | undefined>(undefined, () =>\n this.lookupTranslationWithFallbackResolved(locale, message, options)\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 * @returns A lookup translation function\n *\n * @important prefetchEntries must all be the same locale\n */\n async getLookupTranslation(locale: string): Promise<\n TranslationResolver<TranslationValue> & {\n prefetchEntries?: PrefetchEntriesType<TranslationValue>;\n }\n > {\n return this.guardAsync<TranslationResolver<TranslationValue>>(\n (message) => message,\n async () => {\n // Locale used for the async load\n const asyncBoundaryLocale = this._resolveCacheLocale(locale);\n\n // Early return if i18n is disabled or default locale\n if (!asyncBoundaryLocale) {\n return (message) => message;\n }\n\n const asyncBoundaryTxCache =\n await this.translations.getOrLoad(asyncBoundaryLocale);\n\n // Prefetch any entries during async block (dev hot reload only)\n const prefetchEntries = async (\n prefetchEntries: {\n message: TranslationValue;\n options: LookupOptions;\n }[] = []\n ) => {\n if (\n process.env.NODE_ENV !== 'production' &&\n getI18nConfig().isDevHotReloadEnabled()\n ) {\n // Invariant: all prefetchEntries must be the same locale\n // TODO: investigate why we have made this an invariant, we may be able to drop this requirement\n const resolvedPrefetchEntries = resolvePrefetchEntriesByLocale(\n prefetchEntries,\n asyncBoundaryLocale,\n (entryLocale) =>\n this._resolveCacheLocale(entryLocale) ??\n this._resolveLocale(entryLocale)\n );\n if (resolvedPrefetchEntries.length !== prefetchEntries.length) {\n logger.warn(\n `I18nCache: getLookupTranslation(): prefetchEntries must all be the same locale, ignoring all entries that are not for ${asyncBoundaryLocale}`\n );\n }\n\n await Promise.allSettled(\n resolvedPrefetchEntries\n .filter((entry) => asyncBoundaryTxCache.get(entry) == null)\n .map((entry) => asyncBoundaryTxCache.miss(entry))\n );\n }\n };\n\n // Create translation resolver\n const lookupTranslation: TranslationResolver<TranslationValue> = (\n message,\n lookupOptions: LookupOptions = {} as LookupOptions\n ) =>\n this.guard(undefined, () => {\n const { translationLocale, options } = this.resolveLookupParams(\n lookupOptions.$locale ?? asyncBoundaryLocale,\n lookupOptions\n );\n\n // Default locale, return the message\n if (!translationLocale) return message;\n\n // Request locale overriden, to attempt a synchronous lookup if an alternate locale is requested\n const txCache =\n translationLocale === asyncBoundaryLocale\n ? asyncBoundaryTxCache\n : this.translations.get(translationLocale);\n\n // Get the translation\n return txCache?.get({ message, options });\n });\n\n Object.assign(lookupTranslation, { prefetchEntries });\n return lookupTranslation;\n }\n );\n }\n\n // ========== Error Handling ========== //\n\n /**\n * Run a lookup, routing errors through handleError (log in production,\n * throw in development) and returning the fallback once handled.\n */\n private guard<T>(fallback: T, fn: () => T): T {\n try {\n return fn();\n } catch (error) {\n this.handleError(error);\n return fallback;\n }\n }\n\n private async guardAsync<T>(fallback: T, fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n this.handleError(error);\n return fallback;\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 (getRuntimeEnvironment()) {\n case 'development':\n throw error;\n case 'production':\n default:\n logger.error('I18nCache: ' + error);\n break;\n }\n }\n\n private _resolveLocale(locale: string) {\n const i18nConfig = getI18nConfig();\n const resolvedLocale = i18nConfig.determineLocale(locale);\n if (!i18nConfig.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 const i18nConfig = getI18nConfig();\n if (i18nConfig.requiresTranslation(resolvedLocale)) {\n return resolvedLocale;\n }\n\n const aliasLocale = i18nConfig.resolveAliasLocale(\n i18nConfig.standardizeLocale(locale)\n );\n if (i18nConfig.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 ): LookupOptions {\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 const txCache = await this.translations.getOrLoad(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\nexport { I18nCache };\n\n// ===== Helper Functions ===== //\n\n/**\n * Validate constructor params: log warnings for suspicious configs and throw\n * on hard misconfigurations.\n */\nfunction validateCacheParams(params: I18nCacheConstructorParams): void {\n // Runtime translation against a custom API URL still needs GT credentials\n if (params.runtimeUrl && params.runtimeUrl !== defaultRuntimeApiUrl) {\n if (!params.projectId) {\n logger.warn(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'Runtime translation needs a projectId',\n fix: 'Add projectId to the I18nCache config or disable runtime translation',\n })\n );\n }\n if (!params.devApiKey && !params.apiKey) {\n logger.warn(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'Runtime translation needs devApiKey or apiKey',\n fix: 'Add credentials to the I18nCache config or disable runtime translation',\n })\n );\n }\n }\n\n // loadDictionary requires dictionary so the default locale always has a\n // source dictionary\n if (params.loadDictionary && !params.dictionary) {\n logger.error(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'loadDictionary needs a source dictionary',\n fix: 'Provide dictionary so the default locale has source content',\n })\n );\n throw new Error('Validation errors occurred');\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","import type { ReadonlyConditionStoreInterface as ReadonlyConditionStoreContract } from '../i18n-cache/types';\nimport type { LocaleCandidates } from '../i18n-config/I18nConfig';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\n\nexport type ReadonlyConditionStoreParams = {\n locale: LocaleCandidates;\n region?: string;\n enableI18n?: boolean;\n};\n\nexport class ReadonlyConditionStore implements ReadonlyConditionStoreContract {\n protected locale: string;\n protected region?: string;\n protected enableI18n: boolean;\n\n constructor({\n locale,\n region,\n enableI18n = true,\n }: ReadonlyConditionStoreParams) {\n this.locale = getI18nConfig().resolveSupportedLocale(locale);\n this.region = region;\n this.enableI18n = enableI18n;\n }\n\n getLocale = (): string => {\n return this.locale;\n };\n\n getRegion = (): string | undefined => {\n return this.region;\n };\n\n getEnableI18n = (): boolean => {\n return this.enableI18n;\n };\n\n // --- no-op methods --- //\n\n setLocale = (locale: LocaleCandidates): void => {};\n\n setRegion = (region: string | undefined): void => {};\n\n setEnableI18n = (enableI18n: boolean): void => {};\n}\n","import type { WritableConditionStoreInterface } from '../i18n-cache/types';\nimport type { LocaleCandidates } from '../i18n-config/I18nConfig';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\nimport {\n ReadonlyConditionStore,\n type ReadonlyConditionStoreParams,\n} from './ReadonlyConditionStore';\n\nexport type WritableConditionStoreParams = ReadonlyConditionStoreParams;\n\nexport class WritableConditionStore\n extends ReadonlyConditionStore\n implements WritableConditionStoreInterface\n{\n setLocale = (locale: LocaleCandidates): void => {\n this.locale = getI18nConfig().resolveSupportedLocale(locale);\n };\n\n setRegion = (region: string | undefined): void => {\n this.region = region;\n };\n\n setEnableI18n = (enableI18n: boolean): void => {\n this.enableI18n = enableI18n;\n };\n}\n","import type { LookupOptions } from '../translation-functions/types/options';\nimport type { Translation } from '../types';\nimport { hashMessage } from './hashMessage';\n\nexport type TranslateListenerLookup<T extends Translation = Translation> =\n | {\n locale: string;\n message: T;\n options: LookupOptions;\n }\n | {\n locale: string;\n hash: string;\n };\n\nexport type DictionaryListenerLookup = {\n locale: string;\n id: string;\n};\n\nexport function getTranslateListenerKey<T extends Translation>(\n lookup: TranslateListenerLookup<T>\n): string {\n const hash =\n 'hash' in lookup\n ? lookup.hash\n : hashMessage(lookup.message, lookup.options);\n return `${lookup.locale}:${hash}`;\n}\n\nexport function getDictionaryListenerKey({\n locale,\n id,\n}: DictionaryListenerLookup): string {\n return `${locale}:${id}`;\n}\n","type HeaderValue = string | string[] | null | undefined;\n\n/**\n * Parse an Accept-Language header into locale candidates by preference.\n */\nexport function parseAcceptLanguage(header: HeaderValue): string[] {\n const headerValues = Array.isArray(header) ? header : [header];\n\n return headerValues\n .flatMap((value) => value?.split(',') ?? [])\n .map((entry, index) => {\n const [locale = '', ...parameters] = entry\n .split(';')\n .map((value) => value.trim());\n const qualityParameter = parameters.find((parameter) =>\n parameter.toLowerCase().startsWith('q=')\n );\n const quality = Number(qualityParameter?.slice(2) ?? 1);\n return { locale, quality, index };\n })\n .filter(\n ({ locale, quality }) =>\n locale !== '' && locale !== '*' && quality > 0 && quality <= 1\n )\n .sort((a, b) => b.quality - a.quality || a.index - b.index)\n .map(({ locale }) => locale);\n}\n\n/**\n * Read and decode a value from a Cookie header or document.cookie string.\n */\nexport function getCookieValue(\n cookieHeader: string | null | undefined,\n cookieName: string\n): string | undefined {\n const prefix = `${cookieName}=`;\n const cookie = cookieHeader\n ?.split(';')\n .map((value) => value.trim())\n .find((value) => value.startsWith(prefix));\n if (!cookie) return undefined;\n\n const value = cookie.slice(prefix.length);\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { a as JsxTranslationOptions, c as NormalizedLookupOptions, f as TranslationVariables, l as RuntimeTranslationOptions, n as DictionaryLookupOptions, o as LookupOptions, r as EncodedTranslationOptions, s as LookupOptionsFor } from "./options-BXeFwN0R.cjs";
2
2
  import { o as TFunctionType, r as MFunctionType, t as DictionaryObjectTranslation } from "./functions-BiA2tWER.cjs";
3
3
  import { t as getVersionId } from "./versionId-0COhh5UX.cjs";
4
- import { _ as Hash, a as I18nConfig, c as AsyncReadonlyConditionStoreInterface, d as I18nCacheConstructorParams, i as ReadonlyConditionStoreParams, n as WritableConditionStoreParams, o as I18nConfigParams, p as ReadonlyConditionStoreInterface, r as ReadonlyConditionStore, s as LocaleCandidates, t as WritableConditionStore, u as I18nCacheConfig, v as Locale } from "./WritableConditionStore-7OwoOSxr.cjs";
4
+ import { _ as Hash, a as I18nConfig, c as AsyncReadonlyConditionStoreInterface, d as I18nCacheConstructorParams, i as ReadonlyConditionStoreParams, n as WritableConditionStoreParams, o as I18nConfigParams, p as ReadonlyConditionStoreInterface, r as ReadonlyConditionStore, s as LocaleCandidates, t as WritableConditionStore, u as I18nCacheConfig, v as Locale } from "./WritableConditionStore-ekDSlgJ7.cjs";
5
5
  import { c as DictionaryValue, l as Translation, n as Dictionary, o as DictionaryObject, r as DictionaryEntry } from "./DictionaryCache-DjAdDNiM.cjs";
6
6
  import { n as getGT, r as getGTInternal } from "./types-wiJpMiR8.cjs";
7
7
  import { DataFormat, JsxChildren, StringFormat } from "@generaltranslation/format/types";
@@ -1,7 +1,7 @@
1
1
  import { a as JsxTranslationOptions, c as NormalizedLookupOptions, f as TranslationVariables, l as RuntimeTranslationOptions, n as DictionaryLookupOptions, o as LookupOptions, r as EncodedTranslationOptions, s as LookupOptionsFor } from "./options-DDUyXaLT.mjs";
2
2
  import { o as TFunctionType, r as MFunctionType, t as DictionaryObjectTranslation } from "./functions-BZ_xopQU.mjs";
3
3
  import { t as getVersionId } from "./versionId-Zel3fqtC.mjs";
4
- import { _ as Hash, a as I18nConfig, c as AsyncReadonlyConditionStoreInterface, d as I18nCacheConstructorParams, i as ReadonlyConditionStoreParams, n as WritableConditionStoreParams, o as I18nConfigParams, p as ReadonlyConditionStoreInterface, r as ReadonlyConditionStore, s as LocaleCandidates, t as WritableConditionStore, u as I18nCacheConfig, v as Locale } from "./WritableConditionStore-Y7klxD29.mjs";
4
+ import { _ as Hash, a as I18nConfig, c as AsyncReadonlyConditionStoreInterface, d as I18nCacheConstructorParams, i as ReadonlyConditionStoreParams, n as WritableConditionStoreParams, o as I18nConfigParams, p as ReadonlyConditionStoreInterface, r as ReadonlyConditionStore, s as LocaleCandidates, t as WritableConditionStore, u as I18nCacheConfig, v as Locale } from "./WritableConditionStore-BUblH4YU.mjs";
5
5
  import { c as DictionaryValue, l as Translation, n as Dictionary, o as DictionaryObject, r as DictionaryEntry } from "./DictionaryCache-B7oTBs5W.mjs";
6
6
  import { n as getGT, r as getGTInternal } from "./types-CRivFf_D.mjs";
7
7
  import { DataFormat, JsxChildren, StringFormat } from "@generaltranslation/format/types";
package/dist/internal.mjs CHANGED
@@ -850,6 +850,7 @@ var I18nCache = class {
850
850
  devApiKey: params.devApiKey,
851
851
  apiKey: params.apiKey,
852
852
  runtimeUrl: params.runtimeUrl,
853
+ modelProvider: params.modelProvider,
853
854
  cacheExpiryTime: params.cacheExpiryTime,
854
855
  batchConfig: params.batchConfig,
855
856
  runtimeTranslation: params.runtimeTranslation,
@@ -866,7 +867,10 @@ var I18nCache = class {
866
867
  }
867
868
  });
868
869
  const loadDictionary = params.loadDictionary ?? (() => Promise.resolve({}));
869
- this.createTranslateMany = createTranslateManyFactory(getI18nConfig().getGTClass(), this.config.runtimeTranslation?.timeout ?? DEFAULT_TRANSLATION_TIMEOUT, this.config.runtimeTranslation?.metadata ?? {});
870
+ this.createTranslateMany = createTranslateManyFactory(getI18nConfig().getGTClass(), this.config.runtimeTranslation?.timeout ?? DEFAULT_TRANSLATION_TIMEOUT, {
871
+ ...this.config.modelProvider && { modelProvider: this.config.modelProvider },
872
+ ...this.config.runtimeTranslation?.metadata
873
+ });
870
874
  const ttl = this.config.cacheExpiryTime;
871
875
  this.translations = new ResourceCache({
872
876
  ttl,
@@ -1 +1 @@
1
- {"version":3,"file":"internal.mjs","names":[],"sources":["../src/translation-functions/internal/getGT.ts","../src/translation-functions/internal/getMessages.ts","../src/translation-functions/internal/renderDictionaryEntry.ts","../src/i18n-cache/translations-manager/utils/dictionary-helpers.ts","../src/translation-functions/internal/renderDictionaryObject.ts","../src/translation-functions/internal/getTranslations.ts","../src/translation-functions/internal/tx.ts","../src/translation-functions/internal/runtime-translate.ts","../src/i18n-cache/translations-manager/utils/createTranslateMany.ts","../src/i18n-cache/translations-manager/translations-loaders/createRemoteTranslationLoader.ts","../src/i18n-cache/translations-manager/translations-loaders/routeCreateTranslationLoader.ts","../src/i18n-cache/translations-manager/utils/constants.ts","../src/i18n-cache/translations-manager/utils/dedupePending.ts","../src/i18n-cache/translations-manager/ResourceCache.ts","../src/i18n-cache/translations-manager/TranslationsCache.ts","../src/i18n-cache/translations-manager/utils/DictionarySourceNotFoundError.ts","../src/i18n-cache/translations-manager/utils/materialize-dictionary.ts","../src/i18n-cache/translations-manager/DictionaryCache.ts","../src/i18n-cache/I18nCache.ts","../src/condition-store/ReadonlyConditionStore.ts","../src/condition-store/WritableConditionStore.ts","../src/utils/listenerKeys.ts","../src/utils/request.ts"],"sourcesContent":["import { getI18nCache } from '../../i18n-cache/singleton-operations';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { GTTranslationOptions, TranslationMetadata } from '../types/options';\nimport { GTFunctionType } from '../types/functions';\nimport { interpolateMessage } from '../utils/interpolation/interpolateMessage';\nimport { createLookupOptions } from './helpers';\nimport type { StringFormat } from '@generaltranslation/format/types';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\nexport type Message = TranslationMetadata & {\n message: string;\n};\n\n/**\n * Returns the gt function that registers a string at build time and resolves its translation at runtime.\n * @returns A promise of the gt function\n *\n * @example\n * const gt = await getGT();\n * const greeting = gt('Hello, world!');\n */\nexport async function getGT(_messages?: Message[]): Promise<GTFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getGTInternal({ locale, enableI18n }, _messages);\n}\n\n/**\n * Condition store agnostic getGT function\n */\nexport async function getGTInternal(\n {\n locale,\n enableI18n,\n }: {\n locale: string;\n enableI18n: boolean;\n },\n _messages?: Message[]\n): Promise<GTFunctionType> {\n // Get the translation resolver\n const i18nCache = getI18nCache();\n const sourceLocale = getI18nConfig().getDefaultLocale();\n // Statically gated so bundlers can drop dev hot-reload work from\n // production builds.\n const devHotReloadEnabled =\n process.env.NODE_ENV !== 'production' &&\n getI18nConfig().isDevHotReloadEnabled();\n const lookupTranslation = await i18nCache.getLookupTranslation(\n enableI18n ? locale : sourceLocale\n );\n\n // dev hot reload translate compiler injected lookups\n if (devHotReloadEnabled && lookupTranslation.prefetchEntries) {\n await lookupTranslation.prefetchEntries(\n _messages?.map(({ message, ...options }) => ({\n message,\n options: {\n $format: 'ICU',\n ...options,\n },\n })) ?? []\n );\n }\n\n /**\n * Registers a message at build time and resolves its translation at runtime.\n * @param {string} message - The message to translate\n * @param {GTTranslationOptions} options - The options for the translation\n * @returns The translated message\n *\n * @example\n * // Simple translation without interpolation\n * const gt = await getGT();\n * const greeting = gt('Hello, world!');\n *\n * @example\n * // Translation with interpolation\n * const gt = await getGT();\n * const welcome = gt('Hello, {name}!', { name: 'Alice' });\n */\n const gt: GTFunctionType = (\n message: string,\n options: GTTranslationOptions = {}\n ) => {\n const targetLocale = enableI18n\n ? (options.$locale ?? locale)\n : getI18nConfig().getDefaultLocale();\n const lookupOptions = createLookupOptions<StringFormat>(\n targetLocale,\n options,\n 'ICU'\n );\n\n // Lookup translation\n const translation = lookupTranslation(message, lookupOptions);\n\n // Dev hot reload (fire and forget, will be available in a later lookup)\n if (devHotReloadEnabled && translation == null) {\n void i18nCache\n .lookupTranslationWithFallback(\n lookupOptions.$locale,\n message,\n lookupOptions\n )\n .catch(() => {});\n }\n\n // Format result\n return interpolateMessage({\n source: message,\n target: translation,\n options: lookupOptions,\n sourceLocale,\n });\n };\n\n return gt;\n}\n","import { GTTranslationOptions } from '../types/options';\nimport { decodeOptions } from '../msg/decodeOptions';\nimport { isEncodedTranslationOptions } from '../utils/isEncodedTranslationOptions';\nimport { getGTInternal } from './getGT';\nimport { MFunctionType } from '../types/functions';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\n/**\n * Returns the m function that resolves a registered message to its translation.\n * @returns A promise of the m function\n *\n * @example\n * // Registration\n * const registeredMessage = msg('Hello, world!');\n *\n * // Resolution\n * const m = await getMessages();\n * const greeting = m(registeredMessage);\n */\nexport async function getMessages(): Promise<MFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getMessagesInternal({ locale, enableI18n });\n}\n\n/**\n * Condition store agnostic getMessages function\n */\nexport async function getMessagesInternal({\n locale,\n enableI18n,\n}: {\n locale: string;\n enableI18n: boolean;\n}): Promise<MFunctionType> {\n // Get the gt function\n const gt = await getGTInternal({ locale, enableI18n });\n\n /**\n * Resolves a registered message to its translation.\n * @param {string | null | undefined} encodedMsg - The encoded message to decode and interpolate.\n * @param {GTTranslationOptions} options - The options to interpolate.\n * @returns - The decoded and interpolated message.\n *\n * @example\n * // Simple message without interpolation\n * const m = await getMessages();\n * const greeting = m(msg('Hello, world!'));\n *\n * @example\n * // Message with interpolation\n * const m = await getMessages();\n * const welcome = m(msg('Welcome, {user}!'), { user: 'Alice' });\n */\n const m: MFunctionType = <T extends string | null | undefined>(\n encodedMsg: T,\n options: GTTranslationOptions = {}\n ): T extends string ? string : T => {\n // Return if the encoded message is null or undefined\n if (encodedMsg == null) return encodedMsg as T extends string ? string : T;\n\n // Get any encoded options\n const decodedOptions = decodeOptions(encodedMsg) ?? {};\n\n // Return early if string already interpolated eg: mFallback(msg('Hello, {name}!', { name: 'Brian' }))\n if (isEncodedTranslationOptions(decodedOptions)) {\n return gt(decodedOptions.$_source, decodedOptions) as T extends string\n ? string\n : T;\n }\n\n // Use gt to interpolate\n // Separate from decoded options to match behavior in @gt/react-core\n return gt(encodedMsg, options) as T extends string ? string : T;\n };\n\n return m;\n}\n","import { createLookupOptions } from './helpers';\nimport { extractVariables } from '../../utils/extractVariables';\nimport { interpolateMessage } from '../utils/interpolation/interpolateMessage';\nimport type {\n DictionaryLookupOptions,\n TranslationVariables,\n} from '../types/options';\nimport type { DictionaryEntry } from '../../i18n-cache/translations-manager/DictionaryCache';\nimport type { StringFormat } from '@generaltranslation/format/types';\n\nexport function renderDictionaryEntry({\n sourceLocale,\n targetLocale,\n sourceEntry,\n target,\n dictionaryOptions,\n options = {},\n}: {\n sourceLocale: string;\n targetLocale: string;\n sourceEntry: DictionaryEntry;\n target: string | undefined;\n dictionaryOptions: DictionaryLookupOptions;\n options?: TranslationVariables;\n}): string {\n const lookupOptions = createLookupOptions<StringFormat>(\n targetLocale,\n {\n ...dictionaryOptions,\n ...extractVariables(options),\n },\n dictionaryOptions.$format\n );\n\n return interpolateMessage({\n source: sourceEntry.entry,\n target,\n options: lookupOptions,\n sourceLocale,\n });\n}\n","import type {\n Dictionary,\n DictionaryEntry,\n DictionaryLeaf,\n DictionaryPath,\n DictionaryValue,\n} from './types/dictionary';\nimport type {\n DictionaryEntryOptions,\n DictionaryLookupOptions,\n} from '../../../translation-functions/types/options';\n\nfunction getDictionaryPath(id: DictionaryPath): string[] {\n const path = id ? id.split('.') : [];\n for (const segment of path) {\n assertSafeDictionaryPathSegment(segment, id);\n }\n return path;\n}\n\nexport function assertSafeDictionaryPathSegment(\n segment: string,\n path: DictionaryPath\n): void {\n if (\n segment === '__proto__' ||\n segment === 'constructor' ||\n segment === 'prototype'\n ) {\n throw new Error(`Dictionary path \"${path}\" contains an unsafe segment`);\n }\n}\n\nexport function isDictionaryValue(value: unknown): value is Dictionary {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n}\n\nexport function cloneDictionaryValue<Value extends DictionaryValue | undefined>(\n value: Value\n): Value {\n if (value === undefined || typeof value === 'string') {\n return value;\n }\n return structuredClone(value) as Value;\n}\n\nexport function getDictionaryValueAtPath(\n dictionary: Dictionary,\n path: DictionaryPath\n): DictionaryValue | undefined {\n let current: DictionaryValue = dictionary;\n\n for (const segment of getDictionaryPath(path)) {\n if (!isDictionaryValue(current)) {\n return undefined;\n }\n current = current[segment];\n }\n\n return current;\n}\n\nexport function setDictionaryValueAtPath(\n dictionary: Dictionary,\n path: DictionaryPath,\n value: DictionaryValue\n): void {\n const segments = getDictionaryPath(path);\n if (isDictionaryValue(value)) {\n assertSafeDictionaryObject(value, path);\n }\n\n if (segments.length === 0) {\n if (isDictionaryValue(value)) {\n replaceDictionary(dictionary, value);\n }\n return;\n }\n\n let current = dictionary;\n for (const segment of segments.slice(0, -1)) {\n const next = current[segment];\n if (!isDictionaryValue(next)) {\n current[segment] = {} as Dictionary;\n }\n current = current[segment] as Dictionary;\n }\n\n const leafSegment = segments[segments.length - 1];\n current[leafSegment] = 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 };\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 && isDictionaryLeafOptions(value[1]);\n}\n\nfunction isDictionaryLeafOptions(\n value: unknown\n): value is DictionaryEntryOptions {\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 || typeof options.$maxChars === 'number')\n );\n}\n\nfunction isStringFormat(\n value: unknown\n): value is DictionaryLookupOptions['$format'] {\n return value === 'ICU' || value === 'I18NEXT' || value === 'STRING';\n}\n\nfunction replaceDictionary(target: Dictionary, source: Dictionary): void {\n for (const key of Object.keys(target)) {\n delete target[key];\n }\n for (const key of Object.keys(source)) {\n target[key] = source[key];\n }\n}\n\nfunction assertSafeDictionaryObject(\n dictionary: Dictionary,\n parentPath = ''\n): void {\n for (const [key, value] of Object.entries(dictionary)) {\n const path = parentPath ? `${parentPath}.${key}` : key;\n assertSafeDictionaryPathSegment(key, path);\n if (isDictionaryValue(value)) {\n assertSafeDictionaryObject(value, path);\n }\n }\n}\n","import {\n getDictionaryEntry,\n isDictionaryValue,\n resolveDictionaryLookupOptions,\n} from '../../i18n-cache/translations-manager/utils/dictionary-helpers';\nimport type { DictionaryObjectTranslation } from '../types/functions';\nimport type { DictionaryLookupOptions } from '../types/options';\nimport type {\n DictionaryEntry,\n DictionaryValue,\n} from '../../i18n-cache/translations-manager/DictionaryCache';\n\nexport function renderDictionaryObject({\n sourceObject,\n targetObject,\n translate,\n}: {\n sourceObject: DictionaryValue | undefined;\n targetObject: DictionaryValue | undefined;\n translate?: (\n sourceEntry: DictionaryEntry,\n dictionaryOptions: DictionaryLookupOptions\n ) => string | undefined;\n}): DictionaryObjectTranslation {\n const targetEntry = getDictionaryEntry(targetObject);\n if (targetEntry !== undefined) {\n return targetEntry.entry;\n }\n\n if (isDictionaryValue(targetObject)) {\n if (!isDictionaryValue(sourceObject)) {\n return renderDictionaryObject({\n sourceObject: targetObject,\n targetObject: undefined,\n translate,\n });\n }\n\n return renderDictionaryObjectChildren({\n sourceObject,\n targetObject,\n translate,\n });\n }\n\n const sourceEntry = getDictionaryEntry(sourceObject);\n if (sourceEntry !== undefined) {\n const dictionaryOptions = resolveDictionaryLookupOptions(\n sourceEntry.options\n );\n return translate?.(sourceEntry, dictionaryOptions) ?? sourceEntry.entry;\n }\n\n if (isDictionaryValue(sourceObject)) {\n return renderDictionaryObjectChildren({\n sourceObject,\n targetObject: undefined,\n translate,\n });\n }\n\n throw new Error('Dictionary object cannot be rendered');\n}\n\nfunction renderDictionaryObjectChildren({\n sourceObject,\n targetObject,\n translate,\n}: {\n sourceObject: DictionaryValue;\n targetObject: DictionaryValue | undefined;\n translate?: (\n sourceEntry: DictionaryEntry,\n dictionaryOptions: DictionaryLookupOptions\n ) => string | undefined;\n}): DictionaryObjectTranslation {\n if (!isDictionaryValue(sourceObject)) {\n return renderDictionaryObject({ sourceObject, targetObject, translate });\n }\n\n const result: Record<string, DictionaryObjectTranslation> = {};\n const keys = new Set([\n ...Object.keys(sourceObject),\n ...(isDictionaryValue(targetObject) ? Object.keys(targetObject) : []),\n ]);\n\n for (const key of Array.from(keys)) {\n const renderedChild = renderDictionaryObject({\n sourceObject: sourceObject[key],\n targetObject: isDictionaryValue(targetObject)\n ? targetObject[key]\n : undefined,\n translate,\n });\n if (renderedChild !== undefined) {\n result[key] = renderedChild;\n }\n }\n\n return result;\n}\n","import { getI18nCache } from '../../i18n-cache/singleton-operations';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { TranslationVariables } from '../types/options';\nimport { TFunctionType } from '../types/functions';\nimport { renderDictionaryEntry } from './renderDictionaryEntry';\nimport { renderDictionaryObject } from './renderDictionaryObject';\nimport { resolveDictionaryLookupOptions } from '../../i18n-cache/translations-manager/utils/dictionary-helpers';\nimport type { DictionaryObjectTranslation } from '../types/functions';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\n/**\n * Returns the t function that translates a dictionary entry based on its id and options.\n * @returns A promise of the t function\n * @important Must be used inside of a request context\n *\n * @example\n * const t = await getTranslations();\n * const title = await t('page.title');\n */\nexport async function getTranslations(rootId?: string): Promise<TFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getTranslationsInternal({ locale, enableI18n, rootId });\n}\n\n/**\n * Condition store agnostic getTranslations function\n */\nexport async function getTranslationsInternal({\n locale,\n enableI18n,\n rootId,\n}: {\n locale: string;\n enableI18n: boolean;\n rootId?: string;\n}): Promise<TFunctionType> {\n const i18nCache = getI18nCache();\n const sourceLocale = getI18nConfig().getDefaultLocale();\n const targetLocale = enableI18n ? locale : sourceLocale;\n const [sourceDictionary, targetDictionary, lookupTranslation] =\n await Promise.all([\n i18nCache.getLookupDictionary(sourceLocale),\n i18nCache.getLookupDictionary(targetLocale),\n i18nCache.getLookupTranslation(targetLocale),\n ]);\n const {\n lookupDictionary: lookupSourceDictionary,\n lookupDictionaryObj: lookupSourceDictionaryObj,\n } = sourceDictionary;\n const {\n lookupDictionary: lookupTargetDictionary,\n lookupDictionaryObj: lookupTargetDictionaryObj,\n } = targetDictionary;\n\n /**\n * Dictionary resolution\n * @param {string} id - The id of the translation to translate.\n * @param {TranslationVariables} options - The variables for interpolation.\n * @returns {string} The translated message.\n *\n * @example\n * // Simple dictionary lookup without interpolation\n * const t = await getTranslations();\n * const title = t('page.title');\n *\n * @example\n * // Dictionary lookup with interpolation\n * const t = await getTranslations();\n * const greeting = t('user.greeting', { name: 'Bob' });\n */\n const t = ((id: string, options: TranslationVariables = {}): string => {\n id = getId(rootId, id);\n const sourceEntry = lookupSourceDictionary(id);\n if (sourceEntry === undefined) {\n throw new Error(`Dictionary entry ${id} cannot be found`);\n }\n const targetEntry = lookupTargetDictionary(id);\n const dictionaryOptions = resolveDictionaryLookupOptions(\n sourceEntry.options\n );\n const target =\n targetEntry?.entry ??\n lookupTranslation(sourceEntry.entry, dictionaryOptions);\n return renderDictionaryEntry({\n sourceLocale,\n targetLocale: targetLocale,\n sourceEntry,\n target,\n dictionaryOptions,\n options,\n });\n }) as TFunctionType;\n\n /**\n * Returns a subtree of the dictionary object translation based on its id.\n * @param {string} id - The id of the translation to translate.\n * @returns The translated object.\n *\n * @example\n * const t = await getTranslations();\n * const greetings = t.obj('greetings');\n * console.log(greetings);\n * // { greeting1: 'Hello', greeting2: 'Hi' }\n */\n t.obj = (id: string): DictionaryObjectTranslation => {\n id = getId(rootId, id);\n const sourceObject = lookupSourceDictionaryObj(id);\n if (sourceObject === undefined) {\n throw new Error(`Dictionary entry ${id} cannot be found`);\n }\n const targetObject = lookupTargetDictionaryObj(id);\n return renderDictionaryObject({\n sourceObject,\n targetObject,\n translate: (sourceEntry, dictionaryOptions) =>\n lookupTranslation(sourceEntry.entry, dictionaryOptions),\n });\n };\n\n return t;\n}\n\nfunction getId(prefix: string | undefined, suffix: string): string {\n return prefix ? `${prefix}.${suffix}` : suffix;\n}\n","import { RuntimeTranslationOptions } from '../types/options';\nimport type { StringFormat } from '@generaltranslation/format/types';\nimport {\n prefetchStringContentWithRuntimeFallback,\n resolveStringContentWithRuntimeFallback,\n} from './helpers';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\ntype RuntimeTranslationOptionsWithFormat = Omit<\n RuntimeTranslationOptions,\n '$format'\n> & {\n $format?: StringFormat;\n};\n\n/**\n * Translates a message at runtime.\n * @param {string} message - The message to translate.\n * @param {RuntimeTranslationOptions} options - The options for the translation.\n * @returns {Promise<string>} The translated message.\n *\n * @example\n * // Simple runtime translation without interpolation\n * const status = await tx('Processing complete', { $locale: 'es-MX' });\n *\n * @example\n * // Runtime translation with interpolation\n * const progress = await tx(`Processing ${status}`, { $locale: 'es-MX' });\n */\nexport async function tx(\n content: string,\n options: RuntimeTranslationOptionsWithFormat = {}\n): Promise<string> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n\n return txInternal({ locale, enableI18n, content, options });\n}\n\n/**\n * Condition store agnostic tx function\n */\nexport async function txInternal({\n locale,\n enableI18n,\n content,\n options,\n}: {\n locale: string;\n enableI18n: boolean;\n content: string;\n options: RuntimeTranslationOptionsWithFormat;\n}): Promise<string> {\n const targetLocale = getTargetLocale({ locale, enableI18n, options });\n return resolveStringContentWithRuntimeFallback(targetLocale, content, {\n $format: 'STRING',\n ...options,\n });\n}\n\n/**\n * Registers a message for runtime translation without interpolating the\n * result. For compiler-injected prefetch calls: their return value is\n * discarded and variable values only exist at the render-time call site, so\n * interpolating here would fail for any message with placeholders.\n */\nexport async function txPrefetch(\n content: string,\n options: RuntimeTranslationOptionsWithFormat = {}\n): Promise<void> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n const targetLocale = getTargetLocale({ locale, enableI18n, options });\n await prefetchStringContentWithRuntimeFallback(targetLocale, content, {\n $format: 'STRING',\n ...options,\n });\n}\n\nfunction getTargetLocale({\n locale,\n enableI18n,\n options,\n}: {\n locale: string;\n enableI18n: boolean;\n options: RuntimeTranslationOptionsWithFormat;\n}): string {\n return enableI18n\n ? typeof options.$locale === 'string'\n ? options.$locale\n : locale\n : getI18nConfig().getDefaultLocale();\n}\n","import type {\n JsxChildren,\n StringFormat,\n} from '@generaltranslation/format/types';\nimport { getLocale } from '../../helpers/locale';\nimport type {\n JsxTranslationOptions,\n RuntimeTranslationOptions,\n} from '../types/options';\nimport { resolveJsxWithRuntimeFallback } from './helpers';\nimport { txPrefetch } from './tx';\n\ntype RuntimeStringTranslationOptions = Omit<\n RuntimeTranslationOptions,\n '$format'\n> & {\n $format?: StringFormat;\n};\n\ntype RuntimeJsxTranslationOptions = JsxTranslationOptions & {\n $locale?: string;\n};\n\nexport const GtInternalRuntimeTranslateString = (\n content: string,\n options: RuntimeStringTranslationOptions = {}\n) => {\n // Prefetch/registration only — the compiler-injected call discards the\n // result, and variable values are unavailable here, so the translation\n // must not be interpolated.\n return txPrefetch(content, { $format: 'ICU', ...options });\n};\n\nexport const GtInternalRuntimeTranslateJsx = (\n content: JsxChildren,\n options: RuntimeJsxTranslationOptions = {}\n) => {\n const locale = options.$locale ?? getLocale();\n return resolveJsxWithRuntimeFallback(locale, content, {\n $format: 'JSX',\n ...options,\n });\n};\n","import type { RuntimeTranslateManyOptions } from 'generaltranslation/internal';\nimport type { Locale } from '../TranslationsCache';\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';\nimport { LoadTranslationsType } from '../../utils/getLoadTranslationsType';\nimport logger from '../../../logs/logger';\nimport { createRemoteTranslationLoader } from './createRemoteTranslationLoader';\nimport { getI18nConfig } from '../../../i18n-config/singleton-operations';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\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 };\n loadTranslations?: TranslationsLoader;\n}): TranslationsLoader {\n const { cacheUrl, projectId, _versionId, _branchId } =\n remoteTranslationLoaderParams;\n\n // Warnings are deferred to loader invocation: translations may be provided\n // externally via updateTranslations() (eg streamed from a server), in which\n // case the loader is never invoked and the warnings do not apply\n switch (type) {\n case LoadTranslationsType.REMOTE:\n case LoadTranslationsType.GT_REMOTE:\n // Only reachable for REMOTE: GT_REMOTE requires a projectId\n if (!projectId) {\n return createWarnOnceTranslationLoader(\n createDiagnosticMessage({\n whatHappened:\n 'Loading translations from a remote store needs a projectId. No translations will be loaded.',\n fix: 'Add projectId to the I18nCache config, or set cacheUrl to null to disable translation loading',\n })\n );\n }\n return createRemoteTranslationLoader({\n cacheUrl: cacheUrl as string | undefined,\n projectId,\n _versionId,\n _branchId,\n customMapping: getI18nConfig().getCustomMapping(),\n });\n case LoadTranslationsType.CUSTOM:\n return loadTranslations!;\n case LoadTranslationsType.DISABLED:\n // cacheUrl: null is an explicit opt-out of translation loading\n if (cacheUrl === null) {\n return async () => ({});\n }\n return createWarnOnceTranslationLoader(\n createDiagnosticMessage({\n whatHappened:\n 'No translation loader found. No translations will be loaded.',\n fix: 'Add projectId to the I18nCache config (to load from the GT remote store), provide a loadTranslations function, or set cacheUrl to null to disable translation loading',\n })\n );\n }\n}\n\n/**\n * Loads no translations and logs a warning once on first invocation\n */\nfunction createWarnOnceTranslationLoader(warning: string): TranslationsLoader {\n let warned = false;\n return async (_locale: string) => {\n if (!warned) {\n warned = true;\n logger.warn('I18nCache: ' + warning);\n }\n return {};\n };\n}\n","/**\n * Default cache expiry time in milliseconds\n */\nexport const DEFAULT_CACHE_EXPIRY_TIME = 60_000; // 60 sec\n","/**\n * Share one in-flight promise per key: concurrent callers for the same key\n * await the same promise, and the pending entry is cleared once it settles.\n */\nexport async function dedupePending<Key, Value>(\n pending: Map<Key, Promise<Value>>,\n key: Key,\n create: () => Promise<Value>\n): Promise<Value> {\n let promise = pending.get(key);\n if (!promise) {\n promise = create();\n pending.set(key, promise);\n }\n\n try {\n return await promise;\n } finally {\n pending.delete(key);\n }\n}\n","import { DEFAULT_CACHE_EXPIRY_TIME } from './utils/constants';\nimport { dedupePending } from './utils/dedupePending';\n\nexport type ResourceCacheEntry<Value> = {\n expiresAt: number;\n value: Value;\n};\n\nexport class ResourceCache<Key extends string, Value> {\n private cache = new Map<Key, ResourceCacheEntry<Value>>();\n private pendingLoads = new Map<Key, Promise<Value>>();\n private loadResource: (key: Key) => Promise<Value>;\n private ttl: number;\n\n constructor({\n load,\n ttl,\n }: {\n load: (key: Key) => Promise<Value>;\n ttl?: number | null;\n }) {\n this.loadResource = load;\n this.ttl = ttl === null ? -1 : (ttl ?? DEFAULT_CACHE_EXPIRY_TIME);\n }\n\n public get(key: Key): Value | undefined {\n const entry = this.cache.get(key);\n if (!entry || this.isExpired(entry)) {\n return undefined;\n }\n\n return entry.value;\n }\n\n public set(\n key: Key,\n value: Value,\n { expiresAt = this.getExpiresAt() }: { expiresAt?: number } = {}\n ): void {\n this.cache.set(key, {\n expiresAt,\n value,\n });\n }\n\n public async getOrLoad(key: Key): Promise<Value> {\n return this.get(key) ?? (await this.load(key));\n }\n\n private load(key: Key): Promise<Value> {\n return dedupePending(this.pendingLoads, key, () =>\n // The entry expiry is computed when the load resolves, not when it starts\n this.loadResource(key).then((value) => {\n this.set(key, value);\n return value;\n })\n );\n }\n\n private getExpiresAt(): number {\n // Avoid Date.now() for Next.js Cache Components; Next handles caching.\n return this.ttl <= 0 ? this.ttl : Date.now() + this.ttl;\n }\n\n private isExpired(entry: ResourceCacheEntry<Value>): boolean {\n // Avoid Date.now() for Next.js Cache Components; Next handles caching.\n if (entry.expiresAt === 0) return true;\n return entry.expiresAt > 0 && entry.expiresAt < Date.now();\n }\n}\n","import { LookupOptions } from '../../translation-functions/types/options';\nimport { Translation } from './utils/types/translation-data';\nimport { hashMessage } from '../../utils/hashMessage';\nimport { dedupePending } from './utils/dedupePending';\nimport type { Content } from '@generaltranslation/format/types';\nimport type {\n EntryMetadata,\n TranslateManyEntry,\n TranslationResult,\n} from 'generaltranslation/types';\n\nexport type TranslationBatchConfig = {\n maxConcurrentRequests?: number;\n maxBatchSize?: number;\n batchInterval?: number;\n};\n\n// See gt-next\nconst DEFAULT_BATCH_CONFIG: Required<TranslationBatchConfig> = {\n maxConcurrentRequests: 100,\n maxBatchSize: 25,\n batchInterval: 50,\n};\n\nfunction getPositiveValue(\n value: number | undefined,\n defaultValue: number,\n integer = false\n) {\n if (value === undefined || !Number.isFinite(value)) return defaultValue;\n const resolved = integer ? Math.trunc(value) : value;\n return resolved > 0 ? resolved : defaultValue;\n}\n\nfunction normalizeBatchConfig(\n batchConfig?: TranslationBatchConfig\n): Required<TranslationBatchConfig> {\n return {\n maxConcurrentRequests: getPositiveValue(\n batchConfig?.maxConcurrentRequests,\n DEFAULT_BATCH_CONFIG.maxConcurrentRequests,\n true\n ),\n maxBatchSize: getPositiveValue(\n batchConfig?.maxBatchSize,\n DEFAULT_BATCH_CONFIG.maxBatchSize,\n true\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 * Just being explicit about the purpose of this type\n */\nexport type Locale = string;\n\n/**\n * Called when a translation is resolved through a runtime cache miss.\n * Locale is handled by the I18nCache that owns this cache, so it is not\n * passed here.\n */\nexport type TranslationsCacheMissCallback<\n TranslationValue extends Translation,\n> = (hash: Hash, translation: TranslationValue) => void;\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 by the owning I18nCache. Use a callback function that has the\n * locale parameter embedded if you wish to use the locale code.\n */\nexport class TranslationsCache<TranslationValue extends Translation> {\n private cache: Record<Hash, TranslationValue>;\n private pendingTranslations = new Map<Hash, Promise<TranslationValue>>();\n private queue: Array<QueueEntry<TranslationValue>> = [];\n private batchTimer: ReturnType<typeof setTimeout> | null = null;\n private activeRequests = 0;\n private batchConfig: Required<TranslationBatchConfig>;\n private translateMany: TranslateMany;\n private onMiss?: TranslationsCacheMissCallback<TranslationValue>;\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 onMiss,\n batchConfig,\n }: {\n init: Record<Hash, TranslationValue>;\n translateMany: TranslateMany;\n batchConfig?: TranslationBatchConfig;\n onMiss?: TranslationsCacheMissCallback<TranslationValue>;\n }) {\n this.cache = structuredClone(init);\n this.translateMany = translateMany;\n this.batchConfig = normalizeBatchConfig(batchConfig);\n this.onMiss = onMiss;\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 cacheKey = this.getCacheKey(key);\n return this.cache[cacheKey] as T | undefined;\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 cacheKey = this.getCacheKey(key);\n const value = await dedupePending(this.pendingTranslations, cacheKey, () =>\n this.translate(key)\n );\n if (value != null) {\n this.onMiss?.(cacheKey, value);\n }\n return value as T;\n }\n\n public getInternalCache(): Record<Hash, TranslationValue> {\n return structuredClone(this.cache);\n }\n\n private getCacheKey(key: TranslationKey<TranslationValue>): Hash {\n return hashMessage(key.message, key.options);\n }\n\n private translate(\n key: TranslationKey<TranslationValue>\n ): Promise<TranslationValue> {\n const translationPromise = this.enqueueTranslation(key);\n\n if (this.queue.length >= this.batchConfig.maxBatchSize) {\n this.flushNow();\n } else {\n this.scheduleBatch();\n }\n\n return translationPromise;\n }\n\n public update(translations: Record<Hash, TranslationValue>): void {\n this.cache = { ...this.cache, ...translations };\n }\n\n private flushNow(): void {\n if (this.batchTimer) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n this.drainQueue();\n }\n\n private scheduleBatch(): void {\n if (this.batchTimer) return;\n this.batchTimer = setTimeout(() => {\n this.batchTimer = null;\n this.drainQueue();\n }, this.batchConfig.batchInterval);\n }\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\n if (this.queue.length > 0) {\n this.scheduleBatch();\n }\n }\n\n private enqueueTranslation(\n key: TranslationKey<TranslationValue>\n ): Promise<TranslationValue> {\n const hash = this.getCacheKey(key);\n const options = key.options;\n const metadataOptions = options as {\n $context?: string;\n $id?: string;\n $maxChars?: number;\n $requiresReview?: boolean;\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 // The hash is review-aware; the request metadata must carry the\n // same intent so the platform records it on anything it persists\n ...(metadataOptions.$requiresReview === true && {\n requiresReview: true,\n }),\n dataFormat: options.$format,\n },\n resolve: (value) => resolve(value as TranslationValue),\n reject,\n });\n });\n }\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 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 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.cache[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","export class DictionarySourceNotFoundError extends Error {\n constructor(id: string) {\n super(`I18nCache: source dictionary entry ${id} is not defined`);\n this.name = 'DictionarySourceNotFoundError';\n }\n}\n","import { DictionarySourceNotFoundError } from './DictionarySourceNotFoundError';\nimport {\n assertSafeDictionaryPathSegment,\n cloneDictionaryValue,\n getDictionaryEntry,\n isDictionaryValue,\n} from './dictionary-helpers';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryValue,\n} from './types/dictionary';\n\nexport type TranslateDictionaryEntry = (\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n) => Promise<DictionaryValue>;\n\n/**\n * Builds the dictionary value for a requested path by combining existing target\n * translations with runtime translations of any source leaves that are missing.\n */\nexport async function materializeDictionaryValue({\n key,\n sourceValue,\n targetValue,\n translateEntry,\n}: {\n key: DictionaryKey;\n sourceValue: DictionaryValue;\n targetValue: DictionaryValue | undefined;\n translateEntry: TranslateDictionaryEntry;\n}): Promise<DictionaryValue> {\n if (getDictionaryEntry(targetValue) !== undefined) {\n return cloneDictionaryValue(targetValue as DictionaryValue);\n }\n\n if (isDictionaryValue(targetValue) && !isDictionaryValue(sourceValue)) {\n return cloneDictionaryValue(targetValue);\n }\n\n const sourceEntry = getDictionaryEntry(sourceValue);\n if (sourceEntry !== undefined) {\n return await translateEntry(key, sourceEntry);\n }\n\n if (!isDictionaryValue(sourceValue)) {\n throw new DictionarySourceNotFoundError(key);\n }\n\n const targetDictionary = isDictionaryValue(targetValue) ? targetValue : {};\n const keys = new Set([\n ...Object.keys(sourceValue),\n ...Object.keys(targetDictionary),\n ]);\n const entries = await Promise.all(\n Array.from(keys).map(async (childKey) => {\n const childPath = key ? `${key}.${childKey}` : childKey;\n assertSafeDictionaryPathSegment(childKey, childPath);\n\n const childSource = sourceValue[childKey];\n if (childSource === undefined) {\n return [\n childKey,\n cloneDictionaryValue(targetDictionary[childKey]),\n ] as const;\n }\n\n return [\n childKey,\n await materializeDictionaryValue({\n key: childPath,\n sourceValue: childSource,\n targetValue: targetDictionary[childKey],\n translateEntry,\n }),\n ] as const;\n })\n );\n\n return Object.fromEntries(entries) as Dictionary;\n}\n","import {\n cloneDictionaryValue,\n getDictionaryEntry,\n getDictionaryValue,\n getDictionaryValueAtPath,\n isDictionaryValue,\n setDictionaryValueAtPath,\n} from './utils/dictionary-helpers';\nimport { materializeDictionaryValue } from './utils/materialize-dictionary';\nimport { dedupePending } from './utils/dedupePending';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryPath,\n DictionaryValue,\n} from './utils/types/dictionary';\nexport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryLeaf,\n DictionaryObject,\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 DictionaryLoader = (locale: string) => Promise<Dictionary>;\n\nfunction cloneDictionaryEntry(entry: DictionaryEntry): DictionaryEntry {\n return {\n entry: entry.entry,\n options: structuredClone(entry.options),\n };\n}\n\nexport class DictionaryCache {\n private cache: Dictionary;\n private pendingTranslations = new Map<\n DictionaryKey,\n Promise<DictionaryEntry>\n >();\n private pendingMaterializations = new Map<\n DictionaryKey,\n Promise<DictionaryValue>\n >();\n private runtimeTranslate: DictionaryRuntimeTranslate;\n\n constructor({\n init,\n runtimeTranslate,\n }: {\n init: Dictionary;\n runtimeTranslate: DictionaryRuntimeTranslate;\n }) {\n this.cache = structuredClone(init);\n this.runtimeTranslate = runtimeTranslate;\n }\n\n public getEntry(key: DictionaryKey): DictionaryEntry | undefined {\n const value = getDictionaryValueAtPath(this.cache, key);\n const entry = getDictionaryEntry(value);\n if (entry === undefined) {\n return undefined;\n }\n return cloneDictionaryEntry(entry);\n }\n\n public getValue(key: DictionaryKey): DictionaryValue | undefined {\n const value = getDictionaryValueAtPath(this.cache, key);\n if (value === undefined) {\n return undefined;\n }\n return cloneDictionaryValue(value);\n }\n\n public setValue(key: DictionaryKey, value: DictionaryValue): void {\n setDictionaryValueAtPath(this.cache, key, cloneDictionaryValue(value));\n }\n\n public getInternalCache(): Dictionary {\n return cloneDictionaryValue(this.cache);\n }\n\n public update(dictionary: Dictionary): void {\n mergeDictionary(this.cache, dictionary);\n }\n\n public async materializeValue(\n key: DictionaryKey,\n sourceValue: DictionaryValue,\n targetValue = getDictionaryValueAtPath(this.cache, key)\n ): Promise<DictionaryValue> {\n return dedupePending(this.pendingMaterializations, key, () =>\n materializeDictionaryValue({\n key,\n sourceValue,\n targetValue,\n translateEntry: async (entryKey, sourceEntry) =>\n getDictionaryValue(\n await this.materializeEntry(entryKey, sourceEntry)\n ),\n }).then((value) => {\n this.setValue(key, value);\n return value;\n })\n );\n }\n\n public async materializeEntry(\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n ): Promise<DictionaryEntry> {\n return cloneDictionaryEntry(\n await dedupePending(this.pendingTranslations, key, () =>\n this.runtimeTranslate(key, sourceEntry).then((value) => {\n setDictionaryValueAtPath(this.cache, key, value);\n const entry = getDictionaryEntry(value);\n if (entry === undefined) {\n // Never will happen\n throw new Error(\n 'DictionaryCache materializeEntry did not return a DictionaryEntry'\n );\n }\n return cloneDictionaryEntry(entry);\n })\n )\n );\n }\n}\n\nfunction mergeDictionary(target: Dictionary, source: Dictionary): void {\n for (const [key, value] of Object.entries(source)) {\n const targetValue = target[key];\n if (isDictionaryValue(targetValue) && isDictionaryValue(value)) {\n mergeDictionary(targetValue, value);\n } else {\n target[key] = cloneDictionaryValue(value);\n }\n }\n}\n","import logger from '../logs/logger';\nimport { I18nCacheConfig, I18nCacheConstructorParams } from './types';\nimport {\n createDiagnosticMessage,\n defaultRuntimeApiUrl,\n} from 'generaltranslation/internal';\nimport { Translation } from './translations-manager/utils/types/translation-data';\nimport { LookupOptions } from '../translation-functions/types/options';\nimport { SafeTranslationsLoader } from './translations-manager/translations-loaders/types';\nimport {\n createTranslateManyFactory,\n type CreateTranslateMany,\n} from './translations-manager/utils/createTranslateMany';\nimport { routeCreateTranslationLoader } from './translations-manager/translations-loaders/routeCreateTranslationLoader';\nimport { getLoadTranslationsType } from './utils/getLoadTranslationsType';\nimport { ResourceCache } from './translations-manager/ResourceCache';\nimport { TranslationsCache } from './translations-manager/TranslationsCache';\nimport type { Hash, Locale } from './translations-manager/TranslationsCache';\nimport { DictionaryCache } from './translations-manager/DictionaryCache';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryObject,\n} from './translations-manager/DictionaryCache';\nimport { resolveDictionaryLookupOptions } from './translations-manager/utils/dictionary-helpers';\nimport { DictionarySourceNotFoundError } from './translations-manager/utils/DictionarySourceNotFoundError';\nimport { getRuntimeEnvironment } from '../utils/getRuntimeEnvironment';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\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\ntype DictionaryResolver = (id: string) => DictionaryEntry | undefined;\n\ntype DictionaryObjResolver = (id: string) => DictionaryObject | undefined;\n\ntype DictionaryResolvers = {\n lookupDictionary: DictionaryResolver;\n lookupDictionaryObj: DictionaryObjResolver;\n};\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 * Callback function to prefetch entries during the async period\n */\ntype PrefetchEntriesType<TranslationType extends Translation> = (\n prefetchEntries: PrefetchEntry<TranslationType>[]\n) => Promise<void>;\n\n/**\n * Event fired when a runtime translation resolves a cache miss\n */\nexport type TranslationsCacheMissEvent<\n TranslationValue extends Translation = Translation,\n> = {\n locale: Locale;\n hash: Hash;\n translation: TranslationValue;\n};\n\n/**\n * Class for managing translation functionality\n * @template TranslationValue - The type of the translation that will be cached\n */\nclass I18nCache<TranslationValue extends Translation = Translation> {\n protected config: I18nCacheConfig;\n\n /**\n * Single dev hot-reload listener for runtime-translation cache misses.\n * Subclasses that add cache-miss behavior should wrap any existing listener\n * instead of overwriting it.\n */\n protected onTranslationsCacheMiss?: (\n event: TranslationsCacheMissEvent<TranslationValue>\n ) => void;\n\n /**\n * Locale-keyed caches for translations and dictionaries\n */\n private translations: ResourceCache<\n Locale,\n TranslationsCache<TranslationValue>\n >;\n private dictionaries: ResourceCache<Locale, DictionaryCache>;\n\n /**\n * Creates a locale-bound translateMany for runtime translation\n */\n private createTranslateMany: CreateTranslateMany;\n\n /**\n * Creates an instance of I18nCache.\n * TODO: resolve gtConfig from just file path\n * @param params - The parameters for the I18nCache constructor\n * @param params.config - The configuration for the I18nCache\n */\n constructor(params: I18nCacheConstructorParams) {\n // Validation\n validateCacheParams(params);\n\n this.config = {\n projectId: params.projectId,\n devApiKey: params.devApiKey,\n apiKey: params.apiKey,\n runtimeUrl: params.runtimeUrl,\n cacheExpiryTime: params.cacheExpiryTime,\n batchConfig: params.batchConfig,\n runtimeTranslation: params.runtimeTranslation,\n _versionId: params._versionId,\n };\n\n // Create cache miss handlers\n const loadTranslations = 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 },\n }) as SafeTranslationsLoader<TranslationValue>;\n const loadDictionary = params.loadDictionary ?? (() => Promise.resolve({}));\n this.createTranslateMany = createTranslateManyFactory(\n getI18nConfig().getGTClass(),\n this.config.runtimeTranslation?.timeout ?? DEFAULT_TRANSLATION_TIMEOUT,\n this.config.runtimeTranslation?.metadata ?? {}\n );\n\n // Setup locale-keyed caches\n const ttl = this.config.cacheExpiryTime;\n this.translations = new ResourceCache<\n Locale,\n TranslationsCache<TranslationValue>\n >({\n ttl,\n load: async (locale) =>\n this.createTranslationsCache(locale, await loadTranslations(locale)),\n });\n this.dictionaries = new ResourceCache<Locale, DictionaryCache>({\n ttl,\n load: async (locale) =>\n this.createDictionaryCache(locale, await loadDictionary(locale)),\n });\n\n // The default locale's source dictionary is provided synchronously and\n // never expires\n const defaultLocale = getI18nConfig().getDefaultLocale();\n this.dictionaries.set(\n defaultLocale,\n this.createDictionaryCache(defaultLocale, params.dictionary ?? {}),\n { expiresAt: -1 }\n );\n }\n\n // ========== Cache Factories ========== //\n\n private createTranslationsCache(\n locale: Locale,\n init: Record<Hash, TranslationValue>\n ): TranslationsCache<TranslationValue> {\n return new TranslationsCache<TranslationValue>({\n init,\n translateMany: this.createTranslateMany(locale),\n batchConfig: this.config.batchConfig,\n onMiss: (hash, translation) =>\n this.onTranslationsCacheMiss?.({ locale, hash, translation }),\n });\n }\n\n private createDictionaryCache(\n locale: Locale,\n init: Dictionary\n ): DictionaryCache {\n return new DictionaryCache({\n init,\n runtimeTranslate: (id, sourceEntry) =>\n this.translateDictionaryEntry(locale, id, sourceEntry),\n });\n }\n\n // ========== Getters and Setters ========== //\n\n /**\n * Get the version ID\n */\n getVersionId(): string | undefined {\n return this.config._versionId;\n }\n\n // ========== Translation Updates ========== //\n\n updateTranslations(\n translationsSnapshot: Record<Locale, Record<Hash, TranslationValue>>\n ): void {\n for (const locale in translationsSnapshot) {\n const txCache = this.translations.get(locale);\n if (txCache) {\n txCache.update(translationsSnapshot[locale]);\n } else {\n this.translations.set(\n locale,\n this.createTranslationsCache(locale, translationsSnapshot[locale])\n );\n }\n }\n }\n\n updateDictionaries(dictionarySnapshot: Record<Locale, Dictionary>): void {\n for (const locale in dictionarySnapshot) {\n const dictionaryCache = this.dictionaries.get(locale);\n if (dictionaryCache) {\n dictionaryCache.update(dictionarySnapshot[locale]);\n } else {\n this.dictionaries.set(\n locale,\n this.createDictionaryCache(locale, dictionarySnapshot[locale])\n );\n }\n }\n }\n\n // ========== Translation Resolution ========== //\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 return this.guardAsync({}, async () => {\n // Validate\n const translationLocale = this._resolveCacheLocale(locale);\n if (!translationLocale) {\n return {};\n }\n\n const txCache = await this.translations.getOrLoad(translationLocale);\n\n // Get the translations\n return txCache.getInternalCache();\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 return this.guardAsync({}, async () => {\n // Validate\n const dictionaryLocale = this._resolveCacheLocale(locale);\n if (!dictionaryLocale) {\n return this.getDefaultDictionaryCache()?.getInternalCache() ?? {};\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n\n return dictionaryCache.getInternalCache();\n });\n }\n\n /**\n * Look up a dictionary entry\n */\n lookupDictionary(locale: string, id: string): DictionaryEntry | undefined {\n return this.guard(undefined, () =>\n this.dictionaries\n .get(this.resolveDictionaryCacheLocale(locale))\n ?.getEntry(id)\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 return this.guard(undefined, () =>\n this.dictionaries\n .get(this.resolveDictionaryCacheLocale(locale))\n ?.getValue(id)\n );\n }\n\n async getLookupDictionary(locale: string): Promise<DictionaryResolvers> {\n return this.guardAsync<DictionaryResolvers>(\n {\n lookupDictionary: () => undefined,\n lookupDictionaryObj: () => undefined,\n },\n async () => {\n const asyncBoundaryLocale = this._resolveCacheLocale(locale);\n const asyncBoundaryDictionaryCache = asyncBoundaryLocale\n ? await this.dictionaries.getOrLoad(asyncBoundaryLocale)\n : this.getDefaultDictionaryCache();\n\n return {\n lookupDictionary: (id) => asyncBoundaryDictionaryCache?.getEntry(id),\n lookupDictionaryObj: (id) =>\n asyncBoundaryDictionaryCache?.getValue(id),\n };\n }\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 return this.guardAsync(undefined, async () => {\n const dictionaryLocale = this._resolveCacheLocale(locale);\n if (!dictionaryLocale) {\n return this.getSourceDictionaryEntry(id);\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n\n return (\n dictionaryCache.getEntry(id) ??\n (await dictionaryCache.materializeEntry(\n id,\n this.getSourceDictionaryEntry(id)\n ))\n );\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 return this.guardAsync(undefined, async () => {\n const dictionaryLocale = this._resolveCacheLocale(locale);\n\n if (!dictionaryLocale) {\n return this.getSourceDictionaryObject(id);\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n const targetObject = dictionaryCache.getValue(id);\n const sourceObject = this.getSourceDictionaryObject(id, {\n throwOnMissing: false,\n });\n if (sourceObject === undefined) {\n if (targetObject !== undefined) {\n return targetObject;\n }\n throw new DictionarySourceNotFoundError(id);\n }\n\n return await dictionaryCache.materializeValue(\n id,\n sourceObject,\n targetObject\n );\n });\n }\n\n private async translateDictionaryEntry(\n locale: Locale,\n id: string,\n sourceEntry: DictionaryEntry\n ): Promise<string> {\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 return translation;\n }\n\n private getSourceDictionaryEntry(id: string): DictionaryEntry {\n const sourceEntry = this.getDefaultDictionaryCache()?.getEntry(id);\n if (sourceEntry === undefined) {\n throw new DictionarySourceNotFoundError(id);\n }\n return sourceEntry;\n }\n\n private getSourceDictionaryObject(\n id: string,\n { throwOnMissing = true }: { throwOnMissing?: boolean } = {}\n ): DictionaryObject | undefined {\n const sourceObject = this.getDefaultDictionaryCache()?.getValue(id);\n if (sourceObject === undefined && throwOnMissing) {\n throw new DictionarySourceNotFoundError(id);\n }\n return sourceObject;\n }\n\n private getDefaultDictionaryCache() {\n return this.dictionaries.get(getI18nConfig().getDefaultLocale());\n }\n\n private resolveDictionaryCacheLocale(locale: string): Locale {\n return (\n this._resolveCacheLocale(locale) ?? getI18nConfig().getDefaultLocale()\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 return this.guard<T | undefined>(undefined, () => {\n // Validate\n const { translationLocale, options: lookupOptions } =\n this.resolveLookupParams(locale, options);\n\n // Early return if in default locale\n if (!translationLocale) return message;\n\n // Get the translation from the locale cache\n return this.translations\n .get(translationLocale)\n ?.get({ message, options: lookupOptions });\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 return this.guardAsync<T | undefined>(undefined, () =>\n this.lookupTranslationWithFallbackResolved(locale, message, options)\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 * @returns A lookup translation function\n *\n * @important prefetchEntries must all be the same locale\n */\n async getLookupTranslation(locale: string): Promise<\n TranslationResolver<TranslationValue> & {\n prefetchEntries?: PrefetchEntriesType<TranslationValue>;\n }\n > {\n return this.guardAsync<TranslationResolver<TranslationValue>>(\n (message) => message,\n async () => {\n // Locale used for the async load\n const asyncBoundaryLocale = this._resolveCacheLocale(locale);\n\n // Early return if i18n is disabled or default locale\n if (!asyncBoundaryLocale) {\n return (message) => message;\n }\n\n const asyncBoundaryTxCache =\n await this.translations.getOrLoad(asyncBoundaryLocale);\n\n // Prefetch any entries during async block (dev hot reload only)\n const prefetchEntries = async (\n prefetchEntries: {\n message: TranslationValue;\n options: LookupOptions;\n }[] = []\n ) => {\n if (\n process.env.NODE_ENV !== 'production' &&\n getI18nConfig().isDevHotReloadEnabled()\n ) {\n // Invariant: all prefetchEntries must be the same locale\n // TODO: investigate why we have made this an invariant, we may be able to drop this requirement\n const resolvedPrefetchEntries = resolvePrefetchEntriesByLocale(\n prefetchEntries,\n asyncBoundaryLocale,\n (entryLocale) =>\n this._resolveCacheLocale(entryLocale) ??\n this._resolveLocale(entryLocale)\n );\n if (resolvedPrefetchEntries.length !== prefetchEntries.length) {\n logger.warn(\n `I18nCache: getLookupTranslation(): prefetchEntries must all be the same locale, ignoring all entries that are not for ${asyncBoundaryLocale}`\n );\n }\n\n await Promise.allSettled(\n resolvedPrefetchEntries\n .filter((entry) => asyncBoundaryTxCache.get(entry) == null)\n .map((entry) => asyncBoundaryTxCache.miss(entry))\n );\n }\n };\n\n // Create translation resolver\n const lookupTranslation: TranslationResolver<TranslationValue> = (\n message,\n lookupOptions: LookupOptions = {} as LookupOptions\n ) =>\n this.guard(undefined, () => {\n const { translationLocale, options } = this.resolveLookupParams(\n lookupOptions.$locale ?? asyncBoundaryLocale,\n lookupOptions\n );\n\n // Default locale, return the message\n if (!translationLocale) return message;\n\n // Request locale overriden, to attempt a synchronous lookup if an alternate locale is requested\n const txCache =\n translationLocale === asyncBoundaryLocale\n ? asyncBoundaryTxCache\n : this.translations.get(translationLocale);\n\n // Get the translation\n return txCache?.get({ message, options });\n });\n\n Object.assign(lookupTranslation, { prefetchEntries });\n return lookupTranslation;\n }\n );\n }\n\n // ========== Error Handling ========== //\n\n /**\n * Run a lookup, routing errors through handleError (log in production,\n * throw in development) and returning the fallback once handled.\n */\n private guard<T>(fallback: T, fn: () => T): T {\n try {\n return fn();\n } catch (error) {\n this.handleError(error);\n return fallback;\n }\n }\n\n private async guardAsync<T>(fallback: T, fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n this.handleError(error);\n return fallback;\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 (getRuntimeEnvironment()) {\n case 'development':\n throw error;\n case 'production':\n default:\n logger.error('I18nCache: ' + error);\n break;\n }\n }\n\n private _resolveLocale(locale: string) {\n const i18nConfig = getI18nConfig();\n const resolvedLocale = i18nConfig.determineLocale(locale);\n if (!i18nConfig.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 const i18nConfig = getI18nConfig();\n if (i18nConfig.requiresTranslation(resolvedLocale)) {\n return resolvedLocale;\n }\n\n const aliasLocale = i18nConfig.resolveAliasLocale(\n i18nConfig.standardizeLocale(locale)\n );\n if (i18nConfig.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 ): LookupOptions {\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 const txCache = await this.translations.getOrLoad(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\nexport { I18nCache };\n\n// ===== Helper Functions ===== //\n\n/**\n * Validate constructor params: log warnings for suspicious configs and throw\n * on hard misconfigurations.\n */\nfunction validateCacheParams(params: I18nCacheConstructorParams): void {\n // Runtime translation against a custom API URL still needs GT credentials\n if (params.runtimeUrl && params.runtimeUrl !== defaultRuntimeApiUrl) {\n if (!params.projectId) {\n logger.warn(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'Runtime translation needs a projectId',\n fix: 'Add projectId to the I18nCache config or disable runtime translation',\n })\n );\n }\n if (!params.devApiKey && !params.apiKey) {\n logger.warn(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'Runtime translation needs devApiKey or apiKey',\n fix: 'Add credentials to the I18nCache config or disable runtime translation',\n })\n );\n }\n }\n\n // loadDictionary requires dictionary so the default locale always has a\n // source dictionary\n if (params.loadDictionary && !params.dictionary) {\n logger.error(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'loadDictionary needs a source dictionary',\n fix: 'Provide dictionary so the default locale has source content',\n })\n );\n throw new Error('Validation errors occurred');\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","import type { ReadonlyConditionStoreInterface as ReadonlyConditionStoreContract } from '../i18n-cache/types';\nimport type { LocaleCandidates } from '../i18n-config/I18nConfig';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\n\nexport type ReadonlyConditionStoreParams = {\n locale: LocaleCandidates;\n region?: string;\n enableI18n?: boolean;\n};\n\nexport class ReadonlyConditionStore implements ReadonlyConditionStoreContract {\n protected locale: string;\n protected region?: string;\n protected enableI18n: boolean;\n\n constructor({\n locale,\n region,\n enableI18n = true,\n }: ReadonlyConditionStoreParams) {\n this.locale = getI18nConfig().resolveSupportedLocale(locale);\n this.region = region;\n this.enableI18n = enableI18n;\n }\n\n getLocale = (): string => {\n return this.locale;\n };\n\n getRegion = (): string | undefined => {\n return this.region;\n };\n\n getEnableI18n = (): boolean => {\n return this.enableI18n;\n };\n\n // --- no-op methods --- //\n\n setLocale = (locale: LocaleCandidates): void => {};\n\n setRegion = (region: string | undefined): void => {};\n\n setEnableI18n = (enableI18n: boolean): void => {};\n}\n","import type { WritableConditionStoreInterface } from '../i18n-cache/types';\nimport type { LocaleCandidates } from '../i18n-config/I18nConfig';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\nimport {\n ReadonlyConditionStore,\n type ReadonlyConditionStoreParams,\n} from './ReadonlyConditionStore';\n\nexport type WritableConditionStoreParams = ReadonlyConditionStoreParams;\n\nexport class WritableConditionStore\n extends ReadonlyConditionStore\n implements WritableConditionStoreInterface\n{\n setLocale = (locale: LocaleCandidates): void => {\n this.locale = getI18nConfig().resolveSupportedLocale(locale);\n };\n\n setRegion = (region: string | undefined): void => {\n this.region = region;\n };\n\n setEnableI18n = (enableI18n: boolean): void => {\n this.enableI18n = enableI18n;\n };\n}\n","import type { LookupOptions } from '../translation-functions/types/options';\nimport type { Translation } from '../types';\nimport { hashMessage } from './hashMessage';\n\nexport type TranslateListenerLookup<T extends Translation = Translation> =\n | {\n locale: string;\n message: T;\n options: LookupOptions;\n }\n | {\n locale: string;\n hash: string;\n };\n\nexport type DictionaryListenerLookup = {\n locale: string;\n id: string;\n};\n\nexport function getTranslateListenerKey<T extends Translation>(\n lookup: TranslateListenerLookup<T>\n): string {\n const hash =\n 'hash' in lookup\n ? lookup.hash\n : hashMessage(lookup.message, lookup.options);\n return `${lookup.locale}:${hash}`;\n}\n\nexport function getDictionaryListenerKey({\n locale,\n id,\n}: DictionaryListenerLookup): string {\n return `${locale}:${id}`;\n}\n","type HeaderValue = string | string[] | null | undefined;\n\n/**\n * Parse an Accept-Language header into locale candidates by preference.\n */\nexport function parseAcceptLanguage(header: HeaderValue): string[] {\n const headerValues = Array.isArray(header) ? header : [header];\n\n return headerValues\n .flatMap((value) => value?.split(',') ?? [])\n .map((entry, index) => {\n const [locale = '', ...parameters] = entry\n .split(';')\n .map((value) => value.trim());\n const qualityParameter = parameters.find((parameter) =>\n parameter.toLowerCase().startsWith('q=')\n );\n const quality = Number(qualityParameter?.slice(2) ?? 1);\n return { locale, quality, index };\n })\n .filter(\n ({ locale, quality }) =>\n locale !== '' && locale !== '*' && quality > 0 && quality <= 1\n )\n .sort((a, b) => b.quality - a.quality || a.index - b.index)\n .map(({ locale }) => locale);\n}\n\n/**\n * Read and decode a value from a Cookie header or document.cookie string.\n */\nexport function getCookieValue(\n cookieHeader: string | null | undefined,\n cookieName: string\n): string | undefined {\n const prefix = `${cookieName}=`;\n const cookie = cookieHeader\n ?.split(';')\n .map((value) => value.trim())\n .find((value) => value.startsWith(prefix));\n if (!cookie) return undefined;\n\n const value = cookie.slice(prefix.length);\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"internal.mjs","names":[],"sources":["../src/translation-functions/internal/getGT.ts","../src/translation-functions/internal/getMessages.ts","../src/translation-functions/internal/renderDictionaryEntry.ts","../src/i18n-cache/translations-manager/utils/dictionary-helpers.ts","../src/translation-functions/internal/renderDictionaryObject.ts","../src/translation-functions/internal/getTranslations.ts","../src/translation-functions/internal/tx.ts","../src/translation-functions/internal/runtime-translate.ts","../src/i18n-cache/translations-manager/utils/createTranslateMany.ts","../src/i18n-cache/translations-manager/translations-loaders/createRemoteTranslationLoader.ts","../src/i18n-cache/translations-manager/translations-loaders/routeCreateTranslationLoader.ts","../src/i18n-cache/translations-manager/utils/constants.ts","../src/i18n-cache/translations-manager/utils/dedupePending.ts","../src/i18n-cache/translations-manager/ResourceCache.ts","../src/i18n-cache/translations-manager/TranslationsCache.ts","../src/i18n-cache/translations-manager/utils/DictionarySourceNotFoundError.ts","../src/i18n-cache/translations-manager/utils/materialize-dictionary.ts","../src/i18n-cache/translations-manager/DictionaryCache.ts","../src/i18n-cache/I18nCache.ts","../src/condition-store/ReadonlyConditionStore.ts","../src/condition-store/WritableConditionStore.ts","../src/utils/listenerKeys.ts","../src/utils/request.ts"],"sourcesContent":["import { getI18nCache } from '../../i18n-cache/singleton-operations';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { GTTranslationOptions, TranslationMetadata } from '../types/options';\nimport { GTFunctionType } from '../types/functions';\nimport { interpolateMessage } from '../utils/interpolation/interpolateMessage';\nimport { createLookupOptions } from './helpers';\nimport type { StringFormat } from '@generaltranslation/format/types';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\nexport type Message = TranslationMetadata & {\n message: string;\n};\n\n/**\n * Returns the gt function that registers a string at build time and resolves its translation at runtime.\n * @returns A promise of the gt function\n *\n * @example\n * const gt = await getGT();\n * const greeting = gt('Hello, world!');\n */\nexport async function getGT(_messages?: Message[]): Promise<GTFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getGTInternal({ locale, enableI18n }, _messages);\n}\n\n/**\n * Condition store agnostic getGT function\n */\nexport async function getGTInternal(\n {\n locale,\n enableI18n,\n }: {\n locale: string;\n enableI18n: boolean;\n },\n _messages?: Message[]\n): Promise<GTFunctionType> {\n // Get the translation resolver\n const i18nCache = getI18nCache();\n const sourceLocale = getI18nConfig().getDefaultLocale();\n // Statically gated so bundlers can drop dev hot-reload work from\n // production builds.\n const devHotReloadEnabled =\n process.env.NODE_ENV !== 'production' &&\n getI18nConfig().isDevHotReloadEnabled();\n const lookupTranslation = await i18nCache.getLookupTranslation(\n enableI18n ? locale : sourceLocale\n );\n\n // dev hot reload translate compiler injected lookups\n if (devHotReloadEnabled && lookupTranslation.prefetchEntries) {\n await lookupTranslation.prefetchEntries(\n _messages?.map(({ message, ...options }) => ({\n message,\n options: {\n $format: 'ICU',\n ...options,\n },\n })) ?? []\n );\n }\n\n /**\n * Registers a message at build time and resolves its translation at runtime.\n * @param {string} message - The message to translate\n * @param {GTTranslationOptions} options - The options for the translation\n * @returns The translated message\n *\n * @example\n * // Simple translation without interpolation\n * const gt = await getGT();\n * const greeting = gt('Hello, world!');\n *\n * @example\n * // Translation with interpolation\n * const gt = await getGT();\n * const welcome = gt('Hello, {name}!', { name: 'Alice' });\n */\n const gt: GTFunctionType = (\n message: string,\n options: GTTranslationOptions = {}\n ) => {\n const targetLocale = enableI18n\n ? (options.$locale ?? locale)\n : getI18nConfig().getDefaultLocale();\n const lookupOptions = createLookupOptions<StringFormat>(\n targetLocale,\n options,\n 'ICU'\n );\n\n // Lookup translation\n const translation = lookupTranslation(message, lookupOptions);\n\n // Dev hot reload (fire and forget, will be available in a later lookup)\n if (devHotReloadEnabled && translation == null) {\n void i18nCache\n .lookupTranslationWithFallback(\n lookupOptions.$locale,\n message,\n lookupOptions\n )\n .catch(() => {});\n }\n\n // Format result\n return interpolateMessage({\n source: message,\n target: translation,\n options: lookupOptions,\n sourceLocale,\n });\n };\n\n return gt;\n}\n","import { GTTranslationOptions } from '../types/options';\nimport { decodeOptions } from '../msg/decodeOptions';\nimport { isEncodedTranslationOptions } from '../utils/isEncodedTranslationOptions';\nimport { getGTInternal } from './getGT';\nimport { MFunctionType } from '../types/functions';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\n/**\n * Returns the m function that resolves a registered message to its translation.\n * @returns A promise of the m function\n *\n * @example\n * // Registration\n * const registeredMessage = msg('Hello, world!');\n *\n * // Resolution\n * const m = await getMessages();\n * const greeting = m(registeredMessage);\n */\nexport async function getMessages(): Promise<MFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getMessagesInternal({ locale, enableI18n });\n}\n\n/**\n * Condition store agnostic getMessages function\n */\nexport async function getMessagesInternal({\n locale,\n enableI18n,\n}: {\n locale: string;\n enableI18n: boolean;\n}): Promise<MFunctionType> {\n // Get the gt function\n const gt = await getGTInternal({ locale, enableI18n });\n\n /**\n * Resolves a registered message to its translation.\n * @param {string | null | undefined} encodedMsg - The encoded message to decode and interpolate.\n * @param {GTTranslationOptions} options - The options to interpolate.\n * @returns - The decoded and interpolated message.\n *\n * @example\n * // Simple message without interpolation\n * const m = await getMessages();\n * const greeting = m(msg('Hello, world!'));\n *\n * @example\n * // Message with interpolation\n * const m = await getMessages();\n * const welcome = m(msg('Welcome, {user}!'), { user: 'Alice' });\n */\n const m: MFunctionType = <T extends string | null | undefined>(\n encodedMsg: T,\n options: GTTranslationOptions = {}\n ): T extends string ? string : T => {\n // Return if the encoded message is null or undefined\n if (encodedMsg == null) return encodedMsg as T extends string ? string : T;\n\n // Get any encoded options\n const decodedOptions = decodeOptions(encodedMsg) ?? {};\n\n // Return early if string already interpolated eg: mFallback(msg('Hello, {name}!', { name: 'Brian' }))\n if (isEncodedTranslationOptions(decodedOptions)) {\n return gt(decodedOptions.$_source, decodedOptions) as T extends string\n ? string\n : T;\n }\n\n // Use gt to interpolate\n // Separate from decoded options to match behavior in @gt/react-core\n return gt(encodedMsg, options) as T extends string ? string : T;\n };\n\n return m;\n}\n","import { createLookupOptions } from './helpers';\nimport { extractVariables } from '../../utils/extractVariables';\nimport { interpolateMessage } from '../utils/interpolation/interpolateMessage';\nimport type {\n DictionaryLookupOptions,\n TranslationVariables,\n} from '../types/options';\nimport type { DictionaryEntry } from '../../i18n-cache/translations-manager/DictionaryCache';\nimport type { StringFormat } from '@generaltranslation/format/types';\n\nexport function renderDictionaryEntry({\n sourceLocale,\n targetLocale,\n sourceEntry,\n target,\n dictionaryOptions,\n options = {},\n}: {\n sourceLocale: string;\n targetLocale: string;\n sourceEntry: DictionaryEntry;\n target: string | undefined;\n dictionaryOptions: DictionaryLookupOptions;\n options?: TranslationVariables;\n}): string {\n const lookupOptions = createLookupOptions<StringFormat>(\n targetLocale,\n {\n ...dictionaryOptions,\n ...extractVariables(options),\n },\n dictionaryOptions.$format\n );\n\n return interpolateMessage({\n source: sourceEntry.entry,\n target,\n options: lookupOptions,\n sourceLocale,\n });\n}\n","import type {\n Dictionary,\n DictionaryEntry,\n DictionaryLeaf,\n DictionaryPath,\n DictionaryValue,\n} from './types/dictionary';\nimport type {\n DictionaryEntryOptions,\n DictionaryLookupOptions,\n} from '../../../translation-functions/types/options';\n\nfunction getDictionaryPath(id: DictionaryPath): string[] {\n const path = id ? id.split('.') : [];\n for (const segment of path) {\n assertSafeDictionaryPathSegment(segment, id);\n }\n return path;\n}\n\nexport function assertSafeDictionaryPathSegment(\n segment: string,\n path: DictionaryPath\n): void {\n if (\n segment === '__proto__' ||\n segment === 'constructor' ||\n segment === 'prototype'\n ) {\n throw new Error(`Dictionary path \"${path}\" contains an unsafe segment`);\n }\n}\n\nexport function isDictionaryValue(value: unknown): value is Dictionary {\n return typeof value === 'object' && value != null && !Array.isArray(value);\n}\n\nexport function cloneDictionaryValue<Value extends DictionaryValue | undefined>(\n value: Value\n): Value {\n if (value === undefined || typeof value === 'string') {\n return value;\n }\n return structuredClone(value) as Value;\n}\n\nexport function getDictionaryValueAtPath(\n dictionary: Dictionary,\n path: DictionaryPath\n): DictionaryValue | undefined {\n let current: DictionaryValue = dictionary;\n\n for (const segment of getDictionaryPath(path)) {\n if (!isDictionaryValue(current)) {\n return undefined;\n }\n current = current[segment];\n }\n\n return current;\n}\n\nexport function setDictionaryValueAtPath(\n dictionary: Dictionary,\n path: DictionaryPath,\n value: DictionaryValue\n): void {\n const segments = getDictionaryPath(path);\n if (isDictionaryValue(value)) {\n assertSafeDictionaryObject(value, path);\n }\n\n if (segments.length === 0) {\n if (isDictionaryValue(value)) {\n replaceDictionary(dictionary, value);\n }\n return;\n }\n\n let current = dictionary;\n for (const segment of segments.slice(0, -1)) {\n const next = current[segment];\n if (!isDictionaryValue(next)) {\n current[segment] = {} as Dictionary;\n }\n current = current[segment] as Dictionary;\n }\n\n const leafSegment = segments[segments.length - 1];\n current[leafSegment] = 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 };\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 && isDictionaryLeafOptions(value[1]);\n}\n\nfunction isDictionaryLeafOptions(\n value: unknown\n): value is DictionaryEntryOptions {\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 || typeof options.$maxChars === 'number')\n );\n}\n\nfunction isStringFormat(\n value: unknown\n): value is DictionaryLookupOptions['$format'] {\n return value === 'ICU' || value === 'I18NEXT' || value === 'STRING';\n}\n\nfunction replaceDictionary(target: Dictionary, source: Dictionary): void {\n for (const key of Object.keys(target)) {\n delete target[key];\n }\n for (const key of Object.keys(source)) {\n target[key] = source[key];\n }\n}\n\nfunction assertSafeDictionaryObject(\n dictionary: Dictionary,\n parentPath = ''\n): void {\n for (const [key, value] of Object.entries(dictionary)) {\n const path = parentPath ? `${parentPath}.${key}` : key;\n assertSafeDictionaryPathSegment(key, path);\n if (isDictionaryValue(value)) {\n assertSafeDictionaryObject(value, path);\n }\n }\n}\n","import {\n getDictionaryEntry,\n isDictionaryValue,\n resolveDictionaryLookupOptions,\n} from '../../i18n-cache/translations-manager/utils/dictionary-helpers';\nimport type { DictionaryObjectTranslation } from '../types/functions';\nimport type { DictionaryLookupOptions } from '../types/options';\nimport type {\n DictionaryEntry,\n DictionaryValue,\n} from '../../i18n-cache/translations-manager/DictionaryCache';\n\nexport function renderDictionaryObject({\n sourceObject,\n targetObject,\n translate,\n}: {\n sourceObject: DictionaryValue | undefined;\n targetObject: DictionaryValue | undefined;\n translate?: (\n sourceEntry: DictionaryEntry,\n dictionaryOptions: DictionaryLookupOptions\n ) => string | undefined;\n}): DictionaryObjectTranslation {\n const targetEntry = getDictionaryEntry(targetObject);\n if (targetEntry !== undefined) {\n return targetEntry.entry;\n }\n\n if (isDictionaryValue(targetObject)) {\n if (!isDictionaryValue(sourceObject)) {\n return renderDictionaryObject({\n sourceObject: targetObject,\n targetObject: undefined,\n translate,\n });\n }\n\n return renderDictionaryObjectChildren({\n sourceObject,\n targetObject,\n translate,\n });\n }\n\n const sourceEntry = getDictionaryEntry(sourceObject);\n if (sourceEntry !== undefined) {\n const dictionaryOptions = resolveDictionaryLookupOptions(\n sourceEntry.options\n );\n return translate?.(sourceEntry, dictionaryOptions) ?? sourceEntry.entry;\n }\n\n if (isDictionaryValue(sourceObject)) {\n return renderDictionaryObjectChildren({\n sourceObject,\n targetObject: undefined,\n translate,\n });\n }\n\n throw new Error('Dictionary object cannot be rendered');\n}\n\nfunction renderDictionaryObjectChildren({\n sourceObject,\n targetObject,\n translate,\n}: {\n sourceObject: DictionaryValue;\n targetObject: DictionaryValue | undefined;\n translate?: (\n sourceEntry: DictionaryEntry,\n dictionaryOptions: DictionaryLookupOptions\n ) => string | undefined;\n}): DictionaryObjectTranslation {\n if (!isDictionaryValue(sourceObject)) {\n return renderDictionaryObject({ sourceObject, targetObject, translate });\n }\n\n const result: Record<string, DictionaryObjectTranslation> = {};\n const keys = new Set([\n ...Object.keys(sourceObject),\n ...(isDictionaryValue(targetObject) ? Object.keys(targetObject) : []),\n ]);\n\n for (const key of Array.from(keys)) {\n const renderedChild = renderDictionaryObject({\n sourceObject: sourceObject[key],\n targetObject: isDictionaryValue(targetObject)\n ? targetObject[key]\n : undefined,\n translate,\n });\n if (renderedChild !== undefined) {\n result[key] = renderedChild;\n }\n }\n\n return result;\n}\n","import { getI18nCache } from '../../i18n-cache/singleton-operations';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { TranslationVariables } from '../types/options';\nimport { TFunctionType } from '../types/functions';\nimport { renderDictionaryEntry } from './renderDictionaryEntry';\nimport { renderDictionaryObject } from './renderDictionaryObject';\nimport { resolveDictionaryLookupOptions } from '../../i18n-cache/translations-manager/utils/dictionary-helpers';\nimport type { DictionaryObjectTranslation } from '../types/functions';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\n/**\n * Returns the t function that translates a dictionary entry based on its id and options.\n * @returns A promise of the t function\n * @important Must be used inside of a request context\n *\n * @example\n * const t = await getTranslations();\n * const title = await t('page.title');\n */\nexport async function getTranslations(rootId?: string): Promise<TFunctionType> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n return getTranslationsInternal({ locale, enableI18n, rootId });\n}\n\n/**\n * Condition store agnostic getTranslations function\n */\nexport async function getTranslationsInternal({\n locale,\n enableI18n,\n rootId,\n}: {\n locale: string;\n enableI18n: boolean;\n rootId?: string;\n}): Promise<TFunctionType> {\n const i18nCache = getI18nCache();\n const sourceLocale = getI18nConfig().getDefaultLocale();\n const targetLocale = enableI18n ? locale : sourceLocale;\n const [sourceDictionary, targetDictionary, lookupTranslation] =\n await Promise.all([\n i18nCache.getLookupDictionary(sourceLocale),\n i18nCache.getLookupDictionary(targetLocale),\n i18nCache.getLookupTranslation(targetLocale),\n ]);\n const {\n lookupDictionary: lookupSourceDictionary,\n lookupDictionaryObj: lookupSourceDictionaryObj,\n } = sourceDictionary;\n const {\n lookupDictionary: lookupTargetDictionary,\n lookupDictionaryObj: lookupTargetDictionaryObj,\n } = targetDictionary;\n\n /**\n * Dictionary resolution\n * @param {string} id - The id of the translation to translate.\n * @param {TranslationVariables} options - The variables for interpolation.\n * @returns {string} The translated message.\n *\n * @example\n * // Simple dictionary lookup without interpolation\n * const t = await getTranslations();\n * const title = t('page.title');\n *\n * @example\n * // Dictionary lookup with interpolation\n * const t = await getTranslations();\n * const greeting = t('user.greeting', { name: 'Bob' });\n */\n const t = ((id: string, options: TranslationVariables = {}): string => {\n id = getId(rootId, id);\n const sourceEntry = lookupSourceDictionary(id);\n if (sourceEntry === undefined) {\n throw new Error(`Dictionary entry ${id} cannot be found`);\n }\n const targetEntry = lookupTargetDictionary(id);\n const dictionaryOptions = resolveDictionaryLookupOptions(\n sourceEntry.options\n );\n const target =\n targetEntry?.entry ??\n lookupTranslation(sourceEntry.entry, dictionaryOptions);\n return renderDictionaryEntry({\n sourceLocale,\n targetLocale: targetLocale,\n sourceEntry,\n target,\n dictionaryOptions,\n options,\n });\n }) as TFunctionType;\n\n /**\n * Returns a subtree of the dictionary object translation based on its id.\n * @param {string} id - The id of the translation to translate.\n * @returns The translated object.\n *\n * @example\n * const t = await getTranslations();\n * const greetings = t.obj('greetings');\n * console.log(greetings);\n * // { greeting1: 'Hello', greeting2: 'Hi' }\n */\n t.obj = (id: string): DictionaryObjectTranslation => {\n id = getId(rootId, id);\n const sourceObject = lookupSourceDictionaryObj(id);\n if (sourceObject === undefined) {\n throw new Error(`Dictionary entry ${id} cannot be found`);\n }\n const targetObject = lookupTargetDictionaryObj(id);\n return renderDictionaryObject({\n sourceObject,\n targetObject,\n translate: (sourceEntry, dictionaryOptions) =>\n lookupTranslation(sourceEntry.entry, dictionaryOptions),\n });\n };\n\n return t;\n}\n\nfunction getId(prefix: string | undefined, suffix: string): string {\n return prefix ? `${prefix}.${suffix}` : suffix;\n}\n","import { RuntimeTranslationOptions } from '../types/options';\nimport type { StringFormat } from '@generaltranslation/format/types';\nimport {\n prefetchStringContentWithRuntimeFallback,\n resolveStringContentWithRuntimeFallback,\n} from './helpers';\nimport { getI18nConfig } from '../../i18n-config/singleton-operations';\nimport { getWritableConditionStore } from '../../condition-store/singleton-operations';\n\ntype RuntimeTranslationOptionsWithFormat = Omit<\n RuntimeTranslationOptions,\n '$format'\n> & {\n $format?: StringFormat;\n};\n\n/**\n * Translates a message at runtime.\n * @param {string} message - The message to translate.\n * @param {RuntimeTranslationOptions} options - The options for the translation.\n * @returns {Promise<string>} The translated message.\n *\n * @example\n * // Simple runtime translation without interpolation\n * const status = await tx('Processing complete', { $locale: 'es-MX' });\n *\n * @example\n * // Runtime translation with interpolation\n * const progress = await tx(`Processing ${status}`, { $locale: 'es-MX' });\n */\nexport async function tx(\n content: string,\n options: RuntimeTranslationOptionsWithFormat = {}\n): Promise<string> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n\n return txInternal({ locale, enableI18n, content, options });\n}\n\n/**\n * Condition store agnostic tx function\n */\nexport async function txInternal({\n locale,\n enableI18n,\n content,\n options,\n}: {\n locale: string;\n enableI18n: boolean;\n content: string;\n options: RuntimeTranslationOptionsWithFormat;\n}): Promise<string> {\n const targetLocale = getTargetLocale({ locale, enableI18n, options });\n return resolveStringContentWithRuntimeFallback(targetLocale, content, {\n $format: 'STRING',\n ...options,\n });\n}\n\n/**\n * Registers a message for runtime translation without interpolating the\n * result. For compiler-injected prefetch calls: their return value is\n * discarded and variable values only exist at the render-time call site, so\n * interpolating here would fail for any message with placeholders.\n */\nexport async function txPrefetch(\n content: string,\n options: RuntimeTranslationOptionsWithFormat = {}\n): Promise<void> {\n const conditionStore = getWritableConditionStore();\n const locale = conditionStore.getLocale();\n const enableI18n = conditionStore.getEnableI18n();\n const targetLocale = getTargetLocale({ locale, enableI18n, options });\n await prefetchStringContentWithRuntimeFallback(targetLocale, content, {\n $format: 'STRING',\n ...options,\n });\n}\n\nfunction getTargetLocale({\n locale,\n enableI18n,\n options,\n}: {\n locale: string;\n enableI18n: boolean;\n options: RuntimeTranslationOptionsWithFormat;\n}): string {\n return enableI18n\n ? typeof options.$locale === 'string'\n ? options.$locale\n : locale\n : getI18nConfig().getDefaultLocale();\n}\n","import type {\n JsxChildren,\n StringFormat,\n} from '@generaltranslation/format/types';\nimport { getLocale } from '../../helpers/locale';\nimport type {\n JsxTranslationOptions,\n RuntimeTranslationOptions,\n} from '../types/options';\nimport { resolveJsxWithRuntimeFallback } from './helpers';\nimport { txPrefetch } from './tx';\n\ntype RuntimeStringTranslationOptions = Omit<\n RuntimeTranslationOptions,\n '$format'\n> & {\n $format?: StringFormat;\n};\n\ntype RuntimeJsxTranslationOptions = JsxTranslationOptions & {\n $locale?: string;\n};\n\nexport const GtInternalRuntimeTranslateString = (\n content: string,\n options: RuntimeStringTranslationOptions = {}\n) => {\n // Prefetch/registration only — the compiler-injected call discards the\n // result, and variable values are unavailable here, so the translation\n // must not be interpolated.\n return txPrefetch(content, { $format: 'ICU', ...options });\n};\n\nexport const GtInternalRuntimeTranslateJsx = (\n content: JsxChildren,\n options: RuntimeJsxTranslationOptions = {}\n) => {\n const locale = options.$locale ?? getLocale();\n return resolveJsxWithRuntimeFallback(locale, content, {\n $format: 'JSX',\n ...options,\n });\n};\n","import type { RuntimeTranslateManyOptions } from 'generaltranslation/internal';\nimport type { Locale } from '../TranslationsCache';\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';\nimport { LoadTranslationsType } from '../../utils/getLoadTranslationsType';\nimport logger from '../../../logs/logger';\nimport { createRemoteTranslationLoader } from './createRemoteTranslationLoader';\nimport { getI18nConfig } from '../../../i18n-config/singleton-operations';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\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 };\n loadTranslations?: TranslationsLoader;\n}): TranslationsLoader {\n const { cacheUrl, projectId, _versionId, _branchId } =\n remoteTranslationLoaderParams;\n\n // Warnings are deferred to loader invocation: translations may be provided\n // externally via updateTranslations() (eg streamed from a server), in which\n // case the loader is never invoked and the warnings do not apply\n switch (type) {\n case LoadTranslationsType.REMOTE:\n case LoadTranslationsType.GT_REMOTE:\n // Only reachable for REMOTE: GT_REMOTE requires a projectId\n if (!projectId) {\n return createWarnOnceTranslationLoader(\n createDiagnosticMessage({\n whatHappened:\n 'Loading translations from a remote store needs a projectId. No translations will be loaded.',\n fix: 'Add projectId to the I18nCache config, or set cacheUrl to null to disable translation loading',\n })\n );\n }\n return createRemoteTranslationLoader({\n cacheUrl: cacheUrl as string | undefined,\n projectId,\n _versionId,\n _branchId,\n customMapping: getI18nConfig().getCustomMapping(),\n });\n case LoadTranslationsType.CUSTOM:\n return loadTranslations!;\n case LoadTranslationsType.DISABLED:\n // cacheUrl: null is an explicit opt-out of translation loading\n if (cacheUrl === null) {\n return async () => ({});\n }\n return createWarnOnceTranslationLoader(\n createDiagnosticMessage({\n whatHappened:\n 'No translation loader found. No translations will be loaded.',\n fix: 'Add projectId to the I18nCache config (to load from the GT remote store), provide a loadTranslations function, or set cacheUrl to null to disable translation loading',\n })\n );\n }\n}\n\n/**\n * Loads no translations and logs a warning once on first invocation\n */\nfunction createWarnOnceTranslationLoader(warning: string): TranslationsLoader {\n let warned = false;\n return async (_locale: string) => {\n if (!warned) {\n warned = true;\n logger.warn('I18nCache: ' + warning);\n }\n return {};\n };\n}\n","/**\n * Default cache expiry time in milliseconds\n */\nexport const DEFAULT_CACHE_EXPIRY_TIME = 60_000; // 60 sec\n","/**\n * Share one in-flight promise per key: concurrent callers for the same key\n * await the same promise, and the pending entry is cleared once it settles.\n */\nexport async function dedupePending<Key, Value>(\n pending: Map<Key, Promise<Value>>,\n key: Key,\n create: () => Promise<Value>\n): Promise<Value> {\n let promise = pending.get(key);\n if (!promise) {\n promise = create();\n pending.set(key, promise);\n }\n\n try {\n return await promise;\n } finally {\n pending.delete(key);\n }\n}\n","import { DEFAULT_CACHE_EXPIRY_TIME } from './utils/constants';\nimport { dedupePending } from './utils/dedupePending';\n\nexport type ResourceCacheEntry<Value> = {\n expiresAt: number;\n value: Value;\n};\n\nexport class ResourceCache<Key extends string, Value> {\n private cache = new Map<Key, ResourceCacheEntry<Value>>();\n private pendingLoads = new Map<Key, Promise<Value>>();\n private loadResource: (key: Key) => Promise<Value>;\n private ttl: number;\n\n constructor({\n load,\n ttl,\n }: {\n load: (key: Key) => Promise<Value>;\n ttl?: number | null;\n }) {\n this.loadResource = load;\n this.ttl = ttl === null ? -1 : (ttl ?? DEFAULT_CACHE_EXPIRY_TIME);\n }\n\n public get(key: Key): Value | undefined {\n const entry = this.cache.get(key);\n if (!entry || this.isExpired(entry)) {\n return undefined;\n }\n\n return entry.value;\n }\n\n public set(\n key: Key,\n value: Value,\n { expiresAt = this.getExpiresAt() }: { expiresAt?: number } = {}\n ): void {\n this.cache.set(key, {\n expiresAt,\n value,\n });\n }\n\n public async getOrLoad(key: Key): Promise<Value> {\n return this.get(key) ?? (await this.load(key));\n }\n\n private load(key: Key): Promise<Value> {\n return dedupePending(this.pendingLoads, key, () =>\n // The entry expiry is computed when the load resolves, not when it starts\n this.loadResource(key).then((value) => {\n this.set(key, value);\n return value;\n })\n );\n }\n\n private getExpiresAt(): number {\n // Avoid Date.now() for Next.js Cache Components; Next handles caching.\n return this.ttl <= 0 ? this.ttl : Date.now() + this.ttl;\n }\n\n private isExpired(entry: ResourceCacheEntry<Value>): boolean {\n // Avoid Date.now() for Next.js Cache Components; Next handles caching.\n if (entry.expiresAt === 0) return true;\n return entry.expiresAt > 0 && entry.expiresAt < Date.now();\n }\n}\n","import { LookupOptions } from '../../translation-functions/types/options';\nimport { Translation } from './utils/types/translation-data';\nimport { hashMessage } from '../../utils/hashMessage';\nimport { dedupePending } from './utils/dedupePending';\nimport type { Content } from '@generaltranslation/format/types';\nimport type {\n EntryMetadata,\n TranslateManyEntry,\n TranslationResult,\n} from 'generaltranslation/types';\n\nexport type TranslationBatchConfig = {\n maxConcurrentRequests?: number;\n maxBatchSize?: number;\n batchInterval?: number;\n};\n\n// See gt-next\nconst DEFAULT_BATCH_CONFIG: Required<TranslationBatchConfig> = {\n maxConcurrentRequests: 100,\n maxBatchSize: 25,\n batchInterval: 50,\n};\n\nfunction getPositiveValue(\n value: number | undefined,\n defaultValue: number,\n integer = false\n) {\n if (value === undefined || !Number.isFinite(value)) return defaultValue;\n const resolved = integer ? Math.trunc(value) : value;\n return resolved > 0 ? resolved : defaultValue;\n}\n\nfunction normalizeBatchConfig(\n batchConfig?: TranslationBatchConfig\n): Required<TranslationBatchConfig> {\n return {\n maxConcurrentRequests: getPositiveValue(\n batchConfig?.maxConcurrentRequests,\n DEFAULT_BATCH_CONFIG.maxConcurrentRequests,\n true\n ),\n maxBatchSize: getPositiveValue(\n batchConfig?.maxBatchSize,\n DEFAULT_BATCH_CONFIG.maxBatchSize,\n true\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 * Just being explicit about the purpose of this type\n */\nexport type Locale = string;\n\n/**\n * Called when a translation is resolved through a runtime cache miss.\n * Locale is handled by the I18nCache that owns this cache, so it is not\n * passed here.\n */\nexport type TranslationsCacheMissCallback<\n TranslationValue extends Translation,\n> = (hash: Hash, translation: TranslationValue) => void;\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 by the owning I18nCache. Use a callback function that has the\n * locale parameter embedded if you wish to use the locale code.\n */\nexport class TranslationsCache<TranslationValue extends Translation> {\n private cache: Record<Hash, TranslationValue>;\n private pendingTranslations = new Map<Hash, Promise<TranslationValue>>();\n private queue: Array<QueueEntry<TranslationValue>> = [];\n private batchTimer: ReturnType<typeof setTimeout> | null = null;\n private activeRequests = 0;\n private batchConfig: Required<TranslationBatchConfig>;\n private translateMany: TranslateMany;\n private onMiss?: TranslationsCacheMissCallback<TranslationValue>;\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 onMiss,\n batchConfig,\n }: {\n init: Record<Hash, TranslationValue>;\n translateMany: TranslateMany;\n batchConfig?: TranslationBatchConfig;\n onMiss?: TranslationsCacheMissCallback<TranslationValue>;\n }) {\n this.cache = structuredClone(init);\n this.translateMany = translateMany;\n this.batchConfig = normalizeBatchConfig(batchConfig);\n this.onMiss = onMiss;\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 cacheKey = this.getCacheKey(key);\n return this.cache[cacheKey] as T | undefined;\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 cacheKey = this.getCacheKey(key);\n const value = await dedupePending(this.pendingTranslations, cacheKey, () =>\n this.translate(key)\n );\n if (value != null) {\n this.onMiss?.(cacheKey, value);\n }\n return value as T;\n }\n\n public getInternalCache(): Record<Hash, TranslationValue> {\n return structuredClone(this.cache);\n }\n\n private getCacheKey(key: TranslationKey<TranslationValue>): Hash {\n return hashMessage(key.message, key.options);\n }\n\n private translate(\n key: TranslationKey<TranslationValue>\n ): Promise<TranslationValue> {\n const translationPromise = this.enqueueTranslation(key);\n\n if (this.queue.length >= this.batchConfig.maxBatchSize) {\n this.flushNow();\n } else {\n this.scheduleBatch();\n }\n\n return translationPromise;\n }\n\n public update(translations: Record<Hash, TranslationValue>): void {\n this.cache = { ...this.cache, ...translations };\n }\n\n private flushNow(): void {\n if (this.batchTimer) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n this.drainQueue();\n }\n\n private scheduleBatch(): void {\n if (this.batchTimer) return;\n this.batchTimer = setTimeout(() => {\n this.batchTimer = null;\n this.drainQueue();\n }, this.batchConfig.batchInterval);\n }\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\n if (this.queue.length > 0) {\n this.scheduleBatch();\n }\n }\n\n private enqueueTranslation(\n key: TranslationKey<TranslationValue>\n ): Promise<TranslationValue> {\n const hash = this.getCacheKey(key);\n const options = key.options;\n const metadataOptions = options as {\n $context?: string;\n $id?: string;\n $maxChars?: number;\n $requiresReview?: boolean;\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 // The hash is review-aware; the request metadata must carry the\n // same intent so the platform records it on anything it persists\n ...(metadataOptions.$requiresReview === true && {\n requiresReview: true,\n }),\n dataFormat: options.$format,\n },\n resolve: (value) => resolve(value as TranslationValue),\n reject,\n });\n });\n }\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 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 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.cache[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","export class DictionarySourceNotFoundError extends Error {\n constructor(id: string) {\n super(`I18nCache: source dictionary entry ${id} is not defined`);\n this.name = 'DictionarySourceNotFoundError';\n }\n}\n","import { DictionarySourceNotFoundError } from './DictionarySourceNotFoundError';\nimport {\n assertSafeDictionaryPathSegment,\n cloneDictionaryValue,\n getDictionaryEntry,\n isDictionaryValue,\n} from './dictionary-helpers';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryValue,\n} from './types/dictionary';\n\nexport type TranslateDictionaryEntry = (\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n) => Promise<DictionaryValue>;\n\n/**\n * Builds the dictionary value for a requested path by combining existing target\n * translations with runtime translations of any source leaves that are missing.\n */\nexport async function materializeDictionaryValue({\n key,\n sourceValue,\n targetValue,\n translateEntry,\n}: {\n key: DictionaryKey;\n sourceValue: DictionaryValue;\n targetValue: DictionaryValue | undefined;\n translateEntry: TranslateDictionaryEntry;\n}): Promise<DictionaryValue> {\n if (getDictionaryEntry(targetValue) !== undefined) {\n return cloneDictionaryValue(targetValue as DictionaryValue);\n }\n\n if (isDictionaryValue(targetValue) && !isDictionaryValue(sourceValue)) {\n return cloneDictionaryValue(targetValue);\n }\n\n const sourceEntry = getDictionaryEntry(sourceValue);\n if (sourceEntry !== undefined) {\n return await translateEntry(key, sourceEntry);\n }\n\n if (!isDictionaryValue(sourceValue)) {\n throw new DictionarySourceNotFoundError(key);\n }\n\n const targetDictionary = isDictionaryValue(targetValue) ? targetValue : {};\n const keys = new Set([\n ...Object.keys(sourceValue),\n ...Object.keys(targetDictionary),\n ]);\n const entries = await Promise.all(\n Array.from(keys).map(async (childKey) => {\n const childPath = key ? `${key}.${childKey}` : childKey;\n assertSafeDictionaryPathSegment(childKey, childPath);\n\n const childSource = sourceValue[childKey];\n if (childSource === undefined) {\n return [\n childKey,\n cloneDictionaryValue(targetDictionary[childKey]),\n ] as const;\n }\n\n return [\n childKey,\n await materializeDictionaryValue({\n key: childPath,\n sourceValue: childSource,\n targetValue: targetDictionary[childKey],\n translateEntry,\n }),\n ] as const;\n })\n );\n\n return Object.fromEntries(entries) as Dictionary;\n}\n","import {\n cloneDictionaryValue,\n getDictionaryEntry,\n getDictionaryValue,\n getDictionaryValueAtPath,\n isDictionaryValue,\n setDictionaryValueAtPath,\n} from './utils/dictionary-helpers';\nimport { materializeDictionaryValue } from './utils/materialize-dictionary';\nimport { dedupePending } from './utils/dedupePending';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryPath,\n DictionaryValue,\n} from './utils/types/dictionary';\nexport type {\n Dictionary,\n DictionaryEntry,\n DictionaryKey,\n DictionaryLeaf,\n DictionaryObject,\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 DictionaryLoader = (locale: string) => Promise<Dictionary>;\n\nfunction cloneDictionaryEntry(entry: DictionaryEntry): DictionaryEntry {\n return {\n entry: entry.entry,\n options: structuredClone(entry.options),\n };\n}\n\nexport class DictionaryCache {\n private cache: Dictionary;\n private pendingTranslations = new Map<\n DictionaryKey,\n Promise<DictionaryEntry>\n >();\n private pendingMaterializations = new Map<\n DictionaryKey,\n Promise<DictionaryValue>\n >();\n private runtimeTranslate: DictionaryRuntimeTranslate;\n\n constructor({\n init,\n runtimeTranslate,\n }: {\n init: Dictionary;\n runtimeTranslate: DictionaryRuntimeTranslate;\n }) {\n this.cache = structuredClone(init);\n this.runtimeTranslate = runtimeTranslate;\n }\n\n public getEntry(key: DictionaryKey): DictionaryEntry | undefined {\n const value = getDictionaryValueAtPath(this.cache, key);\n const entry = getDictionaryEntry(value);\n if (entry === undefined) {\n return undefined;\n }\n return cloneDictionaryEntry(entry);\n }\n\n public getValue(key: DictionaryKey): DictionaryValue | undefined {\n const value = getDictionaryValueAtPath(this.cache, key);\n if (value === undefined) {\n return undefined;\n }\n return cloneDictionaryValue(value);\n }\n\n public setValue(key: DictionaryKey, value: DictionaryValue): void {\n setDictionaryValueAtPath(this.cache, key, cloneDictionaryValue(value));\n }\n\n public getInternalCache(): Dictionary {\n return cloneDictionaryValue(this.cache);\n }\n\n public update(dictionary: Dictionary): void {\n mergeDictionary(this.cache, dictionary);\n }\n\n public async materializeValue(\n key: DictionaryKey,\n sourceValue: DictionaryValue,\n targetValue = getDictionaryValueAtPath(this.cache, key)\n ): Promise<DictionaryValue> {\n return dedupePending(this.pendingMaterializations, key, () =>\n materializeDictionaryValue({\n key,\n sourceValue,\n targetValue,\n translateEntry: async (entryKey, sourceEntry) =>\n getDictionaryValue(\n await this.materializeEntry(entryKey, sourceEntry)\n ),\n }).then((value) => {\n this.setValue(key, value);\n return value;\n })\n );\n }\n\n public async materializeEntry(\n key: DictionaryKey,\n sourceEntry: DictionaryEntry\n ): Promise<DictionaryEntry> {\n return cloneDictionaryEntry(\n await dedupePending(this.pendingTranslations, key, () =>\n this.runtimeTranslate(key, sourceEntry).then((value) => {\n setDictionaryValueAtPath(this.cache, key, value);\n const entry = getDictionaryEntry(value);\n if (entry === undefined) {\n // Never will happen\n throw new Error(\n 'DictionaryCache materializeEntry did not return a DictionaryEntry'\n );\n }\n return cloneDictionaryEntry(entry);\n })\n )\n );\n }\n}\n\nfunction mergeDictionary(target: Dictionary, source: Dictionary): void {\n for (const [key, value] of Object.entries(source)) {\n const targetValue = target[key];\n if (isDictionaryValue(targetValue) && isDictionaryValue(value)) {\n mergeDictionary(targetValue, value);\n } else {\n target[key] = cloneDictionaryValue(value);\n }\n }\n}\n","import logger from '../logs/logger';\nimport { I18nCacheConfig, I18nCacheConstructorParams } from './types';\nimport {\n createDiagnosticMessage,\n defaultRuntimeApiUrl,\n} from 'generaltranslation/internal';\nimport { Translation } from './translations-manager/utils/types/translation-data';\nimport { LookupOptions } from '../translation-functions/types/options';\nimport { SafeTranslationsLoader } from './translations-manager/translations-loaders/types';\nimport {\n createTranslateManyFactory,\n type CreateTranslateMany,\n} from './translations-manager/utils/createTranslateMany';\nimport { routeCreateTranslationLoader } from './translations-manager/translations-loaders/routeCreateTranslationLoader';\nimport { getLoadTranslationsType } from './utils/getLoadTranslationsType';\nimport { ResourceCache } from './translations-manager/ResourceCache';\nimport { TranslationsCache } from './translations-manager/TranslationsCache';\nimport type { Hash, Locale } from './translations-manager/TranslationsCache';\nimport { DictionaryCache } from './translations-manager/DictionaryCache';\nimport type {\n Dictionary,\n DictionaryEntry,\n DictionaryObject,\n} from './translations-manager/DictionaryCache';\nimport { resolveDictionaryLookupOptions } from './translations-manager/utils/dictionary-helpers';\nimport { DictionarySourceNotFoundError } from './translations-manager/utils/DictionarySourceNotFoundError';\nimport { getRuntimeEnvironment } from '../utils/getRuntimeEnvironment';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\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\ntype DictionaryResolver = (id: string) => DictionaryEntry | undefined;\n\ntype DictionaryObjResolver = (id: string) => DictionaryObject | undefined;\n\ntype DictionaryResolvers = {\n lookupDictionary: DictionaryResolver;\n lookupDictionaryObj: DictionaryObjResolver;\n};\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 * Callback function to prefetch entries during the async period\n */\ntype PrefetchEntriesType<TranslationType extends Translation> = (\n prefetchEntries: PrefetchEntry<TranslationType>[]\n) => Promise<void>;\n\n/**\n * Event fired when a runtime translation resolves a cache miss\n */\nexport type TranslationsCacheMissEvent<\n TranslationValue extends Translation = Translation,\n> = {\n locale: Locale;\n hash: Hash;\n translation: TranslationValue;\n};\n\n/**\n * Class for managing translation functionality\n * @template TranslationValue - The type of the translation that will be cached\n */\nclass I18nCache<TranslationValue extends Translation = Translation> {\n protected config: I18nCacheConfig;\n\n /**\n * Single dev hot-reload listener for runtime-translation cache misses.\n * Subclasses that add cache-miss behavior should wrap any existing listener\n * instead of overwriting it.\n */\n protected onTranslationsCacheMiss?: (\n event: TranslationsCacheMissEvent<TranslationValue>\n ) => void;\n\n /**\n * Locale-keyed caches for translations and dictionaries\n */\n private translations: ResourceCache<\n Locale,\n TranslationsCache<TranslationValue>\n >;\n private dictionaries: ResourceCache<Locale, DictionaryCache>;\n\n /**\n * Creates a locale-bound translateMany for runtime translation\n */\n private createTranslateMany: CreateTranslateMany;\n\n /**\n * Creates an instance of I18nCache.\n * TODO: resolve gtConfig from just file path\n * @param params - The parameters for the I18nCache constructor\n * @param params.config - The configuration for the I18nCache\n */\n constructor(params: I18nCacheConstructorParams) {\n // Validation\n validateCacheParams(params);\n\n this.config = {\n projectId: params.projectId,\n devApiKey: params.devApiKey,\n apiKey: params.apiKey,\n runtimeUrl: params.runtimeUrl,\n modelProvider: params.modelProvider,\n cacheExpiryTime: params.cacheExpiryTime,\n batchConfig: params.batchConfig,\n runtimeTranslation: params.runtimeTranslation,\n _versionId: params._versionId,\n };\n\n // Create cache miss handlers\n const loadTranslations = 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 },\n }) as SafeTranslationsLoader<TranslationValue>;\n const loadDictionary = params.loadDictionary ?? (() => Promise.resolve({}));\n this.createTranslateMany = createTranslateManyFactory(\n getI18nConfig().getGTClass(),\n this.config.runtimeTranslation?.timeout ?? DEFAULT_TRANSLATION_TIMEOUT,\n {\n ...(this.config.modelProvider && {\n modelProvider: this.config.modelProvider,\n }),\n ...this.config.runtimeTranslation?.metadata,\n }\n );\n\n // Setup locale-keyed caches\n const ttl = this.config.cacheExpiryTime;\n this.translations = new ResourceCache<\n Locale,\n TranslationsCache<TranslationValue>\n >({\n ttl,\n load: async (locale) =>\n this.createTranslationsCache(locale, await loadTranslations(locale)),\n });\n this.dictionaries = new ResourceCache<Locale, DictionaryCache>({\n ttl,\n load: async (locale) =>\n this.createDictionaryCache(locale, await loadDictionary(locale)),\n });\n\n // The default locale's source dictionary is provided synchronously and\n // never expires\n const defaultLocale = getI18nConfig().getDefaultLocale();\n this.dictionaries.set(\n defaultLocale,\n this.createDictionaryCache(defaultLocale, params.dictionary ?? {}),\n { expiresAt: -1 }\n );\n }\n\n // ========== Cache Factories ========== //\n\n private createTranslationsCache(\n locale: Locale,\n init: Record<Hash, TranslationValue>\n ): TranslationsCache<TranslationValue> {\n return new TranslationsCache<TranslationValue>({\n init,\n translateMany: this.createTranslateMany(locale),\n batchConfig: this.config.batchConfig,\n onMiss: (hash, translation) =>\n this.onTranslationsCacheMiss?.({ locale, hash, translation }),\n });\n }\n\n private createDictionaryCache(\n locale: Locale,\n init: Dictionary\n ): DictionaryCache {\n return new DictionaryCache({\n init,\n runtimeTranslate: (id, sourceEntry) =>\n this.translateDictionaryEntry(locale, id, sourceEntry),\n });\n }\n\n // ========== Getters and Setters ========== //\n\n /**\n * Get the version ID\n */\n getVersionId(): string | undefined {\n return this.config._versionId;\n }\n\n // ========== Translation Updates ========== //\n\n updateTranslations(\n translationsSnapshot: Record<Locale, Record<Hash, TranslationValue>>\n ): void {\n for (const locale in translationsSnapshot) {\n const txCache = this.translations.get(locale);\n if (txCache) {\n txCache.update(translationsSnapshot[locale]);\n } else {\n this.translations.set(\n locale,\n this.createTranslationsCache(locale, translationsSnapshot[locale])\n );\n }\n }\n }\n\n updateDictionaries(dictionarySnapshot: Record<Locale, Dictionary>): void {\n for (const locale in dictionarySnapshot) {\n const dictionaryCache = this.dictionaries.get(locale);\n if (dictionaryCache) {\n dictionaryCache.update(dictionarySnapshot[locale]);\n } else {\n this.dictionaries.set(\n locale,\n this.createDictionaryCache(locale, dictionarySnapshot[locale])\n );\n }\n }\n }\n\n // ========== Translation Resolution ========== //\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 return this.guardAsync({}, async () => {\n // Validate\n const translationLocale = this._resolveCacheLocale(locale);\n if (!translationLocale) {\n return {};\n }\n\n const txCache = await this.translations.getOrLoad(translationLocale);\n\n // Get the translations\n return txCache.getInternalCache();\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 return this.guardAsync({}, async () => {\n // Validate\n const dictionaryLocale = this._resolveCacheLocale(locale);\n if (!dictionaryLocale) {\n return this.getDefaultDictionaryCache()?.getInternalCache() ?? {};\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n\n return dictionaryCache.getInternalCache();\n });\n }\n\n /**\n * Look up a dictionary entry\n */\n lookupDictionary(locale: string, id: string): DictionaryEntry | undefined {\n return this.guard(undefined, () =>\n this.dictionaries\n .get(this.resolveDictionaryCacheLocale(locale))\n ?.getEntry(id)\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 return this.guard(undefined, () =>\n this.dictionaries\n .get(this.resolveDictionaryCacheLocale(locale))\n ?.getValue(id)\n );\n }\n\n async getLookupDictionary(locale: string): Promise<DictionaryResolvers> {\n return this.guardAsync<DictionaryResolvers>(\n {\n lookupDictionary: () => undefined,\n lookupDictionaryObj: () => undefined,\n },\n async () => {\n const asyncBoundaryLocale = this._resolveCacheLocale(locale);\n const asyncBoundaryDictionaryCache = asyncBoundaryLocale\n ? await this.dictionaries.getOrLoad(asyncBoundaryLocale)\n : this.getDefaultDictionaryCache();\n\n return {\n lookupDictionary: (id) => asyncBoundaryDictionaryCache?.getEntry(id),\n lookupDictionaryObj: (id) =>\n asyncBoundaryDictionaryCache?.getValue(id),\n };\n }\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 return this.guardAsync(undefined, async () => {\n const dictionaryLocale = this._resolveCacheLocale(locale);\n if (!dictionaryLocale) {\n return this.getSourceDictionaryEntry(id);\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n\n return (\n dictionaryCache.getEntry(id) ??\n (await dictionaryCache.materializeEntry(\n id,\n this.getSourceDictionaryEntry(id)\n ))\n );\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 return this.guardAsync(undefined, async () => {\n const dictionaryLocale = this._resolveCacheLocale(locale);\n\n if (!dictionaryLocale) {\n return this.getSourceDictionaryObject(id);\n }\n\n const dictionaryCache =\n await this.dictionaries.getOrLoad(dictionaryLocale);\n const targetObject = dictionaryCache.getValue(id);\n const sourceObject = this.getSourceDictionaryObject(id, {\n throwOnMissing: false,\n });\n if (sourceObject === undefined) {\n if (targetObject !== undefined) {\n return targetObject;\n }\n throw new DictionarySourceNotFoundError(id);\n }\n\n return await dictionaryCache.materializeValue(\n id,\n sourceObject,\n targetObject\n );\n });\n }\n\n private async translateDictionaryEntry(\n locale: Locale,\n id: string,\n sourceEntry: DictionaryEntry\n ): Promise<string> {\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 return translation;\n }\n\n private getSourceDictionaryEntry(id: string): DictionaryEntry {\n const sourceEntry = this.getDefaultDictionaryCache()?.getEntry(id);\n if (sourceEntry === undefined) {\n throw new DictionarySourceNotFoundError(id);\n }\n return sourceEntry;\n }\n\n private getSourceDictionaryObject(\n id: string,\n { throwOnMissing = true }: { throwOnMissing?: boolean } = {}\n ): DictionaryObject | undefined {\n const sourceObject = this.getDefaultDictionaryCache()?.getValue(id);\n if (sourceObject === undefined && throwOnMissing) {\n throw new DictionarySourceNotFoundError(id);\n }\n return sourceObject;\n }\n\n private getDefaultDictionaryCache() {\n return this.dictionaries.get(getI18nConfig().getDefaultLocale());\n }\n\n private resolveDictionaryCacheLocale(locale: string): Locale {\n return (\n this._resolveCacheLocale(locale) ?? getI18nConfig().getDefaultLocale()\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 return this.guard<T | undefined>(undefined, () => {\n // Validate\n const { translationLocale, options: lookupOptions } =\n this.resolveLookupParams(locale, options);\n\n // Early return if in default locale\n if (!translationLocale) return message;\n\n // Get the translation from the locale cache\n return this.translations\n .get(translationLocale)\n ?.get({ message, options: lookupOptions });\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 return this.guardAsync<T | undefined>(undefined, () =>\n this.lookupTranslationWithFallbackResolved(locale, message, options)\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 * @returns A lookup translation function\n *\n * @important prefetchEntries must all be the same locale\n */\n async getLookupTranslation(locale: string): Promise<\n TranslationResolver<TranslationValue> & {\n prefetchEntries?: PrefetchEntriesType<TranslationValue>;\n }\n > {\n return this.guardAsync<TranslationResolver<TranslationValue>>(\n (message) => message,\n async () => {\n // Locale used for the async load\n const asyncBoundaryLocale = this._resolveCacheLocale(locale);\n\n // Early return if i18n is disabled or default locale\n if (!asyncBoundaryLocale) {\n return (message) => message;\n }\n\n const asyncBoundaryTxCache =\n await this.translations.getOrLoad(asyncBoundaryLocale);\n\n // Prefetch any entries during async block (dev hot reload only)\n const prefetchEntries = async (\n prefetchEntries: {\n message: TranslationValue;\n options: LookupOptions;\n }[] = []\n ) => {\n if (\n process.env.NODE_ENV !== 'production' &&\n getI18nConfig().isDevHotReloadEnabled()\n ) {\n // Invariant: all prefetchEntries must be the same locale\n // TODO: investigate why we have made this an invariant, we may be able to drop this requirement\n const resolvedPrefetchEntries = resolvePrefetchEntriesByLocale(\n prefetchEntries,\n asyncBoundaryLocale,\n (entryLocale) =>\n this._resolveCacheLocale(entryLocale) ??\n this._resolveLocale(entryLocale)\n );\n if (resolvedPrefetchEntries.length !== prefetchEntries.length) {\n logger.warn(\n `I18nCache: getLookupTranslation(): prefetchEntries must all be the same locale, ignoring all entries that are not for ${asyncBoundaryLocale}`\n );\n }\n\n await Promise.allSettled(\n resolvedPrefetchEntries\n .filter((entry) => asyncBoundaryTxCache.get(entry) == null)\n .map((entry) => asyncBoundaryTxCache.miss(entry))\n );\n }\n };\n\n // Create translation resolver\n const lookupTranslation: TranslationResolver<TranslationValue> = (\n message,\n lookupOptions: LookupOptions = {} as LookupOptions\n ) =>\n this.guard(undefined, () => {\n const { translationLocale, options } = this.resolveLookupParams(\n lookupOptions.$locale ?? asyncBoundaryLocale,\n lookupOptions\n );\n\n // Default locale, return the message\n if (!translationLocale) return message;\n\n // Request locale overriden, to attempt a synchronous lookup if an alternate locale is requested\n const txCache =\n translationLocale === asyncBoundaryLocale\n ? asyncBoundaryTxCache\n : this.translations.get(translationLocale);\n\n // Get the translation\n return txCache?.get({ message, options });\n });\n\n Object.assign(lookupTranslation, { prefetchEntries });\n return lookupTranslation;\n }\n );\n }\n\n // ========== Error Handling ========== //\n\n /**\n * Run a lookup, routing errors through handleError (log in production,\n * throw in development) and returning the fallback once handled.\n */\n private guard<T>(fallback: T, fn: () => T): T {\n try {\n return fn();\n } catch (error) {\n this.handleError(error);\n return fallback;\n }\n }\n\n private async guardAsync<T>(fallback: T, fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n this.handleError(error);\n return fallback;\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 (getRuntimeEnvironment()) {\n case 'development':\n throw error;\n case 'production':\n default:\n logger.error('I18nCache: ' + error);\n break;\n }\n }\n\n private _resolveLocale(locale: string) {\n const i18nConfig = getI18nConfig();\n const resolvedLocale = i18nConfig.determineLocale(locale);\n if (!i18nConfig.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 const i18nConfig = getI18nConfig();\n if (i18nConfig.requiresTranslation(resolvedLocale)) {\n return resolvedLocale;\n }\n\n const aliasLocale = i18nConfig.resolveAliasLocale(\n i18nConfig.standardizeLocale(locale)\n );\n if (i18nConfig.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 ): LookupOptions {\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 const txCache = await this.translations.getOrLoad(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\nexport { I18nCache };\n\n// ===== Helper Functions ===== //\n\n/**\n * Validate constructor params: log warnings for suspicious configs and throw\n * on hard misconfigurations.\n */\nfunction validateCacheParams(params: I18nCacheConstructorParams): void {\n // Runtime translation against a custom API URL still needs GT credentials\n if (params.runtimeUrl && params.runtimeUrl !== defaultRuntimeApiUrl) {\n if (!params.projectId) {\n logger.warn(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'Runtime translation needs a projectId',\n fix: 'Add projectId to the I18nCache config or disable runtime translation',\n })\n );\n }\n if (!params.devApiKey && !params.apiKey) {\n logger.warn(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'Runtime translation needs devApiKey or apiKey',\n fix: 'Add credentials to the I18nCache config or disable runtime translation',\n })\n );\n }\n }\n\n // loadDictionary requires dictionary so the default locale always has a\n // source dictionary\n if (params.loadDictionary && !params.dictionary) {\n logger.error(\n 'I18nCache: ' +\n createDiagnosticMessage({\n whatHappened: 'loadDictionary needs a source dictionary',\n fix: 'Provide dictionary so the default locale has source content',\n })\n );\n throw new Error('Validation errors occurred');\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","import type { ReadonlyConditionStoreInterface as ReadonlyConditionStoreContract } from '../i18n-cache/types';\nimport type { LocaleCandidates } from '../i18n-config/I18nConfig';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\n\nexport type ReadonlyConditionStoreParams = {\n locale: LocaleCandidates;\n region?: string;\n enableI18n?: boolean;\n};\n\nexport class ReadonlyConditionStore implements ReadonlyConditionStoreContract {\n protected locale: string;\n protected region?: string;\n protected enableI18n: boolean;\n\n constructor({\n locale,\n region,\n enableI18n = true,\n }: ReadonlyConditionStoreParams) {\n this.locale = getI18nConfig().resolveSupportedLocale(locale);\n this.region = region;\n this.enableI18n = enableI18n;\n }\n\n getLocale = (): string => {\n return this.locale;\n };\n\n getRegion = (): string | undefined => {\n return this.region;\n };\n\n getEnableI18n = (): boolean => {\n return this.enableI18n;\n };\n\n // --- no-op methods --- //\n\n setLocale = (locale: LocaleCandidates): void => {};\n\n setRegion = (region: string | undefined): void => {};\n\n setEnableI18n = (enableI18n: boolean): void => {};\n}\n","import type { WritableConditionStoreInterface } from '../i18n-cache/types';\nimport type { LocaleCandidates } from '../i18n-config/I18nConfig';\nimport { getI18nConfig } from '../i18n-config/singleton-operations';\nimport {\n ReadonlyConditionStore,\n type ReadonlyConditionStoreParams,\n} from './ReadonlyConditionStore';\n\nexport type WritableConditionStoreParams = ReadonlyConditionStoreParams;\n\nexport class WritableConditionStore\n extends ReadonlyConditionStore\n implements WritableConditionStoreInterface\n{\n setLocale = (locale: LocaleCandidates): void => {\n this.locale = getI18nConfig().resolveSupportedLocale(locale);\n };\n\n setRegion = (region: string | undefined): void => {\n this.region = region;\n };\n\n setEnableI18n = (enableI18n: boolean): void => {\n this.enableI18n = enableI18n;\n };\n}\n","import type { LookupOptions } from '../translation-functions/types/options';\nimport type { Translation } from '../types';\nimport { hashMessage } from './hashMessage';\n\nexport type TranslateListenerLookup<T extends Translation = Translation> =\n | {\n locale: string;\n message: T;\n options: LookupOptions;\n }\n | {\n locale: string;\n hash: string;\n };\n\nexport type DictionaryListenerLookup = {\n locale: string;\n id: string;\n};\n\nexport function getTranslateListenerKey<T extends Translation>(\n lookup: TranslateListenerLookup<T>\n): string {\n const hash =\n 'hash' in lookup\n ? lookup.hash\n : hashMessage(lookup.message, lookup.options);\n return `${lookup.locale}:${hash}`;\n}\n\nexport function getDictionaryListenerKey({\n locale,\n id,\n}: DictionaryListenerLookup): string {\n return `${locale}:${id}`;\n}\n","type HeaderValue = string | string[] | null | undefined;\n\n/**\n * Parse an Accept-Language header into locale candidates by preference.\n */\nexport function parseAcceptLanguage(header: HeaderValue): string[] {\n const headerValues = Array.isArray(header) ? header : [header];\n\n return headerValues\n .flatMap((value) => value?.split(',') ?? [])\n .map((entry, index) => {\n const [locale = '', ...parameters] = entry\n .split(';')\n .map((value) => value.trim());\n const qualityParameter = parameters.find((parameter) =>\n parameter.toLowerCase().startsWith('q=')\n );\n const quality = Number(qualityParameter?.slice(2) ?? 1);\n return { locale, quality, index };\n })\n .filter(\n ({ locale, quality }) =>\n locale !== '' && locale !== '*' && quality > 0 && quality <= 1\n )\n .sort((a, b) => b.quality - a.quality || a.index - b.index)\n .map(({ locale }) => locale);\n}\n\n/**\n * Read and decode a value from a Cookie header or document.cookie string.\n */\nexport function getCookieValue(\n cookieHeader: string | null | undefined,\n cookieName: string\n): string | undefined {\n const prefix = `${cookieName}=`;\n const cookie = cookieHeader\n ?.split(';')\n .map((value) => value.trim())\n .find((value) => value.startsWith(prefix));\n if (!cookie) return undefined;\n\n const value = cookie.slice(prefix.length);\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gt-i18n",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Pure JS i18n library for General Translation",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@generaltranslation/format": "0.1.2",
44
- "generaltranslation": "9.0.0"
44
+ "generaltranslation": "9.0.2"
45
45
  },
46
46
  "exports": {
47
47
  ".": {