@asamuzakjp/generational-cache 2.0.4 → 3.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/README.md +58 -47
- package/package.json +6 -4
- package/src/index.js +77 -26
- package/types/index.d.ts +1 -1
package/README.md
CHANGED
|
@@ -4,17 +4,26 @@
|
|
|
4
4
|
[](https://github.com/asamuzaK/generationalCache/actions/workflows/github-code-scanning/codeql)
|
|
5
5
|
[](https://www.npmjs.com/package/@asamuzakjp/generational-cache)
|
|
6
6
|
|
|
7
|
-
A lightweight, **generational
|
|
7
|
+
A lightweight, **generational cache** with strict entry-count limits and payload validation.
|
|
8
8
|
|
|
9
9
|
## How it Works
|
|
10
10
|
|
|
11
11
|
`GenerationalCache` maintains two internal `Map` objects: `current` and `old`.
|
|
12
|
+
It uses an internal boundary of ($max / 2$), allowing both generations to remain bounded while keeping generation swaps inexpensive.
|
|
12
13
|
|
|
13
14
|
1. **Insertion & Validation**: New items are validated against byte size limits before being added to the `current` generation.
|
|
14
15
|
2. **Promotion**: If you get an item that exists in the `old` generation, it is promoted to the `current` generation to ensure it stays in the cache longer.
|
|
15
16
|
3. **Generation Swapping**: Once the `current` generation's size meets or exceeds the boundary threshold ($max / 2$), a generation swap is triggered: the existing `old` generation is discarded, the `current` generation becomes the new `old` generation, and a new empty `current` generation is created.
|
|
16
17
|
|
|
17
|
-
This
|
|
18
|
+
This two-generation approach avoids the overhead of updating timestamps or linked list pointers on every access. While not a drop-in replacement for standard LRU caches, it prioritizes raw throughput over strict eviction ordering.
|
|
19
|
+
|
|
20
|
+
## When NOT to Use
|
|
21
|
+
|
|
22
|
+
`GenerationalCache` may not be a good fit when:
|
|
23
|
+
|
|
24
|
+
* You require strict LRU eviction ordering.
|
|
25
|
+
* Cache hit rate is more important than insertion/eviction throughput.
|
|
26
|
+
* You already know your working set size and can provision a sufficiently large LRU cache.
|
|
18
27
|
|
|
19
28
|
## Installation
|
|
20
29
|
|
|
@@ -29,32 +38,34 @@ import { GenerationalCache } from '@asamuzakjp/generational-cache';
|
|
|
29
38
|
|
|
30
39
|
// Initialize with a max capacity of 1024 items and custom size limits
|
|
31
40
|
const cache = new GenerationalCache(1024, {
|
|
32
|
-
maxKeySize: 4096,
|
|
41
|
+
maxKeySize: 4096, // 4 KB limit for keys
|
|
33
42
|
maxValueSize: 1024 * 1024, // 1 MB limit for values
|
|
34
|
-
strictValidate: true
|
|
43
|
+
strictValidate: true // Enable strict deep validation for objects (default)
|
|
35
44
|
});
|
|
36
45
|
```
|
|
37
46
|
|
|
38
47
|
## API
|
|
39
48
|
|
|
40
|
-
### `new GenerationalCache(max)`
|
|
49
|
+
### `new GenerationalCache(max, opt)`
|
|
41
50
|
|
|
42
|
-
Creates a new cache instance.
|
|
51
|
+
Creates a new cache instance with a maximum capacity of `max` entries.
|
|
43
52
|
|
|
44
53
|
* **max** *(number)*: The maximum number of items the cache can hold. If the specified value is less than 4, or if an invalid value is specified, the default value of 4 will be used.
|
|
45
54
|
* **opt** *(object, optional)*:
|
|
55
|
+
* **cacheFunction** *(boolean)*: Caches functions if `true`. Defaults to `false`.
|
|
56
|
+
* **cacheSymbol** *(boolean)*: Caches symbols if `true`. Defaults to `false`.
|
|
46
57
|
* **maxKeySize** *(number)*: Maximum allowed size for a `key` in bytes. Defaults to 8192 (8 KB).
|
|
47
|
-
* **maxValueSize** *(number)*: Maximum allowed size for a `value` in bytes. Defaults to
|
|
58
|
+
* **maxValueSize** *(number)*: Maximum allowed size for a `value` in bytes. Defaults to 1048576 (1 MB).
|
|
48
59
|
* **strictValidate** *(boolean)*: Strictly validate object payload structures and sizes if `true`. Defaults to `true`.
|
|
49
60
|
|
|
50
|
-
###
|
|
61
|
+
### Properties
|
|
51
62
|
|
|
52
|
-
* **cache.
|
|
53
|
-
**Note:** To maximize write throughput, this library allows temporary key duplication between the `current` and `old` generations (e.g., when an item exists in both generations simultaneously).
|
|
63
|
+
* **cache.entryCount** *(number, read-only)*: Returns the total number of underlying `entries` currently stored across both generations.
|
|
64
|
+
**Note:** To maximize write throughput, this library allows temporary key duplication between the `current` and `old` generations (e.g., when an item exists in both generations simultaneously). The reported count may exceed the number of unique `keys`, but remains bounded by the cache's internal capacity.
|
|
54
65
|
* **cache.max** *(number)*: Gets or sets the maximum item capacity.
|
|
55
66
|
**Note:** Updating this property dynamically **will clear all existing cached items** (it implicitly invokes cache.clear() to safely recalculate boundaries).
|
|
56
67
|
|
|
57
|
-
###
|
|
68
|
+
### Methods
|
|
58
69
|
|
|
59
70
|
* **cache.get(key)**
|
|
60
71
|
Retrieves an item. If the item is found in the `old` generation, it is automatically promoted to the `current` generation to prevent it from being evicted during the next swap.
|
|
@@ -91,77 +102,77 @@ Benchmarks are divided into two states to simulate real-world conditions:
|
|
|
91
102
|
|
|
92
103
|
| Scenario | State | GenerationalCache | LRUCache | QuickLRU | Mnemonist |
|
|
93
104
|
| :---- | :---- | :---- | :---- | :---- | :---- |
|
|
94
|
-
| **Set** | Cold |
|
|
95
|
-
| | Warm | **
|
|
96
|
-
| **Get** | Cold |
|
|
97
|
-
| | Warm |
|
|
98
|
-
| **Eviction** | Cold | **16,
|
|
99
|
-
| | Warm | **
|
|
105
|
+
| **Set** | Cold | 15,137,754 ops/sec | 4,265,484 ops/sec | 13,800,718 ops/sec | **17,844,397 ops/sec** |
|
|
106
|
+
| | Warm | **18,993,352 ops/sec** | 15,299,878 ops/sec | **18,132,366 ops/sec** | **19,007,793 ops/sec** |
|
|
107
|
+
| **Get** | Cold | 16,028,210 ops/sec | 7,566,013 ops/sec | 13,881,177 ops/sec | **30,030,030 ops/sec** |
|
|
108
|
+
| | Warm | 17,917,936 ops/sec | 23,523,877 ops/sec | 16,458,196 ops/sec | **39,416,634 ops/sec** |
|
|
109
|
+
| **Eviction** | Cold | **16,236,402 ops/sec** | 7,372,457 ops/sec | 14,547,571 ops/sec | 5,407,451 ops/sec |
|
|
110
|
+
| | Warm | **20,479,214 ops/sec** | 8,993,615 ops/sec | 17,123,288 ops/sec | 7,668,712 ops/sec |
|
|
100
111
|
|
|
101
112
|
### 2. Medium Cache (Max Size = 2,048)
|
|
102
113
|
|
|
103
114
|
| Scenario | State | GenerationalCache | LRUCache | QuickLRU | Mnemonist |
|
|
104
115
|
| :---- | :---- | :---- | :---- | :---- | :---- |
|
|
105
|
-
| **Set** | Cold | **15,
|
|
106
|
-
| | Warm | **
|
|
107
|
-
| **Get** | Cold |
|
|
108
|
-
| | Warm |
|
|
109
|
-
| **Eviction** | Cold | **
|
|
110
|
-
| | Warm | **
|
|
116
|
+
| **Set** | Cold | **15,024,038 ops/sec** | 4,537,617 ops/sec | 11,818,934 ops/sec | **15,110,305 ops/sec** |
|
|
117
|
+
| | Warm | **17,126,220 ops/sec** | 13,299,641 ops/sec | 15,309,247 ops/sec | **17,070,673 ops/sec** |
|
|
118
|
+
| **Get** | Cold | 13,976,240 ops/sec | 8,134,711 ops/sec | 11,784,115 ops/sec | **26,315,789 ops/sec** |
|
|
119
|
+
| | Warm | 16,015,375 ops/sec | 19,425,019 ops/sec | 13,599,891 ops/sec | **35,663,338 ops/sec** |
|
|
120
|
+
| **Eviction** | Cold | **14,858,841 ops/sec** | 6,439,979 ops/sec | 12,425,447 ops/sec | 5,252,929 ops/sec |
|
|
121
|
+
| | Warm | **19,805,902 ops/sec** | 7,981,483 ops/sec | 16,108,247 ops/sec | 7,295,010 ops/sec |
|
|
111
122
|
|
|
112
123
|
### 3. Large Cache (Max Size = 8,192)
|
|
113
124
|
|
|
114
125
|
| Scenario | State | GenerationalCache | LRUCache | QuickLRU | Mnemonist |
|
|
115
126
|
| :---- | :---- | :---- | :---- | :---- | :---- |
|
|
116
|
-
| **Set** | Cold | **13,
|
|
117
|
-
| | Warm | **
|
|
118
|
-
| **Get** | Cold |
|
|
119
|
-
| | Warm |
|
|
120
|
-
| **Eviction** | Cold | **
|
|
121
|
-
| | Warm | **
|
|
127
|
+
| **Set** | Cold | **13,292,569 ops/sec** | 3,637,686 ops/sec | 7,970,033 ops/sec | 11,318,619 ops/sec |
|
|
128
|
+
| | Warm | **17,652,251 ops/sec** | 11,709,602 ops/sec | 12,781,186 ops/sec | 15,225,335 ops/sec |
|
|
129
|
+
| **Get** | Cold | 13,840,830 ops/sec | 5,746,136 ops/sec | 11,021,713 ops/sec | **17,155,601 ops/sec** |
|
|
130
|
+
| | Warm | 19,116,804 ops/sec | 17,885,888 ops/sec | 15,664,160 ops/sec | **28,344,671 ops/sec** |
|
|
131
|
+
| **Eviction** | Cold | **14,025,245 ops/sec** | 5,358,770 ops/sec | 9,882,399 ops/sec | 4,185,501 ops/sec |
|
|
132
|
+
| | Warm | **19,249,278 ops/sec** | 7,029,383 ops/sec | 13,646,288 ops/sec | 6,086,798 ops/sec |
|
|
122
133
|
|
|
123
|
-
### 4. Non-Primitive Payload (Max Size =
|
|
134
|
+
### 4. Non-Primitive Payload (Max Size = 4,096 / strictValidate = true)
|
|
124
135
|
|
|
125
136
|
| Scenario | State | GenerationalCache | LRUCache | QuickLRU | Mnemonist |
|
|
126
137
|
| :---- | :---- | :---- | :---- | :---- | :---- |
|
|
127
|
-
| **Set** | Cold |
|
|
128
|
-
| | Warm |
|
|
129
|
-
| **Get** | Cold |
|
|
130
|
-
| | Warm |
|
|
131
|
-
| **Eviction** | Cold |
|
|
132
|
-
| | Warm |
|
|
138
|
+
| **Set** | Cold | 602,410 ops/sec | 3,003,725 ops/sec | 9,948,269 ops/sec | **10,231,226 ops/sec** |
|
|
139
|
+
| | Warm | 757,576 ops/sec | 10,964,912 ops/sec | 14,697,237 ops/sec | **16,572,754 ops/sec** |
|
|
140
|
+
| **Get** | Cold | 13,180,440 ops/sec | 7,043,742 ops/sec | 11,037,528 ops/sec | **17,580,872 ops/sec** |
|
|
141
|
+
| | Warm | 16,170,763 ops/sec | 19,007,793 ops/sec | 14,363,689 ops/sec | **28,719,127 ops/sec** |
|
|
142
|
+
| **Eviction** | Cold | 617,284 ops/sec | 5,356,186 ops/sec | **12,072,920 ops/sec** | 2,607,222 ops/sec |
|
|
143
|
+
| | Warm | 775,194 ops/sec | 7,504,127 ops/sec | **14,981,273 ops/sec** | 6,208,481 ops/sec |
|
|
133
144
|
|
|
134
|
-
### 5. Non-Primitive Payload (Max Size =
|
|
145
|
+
### 5. Non-Primitive Payload (Max Size = 4,096 / strictValidate = false)
|
|
135
146
|
|
|
136
147
|
| Scenario | State | GenerationalCache | LRUCache | QuickLRU | Mnemonist |
|
|
137
148
|
| :---- | :---- | :---- | :---- | :---- | :---- |
|
|
138
|
-
| **Set** | Cold | **
|
|
139
|
-
| | Warm |
|
|
140
|
-
| **Get** | Cold |
|
|
141
|
-
| | Warm |
|
|
142
|
-
| **Eviction** | Cold |
|
|
143
|
-
| | Warm | **
|
|
149
|
+
| **Set** | Cold | **12,315,271 ops/sec** | 2,650,060 ops/sec | 10,233,320 ops/sec | 10,884,946 ops/sec |
|
|
150
|
+
| | Warm | **16,100,467 ops/sec** | 10,561,893 ops/sec | 14,624,159 ops/sec | **16,672,224 ops/sec** |
|
|
151
|
+
| **Get** | Cold | 13,835,086 ops/sec | 7,248,478 ops/sec | 10,714,668 ops/sec | **19,015,022 ops/sec** |
|
|
152
|
+
| | Warm | 16,012,810 ops/sec | 18,744,142 ops/sec | 14,106,362 ops/sec | **32,927,231 ops/sec** |
|
|
153
|
+
| **Eviction** | Cold | 10,424,268 ops/sec | 5,473,753 ops/sec | **11,983,223 ops/sec** | 2,544,853 ops/sec |
|
|
154
|
+
| | Warm | **16,291,952 ops/sec** | 6,972,996 ops/sec | 13,417,416 ops/sec | 5,798,782 ops/sec |
|
|
144
155
|
|
|
145
156
|
### 6. Cyclic Access (Max Size = 8,192 / Working Set = 5,000)
|
|
146
157
|
|
|
147
158
|
| Metric | GenerationalCache | LRUCache | QuickLRU | Mnemonist |
|
|
148
159
|
| :---- | :---- | :---- | :---- | :---- |
|
|
149
160
|
| **Hit Rate** | 78.30% | **100.00%** | **100.00%** | **100.00%** |
|
|
150
|
-
| **Throughput** |
|
|
161
|
+
| **Throughput** | 8,783,487 ops/sec | 37,778,617 ops/sec | 38,550,501 ops/sec | **44,742,729 ops/sec** |
|
|
151
162
|
|
|
152
163
|
### 7. Cyclic Access (Max Size = 4,096 / Working Set = 5,000)
|
|
153
164
|
|
|
154
165
|
| Metric | GenerationalCache | LRUCache | QuickLRU | Mnemonist |
|
|
155
166
|
| :---- | :---- | :---- | :---- | :---- |
|
|
156
|
-
| **Hit Rate** |
|
|
157
|
-
| **Throughput** | **
|
|
167
|
+
| **Hit Rate** | 0.00% | 0.00% | **78.30%** | 0.00% |
|
|
168
|
+
| **Throughput** | **9,931,472 ops/sec** | 6,396,724 ops/sec | 8,509,189 ops/sec | 6,078,288 ops/sec |
|
|
158
169
|
|
|
159
170
|
## Key Characteristics
|
|
160
171
|
|
|
161
172
|
* **High Eviction Efficiency**: `GenerationalCache` demonstrates strong throughput during high-turnover workloads, maintaining a performance margin compared to standard LRU designs in large-scale eviction scenarios.
|
|
162
173
|
* **Predictable Scalability**: While other libraries may experience performance degradation as cache size increases, `GenerationalCache` maintains consistent throughput due to its generational swap mechanism.
|
|
163
174
|
* **Balanced Read/Write**: It provides stable and competitive performance across all basic operations (`get`, `set`), making it suitable for both read-heavy and write-heavy environments.
|
|
164
|
-
* **Strict Validation Toggle**: By default, non-primitive payloads undergo deep validation to
|
|
175
|
+
* **Strict Validation Toggle**: By default, non-primitive payloads undergo deep validation to prevent memory exhaustion from oversized objects, which impacts write throughput. Disabling `strictValidate` restores write performance, provided that payload sizes are managed externally (See 4 & 5).
|
|
165
176
|
* **Trade-offs**: In cyclic access patterns where the working set is greater than `max / 2` but smaller than `max`, `GenerationalCache` will experience frequent generation swaps and cache misses. To maximize the performance benefits of `GenerationalCache`, it is often better to keep the `max` size small enough to allow some evictions, rather than trying to fit the entire working set (See 6 & 7).
|
|
166
177
|
|
|
167
178
|
## License
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@asamuzakjp/generational-cache",
|
|
3
|
-
"description": "A generational
|
|
3
|
+
"description": "A generational cache with strict entry-count limits and payload validation.",
|
|
4
4
|
"author": "asamuzaK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/asamuzaK/generationalCache",
|
|
@@ -47,10 +47,12 @@
|
|
|
47
47
|
"yargs": "^18.0.0"
|
|
48
48
|
},
|
|
49
49
|
"eslint": {
|
|
50
|
-
"brace-expansion": "^1.1.13"
|
|
50
|
+
"brace-expansion": "^1.1.13",
|
|
51
|
+
"js-yaml": "^4.2.0"
|
|
51
52
|
},
|
|
52
53
|
"mocha": {
|
|
53
|
-
"diff": "^8.0.3"
|
|
54
|
+
"diff": "^8.0.3",
|
|
55
|
+
"js-yaml": "^4.2.0"
|
|
54
56
|
},
|
|
55
57
|
"serialize-javascript": "^7.0.4"
|
|
56
58
|
},
|
|
@@ -66,5 +68,5 @@
|
|
|
66
68
|
"engines": {
|
|
67
69
|
"node": "^22.13.0 || >=24.0.0"
|
|
68
70
|
},
|
|
69
|
-
"version": "
|
|
71
|
+
"version": "3.0.1"
|
|
70
72
|
}
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file generational-cache.js
|
|
3
|
-
* A generational
|
|
3
|
+
* A generational cache with strict entry-count limits and payload validation.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
/* constants */
|
|
@@ -17,10 +17,10 @@ const MAX_BYTES_PER_CHAR = 4;
|
|
|
17
17
|
const DEFAULT_KEY_SIZE = 8 * 1024;
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* Default maximum allowed size for a value in bytes (
|
|
20
|
+
* Default maximum allowed size for a value in bytes (1 MB).
|
|
21
21
|
* @type {number}
|
|
22
22
|
*/
|
|
23
|
-
const DEFAULT_VALUE_SIZE =
|
|
23
|
+
const DEFAULT_VALUE_SIZE = 1024 * 1024;
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Flag indicating whether the current runtime environment is Node.js.
|
|
@@ -182,6 +182,60 @@ export class GenerationalCache {
|
|
|
182
182
|
return false;
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Performs validation based on the specific type of built-in object.
|
|
187
|
+
* @param {string} typeStr - The type string of the object.
|
|
188
|
+
* @param {object} input - The object to validate.
|
|
189
|
+
* @param {number} max - The maximum allowable size in bytes.
|
|
190
|
+
* @returns {{ result?: boolean, input?: unknown }} The validation result, or the input.
|
|
191
|
+
*/
|
|
192
|
+
#validateBuiltInObject(typeStr, input, max) {
|
|
193
|
+
switch (typeStr) {
|
|
194
|
+
case 'Array': {
|
|
195
|
+
if (input.length > max - 2) {
|
|
196
|
+
return { result: false };
|
|
197
|
+
}
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
case 'Map':
|
|
201
|
+
case 'Set': {
|
|
202
|
+
if (input.size > max - 2) {
|
|
203
|
+
return { result: false };
|
|
204
|
+
}
|
|
205
|
+
input = [...input];
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
case 'Date': {
|
|
209
|
+
if (Number.isNaN(input.getTime())) {
|
|
210
|
+
return { result: false };
|
|
211
|
+
}
|
|
212
|
+
return { result: this.#validateString(input.toISOString(), max - 2) };
|
|
213
|
+
}
|
|
214
|
+
case 'RegExp': {
|
|
215
|
+
return { result: this.#validateString(input.toString(), max) };
|
|
216
|
+
}
|
|
217
|
+
case 'ArrayBuffer':
|
|
218
|
+
case 'DataView':
|
|
219
|
+
case 'Int8Array':
|
|
220
|
+
case 'Uint8Array':
|
|
221
|
+
case 'Uint8ClampedArray':
|
|
222
|
+
case 'Int16Array':
|
|
223
|
+
case 'Uint16Array':
|
|
224
|
+
case 'Int32Array':
|
|
225
|
+
case 'Uint32Array':
|
|
226
|
+
case 'Float32Array':
|
|
227
|
+
case 'Float64Array':
|
|
228
|
+
case 'BigInt64Array':
|
|
229
|
+
case 'BigUint64Array': {
|
|
230
|
+
return { result: input.byteLength <= max };
|
|
231
|
+
}
|
|
232
|
+
default: {
|
|
233
|
+
// fall through
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return { input };
|
|
237
|
+
}
|
|
238
|
+
|
|
185
239
|
/**
|
|
186
240
|
* Validates if the given input fits within the specified maximum byte size.
|
|
187
241
|
* @param {K|V} input - The input data to validate (usually a string).
|
|
@@ -204,8 +258,15 @@ export class GenerationalCache {
|
|
|
204
258
|
return max >= 8;
|
|
205
259
|
}
|
|
206
260
|
case 'bigint': {
|
|
207
|
-
//
|
|
208
|
-
|
|
261
|
+
// Normalize negative bigint for bit-length calculation.
|
|
262
|
+
const signNormalized = input < 0n ? ~input : input;
|
|
263
|
+
if (signNormalized === 0n) {
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
const hex = signNormalized.toString(16);
|
|
267
|
+
const firstCharBits = parseInt(hex[0], 16).toString(2).length;
|
|
268
|
+
const bitLength = (hex.length - 1) * 4 + firstCharBits + 1;
|
|
269
|
+
return bitLength <= max * 8;
|
|
209
270
|
}
|
|
210
271
|
case 'function': {
|
|
211
272
|
return this.#cacheFunction;
|
|
@@ -214,30 +275,20 @@ export class GenerationalCache {
|
|
|
214
275
|
return this.#cacheSymbol;
|
|
215
276
|
}
|
|
216
277
|
default: {
|
|
217
|
-
if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) {
|
|
218
|
-
return input.byteLength <= max;
|
|
219
|
-
}
|
|
220
|
-
if (input instanceof Date) {
|
|
221
|
-
return this.#validateString(input.toISOString(), max);
|
|
222
|
-
}
|
|
223
|
-
if (input instanceof RegExp) {
|
|
224
|
-
return input.toString().length * MAX_BYTES_PER_CHAR <= max;
|
|
225
|
-
}
|
|
226
278
|
if (!this.#strictValidate) {
|
|
227
279
|
return true;
|
|
228
280
|
}
|
|
281
|
+
const typeStr = Object.prototype.toString.call(input).slice(8, -1);
|
|
282
|
+
const typeCheck = this.#validateBuiltInObject(typeStr, input, max);
|
|
283
|
+
if (typeCheck.result !== undefined) {
|
|
284
|
+
return typeCheck.result;
|
|
285
|
+
}
|
|
286
|
+
input = typeCheck.input;
|
|
229
287
|
if (this.#hasForbiddenTypes(input)) {
|
|
230
288
|
return false;
|
|
231
289
|
}
|
|
232
|
-
let targetForJson = input;
|
|
233
|
-
if (input instanceof Map || input instanceof Set) {
|
|
234
|
-
if (!input.size) {
|
|
235
|
-
return max >= 2;
|
|
236
|
-
}
|
|
237
|
-
targetForJson = [...input];
|
|
238
|
-
}
|
|
239
290
|
try {
|
|
240
|
-
const serialized = JSON.stringify(
|
|
291
|
+
const serialized = JSON.stringify(input);
|
|
241
292
|
if (serialized === undefined) {
|
|
242
293
|
return false;
|
|
243
294
|
}
|
|
@@ -250,13 +301,13 @@ export class GenerationalCache {
|
|
|
250
301
|
}
|
|
251
302
|
|
|
252
303
|
/**
|
|
253
|
-
* Gets the
|
|
304
|
+
* Gets the total number of cached entries across both generations.
|
|
254
305
|
* @note To optimize for write speed, this library allows temporary key
|
|
255
|
-
* duplication between generations. Therefore, this value
|
|
256
|
-
*
|
|
306
|
+
* duplication between generations. Therefore, this value reflects the total
|
|
307
|
+
* count of internal entries rather than the exact number of unique keys.
|
|
257
308
|
* @type {number}
|
|
258
309
|
*/
|
|
259
|
-
get
|
|
310
|
+
get entryCount() {
|
|
260
311
|
return this.#current.size + this.#old.size;
|
|
261
312
|
}
|
|
262
313
|
|
package/types/index.d.ts
CHANGED