intor-translator 1.0.1 → 1.0.3
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/README.md +119 -81
- package/dist/index.cjs +205 -155
- package/dist/index.d.cts +339 -221
- package/dist/index.d.ts +339 -221
- package/dist/index.js +204 -154
- package/package.json +19 -10
package/dist/index.cjs
CHANGED
|
@@ -1,37 +1,83 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
// src/cache/cache.ts
|
|
4
|
+
var Cache = class {
|
|
5
|
+
constructor(maxSize = 100, ttl = 1e3 * 60 * 5) {
|
|
6
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
7
|
+
this.maxSize = maxSize;
|
|
8
|
+
this.ttl = ttl;
|
|
9
|
+
}
|
|
10
|
+
// Clean up expired cache entries
|
|
11
|
+
cleanUp() {
|
|
12
|
+
const now = Date.now();
|
|
13
|
+
this.cache.forEach((entry, key) => {
|
|
14
|
+
if (now - entry.timestamp > this.ttl) {
|
|
15
|
+
this.cache.delete(key);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
// Get cache data
|
|
20
|
+
get(key) {
|
|
21
|
+
this.cleanUp();
|
|
22
|
+
const entry = this.cache.get(key);
|
|
23
|
+
if (entry) {
|
|
24
|
+
entry.timestamp = Date.now();
|
|
25
|
+
return entry.value;
|
|
26
|
+
}
|
|
27
|
+
return void 0;
|
|
28
|
+
}
|
|
29
|
+
// Set cache data
|
|
30
|
+
set(key, value) {
|
|
31
|
+
this.cleanUp();
|
|
32
|
+
if (this.cache.size >= this.maxSize) {
|
|
33
|
+
const oldestKey = this.cache.keys().next().value;
|
|
34
|
+
if (oldestKey) this.cache.delete(oldestKey);
|
|
35
|
+
}
|
|
36
|
+
this.cache.set(key, { value, timestamp: Date.now() });
|
|
37
|
+
}
|
|
38
|
+
// Check if a key exists in the cache
|
|
39
|
+
has(key) {
|
|
40
|
+
this.cleanUp();
|
|
41
|
+
return this.cache.has(key);
|
|
42
|
+
}
|
|
43
|
+
// Clear all cache
|
|
44
|
+
clear() {
|
|
45
|
+
this.cache.clear();
|
|
46
|
+
}
|
|
8
47
|
};
|
|
9
48
|
|
|
10
|
-
// src/
|
|
11
|
-
var
|
|
12
|
-
|
|
49
|
+
// src/cache/message-key-cache.ts
|
|
50
|
+
var MESSAGE_KEY_CACHE_MAX_SIZE = 100;
|
|
51
|
+
var MESSAGE_KEY_CACHE_EXPIRES_TIME = 1e3 * 60 * 5;
|
|
52
|
+
var messageKeyCache;
|
|
53
|
+
var getMessageKeyCache = () => {
|
|
54
|
+
if (typeof window !== "undefined" && !messageKeyCache) {
|
|
55
|
+
messageKeyCache = new Cache(
|
|
56
|
+
MESSAGE_KEY_CACHE_MAX_SIZE,
|
|
57
|
+
MESSAGE_KEY_CACHE_EXPIRES_TIME
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return messageKeyCache;
|
|
13
61
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
62
|
+
var clearMessageKeyCache = () => {
|
|
63
|
+
if (messageKeyCache) {
|
|
64
|
+
messageKeyCache.clear();
|
|
65
|
+
messageKeyCache = void 0;
|
|
66
|
+
}
|
|
18
67
|
};
|
|
19
68
|
|
|
20
|
-
// src/
|
|
21
|
-
var createGetMessages = (messagesRef) => {
|
|
22
|
-
return () => getMessages(messagesRef);
|
|
23
|
-
};
|
|
69
|
+
// src/utils/get-value-by-key.ts
|
|
24
70
|
var getValueByKey = (locale, messages, key, useCache = true) => {
|
|
25
|
-
const cache =
|
|
71
|
+
const cache = getMessageKeyCache();
|
|
26
72
|
useCache = Boolean(useCache && cache);
|
|
27
73
|
const cacheKey = `${key}`;
|
|
28
|
-
const currentLocale = cache
|
|
74
|
+
const currentLocale = cache?.get("locale");
|
|
29
75
|
if (currentLocale !== locale) {
|
|
30
|
-
cache
|
|
31
|
-
cache
|
|
76
|
+
cache?.clear();
|
|
77
|
+
cache?.set("locale", locale);
|
|
32
78
|
}
|
|
33
|
-
if (useCache &&
|
|
34
|
-
return cache
|
|
79
|
+
if (useCache && cache?.has(cacheKey)) {
|
|
80
|
+
return cache?.get(cacheKey);
|
|
35
81
|
}
|
|
36
82
|
const value = key.split(".").reduce((acc, key2) => {
|
|
37
83
|
if (acc && typeof acc === "object" && key2 in acc) {
|
|
@@ -40,7 +86,7 @@ var getValueByKey = (locale, messages, key, useCache = true) => {
|
|
|
40
86
|
return void 0;
|
|
41
87
|
}, messages);
|
|
42
88
|
if (useCache && value !== void 0) {
|
|
43
|
-
cache
|
|
89
|
+
cache?.set(cacheKey, value);
|
|
44
90
|
}
|
|
45
91
|
return value;
|
|
46
92
|
};
|
|
@@ -66,49 +112,22 @@ var findMessageInLocales = ({
|
|
|
66
112
|
|
|
67
113
|
// src/utils/resolve-locales-to-try.ts
|
|
68
114
|
var resolveLocalesToTry = (locale, fallbackLocales) => {
|
|
69
|
-
const fallbacks =
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
...fallbacks.filter((l) => l !== locale)
|
|
73
|
-
];
|
|
115
|
+
const fallbacks = fallbackLocales?.[locale] || [];
|
|
116
|
+
const filteredFallbacks = fallbacks.filter((l) => l !== locale);
|
|
117
|
+
return [locale, ...filteredFallbacks];
|
|
74
118
|
};
|
|
75
119
|
|
|
76
|
-
// src/methods/has-key/has-key.ts
|
|
120
|
+
// src/translator-methods/has-key/has-key.ts
|
|
77
121
|
var hasKey = ({
|
|
78
122
|
messagesRef,
|
|
79
123
|
localeRef,
|
|
80
|
-
translatorOptions,
|
|
81
124
|
key,
|
|
82
|
-
|
|
125
|
+
targetLocale
|
|
83
126
|
}) => {
|
|
84
127
|
const messages = messagesRef.current;
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
const message = findMessageInLocales({ messages, localesToTry, key });
|
|
89
|
-
return message ? true : false;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
// src/methods/has-key/create-has-key.ts
|
|
93
|
-
var createHasKey = (messagesRef, localeRef, translatorOptions) => {
|
|
94
|
-
return (key, locale) => hasKey({
|
|
95
|
-
messagesRef,
|
|
96
|
-
localeRef,
|
|
97
|
-
translatorOptions,
|
|
98
|
-
key,
|
|
99
|
-
locale
|
|
100
|
-
});
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// src/utils/get-full-key.ts
|
|
104
|
-
var getFullKey = (preKey, key) => {
|
|
105
|
-
if (!preKey) {
|
|
106
|
-
return key;
|
|
107
|
-
}
|
|
108
|
-
if (!key) {
|
|
109
|
-
return preKey;
|
|
110
|
-
}
|
|
111
|
-
return `${preKey}.${key}`;
|
|
128
|
+
const locale = localeRef.current;
|
|
129
|
+
const localesToTry = resolveLocalesToTry(targetLocale || locale);
|
|
130
|
+
return findMessageInLocales({ messages, localesToTry, key }) ? true : false;
|
|
112
131
|
};
|
|
113
132
|
|
|
114
133
|
// src/utils/replace-values.ts
|
|
@@ -130,24 +149,32 @@ var replaceValues = (message, params) => {
|
|
|
130
149
|
return replaced;
|
|
131
150
|
};
|
|
132
151
|
|
|
133
|
-
// src/methods/translate/translate.ts
|
|
152
|
+
// src/translator-methods/translate/translate.ts
|
|
134
153
|
var translate = ({
|
|
135
154
|
messagesRef,
|
|
136
155
|
localeRef,
|
|
137
|
-
|
|
156
|
+
isLoadingRef,
|
|
157
|
+
translateConfig,
|
|
138
158
|
key,
|
|
139
159
|
replacements
|
|
140
160
|
}) => {
|
|
141
161
|
const messages = messagesRef.current;
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
const
|
|
162
|
+
const locale = localeRef.current;
|
|
163
|
+
const isLoading = isLoadingRef.current;
|
|
164
|
+
const {
|
|
165
|
+
fallbackLocales,
|
|
166
|
+
loadingMessage,
|
|
167
|
+
placeholder,
|
|
168
|
+
handlers = {}
|
|
169
|
+
} = translateConfig;
|
|
170
|
+
const { formatMessage, onLoading, onMissing } = handlers;
|
|
171
|
+
const localesToTry = resolveLocalesToTry(locale, fallbackLocales);
|
|
145
172
|
const message = findMessageInLocales({ messages, localesToTry, key });
|
|
146
173
|
if (isLoading) {
|
|
147
|
-
if (
|
|
148
|
-
return
|
|
174
|
+
if (onLoading) {
|
|
175
|
+
return onLoading({
|
|
149
176
|
key,
|
|
150
|
-
locale
|
|
177
|
+
locale,
|
|
151
178
|
replacements
|
|
152
179
|
});
|
|
153
180
|
}
|
|
@@ -156,113 +183,136 @@ var translate = ({
|
|
|
156
183
|
}
|
|
157
184
|
}
|
|
158
185
|
if (!message) {
|
|
159
|
-
if (
|
|
160
|
-
return
|
|
161
|
-
key,
|
|
162
|
-
locale: localeRef.current,
|
|
163
|
-
replacements
|
|
164
|
-
});
|
|
186
|
+
if (onMissing) {
|
|
187
|
+
return onMissing({ key, locale, replacements });
|
|
165
188
|
}
|
|
166
189
|
if (placeholder) {
|
|
167
190
|
return placeholder;
|
|
168
191
|
}
|
|
169
192
|
return key;
|
|
170
193
|
}
|
|
171
|
-
if (
|
|
172
|
-
return
|
|
173
|
-
message,
|
|
174
|
-
key,
|
|
175
|
-
locale: localeRef.current,
|
|
176
|
-
replacements
|
|
177
|
-
});
|
|
194
|
+
if (formatMessage) {
|
|
195
|
+
return formatMessage({ message, key, locale, replacements });
|
|
178
196
|
} else {
|
|
179
197
|
return replacements ? replaceValues(message, replacements) : message;
|
|
180
198
|
}
|
|
181
199
|
};
|
|
182
200
|
|
|
183
|
-
// src/
|
|
184
|
-
var
|
|
185
|
-
|
|
186
|
-
messagesRef
|
|
187
|
-
localeRef
|
|
188
|
-
|
|
189
|
-
key,
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
messagesRef,
|
|
203
|
-
localeRef,
|
|
204
|
-
translatorOptions
|
|
205
|
-
);
|
|
206
|
-
const baseHasKey = createHasKey(
|
|
207
|
-
messagesRef,
|
|
208
|
-
localeRef,
|
|
209
|
-
translatorOptions
|
|
210
|
-
);
|
|
211
|
-
return {
|
|
212
|
-
// t (Scoped)
|
|
213
|
-
t: (key, replacements) => {
|
|
214
|
-
const fullKey = getFullKey(preKey, key);
|
|
215
|
-
return baseTranslate(fullKey, replacements);
|
|
216
|
-
},
|
|
217
|
-
// hasKey (Scoped)
|
|
218
|
-
hasKey: (key, locale) => {
|
|
219
|
-
const fullKey = getFullKey(preKey, key);
|
|
220
|
-
return baseHasKey(fullKey, locale);
|
|
201
|
+
// src/translators/base-translator/base-translator.ts
|
|
202
|
+
var BaseTranslator = class {
|
|
203
|
+
constructor(options) {
|
|
204
|
+
this.messagesRef = { current: {} };
|
|
205
|
+
this.localeRef = { current: "" };
|
|
206
|
+
/** Check if a key exists in the specified locale or current locale. */
|
|
207
|
+
this.hasKey = (key, targetLocale) => {
|
|
208
|
+
return hasKey({
|
|
209
|
+
messagesRef: this.messagesRef,
|
|
210
|
+
localeRef: this.localeRef,
|
|
211
|
+
key,
|
|
212
|
+
targetLocale
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
if (!options.messages) {
|
|
216
|
+
throw new Error("[intor-translator] 'messages' is required");
|
|
217
|
+
}
|
|
218
|
+
if (!options.locale) {
|
|
219
|
+
throw new Error("[intor-translator] 'locale' is required");
|
|
221
220
|
}
|
|
222
|
-
|
|
221
|
+
this.options = options;
|
|
222
|
+
this.messagesRef.current = options.messages;
|
|
223
|
+
this.localeRef.current = options.locale;
|
|
224
|
+
}
|
|
225
|
+
/** Get all message data. */
|
|
226
|
+
get messages() {
|
|
227
|
+
return this.messagesRef.current;
|
|
228
|
+
}
|
|
229
|
+
/** Replace messages with new ones. */
|
|
230
|
+
setMessages(messages) {
|
|
231
|
+
this.messagesRef.current = messages;
|
|
232
|
+
clearMessageKeyCache();
|
|
233
|
+
}
|
|
234
|
+
/** Get the current active locale. */
|
|
235
|
+
get locale() {
|
|
236
|
+
return this.localeRef.current;
|
|
237
|
+
}
|
|
238
|
+
/** Change the active locale if available. */
|
|
239
|
+
setLocale(newLocale) {
|
|
240
|
+
if (newLocale in this.messagesRef.current) {
|
|
241
|
+
this.localeRef.current = newLocale;
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
223
246
|
};
|
|
224
247
|
|
|
225
|
-
// src/
|
|
226
|
-
var
|
|
227
|
-
|
|
248
|
+
// src/translators/core-translator/core-translator.ts
|
|
249
|
+
var CoreTranslator = class extends BaseTranslator {
|
|
250
|
+
constructor(options) {
|
|
251
|
+
super(options);
|
|
252
|
+
this.isLoadingRef = { current: false };
|
|
253
|
+
this.t = (key, replacements) => {
|
|
254
|
+
return translate({
|
|
255
|
+
messagesRef: this.messagesRef,
|
|
256
|
+
localeRef: this.localeRef,
|
|
257
|
+
isLoadingRef: this.isLoadingRef,
|
|
258
|
+
translateConfig: this.options,
|
|
259
|
+
key,
|
|
260
|
+
replacements
|
|
261
|
+
});
|
|
262
|
+
};
|
|
263
|
+
this.options = options;
|
|
264
|
+
}
|
|
265
|
+
/** Get the current loading state. */
|
|
266
|
+
get isLoading() {
|
|
267
|
+
return this.isLoadingRef.current;
|
|
268
|
+
}
|
|
269
|
+
/** Set the loading state. */
|
|
270
|
+
setLoading(state) {
|
|
271
|
+
this.isLoadingRef.current = state;
|
|
272
|
+
}
|
|
228
273
|
};
|
|
229
274
|
|
|
230
|
-
// src/
|
|
231
|
-
var
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
if (newLocale in messages) {
|
|
238
|
-
localeRef.current = newLocale;
|
|
275
|
+
// src/utils/get-full-key.ts
|
|
276
|
+
var getFullKey = (preKey = "", key = "") => {
|
|
277
|
+
if (!preKey) {
|
|
278
|
+
return key;
|
|
279
|
+
}
|
|
280
|
+
if (!key) {
|
|
281
|
+
return preKey;
|
|
239
282
|
}
|
|
283
|
+
return `${preKey}.${key}`;
|
|
240
284
|
};
|
|
241
285
|
|
|
242
|
-
// src/
|
|
243
|
-
var
|
|
244
|
-
|
|
286
|
+
// src/translators/scope-translator/scope-translator.ts
|
|
287
|
+
var ScopeTranslator = class extends CoreTranslator {
|
|
288
|
+
constructor(options) {
|
|
289
|
+
super(options);
|
|
290
|
+
this.scoped = (preKey) => {
|
|
291
|
+
return {
|
|
292
|
+
hasKey: (key, targetLocale) => {
|
|
293
|
+
const fullKey = getFullKey(preKey, key);
|
|
294
|
+
return hasKey({
|
|
295
|
+
messagesRef: this.messagesRef,
|
|
296
|
+
localeRef: this.localeRef,
|
|
297
|
+
key: fullKey,
|
|
298
|
+
targetLocale
|
|
299
|
+
});
|
|
300
|
+
},
|
|
301
|
+
t: (key, replacements) => {
|
|
302
|
+
const fullKey = getFullKey(preKey, key);
|
|
303
|
+
return translate({
|
|
304
|
+
messagesRef: this.messagesRef,
|
|
305
|
+
localeRef: this.localeRef,
|
|
306
|
+
isLoadingRef: this.isLoadingRef,
|
|
307
|
+
translateConfig: this.options,
|
|
308
|
+
key: fullKey,
|
|
309
|
+
replacements
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
this.options = options;
|
|
315
|
+
}
|
|
245
316
|
};
|
|
246
317
|
|
|
247
|
-
|
|
248
|
-
function createTranslator(translatorOptions) {
|
|
249
|
-
const { locale } = translatorOptions;
|
|
250
|
-
const messagesRef = { current: translatorOptions.messages };
|
|
251
|
-
const localeRef = { current: locale };
|
|
252
|
-
const getLocale2 = createGetLocale(localeRef);
|
|
253
|
-
const setLocale2 = createSetLocale(messagesRef, localeRef);
|
|
254
|
-
const getMessages2 = createGetMessages(messagesRef);
|
|
255
|
-
const hasKey2 = createHasKey(messagesRef, localeRef, translatorOptions);
|
|
256
|
-
const t = createTranslate(messagesRef, localeRef, translatorOptions);
|
|
257
|
-
const scoped2 = createScoped(messagesRef, localeRef, translatorOptions);
|
|
258
|
-
return {
|
|
259
|
-
getLocale: getLocale2,
|
|
260
|
-
setLocale: setLocale2,
|
|
261
|
-
getMessages: getMessages2,
|
|
262
|
-
hasKey: hasKey2,
|
|
263
|
-
t,
|
|
264
|
-
scoped: scoped2
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
exports.createTranslator = createTranslator;
|
|
318
|
+
exports.Translator = ScopeTranslator;
|