@hua-labs/i18n-core 1.0.0
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 +636 -0
- package/dist/components/MissingKeyOverlay.d.ts +33 -0
- package/dist/components/MissingKeyOverlay.d.ts.map +1 -0
- package/dist/components/MissingKeyOverlay.js +138 -0
- package/dist/components/MissingKeyOverlay.js.map +1 -0
- package/dist/core/debug-tools.d.ts +37 -0
- package/dist/core/debug-tools.d.ts.map +1 -0
- package/dist/core/debug-tools.js +241 -0
- package/dist/core/debug-tools.js.map +1 -0
- package/dist/core/i18n-resource.d.ts +59 -0
- package/dist/core/i18n-resource.d.ts.map +1 -0
- package/dist/core/i18n-resource.js +153 -0
- package/dist/core/i18n-resource.js.map +1 -0
- package/dist/core/lazy-loader.d.ts +82 -0
- package/dist/core/lazy-loader.d.ts.map +1 -0
- package/dist/core/lazy-loader.js +193 -0
- package/dist/core/lazy-loader.js.map +1 -0
- package/dist/core/translator-factory.d.ts +50 -0
- package/dist/core/translator-factory.d.ts.map +1 -0
- package/dist/core/translator-factory.js +117 -0
- package/dist/core/translator-factory.js.map +1 -0
- package/dist/core/translator.d.ts +202 -0
- package/dist/core/translator.d.ts.map +1 -0
- package/dist/core/translator.js +912 -0
- package/dist/core/translator.js.map +1 -0
- package/dist/hooks/useI18n.d.ts +39 -0
- package/dist/hooks/useI18n.d.ts.map +1 -0
- package/dist/hooks/useI18n.js +531 -0
- package/dist/hooks/useI18n.js.map +1 -0
- package/dist/hooks/useTranslation.d.ts +55 -0
- package/dist/hooks/useTranslation.d.ts.map +1 -0
- package/dist/hooks/useTranslation.js +58 -0
- package/dist/hooks/useTranslation.js.map +1 -0
- package/dist/index.d.ts +162 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +191 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +162 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +191 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/default-translations.d.ts +20 -0
- package/dist/utils/default-translations.d.ts.map +1 -0
- package/dist/utils/default-translations.js +123 -0
- package/dist/utils/default-translations.js.map +1 -0
- package/package.json +60 -0
- package/src/components/MissingKeyOverlay.tsx +223 -0
- package/src/core/debug-tools.ts +298 -0
- package/src/core/i18n-resource.ts +180 -0
- package/src/core/lazy-loader.ts +255 -0
- package/src/core/translator-factory.ts +137 -0
- package/src/core/translator.tsx +1194 -0
- package/src/hooks/useI18n.tsx +595 -0
- package/src/hooks/useTranslation.tsx +62 -0
- package/src/index.ts +298 -0
- package/src/types/index.ts +443 -0
- package/src/utils/default-translations.ts +129 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { TranslationNamespace } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* 네임스페이스별 지연 로딩 전략
|
|
4
|
+
* 대규모 앱에서 번역 단위 최적화를 위한 loadOnDemand 함수
|
|
5
|
+
*/
|
|
6
|
+
export declare class LazyLoader {
|
|
7
|
+
private static instance;
|
|
8
|
+
private loadingQueue;
|
|
9
|
+
private preloadCache;
|
|
10
|
+
private loadHistory;
|
|
11
|
+
private constructor();
|
|
12
|
+
static getInstance(): LazyLoader;
|
|
13
|
+
/**
|
|
14
|
+
* 필요할 때 네임스페이스 로딩
|
|
15
|
+
*/
|
|
16
|
+
loadOnDemand(language: string, namespace: string, loader: (lang: string, ns: string) => Promise<TranslationNamespace>): Promise<TranslationNamespace>;
|
|
17
|
+
/**
|
|
18
|
+
* 실제 로딩 수행
|
|
19
|
+
*/
|
|
20
|
+
private performLoad;
|
|
21
|
+
/**
|
|
22
|
+
* 로딩 히스토리 업데이트
|
|
23
|
+
*/
|
|
24
|
+
private updateLoadHistory;
|
|
25
|
+
/**
|
|
26
|
+
* 네임스페이스 사전 로딩
|
|
27
|
+
*/
|
|
28
|
+
preloadNamespace(language: string, namespace: string, loader: (lang: string, ns: string) => Promise<TranslationNamespace>): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* 여러 네임스페이스 동시 사전 로딩
|
|
31
|
+
*/
|
|
32
|
+
preloadMultipleNamespaces(language: string, namespaces: string[], loader: (lang: string, ns: string) => Promise<TranslationNamespace>): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* 사용 패턴 기반 자동 사전 로딩
|
|
35
|
+
*/
|
|
36
|
+
autoPreload(language: string, currentNamespace: string, loader: (lang: string, ns: string) => Promise<TranslationNamespace>): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* 관련 네임스페이스 추정
|
|
39
|
+
*/
|
|
40
|
+
private getRelatedNamespaces;
|
|
41
|
+
/**
|
|
42
|
+
* 로딩 우선순위 설정
|
|
43
|
+
*/
|
|
44
|
+
setLoadPriority(namespaces: string[]): void;
|
|
45
|
+
/**
|
|
46
|
+
* 로딩 통계 가져오기
|
|
47
|
+
*/
|
|
48
|
+
getLoadStats(): {
|
|
49
|
+
loadingQueueSize: number;
|
|
50
|
+
preloadedCount: number;
|
|
51
|
+
loadHistorySize: number;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* 메모리 최적화
|
|
55
|
+
*/
|
|
56
|
+
optimizeMemory(): void;
|
|
57
|
+
/**
|
|
58
|
+
* 네임스페이스 사용 빈도 분석
|
|
59
|
+
*/
|
|
60
|
+
analyzeUsagePatterns(): Record<string, number>;
|
|
61
|
+
/**
|
|
62
|
+
* 캐시 무효화
|
|
63
|
+
*/
|
|
64
|
+
invalidateCache(language?: string, namespace?: string): void;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 전역 지연 로더 인스턴스
|
|
68
|
+
*/
|
|
69
|
+
export declare const lazyLoader: LazyLoader;
|
|
70
|
+
/**
|
|
71
|
+
* 편의 함수: 필요할 때 로딩
|
|
72
|
+
*/
|
|
73
|
+
export declare const loadOnDemand: (language: string, namespace: string, loader: (lang: string, ns: string) => Promise<TranslationNamespace>) => Promise<TranslationNamespace>;
|
|
74
|
+
/**
|
|
75
|
+
* 편의 함수: 사전 로딩
|
|
76
|
+
*/
|
|
77
|
+
export declare const preloadNamespace: (language: string, namespace: string, loader: (lang: string, ns: string) => Promise<TranslationNamespace>) => Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* 편의 함수: 자동 사전 로딩
|
|
80
|
+
*/
|
|
81
|
+
export declare const autoPreload: (language: string, currentNamespace: string, loader: (lang: string, ns: string) => Promise<TranslationNamespace>) => Promise<void>;
|
|
82
|
+
//# sourceMappingURL=lazy-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lazy-loader.d.ts","sourceRoot":"","sources":["../../src/core/lazy-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAGhD;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAa;IACpC,OAAO,CAAC,YAAY,CAAoD;IACxE,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,WAAW,CAA6B;IAEhD,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,UAAU;IAOhC;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,GAClE,OAAO,CAAC,oBAAoB,CAAC;IA4BhC;;OAEG;YACW,WAAW;IASzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACG,gBAAgB,CACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,GAClE,OAAO,CAAC,IAAI,CAAC;IAehB;;OAEG;IACG,yBAAyB,CAC7B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAAE,EACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,GAClE,OAAO,CAAC,IAAI,CAAC;IAQhB;;OAEG;IACG,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,GAClE,OAAO,CAAC,IAAI,CAAC;IAShB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAa5B;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;IAI3C;;OAEG;IACH,YAAY;;;;;IAQZ;;OAEG;IACH,cAAc,IAAI,IAAI;IAYtB;;OAEG;IACH,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAW9C;;OAEG;IACH,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;CAqB7D;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,YAA2B,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,YAAY,GACvB,UAAU,MAAM,EAChB,WAAW,MAAM,EACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,kCAGpE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,MAAM,EAChB,WAAW,MAAM,EACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,kBAGpE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,UAAU,MAAM,EAChB,kBAAkB,MAAM,EACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,kBAGpE,CAAC"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { i18nResourceManager } from './i18n-resource';
|
|
2
|
+
/**
|
|
3
|
+
* 네임스페이스별 지연 로딩 전략
|
|
4
|
+
* 대규모 앱에서 번역 단위 최적화를 위한 loadOnDemand 함수
|
|
5
|
+
*/
|
|
6
|
+
export class LazyLoader {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.loadingQueue = new Map();
|
|
9
|
+
this.preloadCache = new Set();
|
|
10
|
+
this.loadHistory = new Map();
|
|
11
|
+
}
|
|
12
|
+
static getInstance() {
|
|
13
|
+
if (!LazyLoader.instance) {
|
|
14
|
+
LazyLoader.instance = new LazyLoader();
|
|
15
|
+
}
|
|
16
|
+
return LazyLoader.instance;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 필요할 때 네임스페이스 로딩
|
|
20
|
+
*/
|
|
21
|
+
async loadOnDemand(language, namespace, loader) {
|
|
22
|
+
const cacheKey = `${language}:${namespace}`;
|
|
23
|
+
// 이미 로딩 중이면 기존 Promise 반환
|
|
24
|
+
if (this.loadingQueue.has(cacheKey)) {
|
|
25
|
+
return this.loadingQueue.get(cacheKey);
|
|
26
|
+
}
|
|
27
|
+
// 캐시에 있으면 반환
|
|
28
|
+
const cached = i18nResourceManager.getCachedTranslationsSync(language, namespace);
|
|
29
|
+
if (cached) {
|
|
30
|
+
this.updateLoadHistory(cacheKey);
|
|
31
|
+
return cached;
|
|
32
|
+
}
|
|
33
|
+
// 새로 로딩
|
|
34
|
+
const loadPromise = this.performLoad(language, namespace, loader);
|
|
35
|
+
this.loadingQueue.set(cacheKey, loadPromise);
|
|
36
|
+
try {
|
|
37
|
+
const result = await loadPromise;
|
|
38
|
+
this.updateLoadHistory(cacheKey);
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
this.loadingQueue.delete(cacheKey);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 실제 로딩 수행
|
|
47
|
+
*/
|
|
48
|
+
async performLoad(language, namespace, loader) {
|
|
49
|
+
const result = await i18nResourceManager.getCachedTranslations(language, namespace, loader);
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 로딩 히스토리 업데이트
|
|
54
|
+
*/
|
|
55
|
+
updateLoadHistory(cacheKey) {
|
|
56
|
+
this.loadHistory.set(cacheKey, Date.now());
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 네임스페이스 사전 로딩
|
|
60
|
+
*/
|
|
61
|
+
async preloadNamespace(language, namespace, loader) {
|
|
62
|
+
const cacheKey = `${language}:${namespace}`;
|
|
63
|
+
if (this.preloadCache.has(cacheKey)) {
|
|
64
|
+
return; // 이미 사전 로딩됨
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
await this.loadOnDemand(language, namespace, loader);
|
|
68
|
+
this.preloadCache.add(cacheKey);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
// Silent fail for preloading
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 여러 네임스페이스 동시 사전 로딩
|
|
76
|
+
*/
|
|
77
|
+
async preloadMultipleNamespaces(language, namespaces, loader) {
|
|
78
|
+
const promises = namespaces.map(namespace => this.preloadNamespace(language, namespace, loader));
|
|
79
|
+
await Promise.allSettled(promises);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 사용 패턴 기반 자동 사전 로딩
|
|
83
|
+
*/
|
|
84
|
+
async autoPreload(language, currentNamespace, loader) {
|
|
85
|
+
// 현재 네임스페이스와 관련된 네임스페이스들 자동 사전 로딩
|
|
86
|
+
const relatedNamespaces = this.getRelatedNamespaces(currentNamespace);
|
|
87
|
+
for (const namespace of relatedNamespaces) {
|
|
88
|
+
await this.preloadNamespace(language, namespace, loader);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 관련 네임스페이스 추정
|
|
93
|
+
*/
|
|
94
|
+
getRelatedNamespaces(currentNamespace) {
|
|
95
|
+
// 실제 구현에서는 사용 패턴 분석을 통해 관련 네임스페이스 추정
|
|
96
|
+
const namespacePatterns = {
|
|
97
|
+
'auth': ['common', 'validation', 'errors'],
|
|
98
|
+
'dashboard': ['common', 'navigation', 'stats'],
|
|
99
|
+
'profile': ['common', 'auth', 'validation'],
|
|
100
|
+
'settings': ['common', 'navigation', 'forms'],
|
|
101
|
+
'common': ['errors', 'validation']
|
|
102
|
+
};
|
|
103
|
+
return namespacePatterns[currentNamespace] || [];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 로딩 우선순위 설정
|
|
107
|
+
*/
|
|
108
|
+
setLoadPriority(namespaces) {
|
|
109
|
+
// 우선순위가 높은 네임스페이스들을 먼저 로딩
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 로딩 통계 가져오기
|
|
113
|
+
*/
|
|
114
|
+
getLoadStats() {
|
|
115
|
+
return {
|
|
116
|
+
loadingQueueSize: this.loadingQueue.size,
|
|
117
|
+
preloadedCount: this.preloadCache.size,
|
|
118
|
+
loadHistorySize: this.loadHistory.size
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 메모리 최적화
|
|
123
|
+
*/
|
|
124
|
+
optimizeMemory() {
|
|
125
|
+
// 오래된 로딩 히스토리 정리
|
|
126
|
+
const now = Date.now();
|
|
127
|
+
const oneHour = 60 * 60 * 1000;
|
|
128
|
+
for (const [key, timestamp] of this.loadHistory.entries()) {
|
|
129
|
+
if (now - timestamp > oneHour) {
|
|
130
|
+
this.loadHistory.delete(key);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* 네임스페이스 사용 빈도 분석
|
|
136
|
+
*/
|
|
137
|
+
analyzeUsagePatterns() {
|
|
138
|
+
const usage = {};
|
|
139
|
+
for (const [key, timestamp] of this.loadHistory.entries()) {
|
|
140
|
+
const namespace = key.split(':')[1];
|
|
141
|
+
usage[namespace] = (usage[namespace] || 0) + 1;
|
|
142
|
+
}
|
|
143
|
+
return usage;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 캐시 무효화
|
|
147
|
+
*/
|
|
148
|
+
invalidateCache(language, namespace) {
|
|
149
|
+
i18nResourceManager.invalidateCache(language, namespace);
|
|
150
|
+
if (language && namespace) {
|
|
151
|
+
const cacheKey = `${language}:${namespace}`;
|
|
152
|
+
this.preloadCache.delete(cacheKey);
|
|
153
|
+
this.loadHistory.delete(cacheKey);
|
|
154
|
+
}
|
|
155
|
+
else if (language) {
|
|
156
|
+
// 특정 언어의 모든 캐시 무효화
|
|
157
|
+
for (const key of this.preloadCache) {
|
|
158
|
+
if (key.startsWith(`${language}:`)) {
|
|
159
|
+
this.preloadCache.delete(key);
|
|
160
|
+
this.loadHistory.delete(key);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// 전체 캐시 무효화
|
|
166
|
+
this.preloadCache.clear();
|
|
167
|
+
this.loadHistory.clear();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 전역 지연 로더 인스턴스
|
|
173
|
+
*/
|
|
174
|
+
export const lazyLoader = LazyLoader.getInstance();
|
|
175
|
+
/**
|
|
176
|
+
* 편의 함수: 필요할 때 로딩
|
|
177
|
+
*/
|
|
178
|
+
export const loadOnDemand = (language, namespace, loader) => {
|
|
179
|
+
return lazyLoader.loadOnDemand(language, namespace, loader);
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* 편의 함수: 사전 로딩
|
|
183
|
+
*/
|
|
184
|
+
export const preloadNamespace = (language, namespace, loader) => {
|
|
185
|
+
return lazyLoader.preloadNamespace(language, namespace, loader);
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* 편의 함수: 자동 사전 로딩
|
|
189
|
+
*/
|
|
190
|
+
export const autoPreload = (language, currentNamespace, loader) => {
|
|
191
|
+
return lazyLoader.autoPreload(language, currentNamespace, loader);
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=lazy-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lazy-loader.js","sourceRoot":"","sources":["../../src/core/lazy-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Translator } from './translator';
|
|
2
|
+
import { I18nConfig } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Translator 인스턴스를 관리하는 Factory 클래스
|
|
5
|
+
* - Config 변경 감지
|
|
6
|
+
* - 테스트 환경 격리
|
|
7
|
+
* - 메모리 관리
|
|
8
|
+
*/
|
|
9
|
+
export declare class TranslatorFactory {
|
|
10
|
+
private static instances;
|
|
11
|
+
private static configCache;
|
|
12
|
+
private static readonly MAX_INSTANCES;
|
|
13
|
+
/**
|
|
14
|
+
* Config를 기반으로 고유 키 생성
|
|
15
|
+
*/
|
|
16
|
+
private static generateConfigKey;
|
|
17
|
+
/**
|
|
18
|
+
* Config가 변경되었는지 확인
|
|
19
|
+
*/
|
|
20
|
+
private static isConfigChanged;
|
|
21
|
+
/**
|
|
22
|
+
* Translator 인스턴스 생성 또는 반환
|
|
23
|
+
*/
|
|
24
|
+
static create(config: I18nConfig): Translator;
|
|
25
|
+
/**
|
|
26
|
+
* 특정 Config 키의 Translator 인스턴스 반환
|
|
27
|
+
*/
|
|
28
|
+
static get(config: I18nConfig): Translator | null;
|
|
29
|
+
/**
|
|
30
|
+
* 모든 Translator 인스턴스 정리 (테스트용)
|
|
31
|
+
*/
|
|
32
|
+
static clear(): void;
|
|
33
|
+
/**
|
|
34
|
+
* 특정 Config 키의 인스턴스만 정리
|
|
35
|
+
*/
|
|
36
|
+
static clearConfig(config: I18nConfig): void;
|
|
37
|
+
/**
|
|
38
|
+
* 현재 관리 중인 인스턴스 수 반환
|
|
39
|
+
*/
|
|
40
|
+
static getInstanceCount(): number;
|
|
41
|
+
/**
|
|
42
|
+
* 디버깅용: 모든 인스턴스 정보 반환
|
|
43
|
+
*/
|
|
44
|
+
static debug(): {
|
|
45
|
+
instanceCount: number;
|
|
46
|
+
configKeys: string[];
|
|
47
|
+
instances: Map<string, Translator>;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=translator-factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translator-factory.d.ts","sourceRoot":"","sources":["../../src/core/translator-factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAiC;IACzD,OAAO,CAAC,MAAM,CAAC,WAAW,CAAiC;IAC3D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAM;IAE3C;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAWhC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAa9B;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU;IAkC7C;;OAEG;IACH,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI;IAKjD;;OAEG;IACH,MAAM,CAAC,KAAK,IAAI,IAAI;IAUpB;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAU5C;;OAEG;IACH,MAAM,CAAC,gBAAgB,IAAI,MAAM;IAIjC;;OAEG;IACH,MAAM,CAAC,KAAK,IAAI;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;KACpC;CAOF"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { Translator } from './translator';
|
|
2
|
+
/**
|
|
3
|
+
* Translator 인스턴스를 관리하는 Factory 클래스
|
|
4
|
+
* - Config 변경 감지
|
|
5
|
+
* - 테스트 환경 격리
|
|
6
|
+
* - 메모리 관리
|
|
7
|
+
*/
|
|
8
|
+
export class TranslatorFactory {
|
|
9
|
+
/**
|
|
10
|
+
* Config를 기반으로 고유 키 생성
|
|
11
|
+
*/
|
|
12
|
+
static generateConfigKey(config) {
|
|
13
|
+
// Config의 핵심 속성들을 기반으로 키 생성
|
|
14
|
+
const keyParts = [
|
|
15
|
+
config.defaultLanguage,
|
|
16
|
+
config.fallbackLanguage || 'en',
|
|
17
|
+
config.namespaces?.join(',') || 'common',
|
|
18
|
+
config.debug ? 'debug' : 'prod',
|
|
19
|
+
];
|
|
20
|
+
return keyParts.join('|');
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Config가 변경되었는지 확인
|
|
24
|
+
*/
|
|
25
|
+
static isConfigChanged(configKey, newConfig) {
|
|
26
|
+
const cachedConfig = this.configCache.get(configKey);
|
|
27
|
+
if (!cachedConfig)
|
|
28
|
+
return true;
|
|
29
|
+
// 핵심 속성들만 비교
|
|
30
|
+
return (cachedConfig.defaultLanguage !== newConfig.defaultLanguage ||
|
|
31
|
+
cachedConfig.fallbackLanguage !== newConfig.fallbackLanguage ||
|
|
32
|
+
JSON.stringify(cachedConfig.namespaces) !== JSON.stringify(newConfig.namespaces) ||
|
|
33
|
+
cachedConfig.debug !== newConfig.debug);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Translator 인스턴스 생성 또는 반환
|
|
37
|
+
*/
|
|
38
|
+
static create(config) {
|
|
39
|
+
const configKey = this.generateConfigKey(config);
|
|
40
|
+
// Config가 변경되었거나 인스턴스가 없으면 새로 생성
|
|
41
|
+
if (!this.instances.has(configKey) || this.isConfigChanged(configKey, config)) {
|
|
42
|
+
// 최대 인스턴스 수 초과 시 오래된 인스턴스 제거 (LRU 방식)
|
|
43
|
+
if (this.instances.size >= this.MAX_INSTANCES && !this.instances.has(configKey)) {
|
|
44
|
+
// 가장 오래된 인스턴스 제거 (Map은 삽입 순서 유지)
|
|
45
|
+
const oldestKey = this.instances.keys().next().value;
|
|
46
|
+
if (oldestKey) {
|
|
47
|
+
const oldInstance = this.instances.get(oldestKey);
|
|
48
|
+
if (oldInstance) {
|
|
49
|
+
oldInstance.clearCache();
|
|
50
|
+
}
|
|
51
|
+
this.instances.delete(oldestKey);
|
|
52
|
+
this.configCache.delete(oldestKey);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// 기존 인스턴스 정리
|
|
56
|
+
if (this.instances.has(configKey)) {
|
|
57
|
+
const oldInstance = this.instances.get(configKey);
|
|
58
|
+
oldInstance.clearCache();
|
|
59
|
+
}
|
|
60
|
+
// 새 인스턴스 생성
|
|
61
|
+
const newInstance = new Translator(config);
|
|
62
|
+
this.instances.set(configKey, newInstance);
|
|
63
|
+
this.configCache.set(configKey, { ...config });
|
|
64
|
+
}
|
|
65
|
+
return this.instances.get(configKey);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 특정 Config 키의 Translator 인스턴스 반환
|
|
69
|
+
*/
|
|
70
|
+
static get(config) {
|
|
71
|
+
const configKey = this.generateConfigKey(config);
|
|
72
|
+
return this.instances.get(configKey) || null;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 모든 Translator 인스턴스 정리 (테스트용)
|
|
76
|
+
*/
|
|
77
|
+
static clear() {
|
|
78
|
+
// 모든 인스턴스의 캐시 정리
|
|
79
|
+
for (const instance of this.instances.values()) {
|
|
80
|
+
instance.clearCache();
|
|
81
|
+
}
|
|
82
|
+
this.instances.clear();
|
|
83
|
+
this.configCache.clear();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 특정 Config 키의 인스턴스만 정리
|
|
87
|
+
*/
|
|
88
|
+
static clearConfig(config) {
|
|
89
|
+
const configKey = this.generateConfigKey(config);
|
|
90
|
+
const instance = this.instances.get(configKey);
|
|
91
|
+
if (instance) {
|
|
92
|
+
instance.clearCache();
|
|
93
|
+
this.instances.delete(configKey);
|
|
94
|
+
this.configCache.delete(configKey);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 현재 관리 중인 인스턴스 수 반환
|
|
99
|
+
*/
|
|
100
|
+
static getInstanceCount() {
|
|
101
|
+
return this.instances.size;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 디버깅용: 모든 인스턴스 정보 반환
|
|
105
|
+
*/
|
|
106
|
+
static debug() {
|
|
107
|
+
return {
|
|
108
|
+
instanceCount: this.instances.size,
|
|
109
|
+
configKeys: Array.from(this.instances.keys()),
|
|
110
|
+
instances: this.instances,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
TranslatorFactory.instances = new Map();
|
|
115
|
+
TranslatorFactory.configCache = new Map();
|
|
116
|
+
TranslatorFactory.MAX_INSTANCES = 10; // 최대 인스턴스 수 제한
|
|
117
|
+
//# sourceMappingURL=translator-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translator-factory.js","sourceRoot":"","sources":["../../src/core/translator-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { I18nConfig, TranslationNamespace, TranslationError } from '../types';
|
|
2
|
+
export interface TranslatorInterface {
|
|
3
|
+
translate(key: string, language?: string): string;
|
|
4
|
+
setLanguage(lang: string): void;
|
|
5
|
+
getCurrentLanguage(): string;
|
|
6
|
+
initialize(): Promise<void>;
|
|
7
|
+
isReady(): boolean;
|
|
8
|
+
debug(): unknown;
|
|
9
|
+
getRawValue(key: string, language?: string): unknown;
|
|
10
|
+
}
|
|
11
|
+
export declare class Translator implements TranslatorInterface {
|
|
12
|
+
private cache;
|
|
13
|
+
private loadedNamespaces;
|
|
14
|
+
private loadingPromises;
|
|
15
|
+
private allTranslations;
|
|
16
|
+
private isInitialized;
|
|
17
|
+
private initializationError;
|
|
18
|
+
private config;
|
|
19
|
+
private currentLang;
|
|
20
|
+
private cacheStats;
|
|
21
|
+
private onTranslationLoadedCallbacks;
|
|
22
|
+
private onLanguageChangedCallbacks;
|
|
23
|
+
private notifyTimer;
|
|
24
|
+
private recentlyNotified;
|
|
25
|
+
/**
|
|
26
|
+
* 번역 로드 완료 콜백 등록
|
|
27
|
+
*/
|
|
28
|
+
onTranslationLoaded(callback: () => void): () => void;
|
|
29
|
+
/**
|
|
30
|
+
* 언어 변경 콜백 등록
|
|
31
|
+
*/
|
|
32
|
+
onLanguageChanged(callback: (language: string) => void): () => void;
|
|
33
|
+
/**
|
|
34
|
+
* 언어 변경 이벤트 발생
|
|
35
|
+
*/
|
|
36
|
+
private notifyLanguageChanged;
|
|
37
|
+
/**
|
|
38
|
+
* 번역 로드 완료 이벤트 발생 (디바운싱 적용)
|
|
39
|
+
*/
|
|
40
|
+
private notifyTranslationLoaded;
|
|
41
|
+
constructor(config: I18nConfig);
|
|
42
|
+
/**
|
|
43
|
+
* 모든 번역 데이터를 미리 로드 (hua-api 스타일)
|
|
44
|
+
*/
|
|
45
|
+
initialize(): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* 초기화되지 않은 상태에서 번역 시도
|
|
48
|
+
*/
|
|
49
|
+
private translateBeforeInitialized;
|
|
50
|
+
/**
|
|
51
|
+
* 다른 로드된 언어에서 번역 찾기 (언어 변경 중 깜빡임 방지)
|
|
52
|
+
*/
|
|
53
|
+
private findInOtherLanguages;
|
|
54
|
+
/**
|
|
55
|
+
* 폴백 언어에서 번역 찾기
|
|
56
|
+
*/
|
|
57
|
+
private findInFallbackLanguage;
|
|
58
|
+
/**
|
|
59
|
+
* 번역 키를 번역된 텍스트로 변환
|
|
60
|
+
*/
|
|
61
|
+
translate(key: string, language?: string): string;
|
|
62
|
+
/**
|
|
63
|
+
* 네임스페이스에서 키 찾기
|
|
64
|
+
*/
|
|
65
|
+
private findInNamespace;
|
|
66
|
+
/**
|
|
67
|
+
* 중첩된 객체에서 값을 가져오기
|
|
68
|
+
*/
|
|
69
|
+
private getNestedValue;
|
|
70
|
+
/**
|
|
71
|
+
* 문자열 값인지 확인하는 타입 가드
|
|
72
|
+
*/
|
|
73
|
+
private isStringValue;
|
|
74
|
+
/**
|
|
75
|
+
* 원시 값 가져오기 (배열, 객체 포함)
|
|
76
|
+
*/
|
|
77
|
+
getRawValue(key: string, language?: string): unknown;
|
|
78
|
+
/**
|
|
79
|
+
* 매개변수 보간
|
|
80
|
+
*/
|
|
81
|
+
private interpolate;
|
|
82
|
+
/**
|
|
83
|
+
* 매개변수가 있는 번역
|
|
84
|
+
*/
|
|
85
|
+
translateWithParams(key: string, params?: Record<string, unknown>, language?: string): string;
|
|
86
|
+
/**
|
|
87
|
+
* 언어 설정
|
|
88
|
+
*/
|
|
89
|
+
setLanguage(language: string): void;
|
|
90
|
+
/**
|
|
91
|
+
* 언어 데이터 로드
|
|
92
|
+
*/
|
|
93
|
+
private loadLanguageData;
|
|
94
|
+
/**
|
|
95
|
+
* 현재 언어 가져오기
|
|
96
|
+
*/
|
|
97
|
+
getCurrentLanguage(): string;
|
|
98
|
+
/**
|
|
99
|
+
* 지원되는 언어 목록 가져오기
|
|
100
|
+
*/
|
|
101
|
+
getSupportedLanguages(): string[];
|
|
102
|
+
/**
|
|
103
|
+
* 초기화 완료 여부 확인
|
|
104
|
+
*/
|
|
105
|
+
isReady(): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* 초기화 오류 가져오기
|
|
108
|
+
*/
|
|
109
|
+
getInitializationError(): TranslationError | null;
|
|
110
|
+
/**
|
|
111
|
+
* 캐시 클리어
|
|
112
|
+
*/
|
|
113
|
+
clearCache(): void;
|
|
114
|
+
/**
|
|
115
|
+
* 캐시 엔트리 설정
|
|
116
|
+
*/
|
|
117
|
+
private setCacheEntry;
|
|
118
|
+
/**
|
|
119
|
+
* 캐시 엔트리 가져오기
|
|
120
|
+
*/
|
|
121
|
+
private getCacheEntry;
|
|
122
|
+
/**
|
|
123
|
+
* 번역 오류 생성
|
|
124
|
+
*/
|
|
125
|
+
private createTranslationError;
|
|
126
|
+
/**
|
|
127
|
+
* 오류 로깅
|
|
128
|
+
*/
|
|
129
|
+
private logError;
|
|
130
|
+
/**
|
|
131
|
+
* 재시도 작업
|
|
132
|
+
*/
|
|
133
|
+
private retryOperation;
|
|
134
|
+
/**
|
|
135
|
+
* 안전한 번역 로드
|
|
136
|
+
*/
|
|
137
|
+
private safeLoadTranslations;
|
|
138
|
+
/**
|
|
139
|
+
* 디버그 정보
|
|
140
|
+
*/
|
|
141
|
+
debug(): {
|
|
142
|
+
isInitialized: boolean;
|
|
143
|
+
currentLanguage: string;
|
|
144
|
+
loadedNamespaces: string[];
|
|
145
|
+
cacheStats: {
|
|
146
|
+
hits: number;
|
|
147
|
+
misses: number;
|
|
148
|
+
};
|
|
149
|
+
cacheSize: number;
|
|
150
|
+
allTranslations: Record<string, Record<string, TranslationNamespace>>;
|
|
151
|
+
initializationError: TranslationError | null;
|
|
152
|
+
config: I18nConfig;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* SSR에서 하이드레이션
|
|
156
|
+
*/
|
|
157
|
+
hydrateFromSSR(translations: Record<string, Record<string, TranslationNamespace>>): void;
|
|
158
|
+
/**
|
|
159
|
+
* 비동기 번역 (고급 기능)
|
|
160
|
+
*/
|
|
161
|
+
translateAsync(key: string, params?: Record<string, unknown>): Promise<string>;
|
|
162
|
+
/**
|
|
163
|
+
* 동기 번역 (고급 기능)
|
|
164
|
+
*/
|
|
165
|
+
translateSync(key: string, params?: Record<string, unknown>): string;
|
|
166
|
+
/**
|
|
167
|
+
* 키 파싱 (네임스페이스:키 또는 네임스페이스.키 형식 지원)
|
|
168
|
+
* 우선순위: : > . (첫 번째 구분자 사용)
|
|
169
|
+
*/
|
|
170
|
+
private parseKey;
|
|
171
|
+
/**
|
|
172
|
+
* 번역 데이터 로드 (고급 기능)
|
|
173
|
+
*/
|
|
174
|
+
private loadTranslationData;
|
|
175
|
+
/**
|
|
176
|
+
* 실제 번역 데이터 로드
|
|
177
|
+
*/
|
|
178
|
+
private _loadTranslationData;
|
|
179
|
+
}
|
|
180
|
+
export declare function ssrTranslate({ translations, key, language, fallbackLanguage, missingKeyHandler }: {
|
|
181
|
+
translations: Record<string, Record<string, TranslationNamespace>>;
|
|
182
|
+
key: string;
|
|
183
|
+
language?: string;
|
|
184
|
+
fallbackLanguage?: string;
|
|
185
|
+
missingKeyHandler?: (key: string) => string;
|
|
186
|
+
}): string;
|
|
187
|
+
export declare function serverTranslate({ translations, key, language, fallbackLanguage, missingKeyHandler, options }: {
|
|
188
|
+
translations: Record<string, unknown>;
|
|
189
|
+
key: string;
|
|
190
|
+
language?: string;
|
|
191
|
+
fallbackLanguage?: string;
|
|
192
|
+
missingKeyHandler?: (key: string) => string;
|
|
193
|
+
options?: {
|
|
194
|
+
cache?: Map<string, string>;
|
|
195
|
+
metrics?: {
|
|
196
|
+
hits: number;
|
|
197
|
+
misses: number;
|
|
198
|
+
};
|
|
199
|
+
debug?: boolean;
|
|
200
|
+
};
|
|
201
|
+
}): string;
|
|
202
|
+
//# sourceMappingURL=translator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translator.d.ts","sourceRoot":"","sources":["../../src/core/translator.tsx"],"names":[],"mappings":"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"}
|