fast-map-cache 1.1.0 → 1.1.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/README.md CHANGED
@@ -13,7 +13,7 @@ A high-performance in-memory LRU cache for Node.js and browsers, implemented wit
13
13
 
14
14
  In real-world scenarios, `fast-map-cache` demonstrates significant performance gains by preventing expensive operations:
15
15
 
16
- - **🚀 Proven Performance**: Delivers a **2x to 3x** performance boost in real-world I/O and CPU-bound scenarios by preventing expensive operations.
16
+ - **🚀 Measured Benefits**: In the simulated API and CPU-bound workloads included in this repo, caching reduced end-to-end work by roughly **2x to 6x** when it could avoid expensive operations. Results depend on hit rate and workload cost.
17
17
 
18
18
  For a detailed analysis, see the full [**Performance Report**](./docs/performance-report.md).
19
19
 
@@ -99,7 +99,7 @@ For more advanced use cases, including batch operations and presets, please see
99
99
 
100
100
  ## API Reference
101
101
 
102
- The cache instance, created by `createCache` or `createCacheWithTTL`, implements the `IFastCache` interface.
102
+ The cache instance created by `createCache` implements `IFastCache`. `FastCacheWithTTL` additionally satisfies `IFastTTLCache` and exposes `cleanup()` and `destroy()`.
103
103
 
104
104
  ### `get(key: K): V | undefined`
105
105
 
@@ -125,11 +125,11 @@ Clears all items from the cache.
125
125
 
126
126
  ### `getMany(keys: K[]): Map<K, V>`
127
127
 
128
- Retrieves multiple values for an array of keys. Returns a `Map` containing the found key-value pairs.
128
+ Retrieves multiple values for an array of keys. Returns a `Map` containing the found key-value pairs. This is a convenience API, not a guaranteed performance optimization.
129
129
 
130
130
  ### `setMany(entries: [K, V][]): void`
131
131
 
132
- Adds or updates multiple key-value pairs from an array of entries.
132
+ Adds or updates multiple key-value pairs from an array of entries. This is a convenience API, not a guaranteed performance optimization.
133
133
 
134
134
  ### `size: number` (getter)
135
135
 
@@ -160,13 +160,13 @@ Manually triggers the cleanup of expired items. Returns the number of items that
160
160
 
161
161
  ### `destroy(): void` (For `FastCacheWithTTL` only)
162
162
 
163
- Clears the automatic cleanup timer if `autoCleanup` was enabled. **Crucial for graceful shutdown in Node.js.**
163
+ Clears the automatic cleanup timer if `autoCleanup` was enabled. Useful for proactively releasing timer resources in long-lived processes or tests.
164
164
 
165
165
  ## Benchmark
166
166
 
167
167
  This library is designed for high performance in real-world scenarios. The core value of a cache is not just the raw speed of its `get`/`set` operations, but its ability to prevent expensive computations or network requests.
168
168
 
169
- Our benchmarks show that in realistic I/O-bound and CPU-bound scenarios, `fast-map-cache` provides a **2x to 3x performance boost on average**. The actual improvement depends heavily on the cost of the operation being cached.
169
+ The included benchmarks show clear gains when cache hits avoid expensive work such as simulated API calls or CPU-heavy computations. Actual results depend on hit rate, cache size, and the real cost of the work being skipped.
170
170
 
171
171
  ## Contributing
172
172
 
package/README_zh-CN.md CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  在真实业务场景中,`fast-map-cache` 通过有效避免高成本操作,展现出显著的性能优势:
15
15
 
16
- - **🚀 可靠性能**: 在真实的 I/O CPU 密集型场景中,通过避免高成本操作,带来 **2-3 倍** 的性能提升。
16
+ - **🚀 可复核收益**: 在仓库自带的模拟 API CPU 密集场景里,当缓存命中能够避开昂贵操作时,端到端收益大致在 **2 6 倍**。实际效果仍取决于命中率和被缓存工作的成本。
17
17
 
18
18
  详细分析请参阅完整的 [**性能报告**](./docs/performance-report.md)。
19
19
 
@@ -99,7 +99,7 @@ cache.destroy()
99
99
 
100
100
  ## API 参考
101
101
 
102
- `createCache` `createCacheWithTTL` 创建的缓存实例均实现了 `IFastCache` 接口。
102
+ `createCache` 返回实现 `IFastCache` 的实例。`FastCacheWithTTL` 进一步满足 `IFastTTLCache`,并额外提供 `cleanup()` 和 `destroy()`。
103
103
 
104
104
  ### `get(key: K): V | undefined`
105
105
 
@@ -125,11 +125,11 @@ cache.destroy()
125
125
 
126
126
  ### `getMany(keys: K[]): Map<K, V>`
127
127
 
128
- 根据键数组批量获取值。返回一个包含已找到的键值对的 `Map`。
128
+ 根据键数组批量获取值。返回一个包含已找到的键值对的 `Map`。这是便捷 API,不保证一定比逐个调用更快。
129
129
 
130
130
  ### `setMany(entries: [K, V][]): void`
131
131
 
132
- 通过一个条目数组批量添加或更新键值对。
132
+ 通过一个条目数组批量添加或更新键值对。这是便捷 API,不保证一定比逐个调用更快。
133
133
 
134
134
  ### `size: number` (getter)
135
135
 
@@ -160,13 +160,13 @@ cache.destroy()
160
160
 
161
161
  ### `destroy(): void` (仅 `FastCacheWithTTL` 可用)
162
162
 
163
- 如果开启了 `autoCleanup`,此方法用于清除自动清理定时器。**这对于在 Node.js 中实现优雅停机至关重要。**
163
+ 如果开启了 `autoCleanup`,此方法用于清除自动清理定时器,适合在长生命周期进程或测试中主动释放资源。
164
164
 
165
165
  ## 性能基准
166
166
 
167
167
  本库为真实场景下的高性能而设计。缓存的核心价值不仅在于 `get`/`set` 操作的原始速度,更在于它能够有效避免昂贵的计算或网络请求。
168
168
 
169
- 我们的基准测试显示,在模拟真实世界的 I/O 密集和 CPU 密集场景下,`fast-map-cache` 平均能带来 **2 到 3 倍的性能提升**。实际提升效果取决于被缓存操作的成本。
169
+ 仓库内自带的 benchmark 显示:当缓存命中可以避开昂贵的 I/O CPU 计算时,收益会很明显。实际效果主要取决于命中率、缓存容量是否覆盖热点集,以及被缓存工作的真实成本。
170
170
 
171
171
  ## 贡献
172
172
 
package/dist/main.d.mts CHANGED
@@ -30,6 +30,10 @@ interface IFastCache<K extends CacheKey, V> {
30
30
  getStats(): CacheStats;
31
31
  cleanup?(): number;
32
32
  }
33
+ interface IFastTTLCache<K extends CacheKey, V> extends IFastCache<K, V> {
34
+ cleanup(): number;
35
+ destroy(): void;
36
+ }
33
37
  interface CacheNode<K extends CacheKey, V> {
34
38
  key: K;
35
39
  value: V;
@@ -81,12 +85,11 @@ declare class FastCache<K extends CacheKey, V> implements IFastCache<K, V> {
81
85
  * 以实现 O(M) 复杂度的过期项目清理(M 为过期数量)。
82
86
  *
83
87
  * @important 在 Node.js 环境下使用 `autoCleanup: true` 时,
84
- * 必须在程序退出前手动调用 `destroy()` 方法来清理定时器,
85
- * 否则定时器会阻止 Node.js 进程正常退出。
88
+ * 内部定时器在支持的运行时会调用 `unref()`,因此通常不会单独阻止进程退出。
89
+ * 如果缓存生命周期明确,仍建议调用 `destroy()` 主动清理定时器。
86
90
  */
87
- declare class FastCacheWithTTL<K extends CacheKey, V> extends FastCache<K, V> {
91
+ declare class FastCacheWithTTL<K extends CacheKey, V> extends FastCache<K, V> implements IFastTTLCache<K, V> {
88
92
  private readonly ttl;
89
- private readonly autoCleanup;
90
93
  private cleanupTimer;
91
94
  private readonly timeHead;
92
95
  private readonly timeTail;
@@ -97,15 +100,10 @@ declare class FastCacheWithTTL<K extends CacheKey, V> extends FastCache<K, V> {
97
100
  delete(key: K): boolean;
98
101
  clear(): void;
99
102
  has(key: K): boolean;
100
- get size(): number;
101
- get capacity(): number;
102
- setMany(entries: [K, V][]): void;
103
- getMany(keys: K[]): Map<K, V>;
104
103
  getStats(): CacheStats;
105
104
  cleanup(): number;
106
105
  /**
107
- * 清理定时器,防止在 Node.js 环境中进程无法正常退出。
108
- * 如果开启了 `autoCleanup`,你应当在应用关闭前调用此方法。
106
+ * 清理自动清理定时器,适合在可控生命周期中主动释放资源。
109
107
  */
110
108
  destroy(): void;
111
109
  /**
@@ -128,4 +126,4 @@ declare const CachePresets: {
128
126
  readonly tempCache: <T>(maxSize?: number, ttl?: number) => FastCacheWithTTL<string, T>;
129
127
  };
130
128
  //#endregion
131
- export { type CacheKey, type CacheNode, type CacheOptions, CachePresets, type CacheStats, FastCache, FastCacheWithTTL, type IFastCache, createCache, createCacheWithTTL };
129
+ export { type CacheKey, type CacheNode, type CacheOptions, CachePresets, type CacheStats, FastCache, FastCacheWithTTL, type IFastCache, type IFastTTLCache, createCache, createCacheWithTTL };
package/dist/main.d.ts CHANGED
@@ -30,6 +30,10 @@ interface IFastCache<K extends CacheKey, V> {
30
30
  getStats(): CacheStats;
31
31
  cleanup?(): number;
32
32
  }
33
+ interface IFastTTLCache<K extends CacheKey, V> extends IFastCache<K, V> {
34
+ cleanup(): number;
35
+ destroy(): void;
36
+ }
33
37
  interface CacheNode<K extends CacheKey, V> {
34
38
  key: K;
35
39
  value: V;
@@ -81,12 +85,11 @@ declare class FastCache<K extends CacheKey, V> implements IFastCache<K, V> {
81
85
  * 以实现 O(M) 复杂度的过期项目清理(M 为过期数量)。
82
86
  *
83
87
  * @important 在 Node.js 环境下使用 `autoCleanup: true` 时,
84
- * 必须在程序退出前手动调用 `destroy()` 方法来清理定时器,
85
- * 否则定时器会阻止 Node.js 进程正常退出。
88
+ * 内部定时器在支持的运行时会调用 `unref()`,因此通常不会单独阻止进程退出。
89
+ * 如果缓存生命周期明确,仍建议调用 `destroy()` 主动清理定时器。
86
90
  */
87
- declare class FastCacheWithTTL<K extends CacheKey, V> extends FastCache<K, V> {
91
+ declare class FastCacheWithTTL<K extends CacheKey, V> extends FastCache<K, V> implements IFastTTLCache<K, V> {
88
92
  private readonly ttl;
89
- private readonly autoCleanup;
90
93
  private cleanupTimer;
91
94
  private readonly timeHead;
92
95
  private readonly timeTail;
@@ -97,15 +100,10 @@ declare class FastCacheWithTTL<K extends CacheKey, V> extends FastCache<K, V> {
97
100
  delete(key: K): boolean;
98
101
  clear(): void;
99
102
  has(key: K): boolean;
100
- get size(): number;
101
- get capacity(): number;
102
- setMany(entries: [K, V][]): void;
103
- getMany(keys: K[]): Map<K, V>;
104
103
  getStats(): CacheStats;
105
104
  cleanup(): number;
106
105
  /**
107
- * 清理定时器,防止在 Node.js 环境中进程无法正常退出。
108
- * 如果开启了 `autoCleanup`,你应当在应用关闭前调用此方法。
106
+ * 清理自动清理定时器,适合在可控生命周期中主动释放资源。
109
107
  */
110
108
  destroy(): void;
111
109
  /**
@@ -128,4 +126,4 @@ declare const CachePresets: {
128
126
  readonly tempCache: <T>(maxSize?: number, ttl?: number) => FastCacheWithTTL<string, T>;
129
127
  };
130
128
  //#endregion
131
- export { type CacheKey, type CacheNode, type CacheOptions, CachePresets, type CacheStats, FastCache, FastCacheWithTTL, type IFastCache, createCache, createCacheWithTTL };
129
+ export { type CacheKey, type CacheNode, type CacheOptions, CachePresets, type CacheStats, FastCache, FastCacheWithTTL, type IFastCache, type IFastTTLCache, createCache, createCacheWithTTL };
package/dist/main.js CHANGED
@@ -1,102 +1,55 @@
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.80.0/node_modules/@oxc-project/runtime/src/helpers/typeof.js
29
- var require_typeof = /* @__PURE__ */ __commonJS({ "node_modules/.pnpm/@oxc-project+runtime@0.80.0/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
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0@oxc-project+runtime@0.115.0/helpers/typeof.js
3
+ function _typeof(o) {
4
+ "@babel/helpers - typeof";
5
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
6
+ return typeof o;
7
+ } : function(o) {
8
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
9
+ }, _typeof(o);
10
+ }
41
11
  //#endregion
42
- //#region node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/toPrimitive.js
43
- var require_toPrimitive = /* @__PURE__ */ __commonJS({ "node_modules/.pnpm/@oxc-project+runtime@0.80.0/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
-
12
+ //#region \0@oxc-project+runtime@0.115.0/helpers/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
+ }
58
23
  //#endregion
59
- //#region node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/toPropertyKey.js
60
- var require_toPropertyKey = /* @__PURE__ */ __commonJS({ "node_modules/.pnpm/@oxc-project+runtime@0.80.0/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
-
24
+ //#region \0@oxc-project+runtime@0.115.0/helpers/toPropertyKey.js
25
+ function toPropertyKey(t) {
26
+ var i = toPrimitive(t, "string");
27
+ return "symbol" == _typeof(i) ? i : i + "";
28
+ }
70
29
  //#endregion
71
- //#region node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/defineProperty.js
72
- var require_defineProperty = /* @__PURE__ */ __commonJS({ "node_modules/.pnpm/@oxc-project+runtime@0.80.0/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
-
30
+ //#region \0@oxc-project+runtime@0.115.0/helpers/defineProperty.js
31
+ function _defineProperty(e, r, t) {
32
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
33
+ value: t,
34
+ enumerable: !0,
35
+ configurable: !0,
36
+ writable: !0
37
+ }) : e[r] = t, e;
38
+ }
85
39
  //#endregion
86
40
  //#region src/fast-cache.ts
87
- var import_defineProperty$1 = /* @__PURE__ */ __toESM(require_defineProperty());
88
41
  /**
89
42
  * 高性能 LRU 缓存实现
90
43
  * 使用 Map + 双向链表实现 O(1) 复杂度的所有操作
91
44
  */
92
45
  var FastCache = class {
93
46
  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);
47
+ _defineProperty(this, "cache", void 0);
48
+ _defineProperty(this, "head", void 0);
49
+ _defineProperty(this, "tail", void 0);
50
+ _defineProperty(this, "maxSize", void 0);
51
+ _defineProperty(this, "hits", 0);
52
+ _defineProperty(this, "misses", 0);
100
53
  if (maxSize <= 0) throw new Error("Cache size must be positive");
101
54
  this.maxSize = maxSize;
102
55
  this.cache = /* @__PURE__ */ new Map();
@@ -109,7 +62,7 @@ var FastCache = class {
109
62
  const node = this.cache.get(key);
110
63
  if (node === void 0) {
111
64
  this.misses++;
112
- return void 0;
65
+ return;
113
66
  }
114
67
  this.moveToHead(node);
115
68
  this.hits++;
@@ -202,36 +155,33 @@ var FastCache = class {
202
155
  if (lastNode && lastNode !== this.head) this.deleteNode(lastNode);
203
156
  }
204
157
  };
205
-
206
158
  //#endregion
207
159
  //#region src/fast-cache-ttl.ts
208
- var import_defineProperty = /* @__PURE__ */ __toESM(require_defineProperty());
209
160
  /**
210
161
  * 带 TTL (Time To Live) 支持的高性能缓存实现。
211
162
  * 继承自 FastCache,并增加了一个按时间排序的独立链表,
212
163
  * 以实现 O(M) 复杂度的过期项目清理(M 为过期数量)。
213
164
  *
214
165
  * @important 在 Node.js 环境下使用 `autoCleanup: true` 时,
215
- * 必须在程序退出前手动调用 `destroy()` 方法来清理定时器,
216
- * 否则定时器会阻止 Node.js 进程正常退出。
166
+ * 内部定时器在支持的运行时会调用 `unref()`,因此通常不会单独阻止进程退出。
167
+ * 如果缓存生命周期明确,仍建议调用 `destroy()` 主动清理定时器。
217
168
  */
218
169
  var FastCacheWithTTL = class extends FastCache {
219
170
  constructor(options) {
220
171
  super(options.maxSize);
221
- (0, import_defineProperty.default)(this, "ttl", void 0);
222
- (0, import_defineProperty.default)(this, "autoCleanup", void 0);
223
- (0, import_defineProperty.default)(this, "cleanupTimer", void 0);
224
- (0, import_defineProperty.default)(this, "timeHead", void 0);
225
- (0, import_defineProperty.default)(this, "timeTail", void 0);
226
- (0, import_defineProperty.default)(this, "expired", 0);
172
+ _defineProperty(this, "ttl", void 0);
173
+ _defineProperty(this, "cleanupTimer", void 0);
174
+ _defineProperty(this, "timeHead", void 0);
175
+ _defineProperty(this, "timeTail", void 0);
176
+ _defineProperty(this, "expired", 0);
227
177
  if (options.ttl !== void 0 && options.ttl <= 0) throw new Error("TTL must be positive");
228
178
  this.ttl = options.ttl ?? 0;
229
- this.autoCleanup = options.autoCleanup ?? false;
179
+ const autoCleanup = options.autoCleanup ?? false;
230
180
  this.timeHead = {};
231
181
  this.timeTail = {};
232
182
  this.timeHead.timeNext = this.timeTail;
233
183
  this.timeTail.timePrev = this.timeHead;
234
- if (this.autoCleanup && this.ttl > 0) {
184
+ if (autoCleanup && this.ttl > 0) {
235
185
  const cleanupInterval = options.cleanupInterval ?? this.ttl;
236
186
  if (cleanupInterval <= 0) throw new Error("cleanupInterval must be positive");
237
187
  this.cleanupTimer = setInterval(() => this.cleanup(), cleanupInterval);
@@ -243,13 +193,13 @@ var FastCacheWithTTL = class extends FastCache {
243
193
  const node = this.cache.get(key);
244
194
  if (node === void 0) {
245
195
  this.misses++;
246
- return void 0;
196
+ return;
247
197
  }
248
198
  if (this.isExpired(node)) {
249
199
  this.delete(key);
250
200
  this.expired++;
251
201
  this.misses++;
252
- return void 0;
202
+ return;
253
203
  }
254
204
  return super.get(key);
255
205
  }
@@ -284,27 +234,9 @@ var FastCacheWithTTL = class extends FastCache {
284
234
  }
285
235
  return true;
286
236
  }
287
- get size() {
288
- return this.cache.size;
289
- }
290
- get capacity() {
291
- return this.maxSize;
292
- }
293
- setMany(entries) {
294
- for (const [key, value] of entries) this.set(key, value);
295
- }
296
- getMany(keys) {
297
- const result = /* @__PURE__ */ new Map();
298
- for (const key of keys) {
299
- const value = this.get(key);
300
- if (value !== void 0) result.set(key, value);
301
- }
302
- return result;
303
- }
304
237
  getStats() {
305
- const stats = super.getStats();
306
238
  return {
307
- ...stats,
239
+ ...super.getStats(),
308
240
  expired: this.expired
309
241
  };
310
242
  }
@@ -322,8 +254,7 @@ var FastCacheWithTTL = class extends FastCache {
322
254
  return removedCount;
323
255
  }
324
256
  /**
325
- * 清理定时器,防止在 Node.js 环境中进程无法正常退出。
326
- * 如果开启了 `autoCleanup`,你应当在应用关闭前调用此方法。
257
+ * 清理自动清理定时器,适合在可控生命周期中主动释放资源。
327
258
  */
328
259
  destroy() {
329
260
  if (this.cleanupTimer) {
@@ -358,7 +289,6 @@ var FastCacheWithTTL = class extends FastCache {
358
289
  this._addToTimeListTail(node);
359
290
  }
360
291
  };
361
-
362
292
  //#endregion
363
293
  //#region src/index.ts
364
294
  function createCache(maxSize) {
@@ -381,10 +311,9 @@ const CachePresets = {
381
311
  autoCleanup: true
382
312
  })
383
313
  };
384
-
385
314
  //#endregion
386
315
  exports.CachePresets = CachePresets;
387
316
  exports.FastCache = FastCache;
388
317
  exports.FastCacheWithTTL = FastCacheWithTTL;
389
318
  exports.createCache = createCache;
390
- exports.createCacheWithTTL = createCacheWithTTL;
319
+ exports.createCacheWithTTL = createCacheWithTTL;
package/dist/main.mjs CHANGED
@@ -1,15 +1,14 @@
1
- //#region node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/typeof.js
1
+ //#region \0@oxc-project+runtime@0.115.0/helpers/typeof.js
2
2
  function _typeof(o) {
3
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;
4
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
5
+ return typeof o;
6
+ } : function(o) {
7
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
8
8
  }, _typeof(o);
9
9
  }
10
-
11
10
  //#endregion
12
- //#region node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/toPrimitive.js
11
+ //#region \0@oxc-project+runtime@0.115.0/helpers/toPrimitive.js
13
12
  function toPrimitive(t, r) {
14
13
  if ("object" != _typeof(t) || !t) return t;
15
14
  var e = t[Symbol.toPrimitive];
@@ -20,16 +19,14 @@ function toPrimitive(t, r) {
20
19
  }
21
20
  return ("string" === r ? String : Number)(t);
22
21
  }
23
-
24
22
  //#endregion
25
- //#region node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/toPropertyKey.js
23
+ //#region \0@oxc-project+runtime@0.115.0/helpers/toPropertyKey.js
26
24
  function toPropertyKey(t) {
27
25
  var i = toPrimitive(t, "string");
28
26
  return "symbol" == _typeof(i) ? i : i + "";
29
27
  }
30
-
31
28
  //#endregion
32
- //#region node_modules/.pnpm/@oxc-project+runtime@0.80.0/node_modules/@oxc-project/runtime/src/helpers/esm/defineProperty.js
29
+ //#region \0@oxc-project+runtime@0.115.0/helpers/defineProperty.js
33
30
  function _defineProperty(e, r, t) {
34
31
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
35
32
  value: t,
@@ -38,7 +35,6 @@ function _defineProperty(e, r, t) {
38
35
  writable: !0
39
36
  }) : e[r] = t, e;
40
37
  }
41
-
42
38
  //#endregion
43
39
  //#region src/fast-cache.ts
44
40
  /**
@@ -65,7 +61,7 @@ var FastCache = class {
65
61
  const node = this.cache.get(key);
66
62
  if (node === void 0) {
67
63
  this.misses++;
68
- return void 0;
64
+ return;
69
65
  }
70
66
  this.moveToHead(node);
71
67
  this.hits++;
@@ -158,7 +154,6 @@ var FastCache = class {
158
154
  if (lastNode && lastNode !== this.head) this.deleteNode(lastNode);
159
155
  }
160
156
  };
161
-
162
157
  //#endregion
163
158
  //#region src/fast-cache-ttl.ts
164
159
  /**
@@ -167,26 +162,25 @@ var FastCache = class {
167
162
  * 以实现 O(M) 复杂度的过期项目清理(M 为过期数量)。
168
163
  *
169
164
  * @important 在 Node.js 环境下使用 `autoCleanup: true` 时,
170
- * 必须在程序退出前手动调用 `destroy()` 方法来清理定时器,
171
- * 否则定时器会阻止 Node.js 进程正常退出。
165
+ * 内部定时器在支持的运行时会调用 `unref()`,因此通常不会单独阻止进程退出。
166
+ * 如果缓存生命周期明确,仍建议调用 `destroy()` 主动清理定时器。
172
167
  */
173
168
  var FastCacheWithTTL = class extends FastCache {
174
169
  constructor(options) {
175
170
  super(options.maxSize);
176
171
  _defineProperty(this, "ttl", void 0);
177
- _defineProperty(this, "autoCleanup", void 0);
178
172
  _defineProperty(this, "cleanupTimer", void 0);
179
173
  _defineProperty(this, "timeHead", void 0);
180
174
  _defineProperty(this, "timeTail", void 0);
181
175
  _defineProperty(this, "expired", 0);
182
176
  if (options.ttl !== void 0 && options.ttl <= 0) throw new Error("TTL must be positive");
183
177
  this.ttl = options.ttl ?? 0;
184
- this.autoCleanup = options.autoCleanup ?? false;
178
+ const autoCleanup = options.autoCleanup ?? false;
185
179
  this.timeHead = {};
186
180
  this.timeTail = {};
187
181
  this.timeHead.timeNext = this.timeTail;
188
182
  this.timeTail.timePrev = this.timeHead;
189
- if (this.autoCleanup && this.ttl > 0) {
183
+ if (autoCleanup && this.ttl > 0) {
190
184
  const cleanupInterval = options.cleanupInterval ?? this.ttl;
191
185
  if (cleanupInterval <= 0) throw new Error("cleanupInterval must be positive");
192
186
  this.cleanupTimer = setInterval(() => this.cleanup(), cleanupInterval);
@@ -198,13 +192,13 @@ var FastCacheWithTTL = class extends FastCache {
198
192
  const node = this.cache.get(key);
199
193
  if (node === void 0) {
200
194
  this.misses++;
201
- return void 0;
195
+ return;
202
196
  }
203
197
  if (this.isExpired(node)) {
204
198
  this.delete(key);
205
199
  this.expired++;
206
200
  this.misses++;
207
- return void 0;
201
+ return;
208
202
  }
209
203
  return super.get(key);
210
204
  }
@@ -239,27 +233,9 @@ var FastCacheWithTTL = class extends FastCache {
239
233
  }
240
234
  return true;
241
235
  }
242
- get size() {
243
- return this.cache.size;
244
- }
245
- get capacity() {
246
- return this.maxSize;
247
- }
248
- setMany(entries) {
249
- for (const [key, value] of entries) this.set(key, value);
250
- }
251
- getMany(keys) {
252
- const result = /* @__PURE__ */ new Map();
253
- for (const key of keys) {
254
- const value = this.get(key);
255
- if (value !== void 0) result.set(key, value);
256
- }
257
- return result;
258
- }
259
236
  getStats() {
260
- const stats = super.getStats();
261
237
  return {
262
- ...stats,
238
+ ...super.getStats(),
263
239
  expired: this.expired
264
240
  };
265
241
  }
@@ -277,8 +253,7 @@ var FastCacheWithTTL = class extends FastCache {
277
253
  return removedCount;
278
254
  }
279
255
  /**
280
- * 清理定时器,防止在 Node.js 环境中进程无法正常退出。
281
- * 如果开启了 `autoCleanup`,你应当在应用关闭前调用此方法。
256
+ * 清理自动清理定时器,适合在可控生命周期中主动释放资源。
282
257
  */
283
258
  destroy() {
284
259
  if (this.cleanupTimer) {
@@ -313,7 +288,6 @@ var FastCacheWithTTL = class extends FastCache {
313
288
  this._addToTimeListTail(node);
314
289
  }
315
290
  };
316
-
317
291
  //#endregion
318
292
  //#region src/index.ts
319
293
  function createCache(maxSize) {
@@ -336,6 +310,5 @@ const CachePresets = {
336
310
  autoCleanup: true
337
311
  })
338
312
  };
339
-
340
313
  //#endregion
341
- export { CachePresets, FastCache, FastCacheWithTTL, createCache, createCacheWithTTL };
314
+ export { CachePresets, FastCache, FastCacheWithTTL, createCache, createCacheWithTTL };
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "fast-map-cache",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "High-performance TypeScript LRU cache (with optional TTL) for Node.js & browsers.",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
+ "type": "commonjs",
8
9
  "main": "./dist/main.js",
9
10
  "module": "./dist/main.mjs",
10
11
  "types": "./dist/main.d.ts",
@@ -20,8 +21,14 @@
20
21
  },
21
22
  "exports": {
22
23
  ".": {
23
- "import": "./dist/main.mjs",
24
- "require": "./dist/main.js"
24
+ "import": {
25
+ "types": "./dist/main.d.mts",
26
+ "default": "./dist/main.mjs"
27
+ },
28
+ "require": {
29
+ "types": "./dist/main.d.ts",
30
+ "default": "./dist/main.js"
31
+ }
25
32
  },
26
33
  "./package.json": "./package.json"
27
34
  },
@@ -44,19 +51,21 @@
44
51
  },
45
52
  "license": "MIT",
46
53
  "devDependencies": {
47
- "@changesets/cli": "^2.29.5",
48
- "@commitlint/cli": "^19.8.1",
49
- "@commitlint/config-conventional": "^19.8.1",
50
- "@vitest/coverage-v8": "^3.2.4",
51
- "lint-staged": "^16.1.2",
52
- "oxlint": "^1.2.0",
53
- "pnpm": "^10.12.2",
54
- "prettier": "^3.6.0",
54
+ "@changesets/cli": "^2.30.0",
55
+ "@commitlint/cli": "^20.4.4",
56
+ "@commitlint/config-conventional": "^20.4.4",
57
+ "@vitest/coverage-v8": "^4.1.0",
58
+ "lint-staged": "^16.3.3",
59
+ "oxlint": "^1.55.0",
60
+ "pnpm": "^10.32.1",
61
+ "prettier": "^3.8.1",
62
+ "publint": "^0.3.15",
55
63
  "simple-git-hooks": "^2.13.0",
56
- "tsdown": "^0.12.8",
57
- "tsx": "^4.20.3",
58
- "typescript": "^5.8.3",
59
- "vitest": "^3.2.4"
64
+ "tsdown": "^0.21.2",
65
+ "tsx": "^4.21.0",
66
+ "typescript": "^5.9.3",
67
+ "vite": "^8.0.0",
68
+ "vitest": "^4.1.0"
60
69
  },
61
70
  "simple-git-hooks": {
62
71
  "pre-commit": "npx lint-staged",
@@ -71,7 +80,7 @@
71
80
  },
72
81
  "repository": {
73
82
  "type": "git",
74
- "url": "https://github.com/crper/fast-map-cache.git"
83
+ "url": "git+https://github.com/crper/fast-map-cache.git"
75
84
  },
76
85
  "bugs": {
77
86
  "url": "https://github.com/crper/fast-map-cache/issues"