fast-ttl-cache 0.1.2 → 0.1.4

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
@@ -20,17 +20,21 @@ import FastTTLCache from 'fast-ttl-cache';
20
20
  const cache = new FastTTLCache({
21
21
  ttl: 5 * 1000, // ttl in millseconds, get an outdated data will return null and delete it
22
22
  capacity: 1000, // max capacity, When the capacity is exceeded, the least recently updated data will be removed.
23
+ cloneLevel: 0, // 0 (no clone), 1 (shallow clone), 2 (deep clone), defaults to 0
23
24
  });
24
25
 
25
26
  cache.put('key1', 'value1');
26
27
  cache.put('key2', 'value2');
27
- cache.get('key2'); // return value2
28
+ cache.put('key3', 'value3');
29
+ console.log(cache.get('key2')); // return value2
28
30
 
29
31
  // wait for 5 seconds
32
+ await new Promise(resolve => setTimeout(resolve, 5000));
33
+
30
34
  cache.get('key1'); // return null and key1 will be removed
31
- cache.size; // return 1, key2 is outdated but is not been removed yet
35
+ cache.size; // return 2, key2 & key3 are outdated but are not been removed yet
32
36
 
33
- cache.get('key2'); // return null and key2 will be removed
37
+ cache.get('key3'); // return null and key2 & key3 will be removed
34
38
  cache.size; // return 0
35
39
  ```
36
40
 
@@ -39,6 +43,7 @@ cache.size; // return 0
39
43
 
40
44
  - ```options.ttl```: number of millseconds, defaults to Infinity
41
45
  - ```options.capacity```: number of max capacity, defaults to Infinity
46
+ - ```options.cloneLevel```: number of clone level, defaults to 0 (no clone), 1 (shallow clone), 2 (deep clone)
42
47
 
43
48
  ```FastTTLCache.prototype.put(key, value)```
44
49
 
@@ -47,6 +52,9 @@ cache.size; // return 0
47
52
  ```FastTTLCache.prototype.get(key)```
48
53
 
49
54
  - Get the value of the key from cache, return null if the key is not exists or has been expired.
55
+ - if cloneLevel is 0, return the original data
56
+ - if cloneLevel is 1, return the shallow cloned data
57
+ - if cloneLevel is 2, return the deep cloned data
50
58
 
51
59
  ```FastTTLCache.prototype.size```
52
60
 
package/dist/index.d.mts CHANGED
@@ -12,36 +12,41 @@ declare class FastTTLCache {
12
12
  /** 存储缓存项的Map */
13
13
  private store;
14
14
  /** 链表头部指针,指向最久未更新的节点 */
15
- head: CacheItem | null;
15
+ head: CacheItem;
16
16
  /** 链表尾部指针,指向最新更新的节点 */
17
- tail: CacheItem | null;
17
+ tail: CacheItem;
18
18
  /** 缓存大小 */
19
19
  size: number;
20
+ /** 数据 clone 方法 */
21
+ private cloneMethod;
20
22
  /**
21
23
  * 构造函数
22
- * @param options 配置选项,包含ttl(过期时间)和capacity(容量)
24
+ * @param {CacheOptions} options 配置选项,包含ttl(过期时间)和capacity(容量)
23
25
  */
24
26
  constructor(options?: CacheOptions);
25
27
  /**
26
28
  * 获取缓存,惰性删除
27
- * @param key 缓存键
29
+ * @param {string} key 缓存键
28
30
  * @returns 如果缓存存在且未过期返回值,否则返回null
29
31
  */
30
- get(key: string): any | null;
32
+ get(key: string): any;
31
33
  /**
32
34
  * 设置缓存,包含已存在或新增
33
- * @param key 缓存键
34
- * @param value 缓存值
35
+ * @param {string} key 缓存键
36
+ * @param {any} value 缓存值
35
37
  */
36
38
  put(key: string, value: any): void;
37
39
  /**
38
40
  * 移除节点
39
- * @param item CacheItem
41
+ * @param {CacheItem} item
42
+ * @param {boolean} [isExpire = false] 是否为过期删除
43
+ * @returns {boolean} 是否删除成功
40
44
  */
41
45
  private del;
42
46
  /**
43
47
  * 将节点移动到队尾,队尾的节点一定是最后一个更新的
44
- * @param item CacheItem
48
+ * @param {CacheItem} item
49
+ * @returns void
45
50
  */
46
51
  private moveToTail;
47
52
  }
package/dist/index.d.ts CHANGED
@@ -12,36 +12,41 @@ declare class FastTTLCache {
12
12
  /** 存储缓存项的Map */
13
13
  private store;
14
14
  /** 链表头部指针,指向最久未更新的节点 */
15
- head: CacheItem | null;
15
+ head: CacheItem;
16
16
  /** 链表尾部指针,指向最新更新的节点 */
17
- tail: CacheItem | null;
17
+ tail: CacheItem;
18
18
  /** 缓存大小 */
19
19
  size: number;
20
+ /** 数据 clone 方法 */
21
+ private cloneMethod;
20
22
  /**
21
23
  * 构造函数
22
- * @param options 配置选项,包含ttl(过期时间)和capacity(容量)
24
+ * @param {CacheOptions} options 配置选项,包含ttl(过期时间)和capacity(容量)
23
25
  */
24
26
  constructor(options?: CacheOptions);
25
27
  /**
26
28
  * 获取缓存,惰性删除
27
- * @param key 缓存键
29
+ * @param {string} key 缓存键
28
30
  * @returns 如果缓存存在且未过期返回值,否则返回null
29
31
  */
30
- get(key: string): any | null;
32
+ get(key: string): any;
31
33
  /**
32
34
  * 设置缓存,包含已存在或新增
33
- * @param key 缓存键
34
- * @param value 缓存值
35
+ * @param {string} key 缓存键
36
+ * @param {any} value 缓存值
35
37
  */
36
38
  put(key: string, value: any): void;
37
39
  /**
38
40
  * 移除节点
39
- * @param item CacheItem
41
+ * @param {CacheItem} item
42
+ * @param {boolean} [isExpire = false] 是否为过期删除
43
+ * @returns {boolean} 是否删除成功
40
44
  */
41
45
  private del;
42
46
  /**
43
47
  * 将节点移动到队尾,队尾的节点一定是最后一个更新的
44
- * @param item CacheItem
48
+ * @param {CacheItem} item
49
+ * @returns void
45
50
  */
46
51
  private moveToTail;
47
52
  }
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
4
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
7
  var __export = (target, all) => {
6
8
  for (var name in all)
@@ -14,6 +16,14 @@ var __copyProps = (to, from, except, desc) => {
14
16
  }
15
17
  return to;
16
18
  };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
17
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
28
 
19
29
  // src/index.ts
@@ -22,10 +32,19 @@ __export(index_exports, {
22
32
  default: () => FastTTLCache
23
33
  });
24
34
  module.exports = __toCommonJS(index_exports);
35
+ var import_lodash = __toESM(require("lodash.clonedeep"));
36
+ var import_lodash2 = __toESM(require("lodash.clone"));
37
+ var pure = (i) => i;
38
+ var NO_CLONE = 0;
39
+ var SHALLOW_CLONE = 1;
40
+ var DEEP_CLONE = 2;
41
+ function getCloneMethod(cloneLevel = NO_CLONE) {
42
+ return cloneLevel === DEEP_CLONE ? import_lodash.default : cloneLevel === SHALLOW_CLONE ? import_lodash2.default : pure;
43
+ }
25
44
  var FastTTLCache = class {
26
45
  /**
27
46
  * 构造函数
28
- * @param options 配置选项,包含ttl(过期时间)和capacity(容量)
47
+ * @param {CacheOptions} options 配置选项,包含ttl(过期时间)和capacity(容量)
29
48
  */
30
49
  constructor(options = {}) {
31
50
  /** 存储缓存项的Map */
@@ -36,8 +55,11 @@ var FastTTLCache = class {
36
55
  this.tail = null;
37
56
  /** 缓存大小 */
38
57
  this.size = 0;
58
+ /** 数据 clone 方法 */
59
+ this.cloneMethod = pure;
39
60
  this.ttl = options.ttl || Infinity;
40
61
  this.capacity = options.capacity || Infinity;
62
+ this.cloneMethod = getCloneMethod(options.cloneLevel);
41
63
  Object.defineProperties(this, {
42
64
  size: {
43
65
  get() {
@@ -62,36 +84,24 @@ var FastTTLCache = class {
62
84
  }
63
85
  /**
64
86
  * 获取缓存,惰性删除
65
- * @param key 缓存键
87
+ * @param {string} key 缓存键
66
88
  * @returns 如果缓存存在且未过期返回值,否则返回null
67
89
  */
68
90
  get(key) {
69
91
  const item = this.store.get(key);
70
92
  if (!item) return null;
71
93
  if (Date.now() - item.time > this.ttl) {
72
- this.del(item);
94
+ this.del(item, true);
73
95
  return null;
74
96
  }
75
- return item.value;
97
+ return this.cloneMethod(item.value);
76
98
  }
77
99
  /**
78
100
  * 设置缓存,包含已存在或新增
79
- * @param key 缓存键
80
- * @param value 缓存值
101
+ * @param {string} key 缓存键
102
+ * @param {any} value 缓存值
81
103
  */
82
104
  put(key, value) {
83
- if (this.size === 0) {
84
- const item2 = {
85
- key,
86
- value,
87
- prev: null,
88
- next: null,
89
- time: Date.now()
90
- };
91
- this.head = this.tail = item2;
92
- this.store.set(key, item2);
93
- return;
94
- }
95
105
  if (this.store.has(key)) {
96
106
  const item2 = this.store.get(key);
97
107
  item2.value = value;
@@ -106,8 +116,12 @@ var FastTTLCache = class {
106
116
  next: null,
107
117
  time: Date.now()
108
118
  };
109
- this.tail.next = item;
110
- this.tail = item;
119
+ if (this.size === 0) {
120
+ this.head = this.tail = item;
121
+ } else {
122
+ this.tail.next = item;
123
+ this.tail = item;
124
+ }
111
125
  this.store.set(key, item);
112
126
  if (this.size > this.capacity) {
113
127
  this.del(this.head);
@@ -115,16 +129,28 @@ var FastTTLCache = class {
115
129
  }
116
130
  /**
117
131
  * 移除节点
118
- * @param item CacheItem
132
+ * @param {CacheItem} item
133
+ * @param {boolean} [isExpire = false] 是否为过期删除
134
+ * @returns {boolean} 是否删除成功
119
135
  */
120
- del(item) {
136
+ del(item, isExpire = false) {
121
137
  const key = item.key;
122
138
  if (!this.store.has(key)) return false;
123
- if (this.size === 1) {
124
- this.head = this.tail = null;
125
- } else if (this.head === item) {
126
- this.head = item.next;
127
- this.head.prev = null;
139
+ if (isExpire) {
140
+ let prevItem = item.prev;
141
+ while (prevItem) {
142
+ this.store.delete(prevItem.key);
143
+ prevItem = prevItem.prev;
144
+ }
145
+ this.head = item;
146
+ }
147
+ if (this.head === item) {
148
+ if (item.next) {
149
+ this.head = item.next;
150
+ this.head.prev = null;
151
+ } else {
152
+ this.head = this.tail = null;
153
+ }
128
154
  } else if (this.tail === item) {
129
155
  this.tail = item.prev;
130
156
  this.tail.next = null;
@@ -132,12 +158,12 @@ var FastTTLCache = class {
132
158
  item.prev.next = item.next;
133
159
  item.next.prev = item.prev;
134
160
  }
135
- this.store.delete(key);
136
- return true;
161
+ return this.store.delete(key);
137
162
  }
138
163
  /**
139
164
  * 将节点移动到队尾,队尾的节点一定是最后一个更新的
140
- * @param item CacheItem
165
+ * @param {CacheItem} item
166
+ * @returns void
141
167
  */
142
168
  moveToTail(item) {
143
169
  const key = item.key;
package/dist/index.mjs CHANGED
@@ -1,8 +1,17 @@
1
1
  // src/index.ts
2
+ import cloneDeep from "lodash.clonedeep";
3
+ import clone from "lodash.clone";
4
+ var pure = (i) => i;
5
+ var NO_CLONE = 0;
6
+ var SHALLOW_CLONE = 1;
7
+ var DEEP_CLONE = 2;
8
+ function getCloneMethod(cloneLevel = NO_CLONE) {
9
+ return cloneLevel === DEEP_CLONE ? cloneDeep : cloneLevel === SHALLOW_CLONE ? clone : pure;
10
+ }
2
11
  var FastTTLCache = class {
3
12
  /**
4
13
  * 构造函数
5
- * @param options 配置选项,包含ttl(过期时间)和capacity(容量)
14
+ * @param {CacheOptions} options 配置选项,包含ttl(过期时间)和capacity(容量)
6
15
  */
7
16
  constructor(options = {}) {
8
17
  /** 存储缓存项的Map */
@@ -13,8 +22,11 @@ var FastTTLCache = class {
13
22
  this.tail = null;
14
23
  /** 缓存大小 */
15
24
  this.size = 0;
25
+ /** 数据 clone 方法 */
26
+ this.cloneMethod = pure;
16
27
  this.ttl = options.ttl || Infinity;
17
28
  this.capacity = options.capacity || Infinity;
29
+ this.cloneMethod = getCloneMethod(options.cloneLevel);
18
30
  Object.defineProperties(this, {
19
31
  size: {
20
32
  get() {
@@ -39,36 +51,24 @@ var FastTTLCache = class {
39
51
  }
40
52
  /**
41
53
  * 获取缓存,惰性删除
42
- * @param key 缓存键
54
+ * @param {string} key 缓存键
43
55
  * @returns 如果缓存存在且未过期返回值,否则返回null
44
56
  */
45
57
  get(key) {
46
58
  const item = this.store.get(key);
47
59
  if (!item) return null;
48
60
  if (Date.now() - item.time > this.ttl) {
49
- this.del(item);
61
+ this.del(item, true);
50
62
  return null;
51
63
  }
52
- return item.value;
64
+ return this.cloneMethod(item.value);
53
65
  }
54
66
  /**
55
67
  * 设置缓存,包含已存在或新增
56
- * @param key 缓存键
57
- * @param value 缓存值
68
+ * @param {string} key 缓存键
69
+ * @param {any} value 缓存值
58
70
  */
59
71
  put(key, value) {
60
- if (this.size === 0) {
61
- const item2 = {
62
- key,
63
- value,
64
- prev: null,
65
- next: null,
66
- time: Date.now()
67
- };
68
- this.head = this.tail = item2;
69
- this.store.set(key, item2);
70
- return;
71
- }
72
72
  if (this.store.has(key)) {
73
73
  const item2 = this.store.get(key);
74
74
  item2.value = value;
@@ -83,8 +83,12 @@ var FastTTLCache = class {
83
83
  next: null,
84
84
  time: Date.now()
85
85
  };
86
- this.tail.next = item;
87
- this.tail = item;
86
+ if (this.size === 0) {
87
+ this.head = this.tail = item;
88
+ } else {
89
+ this.tail.next = item;
90
+ this.tail = item;
91
+ }
88
92
  this.store.set(key, item);
89
93
  if (this.size > this.capacity) {
90
94
  this.del(this.head);
@@ -92,16 +96,28 @@ var FastTTLCache = class {
92
96
  }
93
97
  /**
94
98
  * 移除节点
95
- * @param item CacheItem
99
+ * @param {CacheItem} item
100
+ * @param {boolean} [isExpire = false] 是否为过期删除
101
+ * @returns {boolean} 是否删除成功
96
102
  */
97
- del(item) {
103
+ del(item, isExpire = false) {
98
104
  const key = item.key;
99
105
  if (!this.store.has(key)) return false;
100
- if (this.size === 1) {
101
- this.head = this.tail = null;
102
- } else if (this.head === item) {
103
- this.head = item.next;
104
- this.head.prev = null;
106
+ if (isExpire) {
107
+ let prevItem = item.prev;
108
+ while (prevItem) {
109
+ this.store.delete(prevItem.key);
110
+ prevItem = prevItem.prev;
111
+ }
112
+ this.head = item;
113
+ }
114
+ if (this.head === item) {
115
+ if (item.next) {
116
+ this.head = item.next;
117
+ this.head.prev = null;
118
+ } else {
119
+ this.head = this.tail = null;
120
+ }
105
121
  } else if (this.tail === item) {
106
122
  this.tail = item.prev;
107
123
  this.tail.next = null;
@@ -109,12 +125,12 @@ var FastTTLCache = class {
109
125
  item.prev.next = item.next;
110
126
  item.next.prev = item.prev;
111
127
  }
112
- this.store.delete(key);
113
- return true;
128
+ return this.store.delete(key);
114
129
  }
115
130
  /**
116
131
  * 将节点移动到队尾,队尾的节点一定是最后一个更新的
117
- * @param item CacheItem
132
+ * @param {CacheItem} item
133
+ * @returns void
118
134
  */
119
135
  moveToTail(item) {
120
136
  const key = item.key;
package/dist/types.d.mts CHANGED
@@ -21,6 +21,8 @@ interface CacheOptions {
21
21
  ttl?: number;
22
22
  /** 缓存最大容量 */
23
23
  capacity?: number;
24
+ /** 数据 clone 等级,0表示不克隆,1表示浅克隆,2表示深克隆 */
25
+ cloneLevel?: number;
24
26
  }
25
27
 
26
28
  export type { CacheItem, CacheOptions };
package/dist/types.d.ts CHANGED
@@ -21,6 +21,8 @@ interface CacheOptions {
21
21
  ttl?: number;
22
22
  /** 缓存最大容量 */
23
23
  capacity?: number;
24
+ /** 数据 clone 等级,0表示不克隆,1表示浅克隆,2表示深克隆 */
25
+ cloneLevel?: number;
24
26
  }
25
27
 
26
28
  export type { CacheItem, CacheOptions };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fast-ttl-cache",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "ttl cache with capacity support use no timer",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -35,5 +35,9 @@
35
35
  },
36
36
  "files": [
37
37
  "dist/"
38
- ]
38
+ ],
39
+ "dependencies": {
40
+ "lodash.clone": "^4.5.0",
41
+ "lodash.clonedeep": "^4.5.0"
42
+ }
39
43
  }