@hua-labs/i18n-core 2.1.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 +9 -3
- package/dist/chunk-4IYWT7MS.mjs +1104 -0
- package/dist/chunk-4IYWT7MS.mjs.map +1 -0
- package/dist/index.cjs +2086 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +22 -22
- package/dist/index.d.ts +249 -0
- package/dist/index.mjs +373 -264
- package/dist/index.mjs.map +1 -1
- package/dist/{server-4TeBq6hp.d.mts → server-CQztOmd-.d.mts} +48 -11
- package/dist/server-CQztOmd-.d.ts +404 -0
- package/dist/{chunk-EZL5TNH5.mjs → server.cjs} +148 -46
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.mjs +1 -1
- package/package.json +16 -13
- package/src/__tests__/default-value.test.ts +149 -0
- package/src/components/MissingKeyOverlay.tsx +6 -4
- package/src/core/translator.tsx +392 -195
- package/src/hooks/useI18n.tsx +511 -367
- package/src/index.ts +5 -2
- package/src/types/index.ts +341 -156
- package/dist/chunk-EZL5TNH5.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { validateI18nConfig, Translator } from './chunk-
|
|
2
|
-
export { Translator, serverTranslate, ssrTranslate } from './chunk-
|
|
1
|
+
import { validateI18nConfig, webPlatformAdapter, Translator } from './chunk-4IYWT7MS.mjs';
|
|
2
|
+
export { Translator, headlessPlatformAdapter, serverTranslate, ssrTranslate, webPlatformAdapter } from './chunk-4IYWT7MS.mjs';
|
|
3
3
|
import React, { createContext, useState, useEffect, useMemo, useCallback, useContext } from 'react';
|
|
4
4
|
import { jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -208,11 +208,12 @@ function resolveInitialLanguage(config) {
|
|
|
208
208
|
if (config.defaultLanguage) {
|
|
209
209
|
return config.defaultLanguage;
|
|
210
210
|
}
|
|
211
|
-
|
|
212
|
-
|
|
211
|
+
const adapter = config.platformAdapter ?? webPlatformAdapter;
|
|
212
|
+
const deviceLang = adapter.getDeviceLanguage();
|
|
213
|
+
if (deviceLang) {
|
|
213
214
|
const supportedCodes = config.supportedLanguages?.map((l) => l.code) ?? [];
|
|
214
|
-
if (supportedCodes.includes(
|
|
215
|
-
return
|
|
215
|
+
if (supportedCodes.includes(deviceLang)) {
|
|
216
|
+
return deviceLang;
|
|
216
217
|
}
|
|
217
218
|
}
|
|
218
219
|
return config.supportedLanguages?.[0]?.code ?? "ko";
|
|
@@ -221,7 +222,9 @@ function I18nProvider({
|
|
|
221
222
|
config,
|
|
222
223
|
children
|
|
223
224
|
}) {
|
|
224
|
-
const [currentLanguage, setCurrentLanguageState] = useState(
|
|
225
|
+
const [currentLanguage, setCurrentLanguageState] = useState(
|
|
226
|
+
() => resolveInitialLanguage(config)
|
|
227
|
+
);
|
|
225
228
|
const [isLoading, setIsLoading] = useState(true);
|
|
226
229
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
227
230
|
const [error, setError] = useState(null);
|
|
@@ -242,7 +245,9 @@ function I18nProvider({
|
|
|
242
245
|
const translatorLang = translator.getCurrentLanguage();
|
|
243
246
|
if (translatorLang !== currentLanguage) {
|
|
244
247
|
if (config.debug) {
|
|
245
|
-
console.log(
|
|
248
|
+
console.log(
|
|
249
|
+
`\u{1F504} [USEI18N] Syncing translator language: ${translatorLang} -> ${currentLanguage} (already initialized)`
|
|
250
|
+
);
|
|
246
251
|
}
|
|
247
252
|
translator.setLanguage(currentLanguage);
|
|
248
253
|
}
|
|
@@ -267,13 +272,18 @@ function I18nProvider({
|
|
|
267
272
|
await translator.initialize();
|
|
268
273
|
setIsInitialized(true);
|
|
269
274
|
if (config.debug) {
|
|
270
|
-
console.log(
|
|
275
|
+
console.log(
|
|
276
|
+
"\u2705 [USEI18N] Translator initialization completed successfully"
|
|
277
|
+
);
|
|
271
278
|
}
|
|
272
279
|
} catch (err) {
|
|
273
280
|
const initError = err;
|
|
274
281
|
setError(initError);
|
|
275
282
|
if (config.debug) {
|
|
276
|
-
console.error(
|
|
283
|
+
console.error(
|
|
284
|
+
"\u274C [USEI18N] Failed to initialize translator:",
|
|
285
|
+
initError
|
|
286
|
+
);
|
|
277
287
|
}
|
|
278
288
|
setIsInitialized(true);
|
|
279
289
|
} finally {
|
|
@@ -301,7 +311,9 @@ function I18nProvider({
|
|
|
301
311
|
const unsubscribe = translator.onLanguageChanged((newLanguage) => {
|
|
302
312
|
if (newLanguage !== currentLanguage) {
|
|
303
313
|
if (config.debug) {
|
|
304
|
-
console.log(
|
|
314
|
+
console.log(
|
|
315
|
+
`\u{1F504} [USEI18N] Language changed event: ${currentLanguage} -> ${newLanguage}`
|
|
316
|
+
);
|
|
305
317
|
}
|
|
306
318
|
setCurrentLanguageState(newLanguage);
|
|
307
319
|
setTranslationVersion((prev) => prev + 1);
|
|
@@ -310,57 +322,59 @@ function I18nProvider({
|
|
|
310
322
|
return unsubscribe;
|
|
311
323
|
}, [translator, isInitialized, currentLanguage, config.debug]);
|
|
312
324
|
useEffect(() => {
|
|
313
|
-
if (!config.autoLanguageSync
|
|
325
|
+
if (!config.autoLanguageSync) {
|
|
314
326
|
return;
|
|
315
327
|
}
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
if (
|
|
328
|
+
const adapter = config.platformAdapter ?? webPlatformAdapter;
|
|
329
|
+
return adapter.onLanguageChange((newLanguage) => {
|
|
330
|
+
if (newLanguage !== currentLanguage) {
|
|
319
331
|
if (config.debug) {
|
|
320
332
|
console.log("\u{1F310} Auto language sync:", newLanguage);
|
|
321
333
|
}
|
|
322
334
|
setLanguage(newLanguage);
|
|
323
335
|
}
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
if (currentLang === language) {
|
|
338
|
-
if (config.debug) {
|
|
339
|
-
console.log(`\u23ED\uFE0F [USEI18N] Language unchanged, skipping: ${language}`);
|
|
340
|
-
}
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
if (config.debug) {
|
|
344
|
-
if (config.debug) {
|
|
345
|
-
console.log(`\u{1F504} [USEI18N] setLanguage called: ${currentLang} -> ${language}`);
|
|
336
|
+
});
|
|
337
|
+
}, [config.autoLanguageSync, config.platformAdapter, currentLanguage]);
|
|
338
|
+
const setLanguage = useCallback(
|
|
339
|
+
async (language) => {
|
|
340
|
+
if (!translator) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
const currentLang = translator.getCurrentLanguage();
|
|
344
|
+
if (currentLang === language) {
|
|
345
|
+
if (config.debug) {
|
|
346
|
+
console.log(`\u23ED\uFE0F [USEI18N] Language unchanged, skipping: ${language}`);
|
|
347
|
+
}
|
|
348
|
+
return;
|
|
346
349
|
}
|
|
347
|
-
}
|
|
348
|
-
setIsLoading(true);
|
|
349
|
-
try {
|
|
350
|
-
translator.setLanguage(language);
|
|
351
|
-
setCurrentLanguageState(language);
|
|
352
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
353
350
|
if (config.debug) {
|
|
354
|
-
|
|
351
|
+
if (config.debug) {
|
|
352
|
+
console.log(
|
|
353
|
+
`\u{1F504} [USEI18N] setLanguage called: ${currentLang} -> ${language}`
|
|
354
|
+
);
|
|
355
|
+
}
|
|
355
356
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
357
|
+
setIsLoading(true);
|
|
358
|
+
try {
|
|
359
|
+
translator.setLanguage(language);
|
|
360
|
+
setCurrentLanguageState(language);
|
|
361
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
362
|
+
if (config.debug) {
|
|
363
|
+
console.log(`\u2705 [USEI18N] Language changed to ${language}`);
|
|
364
|
+
}
|
|
365
|
+
} catch (error2) {
|
|
366
|
+
if (config.debug) {
|
|
367
|
+
console.error(
|
|
368
|
+
`\u274C [USEI18N] Failed to change language to ${language}:`,
|
|
369
|
+
error2
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
} finally {
|
|
373
|
+
setIsLoading(false);
|
|
359
374
|
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}, [translator, config.debug]);
|
|
375
|
+
},
|
|
376
|
+
[translator, config.debug]
|
|
377
|
+
);
|
|
364
378
|
const parseKey = useCallback((key) => {
|
|
365
379
|
const parts = key.split(":");
|
|
366
380
|
if (parts.length >= 2) {
|
|
@@ -368,246 +382,336 @@ function I18nProvider({
|
|
|
368
382
|
}
|
|
369
383
|
return { namespace: "common", key };
|
|
370
384
|
}, []);
|
|
371
|
-
const resolveNestedKey = useCallback(
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
current
|
|
380
|
-
|
|
381
|
-
|
|
385
|
+
const resolveNestedKey = useCallback(
|
|
386
|
+
(obj, key) => {
|
|
387
|
+
if (key in obj && typeof obj[key] === "string") {
|
|
388
|
+
return obj[key];
|
|
389
|
+
}
|
|
390
|
+
const parts = key.split(".");
|
|
391
|
+
let current = obj;
|
|
392
|
+
for (const part of parts) {
|
|
393
|
+
if (current && typeof current === "object" && current !== null && part in current) {
|
|
394
|
+
current = current[part];
|
|
395
|
+
} else {
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
382
398
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
const ssrTranslations = config.initialTranslations[targetLang]?.[namespace];
|
|
392
|
-
if (ssrTranslations) {
|
|
393
|
-
const value2 = resolveNestedKey(ssrTranslations, actualKey);
|
|
394
|
-
if (value2 !== null) {
|
|
395
|
-
return value2;
|
|
399
|
+
return typeof current === "string" ? current : null;
|
|
400
|
+
},
|
|
401
|
+
[]
|
|
402
|
+
);
|
|
403
|
+
const findInSSRTranslations = useCallback(
|
|
404
|
+
(key, targetLang) => {
|
|
405
|
+
if (!config.initialTranslations) {
|
|
406
|
+
return null;
|
|
396
407
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
408
|
+
const { namespace, key: actualKey } = parseKey(key);
|
|
409
|
+
const ssrTranslations = config.initialTranslations[targetLang]?.[namespace];
|
|
410
|
+
if (ssrTranslations) {
|
|
411
|
+
const value2 = resolveNestedKey(
|
|
412
|
+
ssrTranslations,
|
|
413
|
+
actualKey
|
|
414
|
+
);
|
|
403
415
|
if (value2 !== null) {
|
|
404
416
|
return value2;
|
|
405
417
|
}
|
|
406
418
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
}
|
|
420
|
-
let params;
|
|
421
|
-
let lang;
|
|
422
|
-
if (typeof paramsOrLang === "string") {
|
|
423
|
-
lang = paramsOrLang;
|
|
424
|
-
} else if (typeof paramsOrLang === "object" && paramsOrLang !== null) {
|
|
425
|
-
params = paramsOrLang;
|
|
426
|
-
lang = language;
|
|
427
|
-
}
|
|
428
|
-
const targetLang = lang || currentLanguage;
|
|
429
|
-
try {
|
|
430
|
-
const result = translator.translate(key, params || lang, params ? lang : void 0);
|
|
431
|
-
if (result && result !== key && result !== "") {
|
|
432
|
-
return result;
|
|
419
|
+
const fallbackLang = config.fallbackLanguage || "en";
|
|
420
|
+
if (targetLang !== fallbackLang) {
|
|
421
|
+
const fallbackTranslations = config.initialTranslations[fallbackLang]?.[namespace];
|
|
422
|
+
if (fallbackTranslations) {
|
|
423
|
+
const value2 = resolveNestedKey(
|
|
424
|
+
fallbackTranslations,
|
|
425
|
+
actualKey
|
|
426
|
+
);
|
|
427
|
+
if (value2 !== null) {
|
|
428
|
+
return value2;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
433
431
|
}
|
|
434
|
-
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
432
|
+
return null;
|
|
433
|
+
},
|
|
434
|
+
[
|
|
435
|
+
config.initialTranslations,
|
|
436
|
+
config.fallbackLanguage,
|
|
437
|
+
parseKey,
|
|
438
|
+
resolveNestedKey
|
|
439
|
+
]
|
|
440
|
+
);
|
|
441
|
+
const findInDefaultTranslations = useCallback(
|
|
442
|
+
(key, targetLang) => {
|
|
443
|
+
const { namespace, key: actualKey } = parseKey(key);
|
|
444
|
+
const defaultTranslations = getDefaultTranslations(targetLang, namespace);
|
|
445
|
+
const fallbackTranslations = getDefaultTranslations(
|
|
446
|
+
config.fallbackLanguage || "en",
|
|
447
|
+
namespace
|
|
448
|
+
);
|
|
449
|
+
return resolveNestedKey(
|
|
450
|
+
defaultTranslations,
|
|
451
|
+
actualKey
|
|
452
|
+
) || resolveNestedKey(
|
|
453
|
+
fallbackTranslations,
|
|
454
|
+
actualKey
|
|
455
|
+
) || null;
|
|
456
|
+
},
|
|
457
|
+
[config.fallbackLanguage, parseKey, resolveNestedKey]
|
|
458
|
+
);
|
|
459
|
+
const t = useCallback(
|
|
460
|
+
(key, paramsOrLang, language) => {
|
|
461
|
+
if (!translator) {
|
|
462
|
+
return key;
|
|
463
|
+
}
|
|
464
|
+
let params;
|
|
465
|
+
let lang;
|
|
466
|
+
if (typeof paramsOrLang === "string") {
|
|
467
|
+
lang = paramsOrLang;
|
|
468
|
+
} else if (typeof paramsOrLang === "object" && paramsOrLang !== null) {
|
|
469
|
+
params = paramsOrLang;
|
|
470
|
+
lang = language;
|
|
471
|
+
}
|
|
472
|
+
const targetLang = lang || currentLanguage;
|
|
473
|
+
try {
|
|
474
|
+
const result = translator.translate(
|
|
475
|
+
key,
|
|
476
|
+
params || lang,
|
|
477
|
+
params ? lang : void 0
|
|
478
|
+
);
|
|
479
|
+
if (result && result !== key && result !== "") {
|
|
480
|
+
return result;
|
|
481
|
+
}
|
|
482
|
+
} catch (error2) {
|
|
460
483
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
484
|
+
const interpolate = (text) => {
|
|
485
|
+
if (!params) return text;
|
|
486
|
+
return text.replace(/\{\{(\w+)\}\}/g, (match, k) => {
|
|
487
|
+
const value2 = params[k];
|
|
488
|
+
return value2 !== void 0 ? String(value2) : match;
|
|
489
|
+
});
|
|
490
|
+
};
|
|
491
|
+
const ssrResult = findInSSRTranslations(key, targetLang);
|
|
492
|
+
if (ssrResult) {
|
|
493
|
+
return interpolate(ssrResult);
|
|
470
494
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
}, [translator, config.debug]);
|
|
476
|
-
const tSync = useCallback((key, namespace, params) => {
|
|
477
|
-
if (!translator) {
|
|
478
|
-
if (config.debug) {
|
|
479
|
-
console.warn("Translator not initialized");
|
|
495
|
+
const defaultResult = findInDefaultTranslations(key, targetLang);
|
|
496
|
+
if (defaultResult) {
|
|
497
|
+
return interpolate(defaultResult);
|
|
480
498
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
return translator.translateSync(key, params);
|
|
484
|
-
}, [translator, config.debug]);
|
|
485
|
-
const getRawValue = useCallback((key, language) => {
|
|
486
|
-
if (!translator || !isInitialized) {
|
|
487
|
-
return void 0;
|
|
488
|
-
}
|
|
489
|
-
return translator.getRawValue(key, language);
|
|
490
|
-
}, [translator, isInitialized]);
|
|
491
|
-
const tArray = useCallback((key, language) => {
|
|
492
|
-
if (!translator || !isInitialized) {
|
|
493
|
-
return [];
|
|
494
|
-
}
|
|
495
|
-
return translator.tArray(key, language);
|
|
496
|
-
}, [translator, isInitialized, translationVersion, currentLanguage]);
|
|
497
|
-
const tPlural = useCallback((key, count, params, language) => {
|
|
498
|
-
if (!translator || !isInitialized) {
|
|
499
|
-
return key;
|
|
500
|
-
}
|
|
501
|
-
return translator.tPlural(key, count, params, language);
|
|
502
|
-
}, [translator, isInitialized, translationVersion, currentLanguage]);
|
|
503
|
-
const debug = useMemo(() => ({
|
|
504
|
-
getCurrentLanguage: () => {
|
|
505
|
-
try {
|
|
506
|
-
return translator?.getCurrentLanguage() || currentLanguage;
|
|
507
|
-
} catch {
|
|
508
|
-
return currentLanguage;
|
|
499
|
+
if (typeof paramsOrLang === "object" && paramsOrLang !== null && "defaultValue" in paramsOrLang && typeof paramsOrLang.defaultValue === "string") {
|
|
500
|
+
return interpolate(paramsOrLang.defaultValue);
|
|
509
501
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
try {
|
|
513
|
-
return translator?.getSupportedLanguages() || config.supportedLanguages?.map((l) => l.code) || [];
|
|
514
|
-
} catch {
|
|
515
|
-
return config.supportedLanguages?.map((l) => l.code) || [];
|
|
502
|
+
if (config.debug) {
|
|
503
|
+
return interpolate(key);
|
|
516
504
|
}
|
|
505
|
+
return "";
|
|
517
506
|
},
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
return Array.from(namespaces);
|
|
507
|
+
[
|
|
508
|
+
translator,
|
|
509
|
+
config.debug,
|
|
510
|
+
currentLanguage,
|
|
511
|
+
config.fallbackLanguage,
|
|
512
|
+
translationVersion,
|
|
513
|
+
findInSSRTranslations,
|
|
514
|
+
findInDefaultTranslations
|
|
515
|
+
]
|
|
516
|
+
);
|
|
517
|
+
const tAsync = useCallback(
|
|
518
|
+
async (key, params) => {
|
|
519
|
+
if (!translator) {
|
|
520
|
+
if (config.debug) {
|
|
521
|
+
console.warn("Translator not initialized");
|
|
534
522
|
}
|
|
535
|
-
return
|
|
536
|
-
} catch (error2) {
|
|
537
|
-
return [];
|
|
523
|
+
return key;
|
|
538
524
|
}
|
|
539
|
-
|
|
540
|
-
getAllTranslations: () => {
|
|
525
|
+
setIsLoading(true);
|
|
541
526
|
try {
|
|
542
|
-
|
|
527
|
+
const result = await translator.translateAsync(key, params);
|
|
528
|
+
return result;
|
|
543
529
|
} catch (error2) {
|
|
544
|
-
|
|
530
|
+
if (config.debug) {
|
|
531
|
+
console.error("Translation error:", error2);
|
|
532
|
+
}
|
|
533
|
+
return key;
|
|
534
|
+
} finally {
|
|
535
|
+
setIsLoading(false);
|
|
545
536
|
}
|
|
546
537
|
},
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
538
|
+
[translator, config.debug]
|
|
539
|
+
);
|
|
540
|
+
const tSync = useCallback(
|
|
541
|
+
(key, namespace, params) => {
|
|
542
|
+
if (!translator) {
|
|
543
|
+
if (config.debug) {
|
|
544
|
+
console.warn("Translator not initialized");
|
|
545
|
+
}
|
|
546
|
+
return key;
|
|
552
547
|
}
|
|
548
|
+
return translator.translateSync(key, params);
|
|
553
549
|
},
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
550
|
+
[translator, config.debug]
|
|
551
|
+
);
|
|
552
|
+
const getRawValue = useCallback(
|
|
553
|
+
(key, language) => {
|
|
554
|
+
if (!translator || !isInitialized) {
|
|
555
|
+
return void 0;
|
|
556
|
+
}
|
|
557
|
+
return translator.getRawValue(key, language);
|
|
560
558
|
},
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
559
|
+
[translator, isInitialized]
|
|
560
|
+
);
|
|
561
|
+
const tArray = useCallback(
|
|
562
|
+
(key, language) => {
|
|
563
|
+
if (!translator || !isInitialized) {
|
|
564
|
+
return [];
|
|
565
565
|
}
|
|
566
|
+
return translator.tArray(key, language);
|
|
566
567
|
},
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
};
|
|
576
|
-
}
|
|
577
|
-
return { size: 0, hits: 0, misses: 0 };
|
|
578
|
-
} catch (error2) {
|
|
579
|
-
return { size: 0, hits: 0, misses: 0 };
|
|
580
|
-
}
|
|
568
|
+
[translator, isInitialized, translationVersion, currentLanguage]
|
|
569
|
+
);
|
|
570
|
+
const tPlural = useCallback(
|
|
571
|
+
(key, count, params, language) => {
|
|
572
|
+
if (!translator || !isInitialized) {
|
|
573
|
+
return key;
|
|
574
|
+
}
|
|
575
|
+
return translator.tPlural(key, count, params, language);
|
|
581
576
|
},
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
577
|
+
[translator, isInitialized, translationVersion, currentLanguage]
|
|
578
|
+
);
|
|
579
|
+
const debug = useMemo(
|
|
580
|
+
() => ({
|
|
581
|
+
getCurrentLanguage: () => {
|
|
582
|
+
try {
|
|
583
|
+
return translator?.getCurrentLanguage() || currentLanguage;
|
|
584
|
+
} catch {
|
|
585
|
+
return currentLanguage;
|
|
586
|
+
}
|
|
587
|
+
},
|
|
588
|
+
getSupportedLanguages: () => {
|
|
586
589
|
try {
|
|
587
|
-
|
|
588
|
-
} catch
|
|
589
|
-
|
|
590
|
-
}
|
|
591
|
-
|
|
590
|
+
return translator?.getSupportedLanguages() || config.supportedLanguages?.map((l) => l.code) || [];
|
|
591
|
+
} catch {
|
|
592
|
+
return config.supportedLanguages?.map((l) => l.code) || [];
|
|
593
|
+
}
|
|
594
|
+
},
|
|
595
|
+
getLoadedNamespaces: () => {
|
|
596
|
+
try {
|
|
597
|
+
const debugInfo = translator?.debug();
|
|
598
|
+
if (debugInfo && debugInfo.loadedNamespaces) {
|
|
599
|
+
return Array.from(debugInfo.loadedNamespaces);
|
|
600
|
+
}
|
|
601
|
+
if (debugInfo && debugInfo.allTranslations) {
|
|
602
|
+
const namespaces = /* @__PURE__ */ new Set();
|
|
603
|
+
Object.values(debugInfo.allTranslations).forEach(
|
|
604
|
+
(langData) => {
|
|
605
|
+
if (langData && typeof langData === "object") {
|
|
606
|
+
Object.keys(langData).forEach((namespace) => {
|
|
607
|
+
namespaces.add(namespace);
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
);
|
|
612
|
+
return Array.from(namespaces);
|
|
613
|
+
}
|
|
614
|
+
return [];
|
|
615
|
+
} catch (error2) {
|
|
616
|
+
return [];
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
getAllTranslations: () => {
|
|
620
|
+
try {
|
|
621
|
+
return translator?.debug()?.allTranslations || {};
|
|
622
|
+
} catch (error2) {
|
|
623
|
+
return {};
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
isReady: () => {
|
|
627
|
+
try {
|
|
628
|
+
return translator?.isReady() || isInitialized;
|
|
629
|
+
} catch {
|
|
630
|
+
return isInitialized;
|
|
631
|
+
}
|
|
632
|
+
},
|
|
633
|
+
getInitializationError: () => {
|
|
634
|
+
try {
|
|
635
|
+
return translator?.getInitializationError() || error;
|
|
636
|
+
} catch {
|
|
637
|
+
return error;
|
|
638
|
+
}
|
|
639
|
+
},
|
|
640
|
+
clearCache: () => {
|
|
641
|
+
try {
|
|
642
|
+
translator?.clearCache();
|
|
643
|
+
} catch {
|
|
644
|
+
}
|
|
645
|
+
},
|
|
646
|
+
getCacheStats: () => {
|
|
647
|
+
try {
|
|
648
|
+
const debugInfo = translator?.debug();
|
|
649
|
+
if (debugInfo && debugInfo.cacheStats) {
|
|
650
|
+
return {
|
|
651
|
+
size: debugInfo.cacheSize || 0,
|
|
652
|
+
hits: debugInfo.cacheStats.hits || 0,
|
|
653
|
+
misses: debugInfo.cacheStats.misses || 0
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
return { size: 0, hits: 0, misses: 0 };
|
|
657
|
+
} catch (error2) {
|
|
658
|
+
return { size: 0, hits: 0, misses: 0 };
|
|
659
|
+
}
|
|
660
|
+
},
|
|
661
|
+
reloadTranslations: async () => {
|
|
662
|
+
if (translator) {
|
|
663
|
+
setIsLoading(true);
|
|
664
|
+
setError(null);
|
|
665
|
+
try {
|
|
666
|
+
await translator.initialize();
|
|
667
|
+
} catch (err) {
|
|
668
|
+
setError(err);
|
|
669
|
+
} finally {
|
|
670
|
+
setIsLoading(false);
|
|
671
|
+
}
|
|
592
672
|
}
|
|
593
673
|
}
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
674
|
+
}),
|
|
675
|
+
[
|
|
676
|
+
translator,
|
|
677
|
+
currentLanguage,
|
|
678
|
+
error,
|
|
679
|
+
isInitialized,
|
|
680
|
+
config.supportedLanguages
|
|
681
|
+
]
|
|
682
|
+
);
|
|
683
|
+
const value = useMemo(
|
|
684
|
+
() => ({
|
|
685
|
+
currentLanguage,
|
|
686
|
+
setLanguage,
|
|
687
|
+
t,
|
|
688
|
+
tPlural,
|
|
689
|
+
tArray,
|
|
690
|
+
tAsync,
|
|
691
|
+
tSync,
|
|
692
|
+
getRawValue,
|
|
693
|
+
isLoading,
|
|
694
|
+
error,
|
|
695
|
+
supportedLanguages: config.supportedLanguages,
|
|
696
|
+
debug,
|
|
697
|
+
isInitialized
|
|
698
|
+
}),
|
|
699
|
+
[
|
|
700
|
+
currentLanguage,
|
|
701
|
+
setLanguage,
|
|
702
|
+
t,
|
|
703
|
+
tPlural,
|
|
704
|
+
tArray,
|
|
705
|
+
tAsync,
|
|
706
|
+
tSync,
|
|
707
|
+
getRawValue,
|
|
708
|
+
isLoading,
|
|
709
|
+
error,
|
|
710
|
+
config.supportedLanguages,
|
|
711
|
+
debug,
|
|
712
|
+
isInitialized
|
|
713
|
+
]
|
|
714
|
+
);
|
|
611
715
|
return /* @__PURE__ */ jsx(I18nContext.Provider, { value, children });
|
|
612
716
|
}
|
|
613
717
|
function useI18n() {
|
|
@@ -617,7 +721,12 @@ function useI18n() {
|
|
|
617
721
|
currentLanguage: "ko",
|
|
618
722
|
setLanguage: () => {
|
|
619
723
|
},
|
|
620
|
-
t: (key) =>
|
|
724
|
+
t: (key, paramsOrLang) => {
|
|
725
|
+
if (typeof paramsOrLang === "object" && paramsOrLang !== null && "defaultValue" in paramsOrLang && typeof paramsOrLang.defaultValue === "string") {
|
|
726
|
+
return paramsOrLang.defaultValue;
|
|
727
|
+
}
|
|
728
|
+
return key;
|
|
729
|
+
},
|
|
621
730
|
tPlural: (key) => key,
|
|
622
731
|
tAsync: async (key) => key,
|
|
623
732
|
tSync: (key) => key,
|