@let-value/translate-react 1.1.2 → 1.1.6-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,41 +1,14 @@
1
- //#region rolldown:runtime
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
- key = keys[i];
11
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
- get: ((k) => from[k]).bind(null, key),
13
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
- });
15
- }
16
- return to;
17
- };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
- value: mod,
20
- enumerable: true
21
- }) : target, mod));
22
-
23
- //#endregion
24
- let __let_value_translate = require("@let-value/translate");
25
- __let_value_translate = __toESM(__let_value_translate);
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _let_value_translate = require("@let-value/translate");
26
3
  let react = require("react");
27
- react = __toESM(react);
28
-
29
4
  //#region src/context.ts
30
5
  const localeContext = (0, react.createContext)(void 0);
31
6
  const translatorContext = (0, react.createContext)(void 0);
32
-
33
7
  //#endregion
34
8
  //#region src/components/LocaleProvider.ts
35
9
  function LocaleProvider({ locale, children }) {
36
10
  return (0, react.createElement)(localeContext.Provider, { value: locale }, children);
37
11
  }
38
-
39
12
  //#endregion
40
13
  //#region src/hooks/useTranslations.ts
41
14
  /** @deprecated replace with `use` from react */
@@ -75,7 +48,6 @@ function useTranslations(locale) {
75
48
  if (state.status === "fulfilled") return state.value;
76
49
  return (0, react.use)(resource);
77
50
  }
78
-
79
51
  //#endregion
80
52
  //#region src/utils.ts
81
53
  function buildTemplateFromChildren(children) {
@@ -111,7 +83,6 @@ function buildTemplateFromChildren(children) {
111
83
  values
112
84
  };
113
85
  }
114
-
115
86
  //#endregion
116
87
  //#region src/components/Message.ts
117
88
  function Message({ context, children }) {
@@ -122,8 +93,7 @@ function Message({ context, children }) {
122
93
  if (context) return translator.context(context).message(input);
123
94
  return translator.message(input);
124
95
  }
125
- const tokens = values.map((_, i) => `\u0000${i}\u0000`);
126
- const built = (0, __let_value_translate.message)(strings, ...tokens);
96
+ const built = (0, _let_value_translate.message)(strings, ...values.map((_, i) => `\u0000${i}\u0000`));
127
97
  const parts = (context ? translator.translate({
128
98
  context,
129
99
  id: built
@@ -136,21 +106,18 @@ function Message({ context, children }) {
136
106
  }
137
107
  return (0, react.createElement)(react.Fragment, null, ...result);
138
108
  }
139
-
140
109
  //#endregion
141
110
  //#region src/components/Plural.ts
142
111
  function Plural({ number, forms, context }) {
143
112
  const translator = useTranslations();
144
113
  const built = forms.map((child, i) => {
145
114
  const { strings, values } = buildTemplateFromChildren(child);
146
- const tokens = values.map((_, j) => `\u0000${i}-${j}\u0000`);
147
115
  return {
148
- message: (0, __let_value_translate.message)(strings, ...tokens),
116
+ message: (0, _let_value_translate.message)(strings, ...values.map((_, j) => `\u0000${i}-${j}\u0000`)),
149
117
  values
150
118
  };
151
119
  });
152
- const messages = built.map((b) => b.message);
153
- const input = (0, __let_value_translate.plural)(...messages, number);
120
+ const input = (0, _let_value_translate.plural)(...built.map((b) => b.message), number);
154
121
  const parts = (context ? translator.translate({
155
122
  context,
156
123
  id: input
@@ -167,7 +134,6 @@ function Plural({ number, forms, context }) {
167
134
  }
168
135
  return (0, react.createElement)(react.Fragment, null, ...result);
169
136
  }
170
-
171
137
  //#endregion
172
138
  //#region src/translatorCache.ts
173
139
  const cacheNoParent = /* @__PURE__ */ new WeakMap();
@@ -208,7 +174,7 @@ function getCachedTranslator(translations, parent) {
208
174
  setInWeakMap(translations, parent, structural);
209
175
  return structural;
210
176
  }
211
- const translator = new __let_value_translate.Translator(translations, parent);
177
+ const translator = new _let_value_translate.Translator(translations, parent);
212
178
  setInWeakMap(translations, parent, translator);
213
179
  structuralCache.unshift({
214
180
  sortedEntries,
@@ -218,22 +184,18 @@ function getCachedTranslator(translations, parent) {
218
184
  if (structuralCache.length > MAX_STRUCTURAL_ENTRIES) structuralCache.pop();
219
185
  return translator;
220
186
  }
221
-
222
187
  //#endregion
223
188
  //#region src/components/TranslationsProvider.ts
224
189
  const EMPTY_TRANSLATIONS = {};
225
190
  function TranslationsProvider({ translations = EMPTY_TRANSLATIONS, children }) {
226
- const parent = (0, react.use)(translatorContext);
227
- const translator = getCachedTranslator(translations, parent);
191
+ const translator = getCachedTranslator(translations, (0, react.use)(translatorContext));
228
192
  return (0, react.createElement)(translatorContext.Provider, { value: translator }, children);
229
193
  }
230
-
231
194
  //#endregion
232
195
  //#region src/hooks/useLocale.ts
233
196
  function useLocale() {
234
197
  return (0, react.use)(localeContext);
235
198
  }
236
-
237
199
  //#endregion
238
200
  exports.LocaleProvider = LocaleProvider;
239
201
  exports.Message = Message;
@@ -241,9 +203,11 @@ exports.Plural = Plural;
241
203
  exports.TranslationsProvider = TranslationsProvider;
242
204
  exports.useLocale = useLocale;
243
205
  exports.useTranslations = useTranslations;
244
- Object.keys(__let_value_translate).forEach(function (k) {
245
- if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
246
- enumerable: true,
247
- get: function () { return __let_value_translate[k]; }
248
- });
206
+ Object.keys(_let_value_translate).forEach(function(k) {
207
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
208
+ enumerable: true,
209
+ get: function() {
210
+ return _let_value_translate[k];
211
+ }
212
+ });
249
213
  });
package/dist/index.d.cts CHANGED
@@ -1,9 +1,6 @@
1
- import * as _let_value_translate0 from "@let-value/translate";
1
+ /// <reference types="node" />
2
2
  import { Locale, LocaleTranslator } from "@let-value/translate";
3
- import * as react1 from "react";
4
- import { ReactNode } from "react";
5
- import * as gettext_parser0 from "gettext-parser";
6
- import { GetTextTranslations } from "gettext-parser";
3
+ import { ReactElement, ReactNode } from "react";
7
4
  export * from "@let-value/translate";
8
5
 
9
6
  //#region src/components/LocaleProvider.d.ts
@@ -14,7 +11,7 @@ interface LocaleProviderProps {
14
11
  declare function LocaleProvider({
15
12
  locale,
16
13
  children
17
- }: LocaleProviderProps): react1.FunctionComponentElement<react1.ProviderProps<Locale | undefined>>;
14
+ }: LocaleProviderProps): import("react").FunctionComponentElement<import("react").ProviderProps<Locale | undefined>>;
18
15
  //#endregion
19
16
  //#region src/components/Message.d.ts
20
17
  interface MessageProps {
@@ -24,7 +21,7 @@ interface MessageProps {
24
21
  declare function Message({
25
22
  context,
26
23
  children
27
- }: MessageProps): string | react1.FunctionComponentElement<react1.FragmentProps>;
24
+ }: MessageProps): string | import("react").FunctionComponentElement<import("react").FragmentProps>;
28
25
  //#endregion
29
26
  //#region src/components/Plural.d.ts
30
27
  interface PluralProps {
@@ -36,7 +33,37 @@ declare function Plural({
36
33
  number,
37
34
  forms,
38
35
  context
39
- }: PluralProps): react1.FunctionComponentElement<react1.FragmentProps>;
36
+ }: PluralProps): import("react").FunctionComponentElement<import("react").FragmentProps>;
37
+ //#endregion
38
+ //#region ../node_modules/.pnpm/@types+gettext-parser@9.0.0/node_modules/@types/gettext-parser/index.d.ts
39
+ interface GetTextComment {
40
+ translator?: string;
41
+ reference?: string;
42
+ extracted?: string;
43
+ flag?: string;
44
+ previous?: string;
45
+ }
46
+ interface GetTextTranslation {
47
+ msgctxt?: string;
48
+ msgid: string;
49
+ msgid_plural?: string;
50
+ msgstr: string[];
51
+ comments?: GetTextComment;
52
+ obsolete?: boolean;
53
+ }
54
+ interface GetTextTranslationRecord {
55
+ [msgctxt: string]: {
56
+ [msgId: string]: GetTextTranslation;
57
+ };
58
+ }
59
+ interface GetTextTranslations {
60
+ charset: string;
61
+ headers: {
62
+ [headerName: string]: string;
63
+ };
64
+ translations: GetTextTranslationRecord;
65
+ obsolete?: GetTextTranslationRecord;
66
+ }
40
67
  //#endregion
41
68
  //#region src/translatorCache.d.ts
42
69
  type TranslationLoader = () => Promise<GetTextTranslations>;
@@ -50,13 +77,7 @@ interface TranslationsProviderProps {
50
77
  declare function TranslationsProvider({
51
78
  translations,
52
79
  children
53
- }: TranslationsProviderProps): react1.FunctionComponentElement<react1.ProviderProps<_let_value_translate0.Translator<Partial<Record<Locale, (gettext_parser0.GetTextTranslations | {
54
- default: gettext_parser0.GetTextTranslations;
55
- }) | Promise<gettext_parser0.GetTextTranslations | {
56
- default: gettext_parser0.GetTextTranslations;
57
- }> | (() => Promise<gettext_parser0.GetTextTranslations | {
58
- default: gettext_parser0.GetTextTranslations;
59
- }>)>>> | undefined>>;
80
+ }: TranslationsProviderProps): ReactElement;
60
81
  //#endregion
61
82
  //#region src/hooks/useLocale.d.ts
62
83
  declare function useLocale(): Locale | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/components/LocaleProvider.ts","../src/components/Message.ts","../src/components/Plural.ts","../src/translatorCache.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts","../src/hooks/useTranslations.ts"],"sourcesContent":[],"mappings":";;;;;;;;;UAIiB,mBAAA;UACL;aACG;;iBAGC,cAAA;;;GAAqC,sBAAmB,MAAA,CAAA,yBAAA,MAAA,CAAA,cAAA;;;UCHvD,YAAA;;YAEH;;iBAGE,OAAA;;;GAA+B,wBAAY,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;UCL1C,WAAA;;kBAEG;;;iBAIJ,MAAA;;;;GAAmC,cAAW,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;KCRzD,iBAAA,SAA0B,QAAQ;KAC3B,gBAAA,GAAmB,sBAAsB;;;UCApC,yBAAA;iBACE,QAAQ,OAAO,QAAQ;aAC3B;;iBAKC,oBAAA;;;GAAsE,4BAAyB,MAAA,CAAA,yBAAA,MAAA,CAAA,cAAA,qBAAA,CAAA,WAAA,QAAA,OAAA,SAAA,eAAA,CAAA,mBAAA;WAAA,eAAA,CAAA;;EJR9F,OAAA,qCAAmB;CAAA,CAAA,GAAA,CAAA,GAAA,UAAA,uCAAA;SACxB,qCAAA;SACG,SAAA,CAAA,CAAA;;;iBKFC,SAAA,CAAA,GAAa;;;iBC0Bb,eAAA,UAAyB,SAAS"}
1
+ {"version":3,"file":"index.d.cts","names":["translator","reference","extracted","flag","previous","msgctxt","msgid","msgid_plural","msgstr","comments","GetTextComment","obsolete","msgId","GetTextTranslation","charset","headers","headerName","translations","GetTextTranslationRecord","defaultCharset","validation","foldLength","escapeCharacters","sort","a","b","eol","parse","Buffer","buffer","GetTextPoParserOptions","options","GetTextTranslations","compile","table","GetTextPoCompilerOptions","createParseStream","TransformOptions","transformOptions","Transform","PoParser","MoParser"],"sources":["../src/components/LocaleProvider.ts","../src/components/Message.ts","../src/components/Plural.ts","../../node_modules/.pnpm/@types+gettext-parser@9.0.0/node_modules/@types/gettext-parser/index.d.ts","../src/translatorCache.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts","../src/hooks/useTranslations.ts"],"x_google_ignoreList":[3],"mappings":";;;;;;UAIiB,mBAAA;EACb,MAAA,EAAQ,MAAA;EACR,QAAA,GAAW,SAAS;AAAA;AAAA,iBAGR,cAAA;EAAiB,MAAA;EAAQ;AAAA,GAAY,mBAAA,mBAAmB,wBAAA,iBAAA,aAAA,CAAA,MAAA;;;UCHvD,YAAA;EACb,OAAA;EACA,QAAA,EAAU,SAAS;AAAA;AAAA,iBAGP,OAAA;EAAU,OAAA;EAAS;AAAA,GAAY,YAAA,4BAAY,wBAAA,iBAAA,aAAA;;;UCL1C,WAAA;EACb,MAAA;EACA,KAAA,WAAgB,SAAS;EACzB,OAAA;AAAA;AAAA,iBAGY,MAAA;EAAS,MAAA;EAAQ,KAAA;EAAO;AAAA,GAAW,WAAA,mBAAW,wBAAA,iBAAA,aAAA;;;UCR7C,cAAA;EACbA,UAAAA;EACAC,SAAAA;EACAC,SAAAA;EACAC,IAAAA;EACAC,QAAAA;AAAAA;AAAAA,UAGa,kBAAA;EACbC,OAAAA;EACAC,KAAAA;EACAC,YAAAA;EACAC,MAAAA;EACAC,QAAAA,GAAW,cAAc;EACzBE,QAAAA;AAAAA;AAAAA,UAGa,wBAAA;EAAA,CACZN,OAAAA;IAAAA,CACIO,KAAAA,WAAgB,kBAAkB;EAAA;AAAA;AAAA,UAI1B,mBAAA;EACbE,OAAAA;EACAC,OAAAA;IAAAA,CAAYC,UAAAA;EAAAA;EACZC,YAAAA,EAAc,wBAAA;EACdN,QAAAA,GAAW,wBAAwB;AAAA;;;KC3BlC,iBAAA,SAA0B,OAAO,CAAC,mBAAA;AAAA,KAC3B,gBAAA,GAAmB,mBAAA,GAAsB,iBAAiB;;;UCArD,yBAAA;EACb,YAAA,GAAe,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAQ,gBAAA;EACtC,QAAA,GAAW,SAAA;AAAA;AAAA,iBAKC,oBAAA;EACZ,YAAA;EACA;AAAA,GACD,yBAAA,GAA4B,YAAA;;;iBCXf,SAAA,IAAa,MAAM;;;iBCyBnB,eAAA,CAAgB,MAAA,GAAS,MAAA,GAAS,gBAAgB"}
@@ -1,9 +1,6 @@
1
- import * as _let_value_translate0 from "@let-value/translate";
1
+ /// <reference types="node" />
2
2
  import { Locale, LocaleTranslator, Translator } from "@let-value/translate";
3
- import * as react5 from "react";
4
- import { ReactNode } from "react";
5
- import * as gettext_parser0 from "gettext-parser";
6
- import { GetTextTranslations } from "gettext-parser";
3
+ import { ReactElement, ReactNode } from "react";
7
4
  export * from "@let-value/translate";
8
5
 
9
6
  //#region src/components/LocaleProvider.d.ts
@@ -14,7 +11,7 @@ interface LocaleProviderProps {
14
11
  declare function LocaleProvider({
15
12
  locale,
16
13
  children
17
- }: LocaleProviderProps): react5.FunctionComponentElement<react5.ProviderProps<Locale | undefined>>;
14
+ }: LocaleProviderProps): import("react").FunctionComponentElement<import("react").ProviderProps<Locale | undefined>>;
18
15
  //#endregion
19
16
  //#region src/components/Message.d.ts
20
17
  interface MessageProps {
@@ -24,7 +21,7 @@ interface MessageProps {
24
21
  declare function Message({
25
22
  context,
26
23
  children
27
- }: MessageProps): string | react5.FunctionComponentElement<react5.FragmentProps>;
24
+ }: MessageProps): string | import("react").FunctionComponentElement<import("react").FragmentProps>;
28
25
  //#endregion
29
26
  //#region src/components/Plural.d.ts
30
27
  interface PluralProps {
@@ -36,7 +33,37 @@ declare function Plural({
36
33
  number,
37
34
  forms,
38
35
  context
39
- }: PluralProps): react5.FunctionComponentElement<react5.FragmentProps>;
36
+ }: PluralProps): import("react").FunctionComponentElement<import("react").FragmentProps>;
37
+ //#endregion
38
+ //#region ../node_modules/.pnpm/@types+gettext-parser@9.0.0/node_modules/@types/gettext-parser/index.d.ts
39
+ interface GetTextComment {
40
+ translator?: string;
41
+ reference?: string;
42
+ extracted?: string;
43
+ flag?: string;
44
+ previous?: string;
45
+ }
46
+ interface GetTextTranslation {
47
+ msgctxt?: string;
48
+ msgid: string;
49
+ msgid_plural?: string;
50
+ msgstr: string[];
51
+ comments?: GetTextComment;
52
+ obsolete?: boolean;
53
+ }
54
+ interface GetTextTranslationRecord {
55
+ [msgctxt: string]: {
56
+ [msgId: string]: GetTextTranslation;
57
+ };
58
+ }
59
+ interface GetTextTranslations {
60
+ charset: string;
61
+ headers: {
62
+ [headerName: string]: string;
63
+ };
64
+ translations: GetTextTranslationRecord;
65
+ obsolete?: GetTextTranslationRecord;
66
+ }
40
67
  //#endregion
41
68
  //#region src/translatorCache.d.ts
42
69
  type TranslationLoader = () => Promise<GetTextTranslations>;
@@ -50,13 +77,7 @@ interface TranslationsProviderProps {
50
77
  declare function TranslationsProvider({
51
78
  translations,
52
79
  children
53
- }: TranslationsProviderProps): react5.FunctionComponentElement<react5.ProviderProps<_let_value_translate0.Translator<Partial<Record<Locale, (gettext_parser0.GetTextTranslations | {
54
- default: gettext_parser0.GetTextTranslations;
55
- }) | Promise<gettext_parser0.GetTextTranslations | {
56
- default: gettext_parser0.GetTextTranslations;
57
- }> | (() => Promise<gettext_parser0.GetTextTranslations | {
58
- default: gettext_parser0.GetTextTranslations;
59
- }>)>>> | undefined>>;
80
+ }: TranslationsProviderProps): ReactElement;
60
81
  //#endregion
61
82
  //#region src/hooks/useLocale.d.ts
62
83
  declare function useLocale(): Locale | undefined;
@@ -65,4 +86,4 @@ declare function useLocale(): Locale | undefined;
65
86
  declare function useTranslations(locale?: Locale): LocaleTranslator;
66
87
  //#endregion
67
88
  export { LocaleProvider, Message, Plural, TranslationsProvider, useLocale, useTranslations };
68
- //# sourceMappingURL=index.d.ts.map
89
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":["translator","reference","extracted","flag","previous","msgctxt","msgid","msgid_plural","msgstr","comments","GetTextComment","obsolete","msgId","GetTextTranslation","charset","headers","headerName","translations","GetTextTranslationRecord","defaultCharset","validation","foldLength","escapeCharacters","sort","a","b","eol","parse","Buffer","buffer","GetTextPoParserOptions","options","GetTextTranslations","compile","table","GetTextPoCompilerOptions","createParseStream","TransformOptions","transformOptions","Transform","PoParser","MoParser"],"sources":["../src/components/LocaleProvider.ts","../src/components/Message.ts","../src/components/Plural.ts","../../node_modules/.pnpm/@types+gettext-parser@9.0.0/node_modules/@types/gettext-parser/index.d.ts","../src/translatorCache.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts","../src/hooks/useTranslations.ts"],"x_google_ignoreList":[3],"mappings":";;;;;;UAIiB,mBAAA;EACb,MAAA,EAAQ,MAAA;EACR,QAAA,GAAW,SAAS;AAAA;AAAA,iBAGR,cAAA;EAAiB,MAAA;EAAQ;AAAA,GAAY,mBAAA,mBAAmB,wBAAA,iBAAA,aAAA,CAAA,MAAA;;;UCHvD,YAAA;EACb,OAAA;EACA,QAAA,EAAU,SAAS;AAAA;AAAA,iBAGP,OAAA;EAAU,OAAA;EAAS;AAAA,GAAY,YAAA,4BAAY,wBAAA,iBAAA,aAAA;;;UCL1C,WAAA;EACb,MAAA;EACA,KAAA,WAAgB,SAAS;EACzB,OAAA;AAAA;AAAA,iBAGY,MAAA;EAAS,MAAA;EAAQ,KAAA;EAAO;AAAA,GAAW,WAAA,mBAAW,wBAAA,iBAAA,aAAA;;;UCR7C,cAAA;EACbA,UAAAA;EACAC,SAAAA;EACAC,SAAAA;EACAC,IAAAA;EACAC,QAAAA;AAAAA;AAAAA,UAGa,kBAAA;EACbC,OAAAA;EACAC,KAAAA;EACAC,YAAAA;EACAC,MAAAA;EACAC,QAAAA,GAAW,cAAc;EACzBE,QAAAA;AAAAA;AAAAA,UAGa,wBAAA;EAAA,CACZN,OAAAA;IAAAA,CACIO,KAAAA,WAAgB,kBAAkB;EAAA;AAAA;AAAA,UAI1B,mBAAA;EACbE,OAAAA;EACAC,OAAAA;IAAAA,CAAYC,UAAAA;EAAAA;EACZC,YAAAA,EAAc,wBAAA;EACdN,QAAAA,GAAW,wBAAwB;AAAA;;;KC3BlC,iBAAA,SAA0B,OAAO,CAAC,mBAAA;AAAA,KAC3B,gBAAA,GAAmB,mBAAA,GAAsB,iBAAiB;;;UCArD,yBAAA;EACb,YAAA,GAAe,OAAA,CAAQ,MAAA,CAAO,MAAA,EAAQ,gBAAA;EACtC,QAAA,GAAW,SAAA;AAAA;AAAA,iBAKC,oBAAA;EACZ,YAAA;EACA;AAAA,GACD,yBAAA,GAA4B,YAAA;;;iBCXf,SAAA,IAAa,MAAM;;;iBCyBnB,eAAA,CAAgB,MAAA,GAAS,MAAA,GAAS,gBAAgB"}
@@ -1,18 +1,14 @@
1
1
  import { Translator, message, plural } from "@let-value/translate";
2
2
  import { Children, Fragment, createContext, createElement, isValidElement, use } from "react";
3
-
4
- export * from "@let-value/translate"
5
-
3
+ export * from "@let-value/translate";
6
4
  //#region src/context.ts
7
5
  const localeContext = createContext(void 0);
8
6
  const translatorContext = createContext(void 0);
9
-
10
7
  //#endregion
11
8
  //#region src/components/LocaleProvider.ts
12
9
  function LocaleProvider({ locale, children }) {
13
10
  return createElement(localeContext.Provider, { value: locale }, children);
14
11
  }
15
-
16
12
  //#endregion
17
13
  //#region src/hooks/useTranslations.ts
18
14
  /** @deprecated replace with `use` from react */
@@ -52,7 +48,6 @@ function useTranslations(locale) {
52
48
  if (state.status === "fulfilled") return state.value;
53
49
  return use(resource);
54
50
  }
55
-
56
51
  //#endregion
57
52
  //#region src/utils.ts
58
53
  function buildTemplateFromChildren(children) {
@@ -88,7 +83,6 @@ function buildTemplateFromChildren(children) {
88
83
  values
89
84
  };
90
85
  }
91
-
92
86
  //#endregion
93
87
  //#region src/components/Message.ts
94
88
  function Message({ context, children }) {
@@ -99,8 +93,7 @@ function Message({ context, children }) {
99
93
  if (context) return translator.context(context).message(input);
100
94
  return translator.message(input);
101
95
  }
102
- const tokens = values.map((_, i) => `\u0000${i}\u0000`);
103
- const built = message(strings, ...tokens);
96
+ const built = message(strings, ...values.map((_, i) => `\u0000${i}\u0000`));
104
97
  const parts = (context ? translator.translate({
105
98
  context,
106
99
  id: built
@@ -113,21 +106,18 @@ function Message({ context, children }) {
113
106
  }
114
107
  return createElement(Fragment, null, ...result);
115
108
  }
116
-
117
109
  //#endregion
118
110
  //#region src/components/Plural.ts
119
111
  function Plural({ number, forms, context }) {
120
112
  const translator = useTranslations();
121
113
  const built = forms.map((child, i) => {
122
114
  const { strings, values } = buildTemplateFromChildren(child);
123
- const tokens = values.map((_, j) => `\u0000${i}-${j}\u0000`);
124
115
  return {
125
- message: message(strings, ...tokens),
116
+ message: message(strings, ...values.map((_, j) => `\u0000${i}-${j}\u0000`)),
126
117
  values
127
118
  };
128
119
  });
129
- const messages = built.map((b) => b.message);
130
- const input = plural(...messages, number);
120
+ const input = plural(...built.map((b) => b.message), number);
131
121
  const parts = (context ? translator.translate({
132
122
  context,
133
123
  id: input
@@ -144,7 +134,6 @@ function Plural({ number, forms, context }) {
144
134
  }
145
135
  return createElement(Fragment, null, ...result);
146
136
  }
147
-
148
137
  //#endregion
149
138
  //#region src/translatorCache.ts
150
139
  const cacheNoParent = /* @__PURE__ */ new WeakMap();
@@ -195,22 +184,19 @@ function getCachedTranslator(translations, parent) {
195
184
  if (structuralCache.length > MAX_STRUCTURAL_ENTRIES) structuralCache.pop();
196
185
  return translator;
197
186
  }
198
-
199
187
  //#endregion
200
188
  //#region src/components/TranslationsProvider.ts
201
189
  const EMPTY_TRANSLATIONS = {};
202
190
  function TranslationsProvider({ translations = EMPTY_TRANSLATIONS, children }) {
203
- const parent = use(translatorContext);
204
- const translator = getCachedTranslator(translations, parent);
191
+ const translator = getCachedTranslator(translations, use(translatorContext));
205
192
  return createElement(translatorContext.Provider, { value: translator }, children);
206
193
  }
207
-
208
194
  //#endregion
209
195
  //#region src/hooks/useLocale.ts
210
196
  function useLocale() {
211
197
  return use(localeContext);
212
198
  }
213
-
214
199
  //#endregion
215
200
  export { LocaleProvider, Message, Plural, TranslationsProvider, useLocale, useTranslations };
216
- //# sourceMappingURL=index.js.map
201
+
202
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/context.ts","../src/components/LocaleProvider.ts","../src/hooks/useTranslations.ts","../src/utils.ts","../src/components/Message.ts","../src/components/Plural.ts","../src/translatorCache.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts"],"sourcesContent":["import type { Locale, Translator } from \"@let-value/translate\";\nimport { createContext } from \"react\";\n\ntype AnyTranslator = Translator<any>;\n\nexport const localeContext = createContext<Locale | undefined>(undefined);\nexport const translatorContext = createContext<AnyTranslator | undefined>(undefined);\n","import type { Locale } from \"@let-value/translate\";\nimport { createElement, type ReactNode } from \"react\";\nimport { localeContext } from \"../context.ts\";\n\nexport interface LocaleProviderProps {\n locale: Locale;\n children?: ReactNode;\n}\n\nexport function LocaleProvider({ locale, children }: LocaleProviderProps) {\n return createElement(localeContext.Provider, { value: locale }, children);\n}\n","import type { Locale, LocaleTranslator } from \"@let-value/translate\";\nimport { use } from \"react\";\n\nimport { localeContext, translatorContext } from \"../context.ts\";\n\n/** @deprecated replace with `use` from react */\nfunction getPromiseState(promise: any) {\n switch (promise.status) {\n case \"pending\":\n return { status: \"pending\" };\n case \"fulfilled\":\n return { status: \"fulfilled\", value: promise.value };\n case \"rejected\":\n return { status: \"rejected\", reason: promise.reason };\n default: {\n promise.status = \"pending\";\n promise.then((value: unknown) => {\n promise.status = \"fulfilled\";\n promise.value = value;\n });\n promise.catch((reason: unknown) => {\n promise.status = \"rejected\";\n promise.reason = reason;\n });\n return getPromiseState(promise);\n }\n }\n}\n\nexport function useTranslations(locale?: Locale): LocaleTranslator {\n const requestedLocale = locale ?? use(localeContext) ?? (\"unknown\" as never);\n const translator = use(translatorContext);\n if (!translator) {\n throw new Error(\"TranslationsProvider is missing\");\n }\n\n const resource = translator.fetchLocale(requestedLocale);\n if (!(resource instanceof Promise)) {\n return resource;\n }\n\n const state = getPromiseState(resource);\n if (state.status === \"pending\") {\n throw resource;\n }\n if (state.status === \"rejected\") {\n throw state.reason;\n }\n if (state.status === \"fulfilled\") {\n return state.value;\n }\n\n return use(resource);\n}\n","import { Children, Fragment, isValidElement, type PropsWithChildren, type ReactNode } from \"react\";\n\nexport function buildTemplateFromChildren(children: ReactNode): {\n strings: string[];\n values: ReactNode[];\n} {\n function flatten(nodes: ReactNode): ReactNode[] {\n const result: ReactNode[] = [];\n Children.forEach(nodes, (child) => {\n if (isValidElement(child) && child.type === Fragment) {\n result.push(...flatten((child.props as PropsWithChildren).children));\n } else {\n result.push(child);\n }\n });\n return result;\n }\n\n const array = flatten(children);\n const strings: string[] = [\"\"];\n const values: ReactNode[] = [];\n let expectValue = false;\n\n array.forEach((child) => {\n if (typeof child === \"string\") {\n if (expectValue) {\n values.push(child);\n strings.push(\"\");\n expectValue = false;\n } else {\n strings[strings.length - 1] += child;\n expectValue = true;\n }\n } else if (typeof child === \"number\" || child != null) {\n values.push(child as ReactNode);\n strings.push(\"\");\n expectValue = false;\n }\n });\n\n return { strings, values };\n}\n","import { message } from \"@let-value/translate\";\nimport { createElement, Fragment, type ReactNode } from \"react\";\n\nimport { useTranslations } from \"../hooks/useTranslations.ts\";\nimport { buildTemplateFromChildren } from \"../utils.ts\";\n\nexport interface MessageProps {\n context?: string;\n children: ReactNode;\n}\n\nexport function Message({ context, children }: MessageProps) {\n const translator = useTranslations();\n const { strings, values } = buildTemplateFromChildren(children);\n\n if (values.length === 0) {\n const input = strings.join(\"\");\n if (context) {\n return translator.context(context as \"\").message(input as never);\n }\n return translator.message(input as never);\n }\n\n const tokens = values.map((_, i) => `\\u0000${i}\\u0000`);\n const built = message(strings as unknown as TemplateStringsArray, ...tokens);\n const translated = context\n ? translator.translate({ context: context as \"\", id: built })\n : translator.translate(built);\n\n // oxlint-disable-next-line no-control-regex -- using null separators\n const parts = translated.split(/\\u0000(\\d+)\\u0000/);\n const result: ReactNode[] = [];\n for (let i = 0; i < parts.length; i += 2) {\n result.push(parts[i]);\n const idx = parts[i + 1];\n if (idx !== undefined) {\n result.push(values[Number(idx)]);\n }\n }\n\n return createElement(Fragment, null, ...result);\n}\n","import { message, plural } from \"@let-value/translate\";\nimport { createElement, Fragment, type ReactNode } from \"react\";\n\nimport { useTranslations } from \"../hooks/useTranslations.ts\";\nimport { buildTemplateFromChildren } from \"../utils.ts\";\n\nexport interface PluralProps {\n number: number;\n forms: readonly ReactNode[];\n context?: string;\n}\n\nexport function Plural({ number, forms, context }: PluralProps) {\n const translator = useTranslations();\n\n const built = forms.map((child, i) => {\n const { strings, values } = buildTemplateFromChildren(child);\n const tokens = values.map((_, j) => `\\u0000${i}-${j}\\u0000`);\n return { message: message(strings as unknown as TemplateStringsArray, ...tokens), values };\n });\n\n const messages = built.map((b) => b.message);\n const input = plural(...messages, number);\n\n const translated = context\n ? translator.translate({ context: context as \"\", id: input })\n : translator.translate(input);\n\n // oxlint-disable-next-line no-control-regex -- using null separators\n const parts = translated.split(/\\u0000(\\d+)-(\\d+)\\u0000/);\n const result: ReactNode[] = [];\n for (let i = 0; i < parts.length; ) {\n result.push(parts[i]);\n if (i + 2 < parts.length) {\n const formIndex = Number(parts[i + 1]);\n const valueIndex = Number(parts[i + 2]);\n result.push(built[formIndex].values[valueIndex]);\n }\n i += 3;\n }\n\n return createElement(Fragment, null, ...result);\n}\n","import type { Locale } from \"@let-value/translate\";\nimport { Translator } from \"@let-value/translate\";\nimport type { GetTextTranslations } from \"gettext-parser\";\n\ntype TranslationLoader = () => Promise<GetTextTranslations>;\nexport type TranslationEntry = GetTextTranslations | TranslationLoader;\nexport type TranslationsMap = Partial<Record<Locale, TranslationEntry>>;\n\n// Fast path: WeakMap keyed on the translations object reference.\n// GC-safe — entries are collected when the object is no longer reachable.\nconst cacheNoParent = new WeakMap<object, Translator>();\nconst cacheWithParent = new WeakMap<object, WeakMap<Translator, Translator>>();\n\nfunction getFromWeakMap(translations: TranslationsMap, parent: Translator | undefined): Translator | undefined {\n if (!parent) return cacheNoParent.get(translations);\n return cacheWithParent.get(translations)?.get(parent);\n}\n\nfunction setInWeakMap(translations: TranslationsMap, parent: Translator | undefined, translator: Translator): void {\n if (!parent) {\n cacheNoParent.set(translations, translator);\n return;\n }\n let byParent = cacheWithParent.get(translations);\n if (!byParent) {\n byParent = new WeakMap();\n cacheWithParent.set(translations, byParent);\n }\n byParent.set(parent, translator);\n}\n\n// Slow path: bounded structural cache for dynamically-created translations objects\n// (e.g. `translations={{ en: data }}` — new wrapper object, stable value references).\n// Bounded to cap memory usage in infinite-render scenarios.\nconst MAX_STRUCTURAL_ENTRIES = 32;\n\ntype SortedEntry = [Locale, TranslationEntry];\n\ninterface StructuralEntry {\n sortedEntries: SortedEntry[];\n parent: Translator | undefined;\n translator: Translator;\n}\n\nconst structuralCache: StructuralEntry[] = [];\n\nfunction toSortedEntries(translations: TranslationsMap): SortedEntry[] {\n return (Object.entries(translations) as SortedEntry[]).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n}\n\nfunction findStructural(sortedEntries: SortedEntry[], parent: Translator | undefined): Translator | undefined {\n for (const entry of structuralCache) {\n if (entry.parent !== parent || entry.sortedEntries.length !== sortedEntries.length) continue;\n if (entry.sortedEntries.every(([k, v], i) => sortedEntries[i][0] === k && sortedEntries[i][1] === v)) {\n return entry.translator;\n }\n }\n return undefined;\n}\n\nexport function getCachedTranslator(translations: TranslationsMap, parent: Translator | undefined): Translator {\n // Fast path: same object reference\n const cached = getFromWeakMap(translations, parent);\n if (cached) return cached;\n\n // Slow path: same locale keys and value references, different wrapper object\n const sortedEntries = toSortedEntries(translations);\n const structural = findStructural(sortedEntries, parent);\n if (structural) {\n // Backfill WeakMap so subsequent renders with the same new-object are O(1)\n setInWeakMap(translations, parent, structural);\n return structural;\n }\n\n const translator = new Translator(translations, parent);\n setInWeakMap(translations, parent, translator);\n structuralCache.unshift({ sortedEntries, parent, translator });\n if (structuralCache.length > MAX_STRUCTURAL_ENTRIES) structuralCache.pop();\n return translator;\n}\n\n/** Exported only for tests — do not use in application code. */\nexport const _structuralCacheSize = (): number => structuralCache.length;\n","import type { Locale } from \"@let-value/translate\";\nimport { createElement, type ReactNode, use, type ReactElement } from \"react\";\nimport { translatorContext } from \"../context.ts\";\nimport { getCachedTranslator, type TranslationEntry, type TranslationsMap } from \"../translatorCache.ts\";\n\nexport interface TranslationsProviderProps {\n translations?: Partial<Record<Locale, TranslationEntry>>;\n children?: ReactNode;\n}\n\nconst EMPTY_TRANSLATIONS: TranslationsMap = {};\n\nexport function TranslationsProvider({\n translations = EMPTY_TRANSLATIONS,\n children,\n}: TranslationsProviderProps): ReactElement {\n const parent = use(translatorContext);\n const translator = getCachedTranslator(translations, parent);\n return createElement(translatorContext.Provider, { value: translator }, children);\n}\n","import type { Locale } from \"@let-value/translate\";\nimport { use } from \"react\";\nimport { localeContext } from \"../context.ts\";\n\nexport function useLocale(): Locale | undefined {\n return use(localeContext);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,42 +1,48 @@
1
1
  {
2
- "name": "@let-value/translate-react",
3
- "version": "1.1.2",
4
- "type": "module",
5
- "main": "dist/index.cjs",
6
- "module": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js",
12
- "require": "./dist/index.cjs"
13
- },
14
- "./package.json": "./package.json"
2
+ "name": "@let-value/translate-react",
3
+ "version": "1.1.6-beta.1",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/let-value/translate"
7
+ },
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "type": "module",
12
+ "main": "dist/index.cjs",
13
+ "module": "dist/index.mjs",
14
+ "types": "dist/index.d.mts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.mts",
18
+ "import": "./dist/index.mjs",
19
+ "require": "./dist/index.cjs"
15
20
  },
16
- "files": [
17
- "dist"
18
- ],
19
- "scripts": {
20
- "build": "tsdown",
21
- "check": "biome check .",
22
- "format": "biome check --write .",
23
- "typecheck": "tsc --build",
24
- "test": "node --test"
25
- },
26
- "dependencies": {
27
- "@let-value/translate": "1.1.2"
28
- },
29
- "devDependencies": {
30
- "@let-value/translate-e2e": "1.1.2",
31
- "@types/gettext-parser": "8.0.0",
32
- "@types/react": "19.1.13",
33
- "@types/react-dom": "19.1.9",
34
- "react": "19.1.1",
35
- "react-dom": "19.1.1",
36
- "tsdown": "0.15.2",
37
- "typescript": "5.9.2"
38
- },
39
- "peerDependencies": {
40
- "react": ">=19"
41
- }
42
- }
21
+ "./package.json": "./package.json"
22
+ },
23
+ "dependencies": {
24
+ "@let-value/translate": "1.1.6-beta.1"
25
+ },
26
+ "devDependencies": {
27
+ "@types/gettext-parser": "9.0.0",
28
+ "@types/react": "19.2.17",
29
+ "@types/react-dom": "19.2.3",
30
+ "@vitest/browser-playwright": "4.1.9",
31
+ "playwright": "latest",
32
+ "react": "^19.2.7",
33
+ "react-dom": "19.2.7",
34
+ "typescript": "6.0.3",
35
+ "vite-plus": "latest",
36
+ "vitest-browser-react": "latest"
37
+ },
38
+ "peerDependencies": {
39
+ "react": ">=19"
40
+ },
41
+ "scripts": {
42
+ "build": "vp pack",
43
+ "check": "vp check",
44
+ "format": "vp fmt",
45
+ "typecheck": "tsc --build",
46
+ "test": "vp test"
47
+ }
48
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/components/LocaleProvider.ts","../src/components/Message.ts","../src/components/Plural.ts","../src/translatorCache.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts","../src/hooks/useTranslations.ts"],"sourcesContent":[],"mappings":";;;;;;;;;UAIiB,mBAAA;UACL;aACG;;iBAGC,cAAA;;;GAAqC,sBAAmB,MAAA,CAAA,yBAAA,MAAA,CAAA,cAAA;;;UCHvD,YAAA;;YAEH;;iBAGE,OAAA;;;GAA+B,wBAAY,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;UCL1C,WAAA;;kBAEG;;;iBAIJ,MAAA;;;;GAAmC,cAAW,MAAA,CAAA,yBAAA,MAAA,CAAA,aAAA;;;KCRzD,iBAAA,SAA0B,QAAQ;KAC3B,gBAAA,GAAmB,sBAAsB;;;UCApC,yBAAA;iBACE,QAAQ,OAAO,QAAQ;aAC3B;;iBAKC,oBAAA;;;GAAsE,4BAAyB,MAAA,CAAA,yBAAA,MAAA,CAAA,cAAA,qBAAA,CAAA,WAAA,QAAA,OAAA,SAAA,eAAA,CAAA,mBAAA;WAAA,eAAA,CAAA;;EJR9F,OAAA,qCAAmB;CAAA,CAAA,GAAA,CAAA,GAAA,UAAA,uCAAA;SACxB,qCAAA;SACG,SAAA,CAAA,CAAA;;;iBKFC,SAAA,CAAA,GAAa;;;iBC0Bb,eAAA,UAAyB,SAAS"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["result: ReactNode[]","strings: string[]","values: ReactNode[]","result: ReactNode[]","result: ReactNode[]","structuralCache: StructuralEntry[]","EMPTY_TRANSLATIONS: TranslationsMap"],"sources":["../src/context.ts","../src/components/LocaleProvider.ts","../src/hooks/useTranslations.ts","../src/utils.ts","../src/components/Message.ts","../src/components/Plural.ts","../src/translatorCache.ts","../src/components/TranslationsProvider.ts","../src/hooks/useLocale.ts"],"sourcesContent":["import type { Locale, Translator } from \"@let-value/translate\";\nimport { createContext } from \"react\";\n\nexport const localeContext = createContext<Locale | undefined>(undefined);\nexport const translatorContext = createContext<Translator | undefined>(undefined);\n","import type { Locale } from \"@let-value/translate\";\nimport { createElement, type ReactNode } from \"react\";\nimport { localeContext } from \"../context.ts\";\n\nexport interface LocaleProviderProps {\n locale: Locale;\n children?: ReactNode;\n}\n\nexport function LocaleProvider({ locale, children }: LocaleProviderProps) {\n return createElement(localeContext.Provider, { value: locale }, children);\n}\n","import type { Locale, LocaleTranslator } from \"@let-value/translate\";\nimport { use } from \"react\";\n\nimport { localeContext, translatorContext } from \"../context.ts\";\n\n/** @deprecated replace with `use` from react */\n// biome-ignore lint/suspicious/noExplicitAny: we need to decorate the promise\nfunction getPromiseState(promise: any) {\n switch (promise.status) {\n case \"pending\":\n return { status: \"pending\" };\n case \"fulfilled\":\n return { status: \"fulfilled\", value: promise.value };\n case \"rejected\":\n return { status: \"rejected\", reason: promise.reason };\n default: {\n promise.status = \"pending\";\n promise.then((value: unknown) => {\n promise.status = \"fulfilled\";\n promise.value = value;\n });\n promise.catch((reason: unknown) => {\n promise.status = \"rejected\";\n promise.reason = reason;\n });\n return getPromiseState(promise);\n }\n }\n}\n\nexport function useTranslations(locale?: Locale): LocaleTranslator {\n const requestedLocale = locale ?? use(localeContext) ?? (\"unknown\" as never);\n const translator = use(translatorContext);\n if (!translator) {\n throw new Error(\"TranslationsProvider is missing\");\n }\n\n const resource = translator.fetchLocale(requestedLocale);\n if (!(resource instanceof Promise)) {\n return resource;\n }\n\n const state = getPromiseState(resource);\n if (state.status === \"pending\") {\n throw resource;\n }\n if (state.status === \"rejected\") {\n throw state.reason;\n }\n if (state.status === \"fulfilled\") {\n return state.value;\n }\n\n return use(resource);\n}\n","import { Children, Fragment, isValidElement, type PropsWithChildren, type ReactNode } from \"react\";\n\nexport function buildTemplateFromChildren(children: ReactNode): {\n strings: string[];\n values: ReactNode[];\n} {\n function flatten(nodes: ReactNode): ReactNode[] {\n const result: ReactNode[] = [];\n Children.forEach(nodes, (child) => {\n if (isValidElement(child) && child.type === Fragment) {\n result.push(...flatten((child.props as PropsWithChildren).children));\n } else {\n result.push(child);\n }\n });\n return result;\n }\n\n const array = flatten(children);\n const strings: string[] = [\"\"];\n const values: ReactNode[] = [];\n let expectValue = false;\n\n array.forEach((child) => {\n if (typeof child === \"string\") {\n if (expectValue) {\n values.push(child);\n strings.push(\"\");\n expectValue = false;\n } else {\n strings[strings.length - 1] += child;\n expectValue = true;\n }\n } else if (typeof child === \"number\" || child != null) {\n values.push(child as ReactNode);\n strings.push(\"\");\n expectValue = false;\n }\n });\n\n return { strings, values };\n}\n","import { message } from \"@let-value/translate\";\nimport { createElement, Fragment, type ReactNode } from \"react\";\n\nimport { useTranslations } from \"../hooks/useTranslations.ts\";\nimport { buildTemplateFromChildren } from \"../utils.ts\";\n\nexport interface MessageProps {\n context?: string;\n children: ReactNode;\n}\n\nexport function Message({ context, children }: MessageProps) {\n const translator = useTranslations();\n const { strings, values } = buildTemplateFromChildren(children);\n\n if (values.length === 0) {\n const input = strings.join(\"\");\n if (context) {\n return translator.context(context as \"\").message(input as never);\n }\n return translator.message(input as never);\n }\n\n const tokens = values.map((_, i) => `\\u0000${i}\\u0000`);\n const built = message(strings as unknown as TemplateStringsArray, ...tokens);\n const translated = context\n ? translator.translate({ context: context as \"\", id: built })\n : translator.translate(built);\n\n // biome-ignore lint/suspicious/noControlCharactersInRegex: using null separators\n const parts = translated.split(/\\u0000(\\d+)\\u0000/);\n const result: ReactNode[] = [];\n for (let i = 0; i < parts.length; i += 2) {\n result.push(parts[i]);\n const idx = parts[i + 1];\n if (idx !== undefined) {\n result.push(values[Number(idx)]);\n }\n }\n\n return createElement(Fragment, null, ...result);\n}\n","import { message, plural } from \"@let-value/translate\";\nimport { createElement, Fragment, type ReactNode } from \"react\";\n\nimport { useTranslations } from \"../hooks/useTranslations.ts\";\nimport { buildTemplateFromChildren } from \"../utils.ts\";\n\nexport interface PluralProps {\n number: number;\n forms: readonly ReactNode[];\n context?: string;\n}\n\nexport function Plural({ number, forms, context }: PluralProps) {\n const translator = useTranslations();\n\n const built = forms.map((child, i) => {\n const { strings, values } = buildTemplateFromChildren(child);\n const tokens = values.map((_, j) => `\\u0000${i}-${j}\\u0000`);\n return { message: message(strings as unknown as TemplateStringsArray, ...tokens), values };\n });\n\n const messages = built.map((b) => b.message);\n const input = plural(...messages, number);\n\n const translated = context\n ? translator.translate({ context: context as \"\", id: input })\n : translator.translate(input);\n\n // biome-ignore lint/suspicious/noControlCharactersInRegex: using null separators\n const parts = translated.split(/\\u0000(\\d+)-(\\d+)\\u0000/);\n const result: ReactNode[] = [];\n for (let i = 0; i < parts.length; ) {\n result.push(parts[i]);\n if (i + 2 < parts.length) {\n const formIndex = Number(parts[i + 1]);\n const valueIndex = Number(parts[i + 2]);\n result.push(built[formIndex].values[valueIndex]);\n }\n i += 3;\n }\n\n return createElement(Fragment, null, ...result);\n}\n","import type { Locale } from \"@let-value/translate\";\nimport { Translator } from \"@let-value/translate\";\nimport type { GetTextTranslations } from \"gettext-parser\";\n\ntype TranslationLoader = () => Promise<GetTextTranslations>;\nexport type TranslationEntry = GetTextTranslations | TranslationLoader;\nexport type TranslationsMap = Partial<Record<Locale, TranslationEntry>>;\n\n// Fast path: WeakMap keyed on the translations object reference.\n// GC-safe — entries are collected when the object is no longer reachable.\nconst cacheNoParent = new WeakMap<object, Translator>();\nconst cacheWithParent = new WeakMap<object, WeakMap<Translator, Translator>>();\n\nfunction getFromWeakMap(translations: TranslationsMap, parent: Translator | undefined): Translator | undefined {\n if (!parent) return cacheNoParent.get(translations);\n return cacheWithParent.get(translations)?.get(parent);\n}\n\nfunction setInWeakMap(translations: TranslationsMap, parent: Translator | undefined, translator: Translator): void {\n if (!parent) {\n cacheNoParent.set(translations, translator);\n return;\n }\n let byParent = cacheWithParent.get(translations);\n if (!byParent) {\n byParent = new WeakMap();\n cacheWithParent.set(translations, byParent);\n }\n byParent.set(parent, translator);\n}\n\n// Slow path: bounded structural cache for dynamically-created translations objects\n// (e.g. `translations={{ en: data }}` — new wrapper object, stable value references).\n// Bounded to cap memory usage in infinite-render scenarios.\nconst MAX_STRUCTURAL_ENTRIES = 32;\n\ntype SortedEntry = [Locale, TranslationEntry];\n\ninterface StructuralEntry {\n sortedEntries: SortedEntry[];\n parent: Translator | undefined;\n translator: Translator;\n}\n\nconst structuralCache: StructuralEntry[] = [];\n\nfunction toSortedEntries(translations: TranslationsMap): SortedEntry[] {\n return (Object.entries(translations) as SortedEntry[]).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n}\n\nfunction findStructural(sortedEntries: SortedEntry[], parent: Translator | undefined): Translator | undefined {\n for (const entry of structuralCache) {\n if (entry.parent !== parent || entry.sortedEntries.length !== sortedEntries.length) continue;\n if (entry.sortedEntries.every(([k, v], i) => sortedEntries[i][0] === k && sortedEntries[i][1] === v)) {\n return entry.translator;\n }\n }\n return undefined;\n}\n\nexport function getCachedTranslator(translations: TranslationsMap, parent: Translator | undefined): Translator {\n // Fast path: same object reference\n const cached = getFromWeakMap(translations, parent);\n if (cached) return cached;\n\n // Slow path: same locale keys and value references, different wrapper object\n const sortedEntries = toSortedEntries(translations);\n const structural = findStructural(sortedEntries, parent);\n if (structural) {\n // Backfill WeakMap so subsequent renders with the same new-object are O(1)\n setInWeakMap(translations, parent, structural);\n return structural;\n }\n\n const translator = new Translator(translations, parent);\n setInWeakMap(translations, parent, translator);\n structuralCache.unshift({ sortedEntries, parent, translator });\n if (structuralCache.length > MAX_STRUCTURAL_ENTRIES) structuralCache.pop();\n return translator;\n}\n\n/** Exported only for tests — do not use in application code. */\nexport const _structuralCacheSize = (): number => structuralCache.length;\n","import type { Locale } from \"@let-value/translate\";\nimport { createElement, type ReactNode, use } from \"react\";\nimport { translatorContext } from \"../context.ts\";\nimport { type TranslationEntry, type TranslationsMap, getCachedTranslator } from \"../translatorCache.ts\";\n\nexport interface TranslationsProviderProps {\n translations?: Partial<Record<Locale, TranslationEntry>>;\n children?: ReactNode;\n}\n\nconst EMPTY_TRANSLATIONS: TranslationsMap = {};\n\nexport function TranslationsProvider({ translations = EMPTY_TRANSLATIONS, children }: TranslationsProviderProps) {\n const parent = use(translatorContext);\n const translator = getCachedTranslator(translations, parent);\n return createElement(translatorContext.Provider, { value: translator }, children);\n}\n","import type { Locale } from \"@let-value/translate\";\nimport { use } from \"react\";\nimport { localeContext } from \"../context.ts\";\n\nexport function useLocale(): Locale | undefined {\n return use(localeContext);\n}\n"],"mappings":"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"}