@hua-labs/i18n-core 1.0.0 → 1.1.0-alpha.0.2
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 +20 -20
- package/README.md +645 -636
- package/dist/core/debug-tools.js +53 -53
- package/dist/index.d.ts.map +1 -1
- package/package.json +6 -3
- package/src/components/MissingKeyOverlay.tsx +222 -222
- package/src/core/debug-tools.ts +297 -297
- package/src/core/i18n-resource.ts +179 -179
- package/src/core/lazy-loader.ts +254 -254
- package/src/core/translator-factory.ts +136 -136
- package/src/core/translator.tsx +1193 -1193
- package/src/hooks/useI18n.tsx +594 -594
- package/src/hooks/useTranslation.tsx +61 -61
- package/src/index.ts +297 -297
- package/src/types/index.ts +442 -442
- package/src/utils/default-translations.ts +129 -129
|
@@ -1,137 +1,137 @@
|
|
|
1
|
-
import { Translator } from './translator';
|
|
2
|
-
import { I18nConfig } from '../types';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Translator 인스턴스를 관리하는 Factory 클래스
|
|
6
|
-
* - Config 변경 감지
|
|
7
|
-
* - 테스트 환경 격리
|
|
8
|
-
* - 메모리 관리
|
|
9
|
-
*/
|
|
10
|
-
export class TranslatorFactory {
|
|
11
|
-
private static instances = new Map<string, Translator>();
|
|
12
|
-
private static configCache = new Map<string, I18nConfig>();
|
|
13
|
-
private static readonly MAX_INSTANCES = 10; // 최대 인스턴스 수 제한
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Config를 기반으로 고유 키 생성
|
|
17
|
-
*/
|
|
18
|
-
private static generateConfigKey(config: I18nConfig): string {
|
|
19
|
-
// Config의 핵심 속성들을 기반으로 키 생성
|
|
20
|
-
const keyParts = [
|
|
21
|
-
config.defaultLanguage,
|
|
22
|
-
config.fallbackLanguage || 'en',
|
|
23
|
-
config.namespaces?.join(',') || 'common',
|
|
24
|
-
config.debug ? 'debug' : 'prod',
|
|
25
|
-
];
|
|
26
|
-
return keyParts.join('|');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Config가 변경되었는지 확인
|
|
31
|
-
*/
|
|
32
|
-
private static isConfigChanged(configKey: string, newConfig: I18nConfig): boolean {
|
|
33
|
-
const cachedConfig = this.configCache.get(configKey);
|
|
34
|
-
if (!cachedConfig) return true;
|
|
35
|
-
|
|
36
|
-
// 핵심 속성들만 비교
|
|
37
|
-
return (
|
|
38
|
-
cachedConfig.defaultLanguage !== newConfig.defaultLanguage ||
|
|
39
|
-
cachedConfig.fallbackLanguage !== newConfig.fallbackLanguage ||
|
|
40
|
-
JSON.stringify(cachedConfig.namespaces) !== JSON.stringify(newConfig.namespaces) ||
|
|
41
|
-
cachedConfig.debug !== newConfig.debug
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Translator 인스턴스 생성 또는 반환
|
|
47
|
-
*/
|
|
48
|
-
static create(config: I18nConfig): Translator {
|
|
49
|
-
const configKey = this.generateConfigKey(config);
|
|
50
|
-
|
|
51
|
-
// Config가 변경되었거나 인스턴스가 없으면 새로 생성
|
|
52
|
-
if (!this.instances.has(configKey) || this.isConfigChanged(configKey, config)) {
|
|
53
|
-
// 최대 인스턴스 수 초과 시 오래된 인스턴스 제거 (LRU 방식)
|
|
54
|
-
if (this.instances.size >= this.MAX_INSTANCES && !this.instances.has(configKey)) {
|
|
55
|
-
// 가장 오래된 인스턴스 제거 (Map은 삽입 순서 유지)
|
|
56
|
-
const oldestKey = this.instances.keys().next().value;
|
|
57
|
-
if (oldestKey) {
|
|
58
|
-
const oldInstance = this.instances.get(oldestKey);
|
|
59
|
-
if (oldInstance) {
|
|
60
|
-
oldInstance.clearCache();
|
|
61
|
-
}
|
|
62
|
-
this.instances.delete(oldestKey);
|
|
63
|
-
this.configCache.delete(oldestKey);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// 기존 인스턴스 정리
|
|
68
|
-
if (this.instances.has(configKey)) {
|
|
69
|
-
const oldInstance = this.instances.get(configKey)!;
|
|
70
|
-
oldInstance.clearCache();
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// 새 인스턴스 생성
|
|
74
|
-
const newInstance = new Translator(config);
|
|
75
|
-
this.instances.set(configKey, newInstance);
|
|
76
|
-
this.configCache.set(configKey, { ...config });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return this.instances.get(configKey)!;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* 특정 Config 키의 Translator 인스턴스 반환
|
|
84
|
-
*/
|
|
85
|
-
static get(config: I18nConfig): Translator | null {
|
|
86
|
-
const configKey = this.generateConfigKey(config);
|
|
87
|
-
return this.instances.get(configKey) || null;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* 모든 Translator 인스턴스 정리 (테스트용)
|
|
92
|
-
*/
|
|
93
|
-
static clear(): void {
|
|
94
|
-
// 모든 인스턴스의 캐시 정리
|
|
95
|
-
for (const instance of this.instances.values()) {
|
|
96
|
-
instance.clearCache();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
this.instances.clear();
|
|
100
|
-
this.configCache.clear();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* 특정 Config 키의 인스턴스만 정리
|
|
105
|
-
*/
|
|
106
|
-
static clearConfig(config: I18nConfig): void {
|
|
107
|
-
const configKey = this.generateConfigKey(config);
|
|
108
|
-
const instance = this.instances.get(configKey);
|
|
109
|
-
if (instance) {
|
|
110
|
-
instance.clearCache();
|
|
111
|
-
this.instances.delete(configKey);
|
|
112
|
-
this.configCache.delete(configKey);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* 현재 관리 중인 인스턴스 수 반환
|
|
118
|
-
*/
|
|
119
|
-
static getInstanceCount(): number {
|
|
120
|
-
return this.instances.size;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* 디버깅용: 모든 인스턴스 정보 반환
|
|
125
|
-
*/
|
|
126
|
-
static debug(): {
|
|
127
|
-
instanceCount: number;
|
|
128
|
-
configKeys: string[];
|
|
129
|
-
instances: Map<string, Translator>;
|
|
130
|
-
} {
|
|
131
|
-
return {
|
|
132
|
-
instanceCount: this.instances.size,
|
|
133
|
-
configKeys: Array.from(this.instances.keys()),
|
|
134
|
-
instances: this.instances,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
1
|
+
import { Translator } from './translator';
|
|
2
|
+
import { I18nConfig } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Translator 인스턴스를 관리하는 Factory 클래스
|
|
6
|
+
* - Config 변경 감지
|
|
7
|
+
* - 테스트 환경 격리
|
|
8
|
+
* - 메모리 관리
|
|
9
|
+
*/
|
|
10
|
+
export class TranslatorFactory {
|
|
11
|
+
private static instances = new Map<string, Translator>();
|
|
12
|
+
private static configCache = new Map<string, I18nConfig>();
|
|
13
|
+
private static readonly MAX_INSTANCES = 10; // 최대 인스턴스 수 제한
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Config를 기반으로 고유 키 생성
|
|
17
|
+
*/
|
|
18
|
+
private static generateConfigKey(config: I18nConfig): string {
|
|
19
|
+
// Config의 핵심 속성들을 기반으로 키 생성
|
|
20
|
+
const keyParts = [
|
|
21
|
+
config.defaultLanguage,
|
|
22
|
+
config.fallbackLanguage || 'en',
|
|
23
|
+
config.namespaces?.join(',') || 'common',
|
|
24
|
+
config.debug ? 'debug' : 'prod',
|
|
25
|
+
];
|
|
26
|
+
return keyParts.join('|');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Config가 변경되었는지 확인
|
|
31
|
+
*/
|
|
32
|
+
private static isConfigChanged(configKey: string, newConfig: I18nConfig): boolean {
|
|
33
|
+
const cachedConfig = this.configCache.get(configKey);
|
|
34
|
+
if (!cachedConfig) return true;
|
|
35
|
+
|
|
36
|
+
// 핵심 속성들만 비교
|
|
37
|
+
return (
|
|
38
|
+
cachedConfig.defaultLanguage !== newConfig.defaultLanguage ||
|
|
39
|
+
cachedConfig.fallbackLanguage !== newConfig.fallbackLanguage ||
|
|
40
|
+
JSON.stringify(cachedConfig.namespaces) !== JSON.stringify(newConfig.namespaces) ||
|
|
41
|
+
cachedConfig.debug !== newConfig.debug
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Translator 인스턴스 생성 또는 반환
|
|
47
|
+
*/
|
|
48
|
+
static create(config: I18nConfig): Translator {
|
|
49
|
+
const configKey = this.generateConfigKey(config);
|
|
50
|
+
|
|
51
|
+
// Config가 변경되었거나 인스턴스가 없으면 새로 생성
|
|
52
|
+
if (!this.instances.has(configKey) || this.isConfigChanged(configKey, config)) {
|
|
53
|
+
// 최대 인스턴스 수 초과 시 오래된 인스턴스 제거 (LRU 방식)
|
|
54
|
+
if (this.instances.size >= this.MAX_INSTANCES && !this.instances.has(configKey)) {
|
|
55
|
+
// 가장 오래된 인스턴스 제거 (Map은 삽입 순서 유지)
|
|
56
|
+
const oldestKey = this.instances.keys().next().value;
|
|
57
|
+
if (oldestKey) {
|
|
58
|
+
const oldInstance = this.instances.get(oldestKey);
|
|
59
|
+
if (oldInstance) {
|
|
60
|
+
oldInstance.clearCache();
|
|
61
|
+
}
|
|
62
|
+
this.instances.delete(oldestKey);
|
|
63
|
+
this.configCache.delete(oldestKey);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 기존 인스턴스 정리
|
|
68
|
+
if (this.instances.has(configKey)) {
|
|
69
|
+
const oldInstance = this.instances.get(configKey)!;
|
|
70
|
+
oldInstance.clearCache();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 새 인스턴스 생성
|
|
74
|
+
const newInstance = new Translator(config);
|
|
75
|
+
this.instances.set(configKey, newInstance);
|
|
76
|
+
this.configCache.set(configKey, { ...config });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return this.instances.get(configKey)!;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 특정 Config 키의 Translator 인스턴스 반환
|
|
84
|
+
*/
|
|
85
|
+
static get(config: I18nConfig): Translator | null {
|
|
86
|
+
const configKey = this.generateConfigKey(config);
|
|
87
|
+
return this.instances.get(configKey) || null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 모든 Translator 인스턴스 정리 (테스트용)
|
|
92
|
+
*/
|
|
93
|
+
static clear(): void {
|
|
94
|
+
// 모든 인스턴스의 캐시 정리
|
|
95
|
+
for (const instance of this.instances.values()) {
|
|
96
|
+
instance.clearCache();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
this.instances.clear();
|
|
100
|
+
this.configCache.clear();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* 특정 Config 키의 인스턴스만 정리
|
|
105
|
+
*/
|
|
106
|
+
static clearConfig(config: I18nConfig): void {
|
|
107
|
+
const configKey = this.generateConfigKey(config);
|
|
108
|
+
const instance = this.instances.get(configKey);
|
|
109
|
+
if (instance) {
|
|
110
|
+
instance.clearCache();
|
|
111
|
+
this.instances.delete(configKey);
|
|
112
|
+
this.configCache.delete(configKey);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 현재 관리 중인 인스턴스 수 반환
|
|
118
|
+
*/
|
|
119
|
+
static getInstanceCount(): number {
|
|
120
|
+
return this.instances.size;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 디버깅용: 모든 인스턴스 정보 반환
|
|
125
|
+
*/
|
|
126
|
+
static debug(): {
|
|
127
|
+
instanceCount: number;
|
|
128
|
+
configKeys: string[];
|
|
129
|
+
instances: Map<string, Translator>;
|
|
130
|
+
} {
|
|
131
|
+
return {
|
|
132
|
+
instanceCount: this.instances.size,
|
|
133
|
+
configKeys: Array.from(this.instances.keys()),
|
|
134
|
+
instances: this.instances,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
137
|
}
|