serializable-bptree 5.1.4 → 5.2.0

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.
@@ -62,253 +62,132 @@ var StringComparator = class extends ValueComparator {
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 });
65
+ var LRUMap = class {
66
+ capacity;
67
+ map;
68
+ head = null;
69
+ tail = null;
70
+ constructor(capacity) {
71
+ this.capacity = capacity;
72
+ this.map = /* @__PURE__ */ new Map();
73
+ }
74
+ // 내부 유틸리티: 노드를 헤드로 이동 (가장 최근 사용됨 표시)
75
+ promote(node) {
76
+ this.extract(node);
77
+ this.prepend(node);
78
+ }
79
+ // 내부 유틸리티: 리스트에서 노드 연결 끊기
80
+ extract(node) {
81
+ if (node.prev) node.prev.next = node.next;
82
+ else this.head = node.next;
83
+ if (node.next) node.next.prev = node.prev;
84
+ else this.tail = node.prev;
85
+ node.prev = null;
86
+ node.next = null;
87
+ }
88
+ // 내부 유틸리티: 리스트 맨 앞에 노드 삽입
89
+ prepend(node) {
90
+ node.next = this.head;
91
+ if (this.head) this.head.prev = node;
92
+ this.head = node;
93
+ if (!this.tail) this.tail = node;
79
94
  }
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" : "");
95
+ /**
96
+ * 데이터를 저장하거나 업데이트합니다.
97
+ * 용량 초과 가장 오래된 항목(tail) 제거합니다.
98
+ */
99
+ set(key, value) {
100
+ const existing = this.map.get(key);
101
+ if (existing) {
102
+ existing.value = value;
103
+ this.promote(existing);
104
+ return;
201
105
  }
202
- }
203
- });
204
- var import_ms = __toESM(require_ms());
205
- var InvertedWeakMap = class {
206
- _map;
207
- _keepAlive;
208
- _timeouts;
209
- _registry;
210
- _lifespan;
211
- constructor(option) {
212
- const { lifespan } = option;
213
- this._lifespan = lifespan;
214
- this._map = /* @__PURE__ */ new Map();
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
- });
221
- }
222
- clear() {
223
- this._keepAlive.clear();
224
- this._map.clear();
225
- }
226
- delete(key) {
227
- const ref = this._map.get(key);
228
- if (ref) {
229
- const raw = ref.deref();
230
- if (raw !== void 0) {
231
- this._registry.unregister(raw);
232
- }
106
+ const newNode = { key, value, prev: null, next: null };
107
+ this.map.set(key, newNode);
108
+ this.prepend(newNode);
109
+ if (this.map.size > this.capacity && this.tail) {
110
+ this.map.delete(this.tail.key);
111
+ this.extract(this.tail);
233
112
  }
234
- this._stopExpire(key, true);
235
- this._keepAlive.delete(key);
236
- return this._map.delete(key);
237
113
  }
114
+ /**
115
+ * 데이터를 가져옵니다. 접근한 데이터는 "최근 사용됨"으로 갱신됩니다.
116
+ */
238
117
  get(key) {
239
- return this._map.get(key)?.deref();
118
+ const node = this.map.get(key);
119
+ if (!node) return void 0;
120
+ this.promote(node);
121
+ return node.value;
240
122
  }
123
+ /**
124
+ * 키의 존재 여부를 확인합니다. (순서는 변경하지 않는 것이 일반적입니다)
125
+ */
241
126
  has(key) {
242
- return this._map.has(key) && this.get(key) !== void 0;
243
- }
244
- set(key, value) {
245
- this._map.set(key, new WeakRef(value));
246
- this._registry.register(value, key);
247
- if (this._lifespan > 0) {
248
- this._stopExpire(key, true);
249
- this._startExpire(key, value);
250
- }
251
- return this;
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));
127
+ return this.map.has(key);
262
128
  }
263
- _startExpire(key, value) {
264
- this._keepAlive.set(key, value);
265
- this._timeouts.set(key, setTimeout(() => {
266
- this._keepAlive.delete(key);
267
- }, this._lifespan));
129
+ /**
130
+ * 특정 키와 데이터를 캐시에서 완전히 제거합니다.
131
+ */
132
+ delete(key) {
133
+ const node = this.map.get(key);
134
+ if (!node) return false;
135
+ this.extract(node);
136
+ this.map.delete(key);
137
+ return true;
268
138
  }
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);
139
+ /**
140
+ * 현재 캐시된 키들을 최근 사용된 순서대로 반환합니다.
141
+ */
142
+ *keys() {
143
+ let current = this.head;
144
+ while (current) {
145
+ yield current.key;
146
+ current = current.next;
278
147
  }
279
148
  }
149
+ /**
150
+ * 현재 캐시된 아이템의 개수를 반환합니다.
151
+ */
280
152
  get size() {
281
- return this._map.size;
153
+ return this.map.size;
282
154
  }
283
- keys() {
284
- return this._map.keys();
155
+ /**
156
+ * 캐시를 완전히 비웁니다.
157
+ */
158
+ clear() {
159
+ this.map.clear();
160
+ this.head = null;
161
+ this.tail = null;
285
162
  }
286
163
  };
287
164
  var CacheEntanglement = class {
288
165
  creation;
289
166
  beforeUpdateHook;
290
- lifespan;
167
+ capacity;
291
168
  dependencies;
292
169
  caches;
293
- assignments;
294
170
  parameters;
171
+ assignments;
295
172
  dependencyProperties;
173
+ updateRequirements;
296
174
  constructor(creation, option) {
297
175
  option = option ?? {};
298
176
  const {
299
177
  dependencies,
300
- lifespan,
178
+ capacity,
301
179
  beforeUpdateHook
302
180
  } = option;
303
181
  this.creation = creation;
304
182
  this.beforeUpdateHook = beforeUpdateHook ?? (() => {
305
183
  });
306
- this.lifespan = this._normalizeMs(lifespan ?? 0);
184
+ this.capacity = capacity ?? 100;
307
185
  this.assignments = [];
308
- this.caches = new InvertedWeakMap({ lifespan: this.lifespan });
186
+ this.caches = new LRUMap(this.capacity);
187
+ this.parameters = /* @__PURE__ */ new Map();
309
188
  this.dependencies = dependencies ?? {};
310
189
  this.dependencyProperties = Object.keys(this.dependencies);
311
- this.parameters = {};
190
+ this.updateRequirements = /* @__PURE__ */ new Set();
312
191
  for (const name in this.dependencies) {
313
192
  const dependency = this.dependencies[name];
314
193
  if (!dependency.assignments.includes(this)) {
@@ -316,22 +195,30 @@ var CacheEntanglement = class {
316
195
  }
317
196
  }
318
197
  }
319
- _normalizeMs(time) {
320
- if (typeof time === "string") {
321
- return (0, import_ms.default)(time);
198
+ bubbleUpdateSignal(key) {
199
+ this.updateRequirements.add(key);
200
+ for (let i = 0, len = this.assignments.length; i < len; i++) {
201
+ const t = this.assignments[i];
202
+ const instance = t;
203
+ for (const cacheKey of instance.caches.keys()) {
204
+ if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
205
+ instance.bubbleUpdateSignal(cacheKey);
206
+ }
207
+ }
322
208
  }
323
- return time;
324
209
  }
325
210
  dependencyKey(key) {
326
- const tokens = key.split("/");
327
- tokens.pop();
328
- return tokens.join("/");
211
+ const i = key.lastIndexOf("/");
212
+ if (i === -1) {
213
+ return key;
214
+ }
215
+ return key.substring(0, i);
329
216
  }
330
217
  /**
331
218
  * Returns all keys stored in the instance.
332
219
  */
333
220
  keys() {
334
- return this.caches.keys();
221
+ return this.parameters.keys();
335
222
  }
336
223
  /**
337
224
  * Deletes all cache values stored in the instance.
@@ -346,17 +233,33 @@ var CacheEntanglement = class {
346
233
  * @param key The key to search.
347
234
  */
348
235
  exists(key) {
349
- return this.caches.has(key);
236
+ return this.parameters.has(key);
350
237
  }
351
238
  /**
352
- * Returns the cache value stored in the key within the instance. If the cached value is not present, an error is thrown.
239
+ * Checks if there is a cache value stored in the key within the instance.
240
+ * This method is an alias for `exists`.
353
241
  * @param key The key to search.
354
242
  */
355
- get(key) {
356
- if (!this.caches.has(key)) {
357
- throw new Error(`Cache value not found: ${key}`);
243
+ has(key) {
244
+ return this.exists(key);
245
+ }
246
+ /**
247
+ * Deletes the cache value stored in the key within the instance.
248
+ * @param key The key to delete.
249
+ */
250
+ delete(key) {
251
+ this.caches.delete(key);
252
+ this.parameters.delete(key);
253
+ this.updateRequirements.delete(key);
254
+ for (let i = 0, len = this.assignments.length; i < len; i++) {
255
+ const t = this.assignments[i];
256
+ const instance = t;
257
+ for (const cacheKey of instance.keys()) {
258
+ if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
259
+ instance.delete(cacheKey);
260
+ }
261
+ }
358
262
  }
359
- return this.caches.get(key);
360
263
  }
361
264
  };
362
265
  var CacheData = class _CacheData {
@@ -407,6 +310,15 @@ var CacheEntanglementSync = class extends CacheEntanglement {
407
310
  constructor(creation, option) {
408
311
  super(creation, option);
409
312
  }
313
+ recache(key) {
314
+ if (!this.parameters.has(key)) {
315
+ return;
316
+ }
317
+ if (!this.caches.has(key) || this.updateRequirements.has(key)) {
318
+ this.resolve(key, ...this.parameters.get(key));
319
+ }
320
+ return this.caches.get(key);
321
+ }
410
322
  resolve(key, ...parameter) {
411
323
  const resolved = {};
412
324
  const dependencyKey = this.dependencyKey(key);
@@ -414,59 +326,53 @@ var CacheEntanglementSync = class extends CacheEntanglement {
414
326
  for (let i = 0, len = this.dependencyProperties.length; i < len; i++) {
415
327
  const name = this.dependencyProperties[i];
416
328
  const dependency = this.dependencies[name];
417
- if (!dependency.caches.has(key) && !dependency.caches.has(dependencyKey)) {
329
+ if (!dependency.exists(key) && !dependency.exists(dependencyKey)) {
418
330
  throw new Error(`The key '${key}' or '${dependencyKey}' has not been assigned yet in dependency '${name.toString()}'.`, {
419
331
  cause: {
420
332
  from: this
421
333
  }
422
334
  });
423
335
  }
424
- const dependencyValue = dependency.caches.get(key) ?? dependency.caches.get(dependencyKey);
336
+ const dependencyValue = dependency.recache(key) ?? dependency.recache(dependencyKey);
425
337
  resolved[name] = dependencyValue;
426
338
  }
427
- this.parameters[key] = parameter;
428
339
  const value = new CacheData(this.creation(key, resolved, ...parameter));
340
+ this.updateRequirements.delete(key);
341
+ this.parameters.set(key, parameter);
429
342
  this.caches.set(key, value);
430
343
  return value;
431
344
  }
345
+ get(key) {
346
+ if (!this.parameters.has(key)) {
347
+ throw new Error(`Cache value not found: ${key}`);
348
+ }
349
+ return this.cache(key, ...this.parameters.get(key));
350
+ }
432
351
  cache(key, ...parameter) {
433
- if (!this.caches.has(key)) {
434
- this.update(key, ...parameter);
435
- } else {
436
- this.caches.extendExpire(key);
352
+ if (!this.caches.has(key) || this.updateRequirements.has(key)) {
353
+ this.resolve(key, ...parameter);
437
354
  }
438
355
  return this.caches.get(key);
439
356
  }
440
357
  update(key, ...parameter) {
358
+ this.bubbleUpdateSignal(key);
441
359
  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
360
  return this.caches.get(key);
452
361
  }
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
362
  };
466
363
  var CacheEntanglementAsync = class extends CacheEntanglement {
467
364
  constructor(creation, option) {
468
365
  super(creation, option);
469
366
  }
367
+ async recache(key) {
368
+ if (!this.parameters.has(key)) {
369
+ return;
370
+ }
371
+ if (!this.caches.has(key) || this.updateRequirements.has(key)) {
372
+ await this.resolve(key, ...this.parameters.get(key));
373
+ }
374
+ return this.caches.get(key);
375
+ }
470
376
  async resolve(key, ...parameter) {
471
377
  const resolved = {};
472
378
  const dependencyKey = this.dependencyKey(key);
@@ -474,54 +380,39 @@ var CacheEntanglementAsync = class extends CacheEntanglement {
474
380
  for (let i = 0, len = this.dependencyProperties.length; i < len; i++) {
475
381
  const name = this.dependencyProperties[i];
476
382
  const dependency = this.dependencies[name];
477
- if (!dependency.caches.has(key) && !dependency.caches.has(dependencyKey)) {
383
+ if (!dependency.exists(key) && !dependency.exists(dependencyKey)) {
478
384
  throw new Error(`The key '${key}' or '${dependencyKey}' has not been assigned yet in dependency '${name.toString()}'.`, {
479
385
  cause: {
480
386
  from: this
481
387
  }
482
388
  });
483
389
  }
484
- const dependencyValue = dependency.caches.get(key) ?? dependency.caches.get(dependencyKey);
390
+ const dependencyValue = await dependency.recache(key) ?? await dependency.recache(dependencyKey);
485
391
  resolved[name] = dependencyValue;
486
392
  }
487
- this.parameters[key] = parameter;
488
393
  const value = new CacheData(await this.creation(key, resolved, ...parameter));
394
+ this.updateRequirements.delete(key);
395
+ this.parameters.set(key, parameter);
489
396
  this.caches.set(key, value);
490
397
  return value;
491
398
  }
399
+ async get(key) {
400
+ if (!this.parameters.has(key)) {
401
+ throw new Error(`Cache value not found: ${key}`);
402
+ }
403
+ return this.cache(key, ...this.parameters.get(key));
404
+ }
492
405
  async cache(key, ...parameter) {
493
- if (!this.caches.has(key)) {
406
+ if (!this.caches.has(key) || this.updateRequirements.has(key)) {
494
407
  await this.update(key, ...parameter);
495
- } else {
496
- this.caches.extendExpire(key);
497
408
  }
498
409
  return this.caches.get(key);
499
410
  }
500
411
  async update(key, ...parameter) {
412
+ this.bubbleUpdateSignal(key);
501
413
  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
414
  return this.caches.get(key);
512
415
  }
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
416
  };
526
417
 
527
418
  // src/base/BPTree.ts
@@ -601,7 +492,7 @@ var BPTree = class {
601
492
  const regexp = new RegExp(`^${pattern}$`, "i");
602
493
  return regexp;
603
494
  }, {
604
- lifespan: this.option.lifespan ?? "3m"
495
+ capacity: this.option.capacity ?? 1e3
605
496
  });
606
497
  }
607
498
  ensureValues(v) {
@@ -625,9 +516,7 @@ var BPTree = class {
625
516
  if (this.comparator.isSame(value, nValue)) {
626
517
  const keys = node.keys[i];
627
518
  if (keys.includes(key)) {
628
- throw new Error("The key already exists.", {
629
- cause: { key, value }
630
- });
519
+ break;
631
520
  }
632
521
  keys.push(key);
633
522
  this.bufferForNodeUpdate(node);
@@ -696,7 +585,7 @@ var BPTreeSync = class extends BPTree {
696
585
  return new CacheEntanglementSync((key) => {
697
586
  return this.strategy.read(key);
698
587
  }, {
699
- lifespan: this.option.lifespan ?? "3m"
588
+ capacity: this.option.capacity ?? 1e3
700
589
  });
701
590
  }
702
591
  getPairsRightToLeft(value, startNode, endNode, comparator) {
@@ -1288,7 +1177,7 @@ var BPTreeAsync = class extends BPTree {
1288
1177
  return new CacheEntanglementAsync(async (key) => {
1289
1178
  return await this.strategy.read(key);
1290
1179
  }, {
1291
- lifespan: this.option.lifespan ?? "3m"
1180
+ capacity: this.option.capacity ?? 1e3
1292
1181
  });
1293
1182
  }
1294
1183
  async getPairsRightToLeft(value, startNode, endNode, comparator) {
@@ -28,253 +28,132 @@ var StringComparator = class extends ValueComparator {
28
28
  };
29
29
 
30
30
  // node_modules/cache-entanglement/dist/esm/index.mjs
31
- var __create = Object.create;
32
- var __defProp = Object.defineProperty;
33
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
34
- var __getOwnPropNames = Object.getOwnPropertyNames;
35
- var __getProtoOf = Object.getPrototypeOf;
36
- var __hasOwnProp = Object.prototype.hasOwnProperty;
37
- var __commonJS = (cb, mod) => function __require() {
38
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
39
- };
40
- var __copyProps = (to, from, except, desc) => {
41
- if (from && typeof from === "object" || typeof from === "function") {
42
- for (let key of __getOwnPropNames(from))
43
- if (!__hasOwnProp.call(to, key) && key !== except)
44
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
31
+ var LRUMap = class {
32
+ capacity;
33
+ map;
34
+ head = null;
35
+ tail = null;
36
+ constructor(capacity) {
37
+ this.capacity = capacity;
38
+ this.map = /* @__PURE__ */ new Map();
39
+ }
40
+ // 내부 유틸리티: 노드를 헤드로 이동 (가장 최근 사용됨 표시)
41
+ promote(node) {
42
+ this.extract(node);
43
+ this.prepend(node);
44
+ }
45
+ // 내부 유틸리티: 리스트에서 노드 연결 끊기
46
+ extract(node) {
47
+ if (node.prev) node.prev.next = node.next;
48
+ else this.head = node.next;
49
+ if (node.next) node.next.prev = node.prev;
50
+ else this.tail = node.prev;
51
+ node.prev = null;
52
+ node.next = null;
53
+ }
54
+ // 내부 유틸리티: 리스트 맨 앞에 노드 삽입
55
+ prepend(node) {
56
+ node.next = this.head;
57
+ if (this.head) this.head.prev = node;
58
+ this.head = node;
59
+ if (!this.tail) this.tail = node;
45
60
  }
46
- return to;
47
- };
48
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
49
- // If the importer is in node compatibility mode or this is not an ESM
50
- // file that has been converted to a CommonJS file using a Babel-
51
- // compatible transform (i.e. "__esModule" has not been set), then set
52
- // "default" to the CommonJS "module.exports" for node compatibility.
53
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
54
- mod
55
- ));
56
- var require_ms = __commonJS({
57
- "node_modules/ms/index.js"(exports, module) {
58
- var s = 1e3;
59
- var m = s * 60;
60
- var h = m * 60;
61
- var d = h * 24;
62
- var w = d * 7;
63
- var y = d * 365.25;
64
- module.exports = function(val, options) {
65
- options = options || {};
66
- var type = typeof val;
67
- if (type === "string" && val.length > 0) {
68
- return parse(val);
69
- } else if (type === "number" && isFinite(val)) {
70
- return options.long ? fmtLong(val) : fmtShort(val);
71
- }
72
- throw new Error(
73
- "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
74
- );
75
- };
76
- function parse(str) {
77
- str = String(str);
78
- if (str.length > 100) {
79
- return;
80
- }
81
- 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(
82
- str
83
- );
84
- if (!match) {
85
- return;
86
- }
87
- var n = parseFloat(match[1]);
88
- var type = (match[2] || "ms").toLowerCase();
89
- switch (type) {
90
- case "years":
91
- case "year":
92
- case "yrs":
93
- case "yr":
94
- case "y":
95
- return n * y;
96
- case "weeks":
97
- case "week":
98
- case "w":
99
- return n * w;
100
- case "days":
101
- case "day":
102
- case "d":
103
- return n * d;
104
- case "hours":
105
- case "hour":
106
- case "hrs":
107
- case "hr":
108
- case "h":
109
- return n * h;
110
- case "minutes":
111
- case "minute":
112
- case "mins":
113
- case "min":
114
- case "m":
115
- return n * m;
116
- case "seconds":
117
- case "second":
118
- case "secs":
119
- case "sec":
120
- case "s":
121
- return n * s;
122
- case "milliseconds":
123
- case "millisecond":
124
- case "msecs":
125
- case "msec":
126
- case "ms":
127
- return n;
128
- default:
129
- return void 0;
130
- }
131
- }
132
- function fmtShort(ms2) {
133
- var msAbs = Math.abs(ms2);
134
- if (msAbs >= d) {
135
- return Math.round(ms2 / d) + "d";
136
- }
137
- if (msAbs >= h) {
138
- return Math.round(ms2 / h) + "h";
139
- }
140
- if (msAbs >= m) {
141
- return Math.round(ms2 / m) + "m";
142
- }
143
- if (msAbs >= s) {
144
- return Math.round(ms2 / s) + "s";
145
- }
146
- return ms2 + "ms";
61
+ /**
62
+ * 데이터를 저장하거나 업데이트합니다.
63
+ * 용량 초과 가장 오래된 항목(tail) 제거합니다.
64
+ */
65
+ set(key, value) {
66
+ const existing = this.map.get(key);
67
+ if (existing) {
68
+ existing.value = value;
69
+ this.promote(existing);
70
+ return;
147
71
  }
148
- function fmtLong(ms2) {
149
- var msAbs = Math.abs(ms2);
150
- if (msAbs >= d) {
151
- return plural(ms2, msAbs, d, "day");
152
- }
153
- if (msAbs >= h) {
154
- return plural(ms2, msAbs, h, "hour");
155
- }
156
- if (msAbs >= m) {
157
- return plural(ms2, msAbs, m, "minute");
158
- }
159
- if (msAbs >= s) {
160
- return plural(ms2, msAbs, s, "second");
161
- }
162
- return ms2 + " ms";
163
- }
164
- function plural(ms2, msAbs, n, name) {
165
- var isPlural = msAbs >= n * 1.5;
166
- return Math.round(ms2 / n) + " " + name + (isPlural ? "s" : "");
167
- }
168
- }
169
- });
170
- var import_ms = __toESM(require_ms());
171
- var InvertedWeakMap = class {
172
- _map;
173
- _keepAlive;
174
- _timeouts;
175
- _registry;
176
- _lifespan;
177
- constructor(option) {
178
- const { lifespan } = option;
179
- this._lifespan = lifespan;
180
- this._map = /* @__PURE__ */ new Map();
181
- this._keepAlive = /* @__PURE__ */ new Map();
182
- this._timeouts = /* @__PURE__ */ new Map();
183
- this._registry = new FinalizationRegistry((key) => {
184
- this._stopExpire(key, true);
185
- this._map.delete(key);
186
- });
187
- }
188
- clear() {
189
- this._keepAlive.clear();
190
- this._map.clear();
191
- }
192
- delete(key) {
193
- const ref = this._map.get(key);
194
- if (ref) {
195
- const raw = ref.deref();
196
- if (raw !== void 0) {
197
- this._registry.unregister(raw);
198
- }
72
+ const newNode = { key, value, prev: null, next: null };
73
+ this.map.set(key, newNode);
74
+ this.prepend(newNode);
75
+ if (this.map.size > this.capacity && this.tail) {
76
+ this.map.delete(this.tail.key);
77
+ this.extract(this.tail);
199
78
  }
200
- this._stopExpire(key, true);
201
- this._keepAlive.delete(key);
202
- return this._map.delete(key);
203
79
  }
80
+ /**
81
+ * 데이터를 가져옵니다. 접근한 데이터는 "최근 사용됨"으로 갱신됩니다.
82
+ */
204
83
  get(key) {
205
- return this._map.get(key)?.deref();
84
+ const node = this.map.get(key);
85
+ if (!node) return void 0;
86
+ this.promote(node);
87
+ return node.value;
206
88
  }
89
+ /**
90
+ * 키의 존재 여부를 확인합니다. (순서는 변경하지 않는 것이 일반적입니다)
91
+ */
207
92
  has(key) {
208
- return this._map.has(key) && this.get(key) !== void 0;
209
- }
210
- set(key, value) {
211
- this._map.set(key, new WeakRef(value));
212
- this._registry.register(value, key);
213
- if (this._lifespan > 0) {
214
- this._stopExpire(key, true);
215
- this._startExpire(key, value);
216
- }
217
- return this;
93
+ return this.map.has(key);
218
94
  }
219
- extendExpire(key) {
220
- if (!(this._lifespan > 0)) {
221
- return;
222
- }
223
- if (!this._keepAlive.has(key)) {
224
- return;
225
- }
226
- this._stopExpire(key, false);
227
- this._startExpire(key, this._keepAlive.get(key));
228
- }
229
- _startExpire(key, value) {
230
- this._keepAlive.set(key, value);
231
- this._timeouts.set(key, setTimeout(() => {
232
- this._keepAlive.delete(key);
233
- }, this._lifespan));
95
+ /**
96
+ * 특정 키와 데이터를 캐시에서 완전히 제거합니다.
97
+ */
98
+ delete(key) {
99
+ const node = this.map.get(key);
100
+ if (!node) return false;
101
+ this.extract(node);
102
+ this.map.delete(key);
103
+ return true;
234
104
  }
235
- _stopExpire(key, removeKeepAlive) {
236
- if (!this._timeouts.has(key)) {
237
- return;
238
- }
239
- const timeout = this._timeouts.get(key);
240
- this._timeouts.delete(key);
241
- clearTimeout(timeout);
242
- if (removeKeepAlive) {
243
- this._keepAlive.delete(key);
105
+ /**
106
+ * 현재 캐시된 키들을 최근 사용된 순서대로 반환합니다.
107
+ */
108
+ *keys() {
109
+ let current = this.head;
110
+ while (current) {
111
+ yield current.key;
112
+ current = current.next;
244
113
  }
245
114
  }
115
+ /**
116
+ * 현재 캐시된 아이템의 개수를 반환합니다.
117
+ */
246
118
  get size() {
247
- return this._map.size;
119
+ return this.map.size;
248
120
  }
249
- keys() {
250
- return this._map.keys();
121
+ /**
122
+ * 캐시를 완전히 비웁니다.
123
+ */
124
+ clear() {
125
+ this.map.clear();
126
+ this.head = null;
127
+ this.tail = null;
251
128
  }
252
129
  };
253
130
  var CacheEntanglement = class {
254
131
  creation;
255
132
  beforeUpdateHook;
256
- lifespan;
133
+ capacity;
257
134
  dependencies;
258
135
  caches;
259
- assignments;
260
136
  parameters;
137
+ assignments;
261
138
  dependencyProperties;
139
+ updateRequirements;
262
140
  constructor(creation, option) {
263
141
  option = option ?? {};
264
142
  const {
265
143
  dependencies,
266
- lifespan,
144
+ capacity,
267
145
  beforeUpdateHook
268
146
  } = option;
269
147
  this.creation = creation;
270
148
  this.beforeUpdateHook = beforeUpdateHook ?? (() => {
271
149
  });
272
- this.lifespan = this._normalizeMs(lifespan ?? 0);
150
+ this.capacity = capacity ?? 100;
273
151
  this.assignments = [];
274
- this.caches = new InvertedWeakMap({ lifespan: this.lifespan });
152
+ this.caches = new LRUMap(this.capacity);
153
+ this.parameters = /* @__PURE__ */ new Map();
275
154
  this.dependencies = dependencies ?? {};
276
155
  this.dependencyProperties = Object.keys(this.dependencies);
277
- this.parameters = {};
156
+ this.updateRequirements = /* @__PURE__ */ new Set();
278
157
  for (const name in this.dependencies) {
279
158
  const dependency = this.dependencies[name];
280
159
  if (!dependency.assignments.includes(this)) {
@@ -282,22 +161,30 @@ var CacheEntanglement = class {
282
161
  }
283
162
  }
284
163
  }
285
- _normalizeMs(time) {
286
- if (typeof time === "string") {
287
- return (0, import_ms.default)(time);
164
+ bubbleUpdateSignal(key) {
165
+ this.updateRequirements.add(key);
166
+ for (let i = 0, len = this.assignments.length; i < len; i++) {
167
+ const t = this.assignments[i];
168
+ const instance = t;
169
+ for (const cacheKey of instance.caches.keys()) {
170
+ if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
171
+ instance.bubbleUpdateSignal(cacheKey);
172
+ }
173
+ }
288
174
  }
289
- return time;
290
175
  }
291
176
  dependencyKey(key) {
292
- const tokens = key.split("/");
293
- tokens.pop();
294
- return tokens.join("/");
177
+ const i = key.lastIndexOf("/");
178
+ if (i === -1) {
179
+ return key;
180
+ }
181
+ return key.substring(0, i);
295
182
  }
296
183
  /**
297
184
  * Returns all keys stored in the instance.
298
185
  */
299
186
  keys() {
300
- return this.caches.keys();
187
+ return this.parameters.keys();
301
188
  }
302
189
  /**
303
190
  * Deletes all cache values stored in the instance.
@@ -312,17 +199,33 @@ var CacheEntanglement = class {
312
199
  * @param key The key to search.
313
200
  */
314
201
  exists(key) {
315
- return this.caches.has(key);
202
+ return this.parameters.has(key);
316
203
  }
317
204
  /**
318
- * Returns the cache value stored in the key within the instance. If the cached value is not present, an error is thrown.
205
+ * Checks if there is a cache value stored in the key within the instance.
206
+ * This method is an alias for `exists`.
319
207
  * @param key The key to search.
320
208
  */
321
- get(key) {
322
- if (!this.caches.has(key)) {
323
- throw new Error(`Cache value not found: ${key}`);
209
+ has(key) {
210
+ return this.exists(key);
211
+ }
212
+ /**
213
+ * Deletes the cache value stored in the key within the instance.
214
+ * @param key The key to delete.
215
+ */
216
+ delete(key) {
217
+ this.caches.delete(key);
218
+ this.parameters.delete(key);
219
+ this.updateRequirements.delete(key);
220
+ for (let i = 0, len = this.assignments.length; i < len; i++) {
221
+ const t = this.assignments[i];
222
+ const instance = t;
223
+ for (const cacheKey of instance.keys()) {
224
+ if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
225
+ instance.delete(cacheKey);
226
+ }
227
+ }
324
228
  }
325
- return this.caches.get(key);
326
229
  }
327
230
  };
328
231
  var CacheData = class _CacheData {
@@ -373,6 +276,15 @@ var CacheEntanglementSync = class extends CacheEntanglement {
373
276
  constructor(creation, option) {
374
277
  super(creation, option);
375
278
  }
279
+ recache(key) {
280
+ if (!this.parameters.has(key)) {
281
+ return;
282
+ }
283
+ if (!this.caches.has(key) || this.updateRequirements.has(key)) {
284
+ this.resolve(key, ...this.parameters.get(key));
285
+ }
286
+ return this.caches.get(key);
287
+ }
376
288
  resolve(key, ...parameter) {
377
289
  const resolved = {};
378
290
  const dependencyKey = this.dependencyKey(key);
@@ -380,59 +292,53 @@ var CacheEntanglementSync = class extends CacheEntanglement {
380
292
  for (let i = 0, len = this.dependencyProperties.length; i < len; i++) {
381
293
  const name = this.dependencyProperties[i];
382
294
  const dependency = this.dependencies[name];
383
- if (!dependency.caches.has(key) && !dependency.caches.has(dependencyKey)) {
295
+ if (!dependency.exists(key) && !dependency.exists(dependencyKey)) {
384
296
  throw new Error(`The key '${key}' or '${dependencyKey}' has not been assigned yet in dependency '${name.toString()}'.`, {
385
297
  cause: {
386
298
  from: this
387
299
  }
388
300
  });
389
301
  }
390
- const dependencyValue = dependency.caches.get(key) ?? dependency.caches.get(dependencyKey);
302
+ const dependencyValue = dependency.recache(key) ?? dependency.recache(dependencyKey);
391
303
  resolved[name] = dependencyValue;
392
304
  }
393
- this.parameters[key] = parameter;
394
305
  const value = new CacheData(this.creation(key, resolved, ...parameter));
306
+ this.updateRequirements.delete(key);
307
+ this.parameters.set(key, parameter);
395
308
  this.caches.set(key, value);
396
309
  return value;
397
310
  }
311
+ get(key) {
312
+ if (!this.parameters.has(key)) {
313
+ throw new Error(`Cache value not found: ${key}`);
314
+ }
315
+ return this.cache(key, ...this.parameters.get(key));
316
+ }
398
317
  cache(key, ...parameter) {
399
- if (!this.caches.has(key)) {
400
- this.update(key, ...parameter);
401
- } else {
402
- this.caches.extendExpire(key);
318
+ if (!this.caches.has(key) || this.updateRequirements.has(key)) {
319
+ this.resolve(key, ...parameter);
403
320
  }
404
321
  return this.caches.get(key);
405
322
  }
406
323
  update(key, ...parameter) {
324
+ this.bubbleUpdateSignal(key);
407
325
  this.resolve(key, ...parameter);
408
- for (let i = 0, len = this.assignments.length; i < len; i++) {
409
- const t = this.assignments[i];
410
- const instance = t;
411
- for (const cacheKey of instance.caches.keys()) {
412
- if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
413
- instance.update(cacheKey, ...instance.parameters[cacheKey]);
414
- }
415
- }
416
- }
417
326
  return this.caches.get(key);
418
327
  }
419
- delete(key) {
420
- this.caches.delete(key);
421
- for (let i = 0, len = this.assignments.length; i < len; i++) {
422
- const t = this.assignments[i];
423
- const instance = t;
424
- for (const cacheKey of instance.caches.keys()) {
425
- if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
426
- instance.delete(cacheKey);
427
- }
428
- }
429
- }
430
- }
431
328
  };
432
329
  var CacheEntanglementAsync = class extends CacheEntanglement {
433
330
  constructor(creation, option) {
434
331
  super(creation, option);
435
332
  }
333
+ async recache(key) {
334
+ if (!this.parameters.has(key)) {
335
+ return;
336
+ }
337
+ if (!this.caches.has(key) || this.updateRequirements.has(key)) {
338
+ await this.resolve(key, ...this.parameters.get(key));
339
+ }
340
+ return this.caches.get(key);
341
+ }
436
342
  async resolve(key, ...parameter) {
437
343
  const resolved = {};
438
344
  const dependencyKey = this.dependencyKey(key);
@@ -440,54 +346,39 @@ var CacheEntanglementAsync = class extends CacheEntanglement {
440
346
  for (let i = 0, len = this.dependencyProperties.length; i < len; i++) {
441
347
  const name = this.dependencyProperties[i];
442
348
  const dependency = this.dependencies[name];
443
- if (!dependency.caches.has(key) && !dependency.caches.has(dependencyKey)) {
349
+ if (!dependency.exists(key) && !dependency.exists(dependencyKey)) {
444
350
  throw new Error(`The key '${key}' or '${dependencyKey}' has not been assigned yet in dependency '${name.toString()}'.`, {
445
351
  cause: {
446
352
  from: this
447
353
  }
448
354
  });
449
355
  }
450
- const dependencyValue = dependency.caches.get(key) ?? dependency.caches.get(dependencyKey);
356
+ const dependencyValue = await dependency.recache(key) ?? await dependency.recache(dependencyKey);
451
357
  resolved[name] = dependencyValue;
452
358
  }
453
- this.parameters[key] = parameter;
454
359
  const value = new CacheData(await this.creation(key, resolved, ...parameter));
360
+ this.updateRequirements.delete(key);
361
+ this.parameters.set(key, parameter);
455
362
  this.caches.set(key, value);
456
363
  return value;
457
364
  }
365
+ async get(key) {
366
+ if (!this.parameters.has(key)) {
367
+ throw new Error(`Cache value not found: ${key}`);
368
+ }
369
+ return this.cache(key, ...this.parameters.get(key));
370
+ }
458
371
  async cache(key, ...parameter) {
459
- if (!this.caches.has(key)) {
372
+ if (!this.caches.has(key) || this.updateRequirements.has(key)) {
460
373
  await this.update(key, ...parameter);
461
- } else {
462
- this.caches.extendExpire(key);
463
374
  }
464
375
  return this.caches.get(key);
465
376
  }
466
377
  async update(key, ...parameter) {
378
+ this.bubbleUpdateSignal(key);
467
379
  await this.resolve(key, ...parameter);
468
- for (let i = 0, len = this.assignments.length; i < len; i++) {
469
- const t = this.assignments[i];
470
- const instance = t;
471
- for (const cacheKey of instance.caches.keys()) {
472
- if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
473
- await instance.update(cacheKey, ...instance.parameters[cacheKey]);
474
- }
475
- }
476
- }
477
380
  return this.caches.get(key);
478
381
  }
479
- async delete(key) {
480
- this.caches.delete(key);
481
- for (let i = 0, len = this.assignments.length; i < len; i++) {
482
- const t = this.assignments[i];
483
- const instance = t;
484
- for (const cacheKey of instance.caches.keys()) {
485
- if (cacheKey === key || cacheKey.startsWith(`${key}/`)) {
486
- await instance.delete(cacheKey);
487
- }
488
- }
489
- }
490
- }
491
382
  };
492
383
 
493
384
  // src/base/BPTree.ts
@@ -567,7 +458,7 @@ var BPTree = class {
567
458
  const regexp = new RegExp(`^${pattern}$`, "i");
568
459
  return regexp;
569
460
  }, {
570
- lifespan: this.option.lifespan ?? "3m"
461
+ capacity: this.option.capacity ?? 1e3
571
462
  });
572
463
  }
573
464
  ensureValues(v) {
@@ -591,9 +482,7 @@ var BPTree = class {
591
482
  if (this.comparator.isSame(value, nValue)) {
592
483
  const keys = node.keys[i];
593
484
  if (keys.includes(key)) {
594
- throw new Error("The key already exists.", {
595
- cause: { key, value }
596
- });
485
+ break;
597
486
  }
598
487
  keys.push(key);
599
488
  this.bufferForNodeUpdate(node);
@@ -662,7 +551,7 @@ var BPTreeSync = class extends BPTree {
662
551
  return new CacheEntanglementSync((key) => {
663
552
  return this.strategy.read(key);
664
553
  }, {
665
- lifespan: this.option.lifespan ?? "3m"
554
+ capacity: this.option.capacity ?? 1e3
666
555
  });
667
556
  }
668
557
  getPairsRightToLeft(value, startNode, endNode, comparator) {
@@ -1254,7 +1143,7 @@ var BPTreeAsync = class extends BPTree {
1254
1143
  return new CacheEntanglementAsync(async (key) => {
1255
1144
  return await this.strategy.read(key);
1256
1145
  }, {
1257
- lifespan: this.option.lifespan ?? "3m"
1146
+ capacity: this.option.capacity ?? 1e3
1258
1147
  });
1259
1148
  }
1260
1149
  async getPairsRightToLeft(value, startNode, endNode, comparator) {
@@ -4,7 +4,7 @@ import { ValueComparator } from './base/ValueComparator';
4
4
  import { SerializableData } from './base/SerializeStrategy';
5
5
  export declare class BPTreeAsync<K, V> extends BPTree<K, V> {
6
6
  protected readonly strategy: SerializeStrategyAsync<K, V>;
7
- protected readonly nodes: ReturnType<BPTreeAsync<K, V>['_createCachedNode']>;
7
+ protected readonly nodes: ReturnType<typeof this._createCachedNode>;
8
8
  constructor(strategy: SerializeStrategyAsync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
9
9
  private _createCachedNode;
10
10
  protected getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): Promise<BPTreePair<K, V>>;
@@ -4,7 +4,7 @@ import { ValueComparator } from './base/ValueComparator';
4
4
  import { SerializableData } from './base/SerializeStrategy';
5
5
  export declare class BPTreeSync<K, V> extends BPTree<K, V> {
6
6
  protected readonly strategy: SerializeStrategySync<K, V>;
7
- protected readonly nodes: ReturnType<BPTreeSync<K, V>['_createCachedNode']>;
7
+ protected readonly nodes: ReturnType<typeof this._createCachedNode>;
8
8
  constructor(strategy: SerializeStrategySync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
9
9
  private _createCachedNode;
10
10
  protected getPairsRightToLeft(value: V, startNode: BPTreeLeafNode<K, V>, endNode: BPTreeLeafNode<K, V> | null, comparator: (nodeValue: V, value: V) => boolean): BPTreePair<K, V>;
@@ -1,4 +1,4 @@
1
- import { CacheEntanglementSync, CacheEntanglementAsync, type StringValue } from 'cache-entanglement';
1
+ import { CacheEntanglementSync, CacheEntanglementAsync } from 'cache-entanglement';
2
2
  import { ValueComparator } from './ValueComparator';
3
3
  import { SerializableData, SerializeStrategy } from './SerializeStrategy';
4
4
  type Sync<T> = T;
@@ -27,14 +27,11 @@ export type BPTreePair<K, V> = Map<K, V>;
27
27
  export type BPTreeUnknownNode<K, V> = BPTreeInternalNode<K, V> | BPTreeLeafNode<K, V>;
28
28
  export interface BPTreeConstructorOption {
29
29
  /**
30
- * The lifespan of the cached node.
31
- * This value is used to determine how long a cached node should be kept in memory.
32
- * If the lifespan is set to a positive number, the cached node will expire after the specified number of milliseconds.
33
- * If the lifespan is set to `0` or a negative number, the cache will not prevent garbage collection.
34
- * If the lifespan is set to a string, the string will be parsed as a time duration.
35
- * For example, '1m' means 1 minute, '1h' means 1 hour, '1d' means 1 day, '1w' means 1 week.
30
+ * The capacity of the cache.
31
+ * This value is used to determine how many nodes can be cached.
32
+ * If not specified, the default value is 1000.
36
33
  */
37
- lifespan?: StringValue | number;
34
+ capacity?: number;
38
35
  }
39
36
  export interface BPTreeNode<K, V> {
40
37
  id: string;
@@ -1,4 +1,4 @@
1
- export type { BPTreeNode, BPTreeCondition } from './base/BPTree';
1
+ export type { BPTreeNode, BPTreeInternalNode, BPTreeLeafNode, BPTreeNodeKey, BPTreePair, BPTreeUnknownNode, BPTreeCondition } from './base/BPTree';
2
2
  export type { SerializeStrategyHead, SerializableData } from './base/SerializeStrategy';
3
3
  export { ValueComparator, NumericComparator, StringComparator } from './base/ValueComparator';
4
4
  export { BPTreeSync } from './BPTreeSync';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serializable-bptree",
3
- "version": "5.1.4",
3
+ "version": "5.2.0",
4
4
  "description": "Store the B+tree flexibly, not only in-memory.",
5
5
  "types": "./dist/types/index.d.ts",
6
6
  "main": "./dist/cjs/index.cjs",
@@ -16,7 +16,7 @@
16
16
  "dist/**/*"
17
17
  ],
18
18
  "scripts": {
19
- "test": "jest -t",
19
+ "test": "jest",
20
20
  "build": "node build/index.js && tsc"
21
21
  },
22
22
  "author": "izure <admin@izure.org>",
@@ -36,13 +36,13 @@
36
36
  },
37
37
  "license": "MIT",
38
38
  "devDependencies": {
39
- "@types/jest": "^29.5.14",
40
- "esbuild": "^0.25.5",
41
- "jest": "^29.7.0",
42
- "ts-jest": "^29.4.0",
43
- "typescript": "^5.8.3"
39
+ "@types/jest": "^30.0.0",
40
+ "esbuild": "^0.27.2",
41
+ "jest": "^30.2.0",
42
+ "ts-jest": "^29.4.6",
43
+ "typescript": "^5.9.3"
44
44
  },
45
45
  "dependencies": {
46
- "cache-entanglement": "^1.5.5"
46
+ "cache-entanglement": "^1.7.0"
47
47
  }
48
- }
48
+ }