@spfn/core 0.2.0-beta.21 → 0.2.0-beta.23

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.
@@ -22,6 +22,15 @@ import { E as EventRouterDef, I as InferEventNames, b as InferEventPayload } fro
22
22
  * manager.destroy();
23
23
  * ```
24
24
  */
25
+ /**
26
+ * Minimal cache client interface (compatible with ioredis Redis | Cluster)
27
+ */
28
+ type CacheClient = {
29
+ set(key: string, value: string, ...args: any[]): Promise<any>;
30
+ getdel?(key: string): Promise<string | null>;
31
+ get(key: string): Promise<string | null>;
32
+ del(key: string | string[]): Promise<number>;
33
+ };
25
34
  /**
26
35
  * Stored SSE token data
27
36
  */
@@ -62,6 +71,31 @@ interface SSETokenManagerConfig {
62
71
  */
63
72
  cleanupInterval?: number;
64
73
  }
74
+ /**
75
+ * Redis/Valkey-backed token store for multi-instance deployments.
76
+ *
77
+ * Uses SET EX for automatic TTL expiry and GETDEL for atomic one-time consumption.
78
+ * No cleanup needed — Redis handles expiration automatically.
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * import { getCache } from '@spfn/core/cache';
83
+ *
84
+ * const cache = getCache();
85
+ * if (cache) {
86
+ * const store = new CacheTokenStore(cache);
87
+ * const manager = new SSETokenManager({ store });
88
+ * }
89
+ * ```
90
+ */
91
+ declare class CacheTokenStore implements SSETokenStore {
92
+ private cache;
93
+ private prefix;
94
+ constructor(cache: CacheClient);
95
+ set(token: string, data: SSEToken): Promise<void>;
96
+ consume(token: string): Promise<SSEToken | null>;
97
+ cleanup(): Promise<void>;
98
+ }
65
99
  declare class SSETokenManager {
66
100
  private store;
67
101
  private ttl;
@@ -302,4 +336,4 @@ type SSEConnectionState = 'connecting' | 'open' | 'closed' | 'error';
302
336
  */
303
337
  type SSEUnsubscribe = () => void;
304
338
 
305
- export { type SSEHandlerConfig as S, type SSEAuthConfig as a, SSETokenManager as b, type SSEToken as c, type SSETokenStore as d, type SSETokenManagerConfig as e, type SSEMessage as f, type SSEHandlerAuthConfig as g, type SSEClientConfig as h, type SSEEventHandler as i, type SSEEventHandlers as j, type SSESubscribeOptions as k, type SSEConnectionState as l, type SSEUnsubscribe as m };
339
+ export { CacheTokenStore as C, type SSEHandlerConfig as S, type SSEAuthConfig as a, SSETokenManager as b, type SSEToken as c, type SSETokenStore as d, type SSETokenManagerConfig as e, type SSEMessage as f, type SSEHandlerAuthConfig as g, type SSEClientConfig as h, type SSEEventHandler as i, type SSEEventHandlers as j, type SSESubscribeOptions as k, type SSEConnectionState as l, type SSEUnsubscribe as m };
package/docs/event.md CHANGED
@@ -307,6 +307,17 @@ if (cache)
307
307
  await userCreated.emit({ userId: '123' });
308
308
  ```
309
309
 
310
+ ### SSE Token Store
311
+
312
+ SSE 토큰 저장소도 멀티 인스턴스에서 공유되어야 합니다.
313
+ 캐시가 연결되면 `CacheTokenStore`가 **자동 사용**됩니다.
314
+
315
+ | 환경 | 토큰 저장소 | 설정 |
316
+ |------|------------|------|
317
+ | `CACHE_URL` 없음 | `InMemoryTokenStore` | 자동 |
318
+ | `CACHE_URL` 설정됨 | `CacheTokenStore` | 자동 감지 |
319
+ | 커스텀 | `SSETokenStore` 구현 | `auth.store` 옵션 |
320
+
310
321
  ## API Reference
311
322
 
312
323
  ### defineEvent(name)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spfn/core",
3
- "version": "0.2.0-beta.21",
3
+ "version": "0.2.0-beta.23",
4
4
  "description": "SPFN Framework Core - File-based routing, transactions, repository pattern",
5
5
  "type": "module",
6
6
  "exports": {