serializable-bptree 5.1.0 → 5.1.2
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 +4 -0
- package/dist/cjs/index.cjs +482 -36
- package/dist/esm/index.mjs +482 -36
- package/dist/types/BPTreeAsync.d.ts +4 -2
- package/dist/types/BPTreeSync.d.ts +4 -2
- package/dist/types/base/BPTree.d.ts +21 -3
- package/package.json +6 -3
- package/dist/types/utils/InvertedWeakMap.d.ts +0 -12
package/README.md
CHANGED
|
@@ -64,6 +64,8 @@ tree.where({ gt: 1 }) // Map([{ key: 'c', value: 3 }])
|
|
|
64
64
|
tree.where({ lt: 2 }) // Map([{ key: 'a', value: 1 }])
|
|
65
65
|
tree.where({ gt: 0, lt: 4 }) // Map([{ key: 'a', value: 1 }, { key: 'c', value: 3 }])
|
|
66
66
|
tree.where({ or: [3, 1] }) // Map([{ key: 'a', value: 1 }, { key: 'c', value: 3 }])
|
|
67
|
+
|
|
68
|
+
tree.clear()
|
|
67
69
|
```
|
|
68
70
|
|
|
69
71
|
## Why use a `serializable-bptree`?
|
|
@@ -461,6 +463,8 @@ await tree.where({ equal: 1 }) // Map([{ key: 'a', value: 1 }])
|
|
|
461
463
|
await tree.where({ gt: 1 }) // Map([{ key: 'c', value: 3 }])
|
|
462
464
|
await tree.where({ lt: 2 }) // Map([{ key: 'a', value: 1 }])
|
|
463
465
|
await tree.where({ gt: 0, lt: 4 }) // Map([{ key: 'a', value: 1 }, { key: 'c', value: 3 }])
|
|
466
|
+
|
|
467
|
+
tree.clear()
|
|
464
468
|
```
|
|
465
469
|
|
|
466
470
|
The implementation method for asynchronous operations is not significantly different. The **-Async** suffix is used instead of the **-Sync** suffix in the **BPTree** and **SerializeStrategy** classes. The only difference is that the methods become asynchronous. The **ValueComparator** class and similar value comparators do not use asynchronous operations.
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -61,16 +61,167 @@ var StringComparator = class extends ValueComparator {
|
|
|
61
61
|
}
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
//
|
|
64
|
+
// node_modules/cache-entanglement/dist/esm/index.mjs
|
|
65
|
+
var __create = Object.create;
|
|
66
|
+
var __defProp2 = Object.defineProperty;
|
|
67
|
+
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
68
|
+
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
69
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
70
|
+
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
71
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
72
|
+
return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
73
|
+
};
|
|
74
|
+
var __copyProps2 = (to, from, except, desc) => {
|
|
75
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
76
|
+
for (let key of __getOwnPropNames2(from))
|
|
77
|
+
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
78
|
+
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
79
|
+
}
|
|
80
|
+
return to;
|
|
81
|
+
};
|
|
82
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps2(
|
|
83
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
84
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
85
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
86
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
87
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target,
|
|
88
|
+
mod
|
|
89
|
+
));
|
|
90
|
+
var require_ms = __commonJS({
|
|
91
|
+
"node_modules/ms/index.js"(exports, module2) {
|
|
92
|
+
var s = 1e3;
|
|
93
|
+
var m = s * 60;
|
|
94
|
+
var h = m * 60;
|
|
95
|
+
var d = h * 24;
|
|
96
|
+
var w = d * 7;
|
|
97
|
+
var y = d * 365.25;
|
|
98
|
+
module2.exports = function(val, options) {
|
|
99
|
+
options = options || {};
|
|
100
|
+
var type = typeof val;
|
|
101
|
+
if (type === "string" && val.length > 0) {
|
|
102
|
+
return parse(val);
|
|
103
|
+
} else if (type === "number" && isFinite(val)) {
|
|
104
|
+
return options.long ? fmtLong(val) : fmtShort(val);
|
|
105
|
+
}
|
|
106
|
+
throw new Error(
|
|
107
|
+
"val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
function parse(str) {
|
|
111
|
+
str = String(str);
|
|
112
|
+
if (str.length > 100) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
|
|
116
|
+
str
|
|
117
|
+
);
|
|
118
|
+
if (!match) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
var n = parseFloat(match[1]);
|
|
122
|
+
var type = (match[2] || "ms").toLowerCase();
|
|
123
|
+
switch (type) {
|
|
124
|
+
case "years":
|
|
125
|
+
case "year":
|
|
126
|
+
case "yrs":
|
|
127
|
+
case "yr":
|
|
128
|
+
case "y":
|
|
129
|
+
return n * y;
|
|
130
|
+
case "weeks":
|
|
131
|
+
case "week":
|
|
132
|
+
case "w":
|
|
133
|
+
return n * w;
|
|
134
|
+
case "days":
|
|
135
|
+
case "day":
|
|
136
|
+
case "d":
|
|
137
|
+
return n * d;
|
|
138
|
+
case "hours":
|
|
139
|
+
case "hour":
|
|
140
|
+
case "hrs":
|
|
141
|
+
case "hr":
|
|
142
|
+
case "h":
|
|
143
|
+
return n * h;
|
|
144
|
+
case "minutes":
|
|
145
|
+
case "minute":
|
|
146
|
+
case "mins":
|
|
147
|
+
case "min":
|
|
148
|
+
case "m":
|
|
149
|
+
return n * m;
|
|
150
|
+
case "seconds":
|
|
151
|
+
case "second":
|
|
152
|
+
case "secs":
|
|
153
|
+
case "sec":
|
|
154
|
+
case "s":
|
|
155
|
+
return n * s;
|
|
156
|
+
case "milliseconds":
|
|
157
|
+
case "millisecond":
|
|
158
|
+
case "msecs":
|
|
159
|
+
case "msec":
|
|
160
|
+
case "ms":
|
|
161
|
+
return n;
|
|
162
|
+
default:
|
|
163
|
+
return void 0;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function fmtShort(ms2) {
|
|
167
|
+
var msAbs = Math.abs(ms2);
|
|
168
|
+
if (msAbs >= d) {
|
|
169
|
+
return Math.round(ms2 / d) + "d";
|
|
170
|
+
}
|
|
171
|
+
if (msAbs >= h) {
|
|
172
|
+
return Math.round(ms2 / h) + "h";
|
|
173
|
+
}
|
|
174
|
+
if (msAbs >= m) {
|
|
175
|
+
return Math.round(ms2 / m) + "m";
|
|
176
|
+
}
|
|
177
|
+
if (msAbs >= s) {
|
|
178
|
+
return Math.round(ms2 / s) + "s";
|
|
179
|
+
}
|
|
180
|
+
return ms2 + "ms";
|
|
181
|
+
}
|
|
182
|
+
function fmtLong(ms2) {
|
|
183
|
+
var msAbs = Math.abs(ms2);
|
|
184
|
+
if (msAbs >= d) {
|
|
185
|
+
return plural(ms2, msAbs, d, "day");
|
|
186
|
+
}
|
|
187
|
+
if (msAbs >= h) {
|
|
188
|
+
return plural(ms2, msAbs, h, "hour");
|
|
189
|
+
}
|
|
190
|
+
if (msAbs >= m) {
|
|
191
|
+
return plural(ms2, msAbs, m, "minute");
|
|
192
|
+
}
|
|
193
|
+
if (msAbs >= s) {
|
|
194
|
+
return plural(ms2, msAbs, s, "second");
|
|
195
|
+
}
|
|
196
|
+
return ms2 + " ms";
|
|
197
|
+
}
|
|
198
|
+
function plural(ms2, msAbs, n, name) {
|
|
199
|
+
var isPlural = msAbs >= n * 1.5;
|
|
200
|
+
return Math.round(ms2 / n) + " " + name + (isPlural ? "s" : "");
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
var import_ms = __toESM(require_ms());
|
|
65
205
|
var InvertedWeakMap = class {
|
|
66
206
|
_map;
|
|
207
|
+
_keepAlive;
|
|
208
|
+
_timeouts;
|
|
67
209
|
_registry;
|
|
68
|
-
|
|
210
|
+
_lifespan;
|
|
211
|
+
constructor(option) {
|
|
212
|
+
const { lifespan } = option;
|
|
213
|
+
this._lifespan = lifespan;
|
|
69
214
|
this._map = /* @__PURE__ */ new Map();
|
|
70
|
-
this.
|
|
215
|
+
this._keepAlive = /* @__PURE__ */ new Map();
|
|
216
|
+
this._timeouts = /* @__PURE__ */ new Map();
|
|
217
|
+
this._registry = new FinalizationRegistry((key) => {
|
|
218
|
+
this._stopExpire(key, true);
|
|
219
|
+
this._map.delete(key);
|
|
220
|
+
});
|
|
71
221
|
}
|
|
72
222
|
clear() {
|
|
73
|
-
|
|
223
|
+
this._keepAlive.clear();
|
|
224
|
+
this._map.clear();
|
|
74
225
|
}
|
|
75
226
|
delete(key) {
|
|
76
227
|
const ref = this._map.get(key);
|
|
@@ -80,6 +231,8 @@ var InvertedWeakMap = class {
|
|
|
80
231
|
this._registry.unregister(raw);
|
|
81
232
|
}
|
|
82
233
|
}
|
|
234
|
+
this._stopExpire(key, true);
|
|
235
|
+
this._keepAlive.delete(key);
|
|
83
236
|
return this._map.delete(key);
|
|
84
237
|
}
|
|
85
238
|
get(key) {
|
|
@@ -91,8 +244,39 @@ var InvertedWeakMap = class {
|
|
|
91
244
|
set(key, value) {
|
|
92
245
|
this._map.set(key, new WeakRef(value));
|
|
93
246
|
this._registry.register(value, key);
|
|
247
|
+
if (this._lifespan > 0) {
|
|
248
|
+
this._stopExpire(key, true);
|
|
249
|
+
this._startExpire(key, value);
|
|
250
|
+
}
|
|
94
251
|
return this;
|
|
95
252
|
}
|
|
253
|
+
extendExpire(key) {
|
|
254
|
+
if (!(this._lifespan > 0)) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (!this._keepAlive.has(key)) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
this._stopExpire(key, false);
|
|
261
|
+
this._startExpire(key, this._keepAlive.get(key));
|
|
262
|
+
}
|
|
263
|
+
_startExpire(key, value) {
|
|
264
|
+
this._keepAlive.set(key, value);
|
|
265
|
+
this._timeouts.set(key, setTimeout(() => {
|
|
266
|
+
this._keepAlive.delete(key);
|
|
267
|
+
}, this._lifespan));
|
|
268
|
+
}
|
|
269
|
+
_stopExpire(key, removeKeepAlive) {
|
|
270
|
+
if (!this._timeouts.has(key)) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const timeout = this._timeouts.get(key);
|
|
274
|
+
this._timeouts.delete(key);
|
|
275
|
+
clearTimeout(timeout);
|
|
276
|
+
if (removeKeepAlive) {
|
|
277
|
+
this._keepAlive.delete(key);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
96
280
|
get size() {
|
|
97
281
|
return this._map.size;
|
|
98
282
|
}
|
|
@@ -100,13 +284,252 @@ var InvertedWeakMap = class {
|
|
|
100
284
|
return this._map.keys();
|
|
101
285
|
}
|
|
102
286
|
};
|
|
287
|
+
var CacheEntanglement = class {
|
|
288
|
+
creation;
|
|
289
|
+
beforeUpdateHook;
|
|
290
|
+
lifespan;
|
|
291
|
+
dependencies;
|
|
292
|
+
caches;
|
|
293
|
+
assignments;
|
|
294
|
+
parameters;
|
|
295
|
+
dependencyKeys;
|
|
296
|
+
constructor(creation, option) {
|
|
297
|
+
option = option ?? {};
|
|
298
|
+
const {
|
|
299
|
+
dependencies,
|
|
300
|
+
lifespan,
|
|
301
|
+
beforeUpdateHook
|
|
302
|
+
} = option;
|
|
303
|
+
this.creation = creation;
|
|
304
|
+
this.beforeUpdateHook = beforeUpdateHook ?? (() => {
|
|
305
|
+
});
|
|
306
|
+
this.lifespan = this._normalizeMs(lifespan ?? 0);
|
|
307
|
+
this.assignments = [];
|
|
308
|
+
this.caches = new InvertedWeakMap({ lifespan: this.lifespan });
|
|
309
|
+
this.dependencies = dependencies ?? {};
|
|
310
|
+
this.dependencyKeys = Object.keys(this.dependencies);
|
|
311
|
+
this.parameters = {};
|
|
312
|
+
for (const name in this.dependencies) {
|
|
313
|
+
const dependency = this.dependencies[name];
|
|
314
|
+
if (!dependency.assignments.includes(this)) {
|
|
315
|
+
dependency.assignments.push(this);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
_normalizeMs(time) {
|
|
320
|
+
if (typeof time === "string") {
|
|
321
|
+
return (0, import_ms.default)(time);
|
|
322
|
+
}
|
|
323
|
+
return time;
|
|
324
|
+
}
|
|
325
|
+
dependencyKey(key) {
|
|
326
|
+
const tokens = key.split("/");
|
|
327
|
+
tokens.pop();
|
|
328
|
+
return tokens.join("/");
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Returns all keys stored in the instance.
|
|
332
|
+
*/
|
|
333
|
+
keys() {
|
|
334
|
+
return this.caches.keys();
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Deletes all cache values stored in the instance.
|
|
338
|
+
*/
|
|
339
|
+
clear() {
|
|
340
|
+
for (const key of this.keys()) {
|
|
341
|
+
this.delete(key);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Checks if there is a cache value stored in the key within the instance.
|
|
346
|
+
* @param key The key to search.
|
|
347
|
+
*/
|
|
348
|
+
exists(key) {
|
|
349
|
+
return this.caches.has(key);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Returns the cache value stored in the key within the instance. If the cached value is not present, an error is thrown.
|
|
353
|
+
* @param key The key to search.
|
|
354
|
+
*/
|
|
355
|
+
get(key) {
|
|
356
|
+
if (!this.caches.has(key)) {
|
|
357
|
+
throw new Error(`Cache value not found: ${key}`);
|
|
358
|
+
}
|
|
359
|
+
return this.caches.get(key);
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
var CacheData = class _CacheData {
|
|
363
|
+
static StructuredClone = globalThis.structuredClone.bind(globalThis);
|
|
364
|
+
_value;
|
|
365
|
+
constructor(value) {
|
|
366
|
+
this._value = value;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* This is cached data.
|
|
370
|
+
* It was generated at the time of caching, so there is a risk of modification if it's an object due to shallow copying.
|
|
371
|
+
* Therefore, if it's not a primitive type, please avoid using this value directly and use the `clone` method to use a copied version of the data.
|
|
372
|
+
*/
|
|
373
|
+
get raw() {
|
|
374
|
+
return this._value;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* The method returns a copied value of the cached data.
|
|
378
|
+
* You can pass a function as a parameter to copy the value. This parameter function should return the copied value.
|
|
379
|
+
*
|
|
380
|
+
* If no parameter is passed, it defaults to using `structuredClone` function to copy the value.
|
|
381
|
+
* If you prefer shallow copying instead of deep copying,
|
|
382
|
+
* you can use the default options `array-shallow-copy`, `object-shallow-copy` and `deep-copy`,
|
|
383
|
+
* which are replaced with functions to shallow copy arrays and objects, respectively. This is a syntactic sugar.
|
|
384
|
+
* @param strategy The function that returns the copied value.
|
|
385
|
+
* If you want to perform a shallow copy, simply pass the strings `array-shallow-copy` or `object-shallow-copy` for easy use.
|
|
386
|
+
* The `array-shallow-copy` strategy performs a shallow copy of an array.
|
|
387
|
+
* The `object-shallow-copy` strategy performs a shallow copy of an object.
|
|
388
|
+
* The `deep-copy` strategy performs a deep copy of the value using `structuredClone`.
|
|
389
|
+
* The default is `deep-copy`.
|
|
390
|
+
*/
|
|
391
|
+
clone(strategy = "deep-copy") {
|
|
392
|
+
if (strategy && typeof strategy !== "string") {
|
|
393
|
+
return strategy(this.raw);
|
|
394
|
+
}
|
|
395
|
+
switch (strategy) {
|
|
396
|
+
case "array-shallow-copy":
|
|
397
|
+
return [].concat(this.raw);
|
|
398
|
+
case "object-shallow-copy":
|
|
399
|
+
return Object.assign({}, this.raw);
|
|
400
|
+
case "deep-copy":
|
|
401
|
+
default:
|
|
402
|
+
return _CacheData.StructuredClone(this.raw);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
var CacheEntanglementSync = class extends CacheEntanglement {
|
|
407
|
+
constructor(creation, option) {
|
|
408
|
+
super(creation, option);
|
|
409
|
+
}
|
|
410
|
+
resolve(key, ...parameter) {
|
|
411
|
+
const resolved = {};
|
|
412
|
+
const dependencyKey = this.dependencyKey(key);
|
|
413
|
+
this.beforeUpdateHook(key, dependencyKey, ...parameter);
|
|
414
|
+
for (let i = 0, len = this.dependencyKeys.length; i < len; i++) {
|
|
415
|
+
const name = this.dependencyKeys[i];
|
|
416
|
+
const dependency = this.dependencies[name];
|
|
417
|
+
if (!dependency.caches.has(key) && !dependency.caches.has(dependencyKey)) {
|
|
418
|
+
throw new Error(`The key '${key}' or '${dependencyKey}' has not been assigned yet in dependency '${name.toString()}'.`, {
|
|
419
|
+
cause: {
|
|
420
|
+
from: this
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
const dependencyValue = dependency.caches.get(key) ?? dependency.caches.get(dependencyKey);
|
|
425
|
+
resolved[name] = dependencyValue;
|
|
426
|
+
}
|
|
427
|
+
this.parameters[key] = parameter;
|
|
428
|
+
const value = new CacheData(this.creation(key, resolved, ...parameter));
|
|
429
|
+
this.caches.set(key, value);
|
|
430
|
+
return value;
|
|
431
|
+
}
|
|
432
|
+
cache(key, ...parameter) {
|
|
433
|
+
if (!this.caches.has(key)) {
|
|
434
|
+
this.resolve(key, ...parameter);
|
|
435
|
+
} else {
|
|
436
|
+
this.caches.extendExpire(key);
|
|
437
|
+
}
|
|
438
|
+
return this.caches.get(key);
|
|
439
|
+
}
|
|
440
|
+
update(key, ...parameter) {
|
|
441
|
+
this.resolve(key, ...parameter);
|
|
442
|
+
for (let i = 0, len = this.assignments.length; i < len; i++) {
|
|
443
|
+
const t = this.assignments[i];
|
|
444
|
+
const instance = t;
|
|
445
|
+
for (const cacheKey of instance.caches.keys()) {
|
|
446
|
+
if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
|
|
447
|
+
instance.update(cacheKey, ...instance.parameters[cacheKey]);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return this.caches.get(key);
|
|
452
|
+
}
|
|
453
|
+
delete(key) {
|
|
454
|
+
this.caches.delete(key);
|
|
455
|
+
for (let i = 0, len = this.assignments.length; i < len; i++) {
|
|
456
|
+
const t = this.assignments[i];
|
|
457
|
+
const instance = t;
|
|
458
|
+
for (const cacheKey of instance.caches.keys()) {
|
|
459
|
+
if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
|
|
460
|
+
instance.delete(cacheKey);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
var CacheEntanglementAsync = class extends CacheEntanglement {
|
|
467
|
+
constructor(creation, option) {
|
|
468
|
+
super(creation, option);
|
|
469
|
+
}
|
|
470
|
+
async resolve(key, ...parameter) {
|
|
471
|
+
const resolved = {};
|
|
472
|
+
const dependencyKey = this.dependencyKey(key);
|
|
473
|
+
await this.beforeUpdateHook(key, dependencyKey, ...parameter);
|
|
474
|
+
for (let i = 0, len = this.dependencyKeys.length; i < len; i++) {
|
|
475
|
+
const name = this.dependencyKeys[i];
|
|
476
|
+
const dependency = this.dependencies[name];
|
|
477
|
+
if (!dependency.caches.has(key) && !dependency.caches.has(dependencyKey)) {
|
|
478
|
+
throw new Error(`The key '${key}' or '${dependencyKey}' has not been assigned yet in dependency '${name.toString()}'.`, {
|
|
479
|
+
cause: {
|
|
480
|
+
from: this
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
const dependencyValue = dependency.caches.get(key) ?? dependency.caches.get(dependencyKey);
|
|
485
|
+
resolved[name] = dependencyValue;
|
|
486
|
+
}
|
|
487
|
+
this.parameters[key] = parameter;
|
|
488
|
+
const value = new CacheData(await this.creation(key, resolved, ...parameter));
|
|
489
|
+
this.caches.set(key, value);
|
|
490
|
+
return value;
|
|
491
|
+
}
|
|
492
|
+
async cache(key, ...parameter) {
|
|
493
|
+
if (!this.caches.has(key)) {
|
|
494
|
+
await this.resolve(key, ...parameter);
|
|
495
|
+
} else {
|
|
496
|
+
this.caches.extendExpire(key);
|
|
497
|
+
}
|
|
498
|
+
return this.caches.get(key);
|
|
499
|
+
}
|
|
500
|
+
async update(key, ...parameter) {
|
|
501
|
+
await this.resolve(key, ...parameter);
|
|
502
|
+
for (let i = 0, len = this.assignments.length; i < len; i++) {
|
|
503
|
+
const t = this.assignments[i];
|
|
504
|
+
const instance = t;
|
|
505
|
+
for (const cacheKey of instance.caches.keys()) {
|
|
506
|
+
if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
|
|
507
|
+
await instance.update(cacheKey, ...instance.parameters[cacheKey]);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return this.caches.get(key);
|
|
512
|
+
}
|
|
513
|
+
async delete(key) {
|
|
514
|
+
this.caches.delete(key);
|
|
515
|
+
for (let i = 0, len = this.assignments.length; i < len; i++) {
|
|
516
|
+
const t = this.assignments[i];
|
|
517
|
+
const instance = t;
|
|
518
|
+
for (const cacheKey of instance.caches.keys()) {
|
|
519
|
+
if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
|
|
520
|
+
await instance.delete(cacheKey);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
};
|
|
103
526
|
|
|
104
527
|
// src/base/BPTree.ts
|
|
105
528
|
var BPTree = class {
|
|
106
529
|
_cachedRegexp;
|
|
107
530
|
strategy;
|
|
108
531
|
comparator;
|
|
109
|
-
|
|
532
|
+
option;
|
|
110
533
|
order;
|
|
111
534
|
root;
|
|
112
535
|
_strategyDirty;
|
|
@@ -124,12 +547,8 @@ var BPTree = class {
|
|
|
124
547
|
like: (nv, v) => {
|
|
125
548
|
const nodeValue = this.comparator.match(nv);
|
|
126
549
|
const value = this.comparator.match(v);
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const regexp2 = new RegExp(`^${pattern}$`, "i");
|
|
130
|
-
this._cachedRegexp.set(value, regexp2);
|
|
131
|
-
}
|
|
132
|
-
const regexp = this._cachedRegexp.get(value);
|
|
550
|
+
const cache = this._cachedRegexp.cache(value);
|
|
551
|
+
const regexp = cache.raw;
|
|
133
552
|
return regexp.test(nodeValue);
|
|
134
553
|
}
|
|
135
554
|
};
|
|
@@ -166,15 +585,24 @@ var BPTree = class {
|
|
|
166
585
|
or: 1,
|
|
167
586
|
like: 1
|
|
168
587
|
};
|
|
169
|
-
constructor(strategy, comparator) {
|
|
588
|
+
constructor(strategy, comparator, option) {
|
|
589
|
+
this.strategy = strategy;
|
|
590
|
+
this.comparator = comparator;
|
|
591
|
+
this.option = option ?? {};
|
|
170
592
|
this._strategyDirty = false;
|
|
171
|
-
this._cachedRegexp = new InvertedWeakMap();
|
|
172
593
|
this._nodeCreateBuffer = /* @__PURE__ */ new Map();
|
|
173
594
|
this._nodeUpdateBuffer = /* @__PURE__ */ new Map();
|
|
174
595
|
this._nodeDeleteBuffer = /* @__PURE__ */ new Map();
|
|
175
|
-
this.
|
|
176
|
-
|
|
177
|
-
|
|
596
|
+
this._cachedRegexp = this._createCachedRegexp();
|
|
597
|
+
}
|
|
598
|
+
_createCachedRegexp() {
|
|
599
|
+
return new CacheEntanglementSync((key) => {
|
|
600
|
+
const pattern = key.replace(/%/g, ".*").replace(/_/g, ".");
|
|
601
|
+
const regexp = new RegExp(`^${pattern}$`, "i");
|
|
602
|
+
return regexp;
|
|
603
|
+
}, {
|
|
604
|
+
lifespan: this.option.lifespan ?? "3m"
|
|
605
|
+
});
|
|
178
606
|
}
|
|
179
607
|
ensureValues(v) {
|
|
180
608
|
if (!Array.isArray(v)) {
|
|
@@ -248,12 +676,28 @@ var BPTree = class {
|
|
|
248
676
|
getHeadData() {
|
|
249
677
|
return this.strategy.head.data;
|
|
250
678
|
}
|
|
679
|
+
/**
|
|
680
|
+
* Clears all cached nodes.
|
|
681
|
+
* This method is useful for freeing up memory when the tree is no longer needed.
|
|
682
|
+
*/
|
|
683
|
+
clear() {
|
|
684
|
+
this._cachedRegexp.clear();
|
|
685
|
+
this.nodes.clear();
|
|
686
|
+
}
|
|
251
687
|
};
|
|
252
688
|
|
|
253
689
|
// src/BPTreeSync.ts
|
|
254
690
|
var BPTreeSync = class extends BPTree {
|
|
255
|
-
constructor(strategy, comparator) {
|
|
256
|
-
super(strategy, comparator);
|
|
691
|
+
constructor(strategy, comparator, option) {
|
|
692
|
+
super(strategy, comparator, option);
|
|
693
|
+
this.nodes = this._createCachedNode();
|
|
694
|
+
}
|
|
695
|
+
_createCachedNode() {
|
|
696
|
+
return new CacheEntanglementSync((key) => {
|
|
697
|
+
return this.strategy.read(key);
|
|
698
|
+
}, {
|
|
699
|
+
lifespan: this.option.lifespan ?? "3m"
|
|
700
|
+
});
|
|
257
701
|
}
|
|
258
702
|
getPairsRightToLeft(value, startNode, endNode, comparator) {
|
|
259
703
|
const pairs = [];
|
|
@@ -338,7 +782,7 @@ var BPTreeSync = class extends BPTree {
|
|
|
338
782
|
next,
|
|
339
783
|
prev
|
|
340
784
|
};
|
|
341
|
-
this.
|
|
785
|
+
this._nodeCreateBuffer.set(id, node);
|
|
342
786
|
return node;
|
|
343
787
|
}
|
|
344
788
|
_deleteEntry(node, key, value) {
|
|
@@ -552,7 +996,6 @@ var BPTreeSync = class extends BPTree {
|
|
|
552
996
|
this.strategy.head.root = root.id;
|
|
553
997
|
node.parent = root.id;
|
|
554
998
|
pointer.parent = root.id;
|
|
555
|
-
this.bufferForNodeCreate(root);
|
|
556
999
|
this.bufferForNodeUpdate(node);
|
|
557
1000
|
this.bufferForNodeUpdate(pointer);
|
|
558
1001
|
return;
|
|
@@ -588,7 +1031,6 @@ var BPTreeSync = class extends BPTree {
|
|
|
588
1031
|
this.bufferForNodeUpdate(node2);
|
|
589
1032
|
}
|
|
590
1033
|
this._insertInParent(parentNode, midValue, parentPointer);
|
|
591
|
-
this.bufferForNodeCreate(parentPointer);
|
|
592
1034
|
this.bufferForNodeUpdate(parentNode);
|
|
593
1035
|
}
|
|
594
1036
|
}
|
|
@@ -600,7 +1042,6 @@ var BPTreeSync = class extends BPTree {
|
|
|
600
1042
|
this.order = this.strategy.order;
|
|
601
1043
|
this.root = this._createNode(true, [], [], true);
|
|
602
1044
|
this.strategy.head.root = this.root.id;
|
|
603
|
-
this.bufferForNodeCreate(this.root);
|
|
604
1045
|
this.commitHeadBuffer();
|
|
605
1046
|
this.commitNodeCreateBuffer();
|
|
606
1047
|
} else {
|
|
@@ -614,10 +1055,11 @@ var BPTreeSync = class extends BPTree {
|
|
|
614
1055
|
}
|
|
615
1056
|
}
|
|
616
1057
|
getNode(id) {
|
|
617
|
-
if (
|
|
618
|
-
|
|
1058
|
+
if (this._nodeCreateBuffer.has(id)) {
|
|
1059
|
+
return this._nodeCreateBuffer.get(id);
|
|
619
1060
|
}
|
|
620
|
-
|
|
1061
|
+
const cache = this.nodes.cache(id);
|
|
1062
|
+
return cache.raw;
|
|
621
1063
|
}
|
|
622
1064
|
insertableNode(value) {
|
|
623
1065
|
let node = this.root;
|
|
@@ -773,7 +1215,6 @@ var BPTreeSync = class extends BPTree {
|
|
|
773
1215
|
this.bufferForNodeUpdate(node);
|
|
774
1216
|
}
|
|
775
1217
|
this._insertInParent(before, after.values[0], after);
|
|
776
|
-
this.bufferForNodeCreate(after);
|
|
777
1218
|
this.bufferForNodeUpdate(before);
|
|
778
1219
|
}
|
|
779
1220
|
this.commitHeadBuffer();
|
|
@@ -839,8 +1280,16 @@ var BPTreeSync = class extends BPTree {
|
|
|
839
1280
|
|
|
840
1281
|
// src/BPTreeAsync.ts
|
|
841
1282
|
var BPTreeAsync = class extends BPTree {
|
|
842
|
-
constructor(strategy, comparator) {
|
|
843
|
-
super(strategy, comparator);
|
|
1283
|
+
constructor(strategy, comparator, option) {
|
|
1284
|
+
super(strategy, comparator, option);
|
|
1285
|
+
this.nodes = this._createCachedNode();
|
|
1286
|
+
}
|
|
1287
|
+
_createCachedNode() {
|
|
1288
|
+
return new CacheEntanglementAsync(async (key) => {
|
|
1289
|
+
return await this.strategy.read(key);
|
|
1290
|
+
}, {
|
|
1291
|
+
lifespan: this.option.lifespan ?? "3m"
|
|
1292
|
+
});
|
|
844
1293
|
}
|
|
845
1294
|
async getPairsRightToLeft(value, startNode, endNode, comparator) {
|
|
846
1295
|
const pairs = [];
|
|
@@ -925,7 +1374,7 @@ var BPTreeAsync = class extends BPTree {
|
|
|
925
1374
|
next,
|
|
926
1375
|
prev
|
|
927
1376
|
};
|
|
928
|
-
this.
|
|
1377
|
+
this._nodeCreateBuffer.set(id, node);
|
|
929
1378
|
return node;
|
|
930
1379
|
}
|
|
931
1380
|
async _deleteEntry(node, key, value) {
|
|
@@ -1139,7 +1588,6 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1139
1588
|
this.strategy.head.root = root.id;
|
|
1140
1589
|
node.parent = root.id;
|
|
1141
1590
|
pointer.parent = root.id;
|
|
1142
|
-
this.bufferForNodeCreate(root);
|
|
1143
1591
|
this.bufferForNodeUpdate(node);
|
|
1144
1592
|
this.bufferForNodeUpdate(pointer);
|
|
1145
1593
|
return;
|
|
@@ -1175,7 +1623,6 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1175
1623
|
this.bufferForNodeUpdate(node2);
|
|
1176
1624
|
}
|
|
1177
1625
|
await this._insertInParent(parentNode, midValue, parentPointer);
|
|
1178
|
-
this.bufferForNodeCreate(parentPointer);
|
|
1179
1626
|
this.bufferForNodeUpdate(parentNode);
|
|
1180
1627
|
}
|
|
1181
1628
|
}
|
|
@@ -1187,7 +1634,6 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1187
1634
|
this.order = this.strategy.order;
|
|
1188
1635
|
this.root = await this._createNode(true, [], [], true);
|
|
1189
1636
|
this.strategy.head.root = this.root.id;
|
|
1190
|
-
this.bufferForNodeCreate(this.root);
|
|
1191
1637
|
await this.commitHeadBuffer();
|
|
1192
1638
|
await this.commitNodeCreateBuffer();
|
|
1193
1639
|
} else {
|
|
@@ -1201,10 +1647,11 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1201
1647
|
}
|
|
1202
1648
|
}
|
|
1203
1649
|
async getNode(id) {
|
|
1204
|
-
if (
|
|
1205
|
-
|
|
1650
|
+
if (this._nodeCreateBuffer.has(id)) {
|
|
1651
|
+
return this._nodeCreateBuffer.get(id);
|
|
1206
1652
|
}
|
|
1207
|
-
|
|
1653
|
+
const cache = await this.nodes.cache(id);
|
|
1654
|
+
return cache.raw;
|
|
1208
1655
|
}
|
|
1209
1656
|
async insertableNode(value) {
|
|
1210
1657
|
let node = this.root;
|
|
@@ -1360,7 +1807,6 @@ var BPTreeAsync = class extends BPTree {
|
|
|
1360
1807
|
this.bufferForNodeUpdate(node);
|
|
1361
1808
|
}
|
|
1362
1809
|
await this._insertInParent(before, after.values[0], after);
|
|
1363
|
-
this.bufferForNodeCreate(after);
|
|
1364
1810
|
this.bufferForNodeUpdate(before);
|
|
1365
1811
|
}
|
|
1366
1812
|
await this.commitHeadBuffer();
|