@hua-labs/i18n-core 2.2.0 → 2.2.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/LICENSE +21 -0
- package/README.md +4 -4
- package/dist/{chunk-7ZYOSEMW.mjs → chunk-4IYWT7MS.mjs} +143 -45
- package/dist/chunk-4IYWT7MS.mjs.map +1 -0
- package/dist/index.cjs +500 -288
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +21 -21
- package/dist/index.d.ts +21 -21
- package/dist/index.mjs +361 -247
- package/dist/index.mjs.map +1 -1
- package/dist/{server-DgpyR0RE.d.mts → server-CQztOmd-.d.mts} +21 -7
- package/dist/{server-DgpyR0RE.d.ts → server-CQztOmd-.d.ts} +21 -7
- package/dist/server.cjs +141 -43
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.mjs +1 -1
- package/package.json +9 -9
- package/src/__tests__/default-value.test.ts +149 -0
- package/src/core/translator.tsx +385 -188
- package/src/hooks/useI18n.tsx +490 -337
- package/src/types/index.ts +291 -163
- package/dist/chunk-7ZYOSEMW.mjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -10,9 +10,17 @@ var React__default = /*#__PURE__*/_interopDefault(React);
|
|
|
10
10
|
// src/index.ts
|
|
11
11
|
|
|
12
12
|
// src/types/index.ts
|
|
13
|
-
var PLURAL_CATEGORIES = /* @__PURE__ */ new Set([
|
|
13
|
+
var PLURAL_CATEGORIES = /* @__PURE__ */ new Set([
|
|
14
|
+
"zero",
|
|
15
|
+
"one",
|
|
16
|
+
"two",
|
|
17
|
+
"few",
|
|
18
|
+
"many",
|
|
19
|
+
"other"
|
|
20
|
+
]);
|
|
14
21
|
function isPluralValue(value) {
|
|
15
|
-
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
22
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
23
|
+
return false;
|
|
16
24
|
const obj = value;
|
|
17
25
|
const keys = Object.keys(obj);
|
|
18
26
|
return keys.length > 0 && keys.every((k) => PLURAL_CATEGORIES.has(k)) && Object.values(obj).every((v) => typeof v === "string") && typeof obj.other === "string";
|
|
@@ -110,7 +118,9 @@ var Translator = class {
|
|
|
110
118
|
this.currentLang = config.defaultLanguage;
|
|
111
119
|
if (config.initialTranslations) {
|
|
112
120
|
this.allTranslations = config.initialTranslations;
|
|
113
|
-
for (const [language, namespaces] of Object.entries(
|
|
121
|
+
for (const [language, namespaces] of Object.entries(
|
|
122
|
+
config.initialTranslations
|
|
123
|
+
)) {
|
|
114
124
|
for (const namespace of Object.keys(namespaces)) {
|
|
115
125
|
this.loadedNamespaces.add(`${language}:${namespace}`);
|
|
116
126
|
}
|
|
@@ -208,9 +218,15 @@ var Translator = class {
|
|
|
208
218
|
}
|
|
209
219
|
}
|
|
210
220
|
if (this.config.debug) {
|
|
211
|
-
console.log(
|
|
221
|
+
console.log(
|
|
222
|
+
"\u{1F30D} [TRANSLATOR] Initializing translator with languages:",
|
|
223
|
+
languages
|
|
224
|
+
);
|
|
212
225
|
console.log("\u{1F4CD} [TRANSLATOR] Current language:", this.currentLang);
|
|
213
|
-
console.log(
|
|
226
|
+
console.log(
|
|
227
|
+
"\u{1F4E6} [TRANSLATOR] Config namespaces:",
|
|
228
|
+
this.config.namespaces
|
|
229
|
+
);
|
|
214
230
|
}
|
|
215
231
|
for (const language of languages) {
|
|
216
232
|
if (this.config.debug) {
|
|
@@ -223,12 +239,23 @@ var Translator = class {
|
|
|
223
239
|
const cacheKey = `${language}:${namespace}`;
|
|
224
240
|
if (skipNamespaces.has(cacheKey)) {
|
|
225
241
|
if (this.config.debug) {
|
|
226
|
-
console.log(
|
|
242
|
+
console.log(
|
|
243
|
+
"\u23ED\uFE0F [TRANSLATOR] Skipping",
|
|
244
|
+
namespace,
|
|
245
|
+
"for",
|
|
246
|
+
language,
|
|
247
|
+
"(already loaded from SSR)"
|
|
248
|
+
);
|
|
227
249
|
}
|
|
228
250
|
continue;
|
|
229
251
|
}
|
|
230
252
|
if (this.config.debug) {
|
|
231
|
-
console.log(
|
|
253
|
+
console.log(
|
|
254
|
+
"Loading namespace:",
|
|
255
|
+
namespace,
|
|
256
|
+
"for language:",
|
|
257
|
+
language
|
|
258
|
+
);
|
|
232
259
|
}
|
|
233
260
|
try {
|
|
234
261
|
const data = await this.safeLoadTranslations(language, namespace);
|
|
@@ -248,7 +275,10 @@ var Translator = class {
|
|
|
248
275
|
if (isRecoverableError(translationError)) {
|
|
249
276
|
if (language !== this.config.fallbackLanguage) {
|
|
250
277
|
try {
|
|
251
|
-
const fallbackData = await this.safeLoadTranslations(
|
|
278
|
+
const fallbackData = await this.safeLoadTranslations(
|
|
279
|
+
this.config.fallbackLanguage || "en",
|
|
280
|
+
namespace
|
|
281
|
+
);
|
|
252
282
|
this.allTranslations[language][namespace] = fallbackData;
|
|
253
283
|
this.loadedNamespaces.add(`${language}:${namespace}`);
|
|
254
284
|
if (this.config.debug) {
|
|
@@ -286,7 +316,9 @@ var Translator = class {
|
|
|
286
316
|
this.logError(this.initializationError);
|
|
287
317
|
this.isInitialized = true;
|
|
288
318
|
if (this.config.debug) {
|
|
289
|
-
console.warn(
|
|
319
|
+
console.warn(
|
|
320
|
+
"Translator initialized with errors, using fallback translations"
|
|
321
|
+
);
|
|
290
322
|
}
|
|
291
323
|
}
|
|
292
324
|
}
|
|
@@ -301,7 +333,10 @@ var Translator = class {
|
|
|
301
333
|
const result = this.findInNamespace(namespace, actualKey, targetLang);
|
|
302
334
|
if (result) {
|
|
303
335
|
if (this.config.debug) {
|
|
304
|
-
console.log(
|
|
336
|
+
console.log(
|
|
337
|
+
`\u2705 [TRANSLATOR] Found fallback translation from initialTranslations:`,
|
|
338
|
+
result
|
|
339
|
+
);
|
|
305
340
|
}
|
|
306
341
|
return result;
|
|
307
342
|
}
|
|
@@ -365,10 +400,17 @@ var Translator = class {
|
|
|
365
400
|
}
|
|
366
401
|
if (!this.isInitialized) {
|
|
367
402
|
const raw = this.translateBeforeInitialized(key, targetLang);
|
|
403
|
+
if ((!raw || raw === key) && params && typeof params === "object" && "defaultValue" in params && typeof params.defaultValue === "string") {
|
|
404
|
+
return this.interpolate(params.defaultValue, params);
|
|
405
|
+
}
|
|
368
406
|
return params ? this.interpolate(raw, params) : raw;
|
|
369
407
|
}
|
|
370
408
|
const { namespace, key: actualKey } = this.parseKey(key);
|
|
371
|
-
let result = this.findInNamespace(
|
|
409
|
+
let result = this.findInNamespace(
|
|
410
|
+
namespace,
|
|
411
|
+
actualKey,
|
|
412
|
+
targetLang
|
|
413
|
+
);
|
|
372
414
|
if (result) {
|
|
373
415
|
this.cacheStats.hits++;
|
|
374
416
|
return params ? this.interpolate(result, params) : result;
|
|
@@ -382,6 +424,9 @@ var Translator = class {
|
|
|
382
424
|
return params ? this.interpolate(result, params) : result;
|
|
383
425
|
}
|
|
384
426
|
this.cacheStats.misses++;
|
|
427
|
+
if (params && typeof params === "object" && "defaultValue" in params && typeof params.defaultValue === "string") {
|
|
428
|
+
return this.interpolate(params.defaultValue, params);
|
|
429
|
+
}
|
|
385
430
|
if (this.config.debug) {
|
|
386
431
|
const missing = this.config.missingKeyHandler?.(key, targetLang, namespace) || key;
|
|
387
432
|
return params ? this.interpolate(missing, params) : missing;
|
|
@@ -398,11 +443,16 @@ var Translator = class {
|
|
|
398
443
|
if (!this.loadedNamespaces.has(cacheKey) && !this.loadingPromises.has(cacheKey)) {
|
|
399
444
|
this.loadTranslationData(language, namespace).catch((error) => {
|
|
400
445
|
if (this.config.debug) {
|
|
401
|
-
console.warn(
|
|
446
|
+
console.warn(
|
|
447
|
+
`\u26A0\uFE0F [TRANSLATOR] Auto-load failed for ${language}/${namespace}:`,
|
|
448
|
+
error
|
|
449
|
+
);
|
|
402
450
|
}
|
|
403
451
|
});
|
|
404
452
|
if (this.config.debug) {
|
|
405
|
-
console.warn(
|
|
453
|
+
console.warn(
|
|
454
|
+
`\u274C [TRANSLATOR] No translations found for ${language}/${namespace}, attempting auto-load...`
|
|
455
|
+
);
|
|
406
456
|
}
|
|
407
457
|
}
|
|
408
458
|
return "";
|
|
@@ -422,7 +472,9 @@ var Translator = class {
|
|
|
422
472
|
return nestedValue[Math.floor(Math.random() * nestedValue.length)];
|
|
423
473
|
}
|
|
424
474
|
if (this.config.debug) {
|
|
425
|
-
console.warn(
|
|
475
|
+
console.warn(
|
|
476
|
+
`\u274C [TRANSLATOR] No match found for key: ${key} in ${language}/${namespace}`
|
|
477
|
+
);
|
|
426
478
|
}
|
|
427
479
|
return "";
|
|
428
480
|
}
|
|
@@ -488,7 +540,10 @@ var Translator = class {
|
|
|
488
540
|
if (actualKey in fallbackTranslations) {
|
|
489
541
|
return fallbackTranslations[actualKey];
|
|
490
542
|
}
|
|
491
|
-
const fallbackNestedValue = this.getNestedValue(
|
|
543
|
+
const fallbackNestedValue = this.getNestedValue(
|
|
544
|
+
fallbackTranslations,
|
|
545
|
+
actualKey
|
|
546
|
+
);
|
|
492
547
|
if (fallbackNestedValue !== void 0) {
|
|
493
548
|
return fallbackNestedValue;
|
|
494
549
|
}
|
|
@@ -534,7 +589,9 @@ var Translator = class {
|
|
|
534
589
|
const raw = this.getRawValue(key, targetLang);
|
|
535
590
|
const mergedParams = { count, ...params };
|
|
536
591
|
if (isPluralValue(raw)) {
|
|
537
|
-
const category = this.getPluralRules(targetLang).select(
|
|
592
|
+
const category = this.getPluralRules(targetLang).select(
|
|
593
|
+
count
|
|
594
|
+
);
|
|
538
595
|
const text = raw[category] ?? raw.other;
|
|
539
596
|
return this.interpolate(text, mergedParams);
|
|
540
597
|
}
|
|
@@ -577,7 +634,9 @@ var Translator = class {
|
|
|
577
634
|
});
|
|
578
635
|
}
|
|
579
636
|
if (this.config.debug) {
|
|
580
|
-
console.log(
|
|
637
|
+
console.log(
|
|
638
|
+
`\u{1F310} [TRANSLATOR] Language changed: ${previousLanguage} -> ${language}`
|
|
639
|
+
);
|
|
581
640
|
}
|
|
582
641
|
}
|
|
583
642
|
/**
|
|
@@ -689,7 +748,11 @@ var Translator = class {
|
|
|
689
748
|
*/
|
|
690
749
|
logError(error) {
|
|
691
750
|
if (this.config.errorHandler) {
|
|
692
|
-
this.config.errorHandler(
|
|
751
|
+
this.config.errorHandler(
|
|
752
|
+
error,
|
|
753
|
+
error.language || "",
|
|
754
|
+
error.namespace || ""
|
|
755
|
+
);
|
|
693
756
|
}
|
|
694
757
|
}
|
|
695
758
|
/**
|
|
@@ -712,7 +775,9 @@ var Translator = class {
|
|
|
712
775
|
if (attempt === maxRetries) {
|
|
713
776
|
break;
|
|
714
777
|
}
|
|
715
|
-
await new Promise(
|
|
778
|
+
await new Promise(
|
|
779
|
+
(resolve) => setTimeout(resolve, Math.pow(2, attempt) * 1e3)
|
|
780
|
+
);
|
|
716
781
|
}
|
|
717
782
|
}
|
|
718
783
|
throw lastError;
|
|
@@ -722,21 +787,29 @@ var Translator = class {
|
|
|
722
787
|
*/
|
|
723
788
|
async safeLoadTranslations(language, namespace) {
|
|
724
789
|
if (this.config.debug) {
|
|
725
|
-
console.log(`\u{1F4E5} [TRANSLATOR] safeLoadTranslations called:`, {
|
|
790
|
+
console.log(`\u{1F4E5} [TRANSLATOR] safeLoadTranslations called:`, {
|
|
791
|
+
language,
|
|
792
|
+
namespace
|
|
793
|
+
});
|
|
726
794
|
}
|
|
727
795
|
const loadOperation = async () => {
|
|
728
796
|
if (!this.config.loadTranslations) {
|
|
729
797
|
throw new Error("No translation loader configured");
|
|
730
798
|
}
|
|
731
799
|
if (this.config.debug) {
|
|
732
|
-
console.log(`\u{1F504} [TRANSLATOR] Calling loadTranslations for:`, {
|
|
800
|
+
console.log(`\u{1F504} [TRANSLATOR] Calling loadTranslations for:`, {
|
|
801
|
+
language,
|
|
802
|
+
namespace
|
|
803
|
+
});
|
|
733
804
|
}
|
|
734
805
|
const data = await this.config.loadTranslations(language, namespace);
|
|
735
806
|
if (this.config.debug) {
|
|
736
807
|
console.log(`\u{1F4E6} [TRANSLATOR] loadTranslations returned:`, data);
|
|
737
808
|
}
|
|
738
809
|
if (!isTranslationNamespace(data)) {
|
|
739
|
-
throw new Error(
|
|
810
|
+
throw new Error(
|
|
811
|
+
`Invalid translation data for ${language}:${namespace}`
|
|
812
|
+
);
|
|
740
813
|
}
|
|
741
814
|
return data;
|
|
742
815
|
};
|
|
@@ -749,7 +822,10 @@ var Translator = class {
|
|
|
749
822
|
language,
|
|
750
823
|
namespace
|
|
751
824
|
);
|
|
752
|
-
return this.retryOperation(loadOperation, translationError, {
|
|
825
|
+
return this.retryOperation(loadOperation, translationError, {
|
|
826
|
+
language,
|
|
827
|
+
namespace
|
|
828
|
+
});
|
|
753
829
|
}
|
|
754
830
|
}
|
|
755
831
|
/**
|
|
@@ -786,35 +862,30 @@ var Translator = class {
|
|
|
786
862
|
if (!this.isInitialized) {
|
|
787
863
|
await this.initialize();
|
|
788
864
|
}
|
|
789
|
-
|
|
790
|
-
if (!params) {
|
|
791
|
-
return translated;
|
|
792
|
-
}
|
|
793
|
-
return this.interpolate(translated, params);
|
|
865
|
+
return this.translate(key, params);
|
|
794
866
|
}
|
|
795
867
|
/**
|
|
796
868
|
* 동기 번역 (고급 기능)
|
|
797
869
|
*/
|
|
798
870
|
translateSync(key, params) {
|
|
799
871
|
if (!this.isInitialized) {
|
|
872
|
+
if (params && typeof params === "object" && "defaultValue" in params && typeof params.defaultValue === "string") {
|
|
873
|
+
return this.interpolate(params.defaultValue, params);
|
|
874
|
+
}
|
|
800
875
|
if (this.config.debug) {
|
|
801
876
|
console.warn("Translator not initialized for sync translation");
|
|
802
877
|
}
|
|
803
878
|
const { namespace } = this.parseKey(key);
|
|
804
879
|
return this.config.missingKeyHandler?.(key, this.currentLang, namespace) || key;
|
|
805
880
|
}
|
|
806
|
-
|
|
807
|
-
if (!params) {
|
|
808
|
-
return translated;
|
|
809
|
-
}
|
|
810
|
-
return this.interpolate(translated, params);
|
|
881
|
+
return this.translate(key, params);
|
|
811
882
|
}
|
|
812
883
|
/**
|
|
813
884
|
* 키 파싱 (네임스페이스:키 형식)
|
|
814
|
-
*
|
|
885
|
+
*
|
|
815
886
|
* - 콜론(:)만 네임스페이스 구분자로 사용
|
|
816
887
|
* - 점(.)은 키 이름의 일부로 취급 (중첩 객체 접근용)
|
|
817
|
-
*
|
|
888
|
+
*
|
|
818
889
|
* @example
|
|
819
890
|
* parseKey("home:hero.badge") → { namespace: "home", key: "hero.badge" }
|
|
820
891
|
* parseKey("hero.badge") → { namespace: "common", key: "hero.badge" }
|
|
@@ -823,7 +894,10 @@ var Translator = class {
|
|
|
823
894
|
parseKey(key) {
|
|
824
895
|
const colonIndex = key.indexOf(":");
|
|
825
896
|
if (colonIndex !== -1) {
|
|
826
|
-
return {
|
|
897
|
+
return {
|
|
898
|
+
namespace: key.substring(0, colonIndex),
|
|
899
|
+
key: key.substring(colonIndex + 1)
|
|
900
|
+
};
|
|
827
901
|
}
|
|
828
902
|
return { namespace: "common", key };
|
|
829
903
|
}
|
|
@@ -862,7 +936,9 @@ var Translator = class {
|
|
|
862
936
|
this.loadedNamespaces.add(cacheKey);
|
|
863
937
|
this.setCacheEntry(cacheKey, data);
|
|
864
938
|
if (this.config.debug) {
|
|
865
|
-
console.log(
|
|
939
|
+
console.log(
|
|
940
|
+
`\u2705 [TRANSLATOR] Auto-loaded and saved ${language}/${namespace}`
|
|
941
|
+
);
|
|
866
942
|
}
|
|
867
943
|
this.notifyTranslationLoaded(language, namespace);
|
|
868
944
|
return data;
|
|
@@ -880,7 +956,9 @@ var Translator = class {
|
|
|
880
956
|
try {
|
|
881
957
|
const data = await this.config.loadTranslations(language, namespace);
|
|
882
958
|
if (!isTranslationNamespace(data)) {
|
|
883
|
-
throw new Error(
|
|
959
|
+
throw new Error(
|
|
960
|
+
`Invalid translation data for ${language}:${namespace}`
|
|
961
|
+
);
|
|
884
962
|
}
|
|
885
963
|
return data;
|
|
886
964
|
} catch (error) {
|
|
@@ -903,12 +981,20 @@ function ssrTranslate({
|
|
|
903
981
|
missingKeyHandler = (key2) => key2
|
|
904
982
|
}) {
|
|
905
983
|
const { namespace, key: actualKey } = parseKey(key);
|
|
906
|
-
let result = ssrFindInNamespace(
|
|
984
|
+
let result = ssrFindInNamespace(
|
|
985
|
+
translations,
|
|
986
|
+
namespace,
|
|
987
|
+
actualKey,
|
|
988
|
+
language);
|
|
907
989
|
if (result) {
|
|
908
990
|
return result;
|
|
909
991
|
}
|
|
910
992
|
if (language !== fallbackLanguage) {
|
|
911
|
-
result = ssrFindInNamespace(
|
|
993
|
+
result = ssrFindInNamespace(
|
|
994
|
+
translations,
|
|
995
|
+
namespace,
|
|
996
|
+
actualKey,
|
|
997
|
+
fallbackLanguage);
|
|
912
998
|
if (result) {
|
|
913
999
|
return result;
|
|
914
1000
|
}
|
|
@@ -947,7 +1033,10 @@ function isStringValue(value) {
|
|
|
947
1033
|
function parseKey(key) {
|
|
948
1034
|
const colonIndex = key.indexOf(":");
|
|
949
1035
|
if (colonIndex !== -1) {
|
|
950
|
-
return {
|
|
1036
|
+
return {
|
|
1037
|
+
namespace: key.substring(0, colonIndex),
|
|
1038
|
+
key: key.substring(colonIndex + 1)
|
|
1039
|
+
};
|
|
951
1040
|
}
|
|
952
1041
|
return { namespace: "common", key };
|
|
953
1042
|
}
|
|
@@ -969,7 +1058,11 @@ function serverTranslate({
|
|
|
969
1058
|
return cached;
|
|
970
1059
|
}
|
|
971
1060
|
}
|
|
972
|
-
const result = findInTranslations(
|
|
1061
|
+
const result = findInTranslations(
|
|
1062
|
+
translations,
|
|
1063
|
+
key,
|
|
1064
|
+
language,
|
|
1065
|
+
fallbackLanguage);
|
|
973
1066
|
if (cache && result) {
|
|
974
1067
|
const cacheKey = `${language}:${key}`;
|
|
975
1068
|
cache.set(cacheKey, result);
|
|
@@ -985,7 +1078,12 @@ function findInTranslations(translations, key, language, fallbackLanguage, missi
|
|
|
985
1078
|
return result;
|
|
986
1079
|
}
|
|
987
1080
|
if (language !== fallbackLanguage) {
|
|
988
|
-
result = findInNamespace(
|
|
1081
|
+
result = findInNamespace(
|
|
1082
|
+
translations,
|
|
1083
|
+
namespace,
|
|
1084
|
+
actualKey,
|
|
1085
|
+
fallbackLanguage
|
|
1086
|
+
);
|
|
989
1087
|
if (result) {
|
|
990
1088
|
return result;
|
|
991
1089
|
}
|
|
@@ -1231,7 +1329,9 @@ function I18nProvider({
|
|
|
1231
1329
|
config,
|
|
1232
1330
|
children
|
|
1233
1331
|
}) {
|
|
1234
|
-
const [currentLanguage, setCurrentLanguageState] = React.useState(
|
|
1332
|
+
const [currentLanguage, setCurrentLanguageState] = React.useState(
|
|
1333
|
+
() => resolveInitialLanguage(config)
|
|
1334
|
+
);
|
|
1235
1335
|
const [isLoading, setIsLoading] = React.useState(true);
|
|
1236
1336
|
const [isInitialized, setIsInitialized] = React.useState(false);
|
|
1237
1337
|
const [error, setError] = React.useState(null);
|
|
@@ -1252,7 +1352,9 @@ function I18nProvider({
|
|
|
1252
1352
|
const translatorLang = translator.getCurrentLanguage();
|
|
1253
1353
|
if (translatorLang !== currentLanguage) {
|
|
1254
1354
|
if (config.debug) {
|
|
1255
|
-
console.log(
|
|
1355
|
+
console.log(
|
|
1356
|
+
`\u{1F504} [USEI18N] Syncing translator language: ${translatorLang} -> ${currentLanguage} (already initialized)`
|
|
1357
|
+
);
|
|
1256
1358
|
}
|
|
1257
1359
|
translator.setLanguage(currentLanguage);
|
|
1258
1360
|
}
|
|
@@ -1277,13 +1379,18 @@ function I18nProvider({
|
|
|
1277
1379
|
await translator.initialize();
|
|
1278
1380
|
setIsInitialized(true);
|
|
1279
1381
|
if (config.debug) {
|
|
1280
|
-
console.log(
|
|
1382
|
+
console.log(
|
|
1383
|
+
"\u2705 [USEI18N] Translator initialization completed successfully"
|
|
1384
|
+
);
|
|
1281
1385
|
}
|
|
1282
1386
|
} catch (err) {
|
|
1283
1387
|
const initError = err;
|
|
1284
1388
|
setError(initError);
|
|
1285
1389
|
if (config.debug) {
|
|
1286
|
-
console.error(
|
|
1390
|
+
console.error(
|
|
1391
|
+
"\u274C [USEI18N] Failed to initialize translator:",
|
|
1392
|
+
initError
|
|
1393
|
+
);
|
|
1287
1394
|
}
|
|
1288
1395
|
setIsInitialized(true);
|
|
1289
1396
|
} finally {
|
|
@@ -1311,7 +1418,9 @@ function I18nProvider({
|
|
|
1311
1418
|
const unsubscribe = translator.onLanguageChanged((newLanguage) => {
|
|
1312
1419
|
if (newLanguage !== currentLanguage) {
|
|
1313
1420
|
if (config.debug) {
|
|
1314
|
-
console.log(
|
|
1421
|
+
console.log(
|
|
1422
|
+
`\u{1F504} [USEI18N] Language changed event: ${currentLanguage} -> ${newLanguage}`
|
|
1423
|
+
);
|
|
1315
1424
|
}
|
|
1316
1425
|
setCurrentLanguageState(newLanguage);
|
|
1317
1426
|
setTranslationVersion((prev) => prev + 1);
|
|
@@ -1333,38 +1442,46 @@ function I18nProvider({
|
|
|
1333
1442
|
}
|
|
1334
1443
|
});
|
|
1335
1444
|
}, [config.autoLanguageSync, config.platformAdapter, currentLanguage]);
|
|
1336
|
-
const setLanguage = React.useCallback(
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
const currentLang = translator.getCurrentLanguage();
|
|
1341
|
-
if (currentLang === language) {
|
|
1342
|
-
if (config.debug) {
|
|
1343
|
-
console.log(`\u23ED\uFE0F [USEI18N] Language unchanged, skipping: ${language}`);
|
|
1445
|
+
const setLanguage = React.useCallback(
|
|
1446
|
+
async (language) => {
|
|
1447
|
+
if (!translator) {
|
|
1448
|
+
return;
|
|
1344
1449
|
}
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1450
|
+
const currentLang = translator.getCurrentLanguage();
|
|
1451
|
+
if (currentLang === language) {
|
|
1452
|
+
if (config.debug) {
|
|
1453
|
+
console.log(`\u23ED\uFE0F [USEI18N] Language unchanged, skipping: ${language}`);
|
|
1454
|
+
}
|
|
1455
|
+
return;
|
|
1350
1456
|
}
|
|
1351
|
-
}
|
|
1352
|
-
setIsLoading(true);
|
|
1353
|
-
try {
|
|
1354
|
-
translator.setLanguage(language);
|
|
1355
|
-
setCurrentLanguageState(language);
|
|
1356
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1357
1457
|
if (config.debug) {
|
|
1358
|
-
|
|
1458
|
+
if (config.debug) {
|
|
1459
|
+
console.log(
|
|
1460
|
+
`\u{1F504} [USEI18N] setLanguage called: ${currentLang} -> ${language}`
|
|
1461
|
+
);
|
|
1462
|
+
}
|
|
1359
1463
|
}
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1464
|
+
setIsLoading(true);
|
|
1465
|
+
try {
|
|
1466
|
+
translator.setLanguage(language);
|
|
1467
|
+
setCurrentLanguageState(language);
|
|
1468
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1469
|
+
if (config.debug) {
|
|
1470
|
+
console.log(`\u2705 [USEI18N] Language changed to ${language}`);
|
|
1471
|
+
}
|
|
1472
|
+
} catch (error2) {
|
|
1473
|
+
if (config.debug) {
|
|
1474
|
+
console.error(
|
|
1475
|
+
`\u274C [USEI18N] Failed to change language to ${language}:`,
|
|
1476
|
+
error2
|
|
1477
|
+
);
|
|
1478
|
+
}
|
|
1479
|
+
} finally {
|
|
1480
|
+
setIsLoading(false);
|
|
1363
1481
|
}
|
|
1364
|
-
}
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
}, [translator, config.debug]);
|
|
1482
|
+
},
|
|
1483
|
+
[translator, config.debug]
|
|
1484
|
+
);
|
|
1368
1485
|
const parseKey2 = React.useCallback((key) => {
|
|
1369
1486
|
const parts = key.split(":");
|
|
1370
1487
|
if (parts.length >= 2) {
|
|
@@ -1372,246 +1489,336 @@ function I18nProvider({
|
|
|
1372
1489
|
}
|
|
1373
1490
|
return { namespace: "common", key };
|
|
1374
1491
|
}, []);
|
|
1375
|
-
const resolveNestedKey = React.useCallback(
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
current
|
|
1384
|
-
|
|
1385
|
-
|
|
1492
|
+
const resolveNestedKey = React.useCallback(
|
|
1493
|
+
(obj, key) => {
|
|
1494
|
+
if (key in obj && typeof obj[key] === "string") {
|
|
1495
|
+
return obj[key];
|
|
1496
|
+
}
|
|
1497
|
+
const parts = key.split(".");
|
|
1498
|
+
let current = obj;
|
|
1499
|
+
for (const part of parts) {
|
|
1500
|
+
if (current && typeof current === "object" && current !== null && part in current) {
|
|
1501
|
+
current = current[part];
|
|
1502
|
+
} else {
|
|
1503
|
+
return null;
|
|
1504
|
+
}
|
|
1386
1505
|
}
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
const ssrTranslations = config.initialTranslations[targetLang]?.[namespace];
|
|
1396
|
-
if (ssrTranslations) {
|
|
1397
|
-
const value2 = resolveNestedKey(ssrTranslations, actualKey);
|
|
1398
|
-
if (value2 !== null) {
|
|
1399
|
-
return value2;
|
|
1506
|
+
return typeof current === "string" ? current : null;
|
|
1507
|
+
},
|
|
1508
|
+
[]
|
|
1509
|
+
);
|
|
1510
|
+
const findInSSRTranslations = React.useCallback(
|
|
1511
|
+
(key, targetLang) => {
|
|
1512
|
+
if (!config.initialTranslations) {
|
|
1513
|
+
return null;
|
|
1400
1514
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1515
|
+
const { namespace, key: actualKey } = parseKey2(key);
|
|
1516
|
+
const ssrTranslations = config.initialTranslations[targetLang]?.[namespace];
|
|
1517
|
+
if (ssrTranslations) {
|
|
1518
|
+
const value2 = resolveNestedKey(
|
|
1519
|
+
ssrTranslations,
|
|
1520
|
+
actualKey
|
|
1521
|
+
);
|
|
1407
1522
|
if (value2 !== null) {
|
|
1408
1523
|
return value2;
|
|
1409
1524
|
}
|
|
1410
1525
|
}
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
}
|
|
1424
|
-
let params;
|
|
1425
|
-
let lang;
|
|
1426
|
-
if (typeof paramsOrLang === "string") {
|
|
1427
|
-
lang = paramsOrLang;
|
|
1428
|
-
} else if (typeof paramsOrLang === "object" && paramsOrLang !== null) {
|
|
1429
|
-
params = paramsOrLang;
|
|
1430
|
-
lang = language;
|
|
1431
|
-
}
|
|
1432
|
-
const targetLang = lang || currentLanguage;
|
|
1433
|
-
try {
|
|
1434
|
-
const result = translator.translate(key, params || lang, params ? lang : void 0);
|
|
1435
|
-
if (result && result !== key && result !== "") {
|
|
1436
|
-
return result;
|
|
1526
|
+
const fallbackLang = config.fallbackLanguage || "en";
|
|
1527
|
+
if (targetLang !== fallbackLang) {
|
|
1528
|
+
const fallbackTranslations = config.initialTranslations[fallbackLang]?.[namespace];
|
|
1529
|
+
if (fallbackTranslations) {
|
|
1530
|
+
const value2 = resolveNestedKey(
|
|
1531
|
+
fallbackTranslations,
|
|
1532
|
+
actualKey
|
|
1533
|
+
);
|
|
1534
|
+
if (value2 !== null) {
|
|
1535
|
+
return value2;
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1437
1538
|
}
|
|
1438
|
-
|
|
1439
|
-
}
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1539
|
+
return null;
|
|
1540
|
+
},
|
|
1541
|
+
[
|
|
1542
|
+
config.initialTranslations,
|
|
1543
|
+
config.fallbackLanguage,
|
|
1544
|
+
parseKey2,
|
|
1545
|
+
resolveNestedKey
|
|
1546
|
+
]
|
|
1547
|
+
);
|
|
1548
|
+
const findInDefaultTranslations = React.useCallback(
|
|
1549
|
+
(key, targetLang) => {
|
|
1550
|
+
const { namespace, key: actualKey } = parseKey2(key);
|
|
1551
|
+
const defaultTranslations = getDefaultTranslations(targetLang, namespace);
|
|
1552
|
+
const fallbackTranslations = getDefaultTranslations(
|
|
1553
|
+
config.fallbackLanguage || "en",
|
|
1554
|
+
namespace
|
|
1555
|
+
);
|
|
1556
|
+
return resolveNestedKey(
|
|
1557
|
+
defaultTranslations,
|
|
1558
|
+
actualKey
|
|
1559
|
+
) || resolveNestedKey(
|
|
1560
|
+
fallbackTranslations,
|
|
1561
|
+
actualKey
|
|
1562
|
+
) || null;
|
|
1563
|
+
},
|
|
1564
|
+
[config.fallbackLanguage, parseKey2, resolveNestedKey]
|
|
1565
|
+
);
|
|
1566
|
+
const t = React.useCallback(
|
|
1567
|
+
(key, paramsOrLang, language) => {
|
|
1568
|
+
if (!translator) {
|
|
1569
|
+
return key;
|
|
1570
|
+
}
|
|
1571
|
+
let params;
|
|
1572
|
+
let lang;
|
|
1573
|
+
if (typeof paramsOrLang === "string") {
|
|
1574
|
+
lang = paramsOrLang;
|
|
1575
|
+
} else if (typeof paramsOrLang === "object" && paramsOrLang !== null) {
|
|
1576
|
+
params = paramsOrLang;
|
|
1577
|
+
lang = language;
|
|
1578
|
+
}
|
|
1579
|
+
const targetLang = lang || currentLanguage;
|
|
1580
|
+
try {
|
|
1581
|
+
const result = translator.translate(
|
|
1582
|
+
key,
|
|
1583
|
+
params || lang,
|
|
1584
|
+
params ? lang : void 0
|
|
1585
|
+
);
|
|
1586
|
+
if (result && result !== key && result !== "") {
|
|
1587
|
+
return result;
|
|
1588
|
+
}
|
|
1589
|
+
} catch (error2) {
|
|
1464
1590
|
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1591
|
+
const interpolate = (text) => {
|
|
1592
|
+
if (!params) return text;
|
|
1593
|
+
return text.replace(/\{\{(\w+)\}\}/g, (match, k) => {
|
|
1594
|
+
const value2 = params[k];
|
|
1595
|
+
return value2 !== void 0 ? String(value2) : match;
|
|
1596
|
+
});
|
|
1597
|
+
};
|
|
1598
|
+
const ssrResult = findInSSRTranslations(key, targetLang);
|
|
1599
|
+
if (ssrResult) {
|
|
1600
|
+
return interpolate(ssrResult);
|
|
1474
1601
|
}
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
}
|
|
1479
|
-
}, [translator, config.debug]);
|
|
1480
|
-
const tSync = React.useCallback((key, namespace, params) => {
|
|
1481
|
-
if (!translator) {
|
|
1482
|
-
if (config.debug) {
|
|
1483
|
-
console.warn("Translator not initialized");
|
|
1602
|
+
const defaultResult = findInDefaultTranslations(key, targetLang);
|
|
1603
|
+
if (defaultResult) {
|
|
1604
|
+
return interpolate(defaultResult);
|
|
1484
1605
|
}
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
return translator.translateSync(key, params);
|
|
1488
|
-
}, [translator, config.debug]);
|
|
1489
|
-
const getRawValue = React.useCallback((key, language) => {
|
|
1490
|
-
if (!translator || !isInitialized) {
|
|
1491
|
-
return void 0;
|
|
1492
|
-
}
|
|
1493
|
-
return translator.getRawValue(key, language);
|
|
1494
|
-
}, [translator, isInitialized]);
|
|
1495
|
-
const tArray = React.useCallback((key, language) => {
|
|
1496
|
-
if (!translator || !isInitialized) {
|
|
1497
|
-
return [];
|
|
1498
|
-
}
|
|
1499
|
-
return translator.tArray(key, language);
|
|
1500
|
-
}, [translator, isInitialized, translationVersion, currentLanguage]);
|
|
1501
|
-
const tPlural = React.useCallback((key, count, params, language) => {
|
|
1502
|
-
if (!translator || !isInitialized) {
|
|
1503
|
-
return key;
|
|
1504
|
-
}
|
|
1505
|
-
return translator.tPlural(key, count, params, language);
|
|
1506
|
-
}, [translator, isInitialized, translationVersion, currentLanguage]);
|
|
1507
|
-
const debug = React.useMemo(() => ({
|
|
1508
|
-
getCurrentLanguage: () => {
|
|
1509
|
-
try {
|
|
1510
|
-
return translator?.getCurrentLanguage() || currentLanguage;
|
|
1511
|
-
} catch {
|
|
1512
|
-
return currentLanguage;
|
|
1606
|
+
if (typeof paramsOrLang === "object" && paramsOrLang !== null && "defaultValue" in paramsOrLang && typeof paramsOrLang.defaultValue === "string") {
|
|
1607
|
+
return interpolate(paramsOrLang.defaultValue);
|
|
1513
1608
|
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
try {
|
|
1517
|
-
return translator?.getSupportedLanguages() || config.supportedLanguages?.map((l) => l.code) || [];
|
|
1518
|
-
} catch {
|
|
1519
|
-
return config.supportedLanguages?.map((l) => l.code) || [];
|
|
1609
|
+
if (config.debug) {
|
|
1610
|
+
return interpolate(key);
|
|
1520
1611
|
}
|
|
1612
|
+
return "";
|
|
1521
1613
|
},
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
return Array.from(namespaces);
|
|
1614
|
+
[
|
|
1615
|
+
translator,
|
|
1616
|
+
config.debug,
|
|
1617
|
+
currentLanguage,
|
|
1618
|
+
config.fallbackLanguage,
|
|
1619
|
+
translationVersion,
|
|
1620
|
+
findInSSRTranslations,
|
|
1621
|
+
findInDefaultTranslations
|
|
1622
|
+
]
|
|
1623
|
+
);
|
|
1624
|
+
const tAsync = React.useCallback(
|
|
1625
|
+
async (key, params) => {
|
|
1626
|
+
if (!translator) {
|
|
1627
|
+
if (config.debug) {
|
|
1628
|
+
console.warn("Translator not initialized");
|
|
1538
1629
|
}
|
|
1539
|
-
return
|
|
1540
|
-
} catch (error2) {
|
|
1541
|
-
return [];
|
|
1630
|
+
return key;
|
|
1542
1631
|
}
|
|
1543
|
-
|
|
1544
|
-
getAllTranslations: () => {
|
|
1632
|
+
setIsLoading(true);
|
|
1545
1633
|
try {
|
|
1546
|
-
|
|
1634
|
+
const result = await translator.translateAsync(key, params);
|
|
1635
|
+
return result;
|
|
1547
1636
|
} catch (error2) {
|
|
1548
|
-
|
|
1637
|
+
if (config.debug) {
|
|
1638
|
+
console.error("Translation error:", error2);
|
|
1639
|
+
}
|
|
1640
|
+
return key;
|
|
1641
|
+
} finally {
|
|
1642
|
+
setIsLoading(false);
|
|
1549
1643
|
}
|
|
1550
1644
|
},
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1645
|
+
[translator, config.debug]
|
|
1646
|
+
);
|
|
1647
|
+
const tSync = React.useCallback(
|
|
1648
|
+
(key, namespace, params) => {
|
|
1649
|
+
if (!translator) {
|
|
1650
|
+
if (config.debug) {
|
|
1651
|
+
console.warn("Translator not initialized");
|
|
1652
|
+
}
|
|
1653
|
+
return key;
|
|
1556
1654
|
}
|
|
1655
|
+
return translator.translateSync(key, params);
|
|
1557
1656
|
},
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1657
|
+
[translator, config.debug]
|
|
1658
|
+
);
|
|
1659
|
+
const getRawValue = React.useCallback(
|
|
1660
|
+
(key, language) => {
|
|
1661
|
+
if (!translator || !isInitialized) {
|
|
1662
|
+
return void 0;
|
|
1663
|
+
}
|
|
1664
|
+
return translator.getRawValue(key, language);
|
|
1564
1665
|
},
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1666
|
+
[translator, isInitialized]
|
|
1667
|
+
);
|
|
1668
|
+
const tArray = React.useCallback(
|
|
1669
|
+
(key, language) => {
|
|
1670
|
+
if (!translator || !isInitialized) {
|
|
1671
|
+
return [];
|
|
1569
1672
|
}
|
|
1673
|
+
return translator.tArray(key, language);
|
|
1570
1674
|
},
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
};
|
|
1580
|
-
}
|
|
1581
|
-
return { size: 0, hits: 0, misses: 0 };
|
|
1582
|
-
} catch (error2) {
|
|
1583
|
-
return { size: 0, hits: 0, misses: 0 };
|
|
1584
|
-
}
|
|
1675
|
+
[translator, isInitialized, translationVersion, currentLanguage]
|
|
1676
|
+
);
|
|
1677
|
+
const tPlural = React.useCallback(
|
|
1678
|
+
(key, count, params, language) => {
|
|
1679
|
+
if (!translator || !isInitialized) {
|
|
1680
|
+
return key;
|
|
1681
|
+
}
|
|
1682
|
+
return translator.tPlural(key, count, params, language);
|
|
1585
1683
|
},
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1684
|
+
[translator, isInitialized, translationVersion, currentLanguage]
|
|
1685
|
+
);
|
|
1686
|
+
const debug = React.useMemo(
|
|
1687
|
+
() => ({
|
|
1688
|
+
getCurrentLanguage: () => {
|
|
1689
|
+
try {
|
|
1690
|
+
return translator?.getCurrentLanguage() || currentLanguage;
|
|
1691
|
+
} catch {
|
|
1692
|
+
return currentLanguage;
|
|
1693
|
+
}
|
|
1694
|
+
},
|
|
1695
|
+
getSupportedLanguages: () => {
|
|
1696
|
+
try {
|
|
1697
|
+
return translator?.getSupportedLanguages() || config.supportedLanguages?.map((l) => l.code) || [];
|
|
1698
|
+
} catch {
|
|
1699
|
+
return config.supportedLanguages?.map((l) => l.code) || [];
|
|
1700
|
+
}
|
|
1701
|
+
},
|
|
1702
|
+
getLoadedNamespaces: () => {
|
|
1703
|
+
try {
|
|
1704
|
+
const debugInfo = translator?.debug();
|
|
1705
|
+
if (debugInfo && debugInfo.loadedNamespaces) {
|
|
1706
|
+
return Array.from(debugInfo.loadedNamespaces);
|
|
1707
|
+
}
|
|
1708
|
+
if (debugInfo && debugInfo.allTranslations) {
|
|
1709
|
+
const namespaces = /* @__PURE__ */ new Set();
|
|
1710
|
+
Object.values(debugInfo.allTranslations).forEach(
|
|
1711
|
+
(langData) => {
|
|
1712
|
+
if (langData && typeof langData === "object") {
|
|
1713
|
+
Object.keys(langData).forEach((namespace) => {
|
|
1714
|
+
namespaces.add(namespace);
|
|
1715
|
+
});
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
);
|
|
1719
|
+
return Array.from(namespaces);
|
|
1720
|
+
}
|
|
1721
|
+
return [];
|
|
1722
|
+
} catch (error2) {
|
|
1723
|
+
return [];
|
|
1724
|
+
}
|
|
1725
|
+
},
|
|
1726
|
+
getAllTranslations: () => {
|
|
1727
|
+
try {
|
|
1728
|
+
return translator?.debug()?.allTranslations || {};
|
|
1729
|
+
} catch (error2) {
|
|
1730
|
+
return {};
|
|
1731
|
+
}
|
|
1732
|
+
},
|
|
1733
|
+
isReady: () => {
|
|
1734
|
+
try {
|
|
1735
|
+
return translator?.isReady() || isInitialized;
|
|
1736
|
+
} catch {
|
|
1737
|
+
return isInitialized;
|
|
1738
|
+
}
|
|
1739
|
+
},
|
|
1740
|
+
getInitializationError: () => {
|
|
1741
|
+
try {
|
|
1742
|
+
return translator?.getInitializationError() || error;
|
|
1743
|
+
} catch {
|
|
1744
|
+
return error;
|
|
1745
|
+
}
|
|
1746
|
+
},
|
|
1747
|
+
clearCache: () => {
|
|
1590
1748
|
try {
|
|
1591
|
-
|
|
1592
|
-
} catch
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1749
|
+
translator?.clearCache();
|
|
1750
|
+
} catch {
|
|
1751
|
+
}
|
|
1752
|
+
},
|
|
1753
|
+
getCacheStats: () => {
|
|
1754
|
+
try {
|
|
1755
|
+
const debugInfo = translator?.debug();
|
|
1756
|
+
if (debugInfo && debugInfo.cacheStats) {
|
|
1757
|
+
return {
|
|
1758
|
+
size: debugInfo.cacheSize || 0,
|
|
1759
|
+
hits: debugInfo.cacheStats.hits || 0,
|
|
1760
|
+
misses: debugInfo.cacheStats.misses || 0
|
|
1761
|
+
};
|
|
1762
|
+
}
|
|
1763
|
+
return { size: 0, hits: 0, misses: 0 };
|
|
1764
|
+
} catch (error2) {
|
|
1765
|
+
return { size: 0, hits: 0, misses: 0 };
|
|
1766
|
+
}
|
|
1767
|
+
},
|
|
1768
|
+
reloadTranslations: async () => {
|
|
1769
|
+
if (translator) {
|
|
1770
|
+
setIsLoading(true);
|
|
1771
|
+
setError(null);
|
|
1772
|
+
try {
|
|
1773
|
+
await translator.initialize();
|
|
1774
|
+
} catch (err) {
|
|
1775
|
+
setError(err);
|
|
1776
|
+
} finally {
|
|
1777
|
+
setIsLoading(false);
|
|
1778
|
+
}
|
|
1596
1779
|
}
|
|
1597
1780
|
}
|
|
1598
|
-
}
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1781
|
+
}),
|
|
1782
|
+
[
|
|
1783
|
+
translator,
|
|
1784
|
+
currentLanguage,
|
|
1785
|
+
error,
|
|
1786
|
+
isInitialized,
|
|
1787
|
+
config.supportedLanguages
|
|
1788
|
+
]
|
|
1789
|
+
);
|
|
1790
|
+
const value = React.useMemo(
|
|
1791
|
+
() => ({
|
|
1792
|
+
currentLanguage,
|
|
1793
|
+
setLanguage,
|
|
1794
|
+
t,
|
|
1795
|
+
tPlural,
|
|
1796
|
+
tArray,
|
|
1797
|
+
tAsync,
|
|
1798
|
+
tSync,
|
|
1799
|
+
getRawValue,
|
|
1800
|
+
isLoading,
|
|
1801
|
+
error,
|
|
1802
|
+
supportedLanguages: config.supportedLanguages,
|
|
1803
|
+
debug,
|
|
1804
|
+
isInitialized
|
|
1805
|
+
}),
|
|
1806
|
+
[
|
|
1807
|
+
currentLanguage,
|
|
1808
|
+
setLanguage,
|
|
1809
|
+
t,
|
|
1810
|
+
tPlural,
|
|
1811
|
+
tArray,
|
|
1812
|
+
tAsync,
|
|
1813
|
+
tSync,
|
|
1814
|
+
getRawValue,
|
|
1815
|
+
isLoading,
|
|
1816
|
+
error,
|
|
1817
|
+
config.supportedLanguages,
|
|
1818
|
+
debug,
|
|
1819
|
+
isInitialized
|
|
1820
|
+
]
|
|
1821
|
+
);
|
|
1615
1822
|
return /* @__PURE__ */ jsxRuntime.jsx(I18nContext.Provider, { value, children });
|
|
1616
1823
|
}
|
|
1617
1824
|
function useI18n() {
|
|
@@ -1621,7 +1828,12 @@ function useI18n() {
|
|
|
1621
1828
|
currentLanguage: "ko",
|
|
1622
1829
|
setLanguage: () => {
|
|
1623
1830
|
},
|
|
1624
|
-
t: (key) =>
|
|
1831
|
+
t: (key, paramsOrLang) => {
|
|
1832
|
+
if (typeof paramsOrLang === "object" && paramsOrLang !== null && "defaultValue" in paramsOrLang && typeof paramsOrLang.defaultValue === "string") {
|
|
1833
|
+
return paramsOrLang.defaultValue;
|
|
1834
|
+
}
|
|
1835
|
+
return key;
|
|
1836
|
+
},
|
|
1625
1837
|
tPlural: (key) => key,
|
|
1626
1838
|
tAsync: async (key) => key,
|
|
1627
1839
|
tSync: (key) => key,
|