@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 +14 -50
- package/dist/index.d.cts +36 -15
- package/dist/index.d.cts.map +1 -1
- package/dist/{index.d.ts → index.d.mts} +37 -16
- package/dist/index.d.mts.map +1 -0
- package/dist/{index.js → index.mjs} +7 -21
- package/dist/index.mjs.map +1 -0
- package/package.json +46 -40
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,41 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
|
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,
|
|
116
|
+
message: (0, _let_value_translate.message)(strings, ...values.map((_, j) => `\u0000${i}-${j}\u0000`)),
|
|
149
117
|
values
|
|
150
118
|
};
|
|
151
119
|
});
|
|
152
|
-
const
|
|
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
|
|
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
|
|
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(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
2
|
import { Locale, LocaleTranslator } from "@let-value/translate";
|
|
3
|
-
import
|
|
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):
|
|
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 |
|
|
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):
|
|
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):
|
|
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;
|
package/dist/index.d.cts.map
CHANGED
|
@@ -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"],"
|
|
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
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
2
|
import { Locale, LocaleTranslator, Translator } from "@let-value/translate";
|
|
3
|
-
import
|
|
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):
|
|
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 |
|
|
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):
|
|
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):
|
|
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.
|
|
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
|
|
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, ...
|
|
116
|
+
message: message(strings, ...values.map((_, j) => `\u0000${i}-${j}\u0000`)),
|
|
126
117
|
values
|
|
127
118
|
};
|
|
128
119
|
});
|
|
129
|
-
const
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
|
|
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
|
+
}
|
package/dist/index.d.ts.map
DELETED
|
@@ -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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"}
|