@vircle/sdk-web 0.2.0 → 0.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/dist/index.d.ts CHANGED
@@ -1,5 +1,410 @@
1
- import { VircleCore, VircleConfig, VircleCoreOptions, EventContext, DeviceContext, PageContext, AppContext, StorageAdapter } from '@vircle/sdk-core-ts';
2
- export { AppContext, DeviceContext, EventContext, PageContext, StorageAdapter, UserProperties, VircleConfig } from '@vircle/sdk-core-ts';
1
+ import { StorageAdapter, VircleCore, VircleConfig, VircleCoreOptions, EventContext, DeviceContext, PageContext, AppContext, ExtendedCryptoAdapter, EncryptedPayload } from '@vircle/sdk-core-ts';
2
+ export { AppContext, DeviceContext, EventContext, PageContext, StorageAdapter, UserTraits, VircleConfig } from '@vircle/sdk-core-ts';
3
+
4
+ /**
5
+ * 브라우저 LocalStorage를 사용하는 스토리지 어댑터
6
+ *
7
+ * @description
8
+ * 브라우저의 LocalStorage API를 활용하여 데이터를 영구 저장합니다.
9
+ * LocalStorage를 사용할 수 없는 환경에서는 자동으로 대체 스토리지로 폴백합니다.
10
+ * 용량 초과 시 자동으로 오래된 항목을 정리하는 LRU 방식을 지원합니다.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const storage = new LocalStorageAdapter('vircle_')
15
+ * await storage.set('user_id', '12345')
16
+ * const userId = await storage.get('user_id')
17
+ * ```
18
+ */
19
+ declare class LocalStorageAdapter implements StorageAdapter {
20
+ private prefix;
21
+ private isAvailable;
22
+ constructor(prefix?: string);
23
+ /**
24
+ * LocalStorage 사용 가능 여부 확인
25
+ *
26
+ * @description
27
+ * LocalStorage API의 사용 가능 여부를 테스트합니다.
28
+ * 개인정보 보호 모드나 보안 제한으로 인해 LocalStorage가 비활성화된 경우를 감지합니다.
29
+ *
30
+ * @private
31
+ * @returns {boolean} LocalStorage 사용 가능 여부
32
+ */
33
+ private checkAvailability;
34
+ /**
35
+ * 키에 접두사 추가
36
+ *
37
+ * @description
38
+ * 키에 접두사를 추가하여 다른 애플리케이션과의 충돌을 방지합니다.
39
+ *
40
+ * @param {string} key - 원본 키
41
+ * @returns {string} 접두사가 추가된 키
42
+ * @private
43
+ */
44
+ private getKey;
45
+ /**
46
+ * 전체 키 반환 (접두사 포함)
47
+ */
48
+ private getFullKey;
49
+ /**
50
+ * 값 저장
51
+ *
52
+ * @description
53
+ * LocalStorage에 값을 저장합니다. 자동으로 타임스탬프를 추가하여 LRU 정리를 지원합니다.
54
+ * 용량 초과 시 자동으로 오래된 항목을 정리한 후 재시도합니다.
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * await storage.set('preferences', { theme: 'dark', lang: 'ko' })
59
+ * ```
60
+ *
61
+ * @template T - 저장할 값의 타입
62
+ * @param {string} key - 키
63
+ * @param {T} value - 저장할 값
64
+ * @throws {VircleStorageError} 저장 실패 시
65
+ * @returns {Promise<void>}
66
+ */
67
+ set<T = unknown>(key: string, value: T): Promise<void>;
68
+ /**
69
+ * 값 가져오기
70
+ *
71
+ * @description
72
+ * LocalStorage에서 값을 가져옵니다. 이전 버전과의 호환성을 지원합니다.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * const preferences = await storage.get<{ theme: string }>('preferences')
77
+ * if (preferences) {
78
+ * console.log(preferences.theme)
79
+ * }
80
+ * ```
81
+ *
82
+ * @template T - 반환할 값의 타입
83
+ * @param {string} key - 키
84
+ * @returns {Promise<T | null>} 저장된 값 또는 null
85
+ */
86
+ get<T = unknown>(key: string): Promise<T | null>;
87
+ /**
88
+ * 값 삭제
89
+ *
90
+ * @description
91
+ * LocalStorage에서 특정 키의 값을 삭제합니다.
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * const removed = await storage.remove('old_data')
96
+ * console.log(removed ? '삭제 성공' : '키가 존재하지 않음')
97
+ * ```
98
+ *
99
+ * @param {string} key - 키
100
+ * @returns {Promise<boolean>} 삭제 성공 여부
101
+ */
102
+ remove(key: string): Promise<boolean>;
103
+ /**
104
+ * 모든 값 삭제
105
+ *
106
+ * @description
107
+ * 현재 접두사로 시작하는 모든 키의 값을 LocalStorage에서 삭제합니다.
108
+ * 성능 최적화를 위해 모든 키를 한 번에 가져와서 필터링합니다.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * await storage.clear()
113
+ * console.log('모든 데이터 삭제 완료')
114
+ * ```
115
+ *
116
+ * @returns {Promise<void>}
117
+ */
118
+ clear(): Promise<void>;
119
+ /**
120
+ * 키 존재 여부 확인
121
+ *
122
+ * @description
123
+ * LocalStorage에 특정 키가 존재하는지 확인합니다.
124
+ *
125
+ * @example
126
+ * ```typescript
127
+ * if (await storage.has('user_preferences')) {
128
+ * const prefs = await storage.get('user_preferences')
129
+ * }
130
+ * ```
131
+ *
132
+ * @param {string} key - 키
133
+ * @returns {Promise<boolean>} 존재 여부
134
+ */
135
+ has(key: string): Promise<boolean>;
136
+ /**
137
+ * 저장된 항목 수
138
+ *
139
+ * @description
140
+ * 현재 접두사로 저장된 모든 항목의 개수를 반환합니다.
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * const count = await storage.size()
145
+ * console.log(`저장된 항목 수: ${count}`)
146
+ * ```
147
+ *
148
+ * @returns {Promise<number>} 항목 수
149
+ */
150
+ size(): Promise<number>;
151
+ /**
152
+ * 모든 키 반환
153
+ *
154
+ * @description
155
+ * 현재 접두사로 저장된 모든 키를 배열로 반환합니다.
156
+ * 접두사는 제거된 원본 키를 반환합니다.
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * const allKeys = await storage.keys()
161
+ * for (const key of allKeys) {
162
+ * console.log(`Key: ${key}`)
163
+ * }
164
+ * ```
165
+ *
166
+ * @returns {Promise<string[]>} 키 배열
167
+ */
168
+ keys(): Promise<string[]>;
169
+ /**
170
+ * 오래된 항목 정리 (LRU 방식)
171
+ *
172
+ * @description
173
+ * LocalStorage 용량이 부족할 때 가장 오래된 항목들을 삭제합니다.
174
+ * 타임스탬프를 기준으로 오래된 순으로 정렬하여 하위 20%를 삭제합니다.
175
+ *
176
+ * @private
177
+ * @returns {Promise<void>}
178
+ */
179
+ private clearOldItems;
180
+ /**
181
+ * 타임스탬프와 함께 저장 (LRU 지원)
182
+ *
183
+ * @deprecated set 메서드가 이미 타임스탬프를 포함합니다
184
+ * @param {string} key - 키
185
+ * @param {T} value - 저장할 값
186
+ * @returns {Promise<void>}
187
+ */
188
+ setWithTimestamp<T = unknown>(key: string, value: T): Promise<void>;
189
+ }
190
+
191
+ /**
192
+ * IndexedDB를 사용하는 비동기 스토리지 어댑터
193
+ *
194
+ * @description
195
+ * 브라우저의 IndexedDB API를 활용하여 대용량 데이터를 비동기적으로 저장합니다.
196
+ * LocalStorage와 달리 메인 스레드를 차단하지 않으며, 더 큰 용량을 지원합니다.
197
+ *
198
+ * @example
199
+ * ```typescript
200
+ * const storage = new IndexedDBAdapter('vircle_')
201
+ * await storage.set('user_id', '12345')
202
+ * const userId = await storage.get('user_id')
203
+ * ```
204
+ */
205
+ declare class IndexedDBAdapter implements StorageAdapter {
206
+ private db;
207
+ private readonly dbName;
208
+ private readonly storeName;
209
+ private readonly dbVersion;
210
+ private readonly prefix;
211
+ private initPromise;
212
+ private isClosed;
213
+ constructor(prefix?: string);
214
+ /**
215
+ * IndexedDB 초기화
216
+ *
217
+ * @description
218
+ * IndexedDB 연결을 초기화하고 스토어를 생성합니다.
219
+ * 여러 번 호출되어도 한 번만 초기화됩니다.
220
+ *
221
+ * @private
222
+ * @returns {Promise<void>}
223
+ */
224
+ private init;
225
+ /**
226
+ * IndexedDB 연결 열기
227
+ *
228
+ * @private
229
+ * @returns {Promise<void>}
230
+ */
231
+ private openDB;
232
+ /**
233
+ * 키에 접두사 추가
234
+ *
235
+ * @private
236
+ * @param {string} key - 원본 키
237
+ * @returns {string} 접두사가 추가된 키
238
+ */
239
+ private getKey;
240
+ /**
241
+ * 값 저장
242
+ *
243
+ * @description
244
+ * IndexedDB에 값을 비동기적으로 저장합니다.
245
+ * 메인 스레드를 차단하지 않아 성능이 향상됩니다.
246
+ *
247
+ * @template T - 저장할 값의 타입
248
+ * @param {string} key - 키
249
+ * @param {T} value - 저장할 값
250
+ * @returns {Promise<void>}
251
+ */
252
+ set<T = unknown>(key: string, value: T): Promise<void>;
253
+ /**
254
+ * 값 가져오기
255
+ *
256
+ * @description
257
+ * IndexedDB에서 값을 비동기적으로 가져옵니다.
258
+ *
259
+ * @template T - 반환할 값의 타입
260
+ * @param {string} key - 키
261
+ * @returns {Promise<T | null>} 저장된 값 또는 null
262
+ */
263
+ get<T = unknown>(key: string): Promise<T | null>;
264
+ /**
265
+ * 값 삭제
266
+ *
267
+ * @description
268
+ * IndexedDB에서 특정 키의 값을 삭제합니다.
269
+ *
270
+ * @param {string} key - 키
271
+ * @returns {Promise<boolean>} 삭제 성공 여부
272
+ */
273
+ remove(key: string): Promise<boolean>;
274
+ /**
275
+ * 모든 값 삭제
276
+ *
277
+ * @description
278
+ * 현재 접두사로 시작하는 모든 키의 값을 삭제합니다.
279
+ *
280
+ * @returns {Promise<void>}
281
+ */
282
+ clear(): Promise<void>;
283
+ /**
284
+ * 키 존재 여부 확인
285
+ *
286
+ * @param {string} key - 키
287
+ * @returns {Promise<boolean>} 존재 여부
288
+ */
289
+ has(key: string): Promise<boolean>;
290
+ /**
291
+ * 저장된 항목 수
292
+ *
293
+ * @description
294
+ * 현재 접두사로 저장된 모든 항목의 개수를 반환합니다.
295
+ *
296
+ * @returns {Promise<number>} 항목 수
297
+ */
298
+ size(): Promise<number>;
299
+ /**
300
+ * 모든 키 반환
301
+ *
302
+ * @description
303
+ * 현재 접두사로 저장된 모든 키를 배열로 반환합니다.
304
+ *
305
+ * @returns {Promise<string[]>} 키 배열
306
+ */
307
+ keys(): Promise<string[]>;
308
+ /**
309
+ * 오래된 항목 정리 (LRU 방식)
310
+ *
311
+ * @description
312
+ * 용량이 부족할 때 타임스탬프 기준으로 오래된 항목을 삭제합니다.
313
+ *
314
+ * @param {number} percentage - 삭제할 비율 (0-1)
315
+ * @returns {Promise<void>}
316
+ */
317
+ clearOldItems(percentage?: number): Promise<void>;
318
+ /**
319
+ * 연결 종료
320
+ *
321
+ * @description
322
+ * IndexedDB 연결을 명시적으로 종료합니다.
323
+ *
324
+ * @returns {Promise<void>}
325
+ */
326
+ close(): Promise<void>;
327
+ }
328
+
329
+ type StorageType = 'auto' | 'localStorage' | 'indexedDB';
330
+ /**
331
+ * 스토리지 어댑터 팩토리
332
+ *
333
+ * @description
334
+ * 환경과 요구사항에 맞는 최적의 스토리지 어댑터를 생성합니다.
335
+ * IndexedDB를 우선 사용하고, 지원하지 않으면 LocalStorage로 폴백합니다.
336
+ */
337
+ declare class StorageFactory {
338
+ /**
339
+ * 스토리지 어댑터 생성 (동기)
340
+ *
341
+ * @description
342
+ * 동기적으로 스토리지 어댑터를 생성합니다.
343
+ * 'auto' 모드에서는 API 존재 여부만 확인하고 IndexedDB를 우선 사용합니다.
344
+ * Safari Private 모드 등에서 실제 사용 불가 시 런타임 에러가 발생할 수 있습니다.
345
+ *
346
+ * @param {string} prefix - 키 접두사
347
+ * @param {StorageType} type - 스토리지 타입
348
+ * @returns {StorageAdapter} 생성된 스토리지 어댑터
349
+ */
350
+ static create(prefix?: string, type?: StorageType): StorageAdapter;
351
+ /**
352
+ * 스토리지 어댑터 생성 (비동기, 권장)
353
+ *
354
+ * @description
355
+ * 비동기적으로 스토리지 어댑터를 생성합니다.
356
+ * 'auto' 모드에서는 실제 IndexedDB 사용 가능 여부를 테스트한 후 결정합니다.
357
+ * Safari Private 모드 등에서도 안전하게 LocalStorage로 폴백됩니다.
358
+ *
359
+ * @param {string} prefix - 키 접두사
360
+ * @param {StorageType} type - 스토리지 타입
361
+ * @returns {Promise<StorageAdapter>} 생성된 스토리지 어댑터
362
+ */
363
+ static createAsync(prefix?: string, type?: StorageType): Promise<StorageAdapter>;
364
+ /**
365
+ * 자동으로 최적의 스토리지 선택 (비동기)
366
+ *
367
+ * @private
368
+ * @param {string} prefix - 키 접두사
369
+ * @returns {Promise<StorageAdapter>} 선택된 스토리지 어댑터
370
+ */
371
+ private static createAutoAsync;
372
+ /**
373
+ * 자동으로 최적의 스토리지 선택
374
+ *
375
+ * @private
376
+ * @param {string} prefix - 키 접두사
377
+ * @returns {StorageAdapter} 선택된 스토리지 어댑터
378
+ */
379
+ private static createAuto;
380
+ /**
381
+ * IndexedDB 사용 가능 여부 확인 (동기)
382
+ *
383
+ * @description
384
+ * API 존재 여부만 동기적으로 확인합니다.
385
+ * Safari Private 모드 등에서의 실제 사용 가능 여부는 IndexedDBAdapter.init()에서 확인됩니다.
386
+ *
387
+ * @private
388
+ * @returns {boolean} API 존재 여부
389
+ */
390
+ private static isIndexedDBAvailable;
391
+ /**
392
+ * IndexedDB 사용 가능 여부 확인 (비동기)
393
+ *
394
+ * @description
395
+ * 실제로 IndexedDB를 열어서 사용 가능 여부를 확인합니다.
396
+ * Safari Private 모드 등에서의 제한도 감지합니다.
397
+ *
398
+ * @returns {Promise<boolean>} 사용 가능 여부
399
+ */
400
+ static isIndexedDBAvailableAsync(): Promise<boolean>;
401
+ /**
402
+ * LocalStorage 사용 가능 여부 확인
403
+ *
404
+ * @returns {boolean} 사용 가능 여부
405
+ */
406
+ static isLocalStorageAvailable(): boolean;
407
+ }
3
408
 
4
409
  interface VircleWebConfig extends VircleConfig {
5
410
  /**
@@ -26,6 +431,23 @@ interface VircleWebConfig extends VircleConfig {
26
431
  * 커스텀 스토리지 키 접두사
27
432
  */
28
433
  storagePrefix?: string;
434
+ /**
435
+ * 스토리지 타입 선택 (기본값: 'auto')
436
+ * - 'auto': 자동으로 최적 선택 (IndexedDB 우선)
437
+ * - 'localStorage': 항상 LocalStorage 사용
438
+ * - 'indexedDB': 항상 IndexedDB 사용
439
+ */
440
+ storageType?: StorageType;
441
+ /**
442
+ * 암호화 활성화 (기본값: false)
443
+ * Web Crypto API를 사용하여 이벤트 데이터를 암호화합니다.
444
+ */
445
+ enableEncryption?: boolean;
446
+ /**
447
+ * 세션 타임아웃 (밀리초, 기본값: 30분)
448
+ * 지정된 시간 동안 비활성 상태이면 새 세션을 시작합니다.
449
+ */
450
+ sessionTimeout?: number;
29
451
  }
30
452
  interface VircleWebOptions extends Partial<VircleCoreOptions> {
31
453
  /**
@@ -36,10 +458,6 @@ interface VircleWebOptions extends Partial<VircleCoreOptions> {
36
458
  * 컨텍스트 캐싱 시간 (ms)
37
459
  */
38
460
  contextCacheTime?: number;
39
- /**
40
- * 성능 측정 활성화
41
- */
42
- enablePerformance?: boolean;
43
461
  }
44
462
  /**
45
463
  * Web 플랫폼용 Vircle SDK
@@ -59,7 +477,6 @@ declare class VircleWeb extends VircleCore {
59
477
  private contextCollector;
60
478
  private webConfig;
61
479
  private webOptions;
62
- private performanceTracker?;
63
480
  private pageViewTracked;
64
481
  private errorHandler?;
65
482
  private unhandledRejectionHandler?;
@@ -67,6 +484,11 @@ declare class VircleWeb extends VircleCore {
67
484
  private submitHandler?;
68
485
  private popstateHandler?;
69
486
  private unloadHandler?;
487
+ private visibilityChangeHandler?;
488
+ private originalPushState?;
489
+ private originalReplaceState?;
490
+ private lastActivityTime;
491
+ private sessionTimeout;
70
492
  constructor(config: VircleWebConfig, options?: VircleWebOptions);
71
493
  /**
72
494
  * SDK 초기화 및 자동 추적 설정
@@ -90,6 +512,13 @@ declare class VircleWeb extends VircleCore {
90
512
  * @returns {Promise<void>}
91
513
  */
92
514
  initialize(): Promise<void>;
515
+ /**
516
+ * 사용자 식별 (컨텍스트 캐시 무효화 포함)
517
+ *
518
+ * @description
519
+ * 사용자를 식별하고 컨텍스트 캐시를 무효화하여 이후 이벤트에 정확한 컨텍스트가 포함되도록 합니다.
520
+ */
521
+ identify<TTraits extends Record<string, unknown> = Record<string, unknown>>(userId: string, traits?: TTraits): Promise<void>;
93
522
  /**
94
523
  * 페이지뷰 추적
95
524
  *
@@ -115,7 +544,7 @@ declare class VircleWeb extends VircleCore {
115
544
  trackPageView(properties?: Record<string, unknown>, context?: EventContext): Promise<void>;
116
545
  /**
117
546
  * 웹 환경에 최적화된 이벤트 추적
118
- * AIDEV-NOTE: 이제 코어의 TaskScheduler를 사용하여 requestIdleCallback 기반의
547
+ * 이제 코어의 TaskScheduler를 사용하여 requestIdleCallback 기반의
119
548
  * 일관된 성능 최적화 구현
120
549
  */
121
550
  track<TProperties extends Record<string, unknown> = Record<string, unknown>>(name: string, properties?: TProperties, context?: EventContext): Promise<void>;
@@ -129,7 +558,7 @@ declare class VircleWeb extends VircleCore {
129
558
  * @private
130
559
  * @returns {Promise<EventContext>} 이벤트 컨텍스트
131
560
  *
132
- * AIDEV-NOTE: 컨텍스트 수집은 DOM 접근이 많아 비용이 높으므로
561
+ * 컨텍스트 수집은 DOM 접근이 많아 비용이 높으므로
133
562
  * 캐싱을 통해 성능을 최적화. 중복 수집 방지를 위한 Promise 재사용 구현
134
563
  */
135
564
  private getCachedContext;
@@ -195,6 +624,16 @@ declare class VircleWeb extends VircleCore {
195
624
  * @private
196
625
  */
197
626
  private handleRouteChange;
627
+ /**
628
+ * 세션 타임아웃 체크
629
+ *
630
+ * @description
631
+ * 마지막 활동 시간으로부터 세션 타임아웃이 경과했는지 확인합니다.
632
+ * 만료 시 새 세션을 생성하고 session_start 이벤트를 추적합니다.
633
+ *
634
+ * @private
635
+ */
636
+ private checkSessionTimeout;
198
637
  /**
199
638
  * 요소가 추적 대상인지 확인
200
639
  *
@@ -337,265 +776,62 @@ declare class WebContextCollector {
337
776
  }
338
777
 
339
778
  /**
340
- * 브라우저 LocalStorage를 사용하는 스토리지 어댑터
779
+ * Web Crypto API 기반 암호화 어댑터
341
780
  *
342
781
  * @description
343
- * 브라우저의 LocalStorage API를 활용하여 데이터를 영구 저장합니다.
344
- * LocalStorage를 사용할 없는 환경에서는 자동으로 대체 스토리지로 폴백합니다.
345
- * 용량 초과 시 자동으로 오래된 항목을 정리하는 LRU 방식을 지원합니다.
346
- *
347
- * @example
348
- * ```typescript
349
- * const storage = new LocalStorageAdapter('vircle_')
350
- * await storage.set('user_id', '12345')
351
- * const userId = await storage.get('user_id')
352
- * ```
782
+ * 브라우저의 Web Crypto API를 사용하여 하이브리드 암호화(AES-256-GCM + RSA-OAEP)를 구현합니다.
783
+ * 모든 암호화 작업은 브라우저의 네이티브 암호화 엔진을 사용하여 보안성과 성능을 보장합니다.
353
784
  */
354
- declare class LocalStorageAdapter implements StorageAdapter {
355
- private prefix;
356
- private isAvailable;
357
- constructor(prefix?: string);
358
- /**
359
- * LocalStorage 사용 가능 여부 확인
360
- *
361
- * @description
362
- * LocalStorage API의 사용 가능 여부를 테스트합니다.
363
- * 개인정보 보호 모드나 보안 제한으로 인해 LocalStorage가 비활성화된 경우를 감지합니다.
364
- *
365
- * @private
366
- * @returns {boolean} LocalStorage 사용 가능 여부
367
- */
368
- private checkAvailability;
369
- /**
370
- * 키에 접두사 추가
371
- *
372
- * @description
373
- * 키에 접두사를 추가하여 다른 애플리케이션과의 충돌을 방지합니다.
374
- *
375
- * @param {string} key - 원본 키
376
- * @returns {string} 접두사가 추가된 키
377
- * @private
378
- */
379
- private getKey;
380
- /**
381
- * 값 저장
382
- *
383
- * @description
384
- * LocalStorage에 값을 저장합니다. 자동으로 타임스탬프를 추가하여 LRU 정리를 지원합니다.
385
- * 용량 초과 시 자동으로 오래된 항목을 정리한 후 재시도합니다.
386
- *
387
- * @example
388
- * ```typescript
389
- * await storage.set('preferences', { theme: 'dark', lang: 'ko' })
390
- * ```
391
- *
392
- * @template T - 저장할 값의 타입
393
- * @param {string} key - 키
394
- * @param {T} value - 저장할 값
395
- * @throws {VircleStorageError} 저장 실패 시
396
- * @returns {Promise<void>}
397
- */
398
- set<T = unknown>(key: string, value: T): Promise<void>;
399
- /**
400
- * 값 가져오기
401
- *
402
- * @description
403
- * LocalStorage에서 값을 가져옵니다. 이전 버전과의 호환성을 지원합니다.
404
- *
405
- * @example
406
- * ```typescript
407
- * const preferences = await storage.get<{ theme: string }>('preferences')
408
- * if (preferences) {
409
- * console.log(preferences.theme)
410
- * }
411
- * ```
412
- *
413
- * @template T - 반환할 값의 타입
414
- * @param {string} key - 키
415
- * @returns {Promise<T | null>} 저장된 값 또는 null
416
- */
417
- get<T = unknown>(key: string): Promise<T | null>;
418
- /**
419
- * 값 삭제
420
- *
421
- * @description
422
- * LocalStorage에서 특정 키의 값을 삭제합니다.
423
- *
424
- * @example
425
- * ```typescript
426
- * const removed = await storage.remove('old_data')
427
- * console.log(removed ? '삭제 성공' : '키가 존재하지 않음')
428
- * ```
429
- *
430
- * @param {string} key - 키
431
- * @returns {Promise<boolean>} 삭제 성공 여부
432
- */
433
- remove(key: string): Promise<boolean>;
434
- /**
435
- * 모든 값 삭제
436
- *
437
- * @description
438
- * 현재 접두사로 시작하는 모든 키의 값을 LocalStorage에서 삭제합니다.
439
- * 성능 최적화를 위해 모든 키를 한 번에 가져와서 필터링합니다.
440
- *
441
- * @example
442
- * ```typescript
443
- * await storage.clear()
444
- * console.log('모든 데이터 삭제 완료')
445
- * ```
446
- *
447
- * @returns {Promise<void>}
448
- */
449
- clear(): Promise<void>;
450
- /**
451
- * 키 존재 여부 확인
452
- *
453
- * @description
454
- * LocalStorage에 특정 키가 존재하는지 확인합니다.
455
- *
456
- * @example
457
- * ```typescript
458
- * if (await storage.has('user_preferences')) {
459
- * const prefs = await storage.get('user_preferences')
460
- * }
461
- * ```
462
- *
463
- * @param {string} key - 키
464
- * @returns {Promise<boolean>} 존재 여부
465
- */
466
- has(key: string): Promise<boolean>;
467
- /**
468
- * 저장된 항목 수
469
- *
470
- * @description
471
- * 현재 접두사로 저장된 모든 항목의 개수를 반환합니다.
472
- *
473
- * @example
474
- * ```typescript
475
- * const count = await storage.size()
476
- * console.log(`저장된 항목 수: ${count}`)
477
- * ```
478
- *
479
- * @returns {Promise<number>} 항목 수
480
- */
481
- size(): Promise<number>;
482
- /**
483
- * 모든 키 반환
484
- *
485
- * @description
486
- * 현재 접두사로 저장된 모든 키를 배열로 반환합니다.
487
- * 접두사는 제거된 원본 키를 반환합니다.
488
- *
489
- * @example
490
- * ```typescript
491
- * const allKeys = await storage.keys()
492
- * for (const key of allKeys) {
493
- * console.log(`Key: ${key}`)
494
- * }
495
- * ```
496
- *
497
- * @returns {Promise<string[]>} 키 배열
498
- */
499
- keys(): Promise<string[]>;
500
- /**
501
- * 오래된 항목 정리 (LRU 방식)
502
- *
503
- * @description
504
- * LocalStorage 용량이 부족할 때 가장 오래된 항목들을 삭제합니다.
505
- * 타임스탬프를 기준으로 오래된 순으로 정렬하여 하위 20%를 삭제합니다.
506
- *
507
- * @private
508
- * @returns {Promise<void>}
509
- */
510
- private clearOldItems;
511
- /**
512
- * 타임스탬프와 함께 저장 (LRU 지원)
513
- *
514
- * @deprecated set 메서드가 이미 타임스탬프를 포함합니다
515
- * @param {string} key - 키
516
- * @param {T} value - 저장할 값
517
- * @returns {Promise<void>}
518
- */
519
- setWithTimestamp<T = unknown>(key: string, value: T): Promise<void>;
520
- }
521
785
 
522
786
  /**
523
- * 성능 측정 추적
787
+ * Web Crypto API를 사용하는 ExtendedCryptoAdapter 구현
524
788
  */
525
- declare class WebPerformanceTracker {
526
- private observer?;
527
- private marks;
528
- /**
529
- * 성능 추적 시작
530
- */
531
- startTracking(): void;
532
- /**
533
- * 성능 추적 중지
534
- */
535
- stopTracking(): void;
789
+ declare class WebExtendedCryptoAdapter implements ExtendedCryptoAdapter {
790
+ private crypto;
791
+ private subtle;
792
+ private available;
793
+ constructor();
536
794
  /**
537
- * Performance API 지원 여부 확인
795
+ * Web Crypto API 초기화
538
796
  */
539
- private isSupported;
797
+ private initCrypto;
540
798
  /**
541
- * Long Task 감지
799
+ * UUID v4 생성
542
800
  */
543
- private observeLongTasks;
801
+ generateUUID(): string;
544
802
  /**
545
- * Layout Shift 감지
803
+ * HMAC-SHA256 서명 생성
546
804
  */
547
- private observeLayoutShifts;
805
+ createHmacSignature(payload: any, secret: string): Promise<string>;
548
806
  /**
549
- * Largest Contentful Paint 감지
807
+ * 하이브리드 암호화 (AES-256-GCM + RSA-OAEP)
808
+ *
809
+ * @description
810
+ * 1. AES-256-GCM으로 데이터 암호화
811
+ * 2. RSA-OAEP로 AES 키 암호화
550
812
  */
551
- private observeLCP;
813
+ encryptPayload(data: Record<string, any>, publicKeyBase64: string): Promise<EncryptedPayload>;
552
814
  /**
553
- * First Input Delay 감지
815
+ * Web Crypto API 사용 가능 여부
554
816
  */
555
- private observeFID;
817
+ isAvailable(): boolean;
556
818
  /**
557
- * 커스텀 성능 마크 시작
558
- * @param name - 마크 이름
819
+ * RSA 공개키 가져오기 (PEM/Base64 → CryptoKey)
559
820
  */
560
- mark(name: string): void;
821
+ private importRsaPublicKey;
561
822
  /**
562
- * 커스텀 성능 측정
563
- * @param name - 마크 이름
564
- * @returns 측정된 시간 (ms)
823
+ * ArrayBuffer를 Base64 문자열로 변환
565
824
  */
566
- measure(name: string): number | null;
825
+ private arrayBufferToBase64;
567
826
  /**
568
- * 페이지 로드 메트릭 가져오기
827
+ * Base64 문자열을 ArrayBuffer로 변환
569
828
  */
570
- getLoadMetrics(): Record<string, number>;
829
+ private base64ToArrayBuffer;
571
830
  /**
572
- * 리소스 타이밍 데이터 가져오기
831
+ * ArrayBuffer를 Hex 문자열로 변환
573
832
  */
574
- getResourceTimings(): Array<{
575
- name: string;
576
- type: string;
577
- duration: number;
578
- size: number;
579
- }>;
833
+ private arrayBufferToHex;
580
834
  }
581
- /**
582
- * 함수 실행 시간 측정 데코레이터
583
- */
584
- declare function measurePerformance(target: unknown, propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;
585
- /**
586
- * 디바운스 유틸리티
587
- * @param func - 디바운스할 함수
588
- * @param wait - 대기 시간 (ms)
589
- * @returns 디바운스된 함수
590
- */
591
- declare function debounce<T extends (...args: unknown[]) => unknown>(func: T, wait: number): (...args: Parameters<T>) => void;
592
- /**
593
- * 쓰로틀 유틸리티
594
- * @param func - 쓰로틀할 함수
595
- * @param limit - 제한 시간 (ms)
596
- * @returns 쓰로틀된 함수
597
- */
598
- declare function throttle<T extends (...args: unknown[]) => unknown>(func: T, limit: number): (...args: Parameters<T>) => void;
599
835
 
600
836
  /**
601
837
  * Vircle Web SDK 전용 에러 클래스
@@ -697,5 +933,5 @@ declare class VircleBrowserCompatibilityError extends VircleWebError {
697
933
  constructor(message: string, details?: Record<string, any>);
698
934
  }
699
935
 
700
- export { LocalStorageAdapter, VircleBrowserCompatibilityError, VircleConfigError, VircleInitializationError, VircleStorageError, VircleWeb, VircleWebError, WebContextCollector, WebPerformanceTracker, debounce, VircleWeb as default, measurePerformance, throttle };
701
- export type { VircleWebConfig, VircleWebOptions };
936
+ export { IndexedDBAdapter, LocalStorageAdapter, StorageFactory, VircleBrowserCompatibilityError, VircleConfigError, VircleInitializationError, VircleStorageError, VircleWeb, VircleWebError, WebContextCollector, WebExtendedCryptoAdapter, VircleWeb as default };
937
+ export type { StorageType, VircleWebConfig, VircleWebOptions };