@zuplo/cli 6.71.21 → 6.71.23
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/node_modules/@posthog/core/dist/error-tracking/exception-steps.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/error-tracking/exception-steps.js +6 -24
- package/node_modules/@posthog/core/dist/error-tracking/exception-steps.mjs +7 -25
- package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts +6 -0
- package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/posthog-core-stateless.js +75 -17
- package/node_modules/@posthog/core/dist/posthog-core-stateless.mjs +73 -18
- package/node_modules/@posthog/core/dist/posthog-core.d.ts +2 -2
- package/node_modules/@posthog/core/dist/posthog-core.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/posthog-core.js +10 -6
- package/node_modules/@posthog/core/dist/posthog-core.mjs +11 -7
- package/node_modules/@posthog/core/dist/testing/PostHogCoreTestClient.d.ts +1 -0
- package/node_modules/@posthog/core/dist/testing/PostHogCoreTestClient.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/testing/PostHogCoreTestClient.js +3 -0
- package/node_modules/@posthog/core/dist/testing/PostHogCoreTestClient.mjs +3 -0
- package/node_modules/@posthog/core/dist/utils/promise-queue.d.ts +3 -0
- package/node_modules/@posthog/core/dist/utils/promise-queue.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/utils/promise-queue.js +15 -3
- package/node_modules/@posthog/core/dist/utils/promise-queue.mjs +15 -3
- package/node_modules/@posthog/core/dist/utils/string-utils.d.ts +1 -0
- package/node_modules/@posthog/core/dist/utils/string-utils.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/utils/string-utils.js +21 -0
- package/node_modules/@posthog/core/dist/utils/string-utils.mjs +19 -1
- package/node_modules/@posthog/core/package.json +1 -1
- package/node_modules/@posthog/core/src/error-tracking/exception-steps.ts +5 -42
- package/node_modules/@posthog/core/src/posthog-core-stateless.ts +118 -23
- package/node_modules/@posthog/core/src/posthog-core.ts +18 -7
- package/node_modules/@posthog/core/src/testing/PostHogCoreTestClient.ts +4 -0
- package/node_modules/@posthog/core/src/utils/promise-queue.ts +17 -4
- package/node_modules/@posthog/core/src/utils/string-utils.spec.ts +38 -1
- package/node_modules/@posthog/core/src/utils/string-utils.ts +42 -0
- package/node_modules/@posthog/types/dist/posthog.d.ts +12 -0
- package/node_modules/@posthog/types/dist/posthog.d.ts.map +1 -1
- package/node_modules/@posthog/types/package.json +1 -1
- package/node_modules/@posthog/types/src/posthog.ts +13 -0
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/buffer.d.ts +64 -25
- package/node_modules/@types/node/crypto.d.ts +18 -5
- package/node_modules/@types/node/diagnostics_channel.d.ts +237 -3
- package/node_modules/@types/node/dns.d.ts +1 -1
- package/node_modules/@types/node/ffi.d.ts +486 -0
- package/node_modules/@types/node/fs/promises.d.ts +3 -0
- package/node_modules/@types/node/fs.d.ts +21 -6
- package/node_modules/@types/node/http.d.ts +25 -0
- package/node_modules/@types/node/index.d.ts +1 -0
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/process.d.ts +14 -1
- package/node_modules/@types/node/quic.d.ts +92 -11
- package/node_modules/@types/node/sqlite.d.ts +55 -0
- package/node_modules/@types/node/stream/iter.d.ts +150 -0
- package/node_modules/@types/node/stream.d.ts +32 -0
- package/node_modules/@types/node/test.d.ts +112 -2
- package/node_modules/@types/node/ts5.6/index.d.ts +1 -0
- package/node_modules/@types/node/ts5.7/index.d.ts +1 -0
- package/node_modules/@types/node/util.d.ts +19 -2
- package/node_modules/@types/node/v8.d.ts +84 -2
- package/node_modules/@types/node/worker_threads.d.ts +8 -7
- package/node_modules/@zuplo/core/customer.cli.minified.js +2 -2
- package/node_modules/@zuplo/core/index.minified.js +2 -2
- package/node_modules/@zuplo/core/package.json +1 -1
- package/node_modules/@zuplo/graphql/out/esm/index.js +11 -11
- package/node_modules/@zuplo/graphql/out/esm/index.js.map +1 -1
- package/node_modules/@zuplo/graphql/package.json +1 -1
- package/node_modules/@zuplo/openapi-tools/package.json +1 -1
- package/node_modules/@zuplo/otel/package.json +1 -1
- package/node_modules/@zuplo/runtime/out/esm/{chunk-DQ4ANJLR.js → chunk-4MNJC7E2.js} +2 -2
- package/node_modules/@zuplo/runtime/out/esm/chunk-4MNJC7E2.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/{chunk-2Y72LML3.js → chunk-4QJJMELB.js} +2 -2
- package/node_modules/@zuplo/runtime/out/esm/{chunk-2Y72LML3.js.map → chunk-4QJJMELB.js.map} +1 -1
- package/node_modules/@zuplo/runtime/out/esm/chunk-5CYWMN74.js +402 -0
- package/node_modules/@zuplo/runtime/out/esm/chunk-5CYWMN74.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/{chunk-L3MZGNQA.js → chunk-DSZS6PZJ.js} +10 -10
- package/node_modules/@zuplo/runtime/out/esm/chunk-DSZS6PZJ.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/index.js.map +1 -1
- package/node_modules/@zuplo/runtime/out/esm/internal/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +7 -7
- package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js.map +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mocks/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/types/index.d.ts +1050 -18
- package/node_modules/@zuplo/runtime/out/types/mcp-gateway/index.d.ts +33 -7
- package/node_modules/@zuplo/runtime/package.json +1 -1
- package/node_modules/iconv-lite/encodings/sbcs-data.js +2 -0
- package/node_modules/iconv-lite/encodings/utf32.js +10 -3
- package/node_modules/iconv-lite/package.json +2 -2
- package/node_modules/iconv-lite/types/encodings.d.ts +2 -0
- package/node_modules/protobufjs/dist/light/protobuf.js +2 -2
- package/node_modules/protobufjs/dist/light/protobuf.min.js +2 -2
- package/node_modules/protobufjs/dist/minimal/protobuf.js +2 -2
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js +2 -2
- package/node_modules/protobufjs/dist/protobuf.js +5 -2
- package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/package.json +1 -1
- package/node_modules/protobufjs/src/parse.js +3 -0
- package/node_modules/toad-cache/README.md +10 -9
- package/node_modules/toad-cache/dist/toad-cache.cjs +139 -139
- package/node_modules/toad-cache/dist/toad-cache.mjs +136 -140
- package/node_modules/toad-cache/package.json +8 -8
- package/node_modules/toad-cache/toad-cache.d.cts +20 -14
- package/node_modules/toad-cache/toad-cache.d.ts +18 -14
- package/package.json +6 -6
- package/node_modules/@zuplo/runtime/out/esm/chunk-DQ4ANJLR.js.map +0 -1
- package/node_modules/@zuplo/runtime/out/esm/chunk-I5HLAHUY.js +0 -357
- package/node_modules/@zuplo/runtime/out/esm/chunk-I5HLAHUY.js.map +0 -1
- package/node_modules/@zuplo/runtime/out/esm/chunk-L3MZGNQA.js.map +0 -1
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-I5HLAHUY.js.LEGAL.txt → chunk-5CYWMN74.js.LEGAL.txt} +0 -0
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-L3MZGNQA.js.LEGAL.txt → chunk-DSZS6PZJ.js.LEGAL.txt} +0 -0
|
@@ -3,17 +3,26 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @copyright 2026 Igor Savin <kibertoad@gmail.com>
|
|
5
5
|
* @license MIT
|
|
6
|
-
* @version 3.7.
|
|
6
|
+
* @version 3.7.3
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Validates the shared cache constructor parameters.
|
|
10
|
+
* Both values must be non-negative integers.
|
|
11
|
+
*
|
|
12
|
+
* @param {number} max
|
|
13
|
+
* @param {number} ttlInMsecs
|
|
14
|
+
*/
|
|
15
|
+
function validateCacheParams(max, ttlInMsecs) {
|
|
16
|
+
if (typeof max !== 'number' || !Number.isInteger(max) || max < 0) {
|
|
17
|
+
throw new Error('Invalid max value')
|
|
18
|
+
}
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
if (typeof ttlInMsecs !== 'number' || !Number.isInteger(ttlInMsecs) || ttlInMsecs < 0) {
|
|
21
|
+
throw new Error('Invalid ttl value')
|
|
22
|
+
}
|
|
23
|
+
}class FifoMap {
|
|
24
|
+
constructor(max = 1000, ttlInMsecs = 0) {
|
|
25
|
+
validateCacheParams(max, ttlInMsecs);
|
|
17
26
|
|
|
18
27
|
this.first = null;
|
|
19
28
|
this.items = new Map();
|
|
@@ -27,15 +36,15 @@ class FifoMap {
|
|
|
27
36
|
}
|
|
28
37
|
|
|
29
38
|
clear() {
|
|
30
|
-
this.items
|
|
39
|
+
this.items.clear();
|
|
31
40
|
this.first = null;
|
|
32
41
|
this.last = null;
|
|
33
42
|
}
|
|
34
43
|
|
|
35
44
|
delete(key) {
|
|
36
|
-
|
|
37
|
-
const deletedItem = this.items.get(key);
|
|
45
|
+
const deletedItem = this.items.get(key);
|
|
38
46
|
|
|
47
|
+
if (deletedItem !== undefined) {
|
|
39
48
|
this.items.delete(key);
|
|
40
49
|
|
|
41
50
|
if (deletedItem.prev !== null) {
|
|
@@ -79,15 +88,17 @@ class FifoMap {
|
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
expiresAt(key) {
|
|
82
|
-
|
|
83
|
-
|
|
91
|
+
const item = this.items.get(key);
|
|
92
|
+
|
|
93
|
+
if (item !== undefined) {
|
|
94
|
+
return item.expiry
|
|
84
95
|
}
|
|
85
96
|
}
|
|
86
97
|
|
|
87
98
|
get(key) {
|
|
88
|
-
|
|
89
|
-
const item = this.items.get(key);
|
|
99
|
+
const item = this.items.get(key);
|
|
90
100
|
|
|
101
|
+
if (item !== undefined) {
|
|
91
102
|
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
92
103
|
this.delete(key);
|
|
93
104
|
return
|
|
@@ -98,10 +109,10 @@ class FifoMap {
|
|
|
98
109
|
}
|
|
99
110
|
|
|
100
111
|
getMany(keys) {
|
|
101
|
-
const result =
|
|
112
|
+
const result = new Array(keys.length);
|
|
102
113
|
|
|
103
114
|
for (var i = 0; i < keys.length; i++) {
|
|
104
|
-
result
|
|
115
|
+
result[i] = this.get(keys[i]);
|
|
105
116
|
}
|
|
106
117
|
|
|
107
118
|
return result
|
|
@@ -113,17 +124,17 @@ class FifoMap {
|
|
|
113
124
|
|
|
114
125
|
set(key, value) {
|
|
115
126
|
// Replace existing item
|
|
116
|
-
|
|
117
|
-
const item = this.items.get(key);
|
|
118
|
-
item.value = value;
|
|
127
|
+
const existing = this.items.get(key);
|
|
119
128
|
|
|
120
|
-
|
|
129
|
+
if (existing !== undefined) {
|
|
130
|
+
existing.value = value;
|
|
131
|
+
existing.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
121
132
|
|
|
122
133
|
return
|
|
123
134
|
}
|
|
124
135
|
|
|
125
136
|
// Add new item
|
|
126
|
-
if (this.max > 0 && this.size
|
|
137
|
+
if (this.max > 0 && this.size >= this.max) {
|
|
127
138
|
this.evict();
|
|
128
139
|
}
|
|
129
140
|
|
|
@@ -146,13 +157,7 @@ class FifoMap {
|
|
|
146
157
|
}
|
|
147
158
|
}class FifoObject {
|
|
148
159
|
constructor(max = 1000, ttlInMsecs = 0) {
|
|
149
|
-
|
|
150
|
-
throw new Error('Invalid max value')
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
|
|
154
|
-
throw new Error('Invalid ttl value')
|
|
155
|
-
}
|
|
160
|
+
validateCacheParams(max, ttlInMsecs);
|
|
156
161
|
|
|
157
162
|
this.first = null;
|
|
158
163
|
this.items = Object.create(null);
|
|
@@ -170,9 +175,9 @@ class FifoMap {
|
|
|
170
175
|
}
|
|
171
176
|
|
|
172
177
|
delete(key) {
|
|
173
|
-
|
|
174
|
-
const deletedItem = this.items[key];
|
|
178
|
+
const deletedItem = this.items[key];
|
|
175
179
|
|
|
180
|
+
if (deletedItem !== undefined) {
|
|
176
181
|
delete this.items[key];
|
|
177
182
|
this.size--;
|
|
178
183
|
|
|
@@ -217,15 +222,17 @@ class FifoMap {
|
|
|
217
222
|
}
|
|
218
223
|
|
|
219
224
|
expiresAt(key) {
|
|
220
|
-
|
|
221
|
-
|
|
225
|
+
const item = this.items[key];
|
|
226
|
+
|
|
227
|
+
if (item !== undefined) {
|
|
228
|
+
return item.expiry
|
|
222
229
|
}
|
|
223
230
|
}
|
|
224
231
|
|
|
225
232
|
get(key) {
|
|
226
|
-
|
|
227
|
-
const item = this.items[key];
|
|
233
|
+
const item = this.items[key];
|
|
228
234
|
|
|
235
|
+
if (item !== undefined) {
|
|
229
236
|
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
230
237
|
this.delete(key);
|
|
231
238
|
return
|
|
@@ -236,10 +243,10 @@ class FifoMap {
|
|
|
236
243
|
}
|
|
237
244
|
|
|
238
245
|
getMany(keys) {
|
|
239
|
-
const result =
|
|
246
|
+
const result = new Array(keys.length);
|
|
240
247
|
|
|
241
248
|
for (var i = 0; i < keys.length; i++) {
|
|
242
|
-
result
|
|
249
|
+
result[i] = this.get(keys[i]);
|
|
243
250
|
}
|
|
244
251
|
|
|
245
252
|
return result
|
|
@@ -251,17 +258,17 @@ class FifoMap {
|
|
|
251
258
|
|
|
252
259
|
set(key, value) {
|
|
253
260
|
// Replace existing item
|
|
254
|
-
|
|
255
|
-
const item = this.items[key];
|
|
256
|
-
item.value = value;
|
|
261
|
+
const existing = this.items[key];
|
|
257
262
|
|
|
258
|
-
|
|
263
|
+
if (existing !== undefined) {
|
|
264
|
+
existing.value = value;
|
|
265
|
+
existing.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
259
266
|
|
|
260
267
|
return
|
|
261
268
|
}
|
|
262
269
|
|
|
263
270
|
// Add new item
|
|
264
|
-
if (this.max > 0 && this.size
|
|
271
|
+
if (this.max > 0 && this.size >= this.max) {
|
|
265
272
|
this.evict();
|
|
266
273
|
}
|
|
267
274
|
|
|
@@ -282,6 +289,24 @@ class FifoMap {
|
|
|
282
289
|
|
|
283
290
|
this.last = item;
|
|
284
291
|
}
|
|
292
|
+
}/**
|
|
293
|
+
* Creates a zeroed statistics record for a single collection window.
|
|
294
|
+
*
|
|
295
|
+
* @returns {object}
|
|
296
|
+
*/
|
|
297
|
+
function createEmptyStatisticsRecord() {
|
|
298
|
+
return {
|
|
299
|
+
cacheSize: 0,
|
|
300
|
+
hits: 0,
|
|
301
|
+
falsyHits: 0,
|
|
302
|
+
emptyHits: 0,
|
|
303
|
+
misses: 0,
|
|
304
|
+
expirations: 0,
|
|
305
|
+
evictions: 0,
|
|
306
|
+
invalidateOne: 0,
|
|
307
|
+
invalidateAll: 0,
|
|
308
|
+
sets: 0,
|
|
309
|
+
}
|
|
285
310
|
}class HitStatisticsRecord {
|
|
286
311
|
constructor() {
|
|
287
312
|
this.records = {};
|
|
@@ -289,35 +314,17 @@ class FifoMap {
|
|
|
289
314
|
|
|
290
315
|
initForCache(cacheId, currentTimeStamp) {
|
|
291
316
|
this.records[cacheId] = {
|
|
292
|
-
[currentTimeStamp]:
|
|
293
|
-
cacheSize: 0,
|
|
294
|
-
hits: 0,
|
|
295
|
-
falsyHits: 0,
|
|
296
|
-
emptyHits: 0,
|
|
297
|
-
misses: 0,
|
|
298
|
-
expirations: 0,
|
|
299
|
-
evictions: 0,
|
|
300
|
-
invalidateOne: 0,
|
|
301
|
-
invalidateAll: 0,
|
|
302
|
-
sets: 0,
|
|
303
|
-
},
|
|
317
|
+
[currentTimeStamp]: createEmptyStatisticsRecord(),
|
|
304
318
|
};
|
|
305
319
|
}
|
|
306
320
|
|
|
307
321
|
resetForCache(cacheId) {
|
|
322
|
+
if (!this.records[cacheId]) {
|
|
323
|
+
return
|
|
324
|
+
}
|
|
325
|
+
|
|
308
326
|
for (let key of Object.keys(this.records[cacheId])) {
|
|
309
|
-
this.records[cacheId][key] =
|
|
310
|
-
cacheSize: 0,
|
|
311
|
-
hits: 0,
|
|
312
|
-
falsyHits: 0,
|
|
313
|
-
emptyHits: 0,
|
|
314
|
-
misses: 0,
|
|
315
|
-
expirations: 0,
|
|
316
|
-
evictions: 0,
|
|
317
|
-
invalidateOne: 0,
|
|
318
|
-
invalidateAll: 0,
|
|
319
|
-
sets: 0,
|
|
320
|
-
};
|
|
327
|
+
this.records[cacheId][key] = createEmptyStatisticsRecord();
|
|
321
328
|
}
|
|
322
329
|
}
|
|
323
330
|
|
|
@@ -326,13 +333,7 @@ class FifoMap {
|
|
|
326
333
|
}
|
|
327
334
|
}class LruMap {
|
|
328
335
|
constructor(max = 1000, ttlInMsecs = 0) {
|
|
329
|
-
|
|
330
|
-
throw new Error('Invalid max value')
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
|
|
334
|
-
throw new Error('Invalid ttl value')
|
|
335
|
-
}
|
|
336
|
+
validateCacheParams(max, ttlInMsecs);
|
|
336
337
|
|
|
337
338
|
this.first = null;
|
|
338
339
|
this.items = new Map();
|
|
@@ -366,6 +367,7 @@ class FifoMap {
|
|
|
366
367
|
prev.next = next;
|
|
367
368
|
}
|
|
368
369
|
|
|
370
|
+
/* v8 ignore next 3 -- next is always non-null here: the early return above guarantees item !== this.last in a well-formed list */
|
|
369
371
|
if (next !== null) {
|
|
370
372
|
next.prev = prev;
|
|
371
373
|
}
|
|
@@ -374,15 +376,15 @@ class FifoMap {
|
|
|
374
376
|
}
|
|
375
377
|
|
|
376
378
|
clear() {
|
|
377
|
-
this.items
|
|
379
|
+
this.items.clear();
|
|
378
380
|
this.first = null;
|
|
379
381
|
this.last = null;
|
|
380
382
|
}
|
|
381
383
|
|
|
382
384
|
delete(key) {
|
|
383
|
-
|
|
384
|
-
const item = this.items.get(key);
|
|
385
|
+
const item = this.items.get(key);
|
|
385
386
|
|
|
387
|
+
if (item !== undefined) {
|
|
386
388
|
this.items.delete(key);
|
|
387
389
|
|
|
388
390
|
if (item.prev !== null) {
|
|
@@ -426,15 +428,17 @@ class FifoMap {
|
|
|
426
428
|
}
|
|
427
429
|
|
|
428
430
|
expiresAt(key) {
|
|
429
|
-
|
|
430
|
-
|
|
431
|
+
const item = this.items.get(key);
|
|
432
|
+
|
|
433
|
+
if (item !== undefined) {
|
|
434
|
+
return item.expiry
|
|
431
435
|
}
|
|
432
436
|
}
|
|
433
437
|
|
|
434
438
|
get(key) {
|
|
435
|
-
|
|
436
|
-
const item = this.items.get(key);
|
|
439
|
+
const item = this.items.get(key);
|
|
437
440
|
|
|
441
|
+
if (item !== undefined) {
|
|
438
442
|
// Item has already expired
|
|
439
443
|
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
440
444
|
this.delete(key);
|
|
@@ -448,10 +452,10 @@ class FifoMap {
|
|
|
448
452
|
}
|
|
449
453
|
|
|
450
454
|
getMany(keys) {
|
|
451
|
-
const result =
|
|
455
|
+
const result = new Array(keys.length);
|
|
452
456
|
|
|
453
457
|
for (var i = 0; i < keys.length; i++) {
|
|
454
|
-
result
|
|
458
|
+
result[i] = this.get(keys[i]);
|
|
455
459
|
}
|
|
456
460
|
|
|
457
461
|
return result
|
|
@@ -463,21 +467,18 @@ class FifoMap {
|
|
|
463
467
|
|
|
464
468
|
set(key, value) {
|
|
465
469
|
// Replace existing item
|
|
466
|
-
|
|
467
|
-
const item = this.items.get(key);
|
|
468
|
-
item.value = value;
|
|
469
|
-
|
|
470
|
-
item.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
470
|
+
const existing = this.items.get(key);
|
|
471
471
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
472
|
+
if (existing !== undefined) {
|
|
473
|
+
existing.value = value;
|
|
474
|
+
existing.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
475
|
+
this.bumpLru(existing);
|
|
475
476
|
|
|
476
477
|
return
|
|
477
478
|
}
|
|
478
479
|
|
|
479
480
|
// Add new item
|
|
480
|
-
if (this.max > 0 && this.size
|
|
481
|
+
if (this.max > 0 && this.size >= this.max) {
|
|
481
482
|
this.evict();
|
|
482
483
|
}
|
|
483
484
|
|
|
@@ -500,13 +501,7 @@ class FifoMap {
|
|
|
500
501
|
}
|
|
501
502
|
}class LruObject {
|
|
502
503
|
constructor(max = 1000, ttlInMsecs = 0) {
|
|
503
|
-
|
|
504
|
-
throw new Error('Invalid max value')
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
|
|
508
|
-
throw new Error('Invalid ttl value')
|
|
509
|
-
}
|
|
504
|
+
validateCacheParams(max, ttlInMsecs);
|
|
510
505
|
|
|
511
506
|
this.first = null;
|
|
512
507
|
this.items = Object.create(null);
|
|
@@ -537,6 +532,7 @@ class FifoMap {
|
|
|
537
532
|
prev.next = next;
|
|
538
533
|
}
|
|
539
534
|
|
|
535
|
+
/* v8 ignore next 3 -- next is always non-null here: the early return above guarantees item !== this.last in a well-formed list */
|
|
540
536
|
if (next !== null) {
|
|
541
537
|
next.prev = prev;
|
|
542
538
|
}
|
|
@@ -552,9 +548,9 @@ class FifoMap {
|
|
|
552
548
|
}
|
|
553
549
|
|
|
554
550
|
delete(key) {
|
|
555
|
-
|
|
556
|
-
const item = this.items[key];
|
|
551
|
+
const item = this.items[key];
|
|
557
552
|
|
|
553
|
+
if (item !== undefined) {
|
|
558
554
|
delete this.items[key];
|
|
559
555
|
this.size--;
|
|
560
556
|
|
|
@@ -599,15 +595,17 @@ class FifoMap {
|
|
|
599
595
|
}
|
|
600
596
|
|
|
601
597
|
expiresAt(key) {
|
|
602
|
-
|
|
603
|
-
|
|
598
|
+
const item = this.items[key];
|
|
599
|
+
|
|
600
|
+
if (item !== undefined) {
|
|
601
|
+
return item.expiry
|
|
604
602
|
}
|
|
605
603
|
}
|
|
606
604
|
|
|
607
605
|
get(key) {
|
|
608
|
-
|
|
609
|
-
const item = this.items[key];
|
|
606
|
+
const item = this.items[key];
|
|
610
607
|
|
|
608
|
+
if (item !== undefined) {
|
|
611
609
|
// Item has already expired
|
|
612
610
|
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
613
611
|
this.delete(key);
|
|
@@ -621,10 +619,10 @@ class FifoMap {
|
|
|
621
619
|
}
|
|
622
620
|
|
|
623
621
|
getMany(keys) {
|
|
624
|
-
const result =
|
|
622
|
+
const result = new Array(keys.length);
|
|
625
623
|
|
|
626
624
|
for (var i = 0; i < keys.length; i++) {
|
|
627
|
-
result
|
|
625
|
+
result[i] = this.get(keys[i]);
|
|
628
626
|
}
|
|
629
627
|
|
|
630
628
|
return result
|
|
@@ -636,21 +634,18 @@ class FifoMap {
|
|
|
636
634
|
|
|
637
635
|
set(key, value) {
|
|
638
636
|
// Replace existing item
|
|
639
|
-
|
|
640
|
-
const item = this.items[key];
|
|
641
|
-
item.value = value;
|
|
637
|
+
const existing = this.items[key];
|
|
642
638
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
}
|
|
639
|
+
if (existing !== undefined) {
|
|
640
|
+
existing.value = value;
|
|
641
|
+
existing.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
642
|
+
this.bumpLru(existing);
|
|
648
643
|
|
|
649
644
|
return
|
|
650
645
|
}
|
|
651
646
|
|
|
652
647
|
// Add new item
|
|
653
|
-
if (this.max > 0 && this.size
|
|
648
|
+
if (this.max > 0 && this.size >= this.max) {
|
|
654
649
|
this.evict();
|
|
655
650
|
}
|
|
656
651
|
|
|
@@ -688,32 +683,24 @@ function getTimestamp(date) {
|
|
|
688
683
|
|
|
689
684
|
this.collectionStart = new Date();
|
|
690
685
|
this.currentTimeStamp = getTimestamp(this.collectionStart);
|
|
686
|
+
this.archiveAfter = this.collectionStart.getTime() + this.statisticTtlInHours * 3_600_000;
|
|
691
687
|
|
|
692
688
|
this.records = globalStatisticsRecord || new HitStatisticsRecord();
|
|
693
689
|
this.records.initForCache(this.cacheId, this.currentTimeStamp);
|
|
694
690
|
}
|
|
695
691
|
|
|
696
692
|
get currentRecord() {
|
|
693
|
+
const cacheRecords = this.records.records[this.cacheId];
|
|
697
694
|
// safety net
|
|
698
|
-
/* c8 ignore next
|
|
699
|
-
if (!
|
|
700
|
-
|
|
701
|
-
cacheSize: 0,
|
|
702
|
-
hits: 0,
|
|
703
|
-
falsyHits: 0,
|
|
704
|
-
emptyHits: 0,
|
|
705
|
-
misses: 0,
|
|
706
|
-
expirations: 0,
|
|
707
|
-
evictions: 0,
|
|
708
|
-
sets: 0,
|
|
709
|
-
invalidateOne: 0,
|
|
710
|
-
invalidateAll: 0,
|
|
711
|
-
};
|
|
695
|
+
/* c8 ignore next 3 */
|
|
696
|
+
if (!cacheRecords[this.currentTimeStamp]) {
|
|
697
|
+
cacheRecords[this.currentTimeStamp] = createEmptyStatisticsRecord();
|
|
712
698
|
}
|
|
713
699
|
|
|
714
|
-
return
|
|
700
|
+
return cacheRecords[this.currentTimeStamp]
|
|
715
701
|
}
|
|
716
702
|
|
|
703
|
+
/* v8 ignore next 3 -- kept for compatibility, no longer used internally */
|
|
717
704
|
hoursPassed() {
|
|
718
705
|
return (Date.now() - this.collectionStart) / 1000 / 60 / 60
|
|
719
706
|
}
|
|
@@ -772,15 +759,19 @@ function getTimestamp(date) {
|
|
|
772
759
|
}
|
|
773
760
|
|
|
774
761
|
archiveIfNeeded() {
|
|
775
|
-
if (
|
|
762
|
+
if (Date.now() >= this.archiveAfter) {
|
|
776
763
|
this.collectionStart = new Date();
|
|
777
764
|
this.currentTimeStamp = getTimestamp(this.collectionStart);
|
|
765
|
+
this.archiveAfter = this.collectionStart.getTime() + this.statisticTtlInHours * 3_600_000;
|
|
778
766
|
this.records.initForCache(this.cacheId, this.currentTimeStamp);
|
|
779
767
|
}
|
|
780
768
|
}
|
|
781
769
|
}class LruObjectHitStatistics extends LruObject {
|
|
782
770
|
constructor(max, ttlInMsecs, cacheId, globalStatisticsRecord, statisticTtlInHours) {
|
|
783
|
-
|
|
771
|
+
// Pass through as-is: the base constructor applies the 1000/0 defaults for
|
|
772
|
+
// omitted (undefined) values and validates everything else, so explicit 0
|
|
773
|
+
// stays unlimited and null/NaN are rejected the same way as the base class.
|
|
774
|
+
super(max, ttlInMsecs);
|
|
784
775
|
|
|
785
776
|
if (!cacheId) {
|
|
786
777
|
throw new Error('Cache id is mandatory')
|
|
@@ -804,15 +795,19 @@ function getTimestamp(date) {
|
|
|
804
795
|
}
|
|
805
796
|
|
|
806
797
|
evict() {
|
|
798
|
+
const hadItems = this.size > 0;
|
|
807
799
|
super.evict();
|
|
808
|
-
|
|
800
|
+
if (hadItems) {
|
|
801
|
+
this.hitStatistics.addEviction();
|
|
802
|
+
}
|
|
809
803
|
this.hitStatistics.setCacheSize(this.size);
|
|
810
804
|
}
|
|
811
805
|
|
|
812
806
|
delete(key, isExpiration = false) {
|
|
807
|
+
const existed = this.items[key] !== undefined;
|
|
813
808
|
super.delete(key);
|
|
814
809
|
|
|
815
|
-
if (!isExpiration) {
|
|
810
|
+
if (existed && !isExpiration) {
|
|
816
811
|
this.hitStatistics.addInvalidateOne();
|
|
817
812
|
}
|
|
818
813
|
this.hitStatistics.setCacheSize(this.size);
|
|
@@ -826,9 +821,9 @@ function getTimestamp(date) {
|
|
|
826
821
|
}
|
|
827
822
|
|
|
828
823
|
get(key) {
|
|
829
|
-
|
|
830
|
-
const item = this.items[key];
|
|
824
|
+
const item = this.items[key];
|
|
831
825
|
|
|
826
|
+
if (item !== undefined) {
|
|
832
827
|
// Item has already expired
|
|
833
828
|
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
834
829
|
this.delete(key, true);
|
|
@@ -840,9 +835,10 @@ function getTimestamp(date) {
|
|
|
840
835
|
this.bumpLru(item);
|
|
841
836
|
if (!item.value) {
|
|
842
837
|
this.hitStatistics.addFalsyHit();
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
838
|
+
// Empty values are a subset of falsy values
|
|
839
|
+
if (item.value === undefined || item.value === null || item.value === '') {
|
|
840
|
+
this.hitStatistics.addEmptyHit();
|
|
841
|
+
}
|
|
846
842
|
}
|
|
847
843
|
this.hitStatistics.addHit();
|
|
848
844
|
return item.value
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toad-cache",
|
|
3
3
|
"description": "LRU and FIFO caches for Client or Server",
|
|
4
|
-
"version": "3.7.
|
|
4
|
+
"version": "3.7.4",
|
|
5
5
|
"homepage": "https://github.com/kibertoad/toad-cache",
|
|
6
6
|
"author": "Igor Savin <kibertoad@gmail.com>",
|
|
7
7
|
"repository": {
|
|
@@ -41,20 +41,20 @@
|
|
|
41
41
|
"devEngines": {
|
|
42
42
|
"runtime": {
|
|
43
43
|
"name": "node",
|
|
44
|
-
"version": ">=
|
|
44
|
+
"version": ">=22.13",
|
|
45
45
|
"onFail": "error"
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@biomejs/biome": "^2.
|
|
50
|
-
"@vitest/coverage-v8": "^4.1.
|
|
51
|
-
"auto-changelog": "^2.
|
|
49
|
+
"@biomejs/biome": "^2.5.2",
|
|
50
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
51
|
+
"auto-changelog": "^2.6.0",
|
|
52
52
|
"del-cli": "^7.0.0",
|
|
53
53
|
"precise": "^5.0.1",
|
|
54
|
-
"rollup": "^4.
|
|
54
|
+
"rollup": "^4.62.2",
|
|
55
55
|
"tsd": "^0.33.0",
|
|
56
56
|
"typescript": "~6.0.3",
|
|
57
|
-
"vitest": "^4.1.
|
|
57
|
+
"vitest": "^4.1.9"
|
|
58
58
|
},
|
|
59
59
|
"keywords": [
|
|
60
60
|
"LRU",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"lint:fix": "biome check --apply index.js benchmark.js src test biome.json",
|
|
77
77
|
"rollup": "rollup --config",
|
|
78
78
|
"test": "vitest",
|
|
79
|
-
"test:coverage": "pnpm run rollup &&
|
|
79
|
+
"test:coverage": "pnpm run rollup && vitest --coverage",
|
|
80
80
|
"test:ci": "pnpm run lint && pnpm run test:coverage && pnpm run test:typescript",
|
|
81
81
|
"test:typescript": "tsd",
|
|
82
82
|
"types:generate": "pnpm exec tsc index.js --declaration --allowJs --emitDeclarationOnly --outDir ."
|
|
@@ -8,6 +8,19 @@ type CacheEntry<T> = {
|
|
|
8
8
|
value: T
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
type CacheStatistics = {
|
|
12
|
+
expirations: number,
|
|
13
|
+
evictions: number,
|
|
14
|
+
hits: number,
|
|
15
|
+
emptyHits: number,
|
|
16
|
+
falsyHits: number,
|
|
17
|
+
misses: number,
|
|
18
|
+
invalidateAll: number,
|
|
19
|
+
invalidateOne: number,
|
|
20
|
+
cacheSize: number,
|
|
21
|
+
sets: number,
|
|
22
|
+
}
|
|
23
|
+
|
|
11
24
|
interface ToadCache<T> {
|
|
12
25
|
first: any;
|
|
13
26
|
last: any;
|
|
@@ -28,7 +41,7 @@ interface ToadCache<T> {
|
|
|
28
41
|
declare class FifoMap<T> implements ToadCache<T>{
|
|
29
42
|
constructor(max?: number, ttlInMsecs?: number);
|
|
30
43
|
first: any;
|
|
31
|
-
items: Map<any, T
|
|
44
|
+
items: Map<any, CacheEntry<T>>;
|
|
32
45
|
last: any;
|
|
33
46
|
max: number;
|
|
34
47
|
ttl: number;
|
|
@@ -66,7 +79,7 @@ declare class FifoObject<T> implements ToadCache<T> {
|
|
|
66
79
|
declare class LruMap<T> implements ToadCache<T> {
|
|
67
80
|
constructor(max?: number, ttlInMsecs?: number);
|
|
68
81
|
first: any;
|
|
69
|
-
items: Map<any, T
|
|
82
|
+
items: Map<any, CacheEntry<T>>;
|
|
70
83
|
last: any;
|
|
71
84
|
max: number;
|
|
72
85
|
ttl: number;
|
|
@@ -103,29 +116,22 @@ declare class LruObject<T> implements ToadCache<T> {
|
|
|
103
116
|
}
|
|
104
117
|
|
|
105
118
|
declare class HitStatisticsRecord {
|
|
106
|
-
records: Record<string, Record<string,
|
|
107
|
-
expirations: number,
|
|
108
|
-
evictions: number,
|
|
109
|
-
hits: number,
|
|
110
|
-
emptyHits: number,
|
|
111
|
-
falsyHits: number,
|
|
112
|
-
misses: number,
|
|
113
|
-
invalidateAll: number,
|
|
114
|
-
invalidateOne: number,
|
|
115
|
-
cacheSize: number,
|
|
116
|
-
sets: number,
|
|
117
|
-
}>>
|
|
119
|
+
records: Record<string, Record<string, CacheStatistics>>
|
|
118
120
|
|
|
119
121
|
initForCache(cacheId: string, currentTimeStamp: string): void
|
|
120
122
|
resetForCache(cacheId: string): void
|
|
123
|
+
getStatistics(): Record<string, Record<string, CacheStatistics>>
|
|
121
124
|
}
|
|
122
125
|
|
|
123
126
|
declare class LruObjectHitStatistics<T> extends LruObject<T>{
|
|
124
127
|
constructor(max?: number, ttlInMsecs?: number, cacheId?: string, globalStatisticsRecord?: HitStatisticsRecord, statisticTtlInHours?: number);
|
|
128
|
+
getStatistics(): Record<string, Record<string, CacheStatistics>>
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
export {
|
|
128
132
|
CacheConstructor,
|
|
133
|
+
CacheEntry,
|
|
134
|
+
CacheStatistics,
|
|
129
135
|
ToadCache,
|
|
130
136
|
LruObject,
|
|
131
137
|
LruMap,
|