@vielzeug/lingua 2.4.0 → 3.0.0

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.
Files changed (52) hide show
  1. package/README.md +9 -28
  2. package/dist/_dev.cjs.map +1 -1
  3. package/dist/_dev.js.map +1 -1
  4. package/dist/_resources.cjs +1 -1
  5. package/dist/_resources.cjs.map +1 -1
  6. package/dist/_resources.d.ts +9 -3
  7. package/dist/_resources.d.ts.map +1 -1
  8. package/dist/_resources.js +19 -22
  9. package/dist/_resources.js.map +1 -1
  10. package/dist/_template.cjs +1 -1
  11. package/dist/_template.cjs.map +1 -1
  12. package/dist/_template.d.ts +2 -1
  13. package/dist/_template.d.ts.map +1 -1
  14. package/dist/_template.js +12 -3
  15. package/dist/_template.js.map +1 -1
  16. package/dist/catalog.cjs +1 -1
  17. package/dist/catalog.cjs.map +1 -1
  18. package/dist/catalog.d.ts +8 -8
  19. package/dist/catalog.d.ts.map +1 -1
  20. package/dist/catalog.js +10 -5
  21. package/dist/catalog.js.map +1 -1
  22. package/dist/errors.cjs +1 -1
  23. package/dist/errors.cjs.map +1 -1
  24. package/dist/errors.d.ts +4 -0
  25. package/dist/errors.d.ts.map +1 -1
  26. package/dist/errors.js +3 -3
  27. package/dist/errors.js.map +1 -1
  28. package/dist/i18n.cjs +1 -1
  29. package/dist/i18n.cjs.map +1 -1
  30. package/dist/i18n.d.ts +6 -7
  31. package/dist/i18n.d.ts.map +1 -1
  32. package/dist/i18n.js +68 -55
  33. package/dist/i18n.js.map +1 -1
  34. package/dist/index.cjs +1 -1
  35. package/dist/index.d.ts +4 -4
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +5 -5
  38. package/dist/lingua.cjs +1 -1
  39. package/dist/lingua.cjs.map +1 -1
  40. package/dist/lingua.iife.js +1 -1
  41. package/dist/lingua.iife.js.map +1 -1
  42. package/dist/lingua.js +1 -1
  43. package/dist/lingua.js.map +1 -1
  44. package/dist/translator.cjs +1 -1
  45. package/dist/translator.cjs.map +1 -1
  46. package/dist/translator.d.ts +15 -10
  47. package/dist/translator.d.ts.map +1 -1
  48. package/dist/translator.js +41 -32
  49. package/dist/translator.js.map +1 -1
  50. package/dist/types.d.ts +38 -14
  51. package/dist/types.d.ts.map +1 -1
  52. package/package.json +8 -8
package/dist/i18n.js CHANGED
@@ -1,91 +1,104 @@
1
1
  import "./_dev.js";
2
- import { LinguaDisposedError as e, LinguaInvalidStateError as t } from "./errors.js";
3
- import { canonicalLocale as n, localeChain as r } from "./_locale.js";
4
- import { createCatalogStore as i } from "./_resources.js";
5
- import { createTranslatorFromCompiled as a } from "./translator.js";
2
+ import { LinguaDisposedError as e, LinguaInvalidStateError as t, LinguaMissingCatalogError as n } from "./errors.js";
3
+ import { canonicalLocale as r, localeChain as i } from "./_locale.js";
4
+ import { createCatalogStore as a } from "./_resources.js";
5
+ import { createTranslatorFromCompiled as o } from "./translator.js";
6
6
  //#region src/i18n.ts
7
- function o(t) {
8
- let o = i(t.catalogs), s = t.fallback, c = (Array.isArray(s) ? s : s ? [s] : []).map(n), l = new AbortController(), u = /* @__PURE__ */ new Set(), d = !1, f = n(t.locale ?? "en"), p = 0, m = () => ({
9
- locale: f,
10
- revision: p,
11
- translator: a(o.catalogMap(), {
12
- ...t,
13
- fallback: s,
14
- locale: f
15
- })
16
- }), h = m(), g = () => {
17
- if (d) throw new e();
18
- }, _ = () => {
19
- d || (d = !0, u.clear(), l.abort());
20
- }, v = (e) => {
7
+ function s(s) {
8
+ if (s.state && s.state.version !== 4) throw new t(`Unsupported lingua state version: ${String(s.state.version)}.`);
9
+ let c = s.fallback, l = (Array.isArray(c) ? c : c ? [c] : []).map(r), u = new AbortController(), d = /* @__PURE__ */ new Set(), f = !1, p = r(s.locale ?? s.state?.locale ?? "en"), m = 0, h = 0, g = a({
10
+ catalogs: s.catalogs,
11
+ loadCatalog: s.loadCatalog
12
+ });
13
+ if (s.state) for (let [e, t] of Object.entries(s.state.catalogs)) g.hydrate(e, t);
14
+ let _ = async (e) => {
15
+ let t = [];
16
+ for (let n of /* @__PURE__ */ new Set([e, ...l])) await g.load(n) && t.push(n);
17
+ return t;
18
+ }, v = () => {
19
+ let e = i(p, l).some(g.isLoaded) ? s.missing : () => {
20
+ throw new n(`No catalog loaded for locale "${p}". Call load() before translating.`);
21
+ };
22
+ return {
23
+ locale: p,
24
+ revision: m,
25
+ translator: o(g.catalogMap(), {
26
+ fallback: c,
27
+ locale: p,
28
+ missing: e
29
+ })
30
+ };
31
+ }, y = v(), b = () => {
32
+ if (f) throw new e();
33
+ }, x = () => {
34
+ f || (f = !0, d.clear(), u.abort());
35
+ }, S = (e) => {
21
36
  try {
22
- e(h);
37
+ e(y);
23
38
  } catch {}
24
- }, y = () => {
25
- p++, h = m();
26
- for (let e of [...u]) v(e);
27
- }, b = (e) => r(f, c).includes(e);
39
+ }, C = () => {
40
+ m++, y = v();
41
+ for (let e of [...d]) S(e);
42
+ }, w = (e) => i(p, l).includes(e);
28
43
  return {
29
44
  get disposalSignal() {
30
- return l.signal;
45
+ return u.signal;
31
46
  },
32
- dispose: _,
47
+ dispose: x,
33
48
  get disposed() {
34
- return d;
49
+ return f;
35
50
  },
36
51
  getSnapshot() {
37
- return h;
52
+ return y;
38
53
  },
39
54
  isLoaded(e) {
40
- return !d && o.isLoaded(e?.locale ?? f);
55
+ return !f && g.isLoaded(e?.locale ?? p);
41
56
  },
42
57
  async load(e) {
43
- g();
44
- let t = n(e?.locale ?? f), r = await o.load(t);
45
- !d && r && b(t) && y();
58
+ b();
59
+ let t = r(e?.locale ?? p), n = await _(t);
60
+ b(), n.some(w) && C();
46
61
  },
47
62
  get locale() {
48
- return f;
63
+ return p;
49
64
  },
50
- segments(e, t) {
51
- return h.translator.segmentsDynamic(e, t);
65
+ parts(e, t) {
66
+ return y.translator.partsDynamic(e, t);
52
67
  },
53
- segmentsDynamic(e, t) {
54
- return h.translator.segmentsDynamic(e, t);
68
+ partsDynamic(e, t) {
69
+ return y.translator.partsDynamic(e, t);
55
70
  },
56
71
  serialize() {
57
- return g(), o.state(f);
72
+ return b(), g.state(p);
58
73
  },
59
74
  async setLocale(e) {
60
- g();
61
- let t = n(e);
62
- t !== f && (f = t, y());
75
+ b();
76
+ let t = r(e), n = ++h, i = await _(t);
77
+ if (b(), n === h) {
78
+ if (t === p) {
79
+ i.some(w) && C();
80
+ return;
81
+ }
82
+ p = t, C();
83
+ }
63
84
  },
64
85
  subscribe(e, t) {
65
- if (g(), t?.signal?.aborted) return () => {};
86
+ if (b(), t?.signal?.aborted) return () => {};
66
87
  let n = () => {
67
- u.delete(e), t?.signal?.removeEventListener("abort", n);
88
+ d.delete(e), t?.signal?.removeEventListener("abort", n);
68
89
  };
69
- return t?.signal?.addEventListener("abort", n, { once: !0 }), u.add(e), t?.immediate && v(e), n;
90
+ return t?.signal?.addEventListener("abort", n, { once: !0 }), d.add(e), t?.immediate && S(e), n;
70
91
  },
71
- [Symbol.dispose]: _,
92
+ [Symbol.dispose]: x,
72
93
  translate(e, t = {}) {
73
- return h.translator.translateDynamic(e, t);
94
+ return y.translator.translateDynamic(e, t);
74
95
  },
75
96
  translateDynamic(e, t) {
76
- return h.translator.translateDynamic(e, t);
97
+ return y.translator.translateDynamic(e, t);
77
98
  }
78
99
  };
79
100
  }
80
- function s(e, n) {
81
- if (e.version !== 3) throw new t(`Unsupported lingua state version: ${String(e.version)}.`);
82
- return o({
83
- ...n,
84
- catalogs: e.catalogs,
85
- locale: e.locale
86
- });
87
- }
88
101
  //#endregion
89
- export { o as createTranslationStore, s as hydrateTranslationStore };
102
+ export { s as createI18n };
90
103
 
91
104
  //# sourceMappingURL=i18n.js.map
package/dist/i18n.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.js","names":[],"sources":["../src/i18n.ts"],"sourcesContent":["import { error as logError } from './_dev';\nimport { canonicalLocale, localeChain } from './_locale';\nimport { createCatalogStore } from './_resources';\nimport { LinguaDisposedError, LinguaInvalidStateError } from './errors';\nimport { createTranslatorFromCompiled, type Translator } from './translator';\nimport type { Catalog, Locale, SubscribeOptions, TranslationState, TranslationStoreOptions } from './types';\n\nexport type TranslationSnapshot<C extends Catalog = Catalog> = {\n readonly locale: Locale;\n readonly revision: number;\n readonly translator: Translator<C>;\n};\n\nexport type TranslationStore<C extends Catalog = Catalog> = Translator<C> & {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n getSnapshot(): TranslationSnapshot<C>;\n isLoaded(options?: { locale?: Locale }): boolean;\n load(options?: { locale?: Locale }): Promise<void>;\n serialize(): TranslationState<C>;\n setLocale(locale: Locale): Promise<void>;\n subscribe(listener: (snapshot: TranslationSnapshot<C>) => void, options?: SubscribeOptions): () => void;\n};\n\nexport function createTranslationStore<C extends Catalog>(options: TranslationStoreOptions<C>): TranslationStore<C> {\n const catalogs = createCatalogStore(options.catalogs);\n const fallback = options.fallback;\n const fallbackLocales = (Array.isArray(fallback) ? fallback : fallback ? [fallback] : []).map(canonicalLocale);\n const controller = new AbortController();\n const subscribers = new Set<(snapshot: TranslationSnapshot<C>) => void>();\n let disposed = false;\n let locale = canonicalLocale(options.locale ?? 'en');\n let revision = 0;\n\n const buildSnapshot = (): TranslationSnapshot<C> => ({\n locale,\n revision,\n translator: createTranslatorFromCompiled<C>(catalogs.catalogMap(), { ...options, fallback, locale }),\n });\n let snapshot = buildSnapshot();\n\n const assertLive = (): void => {\n if (disposed) throw new LinguaDisposedError();\n };\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n subscribers.clear();\n controller.abort();\n };\n\n const dispatch = (listener: (next: TranslationSnapshot<C>) => void): void => {\n try {\n listener(snapshot);\n } catch (error) {\n logError('subscriber error', error);\n }\n };\n\n const notify = (): void => {\n revision++;\n snapshot = buildSnapshot();\n\n for (const listener of [...subscribers]) dispatch(listener);\n };\n\n const relevant = (candidate: Locale): boolean => localeChain(locale, fallbackLocales).includes(candidate);\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n dispose,\n get disposed() {\n return disposed;\n },\n getSnapshot() {\n return snapshot;\n },\n isLoaded(loadOptions) {\n return !disposed && catalogs.isLoaded(loadOptions?.locale ?? locale);\n },\n async load(loadOptions) {\n assertLive();\n\n const targetLocale = canonicalLocale(loadOptions?.locale ?? locale);\n const changed = await catalogs.load(targetLocale);\n\n if (!disposed && changed && relevant(targetLocale)) notify();\n },\n get locale() {\n return locale;\n },\n segments(key: string, translateOptions) {\n return snapshot.translator.segmentsDynamic(key, translateOptions);\n },\n segmentsDynamic(key, translateOptions) {\n return snapshot.translator.segmentsDynamic(key, translateOptions);\n },\n serialize() {\n assertLive();\n\n return catalogs.state(locale);\n },\n async setLocale(nextLocale) {\n assertLive();\n\n const next = canonicalLocale(nextLocale);\n\n if (next === locale) return;\n\n locale = next;\n notify();\n },\n subscribe(listener, subscribeOptions) {\n assertLive();\n\n if (subscribeOptions?.signal?.aborted) return () => {};\n\n const unsubscribe = (): void => {\n subscribers.delete(listener);\n subscribeOptions?.signal?.removeEventListener('abort', unsubscribe);\n };\n\n subscribeOptions?.signal?.addEventListener('abort', unsubscribe, { once: true });\n subscribers.add(listener);\n\n if (subscribeOptions?.immediate) dispatch(listener);\n\n return unsubscribe;\n },\n [Symbol.dispose]: dispose,\n translate(key: string, translateOptions = {}) {\n return snapshot.translator.translateDynamic(key, translateOptions);\n },\n translateDynamic(key, translateOptions) {\n return snapshot.translator.translateDynamic(key, translateOptions);\n },\n } as TranslationStore<C>;\n}\n\nexport function hydrateTranslationStore<C extends Catalog>(\n state: TranslationState<C>,\n options?: Omit<TranslationStoreOptions<C>, 'locale' | 'catalogs'>,\n): TranslationStore<C> {\n if (state.version !== 3) {\n throw new LinguaInvalidStateError(`Unsupported lingua state version: ${String(state.version)}.`);\n }\n\n return createTranslationStore({ ...options, catalogs: state.catalogs, locale: state.locale });\n}\n"],"mappings":";;;;;;AA0BA,SAAgB,EAA0C,GAA0D;CAClH,IAAM,IAAW,EAAmB,EAAQ,QAAQ,GAC9C,IAAW,EAAQ,UACnB,KAAmB,MAAM,QAAQ,CAAQ,IAAI,IAAW,IAAW,CAAC,CAAQ,IAAI,CAAC,EAAA,CAAG,IAAI,CAAe,GACvG,IAAa,IAAI,gBAAgB,GACjC,oBAAc,IAAI,IAAgD,GACpE,IAAW,IACX,IAAS,EAAgB,EAAQ,UAAU,IAAI,GAC/C,IAAW,GAET,WAA+C;EACnD;EACA;EACA,YAAY,EAAgC,EAAS,WAAW,GAAG;GAAE,GAAG;GAAS;GAAU;EAAO,CAAC;CACrG,IACI,IAAW,EAAc,GAEvB,UAAyB;EAC7B,IAAI,GAAU,MAAM,IAAI,EAAoB;CAC9C,GAEM,UAAsB;EACtB,MAEJ,IAAW,IACX,EAAY,MAAM,GAClB,EAAW,MAAM;CACnB,GAEM,KAAY,MAA2D;EAC3E,IAAI;GACF,EAAS,CAAQ;EACnB,QAAgB,CAEhB;CACF,GAEM,UAAqB;EAEzB,AADA,KACA,IAAW,EAAc;EAEzB,KAAK,IAAM,KAAY,CAAC,GAAG,CAAW,GAAG,EAAS,CAAQ;CAC5D,GAEM,KAAY,MAA+B,EAAY,GAAQ,CAAe,CAAC,CAAC,SAAS,CAAS;CAExG,OAAO;EACL,IAAI,iBAAiB;GACnB,OAAO,EAAW;EACpB;EACA;EACA,IAAI,WAAW;GACb,OAAO;EACT;EACA,cAAc;GACZ,OAAO;EACT;EACA,SAAS,GAAa;GACpB,OAAO,CAAC,KAAY,EAAS,SAAS,GAAa,UAAU,CAAM;EACrE;EACA,MAAM,KAAK,GAAa;GACtB,EAAW;GAEX,IAAM,IAAe,EAAgB,GAAa,UAAU,CAAM,GAC5D,IAAU,MAAM,EAAS,KAAK,CAAY;GAEhD,AAAI,CAAC,KAAY,KAAW,EAAS,CAAY,KAAG,EAAO;EAC7D;EACA,IAAI,SAAS;GACX,OAAO;EACT;EACA,SAAS,GAAa,GAAkB;GACtC,OAAO,EAAS,WAAW,gBAAgB,GAAK,CAAgB;EAClE;EACA,gBAAgB,GAAK,GAAkB;GACrC,OAAO,EAAS,WAAW,gBAAgB,GAAK,CAAgB;EAClE;EACA,YAAY;GAGV,OAFA,EAAW,GAEJ,EAAS,MAAM,CAAM;EAC9B;EACA,MAAM,UAAU,GAAY;GAC1B,EAAW;GAEX,IAAM,IAAO,EAAgB,CAAU;GAEnC,MAAS,MAEb,IAAS,GACT,EAAO;EACT;EACA,UAAU,GAAU,GAAkB;GAGpC,IAFA,EAAW,GAEP,GAAkB,QAAQ,SAAS,aAAa,CAAC;GAErD,IAAM,UAA0B;IAE9B,AADA,EAAY,OAAO,CAAQ,GAC3B,GAAkB,QAAQ,oBAAoB,SAAS,CAAW;GACpE;GAOA,OALA,GAAkB,QAAQ,iBAAiB,SAAS,GAAa,EAAE,MAAM,GAAK,CAAC,GAC/E,EAAY,IAAI,CAAQ,GAEpB,GAAkB,aAAW,EAAS,CAAQ,GAE3C;EACT;GACC,OAAO,UAAU;EAClB,UAAU,GAAa,IAAmB,CAAC,GAAG;GAC5C,OAAO,EAAS,WAAW,iBAAiB,GAAK,CAAgB;EACnE;EACA,iBAAiB,GAAK,GAAkB;GACtC,OAAO,EAAS,WAAW,iBAAiB,GAAK,CAAgB;EACnE;CACF;AACF;AAEA,SAAgB,EACd,GACA,GACqB;CACrB,IAAI,EAAM,YAAY,GACpB,MAAM,IAAI,EAAwB,qCAAqC,OAAO,EAAM,OAAO,EAAE,EAAE;CAGjG,OAAO,EAAuB;EAAE,GAAG;EAAS,UAAU,EAAM;EAAU,QAAQ,EAAM;CAAO,CAAC;AAC9F"}
1
+ {"version":3,"file":"i18n.js","names":[],"sources":["../src/i18n.ts"],"sourcesContent":["import { error as logError } from './_dev';\nimport { canonicalLocale, localeChain } from './_locale';\nimport { createCatalogStore } from './_resources';\nimport { LinguaDisposedError, LinguaInvalidStateError, LinguaMissingCatalogError } from './errors';\nimport { createTranslatorFromCompiled, type Translator } from './translator';\nimport type { Catalog, I18nOptions, Locale, SubscribeOptions, TranslationState } from './types';\n\nexport type I18nSnapshot<C extends Catalog = Catalog> = {\n readonly locale: Locale;\n readonly revision: number;\n readonly translator: Translator<C>;\n};\n\nexport type I18n<C extends Catalog = Catalog> = Translator<C> & {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n getSnapshot(): I18nSnapshot<C>;\n isLoaded(options?: { locale?: Locale }): boolean;\n load(options?: { locale?: Locale }): Promise<void>;\n serialize(): TranslationState<C>;\n setLocale(locale: Locale): Promise<void>;\n subscribe(listener: (snapshot: I18nSnapshot<C>) => void, options?: SubscribeOptions): () => void;\n};\n\nexport function createI18n<C extends Catalog>(options: I18nOptions<C>): I18n<C> {\n if (options.state && options.state.version !== 4) {\n throw new LinguaInvalidStateError(`Unsupported lingua state version: ${String(options.state.version)}.`);\n }\n\n const fallback = options.fallback;\n const fallbackLocales = (Array.isArray(fallback) ? fallback : fallback ? [fallback] : []).map(canonicalLocale);\n const controller = new AbortController();\n const subscribers = new Set<(snapshot: I18nSnapshot<C>) => void>();\n let disposed = false;\n let locale = canonicalLocale(options.locale ?? options.state?.locale ?? 'en');\n let revision = 0;\n let transition = 0;\n\n const catalogs = createCatalogStore<C>({ catalogs: options.catalogs, loadCatalog: options.loadCatalog });\n\n // Hydrate from serialized state (SSR).\n if (options.state) {\n for (const [stateLocale, catalog] of Object.entries(options.state.catalogs)) {\n catalogs.hydrate(stateLocale, catalog);\n }\n }\n\n const loadTargets = async (target: Locale): Promise<readonly Locale[]> => {\n const changed: Locale[] = [];\n\n for (const candidate of new Set([target, ...fallbackLocales])) {\n if (await catalogs.load(candidate)) changed.push(candidate);\n }\n\n return changed;\n };\n\n const buildSnapshot = (): I18nSnapshot<C> => {\n const ready = localeChain(locale, fallbackLocales).some(catalogs.isLoaded);\n const missing = ready\n ? options.missing\n : () => {\n throw new LinguaMissingCatalogError(\n `No catalog loaded for locale \"${locale}\". Call load() before translating.`,\n );\n };\n\n return {\n locale,\n revision,\n translator: createTranslatorFromCompiled<C>(catalogs.catalogMap(), { fallback, locale, missing }),\n };\n };\n let snapshot = buildSnapshot();\n\n const assertLive = (): void => {\n if (disposed) throw new LinguaDisposedError();\n };\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n subscribers.clear();\n controller.abort();\n };\n\n const dispatch = (listener: (next: I18nSnapshot<C>) => void): void => {\n try {\n listener(snapshot);\n } catch (error) {\n logError('subscriber error', error);\n }\n };\n\n const notify = (): void => {\n revision++;\n snapshot = buildSnapshot();\n\n for (const listener of [...subscribers]) dispatch(listener);\n };\n\n const relevant = (candidate: Locale): boolean => localeChain(locale, fallbackLocales).includes(candidate);\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n dispose,\n get disposed() {\n return disposed;\n },\n getSnapshot() {\n return snapshot;\n },\n isLoaded(loadOptions) {\n return !disposed && catalogs.isLoaded(loadOptions?.locale ?? locale);\n },\n async load(loadOptions) {\n assertLive();\n\n const targetLocale = canonicalLocale(loadOptions?.locale ?? locale);\n const changed = await loadTargets(targetLocale);\n\n assertLive();\n if (changed.some(relevant)) notify();\n },\n get locale() {\n return locale;\n },\n parts(key: string, translateOptions) {\n return snapshot.translator.partsDynamic(key, translateOptions);\n },\n partsDynamic(key, translateOptions) {\n return snapshot.translator.partsDynamic(key, translateOptions);\n },\n serialize() {\n assertLive();\n\n return catalogs.state(locale);\n },\n async setLocale(nextLocale) {\n assertLive();\n\n const next = canonicalLocale(nextLocale);\n const request = ++transition;\n const changed = await loadTargets(next);\n\n assertLive();\n if (request !== transition) return;\n\n if (next === locale) {\n if (changed.some(relevant)) notify();\n\n return;\n }\n\n locale = next;\n notify();\n },\n subscribe(listener, subscribeOptions) {\n assertLive();\n\n if (subscribeOptions?.signal?.aborted) return () => {};\n\n const unsubscribe = (): void => {\n subscribers.delete(listener);\n subscribeOptions?.signal?.removeEventListener('abort', unsubscribe);\n };\n\n subscribeOptions?.signal?.addEventListener('abort', unsubscribe, { once: true });\n subscribers.add(listener);\n\n if (subscribeOptions?.immediate) dispatch(listener);\n\n return unsubscribe;\n },\n [Symbol.dispose]: dispose,\n translate(key: string, translateOptions = {}) {\n return snapshot.translator.translateDynamic(key, translateOptions);\n },\n translateDynamic(key, translateOptions) {\n return snapshot.translator.translateDynamic(key, translateOptions);\n },\n } as I18n<C>;\n}\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./catalog.cjs"),n=require("./translator.cjs"),r=require("./i18n.cjs");exports.LinguaDisposedError=e.LinguaDisposedError,exports.LinguaError=e.LinguaError,exports.LinguaInvalidCatalogError=e.LinguaInvalidCatalogError,exports.LinguaInvalidLocaleError=e.LinguaInvalidLocaleError,exports.LinguaInvalidPluralCountError=e.LinguaInvalidPluralCountError,exports.LinguaInvalidStateError=e.LinguaInvalidStateError,exports.LinguaMissingCatalogError=e.LinguaMissingCatalogError,exports.catalogKeys=t.catalogKeys,exports.createCatalogTranslator=n.createCatalogTranslator,exports.createTranslationStore=r.createTranslationStore,exports.createTranslator=n.createTranslator,exports.hydrateTranslationStore=r.hydrateTranslationStore;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./catalog.cjs"),n=require("./translator.cjs"),r=require("./i18n.cjs");exports.LinguaDisposedError=e.LinguaDisposedError,exports.LinguaError=e.LinguaError,exports.LinguaInvalidCatalogError=e.LinguaInvalidCatalogError,exports.LinguaInvalidLocaleError=e.LinguaInvalidLocaleError,exports.LinguaInvalidPluralCountError=e.LinguaInvalidPluralCountError,exports.LinguaInvalidStateError=e.LinguaInvalidStateError,exports.LinguaMissingCatalogError=e.LinguaMissingCatalogError,exports.LinguaMissingKeyError=e.LinguaMissingKeyError,exports.LinguaMissingValueError=e.LinguaMissingValueError,exports.catalogKeys=t.catalogKeys,exports.createI18n=r.createI18n,exports.createTranslator=n.createTranslator;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { catalogKeys } from './catalog';
2
- export { LinguaDisposedError, LinguaError, LinguaInvalidCatalogError, LinguaInvalidLocaleError, LinguaInvalidPluralCountError, LinguaInvalidStateError, LinguaMissingCatalogError, } from './errors';
3
- export { createTranslationStore, hydrateTranslationStore, type TranslationSnapshot, type TranslationStore, } from './i18n';
4
- export { createCatalogTranslator, createTranslator, type Translator } from './translator';
5
- export type { Catalog, CatalogLoader, CatalogNode, CatalogSource, CatalogSources, Catalogs, CatalogTranslatorOptions, Locale, MessageKey, PluralCategory, PluralKey, PluralMessage, PluralOptions, SubscribeOptions, TextKey, TranslateOptions, TranslationState, TranslationStoreOptions, TranslatorOptions, Values, } from './types';
2
+ export { LinguaDisposedError, LinguaError, LinguaInvalidCatalogError, LinguaInvalidLocaleError, LinguaInvalidPluralCountError, LinguaInvalidStateError, LinguaMissingCatalogError, LinguaMissingKeyError, LinguaMissingValueError, } from './errors';
3
+ export { createI18n, type I18n, type I18nSnapshot } from './i18n';
4
+ export { createTranslator, type Translator } from './translator';
5
+ export type { Catalog, CatalogNode, Catalogs, I18nOptions, Locale, MessageKey, MissingHandler, MissingInfo, MissingStrategy, Part, PluralCategory, PluralKey, PluralMessage, PluralOptions, SubscribeOptions, TextKey, TextPart, TranslateOptions, TranslationState, TranslatorOptions, ValuePart, Values, } from './types';
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,yBAAyB,EACzB,wBAAwB,EACxB,6BAA6B,EAC7B,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1F,YAAY,EACV,OAAO,EACP,aAAa,EACb,WAAW,EACX,aAAa,EACb,cAAc,EACd,QAAQ,EACR,wBAAwB,EACxB,MAAM,EACN,UAAU,EACV,cAAc,EACd,SAAS,EACT,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,OAAO,EACP,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,MAAM,GACP,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,yBAAyB,EACzB,wBAAwB,EACxB,6BAA6B,EAC7B,uBAAuB,EACvB,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACjE,YAAY,EACV,OAAO,EACP,WAAW,EACX,QAAQ,EACR,WAAW,EACX,MAAM,EACN,UAAU,EACV,cAAc,EACd,WAAW,EACX,eAAe,EACf,IAAI,EACJ,cAAc,EACd,SAAS,EACT,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,OAAO,EACP,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,EACT,MAAM,GACP,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { LinguaDisposedError as e, LinguaError as t, LinguaInvalidCatalogError as n, LinguaInvalidLocaleError as r, LinguaInvalidPluralCountError as i, LinguaInvalidStateError as a, LinguaMissingCatalogError as o } from "./errors.js";
2
- import { catalogKeys as s } from "./catalog.js";
3
- import { createCatalogTranslator as c, createTranslator as l } from "./translator.js";
4
- import { createTranslationStore as u, hydrateTranslationStore as d } from "./i18n.js";
5
- export { e as LinguaDisposedError, t as LinguaError, n as LinguaInvalidCatalogError, r as LinguaInvalidLocaleError, i as LinguaInvalidPluralCountError, a as LinguaInvalidStateError, o as LinguaMissingCatalogError, s as catalogKeys, c as createCatalogTranslator, u as createTranslationStore, l as createTranslator, d as hydrateTranslationStore };
1
+ import { LinguaDisposedError as e, LinguaError as t, LinguaInvalidCatalogError as n, LinguaInvalidLocaleError as r, LinguaInvalidPluralCountError as i, LinguaInvalidStateError as a, LinguaMissingCatalogError as o, LinguaMissingKeyError as s, LinguaMissingValueError as c } from "./errors.js";
2
+ import { catalogKeys as l } from "./catalog.js";
3
+ import { createTranslator as u } from "./translator.js";
4
+ import { createI18n as d } from "./i18n.js";
5
+ export { e as LinguaDisposedError, t as LinguaError, n as LinguaInvalidCatalogError, r as LinguaInvalidLocaleError, i as LinguaInvalidPluralCountError, a as LinguaInvalidStateError, o as LinguaMissingCatalogError, s as LinguaMissingKeyError, c as LinguaMissingValueError, l as catalogKeys, d as createI18n, u as createTranslator };
package/dist/lingua.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=/\{([\p{ID_Continue}-]+)\}/gu;function t(t){let n=[],r=0;for(let i of t.matchAll(e)){let e=i.index??0;e>r&&n.push(t.slice(r,e)),n.push({value:i[1]}),r=e+i[0].length}return r<t.length&&n.push(t.slice(r)),n}function n(e,t,n){return e.map(e=>{if(typeof e==`string`)return e;let r=Object.hasOwn(t,e.value)?t[e.value]:void 0;return r==null?n(e.value):String(r)}).join(``)}function r(e,t,n){let r=[];for(let i of e){if(typeof i==`string`){i!==``&&r.push(i);continue}r.push(Object.hasOwn(t,i.value)?t[i.value]:n(i.value))}return r}var i=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},a=class extends i{constructor(){super(`Operation called on a disposed translation store.`)}},o=class extends i{},s=class extends i{},c=class extends i{},l=class extends i{},u=class extends i{},d=new Set([`__proto__`,`constructor`,`prototype`]);function f(e){return typeof e==`object`&&!!e&&Object.hasOwn(e,`plural`)}function p(e){let n=new Map,r=(e,i)=>{if(typeof e==`string`){n.set(i,{kind:`text`,template:t(e)});return}if(typeof e!=`object`||!e||Array.isArray(e))throw new o(`Catalog node "${i}" must be a string, plural message, or object.`);if(f(e)){if(Reflect.ownKeys(e).some(e=>e!==`plural`))throw new o(`Plural message "${i}" must contain only a "plural" property.`);if(typeof e.plural!=`object`||e.plural===null||Array.isArray(e.plural))throw new o(`Plural message "${i}" must provide an object of string forms.`);let r=new Map;for(let[n,a]of Object.entries(e.plural)){if(typeof a!=`string`)throw new o(`Plural form "${i}.${n}" must be a string.`);r.set(n,t(a))}n.set(i,{forms:r,kind:`plural`});return}for(let[t,n]of Object.entries(e)){if(d.has(t))throw new o(`Catalog key "${t}" is reserved.`);r(n,i?`${i}.${t}`:t)}};for(let[t,n]of Object.entries(e)){if(d.has(t))throw new o(`Catalog key "${t}" is reserved.`);r(n,t)}return n}function m(e){return[...p(typeof e==`object`&&e&&`serialize`in e&&`getSnapshot`in e?e.serialize().catalogs[e.locale]:e).keys()]}var h=new Map;function g(e){try{let[t]=Intl.getCanonicalLocales(e);if(t)return t}catch{}throw new s(`Invalid BCP 47 locale tag: "${e}".`)}function _(e,t){let n=new Set;for(let r of[e,...t]){let e=r.split(`-`);for(let t=e.length;t>0;t--)n.add(e.slice(0,t).join(`-`))}return[...n]}function v(e,t,n){let r=`${e}:${n?`ordinal`:`cardinal`}`,i=h.get(r);return i||(i=new Intl.PluralRules(e,{type:n?`ordinal`:`cardinal`}),h.set(r,i)),i.select(t)}function y(e){let t=new Map,n=new Map,r=new Map;for(let[n,r]of Object.entries(e))t.set(g(n),r);let i=(e,t)=>{n.set(e,{catalog:t,compiled:p(t)})};for(let[e,n]of t)typeof n!=`function`&&i(e,n);return{catalogMap(){return new Map([...n].map(([e,{compiled:t}])=>[e,t]))},isLoaded(e){return n.has(g(e))},load:async e=>{let a=g(e);if(n.has(a))return!1;let o=t.get(a);if(!o)throw new u(`Catalog has no source for locale "${a}".`);if(typeof o!=`function`)return i(a,o),!0;let s=r.get(a);if(s)return await s,!1;let c=o().then(e=>{i(a,e),r.delete(a)},e=>{throw r.delete(a),e});return r.set(a,c),await c,!0},state(e){let t={};for(let[e,{catalog:r}]of n)t[e]=r;return{catalogs:t,locale:e,version:3}}}}function b(e,t={}){let i=g(t.locale??`en`),a=_(i,(Array.isArray(t.fallback)?t.fallback:t.fallback?[t.fallback]:[]).map(g)),o=t.onMissingKey??(e=>e),s=t.onMissingValue??(e=>`{${e}}`),l=t=>{for(let n of a){let r=e.get(n)?.get(t);if(r)return{locale:n,message:r}}},u=(e,t)=>{let n=l(e);if(!n)return;if(n.message.kind===`text`)return`count`in t?void 0:{key:e,template:n.message.template};if(!(`count`in t)||!Number.isFinite(t.count)){if(`count`in t)throw new c("`count` must be a finite number.");return}let r=t.count===0&&!t.ordinal?`zero`:v(n.locale,t.count,t.ordinal??!1),i=n.message.forms.get(r)??n.message.forms.get(`other`);return i?{key:e,template:i}:void 0},d=e=>`count`in e?{count:e.count,...e.values}:e.values??{},f=(e,t)=>{let n=u(e,t);return n?r(n.template,d(t),e=>s(e,n.key,i)):[o(e,i)]},p=(e,t={})=>{let r=u(e,t);return r?n(r.template,d(t),e=>s(e,r.key,i)):o(e,i)};return{locale:i,segments(e,t){return f(e,t)},segmentsDynamic:f,translate(e,t={}){return p(e,t)},translateDynamic:p}}function x(e,t={}){let n=g(t.locale??`en`);return b(new Map([[n,p(e)]]),{...t,locale:n})}function S(e,t){let n=new Map;for(let[t,r]of Object.entries(e))n.set(g(t),p(r));return b(n,t)}function C(e){let t=y(e.catalogs),n=e.fallback,r=(Array.isArray(n)?n:n?[n]:[]).map(g),i=new AbortController,o=new Set,s=!1,c=g(e.locale??`en`),l=0,u=()=>({locale:c,revision:l,translator:b(t.catalogMap(),{...e,fallback:n,locale:c})}),d=u(),f=()=>{if(s)throw new a},p=()=>{s||(s=!0,o.clear(),i.abort())},m=e=>{try{e(d)}catch{}},h=()=>{l++,d=u();for(let e of[...o])m(e)},v=e=>_(c,r).includes(e);return{get disposalSignal(){return i.signal},dispose:p,get disposed(){return s},getSnapshot(){return d},isLoaded(e){return!s&&t.isLoaded(e?.locale??c)},async load(e){f();let n=g(e?.locale??c),r=await t.load(n);!s&&r&&v(n)&&h()},get locale(){return c},segments(e,t){return d.translator.segmentsDynamic(e,t)},segmentsDynamic(e,t){return d.translator.segmentsDynamic(e,t)},serialize(){return f(),t.state(c)},async setLocale(e){f();let t=g(e);t!==c&&(c=t,h())},subscribe(e,t){if(f(),t?.signal?.aborted)return()=>{};let n=()=>{o.delete(e),t?.signal?.removeEventListener(`abort`,n)};return t?.signal?.addEventListener(`abort`,n,{once:!0}),o.add(e),t?.immediate&&m(e),n},[Symbol.dispose]:p,translate(e,t={}){return d.translator.translateDynamic(e,t)},translateDynamic(e,t){return d.translator.translateDynamic(e,t)}}}function w(e,t){if(e.version!==3)throw new l(`Unsupported lingua state version: ${String(e.version)}.`);return C({...t,catalogs:e.catalogs,locale:e.locale})}exports.LinguaDisposedError=a,exports.LinguaError=i,exports.LinguaInvalidCatalogError=o,exports.LinguaInvalidLocaleError=s,exports.LinguaInvalidPluralCountError=c,exports.LinguaInvalidStateError=l,exports.LinguaMissingCatalogError=u,exports.catalogKeys=m,exports.createCatalogTranslator=x,exports.createTranslationStore=C,exports.createTranslator=S,exports.hydrateTranslationStore=w;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=/\{([\p{ID_Continue}-]+)\}/gu;function t(t){let n=[],r=0;for(let i of t.matchAll(e)){let e=i.index??0;e>r&&n.push(t.slice(r,e)),n.push({value:i[1]}),r=e+i[0].length}return r<t.length&&n.push(t.slice(r)),n}function n(e,t,n){return e.map(e=>{if(typeof e==`string`)return e;let r=Object.hasOwn(t,e.value)?t[e.value]:void 0;return r==null?n(e.value):String(r)}).join(``)}function r(e,t,n){let r=[];for(let i of e){if(typeof i==`string`){i!==``&&r.push({type:`text`,value:i});continue}Object.hasOwn(t,i.value)?r.push({type:`value`,value:t[i.value]}):r.push({type:`text`,value:n(i.value)})}return r}var i=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},a=class extends i{constructor(){super(`Operation called on a disposed i18n instance.`)}},o=class extends i{},s=class extends i{},c=class extends i{},l=class extends i{},u=class extends i{},d=class extends i{},f=class extends i{},p=new Set([`__proto__`,`constructor`,`prototype`]);function m(e){return typeof e==`object`&&!!e&&Object.hasOwn(e,`plural`)}function h(e){let n=new Map,r=(e,i)=>{if(typeof e==`string`){n.set(i,{kind:`text`,template:t(e)});return}if(typeof e!=`object`||!e||Array.isArray(e))throw new o(`Catalog node "${i}" must be a string, plural message, or object.`);if(m(e)){if(Reflect.ownKeys(e).some(e=>e!==`plural`))throw new o(`Plural message "${i}" must contain only a "plural" property.`);if(typeof e.plural!=`object`||e.plural===null||Array.isArray(e.plural))throw new o(`Plural message "${i}" must provide an object of string forms.`);let r=new Map;for(let[n,a]of Object.entries(e.plural)){if(typeof a!=`string`)throw new o(`Plural form "${i}.${n}" must be a string.`);r.set(n,t(a))}n.set(i,{forms:r,kind:`plural`});return}for(let[t,n]of Object.entries(e)){if(p.has(t))throw new o(`Catalog key "${t}" is reserved.`);r(n,i?`${i}.${t}`:t)}};for(let[t,n]of Object.entries(e)){if(p.has(t))throw new o(`Catalog key "${t}" is reserved.`);r(n,t)}return n}function g(e){if(typeof e==`object`&&e&&`serialize`in e&&`getSnapshot`in e){let t=e,n=t.serialize().catalogs[t.locale];if(!n)throw new u(`No catalog loaded for locale "${t.locale}".`);return[...h(n).keys()]}return[...h(e).keys()]}var _=new Map;function v(e){try{let[t]=Intl.getCanonicalLocales(e);if(t)return t}catch{}throw new s(`Invalid BCP 47 locale tag: "${e}".`)}function y(e,t){let n=new Set;for(let r of[e,...t]){let e=r.split(`-`);for(let t=e.length;t>0;t--)n.add(e.slice(0,t).join(`-`))}return[...n]}function b(e,t,n){let r=`${e}:${n?`ordinal`:`cardinal`}`,i=_.get(r);return i||(i=new Intl.PluralRules(e,{type:n?`ordinal`:`cardinal`}),_.set(r,i)),i.select(t)}function x(e){let t=new Map,n=new Map,r=(e,n)=>{t.set(v(e),{catalog:n,compiled:h(n)})};for(let[t,n]of Object.entries(e.catalogs??{}))r(t,n);return{catalogMap(){return new Map([...t].map(([e,{compiled:t}])=>[e,t]))},hydrate:r,isLoaded(e){return t.has(v(e))},load:async i=>{let a=v(i);if(t.has(a))return!1;let o=n.get(a);if(o)return await o,!1;if(!e.loadCatalog)throw new u(`No catalog source provided for locale "${a}".`);let s=Promise.resolve(e.loadCatalog(a)).then(e=>{r(a,e),n.delete(a)},e=>{throw n.delete(a),e});return n.set(a,s),await s,!0},state(e){let n={};for(let[e,{catalog:r}]of t)n[e]=r;return{catalogs:n,locale:e,version:4}}}}function S(e,t){if(e===`throw`)throw t.name?new f(`Missing interpolation value "${t.name}" for key "${t.key}" in locale "${t.locale}".`):new d(`Missing translation key "${t.key}" in locale "${t.locale}".`);return typeof e==`function`?e(t):t.name?`{${t.name}}`:t.key}function C(e,t={}){let i=v(t.locale??`en`),a=y(i,(Array.isArray(t.fallback)?t.fallback:t.fallback?[t.fallback]:[]).map(v)),o=t.missing,s=e=>S(o,{key:e,locale:i}),l=(e,t)=>S(o,{key:t,locale:i,name:e}),u=t=>{for(let n of a){let r=e.get(n)?.get(t);if(r)return{locale:n,message:r}}},d=(e,t)=>{let n=u(e);if(!n)return;if(n.message.kind===`text`)return`count`in t?void 0:{key:e,template:n.message.template};if(!(`count`in t)||!Number.isFinite(t.count)){if(`count`in t)throw new c("`count` must be a finite number.");return}let r=t.count===0&&!t.ordinal?`zero`:b(n.locale,t.count,t.ordinal??!1),i=n.message.forms.get(r)??n.message.forms.get(`other`);return i?{key:e,template:i}:void 0},f=e=>`count`in e?{count:e.count,...e.values}:e.values??{},p=(e,t)=>{let n=d(e,t);return n?r(n.template,f(t),e=>l(e,n.key)):[{type:`text`,value:s(e)}]},m=(e,t={})=>{let r=d(e,t);return r?n(r.template,f(t),e=>l(e,r.key)):s(e)};return{locale:i,parts(e,t){return p(e,t)},partsDynamic:p,translate(e,t={}){return m(e,t)},translateDynamic:m}}function w(e,t){let n=v(t?.locale??`en`);return C(new Map([[n,h(e)]]),{...t,locale:n})}function T(e){if(e.state&&e.state.version!==4)throw new l(`Unsupported lingua state version: ${String(e.state.version)}.`);let t=e.fallback,n=(Array.isArray(t)?t:t?[t]:[]).map(v),r=new AbortController,i=new Set,o=!1,s=v(e.locale??e.state?.locale??`en`),c=0,d=0,f=x({catalogs:e.catalogs,loadCatalog:e.loadCatalog});if(e.state)for(let[t,n]of Object.entries(e.state.catalogs))f.hydrate(t,n);let p=async e=>{let t=[];for(let r of new Set([e,...n]))await f.load(r)&&t.push(r);return t},m=()=>{let r=y(s,n).some(f.isLoaded)?e.missing:()=>{throw new u(`No catalog loaded for locale "${s}". Call load() before translating.`)};return{locale:s,revision:c,translator:C(f.catalogMap(),{fallback:t,locale:s,missing:r})}},h=m(),g=()=>{if(o)throw new a},_=()=>{o||(o=!0,i.clear(),r.abort())},b=e=>{try{e(h)}catch{}},S=()=>{c++,h=m();for(let e of[...i])b(e)},w=e=>y(s,n).includes(e);return{get disposalSignal(){return r.signal},dispose:_,get disposed(){return o},getSnapshot(){return h},isLoaded(e){return!o&&f.isLoaded(e?.locale??s)},async load(e){g();let t=v(e?.locale??s),n=await p(t);g(),n.some(w)&&S()},get locale(){return s},parts(e,t){return h.translator.partsDynamic(e,t)},partsDynamic(e,t){return h.translator.partsDynamic(e,t)},serialize(){return g(),f.state(s)},async setLocale(e){g();let t=v(e),n=++d,r=await p(t);if(g(),n===d){if(t===s){r.some(w)&&S();return}s=t,S()}},subscribe(e,t){if(g(),t?.signal?.aborted)return()=>{};let n=()=>{i.delete(e),t?.signal?.removeEventListener(`abort`,n)};return t?.signal?.addEventListener(`abort`,n,{once:!0}),i.add(e),t?.immediate&&b(e),n},[Symbol.dispose]:_,translate(e,t={}){return h.translator.translateDynamic(e,t)},translateDynamic(e,t){return h.translator.translateDynamic(e,t)}}}exports.LinguaDisposedError=a,exports.LinguaError=i,exports.LinguaInvalidCatalogError=o,exports.LinguaInvalidLocaleError=s,exports.LinguaInvalidPluralCountError=c,exports.LinguaInvalidStateError=l,exports.LinguaMissingCatalogError=u,exports.LinguaMissingKeyError=d,exports.LinguaMissingValueError=f,exports.catalogKeys=g,exports.createI18n=T,exports.createTranslator=w;
2
2
  //# sourceMappingURL=lingua.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"lingua.cjs","names":[],"sources":["../src/_template.ts","../src/errors.ts","../src/_catalog.ts","../src/catalog.ts","../src/_dev.ts","../src/_locale.ts","../src/_resources.ts","../src/translator.ts","../src/i18n.ts"],"sourcesContent":["export type TemplatePart = string | { readonly value: string };\nexport type Template = readonly TemplatePart[];\n\nconst interpolation = /\\{([\\p{ID_Continue}-]+)\\}/gu;\n\nexport function compileTemplate(value: string): Template {\n const parts: TemplatePart[] = [];\n let offset = 0;\n\n for (const match of value.matchAll(interpolation)) {\n const index = match.index ?? 0;\n\n if (index > offset) parts.push(value.slice(offset, index));\n\n parts.push({ value: match[1] });\n offset = index + match[0].length;\n }\n\n if (offset < value.length) parts.push(value.slice(offset));\n\n return parts;\n}\n\nexport function renderText(\n parts: Template,\n values: Record<string, unknown>,\n missing: (name: string) => string,\n): string {\n return parts\n .map((part) => {\n if (typeof part === 'string') return part;\n\n const value = Object.hasOwn(values, part.value) ? values[part.value] : undefined;\n\n return value == null ? missing(part.value) : String(value);\n })\n .join('');\n}\n\nexport function renderSegments<V>(\n parts: Template,\n values: Record<string, V | number>,\n missing: (name: string) => string,\n): Array<string | number | V> {\n const result: Array<string | number | V> = [];\n\n for (const part of parts) {\n if (typeof part === 'string') {\n if (part !== '') result.push(part);\n\n continue;\n }\n\n result.push(Object.hasOwn(values, part.value) ? values[part.value]! : missing(part.value));\n }\n\n return result;\n}\n","export class LinguaError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class LinguaDisposedError extends LinguaError {\n constructor() {\n super('Operation called on a disposed translation store.');\n }\n}\n\nexport class LinguaInvalidCatalogError extends LinguaError {}\nexport class LinguaInvalidLocaleError extends LinguaError {}\nexport class LinguaInvalidPluralCountError extends LinguaError {}\nexport class LinguaInvalidStateError extends LinguaError {}\nexport class LinguaMissingCatalogError extends LinguaError {}\n","import { compileTemplate, type Template } from './_template';\nimport { LinguaInvalidCatalogError } from './errors';\nimport type { Catalog, CatalogNode, PluralMessage } from './types';\n\nconst unsafeKeys = new Set(['__proto__', 'constructor', 'prototype']);\n\nexport type CompiledText = { readonly kind: 'text'; readonly template: Template };\nexport type CompiledPlural = { readonly forms: ReadonlyMap<string, Template>; readonly kind: 'plural' };\nexport type CompiledMessage = CompiledPlural | CompiledText;\nexport type CompiledCatalog = ReadonlyMap<string, CompiledMessage>;\n\nexport function isPluralMessage(node: CatalogNode): node is PluralMessage {\n return typeof node === 'object' && node !== null && Object.hasOwn(node, 'plural');\n}\n\n/** Compile explicit catalog nodes once. Nested objects only group keys; plural intent is never inferred. */\nexport function compileCatalog(catalog: Catalog): CompiledCatalog {\n const messages = new Map<string, CompiledMessage>();\n\n const visit = (node: CatalogNode, prefix: string): void => {\n if (typeof node === 'string') {\n messages.set(prefix, { kind: 'text', template: compileTemplate(node) });\n\n return;\n }\n\n if (typeof node !== 'object' || node === null || Array.isArray(node)) {\n throw new LinguaInvalidCatalogError(`Catalog node \"${prefix}\" must be a string, plural message, or object.`);\n }\n\n if (isPluralMessage(node)) {\n if (Reflect.ownKeys(node).some((key) => key !== 'plural')) {\n throw new LinguaInvalidCatalogError(`Plural message \"${prefix}\" must contain only a \"plural\" property.`);\n }\n\n if (typeof node.plural !== 'object' || node.plural === null || Array.isArray(node.plural)) {\n throw new LinguaInvalidCatalogError(`Plural message \"${prefix}\" must provide an object of string forms.`);\n }\n\n const forms = new Map<string, Template>();\n\n for (const [form, template] of Object.entries(node.plural)) {\n if (typeof template !== 'string') {\n throw new LinguaInvalidCatalogError(`Plural form \"${prefix}.${form}\" must be a string.`);\n }\n\n forms.set(form, compileTemplate(template));\n }\n\n messages.set(prefix, { forms, kind: 'plural' });\n\n return;\n }\n\n for (const [key, value] of Object.entries(node)) {\n if (unsafeKeys.has(key)) {\n throw new LinguaInvalidCatalogError(`Catalog key \"${key}\" is reserved.`);\n }\n\n visit(value, prefix ? `${prefix}.${key}` : key);\n }\n };\n\n for (const [key, value] of Object.entries(catalog)) {\n if (unsafeKeys.has(key)) throw new LinguaInvalidCatalogError(`Catalog key \"${key}\" is reserved.`);\n\n visit(value, key);\n }\n\n return messages;\n}\n","import { compileCatalog } from './_catalog';\nimport type { TranslationStore } from './i18n';\nimport type { Catalog, TextKey } from './types';\n\n/** Enumerate every message key in a catalog as a dotted path.\n *\n * Traverses nested grouping objects and explicit `{ plural: ... }` messages,\n * producing the same dotted paths that `TextKey<C>` represents at the type\n * level. Use this to derive key arrays from the catalog itself instead of\n * maintaining a parallel list that can go stale.\n *\n * Pass a `TranslationStore` to enumerate keys from its current locale catalog\n * without specifying a locale explicitly.\n *\n * @example\n * ```ts\n * const messages = {\n * nav: { home: '...', settings: '...' },\n * };\n * const keys = catalogKeys(messages); // ['nav.home', 'nav.settings']\n *\n * // From a translation store — uses current locale's catalog\n * const i18n = createTranslationStore({ catalogs: { en: messages }, locale: 'en' });\n * const allKeys = catalogKeys(i18n);\n * ```\n */\nexport function catalogKeys<C extends Catalog>(store: TranslationStore<C>): ReadonlyArray<TextKey<C>>;\nexport function catalogKeys<C extends Catalog>(catalog: C): ReadonlyArray<TextKey<C>>;\nexport function catalogKeys(source: unknown): ReadonlyArray<TextKey<Catalog>> {\n const catalog =\n typeof source === 'object' && source !== null && 'serialize' in source && 'getSnapshot' in source\n ? (source as TranslationStore).serialize().catalogs[(source as TranslationStore).locale]\n : (source as Catalog);\n\n return [...compileCatalog(catalog).keys()] as unknown as ReadonlyArray<TextKey<Catalog>>;\n}\n","const isDev = !(globalThis as { __LINGUA_PROD__?: boolean }).__LINGUA_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/lingua] ${msg}`);\n}\n\n/** @internal */\nexport function error(msg: string, ...args: unknown[]): void {\n if (isDev) console.error(`[@vielzeug/lingua] ${msg}`, ...args);\n}\n\n/** @internal — Run fn only in dev builds. Use when dev-only logic goes beyond a single warn() / error() call. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n","import { LinguaInvalidLocaleError } from './errors';\nimport type { Locale } from './types';\n\nconst pluralRules = new Map<string, Intl.PluralRules>();\n\nexport function canonicalLocale(locale: string): Locale {\n try {\n const [canonical] = Intl.getCanonicalLocales(locale);\n\n if (canonical) return canonical;\n } catch {\n // Error below names the failed public input.\n }\n\n throw new LinguaInvalidLocaleError(`Invalid BCP 47 locale tag: \"${locale}\".`);\n}\n\nexport function localeChain(locale: Locale, fallback: readonly Locale[]): readonly Locale[] {\n const chain = new Set<Locale>();\n\n for (const candidate of [locale, ...fallback]) {\n const parts = candidate.split('-');\n\n for (let length = parts.length; length > 0; length--) {\n chain.add(parts.slice(0, length).join('-'));\n }\n }\n\n return [...chain];\n}\n\nexport function pluralCategory(locale: Locale, count: number, ordinal: boolean): Intl.LDMLPluralRule {\n const key = `${locale}:${ordinal ? 'ordinal' : 'cardinal'}`;\n let rules = pluralRules.get(key);\n\n if (!rules) {\n rules = new Intl.PluralRules(locale, { type: ordinal ? 'ordinal' : 'cardinal' });\n pluralRules.set(key, rules);\n }\n\n return rules.select(count);\n}\n","import { type CompiledCatalog, compileCatalog } from './_catalog';\nimport { canonicalLocale } from './_locale';\nimport { LinguaMissingCatalogError } from './errors';\nimport type { Catalog, CatalogSources, Catalogs, Locale, TranslationState } from './types';\n\n/** One catalog state machine owns static sources, lazy sources, and in-flight work. */\nexport function createCatalogStore<C extends Catalog>(sources: CatalogSources<C>) {\n const definitions = new Map<Locale, C | (() => Promise<C>)>();\n const loaded = new Map<Locale, { readonly catalog: C; readonly compiled: CompiledCatalog }>();\n const tasks = new Map<Locale, Promise<void>>();\n\n for (const [locale, source] of Object.entries(sources)) definitions.set(canonicalLocale(locale), source);\n\n const add = (locale: Locale, catalog: C): void => {\n loaded.set(locale, { catalog, compiled: compileCatalog(catalog) });\n };\n\n for (const [locale, source] of definitions) {\n if (typeof source !== 'function') add(locale, source);\n }\n\n const load = async (requestedLocale: Locale): Promise<boolean> => {\n const locale = canonicalLocale(requestedLocale);\n\n if (loaded.has(locale)) return false;\n\n const source = definitions.get(locale);\n\n if (!source) throw new LinguaMissingCatalogError(`Catalog has no source for locale \"${locale}\".`);\n\n if (typeof source !== 'function') {\n add(locale, source);\n\n return true;\n }\n\n const existing = tasks.get(locale);\n\n if (existing) {\n await existing;\n\n return false;\n }\n\n const task = source().then(\n (catalog) => {\n add(locale, catalog);\n tasks.delete(locale);\n },\n (error: unknown) => {\n tasks.delete(locale);\n throw error;\n },\n );\n\n tasks.set(locale, task);\n await task;\n\n return true;\n };\n\n return {\n catalogMap(): ReadonlyMap<Locale, CompiledCatalog> {\n return new Map([...loaded].map(([locale, { compiled }]) => [locale, compiled]));\n },\n isLoaded(locale: Locale): boolean {\n return loaded.has(canonicalLocale(locale));\n },\n load,\n state(locale: Locale): TranslationState<C> {\n const catalogs: Catalogs<C> = {};\n\n for (const [loadedLocale, { catalog }] of loaded) catalogs[loadedLocale] = catalog;\n\n return { catalogs, locale, version: 3 };\n },\n };\n}\n","import { type CompiledCatalog, type CompiledMessage, compileCatalog } from './_catalog';\nimport { canonicalLocale, localeChain, pluralCategory } from './_locale';\nimport { renderSegments, renderText, type Template } from './_template';\nimport { LinguaInvalidPluralCountError } from './errors';\nimport type {\n Catalog,\n Catalogs,\n CatalogTranslatorOptions,\n Locale,\n PluralKey,\n PluralOptions,\n TextKey,\n TranslateOptions,\n TranslatorOptions,\n} from './types';\n\nexport type Translator<C extends Catalog = Catalog> = {\n readonly locale: Locale;\n segments<V>(key: TextKey<C>, options: TranslateOptions & { values: Record<string, V> }): Array<string | V>;\n segments<V>(key: PluralKey<C>, options: PluralOptions & { values?: Record<string, V> }): Array<string | number | V>;\n segmentsDynamic<V>(\n key: string,\n options: (TranslateOptions | PluralOptions) & { values?: Record<string, V> },\n ): Array<string | number | V>;\n translate(key: TextKey<C>, options?: TranslateOptions): string;\n translate(key: PluralKey<C>, options: PluralOptions): string;\n translateDynamic(key: string, options?: TranslateOptions | PluralOptions): string;\n};\n\ntype ResolvedMessage = { readonly locale: Locale; readonly message: CompiledMessage };\n\nexport function createTranslatorFromCompiled<C extends Catalog>(\n catalogs: ReadonlyMap<Locale, CompiledCatalog>,\n options: TranslatorOptions = {},\n): Translator<C> {\n const locale = canonicalLocale(options.locale ?? 'en');\n const fallback = (\n Array.isArray(options.fallback) ? options.fallback : options.fallback ? [options.fallback] : []\n ).map(canonicalLocale);\n const chain = localeChain(locale, fallback);\n const missingKey = options.onMissingKey ?? ((key: string) => key);\n const missingValue = options.onMissingValue ?? ((name: string) => `{${name}}`);\n\n const resolve = (key: string): ResolvedMessage | undefined => {\n for (const candidate of chain) {\n const message = catalogs.get(candidate)?.get(key);\n\n if (message) return { locale: candidate, message };\n }\n\n return undefined;\n };\n\n const templateFor = (\n key: string,\n options: TranslateOptions | PluralOptions,\n ): { key: string; template: Template } | undefined => {\n const found = resolve(key);\n\n if (!found) return undefined;\n\n if (found.message.kind === 'text') {\n if ('count' in options) return undefined;\n\n return { key, template: found.message.template };\n }\n\n if (!('count' in options) || !Number.isFinite(options.count)) {\n if ('count' in options) throw new LinguaInvalidPluralCountError('`count` must be a finite number.');\n\n return undefined;\n }\n\n const category =\n options.count === 0 && !options.ordinal\n ? 'zero'\n : pluralCategory(found.locale, options.count, options.ordinal ?? false);\n const template = found.message.forms.get(category) ?? found.message.forms.get('other');\n\n return template ? { key, template } : undefined;\n };\n\n const valuesFor = (options: TranslateOptions | PluralOptions): Record<string, unknown> =>\n 'count' in options ? { count: options.count, ...options.values } : (options.values ?? {});\n\n const segmentsDynamic = <V>(\n key: string,\n options: (TranslateOptions | PluralOptions) & { values?: Record<string, V> },\n ): Array<string | number | V> => {\n const found = templateFor(key, options);\n\n if (!found) return [missingKey(key, locale)];\n\n return renderSegments(found.template, valuesFor(options) as Record<string, V | number>, (name) =>\n missingValue(name, found.key, locale),\n );\n };\n\n const translateDynamic = (key: string, options: TranslateOptions | PluralOptions = {}): string => {\n const found = templateFor(key, options);\n\n if (!found) return missingKey(key, locale);\n\n return renderText(found.template, valuesFor(options), (name) => missingValue(name, found.key, locale));\n };\n\n return {\n locale,\n segments(key: string, options: (TranslateOptions | PluralOptions) & { values?: Record<string, unknown> }) {\n return segmentsDynamic(key, options);\n },\n segmentsDynamic,\n translate(key: string, options: TranslateOptions | PluralOptions = {}) {\n return translateDynamic(key, options);\n },\n translateDynamic,\n } as Translator<C>;\n}\n\n/** Creates a fixed-locale translator from one catalog. Lingua snapshots catalog messages during construction. */\nexport function createCatalogTranslator<C extends Catalog>(\n catalog: C,\n options: CatalogTranslatorOptions = {},\n): Translator<C> {\n const locale = canonicalLocale(options.locale ?? 'en');\n const compiled = new Map<Locale, CompiledCatalog>([[locale, compileCatalog(catalog)]]);\n\n return createTranslatorFromCompiled<C>(compiled, { ...options, locale });\n}\n\nexport function createTranslator<C extends Catalog>(catalogs: Catalogs<C>, options?: TranslatorOptions): Translator<C> {\n const compiled = new Map<Locale, CompiledCatalog>();\n\n for (const [locale, catalog] of Object.entries(catalogs)) {\n compiled.set(canonicalLocale(locale), compileCatalog(catalog));\n }\n\n return createTranslatorFromCompiled<C>(compiled, options);\n}\n","import { error as logError } from './_dev';\nimport { canonicalLocale, localeChain } from './_locale';\nimport { createCatalogStore } from './_resources';\nimport { LinguaDisposedError, LinguaInvalidStateError } from './errors';\nimport { createTranslatorFromCompiled, type Translator } from './translator';\nimport type { Catalog, Locale, SubscribeOptions, TranslationState, TranslationStoreOptions } from './types';\n\nexport type TranslationSnapshot<C extends Catalog = Catalog> = {\n readonly locale: Locale;\n readonly revision: number;\n readonly translator: Translator<C>;\n};\n\nexport type TranslationStore<C extends Catalog = Catalog> = Translator<C> & {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n getSnapshot(): TranslationSnapshot<C>;\n isLoaded(options?: { locale?: Locale }): boolean;\n load(options?: { locale?: Locale }): Promise<void>;\n serialize(): TranslationState<C>;\n setLocale(locale: Locale): Promise<void>;\n subscribe(listener: (snapshot: TranslationSnapshot<C>) => void, options?: SubscribeOptions): () => void;\n};\n\nexport function createTranslationStore<C extends Catalog>(options: TranslationStoreOptions<C>): TranslationStore<C> {\n const catalogs = createCatalogStore(options.catalogs);\n const fallback = options.fallback;\n const fallbackLocales = (Array.isArray(fallback) ? fallback : fallback ? [fallback] : []).map(canonicalLocale);\n const controller = new AbortController();\n const subscribers = new Set<(snapshot: TranslationSnapshot<C>) => void>();\n let disposed = false;\n let locale = canonicalLocale(options.locale ?? 'en');\n let revision = 0;\n\n const buildSnapshot = (): TranslationSnapshot<C> => ({\n locale,\n revision,\n translator: createTranslatorFromCompiled<C>(catalogs.catalogMap(), { ...options, fallback, locale }),\n });\n let snapshot = buildSnapshot();\n\n const assertLive = (): void => {\n if (disposed) throw new LinguaDisposedError();\n };\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n subscribers.clear();\n controller.abort();\n };\n\n const dispatch = (listener: (next: TranslationSnapshot<C>) => void): void => {\n try {\n listener(snapshot);\n } catch (error) {\n logError('subscriber error', error);\n }\n };\n\n const notify = (): void => {\n revision++;\n snapshot = buildSnapshot();\n\n for (const listener of [...subscribers]) dispatch(listener);\n };\n\n const relevant = (candidate: Locale): boolean => localeChain(locale, fallbackLocales).includes(candidate);\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n dispose,\n get disposed() {\n return disposed;\n },\n getSnapshot() {\n return snapshot;\n },\n isLoaded(loadOptions) {\n return !disposed && catalogs.isLoaded(loadOptions?.locale ?? locale);\n },\n async load(loadOptions) {\n assertLive();\n\n const targetLocale = canonicalLocale(loadOptions?.locale ?? locale);\n const changed = await catalogs.load(targetLocale);\n\n if (!disposed && changed && relevant(targetLocale)) notify();\n },\n get locale() {\n return locale;\n },\n segments(key: string, translateOptions) {\n return snapshot.translator.segmentsDynamic(key, translateOptions);\n },\n segmentsDynamic(key, translateOptions) {\n return snapshot.translator.segmentsDynamic(key, translateOptions);\n },\n serialize() {\n assertLive();\n\n return catalogs.state(locale);\n },\n async setLocale(nextLocale) {\n assertLive();\n\n const next = canonicalLocale(nextLocale);\n\n if (next === locale) return;\n\n locale = next;\n notify();\n },\n subscribe(listener, subscribeOptions) {\n assertLive();\n\n if (subscribeOptions?.signal?.aborted) return () => {};\n\n const unsubscribe = (): void => {\n subscribers.delete(listener);\n subscribeOptions?.signal?.removeEventListener('abort', unsubscribe);\n };\n\n subscribeOptions?.signal?.addEventListener('abort', unsubscribe, { once: true });\n subscribers.add(listener);\n\n if (subscribeOptions?.immediate) dispatch(listener);\n\n return unsubscribe;\n },\n [Symbol.dispose]: dispose,\n translate(key: string, translateOptions = {}) {\n return snapshot.translator.translateDynamic(key, translateOptions);\n },\n translateDynamic(key, translateOptions) {\n return snapshot.translator.translateDynamic(key, translateOptions);\n },\n } as TranslationStore<C>;\n}\n\nexport function hydrateTranslationStore<C extends Catalog>(\n state: TranslationState<C>,\n options?: Omit<TranslationStoreOptions<C>, 'locale' | 'catalogs'>,\n): TranslationStore<C> {\n if (state.version !== 3) {\n throw new LinguaInvalidStateError(`Unsupported lingua state version: ${String(state.version)}.`);\n }\n\n return createTranslationStore({ ...options, catalogs: state.catalogs, locale: state.locale });\n}\n"],"mappings":"mEAGA,IAAM,EAAgB,8BAEtB,SAAgB,EAAgB,EAAyB,CACvD,IAAM,EAAwB,CAAC,EAC3B,EAAS,EAEb,IAAK,IAAM,KAAS,EAAM,SAAS,CAAa,EAAG,CACjD,IAAM,EAAQ,EAAM,OAAS,EAEzB,EAAQ,GAAQ,EAAM,KAAK,EAAM,MAAM,EAAQ,CAAK,CAAC,EAEzD,EAAM,KAAK,CAAE,MAAO,EAAM,EAAG,CAAC,EAC9B,EAAS,EAAQ,EAAM,EAAE,CAAC,MAC5B,CAIA,OAFI,EAAS,EAAM,QAAQ,EAAM,KAAK,EAAM,MAAM,CAAM,CAAC,EAElD,CACT,CAEA,SAAgB,EACd,EACA,EACA,EACQ,CACR,OAAO,EACJ,IAAK,GAAS,CACb,GAAI,OAAO,GAAS,SAAU,OAAO,EAErC,IAAM,EAAQ,OAAO,OAAO,EAAQ,EAAK,KAAK,EAAI,EAAO,EAAK,OAAS,IAAA,GAEvE,OAAO,GAAS,KAAO,EAAQ,EAAK,KAAK,EAAI,OAAO,CAAK,CAC3D,CAAC,CAAC,CACD,KAAK,EAAE,CACZ,CAEA,SAAgB,EACd,EACA,EACA,EAC4B,CAC5B,IAAM,EAAqC,CAAC,EAE5C,IAAK,IAAM,KAAQ,EAAO,CACxB,GAAI,OAAO,GAAS,SAAU,CACxB,IAAS,IAAI,EAAO,KAAK,CAAI,EAEjC,QACF,CAEA,EAAO,KAAK,OAAO,OAAO,EAAQ,EAAK,KAAK,EAAI,EAAO,EAAK,OAAU,EAAQ,EAAK,KAAK,CAAC,CAC3F,CAEA,OAAO,CACT,CCzDA,IAAa,EAAb,cAAiC,KAAM,CACrC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAEa,EAAb,cAAyC,CAAY,CACnD,aAAc,CACZ,MAAM,mDAAmD,CAC3D,CACF,EAEa,EAAb,cAA+C,CAAY,CAAC,EAC/C,EAAb,cAA8C,CAAY,CAAC,EAC9C,EAAb,cAAmD,CAAY,CAAC,EACnD,EAAb,cAA6C,CAAY,CAAC,EAC7C,EAAb,cAA+C,CAAY,CAAC,ECdtD,EAAa,IAAI,IAAI,CAAC,YAAa,cAAe,WAAW,CAAC,EAOpE,SAAgB,EAAgB,EAA0C,CACxE,OAAO,OAAO,GAAS,YAAY,GAAiB,OAAO,OAAO,EAAM,QAAQ,CAClF,CAGA,SAAgB,EAAe,EAAmC,CAChE,IAAM,EAAW,IAAI,IAEf,GAAS,EAAmB,IAAyB,CACzD,GAAI,OAAO,GAAS,SAAU,CAC5B,EAAS,IAAI,EAAQ,CAAE,KAAM,OAAQ,SAAU,EAAgB,CAAI,CAAE,CAAC,EAEtE,MACF,CAEA,GAAI,OAAO,GAAS,WAAY,GAAiB,MAAM,QAAQ,CAAI,EACjE,MAAM,IAAI,EAA0B,iBAAiB,EAAO,+CAA+C,EAG7G,GAAI,EAAgB,CAAI,EAAG,CACzB,GAAI,QAAQ,QAAQ,CAAI,CAAC,CAAC,KAAM,GAAQ,IAAQ,QAAQ,EACtD,MAAM,IAAI,EAA0B,mBAAmB,EAAO,yCAAyC,EAGzG,GAAI,OAAO,EAAK,QAAW,UAAY,EAAK,SAAW,MAAQ,MAAM,QAAQ,EAAK,MAAM,EACtF,MAAM,IAAI,EAA0B,mBAAmB,EAAO,0CAA0C,EAG1G,IAAM,EAAQ,IAAI,IAElB,IAAK,GAAM,CAAC,EAAM,KAAa,OAAO,QAAQ,EAAK,MAAM,EAAG,CAC1D,GAAI,OAAO,GAAa,SACtB,MAAM,IAAI,EAA0B,gBAAgB,EAAO,GAAG,EAAK,oBAAoB,EAGzF,EAAM,IAAI,EAAM,EAAgB,CAAQ,CAAC,CAC3C,CAEA,EAAS,IAAI,EAAQ,CAAE,QAAO,KAAM,QAAS,CAAC,EAE9C,MACF,CAEA,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAI,EAAG,CAC/C,GAAI,EAAW,IAAI,CAAG,EACpB,MAAM,IAAI,EAA0B,gBAAgB,EAAI,eAAe,EAGzE,EAAM,EAAO,EAAS,GAAG,EAAO,GAAG,IAAQ,CAAG,CAChD,CACF,EAEA,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,CAAO,EAAG,CAClD,GAAI,EAAW,IAAI,CAAG,EAAG,MAAM,IAAI,EAA0B,gBAAgB,EAAI,eAAe,EAEhG,EAAM,EAAO,CAAG,CAClB,CAEA,OAAO,CACT,CC1CA,SAAgB,EAAY,EAAkD,CAM5E,MAAO,CAAC,GAAG,EAJT,OAAO,GAAW,UAAY,GAAmB,cAAe,GAAU,gBAAiB,EACtF,EAA4B,UAAU,CAAC,CAAC,SAAU,EAA4B,QAC9E,CAE0B,CAAC,CAAC,KAAK,CAAC,CAC3C,CEhCA,IAAM,EAAc,IAAI,IAExB,SAAgB,EAAgB,EAAwB,CACtD,GAAI,CACF,GAAM,CAAC,GAAa,KAAK,oBAAoB,CAAM,EAEnD,GAAI,EAAW,OAAO,CACxB,MAAQ,CAER,CAEA,MAAM,IAAI,EAAyB,+BAA+B,EAAO,GAAG,CAC9E,CAEA,SAAgB,EAAY,EAAgB,EAAgD,CAC1F,IAAM,EAAQ,IAAI,IAElB,IAAK,IAAM,IAAa,CAAC,EAAQ,GAAG,CAAQ,EAAG,CAC7C,IAAM,EAAQ,EAAU,MAAM,GAAG,EAEjC,IAAK,IAAI,EAAS,EAAM,OAAQ,EAAS,EAAG,IAC1C,EAAM,IAAI,EAAM,MAAM,EAAG,CAAM,CAAC,CAAC,KAAK,GAAG,CAAC,CAE9C,CAEA,MAAO,CAAC,GAAG,CAAK,CAClB,CAEA,SAAgB,EAAe,EAAgB,EAAe,EAAuC,CACnG,IAAM,EAAM,GAAG,EAAO,GAAG,EAAU,UAAY,aAC3C,EAAQ,EAAY,IAAI,CAAG,EAO/B,OALK,IACH,EAAQ,IAAI,KAAK,YAAY,EAAQ,CAAE,KAAM,EAAU,UAAY,UAAW,CAAC,EAC/E,EAAY,IAAI,EAAK,CAAK,GAGrB,EAAM,OAAO,CAAK,CAC3B,CCnCA,SAAgB,EAAsC,EAA4B,CAChF,IAAM,EAAc,IAAI,IAClB,EAAS,IAAI,IACb,EAAQ,IAAI,IAElB,IAAK,GAAM,CAAC,EAAQ,KAAW,OAAO,QAAQ,CAAO,EAAG,EAAY,IAAI,EAAgB,CAAM,EAAG,CAAM,EAEvG,IAAM,GAAO,EAAgB,IAAqB,CAChD,EAAO,IAAI,EAAQ,CAAE,UAAS,SAAU,EAAe,CAAO,CAAE,CAAC,CACnE,EAEA,IAAK,GAAM,CAAC,EAAQ,KAAW,EACzB,OAAO,GAAW,YAAY,EAAI,EAAQ,CAAM,EA2CtD,MAAO,CACL,YAAmD,CACjD,OAAO,IAAI,IAAI,CAAC,GAAG,CAAM,CAAC,CAAC,KAAK,CAAC,EAAQ,CAAE,eAAgB,CAAC,EAAQ,CAAQ,CAAC,CAAC,CAChF,EACA,SAAS,EAAyB,CAChC,OAAO,EAAO,IAAI,EAAgB,CAAM,CAAC,CAC3C,EACA,UA/CkB,IAA8C,CAChE,IAAM,EAAS,EAAgB,CAAe,EAE9C,GAAI,EAAO,IAAI,CAAM,EAAG,MAAO,GAE/B,IAAM,EAAS,EAAY,IAAI,CAAM,EAErC,GAAI,CAAC,EAAQ,MAAM,IAAI,EAA0B,qCAAqC,EAAO,GAAG,EAEhG,GAAI,OAAO,GAAW,WAGpB,OAFA,EAAI,EAAQ,CAAM,EAEX,GAGT,IAAM,EAAW,EAAM,IAAI,CAAM,EAEjC,GAAI,EAGF,OAFA,MAAM,EAEC,GAGT,IAAM,EAAO,EAAO,CAAC,CAAC,KACnB,GAAY,CACX,EAAI,EAAQ,CAAO,EACnB,EAAM,OAAO,CAAM,CACrB,EACC,GAAmB,CAElB,MADA,EAAM,OAAO,CAAM,EACb,CACR,CACF,EAKA,OAHA,EAAM,IAAI,EAAQ,CAAI,EACtB,MAAM,EAEC,EACT,EAUE,MAAM,EAAqC,CACzC,IAAM,EAAwB,CAAC,EAE/B,IAAK,GAAM,CAAC,EAAc,CAAE,cAAc,EAAQ,EAAS,GAAgB,EAE3E,MAAO,CAAE,WAAU,SAAQ,QAAS,CAAE,CACxC,CACF,CACF,CC9CA,SAAgB,EACd,EACA,EAA6B,CAAC,EACf,CACf,IAAM,EAAS,EAAgB,EAAQ,QAAU,IAAI,EAI/C,EAAQ,EAAY,GAFxB,MAAM,QAAQ,EAAQ,QAAQ,EAAI,EAAQ,SAAW,EAAQ,SAAW,CAAC,EAAQ,QAAQ,EAAI,CAAC,EAAA,CAC9F,IAAI,CAC4B,CAAQ,EACpC,EAAa,EAAQ,eAAkB,GAAgB,GACvD,EAAe,EAAQ,iBAAoB,GAAiB,IAAI,EAAK,IAErE,EAAW,GAA6C,CAC5D,IAAK,IAAM,KAAa,EAAO,CAC7B,IAAM,EAAU,EAAS,IAAI,CAAS,CAAC,EAAE,IAAI,CAAG,EAEhD,GAAI,EAAS,MAAO,CAAE,OAAQ,EAAW,SAAQ,CACnD,CAGF,EAEM,GACJ,EACA,IACoD,CACpD,IAAM,EAAQ,EAAQ,CAAG,EAEzB,GAAI,CAAC,EAAO,OAEZ,GAAI,EAAM,QAAQ,OAAS,OAGzB,MAFI,UAAW,EAAS,OAEjB,CAAE,MAAK,SAAU,EAAM,QAAQ,QAAS,EAGjD,GAAI,EAAE,UAAW,IAAY,CAAC,OAAO,SAAS,EAAQ,KAAK,EAAG,CAC5D,GAAI,UAAW,EAAS,MAAM,IAAI,EAA8B,kCAAkC,EAElG,MACF,CAEA,IAAM,EACJ,EAAQ,QAAU,GAAK,CAAC,EAAQ,QAC5B,OACA,EAAe,EAAM,OAAQ,EAAQ,MAAO,EAAQ,SAAW,EAAK,EACpE,EAAW,EAAM,QAAQ,MAAM,IAAI,CAAQ,GAAK,EAAM,QAAQ,MAAM,IAAI,OAAO,EAErF,OAAO,EAAW,CAAE,MAAK,UAAS,EAAI,IAAA,EACxC,EAEM,EAAa,GACjB,UAAW,EAAU,CAAE,MAAO,EAAQ,MAAO,GAAG,EAAQ,MAAO,EAAK,EAAQ,QAAU,CAAC,EAEnF,GACJ,EACA,IAC+B,CAC/B,IAAM,EAAQ,EAAY,EAAK,CAAO,EAItC,OAFK,EAEE,EAAe,EAAM,SAAU,EAAU,CAAO,EAAkC,GACvF,EAAa,EAAM,EAAM,IAAK,CAAM,CACtC,EAJmB,CAAC,EAAW,EAAK,CAAM,CAAC,CAK7C,EAEM,GAAoB,EAAa,EAA4C,CAAC,IAAc,CAChG,IAAM,EAAQ,EAAY,EAAK,CAAO,EAItC,OAFK,EAEE,EAAW,EAAM,SAAU,EAAU,CAAO,EAAI,GAAS,EAAa,EAAM,EAAM,IAAK,CAAM,CAAC,EAFlF,EAAW,EAAK,CAAM,CAG3C,EAEA,MAAO,CACL,SACA,SAAS,EAAa,EAAoF,CACxG,OAAO,EAAgB,EAAK,CAAO,CACrC,EACA,kBACA,UAAU,EAAa,EAA4C,CAAC,EAAG,CACrE,OAAO,EAAiB,EAAK,CAAO,CACtC,EACA,kBACF,CACF,CAGA,SAAgB,EACd,EACA,EAAoC,CAAC,EACtB,CACf,IAAM,EAAS,EAAgB,EAAQ,QAAU,IAAI,EAGrD,OAAO,EAAgC,IAFlB,IAA6B,CAAC,CAAC,EAAQ,EAAe,CAAO,CAAC,CAAC,CAE7C,EAAU,CAAE,GAAG,EAAS,QAAO,CAAC,CACzE,CAEA,SAAgB,EAAoC,EAAuB,EAA4C,CACrH,IAAM,EAAW,IAAI,IAErB,IAAK,GAAM,CAAC,EAAQ,KAAY,OAAO,QAAQ,CAAQ,EACrD,EAAS,IAAI,EAAgB,CAAM,EAAG,EAAe,CAAO,CAAC,EAG/D,OAAO,EAAgC,EAAU,CAAO,CAC1D,CChHA,SAAgB,EAA0C,EAA0D,CAClH,IAAM,EAAW,EAAmB,EAAQ,QAAQ,EAC9C,EAAW,EAAQ,SACnB,GAAmB,MAAM,QAAQ,CAAQ,EAAI,EAAW,EAAW,CAAC,CAAQ,EAAI,CAAC,EAAA,CAAG,IAAI,CAAe,EACvG,EAAa,IAAI,gBACjB,EAAc,IAAI,IACpB,EAAW,GACX,EAAS,EAAgB,EAAQ,QAAU,IAAI,EAC/C,EAAW,EAET,OAA+C,CACnD,SACA,WACA,WAAY,EAAgC,EAAS,WAAW,EAAG,CAAE,GAAG,EAAS,WAAU,QAAO,CAAC,CACrG,GACI,EAAW,EAAc,EAEvB,MAAyB,CAC7B,GAAI,EAAU,MAAM,IAAI,CAC1B,EAEM,MAAsB,CACtB,IAEJ,EAAW,GACX,EAAY,MAAM,EAClB,EAAW,MAAM,EACnB,EAEM,EAAY,GAA2D,CAC3E,GAAI,CACF,EAAS,CAAQ,CACnB,MAAgB,CAEhB,CACF,EAEM,MAAqB,CACzB,IACA,EAAW,EAAc,EAEzB,IAAK,IAAM,IAAY,CAAC,GAAG,CAAW,EAAG,EAAS,CAAQ,CAC5D,EAEM,EAAY,GAA+B,EAAY,EAAQ,CAAe,CAAC,CAAC,SAAS,CAAS,EAExG,MAAO,CACL,IAAI,gBAAiB,CACnB,OAAO,EAAW,MACpB,EACA,UACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,aAAc,CACZ,OAAO,CACT,EACA,SAAS,EAAa,CACpB,MAAO,CAAC,GAAY,EAAS,SAAS,GAAa,QAAU,CAAM,CACrE,EACA,MAAM,KAAK,EAAa,CACtB,EAAW,EAEX,IAAM,EAAe,EAAgB,GAAa,QAAU,CAAM,EAC5D,EAAU,MAAM,EAAS,KAAK,CAAY,EAE5C,CAAC,GAAY,GAAW,EAAS,CAAY,GAAG,EAAO,CAC7D,EACA,IAAI,QAAS,CACX,OAAO,CACT,EACA,SAAS,EAAa,EAAkB,CACtC,OAAO,EAAS,WAAW,gBAAgB,EAAK,CAAgB,CAClE,EACA,gBAAgB,EAAK,EAAkB,CACrC,OAAO,EAAS,WAAW,gBAAgB,EAAK,CAAgB,CAClE,EACA,WAAY,CAGV,OAFA,EAAW,EAEJ,EAAS,MAAM,CAAM,CAC9B,EACA,MAAM,UAAU,EAAY,CAC1B,EAAW,EAEX,IAAM,EAAO,EAAgB,CAAU,EAEnC,IAAS,IAEb,EAAS,EACT,EAAO,EACT,EACA,UAAU,EAAU,EAAkB,CAGpC,GAFA,EAAW,EAEP,GAAkB,QAAQ,QAAS,UAAa,CAAC,EAErD,IAAM,MAA0B,CAC9B,EAAY,OAAO,CAAQ,EAC3B,GAAkB,QAAQ,oBAAoB,QAAS,CAAW,CACpE,EAOA,OALA,GAAkB,QAAQ,iBAAiB,QAAS,EAAa,CAAE,KAAM,EAAK,CAAC,EAC/E,EAAY,IAAI,CAAQ,EAEpB,GAAkB,WAAW,EAAS,CAAQ,EAE3C,CACT,GACC,OAAO,SAAU,EAClB,UAAU,EAAa,EAAmB,CAAC,EAAG,CAC5C,OAAO,EAAS,WAAW,iBAAiB,EAAK,CAAgB,CACnE,EACA,iBAAiB,EAAK,EAAkB,CACtC,OAAO,EAAS,WAAW,iBAAiB,EAAK,CAAgB,CACnE,CACF,CACF,CAEA,SAAgB,EACd,EACA,EACqB,CACrB,GAAI,EAAM,UAAY,EACpB,MAAM,IAAI,EAAwB,qCAAqC,OAAO,EAAM,OAAO,EAAE,EAAE,EAGjG,OAAO,EAAuB,CAAE,GAAG,EAAS,SAAU,EAAM,SAAU,OAAQ,EAAM,MAAO,CAAC,CAC9F"}
1
+ {"version":3,"file":"lingua.cjs","names":[],"sources":["../src/_template.ts","../src/errors.ts","../src/_catalog.ts","../src/catalog.ts","../src/_dev.ts","../src/_locale.ts","../src/_resources.ts","../src/translator.ts","../src/i18n.ts"],"sourcesContent":["import type { Part } from './types';\n\nexport type TemplatePart = string | { readonly value: string };\nexport type Template = readonly TemplatePart[];\n\nconst interpolation = /\\{([\\p{ID_Continue}-]+)\\}/gu;\n\nexport function compileTemplate(value: string): Template {\n const parts: TemplatePart[] = [];\n let offset = 0;\n\n for (const match of value.matchAll(interpolation)) {\n const index = match.index ?? 0;\n\n if (index > offset) parts.push(value.slice(offset, index));\n\n parts.push({ value: match[1] });\n offset = index + match[0].length;\n }\n\n if (offset < value.length) parts.push(value.slice(offset));\n\n return parts;\n}\n\nexport function renderText(\n parts: Template,\n values: Record<string, unknown>,\n missing: (name: string) => string,\n): string {\n return parts\n .map((part) => {\n if (typeof part === 'string') return part;\n\n const value = Object.hasOwn(values, part.value) ? values[part.value] : undefined;\n\n return value == null ? missing(part.value) : String(value);\n })\n .join('');\n}\n\nexport function renderParts<V>(\n parts: Template,\n values: Record<string, V | number>,\n missing: (name: string) => string,\n): Array<Part<V | number>> {\n const result: Array<Part<V | number>> = [];\n\n for (const part of parts) {\n if (typeof part === 'string') {\n if (part !== '') result.push({ type: 'text', value: part });\n\n continue;\n }\n\n if (Object.hasOwn(values, part.value)) {\n result.push({ type: 'value', value: values[part.value]! as V | number });\n } else {\n result.push({ type: 'text', value: missing(part.value) });\n }\n }\n\n return result;\n}\n","export class LinguaError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class LinguaDisposedError extends LinguaError {\n constructor() {\n super('Operation called on a disposed i18n instance.');\n }\n}\n\nexport class LinguaInvalidCatalogError extends LinguaError {}\nexport class LinguaInvalidLocaleError extends LinguaError {}\nexport class LinguaInvalidPluralCountError extends LinguaError {}\nexport class LinguaInvalidStateError extends LinguaError {}\nexport class LinguaMissingCatalogError extends LinguaError {}\nexport class LinguaMissingKeyError extends LinguaError {}\nexport class LinguaMissingValueError extends LinguaError {}\n","import { compileTemplate, type Template } from './_template';\nimport { LinguaInvalidCatalogError } from './errors';\nimport type { Catalog, CatalogNode, PluralMessage } from './types';\n\nconst unsafeKeys = new Set(['__proto__', 'constructor', 'prototype']);\n\nexport type CompiledText = { readonly kind: 'text'; readonly template: Template };\nexport type CompiledPlural = { readonly forms: ReadonlyMap<string, Template>; readonly kind: 'plural' };\nexport type CompiledMessage = CompiledPlural | CompiledText;\nexport type CompiledCatalog = ReadonlyMap<string, CompiledMessage>;\n\nexport function isPluralMessage(node: CatalogNode): node is PluralMessage {\n return typeof node === 'object' && node !== null && Object.hasOwn(node, 'plural');\n}\n\n/** Compile explicit catalog nodes once. Nested objects only group keys; plural intent is never inferred. */\nexport function compileCatalog(catalog: Catalog): CompiledCatalog {\n const messages = new Map<string, CompiledMessage>();\n\n const visit = (node: CatalogNode, prefix: string): void => {\n if (typeof node === 'string') {\n messages.set(prefix, { kind: 'text', template: compileTemplate(node) });\n\n return;\n }\n\n if (typeof node !== 'object' || node === null || Array.isArray(node)) {\n throw new LinguaInvalidCatalogError(`Catalog node \"${prefix}\" must be a string, plural message, or object.`);\n }\n\n if (isPluralMessage(node)) {\n if (Reflect.ownKeys(node).some((key) => key !== 'plural')) {\n throw new LinguaInvalidCatalogError(`Plural message \"${prefix}\" must contain only a \"plural\" property.`);\n }\n\n if (typeof node.plural !== 'object' || node.plural === null || Array.isArray(node.plural)) {\n throw new LinguaInvalidCatalogError(`Plural message \"${prefix}\" must provide an object of string forms.`);\n }\n\n const forms = new Map<string, Template>();\n\n for (const [form, template] of Object.entries(node.plural)) {\n if (typeof template !== 'string') {\n throw new LinguaInvalidCatalogError(`Plural form \"${prefix}.${form}\" must be a string.`);\n }\n\n forms.set(form, compileTemplate(template));\n }\n\n messages.set(prefix, { forms, kind: 'plural' });\n\n return;\n }\n\n for (const [key, value] of Object.entries(node)) {\n if (unsafeKeys.has(key)) {\n throw new LinguaInvalidCatalogError(`Catalog key \"${key}\" is reserved.`);\n }\n\n visit(value, prefix ? `${prefix}.${key}` : key);\n }\n };\n\n for (const [key, value] of Object.entries(catalog)) {\n if (unsafeKeys.has(key)) throw new LinguaInvalidCatalogError(`Catalog key \"${key}\" is reserved.`);\n\n visit(value, key);\n }\n\n return messages;\n}\n","import { compileCatalog } from './_catalog';\nimport { LinguaMissingCatalogError } from './errors';\nimport type { I18n } from './i18n';\nimport type { Catalog, MessageKey } from './types';\n\n/** Enumerate every message key in a catalog as a dotted path.\n *\n * Traverses nested grouping objects and explicit `{ plural: ... }` messages,\n * producing the same dotted paths that `MessageKey<C>` represents at the type\n * level. Use this to derive key arrays from the catalog itself instead of\n * maintaining a parallel list that can go stale.\n *\n * Pass an `I18n` instance to enumerate keys from its current locale catalog\n * without specifying a locale explicitly.\n *\n * @example\n * ```ts\n * const messages = {\n * nav: { home: '...', settings: '...' },\n * };\n * const keys = catalogKeys(messages); // ['nav.home', 'nav.settings']\n *\n * // From an i18n instance — uses current locale's catalog\n * const i18n = createI18n({ catalogs: { en: messages }, locale: 'en' });\n * const allKeys = catalogKeys(i18n);\n * ```\n */\nexport function catalogKeys<C extends Catalog>(i18n: I18n<C>): ReadonlyArray<MessageKey<C>>;\nexport function catalogKeys<C extends Catalog>(catalog: C): ReadonlyArray<MessageKey<C>>;\nexport function catalogKeys(source: unknown): ReadonlyArray<MessageKey<Catalog>> {\n if (typeof source === 'object' && source !== null && 'serialize' in source && 'getSnapshot' in source) {\n const i18n = source as I18n;\n const catalog = i18n.serialize().catalogs[i18n.locale];\n\n if (!catalog) throw new LinguaMissingCatalogError(`No catalog loaded for locale \"${i18n.locale}\".`);\n\n return [...compileCatalog(catalog).keys()] as unknown as ReadonlyArray<MessageKey<Catalog>>;\n }\n\n return [...compileCatalog(source as Catalog).keys()] as unknown as ReadonlyArray<MessageKey<Catalog>>;\n}\n","const isDev = !(globalThis as { __LINGUA_PROD__?: boolean }).__LINGUA_PROD__;\n\n/** @internal @security Messages may include user-supplied data. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/lingua] ${msg}`);\n}\n\n/** @internal */\nexport function error(msg: string, ...args: unknown[]): void {\n if (isDev) console.error(`[@vielzeug/lingua] ${msg}`, ...args);\n}\n","import { LinguaInvalidLocaleError } from './errors';\nimport type { Locale } from './types';\n\nconst pluralRules = new Map<string, Intl.PluralRules>();\n\nexport function canonicalLocale(locale: string): Locale {\n try {\n const [canonical] = Intl.getCanonicalLocales(locale);\n\n if (canonical) return canonical;\n } catch {\n // Error below names the failed public input.\n }\n\n throw new LinguaInvalidLocaleError(`Invalid BCP 47 locale tag: \"${locale}\".`);\n}\n\nexport function localeChain(locale: Locale, fallback: readonly Locale[]): readonly Locale[] {\n const chain = new Set<Locale>();\n\n for (const candidate of [locale, ...fallback]) {\n const parts = candidate.split('-');\n\n for (let length = parts.length; length > 0; length--) {\n chain.add(parts.slice(0, length).join('-'));\n }\n }\n\n return [...chain];\n}\n\nexport function pluralCategory(locale: Locale, count: number, ordinal: boolean): Intl.LDMLPluralRule {\n const key = `${locale}:${ordinal ? 'ordinal' : 'cardinal'}`;\n let rules = pluralRules.get(key);\n\n if (!rules) {\n rules = new Intl.PluralRules(locale, { type: ordinal ? 'ordinal' : 'cardinal' });\n pluralRules.set(key, rules);\n }\n\n return rules.select(count);\n}\n","import { type CompiledCatalog, compileCatalog } from './_catalog';\nimport { canonicalLocale } from './_locale';\nimport { LinguaMissingCatalogError } from './errors';\nimport type { Catalog, Catalogs, Locale, TranslationState } from './types';\n\ntype CatalogStoreOptions<C extends Catalog> = {\n readonly catalogs?: Catalogs<C>;\n readonly loadCatalog?: (locale: Locale) => Promise<C> | C;\n};\n\n/** One catalog state machine owns loaded catalogs and in-flight loading work. */\nexport function createCatalogStore<C extends Catalog>(options: CatalogStoreOptions<C>) {\n const loaded = new Map<Locale, { readonly catalog: C; readonly compiled: CompiledCatalog }>();\n const tasks = new Map<Locale, Promise<void>>();\n\n const hydrate = (locale: Locale, catalog: C): void => {\n loaded.set(canonicalLocale(locale), { catalog, compiled: compileCatalog(catalog) });\n };\n\n for (const [locale, catalog] of Object.entries(options.catalogs ?? {})) hydrate(locale, catalog);\n\n const load = async (requestedLocale: Locale): Promise<boolean> => {\n const locale = canonicalLocale(requestedLocale);\n\n if (loaded.has(locale)) return false;\n\n const existing = tasks.get(locale);\n\n if (existing) {\n await existing;\n\n return false;\n }\n\n if (!options.loadCatalog) {\n throw new LinguaMissingCatalogError(`No catalog source provided for locale \"${locale}\".`);\n }\n\n const task = Promise.resolve(options.loadCatalog(locale)).then(\n (catalog) => {\n hydrate(locale, catalog);\n tasks.delete(locale);\n },\n (error: unknown) => {\n tasks.delete(locale);\n throw error;\n },\n );\n\n tasks.set(locale, task);\n await task;\n\n return true;\n };\n\n return {\n catalogMap(): ReadonlyMap<Locale, CompiledCatalog> {\n return new Map([...loaded].map(([locale, { compiled }]) => [locale, compiled]));\n },\n hydrate,\n isLoaded(locale: Locale): boolean {\n return loaded.has(canonicalLocale(locale));\n },\n load,\n state(locale: Locale): TranslationState<C> {\n const catalogs: Catalogs<C> = {};\n\n for (const [loadedLocale, { catalog }] of loaded) catalogs[loadedLocale] = catalog;\n\n return { catalogs, locale, version: 4 };\n },\n };\n}\n","import { type CompiledCatalog, type CompiledMessage, compileCatalog } from './_catalog';\nimport { warn } from './_dev';\nimport { canonicalLocale, localeChain, pluralCategory } from './_locale';\nimport { renderParts, renderText, type Template } from './_template';\nimport { LinguaInvalidPluralCountError, LinguaMissingKeyError, LinguaMissingValueError } from './errors';\nimport type {\n Catalog,\n Locale,\n MissingInfo,\n MissingStrategy,\n Part,\n PluralKey,\n PluralOptions,\n TextKey,\n TranslateOptions,\n TranslatorOptions,\n} from './types';\n\nexport type Translator<C extends Catalog = Catalog> = {\n readonly locale: Locale;\n parts<V>(key: TextKey<C>, options: TranslateOptions & { values: Record<string, V> }): Array<Part<V>>;\n parts<V>(key: PluralKey<C>, options: PluralOptions & { values?: Record<string, V> }): Array<Part<number | V>>;\n partsDynamic<V>(\n key: string,\n options: (TranslateOptions | PluralOptions) & { values?: Record<string, V> },\n ): Array<Part<number | V>>;\n translate(key: TextKey<C>, options?: TranslateOptions): string;\n translate(key: PluralKey<C>, options: PluralOptions): string;\n translateDynamic(key: string, options?: TranslateOptions | PluralOptions): string;\n};\n\ntype InternalOptions = {\n readonly fallback?: Locale | readonly Locale[];\n readonly locale?: Locale;\n readonly missing?: MissingStrategy;\n};\n\nconst isDev = !(globalThis as { __LINGUA_PROD__?: boolean }).__LINGUA_PROD__;\n\nfunction resolveMissing(strategy: MissingStrategy | undefined, info: MissingInfo): string {\n if (strategy === 'throw') {\n throw info.name\n ? new LinguaMissingValueError(\n `Missing interpolation value \"${info.name}\" for key \"${info.key}\" in locale \"${info.locale}\".`,\n )\n : new LinguaMissingKeyError(`Missing translation key \"${info.key}\" in locale \"${info.locale}\".`);\n }\n\n if (typeof strategy === 'function') return strategy(info);\n\n // 'key' or undefined (default)\n if (strategy === undefined && isDev) {\n warn(\n info.name\n ? `Missing interpolation value \"${info.name}\" for key \"${info.key}\" in locale \"${info.locale}\".`\n : `Missing translation key \"${info.key}\" in locale \"${info.locale}\".`,\n );\n }\n\n return info.name ? `{${info.name}}` : info.key;\n}\n\ntype ResolvedMessage = { readonly locale: Locale; readonly message: CompiledMessage };\n\nexport function createTranslatorFromCompiled<C extends Catalog>(\n catalogs: ReadonlyMap<Locale, CompiledCatalog>,\n options: InternalOptions = {},\n): Translator<C> {\n const locale = canonicalLocale(options.locale ?? 'en');\n const fallback = (\n Array.isArray(options.fallback) ? options.fallback : options.fallback ? [options.fallback] : []\n ).map(canonicalLocale);\n const chain = localeChain(locale, fallback);\n const missing = options.missing;\n\n const missingKey = (key: string): string => resolveMissing(missing, { key, locale });\n const missingValue = (name: string, key: string): string => resolveMissing(missing, { key, locale, name });\n\n const resolve = (key: string): ResolvedMessage | undefined => {\n for (const candidate of chain) {\n const message = catalogs.get(candidate)?.get(key);\n\n if (message) return { locale: candidate, message };\n }\n\n return undefined;\n };\n\n const templateFor = (\n key: string,\n options: TranslateOptions | PluralOptions,\n ): { key: string; template: Template } | undefined => {\n const found = resolve(key);\n\n if (!found) return undefined;\n\n if (found.message.kind === 'text') {\n if ('count' in options) return undefined;\n\n return { key, template: found.message.template };\n }\n\n if (!('count' in options) || !Number.isFinite(options.count)) {\n if ('count' in options) throw new LinguaInvalidPluralCountError('`count` must be a finite number.');\n\n return undefined;\n }\n\n const category =\n options.count === 0 && !options.ordinal\n ? 'zero'\n : pluralCategory(found.locale, options.count, options.ordinal ?? false);\n const template = found.message.forms.get(category) ?? found.message.forms.get('other');\n\n return template ? { key, template } : undefined;\n };\n\n const valuesFor = (options: TranslateOptions | PluralOptions): Record<string, unknown> =>\n 'count' in options ? { count: options.count, ...options.values } : (options.values ?? {});\n\n const partsDynamic = <V>(\n key: string,\n options: (TranslateOptions | PluralOptions) & { values?: Record<string, V> },\n ): Array<Part<number | V>> => {\n const found = templateFor(key, options);\n\n if (!found) return [{ type: 'text', value: missingKey(key) }];\n\n return renderParts(found.template, valuesFor(options) as Record<string, V | number>, (name) =>\n missingValue(name, found.key),\n );\n };\n\n const translateDynamic = (key: string, options: TranslateOptions | PluralOptions = {}): string => {\n const found = templateFor(key, options);\n\n if (!found) return missingKey(key);\n\n return renderText(found.template, valuesFor(options), (name) => missingValue(name, found.key));\n };\n\n return {\n locale,\n parts(key: string, options: (TranslateOptions | PluralOptions) & { values?: Record<string, unknown> }) {\n return partsDynamic(key, options);\n },\n partsDynamic,\n translate(key: string, options: TranslateOptions | PluralOptions = {}) {\n return translateDynamic(key, options);\n },\n translateDynamic,\n } as Translator<C>;\n}\n\n/** Creates a fixed-locale translator from one catalog. Lingua snapshots catalog messages during construction. */\nexport function createTranslator<C extends Catalog>(catalog: C, options?: TranslatorOptions): Translator<C> {\n const locale = canonicalLocale(options?.locale ?? 'en');\n const compiled = new Map<Locale, CompiledCatalog>([[locale, compileCatalog(catalog)]]);\n\n return createTranslatorFromCompiled<C>(compiled, { ...options, locale });\n}\n","import { error as logError } from './_dev';\nimport { canonicalLocale, localeChain } from './_locale';\nimport { createCatalogStore } from './_resources';\nimport { LinguaDisposedError, LinguaInvalidStateError, LinguaMissingCatalogError } from './errors';\nimport { createTranslatorFromCompiled, type Translator } from './translator';\nimport type { Catalog, I18nOptions, Locale, SubscribeOptions, TranslationState } from './types';\n\nexport type I18nSnapshot<C extends Catalog = Catalog> = {\n readonly locale: Locale;\n readonly revision: number;\n readonly translator: Translator<C>;\n};\n\nexport type I18n<C extends Catalog = Catalog> = Translator<C> & {\n [Symbol.dispose](): void;\n readonly disposalSignal: AbortSignal;\n dispose(): void;\n readonly disposed: boolean;\n getSnapshot(): I18nSnapshot<C>;\n isLoaded(options?: { locale?: Locale }): boolean;\n load(options?: { locale?: Locale }): Promise<void>;\n serialize(): TranslationState<C>;\n setLocale(locale: Locale): Promise<void>;\n subscribe(listener: (snapshot: I18nSnapshot<C>) => void, options?: SubscribeOptions): () => void;\n};\n\nexport function createI18n<C extends Catalog>(options: I18nOptions<C>): I18n<C> {\n if (options.state && options.state.version !== 4) {\n throw new LinguaInvalidStateError(`Unsupported lingua state version: ${String(options.state.version)}.`);\n }\n\n const fallback = options.fallback;\n const fallbackLocales = (Array.isArray(fallback) ? fallback : fallback ? [fallback] : []).map(canonicalLocale);\n const controller = new AbortController();\n const subscribers = new Set<(snapshot: I18nSnapshot<C>) => void>();\n let disposed = false;\n let locale = canonicalLocale(options.locale ?? options.state?.locale ?? 'en');\n let revision = 0;\n let transition = 0;\n\n const catalogs = createCatalogStore<C>({ catalogs: options.catalogs, loadCatalog: options.loadCatalog });\n\n // Hydrate from serialized state (SSR).\n if (options.state) {\n for (const [stateLocale, catalog] of Object.entries(options.state.catalogs)) {\n catalogs.hydrate(stateLocale, catalog);\n }\n }\n\n const loadTargets = async (target: Locale): Promise<readonly Locale[]> => {\n const changed: Locale[] = [];\n\n for (const candidate of new Set([target, ...fallbackLocales])) {\n if (await catalogs.load(candidate)) changed.push(candidate);\n }\n\n return changed;\n };\n\n const buildSnapshot = (): I18nSnapshot<C> => {\n const ready = localeChain(locale, fallbackLocales).some(catalogs.isLoaded);\n const missing = ready\n ? options.missing\n : () => {\n throw new LinguaMissingCatalogError(\n `No catalog loaded for locale \"${locale}\". Call load() before translating.`,\n );\n };\n\n return {\n locale,\n revision,\n translator: createTranslatorFromCompiled<C>(catalogs.catalogMap(), { fallback, locale, missing }),\n };\n };\n let snapshot = buildSnapshot();\n\n const assertLive = (): void => {\n if (disposed) throw new LinguaDisposedError();\n };\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n subscribers.clear();\n controller.abort();\n };\n\n const dispatch = (listener: (next: I18nSnapshot<C>) => void): void => {\n try {\n listener(snapshot);\n } catch (error) {\n logError('subscriber error', error);\n }\n };\n\n const notify = (): void => {\n revision++;\n snapshot = buildSnapshot();\n\n for (const listener of [...subscribers]) dispatch(listener);\n };\n\n const relevant = (candidate: Locale): boolean => localeChain(locale, fallbackLocales).includes(candidate);\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n dispose,\n get disposed() {\n return disposed;\n },\n getSnapshot() {\n return snapshot;\n },\n isLoaded(loadOptions) {\n return !disposed && catalogs.isLoaded(loadOptions?.locale ?? locale);\n },\n async load(loadOptions) {\n assertLive();\n\n const targetLocale = canonicalLocale(loadOptions?.locale ?? locale);\n const changed = await loadTargets(targetLocale);\n\n assertLive();\n if (changed.some(relevant)) notify();\n },\n get locale() {\n return locale;\n },\n parts(key: string, translateOptions) {\n return snapshot.translator.partsDynamic(key, translateOptions);\n },\n partsDynamic(key, translateOptions) {\n return snapshot.translator.partsDynamic(key, translateOptions);\n },\n serialize() {\n assertLive();\n\n return catalogs.state(locale);\n },\n async setLocale(nextLocale) {\n assertLive();\n\n const next = canonicalLocale(nextLocale);\n const request = ++transition;\n const changed = await loadTargets(next);\n\n assertLive();\n if (request !== transition) return;\n\n if (next === locale) {\n if (changed.some(relevant)) notify();\n\n return;\n }\n\n locale = next;\n notify();\n },\n subscribe(listener, subscribeOptions) {\n assertLive();\n\n if (subscribeOptions?.signal?.aborted) return () => {};\n\n const unsubscribe = (): void => {\n subscribers.delete(listener);\n subscribeOptions?.signal?.removeEventListener('abort', unsubscribe);\n };\n\n subscribeOptions?.signal?.addEventListener('abort', unsubscribe, { once: true });\n subscribers.add(listener);\n\n if (subscribeOptions?.immediate) dispatch(listener);\n\n return unsubscribe;\n },\n [Symbol.dispose]: dispose,\n translate(key: string, translateOptions = {}) {\n return snapshot.translator.translateDynamic(key, translateOptions);\n },\n translateDynamic(key, translateOptions) {\n return snapshot.translator.translateDynamic(key, translateOptions);\n },\n } as I18n<C>;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- var Lingua=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=/\{([\p{ID_Continue}-]+)\}/gu;function n(e){let n=[],r=0;for(let i of e.matchAll(t)){let t=i.index??0;t>r&&n.push(e.slice(r,t)),n.push({value:i[1]}),r=t+i[0].length}return r<e.length&&n.push(e.slice(r)),n}function r(e,t,n){return e.map(e=>{if(typeof e==`string`)return e;let r=Object.hasOwn(t,e.value)?t[e.value]:void 0;return r==null?n(e.value):String(r)}).join(``)}function i(e,t,n){let r=[];for(let i of e){if(typeof i==`string`){i!==``&&r.push(i);continue}r.push(Object.hasOwn(t,i.value)?t[i.value]:n(i.value))}return r}var a=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},o=class extends a{constructor(){super(`Operation called on a disposed translation store.`)}},s=class extends a{},c=class extends a{},l=class extends a{},u=class extends a{},d=class extends a{},f=new Set([`__proto__`,`constructor`,`prototype`]);function p(e){return typeof e==`object`&&!!e&&Object.hasOwn(e,`plural`)}function m(e){let t=new Map,r=(e,i)=>{if(typeof e==`string`){t.set(i,{kind:`text`,template:n(e)});return}if(typeof e!=`object`||!e||Array.isArray(e))throw new s(`Catalog node "${i}" must be a string, plural message, or object.`);if(p(e)){if(Reflect.ownKeys(e).some(e=>e!==`plural`))throw new s(`Plural message "${i}" must contain only a "plural" property.`);if(typeof e.plural!=`object`||e.plural===null||Array.isArray(e.plural))throw new s(`Plural message "${i}" must provide an object of string forms.`);let r=new Map;for(let[t,a]of Object.entries(e.plural)){if(typeof a!=`string`)throw new s(`Plural form "${i}.${t}" must be a string.`);r.set(t,n(a))}t.set(i,{forms:r,kind:`plural`});return}for(let[t,n]of Object.entries(e)){if(f.has(t))throw new s(`Catalog key "${t}" is reserved.`);r(n,i?`${i}.${t}`:t)}};for(let[t,n]of Object.entries(e)){if(f.has(t))throw new s(`Catalog key "${t}" is reserved.`);r(n,t)}return t}function h(e){return[...m(typeof e==`object`&&e&&`serialize`in e&&`getSnapshot`in e?e.serialize().catalogs[e.locale]:e).keys()]}var g=new Map;function _(e){try{let[t]=Intl.getCanonicalLocales(e);if(t)return t}catch{}throw new c(`Invalid BCP 47 locale tag: "${e}".`)}function v(e,t){let n=new Set;for(let r of[e,...t]){let e=r.split(`-`);for(let t=e.length;t>0;t--)n.add(e.slice(0,t).join(`-`))}return[...n]}function y(e,t,n){let r=`${e}:${n?`ordinal`:`cardinal`}`,i=g.get(r);return i||(i=new Intl.PluralRules(e,{type:n?`ordinal`:`cardinal`}),g.set(r,i)),i.select(t)}function b(e){let t=new Map,n=new Map,r=new Map;for(let[n,r]of Object.entries(e))t.set(_(n),r);let i=(e,t)=>{n.set(e,{catalog:t,compiled:m(t)})};for(let[e,n]of t)typeof n!=`function`&&i(e,n);return{catalogMap(){return new Map([...n].map(([e,{compiled:t}])=>[e,t]))},isLoaded(e){return n.has(_(e))},load:async e=>{let a=_(e);if(n.has(a))return!1;let o=t.get(a);if(!o)throw new d(`Catalog has no source for locale "${a}".`);if(typeof o!=`function`)return i(a,o),!0;let s=r.get(a);if(s)return await s,!1;let c=o().then(e=>{i(a,e),r.delete(a)},e=>{throw r.delete(a),e});return r.set(a,c),await c,!0},state(e){let t={};for(let[e,{catalog:r}]of n)t[e]=r;return{catalogs:t,locale:e,version:3}}}}function x(e,t={}){let n=_(t.locale??`en`),a=v(n,(Array.isArray(t.fallback)?t.fallback:t.fallback?[t.fallback]:[]).map(_)),o=t.onMissingKey??(e=>e),s=t.onMissingValue??(e=>`{${e}}`),c=t=>{for(let n of a){let r=e.get(n)?.get(t);if(r)return{locale:n,message:r}}},u=(e,t)=>{let n=c(e);if(!n)return;if(n.message.kind===`text`)return`count`in t?void 0:{key:e,template:n.message.template};if(!(`count`in t)||!Number.isFinite(t.count)){if(`count`in t)throw new l("`count` must be a finite number.");return}let r=t.count===0&&!t.ordinal?`zero`:y(n.locale,t.count,t.ordinal??!1),i=n.message.forms.get(r)??n.message.forms.get(`other`);return i?{key:e,template:i}:void 0},d=e=>`count`in e?{count:e.count,...e.values}:e.values??{},f=(e,t)=>{let r=u(e,t);return r?i(r.template,d(t),e=>s(e,r.key,n)):[o(e,n)]},p=(e,t={})=>{let i=u(e,t);return i?r(i.template,d(t),e=>s(e,i.key,n)):o(e,n)};return{locale:n,segments(e,t){return f(e,t)},segmentsDynamic:f,translate(e,t={}){return p(e,t)},translateDynamic:p}}function S(e,t={}){let n=_(t.locale??`en`);return x(new Map([[n,m(e)]]),{...t,locale:n})}function C(e,t){let n=new Map;for(let[t,r]of Object.entries(e))n.set(_(t),m(r));return x(n,t)}function w(e){let t=b(e.catalogs),n=e.fallback,r=(Array.isArray(n)?n:n?[n]:[]).map(_),i=new AbortController,a=new Set,s=!1,c=_(e.locale??`en`),l=0,u=()=>({locale:c,revision:l,translator:x(t.catalogMap(),{...e,fallback:n,locale:c})}),d=u(),f=()=>{if(s)throw new o},p=()=>{s||(s=!0,a.clear(),i.abort())},m=e=>{try{e(d)}catch{}},h=()=>{l++,d=u();for(let e of[...a])m(e)},g=e=>v(c,r).includes(e);return{get disposalSignal(){return i.signal},dispose:p,get disposed(){return s},getSnapshot(){return d},isLoaded(e){return!s&&t.isLoaded(e?.locale??c)},async load(e){f();let n=_(e?.locale??c),r=await t.load(n);!s&&r&&g(n)&&h()},get locale(){return c},segments(e,t){return d.translator.segmentsDynamic(e,t)},segmentsDynamic(e,t){return d.translator.segmentsDynamic(e,t)},serialize(){return f(),t.state(c)},async setLocale(e){f();let t=_(e);t!==c&&(c=t,h())},subscribe(e,t){if(f(),t?.signal?.aborted)return()=>{};let n=()=>{a.delete(e),t?.signal?.removeEventListener(`abort`,n)};return t?.signal?.addEventListener(`abort`,n,{once:!0}),a.add(e),t?.immediate&&m(e),n},[Symbol.dispose]:p,translate(e,t={}){return d.translator.translateDynamic(e,t)},translateDynamic(e,t){return d.translator.translateDynamic(e,t)}}}function T(e,t){if(e.version!==3)throw new u(`Unsupported lingua state version: ${String(e.version)}.`);return w({...t,catalogs:e.catalogs,locale:e.locale})}return e.LinguaDisposedError=o,e.LinguaError=a,e.LinguaInvalidCatalogError=s,e.LinguaInvalidLocaleError=c,e.LinguaInvalidPluralCountError=l,e.LinguaInvalidStateError=u,e.LinguaMissingCatalogError=d,e.catalogKeys=h,e.createCatalogTranslator=S,e.createTranslationStore=w,e.createTranslator=C,e.hydrateTranslationStore=T,e})({});
1
+ var Lingua=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=/\{([\p{ID_Continue}-]+)\}/gu;function n(e){let n=[],r=0;for(let i of e.matchAll(t)){let t=i.index??0;t>r&&n.push(e.slice(r,t)),n.push({value:i[1]}),r=t+i[0].length}return r<e.length&&n.push(e.slice(r)),n}function r(e,t,n){return e.map(e=>{if(typeof e==`string`)return e;let r=Object.hasOwn(t,e.value)?t[e.value]:void 0;return r==null?n(e.value):String(r)}).join(``)}function i(e,t,n){let r=[];for(let i of e){if(typeof i==`string`){i!==``&&r.push({type:`text`,value:i});continue}Object.hasOwn(t,i.value)?r.push({type:`value`,value:t[i.value]}):r.push({type:`text`,value:n(i.value)})}return r}var a=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},o=class extends a{constructor(){super(`Operation called on a disposed i18n instance.`)}},s=class extends a{},c=class extends a{},l=class extends a{},u=class extends a{},d=class extends a{},f=class extends a{},p=class extends a{},m=new Set([`__proto__`,`constructor`,`prototype`]);function h(e){return typeof e==`object`&&!!e&&Object.hasOwn(e,`plural`)}function g(e){let t=new Map,r=(e,i)=>{if(typeof e==`string`){t.set(i,{kind:`text`,template:n(e)});return}if(typeof e!=`object`||!e||Array.isArray(e))throw new s(`Catalog node "${i}" must be a string, plural message, or object.`);if(h(e)){if(Reflect.ownKeys(e).some(e=>e!==`plural`))throw new s(`Plural message "${i}" must contain only a "plural" property.`);if(typeof e.plural!=`object`||e.plural===null||Array.isArray(e.plural))throw new s(`Plural message "${i}" must provide an object of string forms.`);let r=new Map;for(let[t,a]of Object.entries(e.plural)){if(typeof a!=`string`)throw new s(`Plural form "${i}.${t}" must be a string.`);r.set(t,n(a))}t.set(i,{forms:r,kind:`plural`});return}for(let[t,n]of Object.entries(e)){if(m.has(t))throw new s(`Catalog key "${t}" is reserved.`);r(n,i?`${i}.${t}`:t)}};for(let[t,n]of Object.entries(e)){if(m.has(t))throw new s(`Catalog key "${t}" is reserved.`);r(n,t)}return t}function _(e){if(typeof e==`object`&&e&&`serialize`in e&&`getSnapshot`in e){let t=e,n=t.serialize().catalogs[t.locale];if(!n)throw new d(`No catalog loaded for locale "${t.locale}".`);return[...g(n).keys()]}return[...g(e).keys()]}var v=new Map;function y(e){try{let[t]=Intl.getCanonicalLocales(e);if(t)return t}catch{}throw new c(`Invalid BCP 47 locale tag: "${e}".`)}function b(e,t){let n=new Set;for(let r of[e,...t]){let e=r.split(`-`);for(let t=e.length;t>0;t--)n.add(e.slice(0,t).join(`-`))}return[...n]}function x(e,t,n){let r=`${e}:${n?`ordinal`:`cardinal`}`,i=v.get(r);return i||(i=new Intl.PluralRules(e,{type:n?`ordinal`:`cardinal`}),v.set(r,i)),i.select(t)}function S(e){let t=new Map,n=new Map,r=(e,n)=>{t.set(y(e),{catalog:n,compiled:g(n)})};for(let[t,n]of Object.entries(e.catalogs??{}))r(t,n);return{catalogMap(){return new Map([...t].map(([e,{compiled:t}])=>[e,t]))},hydrate:r,isLoaded(e){return t.has(y(e))},load:async i=>{let a=y(i);if(t.has(a))return!1;let o=n.get(a);if(o)return await o,!1;if(!e.loadCatalog)throw new d(`No catalog source provided for locale "${a}".`);let s=Promise.resolve(e.loadCatalog(a)).then(e=>{r(a,e),n.delete(a)},e=>{throw n.delete(a),e});return n.set(a,s),await s,!0},state(e){let n={};for(let[e,{catalog:r}]of t)n[e]=r;return{catalogs:n,locale:e,version:4}}}}function C(e,t){if(e===`throw`)throw t.name?new p(`Missing interpolation value "${t.name}" for key "${t.key}" in locale "${t.locale}".`):new f(`Missing translation key "${t.key}" in locale "${t.locale}".`);return typeof e==`function`?e(t):t.name?`{${t.name}}`:t.key}function w(e,t={}){let n=y(t.locale??`en`),a=b(n,(Array.isArray(t.fallback)?t.fallback:t.fallback?[t.fallback]:[]).map(y)),o=t.missing,s=e=>C(o,{key:e,locale:n}),c=(e,t)=>C(o,{key:t,locale:n,name:e}),u=t=>{for(let n of a){let r=e.get(n)?.get(t);if(r)return{locale:n,message:r}}},d=(e,t)=>{let n=u(e);if(!n)return;if(n.message.kind===`text`)return`count`in t?void 0:{key:e,template:n.message.template};if(!(`count`in t)||!Number.isFinite(t.count)){if(`count`in t)throw new l("`count` must be a finite number.");return}let r=t.count===0&&!t.ordinal?`zero`:x(n.locale,t.count,t.ordinal??!1),i=n.message.forms.get(r)??n.message.forms.get(`other`);return i?{key:e,template:i}:void 0},f=e=>`count`in e?{count:e.count,...e.values}:e.values??{},p=(e,t)=>{let n=d(e,t);return n?i(n.template,f(t),e=>c(e,n.key)):[{type:`text`,value:s(e)}]},m=(e,t={})=>{let n=d(e,t);return n?r(n.template,f(t),e=>c(e,n.key)):s(e)};return{locale:n,parts(e,t){return p(e,t)},partsDynamic:p,translate(e,t={}){return m(e,t)},translateDynamic:m}}function T(e,t){let n=y(t?.locale??`en`);return w(new Map([[n,g(e)]]),{...t,locale:n})}function E(e){if(e.state&&e.state.version!==4)throw new u(`Unsupported lingua state version: ${String(e.state.version)}.`);let t=e.fallback,n=(Array.isArray(t)?t:t?[t]:[]).map(y),r=new AbortController,i=new Set,a=!1,s=y(e.locale??e.state?.locale??`en`),c=0,l=0,f=S({catalogs:e.catalogs,loadCatalog:e.loadCatalog});if(e.state)for(let[t,n]of Object.entries(e.state.catalogs))f.hydrate(t,n);let p=async e=>{let t=[];for(let r of new Set([e,...n]))await f.load(r)&&t.push(r);return t},m=()=>{let r=b(s,n).some(f.isLoaded)?e.missing:()=>{throw new d(`No catalog loaded for locale "${s}". Call load() before translating.`)};return{locale:s,revision:c,translator:w(f.catalogMap(),{fallback:t,locale:s,missing:r})}},h=m(),g=()=>{if(a)throw new o},_=()=>{a||(a=!0,i.clear(),r.abort())},v=e=>{try{e(h)}catch{}},x=()=>{c++,h=m();for(let e of[...i])v(e)},C=e=>b(s,n).includes(e);return{get disposalSignal(){return r.signal},dispose:_,get disposed(){return a},getSnapshot(){return h},isLoaded(e){return!a&&f.isLoaded(e?.locale??s)},async load(e){g();let t=y(e?.locale??s),n=await p(t);g(),n.some(C)&&x()},get locale(){return s},parts(e,t){return h.translator.partsDynamic(e,t)},partsDynamic(e,t){return h.translator.partsDynamic(e,t)},serialize(){return g(),f.state(s)},async setLocale(e){g();let t=y(e),n=++l,r=await p(t);if(g(),n===l){if(t===s){r.some(C)&&x();return}s=t,x()}},subscribe(e,t){if(g(),t?.signal?.aborted)return()=>{};let n=()=>{i.delete(e),t?.signal?.removeEventListener(`abort`,n)};return t?.signal?.addEventListener(`abort`,n,{once:!0}),i.add(e),t?.immediate&&v(e),n},[Symbol.dispose]:_,translate(e,t={}){return h.translator.translateDynamic(e,t)},translateDynamic(e,t){return h.translator.translateDynamic(e,t)}}}return e.LinguaDisposedError=o,e.LinguaError=a,e.LinguaInvalidCatalogError=s,e.LinguaInvalidLocaleError=c,e.LinguaInvalidPluralCountError=l,e.LinguaInvalidStateError=u,e.LinguaMissingCatalogError=d,e.LinguaMissingKeyError=f,e.LinguaMissingValueError=p,e.catalogKeys=_,e.createI18n=E,e.createTranslator=T,e})({});
2
2
  //# sourceMappingURL=lingua.iife.js.map