@lark-apaas/cache-service 0.1.1-alpha.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.
@@ -0,0 +1,348 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+
31
+ // src/core/index.ts
32
+ var core_exports = {};
33
+ __export(core_exports, {
34
+ CACHE_ERROR_CODE_UNAVAILABLE: () => CACHE_ERROR_CODE_UNAVAILABLE,
35
+ DEFAULT_CONNECT_TIMEOUT_MS: () => DEFAULT_CONNECT_TIMEOUT_MS,
36
+ DEFAULT_SOCKET_TIMEOUT_MS: () => DEFAULT_SOCKET_TIMEOUT_MS,
37
+ TOKEN_WATCH_DEBOUNCE_MS: () => TOKEN_WATCH_DEBOUNCE_MS,
38
+ TOKEN_WATCH_INTERVAL_MS: () => TOKEN_WATCH_INTERVAL_MS,
39
+ createCacheStore: () => createCacheStore,
40
+ registerHooks: () => registerHooks
41
+ });
42
+ module.exports = __toCommonJS(core_exports);
43
+
44
+ // src/core/cache-store.ts
45
+ var import_keyv2 = __toESM(require("keyv"), 1);
46
+ var import_redis = __toESM(require("@keyv/redis"), 1);
47
+ var import_promises = require("fs/promises");
48
+ var import_node_fs = require("fs");
49
+
50
+ // src/core/const.ts
51
+ var DEFAULT_CONNECT_TIMEOUT_MS = 1e4;
52
+ var DEFAULT_SOCKET_TIMEOUT_MS = 5e3;
53
+ var TOKEN_WATCH_INTERVAL_MS = 6e5;
54
+ var TOKEN_WATCH_DEBOUNCE_MS = 300;
55
+ var CACHE_ERROR_CODE_UNAVAILABLE = "CACHE_SERVICE_UNAVAILABLE";
56
+
57
+ // src/core/hooks.ts
58
+ var import_keyv = require("keyv");
59
+ function registerHooks(keyv, observable) {
60
+ const getStart = /* @__PURE__ */ new WeakMap();
61
+ const setStart = /* @__PURE__ */ new WeakMap();
62
+ const delStart = /* @__PURE__ */ new WeakMap();
63
+ keyv.hooks.addHandler(import_keyv.KeyvHooks.PRE_GET, (data) => {
64
+ getStart.set(data, Date.now());
65
+ });
66
+ keyv.hooks.addHandler(import_keyv.KeyvHooks.POST_GET, (data) => {
67
+ const started = getStart.get(data) ?? Date.now();
68
+ const result = data.value === void 0 ? "miss" : "hit";
69
+ observable.log("debug", "cache.read", {
70
+ event: "cache.read",
71
+ cache_key: data.key,
72
+ result,
73
+ duration_ms: Date.now() - started
74
+ });
75
+ getStart.delete(data);
76
+ });
77
+ keyv.hooks.addHandler(import_keyv.KeyvHooks.PRE_SET, (data) => {
78
+ setStart.set(data, Date.now());
79
+ });
80
+ keyv.hooks.addHandler(import_keyv.KeyvHooks.POST_SET, (data) => {
81
+ const started = setStart.get(data) ?? Date.now();
82
+ observable.log("debug", "cache.write", {
83
+ event: "cache.write",
84
+ cache_key: data.key,
85
+ duration_ms: Date.now() - started
86
+ });
87
+ setStart.delete(data);
88
+ });
89
+ keyv.hooks.addHandler(import_keyv.KeyvHooks.PRE_DELETE, (data) => {
90
+ delStart.set(data, Date.now());
91
+ });
92
+ keyv.hooks.addHandler(import_keyv.KeyvHooks.POST_DELETE, (data) => {
93
+ const started = delStart.get(data) ?? Date.now();
94
+ observable.log("debug", "cache.delete", {
95
+ event: "cache.delete",
96
+ cache_key: data.key,
97
+ duration_ms: Date.now() - started
98
+ });
99
+ delStart.delete(data);
100
+ });
101
+ keyv.on("error", (err) => {
102
+ const message = err instanceof Error ? err.message : String(err);
103
+ observable.log("error", "cache.error", {
104
+ event: "cache.error",
105
+ error_code: CACHE_ERROR_CODE_UNAVAILABLE,
106
+ message
107
+ });
108
+ });
109
+ }
110
+ __name(registerHooks, "registerHooks");
111
+
112
+ // src/core/cache-store.ts
113
+ function createCacheStore(options) {
114
+ const { connectionString, connectionTokenFilePath, connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MS, socketTimeoutMs = DEFAULT_SOCKET_TIMEOUT_MS, observable, logger } = options;
115
+ const manager = new StoreManager({
116
+ connectionString,
117
+ connectionTokenFilePath,
118
+ connectTimeoutMs,
119
+ socketTimeoutMs,
120
+ observable,
121
+ logger
122
+ });
123
+ const initialStore = manager.buildStore(null);
124
+ manager.setInitialStore(initialStore);
125
+ const keyv = new import_keyv2.default({
126
+ store: initialStore,
127
+ useKeyPrefix: false,
128
+ throwOnErrors: false
129
+ });
130
+ registerHooks(keyv, observable);
131
+ manager.attach(keyv);
132
+ manager.startTokenWatcher();
133
+ return {
134
+ keyv,
135
+ dispose: /* @__PURE__ */ __name(async () => {
136
+ manager.stopTokenWatcher();
137
+ await manager.disposeCurrentStore();
138
+ }, "dispose")
139
+ };
140
+ }
141
+ __name(createCacheStore, "createCacheStore");
142
+ var StoreManager = class StoreManager2 {
143
+ static {
144
+ __name(this, "StoreManager");
145
+ }
146
+ config;
147
+ keyv = null;
148
+ currentStore = null;
149
+ currentToken = null;
150
+ currentResolvedConnectionString = null;
151
+ connectionOpPromise = null;
152
+ refreshing = false;
153
+ tokenWatchFilePath = null;
154
+ tokenWatchDebounceTimer = null;
155
+ constructor(config) {
156
+ this.config = config;
157
+ }
158
+ attach(keyv) {
159
+ this.keyv = keyv;
160
+ }
161
+ setInitialStore(store) {
162
+ this.currentStore = store;
163
+ }
164
+ /**
165
+ * 基于 connectionString + token 构造新 KeyvRedis
166
+ * 显式列出 socket 超时配置,保持默认值可读
167
+ */
168
+ buildStore(token) {
169
+ const resolvedConnectionString = this.appendTokenToConnectionString(this.config.connectionString, token);
170
+ const store = new import_redis.default({
171
+ url: resolvedConnectionString,
172
+ socket: {
173
+ connectTimeout: this.config.connectTimeoutMs,
174
+ // node-redis SocketOptions.socketTimeout:读写空闲超时
175
+ socketTimeout: this.config.socketTimeoutMs
176
+ }
177
+ }, {
178
+ // @keyv/redis 层的 connect 超时(覆盖 keyv 侧兜底)
179
+ connectionTimeout: this.config.connectTimeoutMs
180
+ });
181
+ this.currentToken = token;
182
+ this.currentResolvedConnectionString = resolvedConnectionString;
183
+ return store;
184
+ }
185
+ startTokenWatcher() {
186
+ const tokenPath = this.config.connectionTokenFilePath;
187
+ if (!tokenPath) {
188
+ return;
189
+ }
190
+ if (this.tokenWatchFilePath === tokenPath) {
191
+ return;
192
+ }
193
+ if (this.tokenWatchFilePath) {
194
+ (0, import_node_fs.unwatchFile)(this.tokenWatchFilePath);
195
+ this.tokenWatchFilePath = null;
196
+ }
197
+ (0, import_node_fs.watchFile)(tokenPath, {
198
+ interval: TOKEN_WATCH_INTERVAL_MS
199
+ }, () => {
200
+ this.scheduleTokenRefresh();
201
+ });
202
+ this.tokenWatchFilePath = tokenPath;
203
+ }
204
+ stopTokenWatcher() {
205
+ if (this.tokenWatchDebounceTimer) {
206
+ clearTimeout(this.tokenWatchDebounceTimer);
207
+ this.tokenWatchDebounceTimer = null;
208
+ }
209
+ if (this.tokenWatchFilePath) {
210
+ (0, import_node_fs.unwatchFile)(this.tokenWatchFilePath);
211
+ this.tokenWatchFilePath = null;
212
+ }
213
+ }
214
+ async disposeCurrentStore() {
215
+ await this.shutdownStoreSafely(this.currentStore);
216
+ this.currentStore = null;
217
+ }
218
+ scheduleTokenRefresh() {
219
+ if (this.tokenWatchDebounceTimer) {
220
+ clearTimeout(this.tokenWatchDebounceTimer);
221
+ }
222
+ this.tokenWatchDebounceTimer = setTimeout(() => {
223
+ void this.refreshIfTokenChanged();
224
+ }, TOKEN_WATCH_DEBOUNCE_MS);
225
+ }
226
+ async refreshIfTokenChanged() {
227
+ if (this.refreshing) {
228
+ return;
229
+ }
230
+ this.refreshing = true;
231
+ try {
232
+ await this.runWithLock(async () => {
233
+ const nextToken = await this.readTokenFromFile();
234
+ const nextResolvedConnectionString = this.appendTokenToConnectionString(this.config.connectionString, nextToken);
235
+ const sameToken = nextToken === this.currentToken;
236
+ const sameConnStr = nextResolvedConnectionString === this.currentResolvedConnectionString;
237
+ if (sameToken && sameConnStr) {
238
+ return;
239
+ }
240
+ const previousStore = this.currentStore;
241
+ const nextStore = this.buildStore(nextToken);
242
+ this.currentStore = nextStore;
243
+ if (this.keyv) {
244
+ this.keyv.store = nextStore;
245
+ }
246
+ await this.shutdownStoreSafely(previousStore);
247
+ });
248
+ } catch (err) {
249
+ this.config.logger?.error("Failed to refresh cache store from token file", err);
250
+ this.config.observable.log("error", "cache.error", {
251
+ event: "cache.error",
252
+ error_code: CACHE_ERROR_CODE_UNAVAILABLE,
253
+ message: err instanceof Error ? err.message : String(err)
254
+ });
255
+ } finally {
256
+ this.refreshing = false;
257
+ }
258
+ }
259
+ /**
260
+ * 单例锁:并发 refresh 只跑一次
261
+ */
262
+ runWithLock(operation) {
263
+ if (this.connectionOpPromise) {
264
+ return this.connectionOpPromise;
265
+ }
266
+ this.connectionOpPromise = (async () => {
267
+ try {
268
+ await operation();
269
+ } finally {
270
+ this.connectionOpPromise = null;
271
+ }
272
+ })();
273
+ return this.connectionOpPromise;
274
+ }
275
+ async readTokenFromFile() {
276
+ const tokenPath = this.config.connectionTokenFilePath;
277
+ if (!tokenPath) {
278
+ return null;
279
+ }
280
+ try {
281
+ const raw = await (0, import_promises.readFile)(tokenPath, "utf-8");
282
+ const trimmed = raw.trim();
283
+ return trimmed.length > 0 ? trimmed : null;
284
+ } catch (err) {
285
+ this.config.logger?.warn("cache-service: failed to read token file, falling back to previous token", {
286
+ tokenPath,
287
+ err
288
+ });
289
+ return null;
290
+ }
291
+ }
292
+ /**
293
+ * 追加 -c miaoda.zti_token=<token> 到 URL 的 options 参数
294
+ * 与 nestjs-datapaas 对齐
295
+ */
296
+ appendTokenToConnectionString(connectionString, token) {
297
+ if (!token) {
298
+ return connectionString;
299
+ }
300
+ let url;
301
+ try {
302
+ url = new URL(connectionString);
303
+ } catch (err) {
304
+ this.config.logger?.warn("cache-service: failed to parse connectionString, skipping token append", {
305
+ connectionString: redactConnectionString(connectionString),
306
+ err
307
+ });
308
+ return connectionString;
309
+ }
310
+ const currentOptions = url.searchParams.get("options") || "";
311
+ const optionsWithoutToken = currentOptions.replace(/(?:^|\s)-c\s+miaoda\.zti_token=[^\s]*/g, " ").replace(/\s+/g, " ").trim();
312
+ const tokenOption = `-c miaoda.zti_token=${token}`;
313
+ const nextOptions = [
314
+ optionsWithoutToken,
315
+ tokenOption
316
+ ].filter(Boolean).join(" ").trim();
317
+ url.searchParams.set("options", nextOptions);
318
+ return url.toString();
319
+ }
320
+ async shutdownStoreSafely(store) {
321
+ if (!store) {
322
+ return;
323
+ }
324
+ try {
325
+ const disconnectable = store;
326
+ if (typeof disconnectable.disconnect === "function") {
327
+ await disconnectable.disconnect();
328
+ }
329
+ } catch (err) {
330
+ this.config.logger?.error("Error shutting down previous KeyvRedis store", err);
331
+ }
332
+ }
333
+ };
334
+ function redactConnectionString(input) {
335
+ return input.replace(/(:\/\/[^:@/]*:)[^@/]*(@)/, "$1***$2");
336
+ }
337
+ __name(redactConnectionString, "redactConnectionString");
338
+ // Annotate the CommonJS export names for ESM import in node:
339
+ 0 && (module.exports = {
340
+ CACHE_ERROR_CODE_UNAVAILABLE,
341
+ DEFAULT_CONNECT_TIMEOUT_MS,
342
+ DEFAULT_SOCKET_TIMEOUT_MS,
343
+ TOKEN_WATCH_DEBOUNCE_MS,
344
+ TOKEN_WATCH_INTERVAL_MS,
345
+ createCacheStore,
346
+ registerHooks
347
+ });
348
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/index.ts","../../src/core/cache-store.ts","../../src/core/const.ts","../../src/core/hooks.ts"],"sourcesContent":["export { createCacheStore } from './cache-store';\nexport { registerHooks } from './hooks';\nexport {\n CACHE_ERROR_CODE_UNAVAILABLE,\n DEFAULT_CONNECT_TIMEOUT_MS,\n DEFAULT_SOCKET_TIMEOUT_MS,\n TOKEN_WATCH_DEBOUNCE_MS,\n TOKEN_WATCH_INTERVAL_MS,\n} from './const';\nexport type {\n CacheReadResult,\n CacheStoreHandle,\n CacheStoreOptions,\n CacheTraceEvent,\n LoggerAdapter,\n ObservableAdapter,\n} from './types';\n","import Keyv from 'keyv';\nimport KeyvRedis from '@keyv/redis';\nimport { readFile } from 'node:fs/promises';\nimport { watchFile, unwatchFile } from 'node:fs';\n\nimport type {\n CacheStoreHandle,\n CacheStoreOptions,\n LoggerAdapter,\n ObservableAdapter,\n} from './types';\nimport {\n CACHE_ERROR_CODE_UNAVAILABLE,\n DEFAULT_CONNECT_TIMEOUT_MS,\n DEFAULT_SOCKET_TIMEOUT_MS,\n TOKEN_WATCH_DEBOUNCE_MS,\n TOKEN_WATCH_INTERVAL_MS,\n} from './const';\nimport { registerHooks } from './hooks';\n\ntype AnyKeyvRedis = KeyvRedis<unknown>;\n\n/**\n * 构造一个带 hooks 上报与 token 热刷新能力的 Keyv 实例\n *\n * 关键设计:\n * - `forRoot` 只构造不握手,KeyvRedis 首次读写时才实际连接 Redis\n * - `connectionTokenFilePath` 存在时启动 watchFile 轮询 + 防抖 + 单例锁重建 store\n * - store 替换通过 `keyv.store = newStore` 完成,业务侧 DI 引用保持稳定\n */\nexport function createCacheStore(options: CacheStoreOptions): CacheStoreHandle {\n const {\n connectionString,\n connectionTokenFilePath,\n connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MS,\n socketTimeoutMs = DEFAULT_SOCKET_TIMEOUT_MS,\n observable,\n logger,\n } = options;\n\n const manager = new StoreManager({\n connectionString,\n connectionTokenFilePath,\n connectTimeoutMs,\n socketTimeoutMs,\n observable,\n logger,\n });\n\n const initialStore = manager.buildStore(null);\n manager.setInitialStore(initialStore);\n const keyv = new Keyv({\n store: initialStore,\n useKeyPrefix: false,\n throwOnErrors: false,\n });\n\n registerHooks(keyv, observable);\n manager.attach(keyv);\n manager.startTokenWatcher();\n\n return {\n keyv,\n dispose: async () => {\n manager.stopTokenWatcher();\n await manager.disposeCurrentStore();\n },\n };\n}\n\ninterface StoreManagerConfig {\n connectionString: string;\n connectionTokenFilePath?: string;\n connectTimeoutMs: number;\n socketTimeoutMs: number;\n observable: ObservableAdapter;\n logger?: LoggerAdapter;\n}\n\n/**\n * StoreManager\n *\n * 负责底层 KeyvRedis 的构造、token 热刷新、并发保护。\n * 骨架照搬 @lark-apaas/nestjs-datapaas 的 DrizzleDatabaseManager:\n * - watchFile 轮询 600 s 兜底\n * - 300 ms 防抖\n * - connectionOpPromise 单例锁\n */\nclass StoreManager {\n private keyv: Keyv | null = null;\n private currentStore: AnyKeyvRedis | null = null;\n private currentToken: string | null = null;\n private currentResolvedConnectionString: string | null = null;\n private connectionOpPromise: Promise<void> | null = null;\n private refreshing = false;\n\n private tokenWatchFilePath: string | null = null;\n private tokenWatchDebounceTimer: NodeJS.Timeout | null = null;\n\n constructor(private readonly config: StoreManagerConfig) {}\n\n attach(keyv: Keyv): void {\n this.keyv = keyv;\n }\n\n setInitialStore(store: AnyKeyvRedis): void {\n this.currentStore = store;\n }\n\n /**\n * 基于 connectionString + token 构造新 KeyvRedis\n * 显式列出 socket 超时配置,保持默认值可读\n */\n buildStore(token: string | null): AnyKeyvRedis {\n const resolvedConnectionString = this.appendTokenToConnectionString(\n this.config.connectionString,\n token,\n );\n\n // @keyv/redis v5 直接接 RedisClientOptions;socket 层配置需要下沉到 clientOptions.socket\n const store = new KeyvRedis(\n {\n url: resolvedConnectionString,\n socket: {\n connectTimeout: this.config.connectTimeoutMs,\n // node-redis SocketOptions.socketTimeout:读写空闲超时\n socketTimeout: this.config.socketTimeoutMs,\n },\n },\n {\n // @keyv/redis 层的 connect 超时(覆盖 keyv 侧兜底)\n connectionTimeout: this.config.connectTimeoutMs,\n },\n );\n\n this.currentToken = token;\n this.currentResolvedConnectionString = resolvedConnectionString;\n return store;\n }\n\n startTokenWatcher(): void {\n const tokenPath = this.config.connectionTokenFilePath;\n if (!tokenPath) {\n return;\n }\n if (this.tokenWatchFilePath === tokenPath) {\n return;\n }\n if (this.tokenWatchFilePath) {\n unwatchFile(this.tokenWatchFilePath);\n this.tokenWatchFilePath = null;\n }\n\n watchFile(tokenPath, { interval: TOKEN_WATCH_INTERVAL_MS }, () => {\n this.scheduleTokenRefresh();\n });\n this.tokenWatchFilePath = tokenPath;\n }\n\n stopTokenWatcher(): void {\n if (this.tokenWatchDebounceTimer) {\n clearTimeout(this.tokenWatchDebounceTimer);\n this.tokenWatchDebounceTimer = null;\n }\n if (this.tokenWatchFilePath) {\n unwatchFile(this.tokenWatchFilePath);\n this.tokenWatchFilePath = null;\n }\n }\n\n async disposeCurrentStore(): Promise<void> {\n await this.shutdownStoreSafely(this.currentStore);\n this.currentStore = null;\n }\n\n private scheduleTokenRefresh(): void {\n if (this.tokenWatchDebounceTimer) {\n clearTimeout(this.tokenWatchDebounceTimer);\n }\n this.tokenWatchDebounceTimer = setTimeout(() => {\n void this.refreshIfTokenChanged();\n }, TOKEN_WATCH_DEBOUNCE_MS);\n }\n\n private async refreshIfTokenChanged(): Promise<void> {\n if (this.refreshing) {\n return;\n }\n this.refreshing = true;\n try {\n await this.runWithLock(async () => {\n const nextToken = await this.readTokenFromFile();\n const nextResolvedConnectionString = this.appendTokenToConnectionString(\n this.config.connectionString,\n nextToken,\n );\n\n const sameToken = nextToken === this.currentToken;\n const sameConnStr =\n nextResolvedConnectionString === this.currentResolvedConnectionString;\n if (sameToken && sameConnStr) {\n return;\n }\n\n const previousStore = this.currentStore;\n const nextStore = this.buildStore(nextToken);\n this.currentStore = nextStore;\n\n if (this.keyv) {\n this.keyv.store = nextStore;\n }\n\n await this.shutdownStoreSafely(previousStore);\n });\n } catch (err) {\n this.config.logger?.error(\n 'Failed to refresh cache store from token file',\n err,\n );\n this.config.observable.log('error', 'cache.error', {\n event: 'cache.error',\n error_code: CACHE_ERROR_CODE_UNAVAILABLE,\n message: err instanceof Error ? err.message : String(err),\n });\n } finally {\n this.refreshing = false;\n }\n }\n\n /**\n * 单例锁:并发 refresh 只跑一次\n */\n private runWithLock(operation: () => Promise<void>): Promise<void> {\n if (this.connectionOpPromise) {\n return this.connectionOpPromise;\n }\n this.connectionOpPromise = (async () => {\n try {\n await operation();\n } finally {\n this.connectionOpPromise = null;\n }\n })();\n return this.connectionOpPromise;\n }\n\n private async readTokenFromFile(): Promise<string | null> {\n const tokenPath = this.config.connectionTokenFilePath;\n if (!tokenPath) {\n return null;\n }\n try {\n const raw = await readFile(tokenPath, 'utf-8');\n const trimmed = raw.trim();\n return trimmed.length > 0 ? trimmed : null;\n } catch (err) {\n this.config.logger?.warn(\n 'cache-service: failed to read token file, falling back to previous token',\n { tokenPath, err },\n );\n return null;\n }\n }\n\n /**\n * 追加 -c miaoda.zti_token=<token> 到 URL 的 options 参数\n * 与 nestjs-datapaas 对齐\n */\n private appendTokenToConnectionString(\n connectionString: string,\n token: string | null,\n ): string {\n if (!token) {\n return connectionString;\n }\n let url: URL;\n try {\n url = new URL(connectionString);\n } catch (err) {\n this.config.logger?.warn(\n 'cache-service: failed to parse connectionString, skipping token append',\n {\n connectionString: redactConnectionString(connectionString),\n err,\n },\n );\n return connectionString;\n }\n\n const currentOptions = url.searchParams.get('options') || '';\n const optionsWithoutToken = currentOptions\n .replace(/(?:^|\\s)-c\\s+miaoda\\.zti_token=[^\\s]*/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n const tokenOption = `-c miaoda.zti_token=${token}`;\n const nextOptions = [optionsWithoutToken, tokenOption]\n .filter(Boolean)\n .join(' ')\n .trim();\n\n url.searchParams.set('options', nextOptions);\n return url.toString();\n }\n\n private async shutdownStoreSafely(store: AnyKeyvRedis | null): Promise<void> {\n if (!store) {\n return;\n }\n try {\n const disconnectable = store as unknown as { disconnect?: () => Promise<void> };\n if (typeof disconnectable.disconnect === 'function') {\n await disconnectable.disconnect();\n }\n } catch (err) {\n this.config.logger?.error(\n 'Error shutting down previous KeyvRedis store',\n err,\n );\n }\n }\n}\n\n/**\n * 屏蔽 URL 中的 password 段,避免打 log 时泄漏凭据\n * redis://user:secret@host:6379 → redis://user:***@host:6379\n * 非法 URL 或无凭据时原样返回\n */\nfunction redactConnectionString(input: string): string {\n return input.replace(/(:\\/\\/[^:@/]*:)[^@/]*(@)/, '$1***$2');\n}\n","export const DEFAULT_CONNECT_TIMEOUT_MS = 10_000;\nexport const DEFAULT_SOCKET_TIMEOUT_MS = 5_000;\n\nexport const TOKEN_WATCH_INTERVAL_MS = 600_000;\nexport const TOKEN_WATCH_DEBOUNCE_MS = 300;\n\nexport const CACHE_ERROR_CODE_UNAVAILABLE = 'CACHE_SERVICE_UNAVAILABLE';\n","import Keyv, { KeyvHooks } from 'keyv';\nimport type { CacheReadResult, ObservableAdapter } from './types';\nimport { CACHE_ERROR_CODE_UNAVAILABLE } from './const';\n\n/**\n * 给 keyv 实例挂 hooks + error 监听,将缓存事件桥接到 Observable\n *\n * 事件契约:\n * - cache.read: cache_key / result(hit|miss) / duration_ms\n * - cache.write: cache_key / duration_ms\n * - cache.delete: cache_key / duration_ms\n * - cache.error: error_code / message\n */\nexport function registerHooks(keyv: Keyv, observable: ObservableAdapter): void {\n const getStart = new WeakMap<object, number>();\n const setStart = new WeakMap<object, number>();\n const delStart = new WeakMap<object, number>();\n\n keyv.hooks.addHandler(KeyvHooks.PRE_GET, (data: { key: string }) => {\n getStart.set(data, Date.now());\n });\n\n keyv.hooks.addHandler(KeyvHooks.POST_GET, (data: { key: string; value: unknown }) => {\n const started = getStart.get(data) ?? Date.now();\n const result: CacheReadResult = data.value === undefined ? 'miss' : 'hit';\n observable.log('debug', 'cache.read', {\n event: 'cache.read',\n cache_key: data.key,\n result,\n duration_ms: Date.now() - started,\n });\n getStart.delete(data);\n });\n\n keyv.hooks.addHandler(KeyvHooks.PRE_SET, (data: { key: string; value: unknown; ttl?: number }) => {\n setStart.set(data, Date.now());\n });\n\n keyv.hooks.addHandler(KeyvHooks.POST_SET, (data: { key: string; value: unknown; ttl?: number }) => {\n const started = setStart.get(data) ?? Date.now();\n observable.log('debug', 'cache.write', {\n event: 'cache.write',\n cache_key: data.key,\n duration_ms: Date.now() - started,\n });\n setStart.delete(data);\n });\n\n keyv.hooks.addHandler(KeyvHooks.PRE_DELETE, (data: { key: string }) => {\n delStart.set(data, Date.now());\n });\n\n keyv.hooks.addHandler(KeyvHooks.POST_DELETE, (data: { key: string; value: unknown }) => {\n const started = delStart.get(data) ?? Date.now();\n observable.log('debug', 'cache.delete', {\n event: 'cache.delete',\n cache_key: data.key,\n duration_ms: Date.now() - started,\n });\n delStart.delete(data);\n });\n\n keyv.on('error', (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n observable.log('error', 'cache.error', {\n event: 'cache.error',\n error_code: CACHE_ERROR_CODE_UNAVAILABLE,\n message,\n });\n });\n}\n"],"mappings":"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","names":["import_keyv","DEFAULT_CONNECT_TIMEOUT_MS","DEFAULT_SOCKET_TIMEOUT_MS","TOKEN_WATCH_INTERVAL_MS","TOKEN_WATCH_DEBOUNCE_MS","CACHE_ERROR_CODE_UNAVAILABLE","registerHooks","keyv","observable","getStart","WeakMap","setStart","delStart","hooks","addHandler","KeyvHooks","PRE_GET","data","set","Date","now","POST_GET","started","get","result","value","undefined","log","event","cache_key","key","duration_ms","delete","PRE_SET","POST_SET","PRE_DELETE","POST_DELETE","on","err","message","Error","String","error_code","CACHE_ERROR_CODE_UNAVAILABLE","createCacheStore","options","connectionString","connectionTokenFilePath","connectTimeoutMs","DEFAULT_CONNECT_TIMEOUT_MS","socketTimeoutMs","DEFAULT_SOCKET_TIMEOUT_MS","observable","logger","manager","StoreManager","initialStore","buildStore","setInitialStore","keyv","Keyv","store","useKeyPrefix","throwOnErrors","registerHooks","attach","startTokenWatcher","dispose","stopTokenWatcher","disposeCurrentStore","currentStore","currentToken","currentResolvedConnectionString","connectionOpPromise","refreshing","tokenWatchFilePath","tokenWatchDebounceTimer","config","token","resolvedConnectionString","appendTokenToConnectionString","KeyvRedis","url","socket","connectTimeout","socketTimeout","connectionTimeout","tokenPath","unwatchFile","watchFile","interval","TOKEN_WATCH_INTERVAL_MS","scheduleTokenRefresh","clearTimeout","shutdownStoreSafely","setTimeout","refreshIfTokenChanged","TOKEN_WATCH_DEBOUNCE_MS","runWithLock","nextToken","readTokenFromFile","nextResolvedConnectionString","sameToken","sameConnStr","previousStore","nextStore","err","error","log","event","error_code","CACHE_ERROR_CODE_UNAVAILABLE","message","Error","String","operation","raw","readFile","trimmed","trim","length","warn","URL","redactConnectionString","currentOptions","searchParams","get","optionsWithoutToken","replace","tokenOption","nextOptions","filter","Boolean","join","set","toString","disconnectable","disconnect","input"]}
@@ -0,0 +1,32 @@
1
+ import { C as CacheStoreOptions, a as CacheStoreHandle, O as ObservableAdapter } from '../types-CFj87Od0.cjs';
2
+ export { b as CacheReadResult, c as CacheTraceEvent, L as LoggerAdapter } from '../types-CFj87Od0.cjs';
3
+ import Keyv from 'keyv';
4
+
5
+ /**
6
+ * 构造一个带 hooks 上报与 token 热刷新能力的 Keyv 实例
7
+ *
8
+ * 关键设计:
9
+ * - `forRoot` 只构造不握手,KeyvRedis 首次读写时才实际连接 Redis
10
+ * - `connectionTokenFilePath` 存在时启动 watchFile 轮询 + 防抖 + 单例锁重建 store
11
+ * - store 替换通过 `keyv.store = newStore` 完成,业务侧 DI 引用保持稳定
12
+ */
13
+ declare function createCacheStore(options: CacheStoreOptions): CacheStoreHandle;
14
+
15
+ /**
16
+ * 给 keyv 实例挂 hooks + error 监听,将缓存事件桥接到 Observable
17
+ *
18
+ * 事件契约:
19
+ * - cache.read: cache_key / result(hit|miss) / duration_ms
20
+ * - cache.write: cache_key / duration_ms
21
+ * - cache.delete: cache_key / duration_ms
22
+ * - cache.error: error_code / message
23
+ */
24
+ declare function registerHooks(keyv: Keyv, observable: ObservableAdapter): void;
25
+
26
+ declare const DEFAULT_CONNECT_TIMEOUT_MS = 10000;
27
+ declare const DEFAULT_SOCKET_TIMEOUT_MS = 5000;
28
+ declare const TOKEN_WATCH_INTERVAL_MS = 600000;
29
+ declare const TOKEN_WATCH_DEBOUNCE_MS = 300;
30
+ declare const CACHE_ERROR_CODE_UNAVAILABLE = "CACHE_SERVICE_UNAVAILABLE";
31
+
32
+ export { CACHE_ERROR_CODE_UNAVAILABLE, CacheStoreHandle, CacheStoreOptions, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_SOCKET_TIMEOUT_MS, ObservableAdapter, TOKEN_WATCH_DEBOUNCE_MS, TOKEN_WATCH_INTERVAL_MS, createCacheStore, registerHooks };
@@ -0,0 +1,32 @@
1
+ import { C as CacheStoreOptions, a as CacheStoreHandle, O as ObservableAdapter } from '../types-CFj87Od0.js';
2
+ export { b as CacheReadResult, c as CacheTraceEvent, L as LoggerAdapter } from '../types-CFj87Od0.js';
3
+ import Keyv from 'keyv';
4
+
5
+ /**
6
+ * 构造一个带 hooks 上报与 token 热刷新能力的 Keyv 实例
7
+ *
8
+ * 关键设计:
9
+ * - `forRoot` 只构造不握手,KeyvRedis 首次读写时才实际连接 Redis
10
+ * - `connectionTokenFilePath` 存在时启动 watchFile 轮询 + 防抖 + 单例锁重建 store
11
+ * - store 替换通过 `keyv.store = newStore` 完成,业务侧 DI 引用保持稳定
12
+ */
13
+ declare function createCacheStore(options: CacheStoreOptions): CacheStoreHandle;
14
+
15
+ /**
16
+ * 给 keyv 实例挂 hooks + error 监听,将缓存事件桥接到 Observable
17
+ *
18
+ * 事件契约:
19
+ * - cache.read: cache_key / result(hit|miss) / duration_ms
20
+ * - cache.write: cache_key / duration_ms
21
+ * - cache.delete: cache_key / duration_ms
22
+ * - cache.error: error_code / message
23
+ */
24
+ declare function registerHooks(keyv: Keyv, observable: ObservableAdapter): void;
25
+
26
+ declare const DEFAULT_CONNECT_TIMEOUT_MS = 10000;
27
+ declare const DEFAULT_SOCKET_TIMEOUT_MS = 5000;
28
+ declare const TOKEN_WATCH_INTERVAL_MS = 600000;
29
+ declare const TOKEN_WATCH_DEBOUNCE_MS = 300;
30
+ declare const CACHE_ERROR_CODE_UNAVAILABLE = "CACHE_SERVICE_UNAVAILABLE";
31
+
32
+ export { CACHE_ERROR_CODE_UNAVAILABLE, CacheStoreHandle, CacheStoreOptions, DEFAULT_CONNECT_TIMEOUT_MS, DEFAULT_SOCKET_TIMEOUT_MS, ObservableAdapter, TOKEN_WATCH_DEBOUNCE_MS, TOKEN_WATCH_INTERVAL_MS, createCacheStore, registerHooks };
@@ -0,0 +1,19 @@
1
+ import {
2
+ CACHE_ERROR_CODE_UNAVAILABLE,
3
+ DEFAULT_CONNECT_TIMEOUT_MS,
4
+ DEFAULT_SOCKET_TIMEOUT_MS,
5
+ TOKEN_WATCH_DEBOUNCE_MS,
6
+ TOKEN_WATCH_INTERVAL_MS,
7
+ createCacheStore,
8
+ registerHooks
9
+ } from "../chunk-BSJRPCEN.js";
10
+ export {
11
+ CACHE_ERROR_CODE_UNAVAILABLE,
12
+ DEFAULT_CONNECT_TIMEOUT_MS,
13
+ DEFAULT_SOCKET_TIMEOUT_MS,
14
+ TOKEN_WATCH_DEBOUNCE_MS,
15
+ TOKEN_WATCH_INTERVAL_MS,
16
+ createCacheStore,
17
+ registerHooks
18
+ };
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}