@vielzeug/lingua 1.1.4 → 2.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 (118) hide show
  1. package/README.md +15 -54
  2. package/dist/_catalog.cjs +1 -1
  3. package/dist/_catalog.cjs.map +1 -1
  4. package/dist/_catalog.d.ts +13 -16
  5. package/dist/_catalog.d.ts.map +1 -1
  6. package/dist/_catalog.js +43 -36
  7. package/dist/_catalog.js.map +1 -1
  8. package/dist/_dev.cjs +1 -1
  9. package/dist/_dev.cjs.map +1 -1
  10. package/dist/_dev.js +3 -11
  11. package/dist/_dev.js.map +1 -1
  12. package/dist/_locale.cjs +2 -0
  13. package/dist/_locale.cjs.map +1 -0
  14. package/dist/_locale.d.ts +5 -0
  15. package/dist/_locale.d.ts.map +1 -0
  16. package/dist/_locale.js +26 -0
  17. package/dist/_locale.js.map +1 -0
  18. package/dist/_resources.cjs +2 -0
  19. package/dist/_resources.cjs.map +1 -0
  20. package/dist/_resources.d.ts +10 -0
  21. package/dist/_resources.d.ts.map +1 -0
  22. package/dist/_resources.js +51 -0
  23. package/dist/_resources.js.map +1 -0
  24. package/dist/_template.cjs +2 -0
  25. package/dist/_template.cjs.map +1 -0
  26. package/dist/_template.d.ts +8 -0
  27. package/dist/_template.d.ts.map +1 -0
  28. package/dist/_template.js +32 -0
  29. package/dist/_template.js.map +1 -0
  30. package/dist/errors.cjs +1 -1
  31. package/dist/errors.cjs.map +1 -1
  32. package/dist/errors.d.ts +6 -18
  33. package/dist/errors.d.ts.map +1 -1
  34. package/dist/errors.js +3 -9
  35. package/dist/errors.js.map +1 -1
  36. package/dist/format.cjs +1 -1
  37. package/dist/format.cjs.map +1 -1
  38. package/dist/format.d.ts +0 -9
  39. package/dist/format.d.ts.map +1 -1
  40. package/dist/format.js +10 -12
  41. package/dist/format.js.map +1 -1
  42. package/dist/i18n.cjs +1 -1
  43. package/dist/i18n.cjs.map +1 -1
  44. package/dist/i18n.d.ts +25 -11
  45. package/dist/i18n.d.ts.map +1 -1
  46. package/dist/i18n.js +66 -183
  47. package/dist/i18n.js.map +1 -1
  48. package/dist/index.cjs +1 -1
  49. package/dist/index.d.ts +4 -12
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +4 -4
  52. package/dist/lingua.cjs +1 -1
  53. package/dist/lingua.cjs.map +1 -1
  54. package/dist/lingua.iife.js +1 -1
  55. package/dist/lingua.iife.js.map +1 -1
  56. package/dist/lingua.js +1 -1
  57. package/dist/lingua.js.map +1 -1
  58. package/dist/translator.cjs +2 -0
  59. package/dist/translator.cjs.map +1 -0
  60. package/dist/translator.d.ts +20 -0
  61. package/dist/translator.d.ts.map +1 -0
  62. package/dist/translator.js +61 -0
  63. package/dist/translator.js.map +1 -0
  64. package/dist/types.d.ts +53 -0
  65. package/dist/types.d.ts.map +1 -0
  66. package/dist/validate.cjs +1 -1
  67. package/dist/validate.cjs.map +1 -1
  68. package/dist/validate.d.ts +5 -37
  69. package/dist/validate.d.ts.map +1 -1
  70. package/dist/validate.js +21 -52
  71. package/dist/validate.js.map +1 -1
  72. package/package.json +4 -4
  73. package/dist/_catalog-store.cjs +0 -2
  74. package/dist/_catalog-store.cjs.map +0 -1
  75. package/dist/_catalog-store.d.ts +0 -34
  76. package/dist/_catalog-store.d.ts.map +0 -1
  77. package/dist/_catalog-store.js +0 -81
  78. package/dist/_catalog-store.js.map +0 -1
  79. package/dist/_chain.cjs +0 -2
  80. package/dist/_chain.cjs.map +0 -1
  81. package/dist/_chain.d.ts +0 -21
  82. package/dist/_chain.d.ts.map +0 -1
  83. package/dist/_chain.js +0 -45
  84. package/dist/_chain.js.map +0 -1
  85. package/dist/_constants.cjs +0 -2
  86. package/dist/_constants.cjs.map +0 -1
  87. package/dist/_constants.d.ts +0 -3
  88. package/dist/_constants.d.ts.map +0 -1
  89. package/dist/_constants.js +0 -17
  90. package/dist/_constants.js.map +0 -1
  91. package/dist/_namespace-store.cjs +0 -2
  92. package/dist/_namespace-store.cjs.map +0 -1
  93. package/dist/_namespace-store.d.ts +0 -31
  94. package/dist/_namespace-store.d.ts.map +0 -1
  95. package/dist/_namespace-store.js +0 -54
  96. package/dist/_namespace-store.js.map +0 -1
  97. package/dist/_translate.cjs +0 -2
  98. package/dist/_translate.cjs.map +0 -1
  99. package/dist/_translate.d.ts +0 -21
  100. package/dist/_translate.d.ts.map +0 -1
  101. package/dist/_translate.js +0 -54
  102. package/dist/_translate.js.map +0 -1
  103. package/dist/i18n-types.d.ts +0 -261
  104. package/dist/i18n-types.d.ts.map +0 -1
  105. package/dist/template-BZRFdmaQ.cjs +0 -2
  106. package/dist/template-BZRFdmaQ.cjs.map +0 -1
  107. package/dist/template-BihTfBYb.js +0 -2
  108. package/dist/template-BihTfBYb.js.map +0 -1
  109. package/dist/template.cjs +0 -2
  110. package/dist/template.cjs.map +0 -1
  111. package/dist/template.d.ts +0 -15
  112. package/dist/template.d.ts.map +0 -1
  113. package/dist/template.js +0 -49
  114. package/dist/template.js.map +0 -1
  115. package/dist/validate-D1U8TTeT.js +0 -2
  116. package/dist/validate-D1U8TTeT.js.map +0 -1
  117. package/dist/validate-x7lFFyV2.cjs +0 -2
  118. package/dist/validate-x7lFFyV2.cjs.map +0 -1
package/dist/i18n.js CHANGED
@@ -1,208 +1,91 @@
1
- import { getOrCreate as e } from "./_bounded-cache.js";
2
- import { createFormatter as t } from "./format.js";
3
- import { error as n } from "./_dev.js";
4
- import { CatalogEntry as r, flattenStrings as i } from "./_catalog.js";
5
- import { LinguaCountInVarsError as a, LinguaDisposedError as o, LinguaError as s, LinguaInvalidCountError as c, LinguaInvalidLocaleError as l, LinguaMissingLocaleError as u, LinguaNamespaceMissingError as d, LinguaRestoreError as f, checkDisposed as p } from "./errors.js";
6
- import { createCatalogStore as m, validateCatalogInDev as h } from "./_catalog-store.js";
7
- import { buildLocaleChain as g, canon as _, createLocaleCaches as v } from "./_chain.js";
8
- import { createNamespaceStore as y } from "./_namespace-store.js";
9
- import { hasKey as b, translate as x, translatePlural as S } from "./_translate.js";
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";
10
6
  //#region src/i18n.ts
11
- var C = 128;
12
- function w(e, t, n) {
13
- let { chain: r, set: i } = g(e, t, n);
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) => {
21
+ try {
22
+ e(h);
23
+ } catch {}
24
+ }, y = () => {
25
+ p++, h = m();
26
+ for (let e of [...u]) v(e);
27
+ }, b = (e) => r(f, c).includes(e);
14
28
  return {
15
- chain: r,
16
- chainSet: i,
17
- locale: e
18
- };
19
- }
20
- function T(e) {
21
- return E(e);
22
- }
23
- function E(a, s) {
24
- let c = a ?? {}, l = v(), u = (e) => _(e, l), d = Array.isArray(c.fallback) ? c.fallback.map(u) : c.fallback ? [u(c.fallback)] : [], g = !1, T = new AbortController(), D = m(() => g), O = y(() => g), k = w(u(c.locale ?? "en"), d, l), A = /* @__PURE__ */ new Set(), j = /* @__PURE__ */ new Set(), M = c.onMissingKey ?? ((e) => e), N = c.onMissingVar ?? ((e) => `{${e}}`), P = c.onSubscriberError ?? ((e) => n("subscriber error", e)), F, I = /* @__PURE__ */ new Map(), L = () => (F ||= t(() => k.locale), F), R = () => ({
25
- caches: l,
26
- catalogStore: D,
27
- chain: k.chain,
28
- locale: k.locale,
29
- onMissingKey: M,
30
- onMissingVar: N
31
- }), z = (e) => b(R(), e), B = (e, t) => x(R(), String(e), t), V = (e, t, n) => S(R(), String(e), t, n), H = {
32
- locale: k.locale,
33
- t: B,
34
- tp: V
35
- }, U = () => {
36
- H = {
37
- locale: k.locale,
38
- t: B,
39
- tp: V
40
- };
41
- let e = [...A];
42
- for (let t of e) try {
43
- t(H);
44
- } catch (e) {
45
- P(e);
46
- }
47
- };
48
- if (D.onChange = (e) => {
49
- k.chainSet.has(e) && U();
50
- }, s?.catalogStore && D.seedFrom(s.catalogStore.snapshotCatalogs(), s.catalogStore.snapshotLoaders()), s?.nsStore && O.seedFrom(s.nsStore), c.catalogs) {
51
- let e = /* @__PURE__ */ new Map(), t = /* @__PURE__ */ new Map();
52
- for (let [n, a] of Object.entries(c.catalogs)) {
53
- let o = u(n);
54
- if (typeof a == "function") t.set(o, a);
55
- else {
56
- let t = new r();
57
- t.setAll(i(a)), e.set(o, t), h(o, a);
58
- }
59
- }
60
- D.seedFrom(e, t);
61
- }
62
- let W = (e) => D.preload(u(e)), G = 0, K = {
63
29
  get disposalSignal() {
64
- return T.signal;
65
- },
66
- dispose() {
67
- if (!g) {
68
- g = !0, T.abort();
69
- for (let e of [...j]) e();
70
- j.clear(), A.clear(), D.dispose(), O.dispose(), I.clear();
71
- }
30
+ return l.signal;
72
31
  },
32
+ dispose: _,
73
33
  get disposed() {
74
- return g;
75
- },
76
- extend(e, t, n) {
77
- p(g), O.registerNamespace(e, t);
78
- let r = n ? u(n) : k.locale;
79
- return O.loadNamespace(e, r, (e, t) => D.patch(e, t));
80
- },
81
- get fmt() {
82
- return L();
83
- },
84
- fork(e) {
85
- return E({
86
- fallback: e?.fallback ?? (d.length > 0 ? d : void 0),
87
- locale: e?.locale ?? k.locale,
88
- onMissingKey: e?.onMissingKey ?? c.onMissingKey,
89
- onMissingVar: e?.onMissingVar ?? c.onMissingVar,
90
- onSubscriberError: e?.onSubscriberError ?? c.onSubscriberError
91
- }, {
92
- catalogStore: D,
93
- nsStore: O
94
- });
34
+ return d;
95
35
  },
96
36
  getSnapshot() {
97
- return H;
98
- },
99
- getState() {
100
- let e = {};
101
- for (let [t, n] of D.snapshotCatalogs()) e[t] = Object.fromEntries([...n.entries.entries()].map(([e, { message: t }]) => [e, t]));
102
- return {
103
- catalogs: e,
104
- locale: k.locale
105
- };
106
- },
107
- getSupportedLocales(e) {
108
- let t = [...D.knownLocales()];
109
- return e === !0 ? t.sort() : t;
110
- },
111
- has(e) {
112
- return z(String(e));
37
+ return h;
113
38
  },
114
39
  isLoaded(e) {
115
- try {
116
- return D.isLoaded(u(e));
117
- } catch {
118
- return !1;
119
- }
120
- },
121
- isNamespaceLoaded(e, t) {
122
- if (!t) return O.isLoaded(e, k.locale);
123
- try {
124
- return O.isLoaded(e, u(t));
125
- } catch {
126
- return !1;
127
- }
128
- },
129
- isNamespaceRegistered(e) {
130
- return O.isRegistered(e);
40
+ return !d && o.isLoaded(e?.locale ?? f);
131
41
  },
132
- isRegistered(e) {
133
- try {
134
- return D.isRegistered(u(e));
135
- } catch {
136
- return !1;
137
- }
138
- },
139
- loadNamespace(e, t) {
140
- let n = t ? u(t) : k.locale;
141
- return O.loadNamespace(e, n, (e, t) => D.patch(e, t));
42
+ async load(e) {
43
+ g();
44
+ let t = n(e?.locale ?? f), r = await o.load(t);
45
+ !d && r && b(t) && y();
142
46
  },
143
47
  get locale() {
144
- return k.locale;
145
- },
146
- preload: W,
147
- register(e, t) {
148
- let n = u(e);
149
- return D.register(n, t, O);
48
+ return f;
150
49
  },
151
- registerNamespace(e, t) {
152
- O.registerNamespace(e, t);
50
+ segments(e, t) {
51
+ return h.translator.segmentsDynamic(e, t);
153
52
  },
154
- restoreState(e) {
155
- if (p(g), !Object.hasOwn(e.catalogs, e.locale)) throw new f(`restoreState: locale "${e.locale}" has no catalog in the provided state.`);
156
- let t = /* @__PURE__ */ new Map(), n = D.knownLocales();
157
- for (let e of n) O.clearLocale(e);
158
- for (let [n, i] of Object.entries(e.catalogs)) {
159
- let e = u(n), a = new r();
160
- a.setAll(Object.entries(i)), t.set(e, a);
161
- }
162
- D.dispose(), D.onChange = (e) => {
163
- k.chainSet.has(e) && U();
164
- }, D.seedFrom(t, /* @__PURE__ */ new Map()), k = w(u(e.locale), d, l), F?.clear(), U();
53
+ segmentsDynamic(e, t) {
54
+ return h.translator.segmentsDynamic(e, t);
165
55
  },
166
- scope(t) {
167
- let n = String(t);
168
- return e(I, n, C, () => ({
169
- get fmt() {
170
- return L();
171
- },
172
- has: (e) => z(`${n}.${e}`),
173
- t: (e, t) => B(`${n}.${e}`, t),
174
- tp: (e, t, r) => V(`${n}.${e}`, t, r)
175
- }));
56
+ serialize() {
57
+ return g(), o.state(f);
176
58
  },
177
59
  async setLocale(e) {
178
- p(g);
179
- let t = u(e);
180
- if (k.locale === t) return;
181
- let n = ++G;
182
- await W(t), !(g || G !== n) && (k = w(t, d, l), F?.clear(), U());
183
- },
184
- subscribe: (e, t) => {
185
- let n = t?.signal, r = () => {
186
- A.delete(e), n?.removeEventListener("abort", r), j.delete(r);
60
+ g();
61
+ let t = n(e);
62
+ t !== f && (f = t, y());
63
+ },
64
+ subscribe(e, t) {
65
+ if (g(), t?.signal?.aborted) return () => {};
66
+ let n = () => {
67
+ u.delete(e), t?.signal?.removeEventListener("abort", n);
187
68
  };
188
- if (g) throw new o();
189
- if (n?.aborted) return r;
190
- if (t?.immediate === !0) try {
191
- e(H);
192
- } catch (e) {
193
- return P(e), r;
194
- }
195
- return A.add(e), n?.addEventListener("abort", r, { once: !0 }), j.add(r), r;
69
+ return t?.signal?.addEventListener("abort", n, { once: !0 }), u.add(e), t?.immediate && v(e), n;
196
70
  },
197
- [Symbol.dispose]() {
198
- K.dispose();
71
+ [Symbol.dispose]: _,
72
+ translate(e, t = {}) {
73
+ return h.translator.translateDynamic(e, t);
199
74
  },
200
- t: B,
201
- tp: V
75
+ translateDynamic(e, t) {
76
+ return h.translator.translateDynamic(e, t);
77
+ }
202
78
  };
203
- return K;
79
+ }
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
+ });
204
87
  }
205
88
  //#endregion
206
- export { a as LinguaCountInVarsError, o as LinguaDisposedError, s as LinguaError, c as LinguaInvalidCountError, l as LinguaInvalidLocaleError, u as LinguaMissingLocaleError, d as LinguaNamespaceMissingError, f as LinguaRestoreError, T as createI18n };
89
+ export { o as createTranslationStore, s as hydrateTranslationStore };
207
90
 
208
91
  //# 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 type {\n I18n,\n I18nOptions,\n I18nSnapshot,\n I18nState,\n Locale,\n MessageBranchKeys,\n MessageLeafKeys,\n ScopedI18n,\n SubscribeOptions,\n TpOptions,\n TranslateVars,\n Unsubscribe,\n} from './i18n-types';\n\nimport { getOrCreate } from './_bounded-cache';\nimport { CatalogEntry, type Messages, flattenStrings } from './_catalog';\nimport {\n type CatalogStore,\n type Loader,\n type LocaleSource,\n createCatalogStore,\n validateCatalogInDev,\n} from './_catalog-store';\nimport { type LocaleCaches, buildLocaleChain, canon, createLocaleCaches } from './_chain';\nimport { error as logError } from './_dev';\nimport { type NamespaceFactory, type NamespaceStore, createNamespaceStore } from './_namespace-store';\nimport {\n type TranslateContext,\n hasKey as hasKeyIn,\n translate as translateIn,\n translatePlural as translatePluralIn,\n} from './_translate';\nimport { LinguaDisposedError, LinguaRestoreError, checkDisposed } from './errors';\nimport { type Formatter, createFormatter } from './format';\n\nexport {\n LinguaCountInVarsError,\n LinguaDisposedError,\n LinguaError,\n LinguaInvalidCountError,\n LinguaInvalidLocaleError,\n LinguaMissingLocaleError,\n LinguaNamespaceMissingError,\n LinguaRestoreError,\n} from './errors';\n\nexport type {\n I18n,\n I18nOptions,\n I18nSnapshot,\n I18nState,\n Locale,\n MessageBranchKeys,\n MessageLeafKeys,\n ScopedI18n,\n SubscribeOptions,\n TpOptions,\n TranslateVars,\n Unsubscribe,\n} from './i18n-types';\nexport type { Loader, LocaleSource } from './_catalog-store';\nexport type { Messages } from './_catalog';\nexport type { NamespaceFactory } from './_namespace-store';\n\n// Bound for the per-instance `scope()` cache — see its declaration below for why it's bounded.\nconst SCOPE_CACHE_MAX = 128;\n\n// ─── Locale state ─────────────────────────────────────────────────────────────\n// Replaced atomically on every locale change.\n\ntype LocaleState = {\n readonly chain: readonly Locale[];\n readonly chainSet: ReadonlySet<Locale>;\n readonly locale: Locale;\n};\n\nfunction buildState(locale: Locale, fallback: Locale[], caches: LocaleCaches): LocaleState {\n const { chain, set } = buildLocaleChain(locale, fallback, caches);\n\n return { chain, chainSet: set, locale };\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\n/** Overload: explicit type parameter (strict typing) */\nexport function createI18n<M extends Messages>(config: I18nOptions<M>): I18n<M>;\n/** Overload: no type parameter (loose typing, allows heterogeneous catalogs) */\nexport function createI18n(config?: I18nOptions<Messages>): I18n<Messages>;\nexport function createI18n<M extends Messages = Messages>(config?: I18nOptions<M>): I18n<M> {\n return _createI18nImpl<M>(config);\n}\n\n// ─── Internal seed shape ──────────────────────────────────────────────────────\n\ntype I18nSeed<M extends Messages> = {\n catalogStore?: CatalogStore<M>;\n nsStore?: NamespaceStore;\n};\n\nfunction _createI18nImpl<M extends Messages = Messages>(config?: I18nOptions<M>, _seed?: I18nSeed<M>): I18n<M> {\n const cfg: I18nOptions<M> = config ?? {};\n\n // ─── Per-instance caches (no shared module-level state) ───────────────────\n const caches: LocaleCaches = createLocaleCaches();\n\n const canonL = (loc: string) => canon(loc, caches);\n\n const fallback = Array.isArray(cfg.fallback) ? cfg.fallback.map(canonL) : cfg.fallback ? [canonL(cfg.fallback)] : [];\n\n // ─── Disposal ─────────────────────────────────────────────────────────────\n let disposed = false;\n const disposeController = new AbortController();\n\n // ─── Bounded stores ───────────────────────────────────────────────────────\n const catalogStore: CatalogStore<M> = createCatalogStore(() => disposed);\n const nsStore: NamespaceStore = createNamespaceStore(() => disposed);\n\n // ─── Locale state ─────────────────────────────────────────────────────────\n let state: LocaleState = buildState(canonL(cfg.locale ?? 'en'), fallback, caches);\n\n // ─── Subscribers ──────────────────────────────────────────────────────────\n const subscribers = new Set<(snapshot: I18nSnapshot) => void>();\n const subscriptionUnsubscribers = new Set<Unsubscribe>();\n\n const onMissingKey = cfg.onMissingKey ?? ((key: string) => key);\n const onMissingVar = cfg.onMissingVar ?? ((varName: string) => `{${varName}}`);\n const onSubscriberError = cfg.onSubscriberError ?? ((error: unknown) => logError('subscriber error', error));\n\n // ─── Lazy formatter — avoids Intl overhead for SSR forks that only need t(). ──\n let _fmt: Formatter | undefined;\n\n // ─── Scope cache — stable object references per prefix for reactive framework renders. ──\n // Bounded the same way format.ts bounds its Intl-formatter caches: `scope()` is meant for a\n // static, finite set of prefixes (nav sections, form names, ...), but nothing stopped a caller\n // from passing a dynamic per-item prefix (e.g. `scope(`item.${id}`)` in a list render) and\n // growing this unboundedly for the instance's lifetime. Oldest entry evicts past the cap.\n const scopeCache = new Map<string, ScopedI18n>();\n\n const getFormatter = (): Formatter => {\n if (!_fmt) _fmt = createFormatter(() => state.locale);\n\n return _fmt;\n };\n\n // ─── Translate helpers ────────────────────────────────────────────────────\n // The actual algorithm (fallback-chain lookup, plural-form selection, interpolation) lives in\n // `_translate.ts` — this instance just supplies fresh context (current locale/chain) per call.\n\n const translateContext = (): TranslateContext => ({\n caches,\n catalogStore,\n chain: state.chain,\n locale: state.locale,\n onMissingKey,\n onMissingVar,\n });\n\n // Shared by has() and scope().has().\n const hasKey = (base: string): boolean => hasKeyIn(translateContext(), base);\n\n const translate = (key: MessageLeafKeys<M> | (string & {}), vars?: TranslateVars): string =>\n translateIn(translateContext(), String(key), vars);\n\n const translatePlural = (key: MessageBranchKeys<M> | (string & {}), count: number, options?: TpOptions): string =>\n translatePluralIn(translateContext(), String(key), count, options);\n\n // ─── bump() ───────────────────────────────────────────────────────────────\n // Rebuilds the snapshot and notifies all current subscribers.\n\n let snapshot: I18nSnapshot = {\n locale: state.locale,\n t: translate,\n tp: translatePlural,\n };\n\n const bump = (): void => {\n snapshot = { locale: state.locale, t: translate, tp: translatePlural };\n\n const listeners = [...subscribers];\n\n for (const listener of listeners) {\n try {\n listener(snapshot);\n } catch (error) {\n onSubscriberError(error);\n }\n }\n };\n\n // ─── Wire catalog store onChange → bump ───────────────────────────────────\n catalogStore.onChange = (loc: Locale) => {\n if (state.chainSet.has(loc)) bump();\n };\n\n // ─── Seed from parent fork ─────────────────────────────────────────────────\n if (_seed?.catalogStore) {\n catalogStore.seedFrom(_seed.catalogStore.snapshotCatalogs(), _seed.catalogStore.snapshotLoaders());\n }\n\n if (_seed?.nsStore) {\n nsStore.seedFrom(_seed.nsStore);\n }\n\n // ─── Initial catalogs from config ─────────────────────────────────────────\n if (cfg.catalogs) {\n const staticEntries = new Map<Locale, CatalogEntry>();\n const loaderEntries = new Map<Locale, Loader<M>>();\n\n for (const [loc, source] of Object.entries(cfg.catalogs)) {\n const normalized = canonL(loc);\n\n if (typeof source === 'function') {\n loaderEntries.set(normalized, source as Loader<M>);\n } else {\n const entry = new CatalogEntry();\n\n entry.setAll(flattenStrings(source as M));\n staticEntries.set(normalized, entry);\n validateCatalogInDev(normalized, source as M);\n }\n }\n\n // Use seedFrom for zero-overhead init (no bump, no notifications during setup)\n catalogStore.seedFrom(staticEntries, loaderEntries);\n }\n\n // ─── Preload helper ───────────────────────────────────────────────────────\n\n const preload = (loc: Locale): Promise<void> => catalogStore.preload(canonL(loc));\n\n // ─── Monotonic generation counter — last writer wins for concurrent setLocale() ──\n let switchGen = 0;\n\n // ─── Subscribe helper ─────────────────────────────────────────────────────\n\n const subscribeInternal = (callback: (snapshot: I18nSnapshot) => void, options?: SubscribeOptions): Unsubscribe => {\n const signal = options?.signal;\n\n const unsubscribe = (): void => {\n subscribers.delete(callback);\n signal?.removeEventListener('abort', unsubscribe);\n subscriptionUnsubscribers.delete(unsubscribe);\n };\n\n if (disposed) throw new LinguaDisposedError();\n\n if (signal?.aborted) return unsubscribe;\n\n if (options?.immediate === true) {\n try {\n callback(snapshot);\n } catch (error) {\n onSubscriberError(error);\n\n return unsubscribe;\n }\n }\n\n subscribers.add(callback);\n signal?.addEventListener('abort', unsubscribe, { once: true });\n subscriptionUnsubscribers.add(unsubscribe);\n\n return unsubscribe;\n };\n\n // ─── Public object ─────────────────────────────────────────────────────────\n // Named `const` (not a bare `return { ... }`) so `[Symbol.dispose]` below can close over\n // `source` directly instead of `this` — `this` inside an object-literal method is only bound\n // when called as `obj.method()`; detaching it first (`const d = i18n[Symbol.dispose]; d()`,\n // the exact shape most framework cleanup-hook APIs expect) would otherwise throw.\n\n const source: I18n<M> = {\n get disposalSignal(): AbortSignal {\n return disposeController.signal;\n },\n\n dispose(): void {\n if (disposed) return;\n\n disposed = true;\n disposeController.abort();\n for (const unsubscribe of [...subscriptionUnsubscribers]) unsubscribe();\n subscriptionUnsubscribers.clear();\n subscribers.clear();\n catalogStore.dispose();\n nsStore.dispose();\n scopeCache.clear();\n },\n\n get disposed(): boolean {\n return disposed;\n },\n\n extend(ns: string, factory: NamespaceFactory, loc?: Locale): Promise<void> {\n checkDisposed(disposed);\n\n nsStore.registerNamespace(ns, factory);\n\n const normalized = loc ? canonL(loc) : state.locale;\n\n return nsStore.loadNamespace(ns, normalized, (l, messages) => catalogStore.patch(l, messages));\n },\n\n get fmt(): Formatter {\n return getFormatter();\n },\n\n fork(overrides?: Omit<I18nOptions<M>, 'catalogs'>): I18n<M> {\n return _createI18nImpl(\n {\n fallback: overrides?.fallback ?? (fallback.length > 0 ? fallback : undefined),\n locale: overrides?.locale ?? state.locale,\n onMissingKey: overrides?.onMissingKey ?? cfg.onMissingKey,\n onMissingVar: overrides?.onMissingVar ?? cfg.onMissingVar,\n onSubscriberError: overrides?.onSubscriberError ?? cfg.onSubscriberError,\n },\n {\n catalogStore,\n nsStore,\n },\n );\n },\n\n getSnapshot() {\n return snapshot;\n },\n\n getState(): I18nState {\n const catalogsOut: Record<Locale, Record<string, string>> = {};\n\n for (const [loc, entry] of catalogStore.snapshotCatalogs()) {\n catalogsOut[loc] = Object.fromEntries([...entry.entries.entries()].map(([k, { message }]) => [k, message]));\n }\n\n return { catalogs: catalogsOut, locale: state.locale };\n },\n\n getSupportedLocales(sorted?: boolean): Locale[] {\n const locales = [...catalogStore.knownLocales()];\n\n return sorted === true ? locales.sort() : locales;\n },\n\n has(key: MessageLeafKeys<M> | MessageBranchKeys<M> | (string & {})): boolean {\n return hasKey(String(key));\n },\n\n isLoaded(loc: Locale): boolean {\n try {\n return catalogStore.isLoaded(canonL(loc));\n } catch {\n return false;\n }\n },\n\n isNamespaceLoaded(ns: string, loc?: Locale): boolean {\n if (!loc) return nsStore.isLoaded(ns, state.locale);\n\n try {\n return nsStore.isLoaded(ns, canonL(loc));\n } catch {\n return false;\n }\n },\n\n isNamespaceRegistered(ns: string): boolean {\n return nsStore.isRegistered(ns);\n },\n\n isRegistered(loc: Locale): boolean {\n try {\n return catalogStore.isRegistered(canonL(loc));\n } catch {\n return false;\n }\n },\n\n loadNamespace(ns: string, loc?: Locale): Promise<void> {\n const normalized = loc ? canonL(loc) : state.locale;\n\n return nsStore.loadNamespace(ns, normalized, (l, messages) => catalogStore.patch(l, messages));\n },\n\n get locale(): Locale {\n return state.locale;\n },\n\n preload,\n\n register(loc: Locale, source: LocaleSource<M>): Promise<void> {\n const normalized = canonL(loc);\n\n return catalogStore.register(normalized, source, nsStore);\n },\n\n registerNamespace(ns: string, factory: NamespaceFactory): void {\n nsStore.registerNamespace(ns, factory);\n },\n\n restoreState(st: I18nState): void {\n checkDisposed(disposed);\n\n if (!Object.hasOwn(st.catalogs, st.locale)) {\n throw new LinguaRestoreError(`restoreState: locale \"${st.locale}\" has no catalog in the provided state.`);\n }\n\n const freshEntries = new Map<Locale, CatalogEntry>();\n const knownLocales = catalogStore.knownLocales();\n\n for (const knownLocale of knownLocales) {\n nsStore.clearLocale(knownLocale);\n }\n\n // No validateCatalogInDev() call here, unlike register()/construction/preload(): `state`\n // is already flattened dot-notation (I18nState.catalogs), not the nested Messages shape\n // validateCatalog() expects, and restoreState() exists specifically for cheap SSR\n // hydration of a payload that was already registered — and therefore already\n // validated — once on the system that produced it. Re-validating here would mean\n // un-flattening every restored catalog back into nested form on every hydration, for a\n // check that's already run.\n for (const [loc, flatCatalog] of Object.entries(st.catalogs)) {\n const normalized = canonL(loc);\n const entry = new CatalogEntry();\n\n entry.setAll(Object.entries(flatCatalog));\n freshEntries.set(normalized, entry);\n }\n\n // Dispose and re-seed the catalog store with the restored entries.\n // onChange is re-wired immediately after dispose.\n catalogStore.dispose();\n catalogStore.onChange = (loc: Locale) => {\n if (state.chainSet.has(loc)) bump();\n };\n catalogStore.seedFrom(freshEntries, new Map());\n\n const normalized = canonL(st.locale);\n\n state = buildState(normalized, fallback, caches);\n _fmt?.clear();\n bump();\n },\n\n scope(prefix: MessageBranchKeys<M> | (string & {})): ScopedI18n {\n const pre = String(prefix);\n\n return getOrCreate(scopeCache, pre, SCOPE_CACHE_MAX, () => ({\n get fmt() {\n return getFormatter();\n },\n has: (key) => hasKey(`${pre}.${key}`),\n t: (key, vars?) => translate(`${pre}.${key}`, vars),\n tp: (key, count, options?) => translatePlural(`${pre}.${key}`, count, options),\n }));\n },\n\n async setLocale(next: Locale): Promise<void> {\n checkDisposed(disposed);\n\n const normalized = canonL(next);\n\n if (state.locale === normalized) return;\n\n // Monotonic generation counter — last writer wins.\n const gen = ++switchGen;\n\n await preload(normalized);\n\n if (disposed || switchGen !== gen) return;\n\n state = buildState(normalized, fallback, caches);\n _fmt?.clear();\n bump();\n },\n\n subscribe: subscribeInternal,\n\n [Symbol.dispose](): void {\n source.dispose();\n },\n\n t: translate,\n\n tp: translatePlural,\n };\n\n return source;\n}\n"],"mappings":";;;;;;;;;;AAkEA,IAAM,IAAkB;AAWxB,SAAS,EAAW,GAAgB,GAAoB,GAAmC;CACzF,IAAM,EAAE,UAAO,WAAQ,EAAiB,GAAQ,GAAU,CAAM;CAEhE,OAAO;EAAE;EAAO,UAAU;EAAK;CAAO;AACxC;AAQA,SAAgB,EAA0C,GAAkC;CAC1F,OAAO,EAAmB,CAAM;AAClC;AASA,SAAS,EAA+C,GAAyB,GAA8B;CAC7G,IAAM,IAAsB,KAAU,CAAC,GAGjC,IAAuB,EAAmB,GAE1C,KAAU,MAAgB,EAAM,GAAK,CAAM,GAE3C,IAAW,MAAM,QAAQ,EAAI,QAAQ,IAAI,EAAI,SAAS,IAAI,CAAM,IAAI,EAAI,WAAW,CAAC,EAAO,EAAI,QAAQ,CAAC,IAAI,CAAC,GAG/G,IAAW,IACT,IAAoB,IAAI,gBAAgB,GAGxC,IAAgC,QAAyB,CAAQ,GACjE,IAA0B,QAA2B,CAAQ,GAG/D,IAAqB,EAAW,EAAO,EAAI,UAAU,IAAI,GAAG,GAAU,CAAM,GAG1E,oBAAc,IAAI,IAAsC,GACxD,oBAA4B,IAAI,IAAiB,GAEjD,IAAe,EAAI,kBAAkB,MAAgB,IACrD,IAAe,EAAI,kBAAkB,MAAoB,IAAI,EAAQ,KACrE,IAAoB,EAAI,uBAAuB,MAAmB,EAAS,oBAAoB,CAAK,IAGtG,GAOE,oBAAa,IAAI,IAAwB,GAEzC,WACJ,AAAW,MAAO,QAAsB,EAAM,MAAM,GAE7C,IAOH,WAA4C;EAChD;EACA;EACA,OAAO,EAAM;EACb,QAAQ,EAAM;EACd;EACA;CACF,IAGM,KAAU,MAA0B,EAAS,EAAiB,GAAG,CAAI,GAErE,KAAa,GAAyC,MAC1D,EAAY,EAAiB,GAAG,OAAO,CAAG,GAAG,CAAI,GAE7C,KAAmB,GAA2C,GAAe,MACjF,EAAkB,EAAiB,GAAG,OAAO,CAAG,GAAG,GAAO,CAAO,GAK/D,IAAyB;EAC3B,QAAQ,EAAM;EACd,GAAG;EACH,IAAI;CACN,GAEM,UAAmB;EACvB,IAAW;GAAE,QAAQ,EAAM;GAAQ,GAAG;GAAW,IAAI;EAAgB;EAErE,IAAM,IAAY,CAAC,GAAG,CAAW;EAEjC,KAAK,IAAM,KAAY,GACrB,IAAI;GACF,EAAS,CAAQ;EACnB,SAAS,GAAO;GACd,EAAkB,CAAK;EACzB;CAEJ;CAiBA,IAdA,EAAa,YAAY,MAAgB;EACvC,AAAI,EAAM,SAAS,IAAI,CAAG,KAAG,EAAK;CACpC,GAGI,GAAO,gBACT,EAAa,SAAS,EAAM,aAAa,iBAAiB,GAAG,EAAM,aAAa,gBAAgB,CAAC,GAG/F,GAAO,WACT,EAAQ,SAAS,EAAM,OAAO,GAI5B,EAAI,UAAU;EAChB,IAAM,oBAAgB,IAAI,IAA0B,GAC9C,oBAAgB,IAAI,IAAuB;EAEjD,KAAK,IAAM,CAAC,GAAK,MAAW,OAAO,QAAQ,EAAI,QAAQ,GAAG;GACxD,IAAM,IAAa,EAAO,CAAG;GAE7B,IAAI,OAAO,KAAW,YACpB,EAAc,IAAI,GAAY,CAAmB;QAC5C;IACL,IAAM,IAAQ,IAAI,EAAa;IAI/B,AAFA,EAAM,OAAO,EAAe,CAAW,CAAC,GACxC,EAAc,IAAI,GAAY,CAAK,GACnC,EAAqB,GAAY,CAAW;GAC9C;EACF;EAGA,EAAa,SAAS,GAAe,CAAa;CACpD;CAIA,IAAM,KAAW,MAA+B,EAAa,QAAQ,EAAO,CAAG,CAAC,GAG5E,IAAY,GAwCV,IAAkB;EACtB,IAAI,iBAA8B;GAChC,OAAO,EAAkB;EAC3B;EAEA,UAAgB;GACV,QAGJ;IADA,IAAW,IACX,EAAkB,MAAM;IACxB,KAAK,IAAM,KAAe,CAAC,GAAG,CAAyB,GAAG,EAAY;IAKtE,AAJA,EAA0B,MAAM,GAChC,EAAY,MAAM,GAClB,EAAa,QAAQ,GACrB,EAAQ,QAAQ,GAChB,EAAW,MAAM;GANO;EAO1B;EAEA,IAAI,WAAoB;GACtB,OAAO;EACT;EAEA,OAAO,GAAY,GAA2B,GAA6B;GAGzE,AAFA,EAAc,CAAQ,GAEtB,EAAQ,kBAAkB,GAAI,CAAO;GAErC,IAAM,IAAa,IAAM,EAAO,CAAG,IAAI,EAAM;GAE7C,OAAO,EAAQ,cAAc,GAAI,IAAa,GAAG,MAAa,EAAa,MAAM,GAAG,CAAQ,CAAC;EAC/F;EAEA,IAAI,MAAiB;GACnB,OAAO,EAAa;EACtB;EAEA,KAAK,GAAuD;GAC1D,OAAO,EACL;IACE,UAAU,GAAW,aAAa,EAAS,SAAS,IAAI,IAAW,KAAA;IACnE,QAAQ,GAAW,UAAU,EAAM;IACnC,cAAc,GAAW,gBAAgB,EAAI;IAC7C,cAAc,GAAW,gBAAgB,EAAI;IAC7C,mBAAmB,GAAW,qBAAqB,EAAI;GACzD,GACA;IACE;IACA;GACF,CACF;EACF;EAEA,cAAc;GACZ,OAAO;EACT;EAEA,WAAsB;GACpB,IAAM,IAAsD,CAAC;GAE7D,KAAK,IAAM,CAAC,GAAK,MAAU,EAAa,iBAAiB,GACvD,EAAY,KAAO,OAAO,YAAY,CAAC,GAAG,EAAM,QAAQ,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,kBAAe,CAAC,GAAG,CAAO,CAAC,CAAC;GAG5G,OAAO;IAAE,UAAU;IAAa,QAAQ,EAAM;GAAO;EACvD;EAEA,oBAAoB,GAA4B;GAC9C,IAAM,IAAU,CAAC,GAAG,EAAa,aAAa,CAAC;GAE/C,OAAO,MAAW,KAAO,EAAQ,KAAK,IAAI;EAC5C;EAEA,IAAI,GAAyE;GAC3E,OAAO,EAAO,OAAO,CAAG,CAAC;EAC3B;EAEA,SAAS,GAAsB;GAC7B,IAAI;IACF,OAAO,EAAa,SAAS,EAAO,CAAG,CAAC;GAC1C,QAAQ;IACN,OAAO;GACT;EACF;EAEA,kBAAkB,GAAY,GAAuB;GACnD,IAAI,CAAC,GAAK,OAAO,EAAQ,SAAS,GAAI,EAAM,MAAM;GAElD,IAAI;IACF,OAAO,EAAQ,SAAS,GAAI,EAAO,CAAG,CAAC;GACzC,QAAQ;IACN,OAAO;GACT;EACF;EAEA,sBAAsB,GAAqB;GACzC,OAAO,EAAQ,aAAa,CAAE;EAChC;EAEA,aAAa,GAAsB;GACjC,IAAI;IACF,OAAO,EAAa,aAAa,EAAO,CAAG,CAAC;GAC9C,QAAQ;IACN,OAAO;GACT;EACF;EAEA,cAAc,GAAY,GAA6B;GACrD,IAAM,IAAa,IAAM,EAAO,CAAG,IAAI,EAAM;GAE7C,OAAO,EAAQ,cAAc,GAAI,IAAa,GAAG,MAAa,EAAa,MAAM,GAAG,CAAQ,CAAC;EAC/F;EAEA,IAAI,SAAiB;GACnB,OAAO,EAAM;EACf;EAEA;EAEA,SAAS,GAAa,GAAwC;GAC5D,IAAM,IAAa,EAAO,CAAG;GAE7B,OAAO,EAAa,SAAS,GAAY,GAAQ,CAAO;EAC1D;EAEA,kBAAkB,GAAY,GAAiC;GAC7D,EAAQ,kBAAkB,GAAI,CAAO;EACvC;EAEA,aAAa,GAAqB;GAGhC,IAFA,EAAc,CAAQ,GAElB,CAAC,OAAO,OAAO,EAAG,UAAU,EAAG,MAAM,GACvC,MAAM,IAAI,EAAmB,yBAAyB,EAAG,OAAO,wCAAwC;GAG1G,IAAM,oBAAe,IAAI,IAA0B,GAC7C,IAAe,EAAa,aAAa;GAE/C,KAAK,IAAM,KAAe,GACxB,EAAQ,YAAY,CAAW;GAUjC,KAAK,IAAM,CAAC,GAAK,MAAgB,OAAO,QAAQ,EAAG,QAAQ,GAAG;IAC5D,IAAM,IAAa,EAAO,CAAG,GACvB,IAAQ,IAAI,EAAa;IAG/B,AADA,EAAM,OAAO,OAAO,QAAQ,CAAW,CAAC,GACxC,EAAa,IAAI,GAAY,CAAK;GACpC;GAcA,AAVA,EAAa,QAAQ,GACrB,EAAa,YAAY,MAAgB;IACvC,AAAI,EAAM,SAAS,IAAI,CAAG,KAAG,EAAK;GACpC,GACA,EAAa,SAAS,mBAAc,IAAI,IAAI,CAAC,GAI7C,IAAQ,EAFW,EAAO,EAAG,MAEV,GAAY,GAAU,CAAM,GAC/C,GAAM,MAAM,GACZ,EAAK;EACP;EAEA,MAAM,GAA0D;GAC9D,IAAM,IAAM,OAAO,CAAM;GAEzB,OAAO,EAAY,GAAY,GAAK,UAAwB;IAC1D,IAAI,MAAM;KACR,OAAO,EAAa;IACtB;IACA,MAAM,MAAQ,EAAO,GAAG,EAAI,GAAG,GAAK;IACpC,IAAI,GAAK,MAAU,EAAU,GAAG,EAAI,GAAG,KAAO,CAAI;IAClD,KAAK,GAAK,GAAO,MAAa,EAAgB,GAAG,EAAI,GAAG,KAAO,GAAO,CAAO;GAC/E,EAAE;EACJ;EAEA,MAAM,UAAU,GAA6B;GAC3C,EAAc,CAAQ;GAEtB,IAAM,IAAa,EAAO,CAAI;GAE9B,IAAI,EAAM,WAAW,GAAY;GAGjC,IAAM,IAAM,EAAE;GAEd,MAAM,EAAQ,CAAU,GAEpB,OAAY,MAAc,OAE9B,IAAQ,EAAW,GAAY,GAAU,CAAM,GAC/C,GAAM,MAAM,GACZ,EAAK;EACP;EAEA,YAhPyB,GAA4C,MAA4C;GACjH,IAAM,IAAS,GAAS,QAElB,UAA0B;IAG9B,AAFA,EAAY,OAAO,CAAQ,GAC3B,GAAQ,oBAAoB,SAAS,CAAW,GAChD,EAA0B,OAAO,CAAW;GAC9C;GAEA,IAAI,GAAU,MAAM,IAAI,EAAoB;GAE5C,IAAI,GAAQ,SAAS,OAAO;GAE5B,IAAI,GAAS,cAAc,IACzB,IAAI;IACF,EAAS,CAAQ;GACnB,SAAS,GAAO;IAGd,OAFA,EAAkB,CAAK,GAEhB;GACT;GAOF,OAJA,EAAY,IAAI,CAAQ,GACxB,GAAQ,iBAAiB,SAAS,GAAa,EAAE,MAAM,GAAK,CAAC,GAC7D,EAA0B,IAAI,CAAW,GAElC;EACT;EAsNE,CAAC,OAAO,WAAiB;GACvB,EAAO,QAAQ;EACjB;EAEA,GAAG;EAEH,IAAI;CACN;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"i18n.js","names":[],"sources":["../src/i18n.ts"],"sourcesContent":["import type { Catalog, TranslationStoreOptions, TranslationState, Locale, SubscribeOptions } from './types';\n\nimport { error as logError } from './_dev';\nimport { canonicalLocale, localeChain } from './_locale';\nimport { createCatalogStore } from './_resources';\nimport { LinguaDisposedError, LinguaInvalidStateError } from './errors';\nimport { type Translator, createTranslatorFromCompiled } from './translator';\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":";;;;;;AA2BA,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"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./format.cjs"),t=require("./errors.cjs"),n=require("./i18n.cjs");exports.LinguaCountInVarsError=t.LinguaCountInVarsError,exports.LinguaDisposedError=t.LinguaDisposedError,exports.LinguaError=t.LinguaError,exports.LinguaInvalidCountError=t.LinguaInvalidCountError,exports.LinguaInvalidLocaleError=t.LinguaInvalidLocaleError,exports.LinguaMissingLocaleError=t.LinguaMissingLocaleError,exports.LinguaNamespaceMissingError=t.LinguaNamespaceMissingError,exports.LinguaRestoreError=t.LinguaRestoreError,exports.createFormatter=e.createFormatter,exports.createI18n=n.createI18n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./translator.cjs"),n=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.createTranslationStore=n.createTranslationStore,exports.createTranslator=t.createTranslator,exports.hydrateTranslationStore=n.hydrateTranslationStore;
package/dist/index.d.ts CHANGED
@@ -1,13 +1,5 @@
1
- /**
2
- * /lingua Lightweight, type-safe i18n runtime.
3
- *
4
- * @security `t()` and `tp()` return raw strings with no HTML sanitization.
5
- * If catalog content can originate from untrusted sources (user-generated content,
6
- * external CMS, writable APIs), sanitize translated strings before inserting them
7
- * into the DOM via `innerHTML`. Rendering via `.textContent` is always safe.
8
- */
9
- export type { I18n, I18nOptions, I18nSnapshot, I18nState, Loader, Locale, LocaleSource, MessageBranchKeys, MessageLeafKeys, Messages, NamespaceFactory, ScopedI18n, SubscribeOptions, TpOptions, TranslateVars, Unsubscribe, } from './i18n';
10
- export type { DurationFormatOptions, DurationValue, Formatter, ListFormatOptions } from './format';
11
- export { createFormatter } from './format';
12
- export { LinguaCountInVarsError, LinguaDisposedError, LinguaError, LinguaInvalidCountError, LinguaInvalidLocaleError, LinguaMissingLocaleError, LinguaNamespaceMissingError, LinguaRestoreError, createI18n, } from './i18n';
1
+ export { LinguaDisposedError, LinguaError, LinguaInvalidCatalogError, LinguaInvalidLocaleError, LinguaInvalidPluralCountError, LinguaInvalidStateError, LinguaMissingCatalogError, } from './errors';
2
+ export { createTranslationStore, hydrateTranslationStore, type TranslationSnapshot, type TranslationStore, } from './i18n';
3
+ export { createTranslator, type Translator } from './translator';
4
+ export type { Catalog, CatalogLoader, CatalogNode, Catalogs, CatalogSource, CatalogSources, TranslationState, TranslationStoreOptions, LoadedCatalogs, Locale, MessageKey, PluralCategory, PluralKey, PluralMessage, PluralOptions, SubscribeOptions, TextKey, TranslateOptions, TranslatorOptions, Values, } from './types';
13
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,EACV,IAAI,EACJ,WAAW,EACX,YAAY,EACZ,SAAS,EACT,MAAM,EACN,MAAM,EACN,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,WAAW,GACZ,MAAM,QAAQ,CAAC;AAEhB,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAEnG,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,WAAW,EACX,uBAAuB,EACvB,wBAAwB,EACxB,wBAAwB,EACxB,2BAA2B,EAC3B,kBAAkB,EAClB,UAAU,GACX,MAAM,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,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,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACjE,YAAY,EACV,OAAO,EACP,aAAa,EACb,WAAW,EACX,QAAQ,EACR,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,MAAM,EACN,UAAU,EACV,cAAc,EACd,SAAS,EACT,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,MAAM,GACP,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createFormatter as e } from "./format.js";
2
- import { LinguaCountInVarsError as t, LinguaDisposedError as n, LinguaError as r, LinguaInvalidCountError as i, LinguaInvalidLocaleError as a, LinguaMissingLocaleError as o, LinguaNamespaceMissingError as s, LinguaRestoreError as c } from "./errors.js";
3
- import { createI18n as l } from "./i18n.js";
4
- export { t as LinguaCountInVarsError, n as LinguaDisposedError, r as LinguaError, i as LinguaInvalidCountError, a as LinguaInvalidLocaleError, o as LinguaMissingLocaleError, s as LinguaNamespaceMissingError, c as LinguaRestoreError, e as createFormatter, l as createI18n };
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 { createTranslator as s } from "./translator.js";
3
+ import { createTranslationStore as c, hydrateTranslationStore as l } from "./i18n.js";
4
+ export { e as LinguaDisposedError, t as LinguaError, n as LinguaInvalidCatalogError, r as LinguaInvalidLocaleError, i as LinguaInvalidPluralCountError, a as LinguaInvalidStateError, o as LinguaMissingCatalogError, c as createTranslationStore, s as createTranslator, l as hydrateTranslationStore };
package/dist/lingua.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./template-BZRFdmaQ.cjs");function t(e,t,n,r){if(e.has(t))return e.get(t);let i=r();return e.size>=n&&e.delete(e.keys().next().value),e.set(t,i),i}var n=128,r=[`years`,`months`,`weeks`,`days`,`hours`,`minutes`,`seconds`,`milliseconds`,`microseconds`,`nanoseconds`],i={days:`d`,hours:`h`,microseconds:`us`,milliseconds:`ms`,minutes:`min`,months:`mo`,nanoseconds:`ns`,seconds:`s`,weeks:`w`,years:`y`};function a(e){return r.map(t=>{let n=e[t];return typeof n==`number`?`${n}${i[t]}`:void 0}).filter(e=>e!==void 0).join(` `)}function o(e){let i=new Map,o=new Map,s=new Map,c=new Map,l=new Map,u=new Map,d=typeof e==`string`?()=>e:e;function f(e,t){if(!t)return e;let n={};for(let e of Object.keys(t).sort())n[e]=t[e];try{return`${e}:${JSON.stringify(n)}`}catch{return e}}return{clear(){i.clear(),o.clear(),s.clear(),c.clear(),l.clear(),u.clear()},currency(e,r,i){let a=d(),s={...i,currency:r,style:`currency`};return t(o,f(a,s),n,()=>new Intl.NumberFormat(a,s)).format(e)},date(e,r){let i=d();return t(s,f(i,r),n,()=>new Intl.DateTimeFormat(i,r)).format(e)},duration(e,i){let o=d(),s=Intl;return s.DurationFormat?r.every(t=>e[t]===void 0)?``:t(u,f(o,i),n,()=>new s.DurationFormat(o,i)).format(e):a(e)},list(e,r){let i=d(),a=e.map(e=>String(e)),o=r?.style??`long`,s=r?.type===`or`?`disjunction`:`conjunction`;return t(l,f(i,{style:o,type:s}),n,()=>new Intl.ListFormat(i,{style:o,type:s})).format(a)},number(e,r){let a=d();return t(i,f(a,r),n,()=>new Intl.NumberFormat(a,r)).format(e)},relative(e,r,i){let a=d();return t(c,f(a,i),n,()=>new Intl.RelativeTimeFormat(a,i)).format(e,r)}}}var s=class t{entries=new Map;prefixes=new Set;get(e){return this.entries.get(e)}set(t,n){this.entries.set(t,{compiled:e.t(n),message:n});let r=t.indexOf(`.`);for(;r!==-1;)this.prefixes.add(t.slice(0,r)),r=t.indexOf(`.`,r+1)}setAll(e){for(let[t,n]of e)this.set(t,n)}clone(){let e=new t;for(let[t,n]of this.entries)e.entries.set(t,n);for(let t of this.prefixes)e.prefixes.add(t);return e}};function c(t,n=new Map,r){for(let[i,a]of Object.entries(t)){if(e.c.has(i))continue;let t=r?`${r}.${i}`:i;if(typeof a==`string`){let r=e.n(a);r?c(r,n,t):n.set(t,a)}else c(a,n,t)}return n}var l=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},u=class extends l{constructor(){super(`Operation called on a disposed i18n instance.`)}},d=class extends l{},f=class extends l{},p=class extends l{},m=class extends l{},h=class extends l{},g=class extends l{};function _(e){if(e)throw new u}function v(e){return e?Promise.reject(new u):null}function y(t,n){e.i(()=>{Promise.resolve().then(()=>require("./validate-x7lFFyV2.cjs")).then(({validateCatalog:r})=>{for(let i of r(n,t))e.o(`catalog('${t}'): missing plural form '${i.form}' for key '${i.key}'.`)})})}function b(t){let n=new Map,r=new Map,i=new Map,a=new Set,o,l=(e,t)=>{let r=n.get(e);r||(r=new s,n.set(e,r)),r.setAll(t)},u=e=>{let a=v(t());if(a)return a;if(n.has(e))return Promise.resolve();let s=r.get(e);if(!s)return Promise.reject(new p(`Missing locale source for "${e}".`));let u=i.get(e);if(u)return u;let d=s().then(t=>{r.get(e)===s&&(r.delete(e),l(e,c(t)),y(e,t),i.delete(e),o?.(e))},t=>{throw r.get(e)===s&&i.delete(e),t});return i.set(e,d),d};return{dispose(){n.clear(),r.clear(),i.clear(),a.clear(),o=void 0},isLoaded(e){return n.has(e)},isRegistered(e){return a.has(e)},knownLocales(){return[...a]},get onChange(){return o},set onChange(e){o=e},patch(e,n){return v(t())||(r.has(e)?u(e).then(()=>{t()||(l(e,c(n)),a.add(e),o?.(e))}):(l(e,c(n)),a.add(e),o?.(e),Promise.resolve()))},preload:u,register(s,d,f){_(t()),i.delete(s),a.add(s);let p=f.clearLocale(s);p.length>0&&e.o(`register('${s}') cleared loaded namespace markers for: ${p.map(e=>`'${e}'`).join(`, `)}. Call loadNamespace() again to reload.`);let m;return typeof d==`function`?(r.set(s,d),n.delete(s),m=u(s)):(r.delete(s),n.delete(s),l(s,c(d)),y(s,d),m=Promise.resolve(),o?.(s)),m},resolve(e){return n.get(e)},seedFrom(e,t){for(let[t,r]of e)n.set(t,r.clone()),a.add(t);for(let[e,n]of t)r.set(e,n),a.add(e)},snapshotCatalogs(){return n},snapshotLoaders(){return r}}}function x(){return{canon:new Map,chain:new Map,plural:new Map}}function S(e,t){let n=t.canon.get(e);if(n!==void 0)return n;let r;try{[r]=Intl.getCanonicalLocales(e)}catch{}if(!r)throw new m(`Invalid BCP 47 locale tag: "${e}".`);return t.canon.set(e,r),r}function C(e,t,n,r){let i=`${e}:${n?`ordinal`:`cardinal`}`,a=r.plural.get(i);return a||(a=new Intl.PluralRules(e,{type:n?`ordinal`:`cardinal`}),r.plural.set(i,a)),a.select(t)}function w(e,t){let n=new Set;for(let r of[e,...t]){n.add(r);let e=r.split(`-`);for(let t=e.length-1;t>0;t--)n.add(e.slice(0,t).join(`-`))}return{chain:[...n],set:n}}function T(e,t,n){let r=t.length===0?e:`${e}|${t.join(`,`)}`,i=n.chain.get(r);if(i)return i;let a=w(e,t);return n.chain.set(r,a),a}function E(e){let t=new Map,n=new Map,r=new Map;return{clearLocale(e){let t=[];for(let[r,i]of n.entries())i.delete(e)&&t.push(r);return t},dispose(){t.clear(),n.clear(),r.clear()},isLoaded(e,t){return n.get(e)?.has(t)??!1},isRegistered(e){return t.has(e)},loadNamespace(i,a,o){let s=v(e());if(s)return s;let c=t.get(i);if(!c)return Promise.reject(new h(`Namespace '${i}' is not registered. Call registerNamespace() first.`));if(n.get(i)?.has(a))return Promise.resolve();let l=r.get(i)?.get(a);if(l)return l;let u=c(a).then(e=>o(a,e)).then(()=>{let e=n.get(i);e||(e=new Set,n.set(i,e)),e.add(a),r.get(i)?.delete(a)},e=>{throw r.get(i)?.delete(a),e});return r.has(i)||r.set(i,new Map),r.get(i).set(a,u),u},registerNamespace(n,r){_(e()),t.set(n,r)},seedFrom(e){for(let[n,r]of e.snapshotRegistry())t.set(n,r);for(let[t,r]of e.snapshotLoaded())n.set(t,new Set(r))},snapshotLoaded(){return n},snapshotRegistry(){return t}}}function D(e,t){for(let n of e.chain){let r=e.catalogStore.resolve(n)?.get(t);if(r!==void 0)return r}}function O(e,t){for(let n of e.chain)if(e.catalogStore.resolve(n)?.prefixes.has(t))return!0;return!1}function k(e,t){return D(e,t)!==void 0||O(e,t)}function A(t,n,r,i){return e.r(r.compiled,i,n,t.locale,t.onMissingVar)}function j(t,n,r){let i=D(t,n);return i?A(t,n,i,r):(e.i(()=>{O(t,n)&&e.o(`t('${n}') resolved to the missing-key fallback, but '${n}' exists as a plural branch — use tp('${n}', count) instead.`)}),t.onMissingKey(n,t.locale))}function M(e,t,n,r){let i=[];return!r&&n===0&&i.push(`${e}.zero`),(t!==`zero`||r)&&i.push(`${e}.${t}`),t!==`other`&&i.push(`${e}.other`),i}function N(e,t,n,r){if(!Number.isFinite(n))throw new d("`count` must be a finite number.");let i=r?.vars,a=r?.ordinal??!1;if(i&&Object.hasOwn(i,`count`))throw new f("`tp` does not allow `vars.count`; `count` is injected automatically.");let o=i?{count:n,...i}:{count:n};for(let r of e.chain){let i=e.catalogStore.resolve(r);if(!i)continue;let s=M(t,C(r,n,a,e.caches),n,a);for(let t of s){let n=i.get(t);if(n!==void 0)return A(e,t,n,o)}}return e.onMissingKey(t,e.locale)}var P=128;function F(e,t,n){let{chain:r,set:i}=T(e,t,n);return{chain:r,chainSet:i,locale:e}}function I(e){return L(e)}function L(n,r){let i=n??{},a=x(),l=e=>S(e,a),d=Array.isArray(i.fallback)?i.fallback.map(l):i.fallback?[l(i.fallback)]:[],f=!1,p=new AbortController,m=b(()=>f),h=E(()=>f),v=F(l(i.locale??`en`),d,a),C=new Set,w=new Set,T=i.onMissingKey??(e=>e),D=i.onMissingVar??(e=>`{${e}}`),O=i.onSubscriberError??(t=>e.a(`subscriber error`,t)),A,M=new Map,I=()=>(A||=o(()=>v.locale),A),R=()=>({caches:a,catalogStore:m,chain:v.chain,locale:v.locale,onMissingKey:T,onMissingVar:D}),z=e=>k(R(),e),B=(e,t)=>j(R(),String(e),t),V=(e,t,n)=>N(R(),String(e),t,n),H={locale:v.locale,t:B,tp:V},U=()=>{H={locale:v.locale,t:B,tp:V};let e=[...C];for(let t of e)try{t(H)}catch(e){O(e)}};if(m.onChange=e=>{v.chainSet.has(e)&&U()},r?.catalogStore&&m.seedFrom(r.catalogStore.snapshotCatalogs(),r.catalogStore.snapshotLoaders()),r?.nsStore&&h.seedFrom(r.nsStore),i.catalogs){let e=new Map,t=new Map;for(let[n,r]of Object.entries(i.catalogs)){let i=l(n);if(typeof r==`function`)t.set(i,r);else{let t=new s;t.setAll(c(r)),e.set(i,t),y(i,r)}}m.seedFrom(e,t)}let W=e=>m.preload(l(e)),G=0,K={get disposalSignal(){return p.signal},dispose(){if(!f){f=!0,p.abort();for(let e of[...w])e();w.clear(),C.clear(),m.dispose(),h.dispose(),M.clear()}},get disposed(){return f},extend(e,t,n){_(f),h.registerNamespace(e,t);let r=n?l(n):v.locale;return h.loadNamespace(e,r,(e,t)=>m.patch(e,t))},get fmt(){return I()},fork(e){return L({fallback:e?.fallback??(d.length>0?d:void 0),locale:e?.locale??v.locale,onMissingKey:e?.onMissingKey??i.onMissingKey,onMissingVar:e?.onMissingVar??i.onMissingVar,onSubscriberError:e?.onSubscriberError??i.onSubscriberError},{catalogStore:m,nsStore:h})},getSnapshot(){return H},getState(){let e={};for(let[t,n]of m.snapshotCatalogs())e[t]=Object.fromEntries([...n.entries.entries()].map(([e,{message:t}])=>[e,t]));return{catalogs:e,locale:v.locale}},getSupportedLocales(e){let t=[...m.knownLocales()];return e===!0?t.sort():t},has(e){return z(String(e))},isLoaded(e){try{return m.isLoaded(l(e))}catch{return!1}},isNamespaceLoaded(e,t){if(!t)return h.isLoaded(e,v.locale);try{return h.isLoaded(e,l(t))}catch{return!1}},isNamespaceRegistered(e){return h.isRegistered(e)},isRegistered(e){try{return m.isRegistered(l(e))}catch{return!1}},loadNamespace(e,t){let n=t?l(t):v.locale;return h.loadNamespace(e,n,(e,t)=>m.patch(e,t))},get locale(){return v.locale},preload:W,register(e,t){let n=l(e);return m.register(n,t,h)},registerNamespace(e,t){h.registerNamespace(e,t)},restoreState(e){if(_(f),!Object.hasOwn(e.catalogs,e.locale))throw new g(`restoreState: locale "${e.locale}" has no catalog in the provided state.`);let t=new Map,n=m.knownLocales();for(let e of n)h.clearLocale(e);for(let[n,r]of Object.entries(e.catalogs)){let e=l(n),i=new s;i.setAll(Object.entries(r)),t.set(e,i)}m.dispose(),m.onChange=e=>{v.chainSet.has(e)&&U()},m.seedFrom(t,new Map),v=F(l(e.locale),d,a),A?.clear(),U()},scope(e){let n=String(e);return t(M,n,P,()=>({get fmt(){return I()},has:e=>z(`${n}.${e}`),t:(e,t)=>B(`${n}.${e}`,t),tp:(e,t,r)=>V(`${n}.${e}`,t,r)}))},async setLocale(e){_(f);let t=l(e);if(v.locale===t)return;let n=++G;await W(t),!(f||G!==n)&&(v=F(t,d,a),A?.clear(),U())},subscribe:(e,t)=>{let n=t?.signal,r=()=>{C.delete(e),n?.removeEventListener(`abort`,r),w.delete(r)};if(f)throw new u;if(n?.aborted)return r;if(t?.immediate===!0)try{e(H)}catch(e){return O(e),r}return C.add(e),n?.addEventListener(`abort`,r,{once:!0}),w.add(r),r},[Symbol.dispose](){K.dispose()},t:B,tp:V};return K}exports.LinguaCountInVarsError=f,exports.LinguaDisposedError=u,exports.LinguaError=l,exports.LinguaInvalidCountError=d,exports.LinguaInvalidLocaleError=m,exports.LinguaMissingLocaleError=p,exports.LinguaNamespaceMissingError=h,exports.LinguaRestoreError=g,exports.createFormatter=o,exports.createI18n=I;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class e extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}static is(t){return t instanceof e}},t=class extends e{constructor(){super(`Operation called on a disposed translation store.`)}},n=class extends e{},r=class extends e{},i=class extends e{},a=class extends e{},o=class extends e{},s=new Map;function c(e){try{let[t]=Intl.getCanonicalLocales(e);if(t)return t}catch{}throw new r(`Invalid BCP 47 locale tag: "${e}".`)}function l(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 u(e,t,n){let r=`${e}:${n?`ordinal`:`cardinal`}`,i=s.get(r);return i||(i=new Intl.PluralRules(e,{type:n?`ordinal`:`cardinal`}),s.set(r,i)),i.select(t)}var d=/\{([\p{ID_Continue}-]+)\}/gu;function f(e){let t=[],n=0;for(let r of e.matchAll(d)){let i=r.index??0;i>n&&t.push(e.slice(n,i)),t.push({value:r[1]}),n=i+r[0].length}return n<e.length&&t.push(e.slice(n)),t}function p(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 m(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 h=new Set([`__proto__`,`constructor`,`prototype`]);function g(e){return typeof e==`object`&&!!e&&Object.hasOwn(e,`plural`)}function _(e){let t=new Map,r=(e,i)=>{if(typeof e==`string`){t.set(i,{kind:`text`,template:f(e)});return}if(typeof e!=`object`||!e||Array.isArray(e))throw new n(`Catalog node "${i}" must be a string, plural message, or object.`);if(g(e)){if(typeof e.plural!=`object`||e.plural===null||Array.isArray(e.plural))throw new n(`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 n(`Plural form "${i}.${t}" must be a string.`);r.set(t,f(a))}t.set(i,{forms:r,kind:`plural`});return}for(let[t,a]of Object.entries(e)){if(h.has(t))throw new n(`Catalog key "${t}" is reserved.`);r(a,i?`${i}.${t}`:t)}};for(let[t,i]of Object.entries(e)){if(h.has(t))throw new n(`Catalog key "${t}" is reserved.`);r(i,t)}return t}function v(e){let t=new Map,n=new Map,r=new Map;for(let[n,r]of Object.entries(e))t.set(c(n),r);let i=(e,t)=>{n.set(e,{catalog:t,compiled:_(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(c(e))},load:async e=>{let a=c(e);if(n.has(a))return!1;let s=t.get(a);if(!s)throw new o(`Catalog has no source for locale "${a}".`);if(typeof s!=`function`)return i(a,s),!0;let l=r.get(a);if(l)return await l,!1;let u=s().then(e=>{i(a,e),r.delete(a)},e=>{throw r.delete(a),e});return r.set(a,u),await u,!0},state(e){let t={};for(let[e,{catalog:r}]of n)t[e]=r;return{catalogs:t,locale:e,version:3}}}}function y(e,t={}){let n=c(t.locale??`en`),r=l(n,(Array.isArray(t.fallback)?t.fallback:t.fallback?[t.fallback]:[]).map(c)),a=t.onMissingKey??(e=>e),o=t.onMissingValue??(e=>`{${e}}`),s=t=>{for(let n of r){let r=e.get(n)?.get(t);if(r)return{locale:n,message:r}}},d=(e,t)=>{let n=s(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 i("`count` must be a finite number.");return}let r=t.count===0&&!t.ordinal?`zero`:u(n.locale,t.count,t.ordinal??!1),a=n.message.forms.get(r)??n.message.forms.get(`other`);return a?{key:e,template:a}:void 0},f=e=>`count`in e?{count:e.count,...e.values}:e.values??{},h=(e,t)=>{let r=d(e,t);return r?m(r.template,f(t),e=>o(e,r.key,n)):[a(e,n)]},g=(e,t={})=>{let r=d(e,t);return r?p(r.template,f(t),e=>o(e,r.key,n)):a(e,n)};return{locale:n,segments(e,t){return h(e,t)},segmentsDynamic:h,translate(e,t={}){return g(e,t)},translateDynamic:g}}function b(e,t){let n=new Map;for(let[t,r]of Object.entries(e))n.set(c(t),_(r));return y(n,t)}function x(e){let n=v(e.catalogs),r=e.fallback,i=(Array.isArray(r)?r:r?[r]:[]).map(c),a=new AbortController,o=new Set,s=!1,u=c(e.locale??`en`),d=0,f=()=>({locale:u,revision:d,translator:y(n.catalogMap(),{...e,fallback:r,locale:u})}),p=f(),m=()=>{if(s)throw new t},h=()=>{s||(s=!0,o.clear(),a.abort())},g=e=>{try{e(p)}catch{}},_=()=>{d++,p=f();for(let e of[...o])g(e)},b=e=>l(u,i).includes(e);return{get disposalSignal(){return a.signal},dispose:h,get disposed(){return s},getSnapshot(){return p},isLoaded(e){return!s&&n.isLoaded(e?.locale??u)},async load(e){m();let t=c(e?.locale??u),r=await n.load(t);!s&&r&&b(t)&&_()},get locale(){return u},segments(e,t){return p.translator.segmentsDynamic(e,t)},segmentsDynamic(e,t){return p.translator.segmentsDynamic(e,t)},serialize(){return m(),n.state(u)},async setLocale(e){m();let t=c(e);t!==u&&(u=t,_())},subscribe(e,t){if(m(),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&&g(e),n},[Symbol.dispose]:h,translate(e,t={}){return p.translator.translateDynamic(e,t)},translateDynamic(e,t){return p.translator.translateDynamic(e,t)}}}function S(e,t){if(e.version!==3)throw new a(`Unsupported lingua state version: ${String(e.version)}.`);return x({...t,catalogs:e.catalogs,locale:e.locale})}exports.LinguaDisposedError=t,exports.LinguaError=e,exports.LinguaInvalidCatalogError=n,exports.LinguaInvalidLocaleError=r,exports.LinguaInvalidPluralCountError=i,exports.LinguaInvalidStateError=a,exports.LinguaMissingCatalogError=o,exports.createTranslationStore=x,exports.createTranslator=b,exports.hydrateTranslationStore=S;
2
2
  //# sourceMappingURL=lingua.cjs.map