@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
|
@@ -144,7 +144,7 @@ console.log(cache.keys())
|
|
|
144
144
|
|
|
145
145
|
### Property
|
|
146
146
|
|
|
147
|
-
Max items to hold in cache (1000)
|
|
147
|
+
Max items to hold in cache (1000). Must be a non-negative integer; `0` means no size limit.
|
|
148
148
|
|
|
149
149
|
**Example**
|
|
150
150
|
|
|
@@ -201,7 +201,7 @@ cache.size // 0 - it's a new cache!
|
|
|
201
201
|
|
|
202
202
|
### Property
|
|
203
203
|
|
|
204
|
-
Milliseconds an item will remain in cache; lazy expiration upon next `get()` of an item
|
|
204
|
+
Milliseconds an item will remain in cache; lazy expiration upon next `get()` of an item. Must be a non-negative integer; `0` disables expiration.
|
|
205
205
|
|
|
206
206
|
**Example**
|
|
207
207
|
|
|
@@ -211,6 +211,8 @@ const cache = new Lru()
|
|
|
211
211
|
cache.ttl = 3e4
|
|
212
212
|
```
|
|
213
213
|
|
|
214
|
+
Note: entries stored while `ttl` was `0` have no expiry timestamp, so enabling a TTL at runtime immediately expires them on their next `get()`. Prefer setting the TTL via the constructor.
|
|
215
|
+
|
|
214
216
|
## Hit/miss/expiration tracking
|
|
215
217
|
|
|
216
218
|
In case you want to gather information on cache hit/miss/expiration ratio, as well as cache size and eviction statistics, you can use LruHitStatistics class:
|
|
@@ -218,13 +220,12 @@ In case you want to gather information on cache hit/miss/expiration ratio, as we
|
|
|
218
220
|
```js
|
|
219
221
|
const sharedRecord = new HitStatisticsRecord() // if you want to use single record object for all of caches, create it manually and pass to each cache
|
|
220
222
|
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
})
|
|
223
|
+
const max = 1000
|
|
224
|
+
const ttlInMsecs = 0
|
|
225
|
+
const cacheId = 'some-cache-id'
|
|
226
|
+
const statisticTtlInHours = 24 // how often to reset statistics. On every rotation previously accumulated data is removed
|
|
227
|
+
|
|
228
|
+
const cache = new LruHitStatistics(max, ttlInMsecs, cacheId, sharedRecord, statisticTtlInHours)
|
|
228
229
|
```
|
|
229
230
|
|
|
230
231
|
You can retrieve accumulated statistics from the cache, or from the record directly:
|
|
@@ -3,19 +3,30 @@
|
|
|
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
8
|
'use strict';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Validates the shared cache constructor parameters.
|
|
12
|
+
* Both values must be non-negative integers.
|
|
13
|
+
*
|
|
14
|
+
* @param {number} max
|
|
15
|
+
* @param {number} ttlInMsecs
|
|
16
|
+
*/
|
|
17
|
+
function validateCacheParams(max, ttlInMsecs) {
|
|
18
|
+
if (typeof max !== 'number' || !Number.isInteger(max) || max < 0) {
|
|
19
|
+
throw new Error('Invalid max value')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (typeof ttlInMsecs !== 'number' || !Number.isInteger(ttlInMsecs) || ttlInMsecs < 0) {
|
|
23
|
+
throw new Error('Invalid ttl value')
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
10
27
|
class FifoMap {
|
|
11
28
|
constructor(max = 1000, ttlInMsecs = 0) {
|
|
12
|
-
|
|
13
|
-
throw new Error('Invalid max value')
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
|
|
17
|
-
throw new Error('Invalid ttl value')
|
|
18
|
-
}
|
|
29
|
+
validateCacheParams(max, ttlInMsecs);
|
|
19
30
|
|
|
20
31
|
this.first = null;
|
|
21
32
|
this.items = new Map();
|
|
@@ -29,15 +40,15 @@ class FifoMap {
|
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
clear() {
|
|
32
|
-
this.items
|
|
43
|
+
this.items.clear();
|
|
33
44
|
this.first = null;
|
|
34
45
|
this.last = null;
|
|
35
46
|
}
|
|
36
47
|
|
|
37
48
|
delete(key) {
|
|
38
|
-
|
|
39
|
-
const deletedItem = this.items.get(key);
|
|
49
|
+
const deletedItem = this.items.get(key);
|
|
40
50
|
|
|
51
|
+
if (deletedItem !== undefined) {
|
|
41
52
|
this.items.delete(key);
|
|
42
53
|
|
|
43
54
|
if (deletedItem.prev !== null) {
|
|
@@ -81,15 +92,17 @@ class FifoMap {
|
|
|
81
92
|
}
|
|
82
93
|
|
|
83
94
|
expiresAt(key) {
|
|
84
|
-
|
|
85
|
-
|
|
95
|
+
const item = this.items.get(key);
|
|
96
|
+
|
|
97
|
+
if (item !== undefined) {
|
|
98
|
+
return item.expiry
|
|
86
99
|
}
|
|
87
100
|
}
|
|
88
101
|
|
|
89
102
|
get(key) {
|
|
90
|
-
|
|
91
|
-
const item = this.items.get(key);
|
|
103
|
+
const item = this.items.get(key);
|
|
92
104
|
|
|
105
|
+
if (item !== undefined) {
|
|
93
106
|
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
94
107
|
this.delete(key);
|
|
95
108
|
return
|
|
@@ -100,10 +113,10 @@ class FifoMap {
|
|
|
100
113
|
}
|
|
101
114
|
|
|
102
115
|
getMany(keys) {
|
|
103
|
-
const result =
|
|
116
|
+
const result = new Array(keys.length);
|
|
104
117
|
|
|
105
118
|
for (var i = 0; i < keys.length; i++) {
|
|
106
|
-
result
|
|
119
|
+
result[i] = this.get(keys[i]);
|
|
107
120
|
}
|
|
108
121
|
|
|
109
122
|
return result
|
|
@@ -115,17 +128,17 @@ class FifoMap {
|
|
|
115
128
|
|
|
116
129
|
set(key, value) {
|
|
117
130
|
// Replace existing item
|
|
118
|
-
|
|
119
|
-
const item = this.items.get(key);
|
|
120
|
-
item.value = value;
|
|
131
|
+
const existing = this.items.get(key);
|
|
121
132
|
|
|
122
|
-
|
|
133
|
+
if (existing !== undefined) {
|
|
134
|
+
existing.value = value;
|
|
135
|
+
existing.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
123
136
|
|
|
124
137
|
return
|
|
125
138
|
}
|
|
126
139
|
|
|
127
140
|
// Add new item
|
|
128
|
-
if (this.max > 0 && this.size
|
|
141
|
+
if (this.max > 0 && this.size >= this.max) {
|
|
129
142
|
this.evict();
|
|
130
143
|
}
|
|
131
144
|
|
|
@@ -150,13 +163,7 @@ class FifoMap {
|
|
|
150
163
|
|
|
151
164
|
class FifoObject {
|
|
152
165
|
constructor(max = 1000, ttlInMsecs = 0) {
|
|
153
|
-
|
|
154
|
-
throw new Error('Invalid max value')
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
|
|
158
|
-
throw new Error('Invalid ttl value')
|
|
159
|
-
}
|
|
166
|
+
validateCacheParams(max, ttlInMsecs);
|
|
160
167
|
|
|
161
168
|
this.first = null;
|
|
162
169
|
this.items = Object.create(null);
|
|
@@ -174,9 +181,9 @@ class FifoObject {
|
|
|
174
181
|
}
|
|
175
182
|
|
|
176
183
|
delete(key) {
|
|
177
|
-
|
|
178
|
-
const deletedItem = this.items[key];
|
|
184
|
+
const deletedItem = this.items[key];
|
|
179
185
|
|
|
186
|
+
if (deletedItem !== undefined) {
|
|
180
187
|
delete this.items[key];
|
|
181
188
|
this.size--;
|
|
182
189
|
|
|
@@ -221,15 +228,17 @@ class FifoObject {
|
|
|
221
228
|
}
|
|
222
229
|
|
|
223
230
|
expiresAt(key) {
|
|
224
|
-
|
|
225
|
-
|
|
231
|
+
const item = this.items[key];
|
|
232
|
+
|
|
233
|
+
if (item !== undefined) {
|
|
234
|
+
return item.expiry
|
|
226
235
|
}
|
|
227
236
|
}
|
|
228
237
|
|
|
229
238
|
get(key) {
|
|
230
|
-
|
|
231
|
-
const item = this.items[key];
|
|
239
|
+
const item = this.items[key];
|
|
232
240
|
|
|
241
|
+
if (item !== undefined) {
|
|
233
242
|
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
234
243
|
this.delete(key);
|
|
235
244
|
return
|
|
@@ -240,10 +249,10 @@ class FifoObject {
|
|
|
240
249
|
}
|
|
241
250
|
|
|
242
251
|
getMany(keys) {
|
|
243
|
-
const result =
|
|
252
|
+
const result = new Array(keys.length);
|
|
244
253
|
|
|
245
254
|
for (var i = 0; i < keys.length; i++) {
|
|
246
|
-
result
|
|
255
|
+
result[i] = this.get(keys[i]);
|
|
247
256
|
}
|
|
248
257
|
|
|
249
258
|
return result
|
|
@@ -255,17 +264,17 @@ class FifoObject {
|
|
|
255
264
|
|
|
256
265
|
set(key, value) {
|
|
257
266
|
// Replace existing item
|
|
258
|
-
|
|
259
|
-
const item = this.items[key];
|
|
260
|
-
item.value = value;
|
|
267
|
+
const existing = this.items[key];
|
|
261
268
|
|
|
262
|
-
|
|
269
|
+
if (existing !== undefined) {
|
|
270
|
+
existing.value = value;
|
|
271
|
+
existing.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
263
272
|
|
|
264
273
|
return
|
|
265
274
|
}
|
|
266
275
|
|
|
267
276
|
// Add new item
|
|
268
|
-
if (this.max > 0 && this.size
|
|
277
|
+
if (this.max > 0 && this.size >= this.max) {
|
|
269
278
|
this.evict();
|
|
270
279
|
}
|
|
271
280
|
|
|
@@ -288,6 +297,26 @@ class FifoObject {
|
|
|
288
297
|
}
|
|
289
298
|
}
|
|
290
299
|
|
|
300
|
+
/**
|
|
301
|
+
* Creates a zeroed statistics record for a single collection window.
|
|
302
|
+
*
|
|
303
|
+
* @returns {object}
|
|
304
|
+
*/
|
|
305
|
+
function createEmptyStatisticsRecord() {
|
|
306
|
+
return {
|
|
307
|
+
cacheSize: 0,
|
|
308
|
+
hits: 0,
|
|
309
|
+
falsyHits: 0,
|
|
310
|
+
emptyHits: 0,
|
|
311
|
+
misses: 0,
|
|
312
|
+
expirations: 0,
|
|
313
|
+
evictions: 0,
|
|
314
|
+
invalidateOne: 0,
|
|
315
|
+
invalidateAll: 0,
|
|
316
|
+
sets: 0,
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
291
320
|
class HitStatisticsRecord {
|
|
292
321
|
constructor() {
|
|
293
322
|
this.records = {};
|
|
@@ -295,35 +324,17 @@ class HitStatisticsRecord {
|
|
|
295
324
|
|
|
296
325
|
initForCache(cacheId, currentTimeStamp) {
|
|
297
326
|
this.records[cacheId] = {
|
|
298
|
-
[currentTimeStamp]:
|
|
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
|
-
},
|
|
327
|
+
[currentTimeStamp]: createEmptyStatisticsRecord(),
|
|
310
328
|
};
|
|
311
329
|
}
|
|
312
330
|
|
|
313
331
|
resetForCache(cacheId) {
|
|
332
|
+
if (!this.records[cacheId]) {
|
|
333
|
+
return
|
|
334
|
+
}
|
|
335
|
+
|
|
314
336
|
for (let key of Object.keys(this.records[cacheId])) {
|
|
315
|
-
this.records[cacheId][key] =
|
|
316
|
-
cacheSize: 0,
|
|
317
|
-
hits: 0,
|
|
318
|
-
falsyHits: 0,
|
|
319
|
-
emptyHits: 0,
|
|
320
|
-
misses: 0,
|
|
321
|
-
expirations: 0,
|
|
322
|
-
evictions: 0,
|
|
323
|
-
invalidateOne: 0,
|
|
324
|
-
invalidateAll: 0,
|
|
325
|
-
sets: 0,
|
|
326
|
-
};
|
|
337
|
+
this.records[cacheId][key] = createEmptyStatisticsRecord();
|
|
327
338
|
}
|
|
328
339
|
}
|
|
329
340
|
|
|
@@ -334,13 +345,7 @@ class HitStatisticsRecord {
|
|
|
334
345
|
|
|
335
346
|
class LruMap {
|
|
336
347
|
constructor(max = 1000, ttlInMsecs = 0) {
|
|
337
|
-
|
|
338
|
-
throw new Error('Invalid max value')
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
|
|
342
|
-
throw new Error('Invalid ttl value')
|
|
343
|
-
}
|
|
348
|
+
validateCacheParams(max, ttlInMsecs);
|
|
344
349
|
|
|
345
350
|
this.first = null;
|
|
346
351
|
this.items = new Map();
|
|
@@ -374,6 +379,7 @@ class LruMap {
|
|
|
374
379
|
prev.next = next;
|
|
375
380
|
}
|
|
376
381
|
|
|
382
|
+
/* v8 ignore next 3 -- next is always non-null here: the early return above guarantees item !== this.last in a well-formed list */
|
|
377
383
|
if (next !== null) {
|
|
378
384
|
next.prev = prev;
|
|
379
385
|
}
|
|
@@ -382,15 +388,15 @@ class LruMap {
|
|
|
382
388
|
}
|
|
383
389
|
|
|
384
390
|
clear() {
|
|
385
|
-
this.items
|
|
391
|
+
this.items.clear();
|
|
386
392
|
this.first = null;
|
|
387
393
|
this.last = null;
|
|
388
394
|
}
|
|
389
395
|
|
|
390
396
|
delete(key) {
|
|
391
|
-
|
|
392
|
-
const item = this.items.get(key);
|
|
397
|
+
const item = this.items.get(key);
|
|
393
398
|
|
|
399
|
+
if (item !== undefined) {
|
|
394
400
|
this.items.delete(key);
|
|
395
401
|
|
|
396
402
|
if (item.prev !== null) {
|
|
@@ -434,15 +440,17 @@ class LruMap {
|
|
|
434
440
|
}
|
|
435
441
|
|
|
436
442
|
expiresAt(key) {
|
|
437
|
-
|
|
438
|
-
|
|
443
|
+
const item = this.items.get(key);
|
|
444
|
+
|
|
445
|
+
if (item !== undefined) {
|
|
446
|
+
return item.expiry
|
|
439
447
|
}
|
|
440
448
|
}
|
|
441
449
|
|
|
442
450
|
get(key) {
|
|
443
|
-
|
|
444
|
-
const item = this.items.get(key);
|
|
451
|
+
const item = this.items.get(key);
|
|
445
452
|
|
|
453
|
+
if (item !== undefined) {
|
|
446
454
|
// Item has already expired
|
|
447
455
|
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
448
456
|
this.delete(key);
|
|
@@ -456,10 +464,10 @@ class LruMap {
|
|
|
456
464
|
}
|
|
457
465
|
|
|
458
466
|
getMany(keys) {
|
|
459
|
-
const result =
|
|
467
|
+
const result = new Array(keys.length);
|
|
460
468
|
|
|
461
469
|
for (var i = 0; i < keys.length; i++) {
|
|
462
|
-
result
|
|
470
|
+
result[i] = this.get(keys[i]);
|
|
463
471
|
}
|
|
464
472
|
|
|
465
473
|
return result
|
|
@@ -471,21 +479,18 @@ class LruMap {
|
|
|
471
479
|
|
|
472
480
|
set(key, value) {
|
|
473
481
|
// Replace existing item
|
|
474
|
-
|
|
475
|
-
const item = this.items.get(key);
|
|
476
|
-
item.value = value;
|
|
482
|
+
const existing = this.items.get(key);
|
|
477
483
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
}
|
|
484
|
+
if (existing !== undefined) {
|
|
485
|
+
existing.value = value;
|
|
486
|
+
existing.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
487
|
+
this.bumpLru(existing);
|
|
483
488
|
|
|
484
489
|
return
|
|
485
490
|
}
|
|
486
491
|
|
|
487
492
|
// Add new item
|
|
488
|
-
if (this.max > 0 && this.size
|
|
493
|
+
if (this.max > 0 && this.size >= this.max) {
|
|
489
494
|
this.evict();
|
|
490
495
|
}
|
|
491
496
|
|
|
@@ -510,13 +515,7 @@ class LruMap {
|
|
|
510
515
|
|
|
511
516
|
class LruObject {
|
|
512
517
|
constructor(max = 1000, ttlInMsecs = 0) {
|
|
513
|
-
|
|
514
|
-
throw new Error('Invalid max value')
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
if (isNaN(ttlInMsecs) || ttlInMsecs < 0) {
|
|
518
|
-
throw new Error('Invalid ttl value')
|
|
519
|
-
}
|
|
518
|
+
validateCacheParams(max, ttlInMsecs);
|
|
520
519
|
|
|
521
520
|
this.first = null;
|
|
522
521
|
this.items = Object.create(null);
|
|
@@ -547,6 +546,7 @@ class LruObject {
|
|
|
547
546
|
prev.next = next;
|
|
548
547
|
}
|
|
549
548
|
|
|
549
|
+
/* v8 ignore next 3 -- next is always non-null here: the early return above guarantees item !== this.last in a well-formed list */
|
|
550
550
|
if (next !== null) {
|
|
551
551
|
next.prev = prev;
|
|
552
552
|
}
|
|
@@ -562,9 +562,9 @@ class LruObject {
|
|
|
562
562
|
}
|
|
563
563
|
|
|
564
564
|
delete(key) {
|
|
565
|
-
|
|
566
|
-
const item = this.items[key];
|
|
565
|
+
const item = this.items[key];
|
|
567
566
|
|
|
567
|
+
if (item !== undefined) {
|
|
568
568
|
delete this.items[key];
|
|
569
569
|
this.size--;
|
|
570
570
|
|
|
@@ -609,15 +609,17 @@ class LruObject {
|
|
|
609
609
|
}
|
|
610
610
|
|
|
611
611
|
expiresAt(key) {
|
|
612
|
-
|
|
613
|
-
|
|
612
|
+
const item = this.items[key];
|
|
613
|
+
|
|
614
|
+
if (item !== undefined) {
|
|
615
|
+
return item.expiry
|
|
614
616
|
}
|
|
615
617
|
}
|
|
616
618
|
|
|
617
619
|
get(key) {
|
|
618
|
-
|
|
619
|
-
const item = this.items[key];
|
|
620
|
+
const item = this.items[key];
|
|
620
621
|
|
|
622
|
+
if (item !== undefined) {
|
|
621
623
|
// Item has already expired
|
|
622
624
|
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
623
625
|
this.delete(key);
|
|
@@ -631,10 +633,10 @@ class LruObject {
|
|
|
631
633
|
}
|
|
632
634
|
|
|
633
635
|
getMany(keys) {
|
|
634
|
-
const result =
|
|
636
|
+
const result = new Array(keys.length);
|
|
635
637
|
|
|
636
638
|
for (var i = 0; i < keys.length; i++) {
|
|
637
|
-
result
|
|
639
|
+
result[i] = this.get(keys[i]);
|
|
638
640
|
}
|
|
639
641
|
|
|
640
642
|
return result
|
|
@@ -646,21 +648,18 @@ class LruObject {
|
|
|
646
648
|
|
|
647
649
|
set(key, value) {
|
|
648
650
|
// Replace existing item
|
|
649
|
-
|
|
650
|
-
const item = this.items[key];
|
|
651
|
-
item.value = value;
|
|
652
|
-
|
|
653
|
-
item.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
651
|
+
const existing = this.items[key];
|
|
654
652
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
653
|
+
if (existing !== undefined) {
|
|
654
|
+
existing.value = value;
|
|
655
|
+
existing.expiry = this.ttl > 0 ? Date.now() + this.ttl : this.ttl;
|
|
656
|
+
this.bumpLru(existing);
|
|
658
657
|
|
|
659
658
|
return
|
|
660
659
|
}
|
|
661
660
|
|
|
662
661
|
// Add new item
|
|
663
|
-
if (this.max > 0 && this.size
|
|
662
|
+
if (this.max > 0 && this.size >= this.max) {
|
|
664
663
|
this.evict();
|
|
665
664
|
}
|
|
666
665
|
|
|
@@ -702,32 +701,24 @@ class HitStatistics {
|
|
|
702
701
|
|
|
703
702
|
this.collectionStart = new Date();
|
|
704
703
|
this.currentTimeStamp = getTimestamp(this.collectionStart);
|
|
704
|
+
this.archiveAfter = this.collectionStart.getTime() + this.statisticTtlInHours * 3_600_000;
|
|
705
705
|
|
|
706
706
|
this.records = globalStatisticsRecord || new HitStatisticsRecord();
|
|
707
707
|
this.records.initForCache(this.cacheId, this.currentTimeStamp);
|
|
708
708
|
}
|
|
709
709
|
|
|
710
710
|
get currentRecord() {
|
|
711
|
+
const cacheRecords = this.records.records[this.cacheId];
|
|
711
712
|
// safety net
|
|
712
|
-
/* c8 ignore next
|
|
713
|
-
if (!
|
|
714
|
-
|
|
715
|
-
cacheSize: 0,
|
|
716
|
-
hits: 0,
|
|
717
|
-
falsyHits: 0,
|
|
718
|
-
emptyHits: 0,
|
|
719
|
-
misses: 0,
|
|
720
|
-
expirations: 0,
|
|
721
|
-
evictions: 0,
|
|
722
|
-
sets: 0,
|
|
723
|
-
invalidateOne: 0,
|
|
724
|
-
invalidateAll: 0,
|
|
725
|
-
};
|
|
713
|
+
/* c8 ignore next 3 */
|
|
714
|
+
if (!cacheRecords[this.currentTimeStamp]) {
|
|
715
|
+
cacheRecords[this.currentTimeStamp] = createEmptyStatisticsRecord();
|
|
726
716
|
}
|
|
727
717
|
|
|
728
|
-
return
|
|
718
|
+
return cacheRecords[this.currentTimeStamp]
|
|
729
719
|
}
|
|
730
720
|
|
|
721
|
+
/* v8 ignore next 3 -- kept for compatibility, no longer used internally */
|
|
731
722
|
hoursPassed() {
|
|
732
723
|
return (Date.now() - this.collectionStart) / 1000 / 60 / 60
|
|
733
724
|
}
|
|
@@ -786,9 +777,10 @@ class HitStatistics {
|
|
|
786
777
|
}
|
|
787
778
|
|
|
788
779
|
archiveIfNeeded() {
|
|
789
|
-
if (
|
|
780
|
+
if (Date.now() >= this.archiveAfter) {
|
|
790
781
|
this.collectionStart = new Date();
|
|
791
782
|
this.currentTimeStamp = getTimestamp(this.collectionStart);
|
|
783
|
+
this.archiveAfter = this.collectionStart.getTime() + this.statisticTtlInHours * 3_600_000;
|
|
792
784
|
this.records.initForCache(this.cacheId, this.currentTimeStamp);
|
|
793
785
|
}
|
|
794
786
|
}
|
|
@@ -796,7 +788,10 @@ class HitStatistics {
|
|
|
796
788
|
|
|
797
789
|
class LruObjectHitStatistics extends LruObject {
|
|
798
790
|
constructor(max, ttlInMsecs, cacheId, globalStatisticsRecord, statisticTtlInHours) {
|
|
799
|
-
|
|
791
|
+
// Pass through as-is: the base constructor applies the 1000/0 defaults for
|
|
792
|
+
// omitted (undefined) values and validates everything else, so explicit 0
|
|
793
|
+
// stays unlimited and null/NaN are rejected the same way as the base class.
|
|
794
|
+
super(max, ttlInMsecs);
|
|
800
795
|
|
|
801
796
|
if (!cacheId) {
|
|
802
797
|
throw new Error('Cache id is mandatory')
|
|
@@ -820,15 +815,19 @@ class LruObjectHitStatistics extends LruObject {
|
|
|
820
815
|
}
|
|
821
816
|
|
|
822
817
|
evict() {
|
|
818
|
+
const hadItems = this.size > 0;
|
|
823
819
|
super.evict();
|
|
824
|
-
|
|
820
|
+
if (hadItems) {
|
|
821
|
+
this.hitStatistics.addEviction();
|
|
822
|
+
}
|
|
825
823
|
this.hitStatistics.setCacheSize(this.size);
|
|
826
824
|
}
|
|
827
825
|
|
|
828
826
|
delete(key, isExpiration = false) {
|
|
827
|
+
const existed = this.items[key] !== undefined;
|
|
829
828
|
super.delete(key);
|
|
830
829
|
|
|
831
|
-
if (!isExpiration) {
|
|
830
|
+
if (existed && !isExpiration) {
|
|
832
831
|
this.hitStatistics.addInvalidateOne();
|
|
833
832
|
}
|
|
834
833
|
this.hitStatistics.setCacheSize(this.size);
|
|
@@ -842,9 +841,9 @@ class LruObjectHitStatistics extends LruObject {
|
|
|
842
841
|
}
|
|
843
842
|
|
|
844
843
|
get(key) {
|
|
845
|
-
|
|
846
|
-
const item = this.items[key];
|
|
844
|
+
const item = this.items[key];
|
|
847
845
|
|
|
846
|
+
if (item !== undefined) {
|
|
848
847
|
// Item has already expired
|
|
849
848
|
if (this.ttl > 0 && item.expiry <= Date.now()) {
|
|
850
849
|
this.delete(key, true);
|
|
@@ -856,9 +855,10 @@ class LruObjectHitStatistics extends LruObject {
|
|
|
856
855
|
this.bumpLru(item);
|
|
857
856
|
if (!item.value) {
|
|
858
857
|
this.hitStatistics.addFalsyHit();
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
858
|
+
// Empty values are a subset of falsy values
|
|
859
|
+
if (item.value === undefined || item.value === null || item.value === '') {
|
|
860
|
+
this.hitStatistics.addEmptyHit();
|
|
861
|
+
}
|
|
862
862
|
}
|
|
863
863
|
this.hitStatistics.addHit();
|
|
864
864
|
return item.value
|