lunibee 0.1.7 → 0.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.
Files changed (78) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +225 -223
  3. package/dist/builders/commands.d.ts +6 -4
  4. package/dist/builders/components.d.ts +23 -0
  5. package/dist/builders/index.d.ts +2 -2
  6. package/dist/builders/index.js +120 -24
  7. package/dist/builders/index.js.map +9 -8
  8. package/dist/collection/index.d.ts +68 -1
  9. package/dist/collection/index.js +335 -1
  10. package/dist/collection/index.js.map +4 -4
  11. package/dist/core/collector.d.ts +13 -0
  12. package/dist/core/events.d.ts +112 -2
  13. package/dist/core/index.d.ts +30 -93
  14. package/dist/core/index.js +3386 -957
  15. package/dist/core/index.js.map +48 -24
  16. package/dist/core/permissions.d.ts +48 -0
  17. package/dist/formatters/index.js.map +1 -1
  18. package/dist/handlers/index.js.map +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.js +3806 -1193
  21. package/dist/index.js.map +64 -43
  22. package/dist/managers/advanced.d.ts +116 -0
  23. package/dist/managers/base.d.ts +13 -2
  24. package/dist/managers/emoji.d.ts +1 -1
  25. package/dist/managers/guild-resources.d.ts +109 -0
  26. package/dist/managers/guild.d.ts +33 -2
  27. package/dist/managers/index.d.ts +44 -6
  28. package/dist/managers/index.js +1186 -150
  29. package/dist/managers/index.js.map +27 -21
  30. package/dist/managers/message.d.ts +10 -1
  31. package/dist/rest/decoder.d.ts +23 -0
  32. package/dist/rest/errors.d.ts +53 -0
  33. package/dist/rest/index.d.ts +21 -17
  34. package/dist/rest/index.js +526 -264
  35. package/dist/rest/index.js.map +14 -8
  36. package/dist/rest/limiter.d.ts +42 -0
  37. package/dist/rest/redis.d.ts +18 -1
  38. package/dist/rest/route.d.ts +31 -0
  39. package/dist/rest/routes.d.ts +22 -0
  40. package/dist/rest/scheduler.d.ts +42 -0
  41. package/dist/rest/store.d.ts +29 -0
  42. package/dist/rest/transport.d.ts +40 -0
  43. package/dist/sharding/bus.d.ts +31 -0
  44. package/dist/sharding/cluster.d.ts +10 -0
  45. package/dist/sharding/index.d.ts +39 -2
  46. package/dist/sharding/index.js +1105 -404
  47. package/dist/sharding/index.js.map +18 -8
  48. package/dist/structures/base.d.ts +10 -0
  49. package/dist/structures/channels.d.ts +56 -0
  50. package/dist/structures/index.d.ts +1 -0
  51. package/dist/structures/index.js +305 -311
  52. package/dist/structures/index.js.map +18 -14
  53. package/dist/structures/interactions.d.ts +38 -52
  54. package/dist/structures/options.d.ts +55 -0
  55. package/dist/structures/resources.d.ts +3 -3
  56. package/dist/types/gateway-events.d.ts +132 -0
  57. package/dist/types/gateway.d.ts +197 -0
  58. package/dist/types/index.d.ts +53 -260
  59. package/dist/types/index.js +44 -2
  60. package/dist/types/index.js.map +5 -4
  61. package/dist/utils/index.js.map +1 -1
  62. package/dist/voice/index.d.ts +32 -1
  63. package/dist/voice/index.js +73 -7
  64. package/dist/voice/index.js.map +3 -3
  65. package/dist/ws/close-codes.d.ts +23 -0
  66. package/dist/ws/decoder.d.ts +58 -0
  67. package/dist/ws/heartbeat.d.ts +87 -0
  68. package/dist/ws/index.d.ts +18 -65
  69. package/dist/ws/index.js +911 -385
  70. package/dist/ws/index.js.map +15 -5
  71. package/dist/ws/opcodes.d.ts +14 -0
  72. package/dist/ws/protocol.d.ts +110 -0
  73. package/dist/ws/reconnect.d.ts +108 -0
  74. package/dist/ws/send-budget.d.ts +17 -0
  75. package/dist/ws/session.d.ts +100 -0
  76. package/dist/ws/state.d.ts +27 -0
  77. package/dist/ws/transport.d.ts +80 -0
  78. package/package.json +21 -20
@@ -1,5 +1,72 @@
1
- /** A lightweight keyed collection for Lunibee resource and application state. */
1
+ /** Retention policy for a {@link Collection}. */
2
+ export interface CollectionOptions<K = unknown, V = unknown> {
3
+ /** Default sliding TTL in ms for `set()`. Omit for no expiry. */
4
+ ttl?: number;
5
+ /** Maximum entries stored with `set()`; least-recently-used are evicted past it. `setWithoutTTL()` entries are never counted or evicted. */
6
+ maxSize?: number;
7
+ /** Called after an entry is removed automatically, with why. Exceptions are swallowed. */
8
+ onEvict?: (key: K, value: V, reason: EvictionReason) => void;
9
+ }
10
+ /** Why an entry was removed automatically. */
11
+ export type EvictionReason = "expired" | "evicted";
12
+ /** Cumulative counters from {@link Collection.stats}. */
13
+ export interface CollectionStats {
14
+ /** `get`/`peek` calls that found a value. */ hits: number;
15
+ /** `get`/`peek` calls that found nothing. */ misses: number;
16
+ /** Entries removed because their TTL lapsed. */ expired: number;
17
+ /** Entries removed to stay within `maxSize`. */ evicted: number;
18
+ }
19
+ /**
20
+ * A keyed collection for Lunibee resource and application state.
21
+ *
22
+ * - `set(key, value, ttl?)` is TTL/LRU-aware: with a TTL (the default from
23
+ * options, or per call) the entry expires after that window of inactivity,
24
+ * and with `maxSize` it counts toward the cap.
25
+ * - `setWithoutTTL(key, value)` never expires: no deadline, no heap record,
26
+ * no timer, and exempt from `maxSize` eviction. Resource managers store
27
+ * Discord state this way, so it leaves only through an explicit delete.
28
+ *
29
+ * Without options, a Collection behaves like a plain Map.
30
+ */
2
31
  export declare class Collection<K, V> extends Map<K, V> {
32
+ #private;
33
+ /**
34
+ * @param entries Initial entries, stored with `set()`.
35
+ * @param options TTL and size policy.
36
+ * @throws {RangeError} On a non-positive TTL or non-integer `maxSize`.
37
+ */
38
+ constructor(entries?: Iterable<readonly [K, V]> | null, options?: CollectionOptions<K, V>);
39
+ /**
40
+ * Stores an entry with the default TTL (or `ttl`), marks it most recently
41
+ * used, and enforces `maxSize`. Turns a `setWithoutTTL()` entry back into
42
+ * a TTL/LRU entry.
43
+ */
44
+ set(key: K, value: V, ttl?: number): this;
45
+ /**
46
+ * Stores an entry that never expires: no deadline, heap record, timer or
47
+ * LRU eviction. It leaves only through `delete`, `sweep`, `clear`, or a
48
+ * later `set()`.
49
+ */
50
+ setWithoutTTL(key: K, value: V): this;
51
+ /** Reads a value; restarts a TTL entry's window and promotes it. */
52
+ get(key: K): V | undefined;
53
+ /** Reads a value without restarting its TTL or promoting it. */
54
+ peek(key: K): V | undefined;
55
+ /** Cumulative hit, miss, expiry and eviction counters (a copy). */
56
+ get stats(): CollectionStats;
57
+ has(key: K): boolean;
58
+ delete(key: K): boolean;
59
+ clear(): void;
60
+ get size(): number;
61
+ entries(): MapIterator<[K, V]>;
62
+ keys(): MapIterator<K>;
63
+ values(): MapIterator<V>;
64
+ [Symbol.iterator](): MapIterator<[K, V]>;
65
+ forEach(callback: (value: V, key: K, map: Map<K, V>) => void, thisArg?: unknown): void;
66
+ /** Milliseconds until a key lapses, or undefined if absent or never expiring. */
67
+ ttlRemaining(key: K): number | undefined;
68
+ /** Drops every lapsed TTL entry now. @returns How many were dropped. */
69
+ purge(): number;
3
70
  /** Returns the first stored value. */
4
71
  first(): V | undefined;
5
72
  /** Returns the first stored key. */
@@ -17,6 +17,7 @@ class Cache {
17
17
  if (!Number.isFinite(interval) || interval < 1)
18
18
  throw new RangeError("Cache sweepInterval must be positive.");
19
19
  this.#timer = setInterval(() => this.sweep(), interval);
20
+ this.#timer.unref?.();
20
21
  }
21
22
  }
22
23
  get size() {
@@ -95,7 +96,340 @@ class Cache {
95
96
  }
96
97
 
97
98
  // packages/collection/src/index.ts
99
+ class RecencyList {
100
+ #nodes = new Map;
101
+ #oldest;
102
+ #newest;
103
+ get size() {
104
+ return this.#nodes.size;
105
+ }
106
+ oldest() {
107
+ return this.#oldest?.key;
108
+ }
109
+ touch(key) {
110
+ const node = this.#nodes.get(key);
111
+ if (node)
112
+ return this.#moveNewest(node);
113
+ const created = { key, older: this.#newest };
114
+ if (this.#newest)
115
+ this.#newest.newer = created;
116
+ else
117
+ this.#oldest = created;
118
+ this.#newest = created;
119
+ this.#nodes.set(key, created);
120
+ }
121
+ promote(key) {
122
+ const node = this.#nodes.get(key);
123
+ if (node)
124
+ this.#moveNewest(node);
125
+ }
126
+ delete(key) {
127
+ const node = this.#nodes.get(key);
128
+ if (!node)
129
+ return false;
130
+ this.#unlink(node);
131
+ this.#nodes.delete(key);
132
+ return true;
133
+ }
134
+ clear() {
135
+ this.#nodes.clear();
136
+ this.#oldest = this.#newest = undefined;
137
+ }
138
+ #unlink(node) {
139
+ if (node.older)
140
+ node.older.newer = node.newer;
141
+ else
142
+ this.#oldest = node.newer;
143
+ if (node.newer)
144
+ node.newer.older = node.older;
145
+ else
146
+ this.#newest = node.older;
147
+ node.older = node.newer = undefined;
148
+ }
149
+ #moveNewest(node) {
150
+ if (node === this.#newest)
151
+ return;
152
+ this.#unlink(node);
153
+ node.older = this.#newest;
154
+ if (this.#newest)
155
+ this.#newest.newer = node;
156
+ else
157
+ this.#oldest = node;
158
+ this.#newest = node;
159
+ }
160
+ }
161
+ function assertTTL(ttl) {
162
+ if (ttl !== undefined && (!Number.isFinite(ttl) || ttl <= 0))
163
+ throw new RangeError("TTL must be a positive number, or omitted.");
164
+ }
165
+
98
166
  class Collection extends Map {
167
+ #ttl;
168
+ #maxSize;
169
+ #onEvict;
170
+ #expiry = new Map;
171
+ #lru = new RecencyList;
172
+ #stats = {
173
+ hits: 0,
174
+ misses: 0,
175
+ expired: 0,
176
+ evicted: 0
177
+ };
178
+ #heap = [];
179
+ #timer;
180
+ #armedFor = Infinity;
181
+ constructor(entries, options = {}) {
182
+ super();
183
+ assertTTL(options.ttl);
184
+ if (options.maxSize !== undefined && (!Number.isInteger(options.maxSize) || options.maxSize <= 0))
185
+ throw new RangeError("maxSize must be a positive integer.");
186
+ this.#ttl = options.ttl;
187
+ this.#maxSize = options.maxSize;
188
+ this.#onEvict = options.onEvict;
189
+ if (entries)
190
+ for (const [key, value] of entries)
191
+ this.set(key, value);
192
+ }
193
+ set(key, value, ttl) {
194
+ assertTTL(ttl);
195
+ const window = ttl ?? this.#ttl;
196
+ if (this.#maxSize !== undefined) {
197
+ this.#lru.touch(key);
198
+ }
199
+ super.set(key, value);
200
+ if (window !== undefined)
201
+ this.#schedule(key, window);
202
+ else if (this.#expiry.size > 0)
203
+ this.#expiry.delete(key);
204
+ this.#enforceCap();
205
+ return this;
206
+ }
207
+ setWithoutTTL(key, value) {
208
+ if (this.#expiry.size > 0)
209
+ this.#expiry.delete(key);
210
+ if (this.#lru.size > 0)
211
+ this.#lru.delete(key);
212
+ super.set(key, value);
213
+ return this;
214
+ }
215
+ get(key) {
216
+ if (this.#expireIfDue(key)) {
217
+ this.#stats.misses++;
218
+ return;
219
+ }
220
+ const value = super.get(key);
221
+ if (value === undefined && !super.has(key)) {
222
+ this.#stats.misses++;
223
+ return;
224
+ }
225
+ this.#stats.hits++;
226
+ const expiry = this.#expiry.get(key);
227
+ if (expiry)
228
+ expiry.deadline = Date.now() + expiry.window;
229
+ this.#lru.promote(key);
230
+ return value;
231
+ }
232
+ peek(key) {
233
+ if (!this.#expireIfDue(key) && super.has(key)) {
234
+ this.#stats.hits++;
235
+ return super.get(key);
236
+ }
237
+ this.#stats.misses++;
238
+ return;
239
+ }
240
+ get stats() {
241
+ return { ...this.#stats };
242
+ }
243
+ has(key) {
244
+ return !this.#expireIfDue(key) && super.has(key);
245
+ }
246
+ delete(key) {
247
+ if (this.#expireIfDue(key))
248
+ return false;
249
+ this.#expiry.delete(key);
250
+ this.#lru.delete(key);
251
+ return super.delete(key);
252
+ }
253
+ clear() {
254
+ super.clear();
255
+ this.#expiry.clear();
256
+ this.#lru.clear();
257
+ this.#heap.length = 0;
258
+ if (this.#timer)
259
+ clearTimeout(this.#timer);
260
+ this.#timer = undefined;
261
+ this.#armedFor = Infinity;
262
+ }
263
+ get size() {
264
+ this.purge();
265
+ return super.size;
266
+ }
267
+ entries() {
268
+ this.purge();
269
+ return super.entries();
270
+ }
271
+ keys() {
272
+ this.purge();
273
+ return super.keys();
274
+ }
275
+ values() {
276
+ this.purge();
277
+ return super.values();
278
+ }
279
+ [Symbol.iterator]() {
280
+ return this.entries();
281
+ }
282
+ forEach(callback, thisArg) {
283
+ this.purge();
284
+ super.forEach(callback, thisArg);
285
+ }
286
+ ttlRemaining(key) {
287
+ if (this.#expireIfDue(key))
288
+ return;
289
+ const expiry = this.#expiry.get(key);
290
+ return expiry && Math.max(0, expiry.deadline - Date.now());
291
+ }
292
+ purge() {
293
+ if (this.#expiry.size === 0)
294
+ return 0;
295
+ const now = Date.now();
296
+ let removed = 0;
297
+ const dropped = [];
298
+ while (this.#nextDeadline() <= now) {
299
+ const due = this.#heapPop();
300
+ dropped.push([due.key, super.get(due.key)]);
301
+ this.#remove(due.key);
302
+ removed++;
303
+ }
304
+ this.#stats.expired += removed;
305
+ this.#rearm();
306
+ for (const [key, value] of dropped)
307
+ this.#notify(key, value, "expired");
308
+ return removed;
309
+ }
310
+ #expireIfDue(key) {
311
+ const expiry = this.#expiry.get(key);
312
+ if (!expiry || expiry.deadline > Date.now())
313
+ return false;
314
+ const value = super.get(key);
315
+ this.#remove(key);
316
+ this.#stats.expired++;
317
+ this.#notify(key, value, "expired");
318
+ return true;
319
+ }
320
+ #remove(key) {
321
+ this.#expiry.delete(key);
322
+ this.#lru.delete(key);
323
+ super.delete(key);
324
+ }
325
+ #notify(key, value, reason) {
326
+ if (!this.#onEvict)
327
+ return;
328
+ try {
329
+ this.#onEvict(key, value, reason);
330
+ } catch {}
331
+ }
332
+ #enforceCap() {
333
+ if (this.#maxSize === undefined)
334
+ return;
335
+ while (this.#lru.size > this.#maxSize) {
336
+ const oldest = this.#lru.oldest();
337
+ const value = super.get(oldest);
338
+ this.#remove(oldest);
339
+ this.#stats.evicted++;
340
+ this.#notify(oldest, value, "evicted");
341
+ }
342
+ }
343
+ #schedule(key, window) {
344
+ const deadline = Date.now() + window;
345
+ const expiry = this.#expiry.get(key);
346
+ if (expiry) {
347
+ expiry.deadline = deadline;
348
+ expiry.window = window;
349
+ if (deadline >= expiry.filed)
350
+ return;
351
+ expiry.filed = deadline;
352
+ } else
353
+ this.#expiry.set(key, { deadline, window, filed: deadline });
354
+ this.#heapPush({ key, deadline });
355
+ if (this.#heap.length > 2 * this.#expiry.size + 8)
356
+ this.#compact();
357
+ this.#rearm();
358
+ }
359
+ #nextDeadline() {
360
+ for (;; ) {
361
+ const top = this.#heap[0];
362
+ if (top === undefined)
363
+ return Infinity;
364
+ const expiry = this.#expiry.get(top.key);
365
+ if (!expiry || expiry.filed !== top.deadline) {
366
+ this.#heapPop();
367
+ continue;
368
+ }
369
+ if (expiry.deadline === top.deadline)
370
+ return top.deadline;
371
+ this.#heapPop();
372
+ expiry.filed = expiry.deadline;
373
+ this.#heapPush({ key: top.key, deadline: expiry.deadline });
374
+ }
375
+ }
376
+ #compact() {
377
+ const live = this.#heap.filter((record) => this.#expiry.get(record.key)?.filed === record.deadline);
378
+ this.#heap.length = 0;
379
+ for (const record of live)
380
+ this.#heapPush(record);
381
+ }
382
+ #rearm() {
383
+ const deadline = this.#nextDeadline();
384
+ if (this.#timer !== undefined && deadline >= this.#armedFor)
385
+ return;
386
+ if (this.#timer)
387
+ clearTimeout(this.#timer);
388
+ this.#timer = undefined;
389
+ this.#armedFor = deadline;
390
+ if (deadline === Infinity)
391
+ return;
392
+ this.#timer = setTimeout(() => {
393
+ this.#timer = undefined;
394
+ this.#armedFor = Infinity;
395
+ this.purge();
396
+ }, Math.max(0, deadline - Date.now()));
397
+ this.#timer.unref?.();
398
+ }
399
+ #heapPush(record) {
400
+ const heap = this.#heap;
401
+ heap.push(record);
402
+ let i = heap.length - 1;
403
+ while (i > 0) {
404
+ const parent = i - 1 >> 1;
405
+ if (heap[parent].deadline <= heap[i].deadline)
406
+ break;
407
+ [heap[parent], heap[i]] = [heap[i], heap[parent]];
408
+ i = parent;
409
+ }
410
+ }
411
+ #heapPop() {
412
+ const heap = this.#heap;
413
+ const top = heap[0];
414
+ const last = heap.pop();
415
+ if (top === undefined || heap.length === 0)
416
+ return top;
417
+ heap[0] = last;
418
+ for (let i = 0;; ) {
419
+ const left = 2 * i + 1;
420
+ const right = left + 1;
421
+ let smallest = i;
422
+ if (left < heap.length && heap[left].deadline < heap[smallest].deadline)
423
+ smallest = left;
424
+ if (right < heap.length && heap[right].deadline < heap[smallest].deadline)
425
+ smallest = right;
426
+ if (smallest === i)
427
+ break;
428
+ [heap[smallest], heap[i]] = [heap[i], heap[smallest]];
429
+ i = smallest;
430
+ }
431
+ return top;
432
+ }
99
433
  first() {
100
434
  for (const value of this.values())
101
435
  return value;
@@ -315,4 +649,4 @@ export {
315
649
  Collection
316
650
  };
317
651
 
318
- //# debugId=F7AF9637261DF97664756E2164756E21
652
+ //# debugId=4109A00736CB03B064756E2164756E21
@@ -2,10 +2,10 @@
2
2
  "version": 3,
3
3
  "sources": ["../../packages/collection/src/cache.ts", "../../packages/collection/src/index.ts"],
4
4
  "sourcesContent": [
5
- "import { Collection } from \"./index.js\";\r\n\r\n/** Cache policy for bounded resource storage. */\r\nexport interface CacheOptions {\r\n /** Maximum number of entries retained. */\r\n maxSize?: number;\r\n /** Time-to-live in milliseconds. Omit to disable expiration. */\r\n ttl?: number;\r\n /** Sweep interval in milliseconds. */\r\n sweepInterval?: number;\r\n}\r\n\r\ntype Entry<V> = { value: V; expiresAt: number };\r\n\r\n/** Bounded cache with TTL expiration and explicit invalidation support. */\r\nexport class Cache<K, V> {\r\n readonly #entries = new Collection<K, Entry<V>>();\r\n readonly #maxSize: number;\r\n readonly #ttl: number;\r\n #timer?: ReturnType<typeof setInterval>;\r\n\r\n /** Creates a cache using the supplied retention policy. */\r\n public constructor(options: CacheOptions = {}) {\r\n this.#maxSize = options.maxSize ?? Infinity;\r\n this.#ttl = options.ttl ?? 0;\r\n if (\r\n (!Number.isInteger(this.#maxSize) && this.#maxSize !== Infinity) ||\r\n this.#maxSize < 1\r\n )\r\n throw new RangeError(\"Cache maxSize must be a positive integer.\");\r\n if (!Number.isFinite(this.#ttl) || this.#ttl < 0)\r\n throw new RangeError(\r\n \"Cache ttl must be a non-negative finite number.\",\r\n );\r\n if (this.#ttl > 0) {\r\n const interval =\r\n options.sweepInterval ?? Math.min(this.#ttl, 60_000);\r\n if (!Number.isFinite(interval) || interval < 1)\r\n throw new RangeError(\"Cache sweepInterval must be positive.\");\r\n this.#timer = setInterval(() => this.sweep(), interval);\r\n }\r\n }\r\n\r\n /** Number of currently live entries. */\r\n public get size(): number {\r\n this.#sweepExpired();\r\n return this.#entries.size;\r\n }\r\n /** Reads a live entry. */\r\n public get(key: K): V | undefined {\r\n const entry = this.#entries.get(key);\r\n if (!entry) return undefined;\r\n if (entry.expiresAt > 0 && entry.expiresAt <= Date.now()) {\r\n this.#entries.delete(key);\r\n return undefined;\r\n }\r\n // LRU Promotion: move to end of insertion order\r\n this.#entries.delete(key);\r\n this.#entries.set(key, entry);\r\n return entry.value;\r\n }\r\n /** Returns whether a live entry exists. */\r\n public has(key: K): boolean {\r\n const entry = this.#entries.get(key);\r\n if (!entry) return false;\r\n if (entry.expiresAt > 0 && entry.expiresAt <= Date.now()) {\r\n this.#entries.delete(key);\r\n return false;\r\n }\r\n return true;\r\n }\r\n /** Stores an entry and evicts the oldest entries when the bound is exceeded. */\r\n public set(key: K, value: V): this {\r\n const expiresAt = this.#ttl > 0 ? Date.now() + this.#ttl : 0;\r\n this.#entries.delete(key);\r\n this.#entries.set(key, { value, expiresAt });\r\n // Skip eviction entirely for unbounded caches (maxSize === Infinity).\r\n if (this.#maxSize !== Infinity) {\r\n while (this.#entries.size > this.#maxSize) {\r\n const oldest = this.#entries.firstKey();\r\n if (oldest !== undefined) this.#entries.delete(oldest);\r\n else break;\r\n }\r\n }\r\n return this;\r\n }\r\n /** Invalidates one key. */\r\n public delete(key: K): boolean {\r\n return this.#entries.delete(key);\r\n }\r\n /** Invalidates every cached resource. */\r\n public clear(): void {\r\n this.#entries.clear();\r\n }\r\n /** Invalidates every entry matching a predicate. */\r\n public invalidate(predicate: (value: V, key: K) => boolean): number {\r\n return this.#entries.sweep((entry, key) => predicate(entry.value, key));\r\n }\r\n /** Removes expired entries and returns the number removed. */\r\n public sweep(): number {\r\n return this.#entries.sweep((entry) => this.#expired(entry));\r\n }\r\n /** Stops the background sweeper and releases its timer. */\r\n public dispose(): void {\r\n if (this.#timer) clearInterval(this.#timer);\r\n this.#timer = undefined;\r\n }\r\n /** Returns live cached values. */\r\n public values(): V[] {\r\n this.#sweepExpired();\r\n return this.#entries.map((entry) => entry.value);\r\n }\r\n /** Returns live cached entries. */\r\n public entries(): [K, V][] {\r\n this.#sweepExpired();\r\n return this.#entries.map((entry, key) => [key, entry.value]);\r\n }\r\n #expired(entry: Entry<V>): boolean {\r\n return entry.expiresAt > 0 && entry.expiresAt <= Date.now();\r\n }\r\n #sweepExpired(): void {\r\n if (this.#ttl > 0) this.sweep();\r\n }\r\n}\r\n",
6
- "/** A lightweight keyed collection for Lunibee resource and application state. */\r\nexport class Collection<K, V> extends Map<K, V> {\r\n /** Returns the first stored value. */\r\n public first(): V | undefined {\r\n for (const value of this.values()) return value;\r\n return undefined;\r\n }\r\n /** Returns the first stored key. */\r\n public firstKey(): K | undefined {\r\n for (const key of this.keys()) return key;\r\n return undefined;\r\n }\r\n /** Returns the last stored value. */\r\n public last(): V | undefined {\r\n let value: V | undefined;\r\n for (const item of this.values()) value = item;\r\n return value;\r\n }\r\n /** Returns the last stored key. */\r\n public lastKey(): K | undefined {\r\n let key: K | undefined;\r\n for (const item of this.keys()) key = item;\r\n return key;\r\n }\r\n /** Finds the first value matching a predicate. */\r\n public find(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): V | undefined {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) return value;\r\n }\r\n return undefined;\r\n }\r\n /** Returns all values matching a predicate. */\r\n public filter(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): Collection<K, V> {\r\n const result = new Collection<K, V>();\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) result.set(key, value);\r\n }\r\n return result;\r\n }\r\n /** Transforms every stored value into an array. */\r\n public map<T>(transform: (value: V, key: K, collection: this) => T): T[] {\r\n const result: T[] = [];\r\n for (const [key, value] of this) {\r\n result.push(transform(value, key, this));\r\n }\r\n return result;\r\n }\r\n /** Returns whether at least one stored value satisfies a predicate. */\r\n public some(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): boolean {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) return true;\r\n }\r\n return false;\r\n }\r\n /** Returns whether every stored value satisfies a predicate. */\r\n public every(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): boolean {\r\n for (const [key, value] of this) {\r\n if (!predicate(value, key, this)) return false;\r\n }\r\n return true;\r\n }\r\n /** Runs a callback for each stored value. */\r\n public each(\r\n callback: (value: V, key: K, collection: this) => unknown,\r\n ): this {\r\n for (const [key, value] of this) {\r\n callback(value, key, this);\r\n }\r\n return this;\r\n }\r\n /** Returns an array containing all stored values. */\r\n public array(): V[] {\r\n return [...this.values()];\r\n }\r\n /** Returns an array containing all stored keys. */\r\n public keyArray(): K[] {\r\n return [...this.keys()];\r\n }\r\n /** Returns a plain array of entries. */\r\n public entriesArray(): [K, V][] {\r\n return [...this.entries()];\r\n }\r\n /** Returns a new collection with the same entries. */\r\n public clone(): Collection<K, V> {\r\n const copy = new Collection<K, V>();\r\n for (const [key, value] of this) copy.set(key, value);\r\n return copy;\r\n }\r\n /** Returns whether all supplied keys are present. */\r\n public hasAll(...keys: K[]): boolean {\r\n for (let i = 0; i < keys.length; i++) {\r\n if (!this.has(keys[i]!)) return false;\r\n }\r\n return true;\r\n }\r\n /** Returns whether at least one supplied key is present. */\r\n public hasAny(...keys: K[]): boolean {\r\n for (let i = 0; i < keys.length; i++) {\r\n if (this.has(keys[i]!)) return true;\r\n }\r\n return false;\r\n }\r\n /** Returns the first key whose value matches a predicate. */\r\n public findKey(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): K | undefined {\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) return key;\r\n }\r\n return undefined;\r\n }\r\n /** Returns whether a predicate matches at least one entry. */\r\n public someEntry(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): boolean {\r\n return this.some(predicate);\r\n }\r\n /** Removes every entry matching a predicate and returns the number removed. */\r\n public sweep(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): number {\r\n let removed = 0;\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this) && this.delete(key)) removed++;\r\n }\r\n return removed;\r\n }\r\n /** Returns the collection's first matching entry as a tuple. */\r\n public firstEntry(): [K, V] | undefined {\r\n for (const [key, value] of this) return [key, value];\r\n return undefined;\r\n }\r\n /** Returns the collection's last matching entry as a tuple. */\r\n public lastEntry(): [K, V] | undefined {\r\n let entry: [K, V] | undefined;\r\n for (const item of this) entry = [item[0], item[1]];\r\n return entry;\r\n }\r\n /** Returns a new Collection containing elements from both collections. */\r\n public union(other: Collection<K, V>): Collection<K, V> {\r\n const result = this.clone();\r\n for (const [key, value] of other) result.set(key, value);\r\n return result;\r\n }\r\n /** Returns a new Collection containing only elements present in both collections. */\r\n public intersection(other: Collection<K, V>): Collection<K, V> {\r\n const result = new Collection<K, V>();\r\n for (const [key, value] of this) {\r\n if (other.has(key)) result.set(key, value);\r\n }\r\n return result;\r\n }\r\n /** Returns a new Collection containing elements present in this collection but not the other. */\r\n public difference(other: Collection<K, V>): Collection<K, V> {\r\n const result = new Collection<K, V>();\r\n for (const [key, value] of this) {\r\n if (!other.has(key)) result.set(key, value);\r\n }\r\n return result;\r\n }\r\n /** Splits the collection into two collections based on a predicate.\r\n * @returns `[passing, failing]` — entries satisfying the predicate, then those that don't.\r\n */\r\n public partition(\r\n predicate: (value: V, key: K, collection: this) => boolean,\r\n ): [Collection<K, V>, Collection<K, V>] {\r\n const pass = new Collection<K, V>();\r\n const fail = new Collection<K, V>();\r\n for (const [key, value] of this) {\r\n if (predicate(value, key, this)) pass.set(key, value);\r\n else fail.set(key, value);\r\n }\r\n return [pass, fail];\r\n }\r\n /** Calls `fn` with this collection and returns the collection unchanged.\r\n * Useful for inserting debug side-effects in a chain without breaking the flow.\r\n */\r\n public tap(fn: (collection: this) => unknown): this {\r\n fn(this);\r\n return this;\r\n }\r\n /** Maps every entry to an array of items and flattens the results. */\r\n public flatMap<T>(\r\n transform: (value: V, key: K, collection: this) => T[],\r\n ): T[] {\r\n const result: T[] = [];\r\n for (const [key, value] of this) {\r\n for (const item of transform(value, key, this)) result.push(item);\r\n }\r\n return result;\r\n }\r\n /** Reduces the collection to a single value. */\r\n public reduce<T>(\r\n fn: (accumulator: T, value: V, key: K, collection: this) => T,\r\n initialValue: T,\r\n ): T {\r\n let acc = initialValue;\r\n for (const [key, value] of this) acc = fn(acc, value, key, this);\r\n return acc;\r\n }\r\n /** Returns a new Collection with entries sorted by comparator (non-mutating).\r\n * Defaults to insertion order if no comparator is provided.\r\n */\r\n public sorted(\r\n comparator?: (a: V, b: V, aKey: K, bKey: K) => number,\r\n ): Collection<K, V> {\r\n // Decorate with the original insertion index and use it as a tiebreaker so\r\n // equal elements keep their insertion order (a stable sort independent of\r\n // the engine's Array.prototype.sort stability guarantees).\r\n const decorated = [...this.entries()].map((entry, index) => ({\r\n entry,\r\n index,\r\n }));\r\n if (comparator)\r\n decorated.sort((x, y) => {\r\n const comparison = comparator(\r\n x.entry[1],\r\n y.entry[1],\r\n x.entry[0],\r\n y.entry[0],\r\n );\r\n return comparison !== 0 ? comparison : x.index - y.index;\r\n });\r\n const result = new Collection<K, V>();\r\n for (const { entry } of decorated) result.set(entry[0], entry[1]);\r\n return result;\r\n }\r\n /** Returns a random value from the collection, or `undefined` if empty.\r\n * Uses `Math.random()` (fast, non-cryptographic) — do not use for security-sensitive\r\n * selection such as tokens or secrets. */\r\n public random(): V | undefined {\r\n const arr = [...this.values()];\r\n if (!arr.length) return undefined;\r\n return arr[Math.floor(Math.random() * arr.length)];\r\n }\r\n /** Returns a random key from the collection, or `undefined` if empty.\r\n * Uses `Math.random()` (fast, non-cryptographic) — do not use for security-sensitive\r\n * selection such as tokens or secrets. */\r\n public randomKey(): K | undefined {\r\n const arr = [...this.keys()];\r\n if (!arr.length) return undefined;\r\n return arr[Math.floor(Math.random() * arr.length)];\r\n }\r\n /** Returns the value at a given insertion-order index (supports negative indices). */\r\n public at(index: number): V | undefined {\r\n const arr = [...this.values()];\r\n const i = index < 0 ? arr.length + index : index;\r\n return arr[i];\r\n }\r\n /** Returns the key at a given insertion-order index (supports negative indices). */\r\n public keyAt(index: number): K | undefined {\r\n const arr = [...this.keys()];\r\n const i = index < 0 ? arr.length + index : index;\r\n return arr[i];\r\n }\r\n /** Serializes the collection to a plain `[key, value]` array. */\r\n public toJSON(): [K, V][] {\r\n return [...this.entries()];\r\n }\r\n}\r\n\r\nexport { Cache } from \"./cache.js\";\r\nexport type { CacheOptions } from \"./cache.js\";\r\n"
5
+ "import { Collection } from \"./index.js\";\n\n/** Cache policy for bounded resource storage. */\nexport interface CacheOptions {\n /** Maximum number of entries retained. */\n maxSize?: number;\n /** Time-to-live in milliseconds. Omit to disable expiration. */\n ttl?: number;\n /** Sweep interval in milliseconds. */\n sweepInterval?: number;\n}\n\ntype Entry<V> = { value: V; expiresAt: number };\n\n/** Bounded cache with TTL expiration and explicit invalidation support. */\nexport class Cache<K, V> {\n readonly #entries = new Collection<K, Entry<V>>();\n readonly #maxSize: number;\n readonly #ttl: number;\n #timer?: ReturnType<typeof setInterval>;\n\n /** Creates a cache using the supplied retention policy. */\n public constructor(options: CacheOptions = {}) {\n this.#maxSize = options.maxSize ?? Infinity;\n this.#ttl = options.ttl ?? 0;\n if (\n (!Number.isInteger(this.#maxSize) && this.#maxSize !== Infinity) ||\n this.#maxSize < 1\n )\n throw new RangeError(\"Cache maxSize must be a positive integer.\");\n if (!Number.isFinite(this.#ttl) || this.#ttl < 0)\n throw new RangeError(\n \"Cache ttl must be a non-negative finite number.\",\n );\n if (this.#ttl > 0) {\n const interval =\n options.sweepInterval ?? Math.min(this.#ttl, 60_000);\n if (!Number.isFinite(interval) || interval < 1)\n throw new RangeError(\"Cache sweepInterval must be positive.\");\n this.#timer = setInterval(() => this.sweep(), interval);\n // A sweeper is housekeeping, not work: keeping it referenced makes\n // a TTL cache hold the process open until dispose() is called.\n (this.#timer as { unref?: () => void }).unref?.();\n }\n }\n\n /** Number of currently live entries. */\n public get size(): number {\n this.#sweepExpired();\n return this.#entries.size;\n }\n /** Reads a live entry. */\n public get(key: K): V | undefined {\n const entry = this.#entries.get(key);\n if (!entry) return undefined;\n if (entry.expiresAt > 0 && entry.expiresAt <= Date.now()) {\n this.#entries.delete(key);\n return undefined;\n }\n // LRU Promotion: move to end of insertion order\n this.#entries.delete(key);\n this.#entries.set(key, entry);\n return entry.value;\n }\n /** Returns whether a live entry exists. */\n public has(key: K): boolean {\n const entry = this.#entries.get(key);\n if (!entry) return false;\n if (entry.expiresAt > 0 && entry.expiresAt <= Date.now()) {\n this.#entries.delete(key);\n return false;\n }\n return true;\n }\n /** Stores an entry and evicts the oldest entries when the bound is exceeded. */\n public set(key: K, value: V): this {\n const expiresAt = this.#ttl > 0 ? Date.now() + this.#ttl : 0;\n this.#entries.delete(key);\n this.#entries.set(key, { value, expiresAt });\n // Skip eviction entirely for unbounded caches (maxSize === Infinity).\n if (this.#maxSize !== Infinity) {\n while (this.#entries.size > this.#maxSize) {\n const oldest = this.#entries.firstKey();\n if (oldest !== undefined) this.#entries.delete(oldest);\n else break;\n }\n }\n return this;\n }\n /** Invalidates one key. */\n public delete(key: K): boolean {\n return this.#entries.delete(key);\n }\n /** Invalidates every cached resource. */\n public clear(): void {\n this.#entries.clear();\n }\n /** Invalidates every entry matching a predicate. */\n public invalidate(predicate: (value: V, key: K) => boolean): number {\n return this.#entries.sweep((entry, key) => predicate(entry.value, key));\n }\n /** Removes expired entries and returns the number removed. */\n public sweep(): number {\n return this.#entries.sweep((entry) => this.#expired(entry));\n }\n /** Stops the background sweeper and releases its timer. */\n public dispose(): void {\n if (this.#timer) clearInterval(this.#timer);\n this.#timer = undefined;\n }\n /** Returns live cached values. */\n public values(): V[] {\n this.#sweepExpired();\n return this.#entries.map((entry) => entry.value);\n }\n /** Returns live cached entries. */\n public entries(): [K, V][] {\n this.#sweepExpired();\n return this.#entries.map((entry, key) => [key, entry.value]);\n }\n #expired(entry: Entry<V>): boolean {\n return entry.expiresAt > 0 && entry.expiresAt <= Date.now();\n }\n #sweepExpired(): void {\n if (this.#ttl > 0) this.sweep();\n }\n}\n",
6
+ "type RecencyNode<K> = {\n key: K;\n older?: RecencyNode<K>;\n newer?: RecencyNode<K>;\n};\n\n/**\n * Keys in recency order with O(1) touch, promote, delete and oldest. A Set\n * cannot do this: repeatedly removing its first key leaves tombstones that\n * every new iterator scans past.\n */\nclass RecencyList<K> {\n readonly #nodes = new Map<K, RecencyNode<K>>();\n #oldest?: RecencyNode<K>;\n #newest?: RecencyNode<K>;\n\n public get size(): number {\n return this.#nodes.size;\n }\n\n public oldest(): K | undefined {\n return this.#oldest?.key;\n }\n\n /** Adds the key as newest, or moves it there. */\n public touch(key: K): void {\n const node = this.#nodes.get(key);\n if (node) return this.#moveNewest(node);\n const created: RecencyNode<K> = { key, older: this.#newest };\n if (this.#newest) this.#newest.newer = created;\n else this.#oldest = created;\n this.#newest = created;\n this.#nodes.set(key, created);\n }\n\n /** Moves an existing key to newest; ignores unknown keys. */\n public promote(key: K): void {\n const node = this.#nodes.get(key);\n if (node) this.#moveNewest(node);\n }\n\n public delete(key: K): boolean {\n const node = this.#nodes.get(key);\n if (!node) return false;\n this.#unlink(node);\n this.#nodes.delete(key);\n return true;\n }\n\n public clear(): void {\n this.#nodes.clear();\n this.#oldest = this.#newest = undefined;\n }\n\n #unlink(node: RecencyNode<K>): void {\n if (node.older) node.older.newer = node.newer;\n else this.#oldest = node.newer;\n if (node.newer) node.newer.older = node.older;\n else this.#newest = node.older;\n node.older = node.newer = undefined;\n }\n\n #moveNewest(node: RecencyNode<K>): void {\n if (node === this.#newest) return;\n this.#unlink(node);\n node.older = this.#newest;\n if (this.#newest) this.#newest.newer = node;\n else this.#oldest = node;\n this.#newest = node;\n }\n}\n\n/** Retention policy for a {@link Collection}. */\nexport interface CollectionOptions<K = unknown, V = unknown> {\n /** Default sliding TTL in ms for `set()`. Omit for no expiry. */\n ttl?: number;\n /** Maximum entries stored with `set()`; least-recently-used are evicted past it. `setWithoutTTL()` entries are never counted or evicted. */\n maxSize?: number;\n /** Called after an entry is removed automatically, with why. Exceptions are swallowed. */\n onEvict?: (key: K, value: V, reason: EvictionReason) => void;\n}\n\n/** Why an entry was removed automatically. */\nexport type EvictionReason = \"expired\" | \"evicted\";\n\n/** Cumulative counters from {@link Collection.stats}. */\nexport interface CollectionStats {\n /** `get`/`peek` calls that found a value. */ hits: number;\n /** `get`/`peek` calls that found nothing. */ misses: number;\n /** Entries removed because their TTL lapsed. */ expired: number;\n /** Entries removed to stay within `maxSize`. */ evicted: number;\n}\n\ntype Expiry = { deadline: number; window: number; filed: number };\n\nfunction assertTTL(ttl: number | undefined): void {\n if (ttl !== undefined && (!Number.isFinite(ttl) || ttl <= 0))\n throw new RangeError(\"TTL must be a positive number, or omitted.\");\n}\n\n/**\n * A keyed collection for Lunibee resource and application state.\n *\n * - `set(key, value, ttl?)` is TTL/LRU-aware: with a TTL (the default from\n * options, or per call) the entry expires after that window of inactivity,\n * and with `maxSize` it counts toward the cap.\n * - `setWithoutTTL(key, value)` never expires: no deadline, no heap record,\n * no timer, and exempt from `maxSize` eviction. Resource managers store\n * Discord state this way, so it leaves only through an explicit delete.\n *\n * Without options, a Collection behaves like a plain Map.\n */\nexport class Collection<K, V> extends Map<K, V> {\n readonly #ttl?: number;\n readonly #maxSize?: number;\n /** Stored loosely typed so the callback does not make Collection invariant in K and V. */\n readonly #onEvict?: (\n key: unknown,\n value: unknown,\n reason: EvictionReason,\n ) => void;\n /** Deadlines of TTL entries only. */\n readonly #expiry = new Map<K, Expiry>();\n /** `set()` keys in recency order (oldest first), tracked only when `maxSize` is set; `setWithoutTTL()` keys are never here. */\n readonly #lru = new RecencyList<K>();\n readonly #stats: CollectionStats = {\n hits: 0,\n misses: 0,\n expired: 0,\n evicted: 0,\n };\n /** Min-heap of filed deadlines; stale records are dropped lazily. */\n readonly #heap: { key: K; deadline: number }[] = [];\n #timer?: ReturnType<typeof setTimeout>;\n #armedFor = Infinity;\n\n /**\n * @param entries Initial entries, stored with `set()`.\n * @param options TTL and size policy.\n * @throws {RangeError} On a non-positive TTL or non-integer `maxSize`.\n */\n public constructor(\n entries?: Iterable<readonly [K, V]> | null,\n options: CollectionOptions<K, V> = {},\n ) {\n super();\n assertTTL(options.ttl);\n if (\n options.maxSize !== undefined &&\n (!Number.isInteger(options.maxSize) || options.maxSize <= 0)\n )\n throw new RangeError(\"maxSize must be a positive integer.\");\n this.#ttl = options.ttl;\n this.#maxSize = options.maxSize;\n this.#onEvict = options.onEvict as\n | ((key: unknown, value: unknown, reason: EvictionReason) => void)\n | undefined;\n if (entries) for (const [key, value] of entries) this.set(key, value);\n }\n\n /**\n * Stores an entry with the default TTL (or `ttl`), marks it most recently\n * used, and enforces `maxSize`. Turns a `setWithoutTTL()` entry back into\n * a TTL/LRU entry.\n */\n public override set(key: K, value: V, ttl?: number): this {\n assertTTL(ttl);\n const window = ttl ?? this.#ttl;\n if (this.#maxSize !== undefined) {\n this.#lru.touch(key);\n }\n super.set(key, value);\n if (window !== undefined) this.#schedule(key, window);\n else if (this.#expiry.size > 0) this.#expiry.delete(key);\n this.#enforceCap();\n return this;\n }\n\n /**\n * Stores an entry that never expires: no deadline, heap record, timer or\n * LRU eviction. It leaves only through `delete`, `sweep`, `clear`, or a\n * later `set()`.\n */\n public setWithoutTTL(key: K, value: V): this {\n if (this.#expiry.size > 0) this.#expiry.delete(key);\n if (this.#lru.size > 0) this.#lru.delete(key);\n super.set(key, value);\n return this;\n }\n\n /** Reads a value; restarts a TTL entry's window and promotes it. */\n public override get(key: K): V | undefined {\n if (this.#expireIfDue(key)) {\n this.#stats.misses++;\n return undefined;\n }\n const value = super.get(key);\n if (value === undefined && !super.has(key)) {\n this.#stats.misses++;\n return undefined;\n }\n this.#stats.hits++;\n const expiry = this.#expiry.get(key);\n if (expiry) expiry.deadline = Date.now() + expiry.window;\n this.#lru.promote(key);\n return value;\n }\n\n /** Reads a value without restarting its TTL or promoting it. */\n public peek(key: K): V | undefined {\n if (!this.#expireIfDue(key) && super.has(key)) {\n this.#stats.hits++;\n return super.get(key);\n }\n this.#stats.misses++;\n return undefined;\n }\n\n /** Cumulative hit, miss, expiry and eviction counters (a copy). */\n public get stats(): CollectionStats {\n return { ...this.#stats };\n }\n\n public override has(key: K): boolean {\n return !this.#expireIfDue(key) && super.has(key);\n }\n\n public override delete(key: K): boolean {\n if (this.#expireIfDue(key)) return false;\n this.#expiry.delete(key);\n this.#lru.delete(key);\n return super.delete(key);\n }\n\n public override clear(): void {\n super.clear();\n this.#expiry.clear();\n this.#lru.clear();\n this.#heap.length = 0;\n if (this.#timer) clearTimeout(this.#timer);\n this.#timer = undefined;\n this.#armedFor = Infinity;\n }\n\n public override get size(): number {\n this.purge();\n return super.size;\n }\n\n public override entries(): MapIterator<[K, V]> {\n this.purge();\n return super.entries();\n }\n\n public override keys(): MapIterator<K> {\n this.purge();\n return super.keys();\n }\n\n public override values(): MapIterator<V> {\n this.purge();\n return super.values();\n }\n\n public override [Symbol.iterator](): MapIterator<[K, V]> {\n return this.entries();\n }\n\n public override forEach(\n callback: (value: V, key: K, map: Map<K, V>) => void,\n thisArg?: unknown,\n ): void {\n this.purge();\n super.forEach(callback, thisArg);\n }\n\n /** Milliseconds until a key lapses, or undefined if absent or never expiring. */\n public ttlRemaining(key: K): number | undefined {\n if (this.#expireIfDue(key)) return undefined;\n const expiry = this.#expiry.get(key);\n return expiry && Math.max(0, expiry.deadline - Date.now());\n }\n\n /** Drops every lapsed TTL entry now. @returns How many were dropped. */\n public purge(): number {\n if (this.#expiry.size === 0) return 0;\n const now = Date.now();\n let removed = 0;\n const dropped: [K, V][] = [];\n while (this.#nextDeadline() <= now) {\n const due = this.#heapPop()!;\n dropped.push([due.key, super.get(due.key)!]);\n this.#remove(due.key);\n removed++;\n }\n this.#stats.expired += removed;\n this.#rearm();\n for (const [key, value] of dropped) this.#notify(key, value, \"expired\");\n return removed;\n }\n\n #expireIfDue(key: K): boolean {\n const expiry = this.#expiry.get(key);\n if (!expiry || expiry.deadline > Date.now()) return false;\n const value = super.get(key)!;\n this.#remove(key);\n this.#stats.expired++;\n this.#notify(key, value, \"expired\");\n return true;\n }\n\n #remove(key: K): void {\n this.#expiry.delete(key);\n this.#lru.delete(key);\n super.delete(key);\n }\n\n #notify(key: K, value: V, reason: EvictionReason): void {\n if (!this.#onEvict) return;\n try {\n this.#onEvict(key, value, reason);\n } catch {\n // A throwing callback must not leave the collection inconsistent.\n }\n }\n\n /** Evicts least-recently-used `set()` entries past `maxSize`; O(1) per eviction. */\n #enforceCap(): void {\n if (this.#maxSize === undefined) return;\n while (this.#lru.size > this.#maxSize) {\n const oldest = this.#lru.oldest()!;\n const value = super.get(oldest)!;\n this.#remove(oldest);\n this.#stats.evicted++;\n this.#notify(oldest, value, \"evicted\");\n }\n }\n\n /**\n * Gives an entry a deadline. Extending one writes a number; the stale\n * heap record re-files itself when it surfaces. Only a deadline that\n * moves earlier (or a new one) is pushed.\n */\n #schedule(key: K, window: number): void {\n const deadline = Date.now() + window;\n const expiry = this.#expiry.get(key);\n if (expiry) {\n expiry.deadline = deadline;\n expiry.window = window;\n if (deadline >= expiry.filed) return;\n expiry.filed = deadline;\n } else this.#expiry.set(key, { deadline, window, filed: deadline });\n this.#heapPush({ key, deadline });\n if (this.#heap.length > 2 * this.#expiry.size + 8) this.#compact();\n this.#rearm();\n }\n\n #nextDeadline(): number {\n for (;;) {\n const top = this.#heap[0];\n if (top === undefined) return Infinity;\n const expiry = this.#expiry.get(top.key);\n if (!expiry || expiry.filed !== top.deadline) {\n this.#heapPop();\n continue;\n }\n if (expiry.deadline === top.deadline) return top.deadline;\n // Extended since it was filed: re-file for its current deadline.\n this.#heapPop();\n expiry.filed = expiry.deadline;\n this.#heapPush({ key: top.key, deadline: expiry.deadline });\n }\n }\n\n #compact(): void {\n const live = this.#heap.filter(\n (record) => this.#expiry.get(record.key)?.filed === record.deadline,\n );\n this.#heap.length = 0;\n for (const record of live) this.#heapPush(record);\n }\n\n #rearm(): void {\n const deadline = this.#nextDeadline();\n if (this.#timer !== undefined && deadline >= this.#armedFor) return;\n if (this.#timer) clearTimeout(this.#timer);\n this.#timer = undefined;\n this.#armedFor = deadline;\n if (deadline === Infinity) return;\n this.#timer = setTimeout(\n () => {\n this.#timer = undefined;\n this.#armedFor = Infinity;\n this.purge();\n },\n Math.max(0, deadline - Date.now()),\n );\n // Pending expiry is housekeeping, not a reason to keep the process alive.\n (this.#timer as { unref?: () => void }).unref?.();\n }\n\n #heapPush(record: { key: K; deadline: number }): void {\n const heap = this.#heap;\n heap.push(record);\n let i = heap.length - 1;\n while (i > 0) {\n const parent = (i - 1) >> 1;\n if (heap[parent]!.deadline <= heap[i]!.deadline) break;\n [heap[parent], heap[i]] = [heap[i]!, heap[parent]!];\n i = parent;\n }\n }\n\n #heapPop(): { key: K; deadline: number } | undefined {\n const heap = this.#heap;\n const top = heap[0];\n const last = heap.pop();\n if (top === undefined || heap.length === 0) return top;\n heap[0] = last!;\n for (let i = 0; ;) {\n const left = 2 * i + 1;\n const right = left + 1;\n let smallest = i;\n if (\n left < heap.length &&\n heap[left]!.deadline < heap[smallest]!.deadline\n )\n smallest = left;\n if (\n right < heap.length &&\n heap[right]!.deadline < heap[smallest]!.deadline\n )\n smallest = right;\n if (smallest === i) break;\n [heap[smallest], heap[i]] = [heap[i]!, heap[smallest]!];\n i = smallest;\n }\n return top;\n }\n\n /** Returns the first stored value. */\n public first(): V | undefined {\n for (const value of this.values()) return value;\n return undefined;\n }\n /** Returns the first stored key. */\n public firstKey(): K | undefined {\n for (const key of this.keys()) return key;\n return undefined;\n }\n /** Returns the last stored value. */\n public last(): V | undefined {\n let value: V | undefined;\n for (const item of this.values()) value = item;\n return value;\n }\n /** Returns the last stored key. */\n public lastKey(): K | undefined {\n let key: K | undefined;\n for (const item of this.keys()) key = item;\n return key;\n }\n /** Finds the first value matching a predicate. */\n public find(\n predicate: (value: V, key: K, collection: this) => boolean,\n ): V | undefined {\n for (const [key, value] of this) {\n if (predicate(value, key, this)) return value;\n }\n return undefined;\n }\n /** Returns all values matching a predicate. */\n public filter(\n predicate: (value: V, key: K, collection: this) => boolean,\n ): Collection<K, V> {\n const result = new Collection<K, V>();\n for (const [key, value] of this) {\n if (predicate(value, key, this)) result.set(key, value);\n }\n return result;\n }\n /** Transforms every stored value into an array. */\n public map<T>(transform: (value: V, key: K, collection: this) => T): T[] {\n const result: T[] = [];\n for (const [key, value] of this) {\n result.push(transform(value, key, this));\n }\n return result;\n }\n /** Returns whether at least one stored value satisfies a predicate. */\n public some(\n predicate: (value: V, key: K, collection: this) => boolean,\n ): boolean {\n for (const [key, value] of this) {\n if (predicate(value, key, this)) return true;\n }\n return false;\n }\n /** Returns whether every stored value satisfies a predicate. */\n public every(\n predicate: (value: V, key: K, collection: this) => boolean,\n ): boolean {\n for (const [key, value] of this) {\n if (!predicate(value, key, this)) return false;\n }\n return true;\n }\n /** Runs a callback for each stored value. */\n public each(\n callback: (value: V, key: K, collection: this) => unknown,\n ): this {\n for (const [key, value] of this) {\n callback(value, key, this);\n }\n return this;\n }\n /** Returns an array containing all stored values. */\n public array(): V[] {\n return [...this.values()];\n }\n /** Returns an array containing all stored keys. */\n public keyArray(): K[] {\n return [...this.keys()];\n }\n /** Returns a plain array of entries. */\n public entriesArray(): [K, V][] {\n return [...this.entries()];\n }\n /** Returns a new collection with the same entries. */\n public clone(): Collection<K, V> {\n const copy = new Collection<K, V>();\n for (const [key, value] of this) copy.set(key, value);\n return copy;\n }\n /** Returns whether all supplied keys are present. */\n public hasAll(...keys: K[]): boolean {\n for (let i = 0; i < keys.length; i++) {\n if (!this.has(keys[i]!)) return false;\n }\n return true;\n }\n /** Returns whether at least one supplied key is present. */\n public hasAny(...keys: K[]): boolean {\n for (let i = 0; i < keys.length; i++) {\n if (this.has(keys[i]!)) return true;\n }\n return false;\n }\n /** Returns the first key whose value matches a predicate. */\n public findKey(\n predicate: (value: V, key: K, collection: this) => boolean,\n ): K | undefined {\n for (const [key, value] of this) {\n if (predicate(value, key, this)) return key;\n }\n return undefined;\n }\n /** Returns whether a predicate matches at least one entry. */\n public someEntry(\n predicate: (value: V, key: K, collection: this) => boolean,\n ): boolean {\n return this.some(predicate);\n }\n /** Removes every entry matching a predicate and returns the number removed. */\n public sweep(\n predicate: (value: V, key: K, collection: this) => boolean,\n ): number {\n let removed = 0;\n for (const [key, value] of this) {\n if (predicate(value, key, this) && this.delete(key)) removed++;\n }\n return removed;\n }\n /** Returns the collection's first matching entry as a tuple. */\n public firstEntry(): [K, V] | undefined {\n for (const [key, value] of this) return [key, value];\n return undefined;\n }\n /** Returns the collection's last matching entry as a tuple. */\n public lastEntry(): [K, V] | undefined {\n let entry: [K, V] | undefined;\n for (const item of this) entry = [item[0], item[1]];\n return entry;\n }\n /** Returns a new Collection containing elements from both collections. */\n public union(other: Collection<K, V>): Collection<K, V> {\n const result = this.clone();\n for (const [key, value] of other) result.set(key, value);\n return result;\n }\n /** Returns a new Collection containing only elements present in both collections. */\n public intersection(other: Collection<K, V>): Collection<K, V> {\n const result = new Collection<K, V>();\n for (const [key, value] of this) {\n if (other.has(key)) result.set(key, value);\n }\n return result;\n }\n /** Returns a new Collection containing elements present in this collection but not the other. */\n public difference(other: Collection<K, V>): Collection<K, V> {\n const result = new Collection<K, V>();\n for (const [key, value] of this) {\n if (!other.has(key)) result.set(key, value);\n }\n return result;\n }\n /** Splits the collection into two collections based on a predicate.\n * @returns `[passing, failing]` — entries satisfying the predicate, then those that don't.\n */\n public partition(\n predicate: (value: V, key: K, collection: this) => boolean,\n ): [Collection<K, V>, Collection<K, V>] {\n const pass = new Collection<K, V>();\n const fail = new Collection<K, V>();\n for (const [key, value] of this) {\n if (predicate(value, key, this)) pass.set(key, value);\n else fail.set(key, value);\n }\n return [pass, fail];\n }\n /** Calls `fn` with this collection and returns the collection unchanged.\n * Useful for inserting debug side-effects in a chain without breaking the flow.\n */\n public tap(fn: (collection: this) => unknown): this {\n fn(this);\n return this;\n }\n /** Maps every entry to an array of items and flattens the results. */\n public flatMap<T>(\n transform: (value: V, key: K, collection: this) => T[],\n ): T[] {\n const result: T[] = [];\n for (const [key, value] of this) {\n for (const item of transform(value, key, this)) result.push(item);\n }\n return result;\n }\n /** Reduces the collection to a single value. */\n public reduce<T>(\n fn: (accumulator: T, value: V, key: K, collection: this) => T,\n initialValue: T,\n ): T {\n let acc = initialValue;\n for (const [key, value] of this) acc = fn(acc, value, key, this);\n return acc;\n }\n /** Returns a new Collection with entries sorted by comparator (non-mutating).\n * Defaults to insertion order if no comparator is provided.\n */\n public sorted(\n comparator?: (a: V, b: V, aKey: K, bKey: K) => number,\n ): Collection<K, V> {\n // Decorate with the original insertion index and use it as a tiebreaker so\n // equal elements keep their insertion order (a stable sort independent of\n // the engine's Array.prototype.sort stability guarantees).\n const decorated = [...this.entries()].map((entry, index) => ({\n entry,\n index,\n }));\n if (comparator)\n decorated.sort((x, y) => {\n const comparison = comparator(\n x.entry[1],\n y.entry[1],\n x.entry[0],\n y.entry[0],\n );\n return comparison !== 0 ? comparison : x.index - y.index;\n });\n const result = new Collection<K, V>();\n for (const { entry } of decorated) result.set(entry[0], entry[1]);\n return result;\n }\n /** Returns a random value from the collection, or `undefined` if empty.\n * Uses `Math.random()` (fast, non-cryptographic) — do not use for security-sensitive\n * selection such as tokens or secrets. */\n public random(): V | undefined {\n const arr = [...this.values()];\n if (!arr.length) return undefined;\n return arr[Math.floor(Math.random() * arr.length)];\n }\n /** Returns a random key from the collection, or `undefined` if empty.\n * Uses `Math.random()` (fast, non-cryptographic) — do not use for security-sensitive\n * selection such as tokens or secrets. */\n public randomKey(): K | undefined {\n const arr = [...this.keys()];\n if (!arr.length) return undefined;\n return arr[Math.floor(Math.random() * arr.length)];\n }\n /** Returns the value at a given insertion-order index (supports negative indices). */\n public at(index: number): V | undefined {\n const arr = [...this.values()];\n const i = index < 0 ? arr.length + index : index;\n return arr[i];\n }\n /** Returns the key at a given insertion-order index (supports negative indices). */\n public keyAt(index: number): K | undefined {\n const arr = [...this.keys()];\n const i = index < 0 ? arr.length + index : index;\n return arr[i];\n }\n /** Serializes the collection to a plain `[key, value]` array. */\n public toJSON(): [K, V][] {\n return [...this.entries()];\n }\n}\n\nexport { Cache } from \"./cache.js\";\nexport type { CacheOptions } from \"./cache.js\";\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "F7AF9637261DF97664756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "4109A00736CB03B064756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -8,6 +8,10 @@ export interface CollectorOptions<T> {
8
8
  max?: number;
9
9
  /** Maximum number of processed elements. */
10
10
  maxProcessed?: number;
11
+ /** Stop after this many milliseconds without a collected item. */
12
+ idle?: number;
13
+ /** Stop (reason `"abort"`) when this signal aborts. */
14
+ signal?: AbortSignal;
11
15
  }
12
16
  /** General-purpose event collector for interactions and messages. */
13
17
  export declare class Collector<K, V> extends EventEmitter {
@@ -18,10 +22,19 @@ export declare class Collector<K, V> extends EventEmitter {
18
22
  endReason?: string;
19
23
  totalProcessed: number;
20
24
  constructor(options?: CollectorOptions<V>);
25
+ /** Registers a function to run once when the collector ends. Runs immediately if it already has. */
26
+ onDispose(cleanup: () => void): this;
21
27
  /** Handles a candidate item for collection. */
22
28
  handle(key: K, item: V): Promise<boolean>;
23
29
  /** Stops the collector and emits the "end" event. */
24
30
  stop(reason?: string): void;
31
+ /** Resolves with everything collected once the collector ends. */
32
+ wait(): Promise<Map<K, V>>;
33
+ /** Yields items as they are collected until the collector ends. Items
34
+ * collected between iterations are buffered, not dropped. */
35
+ [Symbol.asyncIterator](): AsyncGenerator<V, void, undefined>;
36
+ /** Stops the collector (reason `"disposed"`); enables `using collector = ...`. */
37
+ [Symbol.dispose](): void;
25
38
  /** Returns a Promise that resolves with the next collected item or rejects on end/timeout. */
26
39
  next(): Promise<V>;
27
40
  }