fast-map-cache 1.0.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/main.js ADDED
@@ -0,0 +1,376 @@
1
+ //#region rolldown:runtime
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 __commonJS = (cb, mod) => function() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
13
+ key = keys[i];
14
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
15
+ get: ((k) => from[k]).bind(null, key),
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
22
+ value: mod,
23
+ enumerable: true
24
+ }) : target, mod));
25
+
26
+ //#endregion
27
+
28
+ //#region node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/typeof.js
29
+ var require_typeof = __commonJS({ "node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/typeof.js"(exports, module) {
30
+ function _typeof$2(o) {
31
+ "@babel/helpers - typeof";
32
+ return module.exports = _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
33
+ return typeof o$1;
34
+ } : function(o$1) {
35
+ return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
36
+ }, module.exports.__esModule = true, module.exports["default"] = module.exports, _typeof$2(o);
37
+ }
38
+ module.exports = _typeof$2, module.exports.__esModule = true, module.exports["default"] = module.exports;
39
+ } });
40
+
41
+ //#endregion
42
+ //#region node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/toPrimitive.js
43
+ var require_toPrimitive = __commonJS({ "node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/toPrimitive.js"(exports, module) {
44
+ var _typeof$1 = require_typeof()["default"];
45
+ function toPrimitive$1(t, r) {
46
+ if ("object" != _typeof$1(t) || !t) return t;
47
+ var e = t[Symbol.toPrimitive];
48
+ if (void 0 !== e) {
49
+ var i = e.call(t, r || "default");
50
+ if ("object" != _typeof$1(i)) return i;
51
+ throw new TypeError("@@toPrimitive must return a primitive value.");
52
+ }
53
+ return ("string" === r ? String : Number)(t);
54
+ }
55
+ module.exports = toPrimitive$1, module.exports.__esModule = true, module.exports["default"] = module.exports;
56
+ } });
57
+
58
+ //#endregion
59
+ //#region node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/toPropertyKey.js
60
+ var require_toPropertyKey = __commonJS({ "node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/toPropertyKey.js"(exports, module) {
61
+ var _typeof = require_typeof()["default"];
62
+ var toPrimitive = require_toPrimitive();
63
+ function toPropertyKey$1(t) {
64
+ var i = toPrimitive(t, "string");
65
+ return "symbol" == _typeof(i) ? i : i + "";
66
+ }
67
+ module.exports = toPropertyKey$1, module.exports.__esModule = true, module.exports["default"] = module.exports;
68
+ } });
69
+
70
+ //#endregion
71
+ //#region node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/defineProperty.js
72
+ var require_defineProperty = __commonJS({ "node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/defineProperty.js"(exports, module) {
73
+ var toPropertyKey = require_toPropertyKey();
74
+ function _defineProperty$2(e, r, t) {
75
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
76
+ value: t,
77
+ enumerable: !0,
78
+ configurable: !0,
79
+ writable: !0
80
+ }) : e[r] = t, e;
81
+ }
82
+ module.exports = _defineProperty$2, module.exports.__esModule = true, module.exports["default"] = module.exports;
83
+ } });
84
+
85
+ //#endregion
86
+ //#region src/fast-cache.ts
87
+ var import_defineProperty$1 = __toESM(require_defineProperty());
88
+ /**
89
+ * 高性能 LRU 缓存实现
90
+ * 使用 Map + 双向链表实现 O(1) 复杂度的所有操作
91
+ */
92
+ var FastCache = class {
93
+ constructor(maxSize) {
94
+ (0, import_defineProperty$1.default)(this, "cache", void 0);
95
+ (0, import_defineProperty$1.default)(this, "head", void 0);
96
+ (0, import_defineProperty$1.default)(this, "tail", void 0);
97
+ (0, import_defineProperty$1.default)(this, "maxSize", void 0);
98
+ (0, import_defineProperty$1.default)(this, "hits", 0);
99
+ (0, import_defineProperty$1.default)(this, "misses", 0);
100
+ if (maxSize <= 0) throw new Error("Cache size must be positive");
101
+ this.maxSize = maxSize;
102
+ this.cache = /* @__PURE__ */ new Map();
103
+ this.head = {};
104
+ this.tail = {};
105
+ this.head.next = this.tail;
106
+ this.tail.prev = this.head;
107
+ }
108
+ get(key) {
109
+ const node = this.cache.get(key);
110
+ if (node === void 0) {
111
+ this.misses++;
112
+ return void 0;
113
+ }
114
+ this.moveToHead(node);
115
+ this.hits++;
116
+ return node.value;
117
+ }
118
+ set(key, value) {
119
+ const existingNode = this.cache.get(key);
120
+ if (existingNode !== void 0) {
121
+ existingNode.value = value;
122
+ this.moveToHead(existingNode);
123
+ return;
124
+ }
125
+ const newNode = {
126
+ key,
127
+ value,
128
+ prev: null,
129
+ next: null
130
+ };
131
+ if (this.cache.size >= this.maxSize) this.removeTail();
132
+ this.cache.set(key, newNode);
133
+ this.addToHead(newNode);
134
+ }
135
+ delete(key) {
136
+ const node = this.cache.get(key);
137
+ if (node === void 0) return false;
138
+ this.cache.delete(key);
139
+ this.removeNode(node);
140
+ return true;
141
+ }
142
+ clear() {
143
+ this.cache.clear();
144
+ this.head.next = this.tail;
145
+ this.tail.prev = this.head;
146
+ this.hits = 0;
147
+ this.misses = 0;
148
+ }
149
+ has(key) {
150
+ return this.cache.has(key);
151
+ }
152
+ get size() {
153
+ return this.cache.size;
154
+ }
155
+ get capacity() {
156
+ return this.maxSize;
157
+ }
158
+ setMany(entries) {
159
+ for (const [key, value] of entries) this.set(key, value);
160
+ }
161
+ getMany(keys) {
162
+ const result = /* @__PURE__ */ new Map();
163
+ for (const key of keys) {
164
+ const value = this.get(key);
165
+ if (value !== void 0) result.set(key, value);
166
+ }
167
+ return result;
168
+ }
169
+ getStats() {
170
+ const total = this.hits + this.misses;
171
+ return {
172
+ hits: this.hits,
173
+ misses: this.misses,
174
+ hitRate: total > 0 ? this.hits / total : 0,
175
+ size: this.size,
176
+ capacity: this.capacity
177
+ };
178
+ }
179
+ addToHead(node) {
180
+ node.prev = this.head;
181
+ node.next = this.head.next;
182
+ this.head.next.prev = node;
183
+ this.head.next = node;
184
+ }
185
+ removeNode(node) {
186
+ if (node.prev) node.prev.next = node.next;
187
+ if (node.next) node.next.prev = node.prev;
188
+ }
189
+ moveToHead(node) {
190
+ this.removeNode(node);
191
+ this.addToHead(node);
192
+ }
193
+ removeTail() {
194
+ const lastNode = this.tail.prev;
195
+ if (lastNode && lastNode !== this.head) {
196
+ this.cache.delete(lastNode.key);
197
+ this.removeNode(lastNode);
198
+ }
199
+ }
200
+ };
201
+
202
+ //#endregion
203
+ //#region src/fast-cache-ttl.ts
204
+ var import_defineProperty = __toESM(require_defineProperty());
205
+ /**
206
+ * 带 TTL (Time To Live) 支持的高性能缓存实现。
207
+ * 继承自 FastCache,并增加了一个按时间排序的独立链表,
208
+ * 以实现 O(M) 复杂度的过期项目清理(M 为过期数量)。
209
+ *
210
+ * @important 在 Node.js 环境下使用 `autoCleanup: true` 时,
211
+ * 必须在程序退出前手动调用 `destroy()` 方法来清理定时器,
212
+ * 否则定时器会阻止 Node.js 进程正常退出。
213
+ */
214
+ var FastCacheWithTTL = class extends FastCache {
215
+ constructor(options) {
216
+ super(options.maxSize);
217
+ (0, import_defineProperty.default)(this, "ttl", void 0);
218
+ (0, import_defineProperty.default)(this, "autoCleanup", void 0);
219
+ (0, import_defineProperty.default)(this, "cleanupTimer", void 0);
220
+ (0, import_defineProperty.default)(this, "timeHead", void 0);
221
+ (0, import_defineProperty.default)(this, "timeTail", void 0);
222
+ (0, import_defineProperty.default)(this, "expired", 0);
223
+ if (options.ttl !== void 0 && options.ttl <= 0) throw new Error("TTL must be positive");
224
+ this.ttl = options.ttl ?? 0;
225
+ this.autoCleanup = options.autoCleanup ?? false;
226
+ this.timeHead = {};
227
+ this.timeTail = {};
228
+ this.timeHead.timeNext = this.timeTail;
229
+ this.timeTail.timePrev = this.timeHead;
230
+ if (this.autoCleanup && this.ttl > 0) {
231
+ const cleanupInterval = options.cleanupInterval ?? this.ttl;
232
+ this.cleanupTimer = setInterval(() => this.cleanup(), cleanupInterval);
233
+ }
234
+ }
235
+ get(key) {
236
+ const node = this.cache.get(key);
237
+ if (node === void 0) {
238
+ this.misses++;
239
+ return void 0;
240
+ }
241
+ if (this.isExpired(node)) {
242
+ this.delete(key);
243
+ this.expired++;
244
+ this.misses++;
245
+ return void 0;
246
+ }
247
+ return super.get(key);
248
+ }
249
+ set(key, value) {
250
+ const existingNode = this.cache.get(key);
251
+ const now = this.ttl > 0 ? Date.now() : 0;
252
+ super.set(key, value);
253
+ const node = this.cache.get(key);
254
+ node.timestamp = now;
255
+ if (existingNode) this._moveToTimeListTail(node);
256
+ else this._addToTimeListTail(node);
257
+ }
258
+ delete(key) {
259
+ const node = this.cache.get(key);
260
+ if (node === void 0) return false;
261
+ this._removeFromTimeList(node);
262
+ return super.delete(key);
263
+ }
264
+ clear() {
265
+ super.clear();
266
+ this.timeHead.timeNext = this.timeTail;
267
+ this.timeTail.timePrev = this.timeHead;
268
+ this.expired = 0;
269
+ }
270
+ has(key) {
271
+ const node = this.cache.get(key);
272
+ if (node === void 0) return false;
273
+ if (this.isExpired(node)) {
274
+ this.delete(key);
275
+ this.expired++;
276
+ return false;
277
+ }
278
+ return true;
279
+ }
280
+ get size() {
281
+ return this.cache.size;
282
+ }
283
+ get capacity() {
284
+ return this.maxSize;
285
+ }
286
+ setMany(entries) {
287
+ for (const [key, value] of entries) this.set(key, value);
288
+ }
289
+ getMany(keys) {
290
+ const result = /* @__PURE__ */ new Map();
291
+ for (const key of keys) {
292
+ const value = this.get(key);
293
+ if (value !== void 0) result.set(key, value);
294
+ }
295
+ return result;
296
+ }
297
+ getStats() {
298
+ const stats = super.getStats();
299
+ return {
300
+ ...stats,
301
+ expired: this.expired
302
+ };
303
+ }
304
+ cleanup() {
305
+ if (this.ttl === 0) return 0;
306
+ let removedCount = 0;
307
+ const now = Date.now();
308
+ let currentNode = this.timeHead.timeNext;
309
+ while (currentNode && currentNode !== this.timeTail) if (this.isExpired(currentNode, now)) {
310
+ this.delete(currentNode.key);
311
+ removedCount++;
312
+ this.expired++;
313
+ currentNode = this.timeHead.timeNext;
314
+ } else break;
315
+ return removedCount;
316
+ }
317
+ /**
318
+ * 清理定时器,防止在 Node.js 环境中进程无法正常退出。
319
+ * 如果开启了 `autoCleanup`,你应当在应用关闭前调用此方法。
320
+ */
321
+ destroy() {
322
+ if (this.cleanupTimer) {
323
+ clearInterval(this.cleanupTimer);
324
+ this.cleanupTimer = void 0;
325
+ }
326
+ }
327
+ isExpired(node, now) {
328
+ if (this.ttl === 0 || node.timestamp === void 0) return false;
329
+ return (now ?? Date.now()) - node.timestamp > this.ttl;
330
+ }
331
+ _addToTimeListTail(node) {
332
+ const prev = this.timeTail.timePrev;
333
+ prev.timeNext = node;
334
+ node.timePrev = prev;
335
+ node.timeNext = this.timeTail;
336
+ this.timeTail.timePrev = node;
337
+ }
338
+ _removeFromTimeList(node) {
339
+ if (node.timePrev) node.timePrev.timeNext = node.timeNext ?? null;
340
+ if (node.timeNext) node.timeNext.timePrev = node.timePrev ?? null;
341
+ }
342
+ _moveToTimeListTail(node) {
343
+ this._removeFromTimeList(node);
344
+ this._addToTimeListTail(node);
345
+ }
346
+ };
347
+
348
+ //#endregion
349
+ //#region src/index.ts
350
+ function createCache(maxSize) {
351
+ return new FastCache(maxSize);
352
+ }
353
+ function createCacheWithTTL(options) {
354
+ return new FastCacheWithTTL(options);
355
+ }
356
+ const CachePresets = {
357
+ apiCache: (maxSize = 1e3) => createCache(maxSize),
358
+ computeCache: (maxSize = 500) => createCache(maxSize),
359
+ sessionCache: (maxSize = 100, ttl = 30 * 60 * 1e3) => createCacheWithTTL({
360
+ maxSize,
361
+ ttl,
362
+ autoCleanup: true
363
+ }),
364
+ tempCache: (maxSize = 200, ttl = 5 * 60 * 1e3) => createCacheWithTTL({
365
+ maxSize,
366
+ ttl,
367
+ autoCleanup: true
368
+ })
369
+ };
370
+
371
+ //#endregion
372
+ exports.CachePresets = CachePresets;
373
+ exports.FastCache = FastCache;
374
+ exports.FastCacheWithTTL = FastCacheWithTTL;
375
+ exports.createCache = createCache;
376
+ exports.createCacheWithTTL = createCacheWithTTL;
package/dist/main.mjs ADDED
@@ -0,0 +1,327 @@
1
+ //#region node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/esm/typeof.js
2
+ function _typeof(o) {
3
+ "@babel/helpers - typeof";
4
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
5
+ return typeof o$1;
6
+ } : function(o$1) {
7
+ return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
8
+ }, _typeof(o);
9
+ }
10
+
11
+ //#endregion
12
+ //#region node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/esm/toPrimitive.js
13
+ function toPrimitive(t, r) {
14
+ if ("object" != _typeof(t) || !t) return t;
15
+ var e = t[Symbol.toPrimitive];
16
+ if (void 0 !== e) {
17
+ var i = e.call(t, r || "default");
18
+ if ("object" != _typeof(i)) return i;
19
+ throw new TypeError("@@toPrimitive must return a primitive value.");
20
+ }
21
+ return ("string" === r ? String : Number)(t);
22
+ }
23
+
24
+ //#endregion
25
+ //#region node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/esm/toPropertyKey.js
26
+ function toPropertyKey(t) {
27
+ var i = toPrimitive(t, "string");
28
+ return "symbol" == _typeof(i) ? i : i + "";
29
+ }
30
+
31
+ //#endregion
32
+ //#region node_modules/.pnpm/@oxc-project+runtime@0.72.3/node_modules/@oxc-project/runtime/src/helpers/esm/defineProperty.js
33
+ function _defineProperty(e, r, t) {
34
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
35
+ value: t,
36
+ enumerable: !0,
37
+ configurable: !0,
38
+ writable: !0
39
+ }) : e[r] = t, e;
40
+ }
41
+
42
+ //#endregion
43
+ //#region src/fast-cache.ts
44
+ /**
45
+ * 高性能 LRU 缓存实现
46
+ * 使用 Map + 双向链表实现 O(1) 复杂度的所有操作
47
+ */
48
+ var FastCache = class {
49
+ constructor(maxSize) {
50
+ _defineProperty(this, "cache", void 0);
51
+ _defineProperty(this, "head", void 0);
52
+ _defineProperty(this, "tail", void 0);
53
+ _defineProperty(this, "maxSize", void 0);
54
+ _defineProperty(this, "hits", 0);
55
+ _defineProperty(this, "misses", 0);
56
+ if (maxSize <= 0) throw new Error("Cache size must be positive");
57
+ this.maxSize = maxSize;
58
+ this.cache = /* @__PURE__ */ new Map();
59
+ this.head = {};
60
+ this.tail = {};
61
+ this.head.next = this.tail;
62
+ this.tail.prev = this.head;
63
+ }
64
+ get(key) {
65
+ const node = this.cache.get(key);
66
+ if (node === void 0) {
67
+ this.misses++;
68
+ return void 0;
69
+ }
70
+ this.moveToHead(node);
71
+ this.hits++;
72
+ return node.value;
73
+ }
74
+ set(key, value) {
75
+ const existingNode = this.cache.get(key);
76
+ if (existingNode !== void 0) {
77
+ existingNode.value = value;
78
+ this.moveToHead(existingNode);
79
+ return;
80
+ }
81
+ const newNode = {
82
+ key,
83
+ value,
84
+ prev: null,
85
+ next: null
86
+ };
87
+ if (this.cache.size >= this.maxSize) this.removeTail();
88
+ this.cache.set(key, newNode);
89
+ this.addToHead(newNode);
90
+ }
91
+ delete(key) {
92
+ const node = this.cache.get(key);
93
+ if (node === void 0) return false;
94
+ this.cache.delete(key);
95
+ this.removeNode(node);
96
+ return true;
97
+ }
98
+ clear() {
99
+ this.cache.clear();
100
+ this.head.next = this.tail;
101
+ this.tail.prev = this.head;
102
+ this.hits = 0;
103
+ this.misses = 0;
104
+ }
105
+ has(key) {
106
+ return this.cache.has(key);
107
+ }
108
+ get size() {
109
+ return this.cache.size;
110
+ }
111
+ get capacity() {
112
+ return this.maxSize;
113
+ }
114
+ setMany(entries) {
115
+ for (const [key, value] of entries) this.set(key, value);
116
+ }
117
+ getMany(keys) {
118
+ const result = /* @__PURE__ */ new Map();
119
+ for (const key of keys) {
120
+ const value = this.get(key);
121
+ if (value !== void 0) result.set(key, value);
122
+ }
123
+ return result;
124
+ }
125
+ getStats() {
126
+ const total = this.hits + this.misses;
127
+ return {
128
+ hits: this.hits,
129
+ misses: this.misses,
130
+ hitRate: total > 0 ? this.hits / total : 0,
131
+ size: this.size,
132
+ capacity: this.capacity
133
+ };
134
+ }
135
+ addToHead(node) {
136
+ node.prev = this.head;
137
+ node.next = this.head.next;
138
+ this.head.next.prev = node;
139
+ this.head.next = node;
140
+ }
141
+ removeNode(node) {
142
+ if (node.prev) node.prev.next = node.next;
143
+ if (node.next) node.next.prev = node.prev;
144
+ }
145
+ moveToHead(node) {
146
+ this.removeNode(node);
147
+ this.addToHead(node);
148
+ }
149
+ removeTail() {
150
+ const lastNode = this.tail.prev;
151
+ if (lastNode && lastNode !== this.head) {
152
+ this.cache.delete(lastNode.key);
153
+ this.removeNode(lastNode);
154
+ }
155
+ }
156
+ };
157
+
158
+ //#endregion
159
+ //#region src/fast-cache-ttl.ts
160
+ /**
161
+ * 带 TTL (Time To Live) 支持的高性能缓存实现。
162
+ * 继承自 FastCache,并增加了一个按时间排序的独立链表,
163
+ * 以实现 O(M) 复杂度的过期项目清理(M 为过期数量)。
164
+ *
165
+ * @important 在 Node.js 环境下使用 `autoCleanup: true` 时,
166
+ * 必须在程序退出前手动调用 `destroy()` 方法来清理定时器,
167
+ * 否则定时器会阻止 Node.js 进程正常退出。
168
+ */
169
+ var FastCacheWithTTL = class extends FastCache {
170
+ constructor(options) {
171
+ super(options.maxSize);
172
+ _defineProperty(this, "ttl", void 0);
173
+ _defineProperty(this, "autoCleanup", void 0);
174
+ _defineProperty(this, "cleanupTimer", void 0);
175
+ _defineProperty(this, "timeHead", void 0);
176
+ _defineProperty(this, "timeTail", void 0);
177
+ _defineProperty(this, "expired", 0);
178
+ if (options.ttl !== void 0 && options.ttl <= 0) throw new Error("TTL must be positive");
179
+ this.ttl = options.ttl ?? 0;
180
+ this.autoCleanup = options.autoCleanup ?? false;
181
+ this.timeHead = {};
182
+ this.timeTail = {};
183
+ this.timeHead.timeNext = this.timeTail;
184
+ this.timeTail.timePrev = this.timeHead;
185
+ if (this.autoCleanup && this.ttl > 0) {
186
+ const cleanupInterval = options.cleanupInterval ?? this.ttl;
187
+ this.cleanupTimer = setInterval(() => this.cleanup(), cleanupInterval);
188
+ }
189
+ }
190
+ get(key) {
191
+ const node = this.cache.get(key);
192
+ if (node === void 0) {
193
+ this.misses++;
194
+ return void 0;
195
+ }
196
+ if (this.isExpired(node)) {
197
+ this.delete(key);
198
+ this.expired++;
199
+ this.misses++;
200
+ return void 0;
201
+ }
202
+ return super.get(key);
203
+ }
204
+ set(key, value) {
205
+ const existingNode = this.cache.get(key);
206
+ const now = this.ttl > 0 ? Date.now() : 0;
207
+ super.set(key, value);
208
+ const node = this.cache.get(key);
209
+ node.timestamp = now;
210
+ if (existingNode) this._moveToTimeListTail(node);
211
+ else this._addToTimeListTail(node);
212
+ }
213
+ delete(key) {
214
+ const node = this.cache.get(key);
215
+ if (node === void 0) return false;
216
+ this._removeFromTimeList(node);
217
+ return super.delete(key);
218
+ }
219
+ clear() {
220
+ super.clear();
221
+ this.timeHead.timeNext = this.timeTail;
222
+ this.timeTail.timePrev = this.timeHead;
223
+ this.expired = 0;
224
+ }
225
+ has(key) {
226
+ const node = this.cache.get(key);
227
+ if (node === void 0) return false;
228
+ if (this.isExpired(node)) {
229
+ this.delete(key);
230
+ this.expired++;
231
+ return false;
232
+ }
233
+ return true;
234
+ }
235
+ get size() {
236
+ return this.cache.size;
237
+ }
238
+ get capacity() {
239
+ return this.maxSize;
240
+ }
241
+ setMany(entries) {
242
+ for (const [key, value] of entries) this.set(key, value);
243
+ }
244
+ getMany(keys) {
245
+ const result = /* @__PURE__ */ new Map();
246
+ for (const key of keys) {
247
+ const value = this.get(key);
248
+ if (value !== void 0) result.set(key, value);
249
+ }
250
+ return result;
251
+ }
252
+ getStats() {
253
+ const stats = super.getStats();
254
+ return {
255
+ ...stats,
256
+ expired: this.expired
257
+ };
258
+ }
259
+ cleanup() {
260
+ if (this.ttl === 0) return 0;
261
+ let removedCount = 0;
262
+ const now = Date.now();
263
+ let currentNode = this.timeHead.timeNext;
264
+ while (currentNode && currentNode !== this.timeTail) if (this.isExpired(currentNode, now)) {
265
+ this.delete(currentNode.key);
266
+ removedCount++;
267
+ this.expired++;
268
+ currentNode = this.timeHead.timeNext;
269
+ } else break;
270
+ return removedCount;
271
+ }
272
+ /**
273
+ * 清理定时器,防止在 Node.js 环境中进程无法正常退出。
274
+ * 如果开启了 `autoCleanup`,你应当在应用关闭前调用此方法。
275
+ */
276
+ destroy() {
277
+ if (this.cleanupTimer) {
278
+ clearInterval(this.cleanupTimer);
279
+ this.cleanupTimer = void 0;
280
+ }
281
+ }
282
+ isExpired(node, now) {
283
+ if (this.ttl === 0 || node.timestamp === void 0) return false;
284
+ return (now ?? Date.now()) - node.timestamp > this.ttl;
285
+ }
286
+ _addToTimeListTail(node) {
287
+ const prev = this.timeTail.timePrev;
288
+ prev.timeNext = node;
289
+ node.timePrev = prev;
290
+ node.timeNext = this.timeTail;
291
+ this.timeTail.timePrev = node;
292
+ }
293
+ _removeFromTimeList(node) {
294
+ if (node.timePrev) node.timePrev.timeNext = node.timeNext ?? null;
295
+ if (node.timeNext) node.timeNext.timePrev = node.timePrev ?? null;
296
+ }
297
+ _moveToTimeListTail(node) {
298
+ this._removeFromTimeList(node);
299
+ this._addToTimeListTail(node);
300
+ }
301
+ };
302
+
303
+ //#endregion
304
+ //#region src/index.ts
305
+ function createCache(maxSize) {
306
+ return new FastCache(maxSize);
307
+ }
308
+ function createCacheWithTTL(options) {
309
+ return new FastCacheWithTTL(options);
310
+ }
311
+ const CachePresets = {
312
+ apiCache: (maxSize = 1e3) => createCache(maxSize),
313
+ computeCache: (maxSize = 500) => createCache(maxSize),
314
+ sessionCache: (maxSize = 100, ttl = 30 * 60 * 1e3) => createCacheWithTTL({
315
+ maxSize,
316
+ ttl,
317
+ autoCleanup: true
318
+ }),
319
+ tempCache: (maxSize = 200, ttl = 5 * 60 * 1e3) => createCacheWithTTL({
320
+ maxSize,
321
+ ttl,
322
+ autoCleanup: true
323
+ })
324
+ };
325
+
326
+ //#endregion
327
+ export { CachePresets, FastCache, FastCacheWithTTL, createCache, createCacheWithTTL };