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/dist/index.cjs CHANGED
@@ -1,37 +1,83 @@
1
1
  'use strict';
2
2
 
3
- var intorCache = require('intor-cache');
4
-
5
- // src/methods/get-locale/get-locale.ts
6
- var getLocale = (localeRef) => {
7
- return localeRef.current;
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/methods/get-locale/create-get-locale.ts
11
- var createGetLocale = (localeRef) => {
12
- return () => getLocale(localeRef);
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
- // src/methods/get-messages/get-messages.ts
16
- var getMessages = (messagesRef) => {
17
- return messagesRef.current;
62
+ var clearMessageKeyCache = () => {
63
+ if (messageKeyCache) {
64
+ messageKeyCache.clear();
65
+ messageKeyCache = void 0;
66
+ }
18
67
  };
19
68
 
20
- // src/methods/get-messages/create-get-messages.ts
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 = intorCache.getMessageKeyCache();
71
+ const cache = getMessageKeyCache();
26
72
  useCache = Boolean(useCache && cache);
27
73
  const cacheKey = `${key}`;
28
- const currentLocale = cache == null ? void 0 : cache.get("locale");
74
+ const currentLocale = cache?.get("locale");
29
75
  if (currentLocale !== locale) {
30
- cache == null ? void 0 : cache.clear();
31
- cache == null ? void 0 : cache.set("locale", locale);
76
+ cache?.clear();
77
+ cache?.set("locale", locale);
32
78
  }
33
- if (useCache && (cache == null ? void 0 : cache.has(cacheKey))) {
34
- return cache == null ? void 0 : cache.get(cacheKey);
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 == null ? void 0 : cache.set(cacheKey, value);
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 = (fallbackLocales == null ? void 0 : fallbackLocales[locale]) || [];
70
- return [
71
- locale,
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
- locale
125
+ targetLocale
83
126
  }) => {
84
127
  const messages = messagesRef.current;
85
- const { fallbackLocales } = translatorOptions;
86
- const targetLocale = locale != null ? locale : localeRef.current;
87
- const localesToTry = resolveLocalesToTry(targetLocale, fallbackLocales);
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
- translatorOptions,
156
+ isLoadingRef,
157
+ translateConfig,
138
158
  key,
139
159
  replacements
140
160
  }) => {
141
161
  const messages = messagesRef.current;
142
- const { fallbackLocales, isLoading, loadingMessage, placeholder } = translatorOptions;
143
- const { messageFormatter, loadingMessageHandler, placeholderHandler } = translatorOptions.handlers || {};
144
- const localesToTry = resolveLocalesToTry(localeRef.current, fallbackLocales);
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 (loadingMessageHandler) {
148
- return loadingMessageHandler({
174
+ if (onLoading) {
175
+ return onLoading({
149
176
  key,
150
- locale: localeRef.current,
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 (placeholderHandler) {
160
- return placeholderHandler({
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 (messageFormatter) {
172
- return messageFormatter({
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/methods/translate/create-translate.ts
184
- var createTranslate = (messagesRef, localeRef, translatorOptions) => {
185
- return (key, replacements) => translate({
186
- messagesRef,
187
- localeRef,
188
- translatorOptions,
189
- key,
190
- replacements
191
- });
192
- };
193
-
194
- // src/methods/scoped/scoped.ts
195
- var scoped = ({
196
- messagesRef,
197
- localeRef,
198
- translatorOptions,
199
- preKey
200
- }) => {
201
- const baseTranslate = createTranslate(
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/methods/scoped/create-scoped.ts
226
- var createScoped = (messagesRef, localeRef, translatorOptions) => {
227
- return (preKey) => scoped({ messagesRef, localeRef, translatorOptions, preKey });
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/methods/set-locale/set-locale.ts
231
- var setLocale = ({
232
- messagesRef,
233
- localeRef,
234
- newLocale
235
- }) => {
236
- const messages = messagesRef.current;
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/methods/set-locale/create-set-locale.ts
243
- var createSetLocale = (messagesRef, localeRef) => {
244
- return (newLocale) => setLocale({ messagesRef, localeRef, newLocale });
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
- // src/create-translator.ts
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;