lunibee 0.3.3 → 0.4.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 (125) hide show
  1. package/README.md +1 -1
  2. package/dist/builders/commands.d.ts +1 -1
  3. package/dist/builders/components.d.ts +9 -11
  4. package/dist/builders/embed.d.ts +1 -1
  5. package/dist/builders/index.d.ts +1 -1
  6. package/dist/builders/index.js +87 -1298
  7. package/dist/builders/index.js.map +3 -11
  8. package/dist/chunks/index-0wn81eng.js +2492 -0
  9. package/dist/chunks/index-0wn81eng.js.map +17 -0
  10. package/dist/chunks/index-2en489j6.js +40 -0
  11. package/dist/chunks/index-2en489j6.js.map +10 -0
  12. package/dist/chunks/index-3hyps48a.js +203 -0
  13. package/dist/chunks/index-3hyps48a.js.map +11 -0
  14. package/dist/chunks/index-57c5n3ms.js +2274 -0
  15. package/dist/chunks/index-57c5n3ms.js.map +19 -0
  16. package/dist/chunks/index-5yx92e36.js +1170 -0
  17. package/dist/chunks/index-5yx92e36.js.map +14 -0
  18. package/dist/chunks/index-690bp093.js +95 -0
  19. package/dist/chunks/index-690bp093.js.map +10 -0
  20. package/dist/chunks/index-7fp2hvmg.js +2155 -0
  21. package/dist/chunks/index-7fp2hvmg.js.map +24 -0
  22. package/dist/chunks/index-cnmsajvk.js +1119 -0
  23. package/dist/chunks/index-cnmsajvk.js.map +12 -0
  24. package/dist/chunks/index-fdvgk2sw.js +1310 -0
  25. package/dist/chunks/index-fdvgk2sw.js.map +21 -0
  26. package/dist/chunks/index-gyvps8b9.js +214 -0
  27. package/dist/chunks/index-gyvps8b9.js.map +12 -0
  28. package/dist/chunks/index-jzg4bh99.js +1533 -0
  29. package/dist/chunks/index-jzg4bh99.js.map +21 -0
  30. package/dist/chunks/index-mgw2yvrm.js +3547 -0
  31. package/dist/chunks/index-mgw2yvrm.js.map +25 -0
  32. package/dist/chunks/index-yh76b55h.js +3449 -0
  33. package/dist/chunks/index-yh76b55h.js.map +29 -0
  34. package/dist/collection/index.js +9 -1118
  35. package/dist/collection/index.js.map +3 -6
  36. package/dist/core/api.d.ts +3 -3
  37. package/dist/core/channel-create.d.ts +2 -2
  38. package/dist/core/commands.d.ts +3 -3
  39. package/dist/core/events.d.ts +4 -4
  40. package/dist/core/handles.d.ts +4 -4
  41. package/dist/core/index.d.ts +25 -20
  42. package/dist/core/index.js +68 -10130
  43. package/dist/core/index.js.map +3 -65
  44. package/dist/core/permissions.d.ts +1 -1
  45. package/dist/core/redis-cache.d.ts +1 -1
  46. package/dist/formatters/index.js +41 -110
  47. package/dist/formatters/index.js.map +3 -4
  48. package/dist/handlers/index.js +5 -37
  49. package/dist/handlers/index.js.map +3 -4
  50. package/dist/index.d.ts +21 -21
  51. package/dist/index.js +641 -16325
  52. package/dist/index.js.map +3 -92
  53. package/dist/managers/advanced.d.ts +3 -3
  54. package/dist/managers/application.d.ts +2 -2
  55. package/dist/managers/base.d.ts +1 -1
  56. package/dist/managers/emoji.d.ts +2 -2
  57. package/dist/managers/guild-resources.d.ts +6 -6
  58. package/dist/managers/guild.d.ts +3 -3
  59. package/dist/managers/index.d.ts +4 -8
  60. package/dist/managers/index.js +51 -4060
  61. package/dist/managers/index.js.map +3 -29
  62. package/dist/managers/member.d.ts +2 -2
  63. package/dist/managers/message.d.ts +14 -6
  64. package/dist/managers/role.d.ts +2 -2
  65. package/dist/managers/thread.d.ts +3 -3
  66. package/dist/managers/user.d.ts +7 -4
  67. package/dist/rest/index.d.ts +10 -35
  68. package/dist/rest/index.js +57 -2184
  69. package/dist/rest/index.js.map +3 -18
  70. package/dist/rest/limiter.d.ts +9 -1
  71. package/dist/rest/webhook.d.ts +2 -8
  72. package/dist/sharding/bus.d.ts +2 -2
  73. package/dist/sharding/cluster.d.ts +45 -5
  74. package/dist/sharding/context.d.ts +45 -3
  75. package/dist/sharding/gateway-bot.d.ts +2 -1
  76. package/dist/sharding/health.d.ts +1 -1
  77. package/dist/sharding/identify.d.ts +12 -0
  78. package/dist/sharding/index.d.ts +44 -11
  79. package/dist/sharding/index.js +60 -4620
  80. package/dist/sharding/index.js.map +3 -33
  81. package/dist/sharding/supervisor.d.ts +4 -2
  82. package/dist/structures/audit-log.d.ts +1 -1
  83. package/dist/structures/base.d.ts +6 -6
  84. package/dist/structures/channels.d.ts +1 -1
  85. package/dist/structures/embed.d.ts +1 -1
  86. package/dist/structures/index.d.ts +14 -14
  87. package/dist/structures/index.js +109 -2382
  88. package/dist/structures/index.js.map +3 -16
  89. package/dist/structures/interactions.d.ts +13 -9
  90. package/dist/structures/options.d.ts +1 -1
  91. package/dist/structures/permissions.d.ts +2 -2
  92. package/dist/structures/resources.d.ts +10 -10
  93. package/dist/structures/sticker.d.ts +1 -1
  94. package/dist/types/gateway.d.ts +2 -79
  95. package/dist/types/index.d.ts +0 -6
  96. package/dist/types/index.js +41 -272
  97. package/dist/types/index.js.map +3 -6
  98. package/dist/utils/index.js +23 -209
  99. package/dist/utils/index.js.map +3 -5
  100. package/dist/voice/connection.d.ts +200 -0
  101. package/dist/voice/crypto.d.ts +50 -0
  102. package/dist/voice/dave.d.ts +85 -0
  103. package/dist/voice/effects.d.ts +31 -0
  104. package/dist/voice/emitter.d.ts +14 -0
  105. package/dist/voice/gateway.d.ts +59 -0
  106. package/dist/voice/index.d.ts +25 -228
  107. package/dist/voice/index.js +111 -442
  108. package/dist/voice/index.js.map +3 -4
  109. package/dist/voice/libopus.d.ts +88 -0
  110. package/dist/voice/networking.d.ts +80 -0
  111. package/dist/voice/ogg.d.ts +24 -0
  112. package/dist/voice/opus.d.ts +18 -0
  113. package/dist/voice/player.d.ts +79 -0
  114. package/dist/voice/protocol.d.ts +76 -0
  115. package/dist/voice/receiver.d.ts +59 -0
  116. package/dist/voice/resource.d.ts +102 -0
  117. package/dist/voice/udp.d.ts +40 -0
  118. package/dist/ws/close-codes.d.ts +1 -1
  119. package/dist/ws/index.d.ts +25 -4
  120. package/dist/ws/index.js +47 -1336
  121. package/dist/ws/index.js.map +3 -17
  122. package/dist/ws/protocol.d.ts +1 -1
  123. package/dist/ws/send-budget.d.ts +0 -2
  124. package/dist/ws/state.d.ts +0 -10
  125. package/package.json +19 -16
@@ -0,0 +1,1119 @@
1
+ // @bun
2
+ // packages/collection/src/cache.ts
3
+ class Cache2 {
4
+ #entries;
5
+ constructor(options = {}) {
6
+ const maxSize = options.maxSize ?? Infinity;
7
+ const ttl = options.ttl ?? 0;
8
+ if (!Number.isInteger(maxSize) && maxSize !== Infinity || maxSize < 1)
9
+ throw new RangeError("Cache maxSize must be a positive integer.");
10
+ if (!Number.isFinite(ttl) || ttl < 0)
11
+ throw new RangeError("Cache ttl must be a non-negative finite number.");
12
+ if (!((options.jitter ?? 0) >= 0 && (options.jitter ?? 0) <= 1))
13
+ throw new RangeError("Cache jitter must be between 0 and 1.");
14
+ if (ttl > 0) {
15
+ const interval = options.sweepInterval ?? Math.min(ttl, 60000);
16
+ if (!Number.isFinite(interval) || interval < 1)
17
+ throw new RangeError("Cache sweepInterval must be positive.");
18
+ }
19
+ this.#entries = new Collection2(null, {
20
+ ttl: ttl > 0 ? ttl : undefined,
21
+ jitter: options.jitter,
22
+ maxSize: maxSize === Infinity ? undefined : maxSize,
23
+ slide: false
24
+ });
25
+ }
26
+ get size() {
27
+ return this.#entries.size;
28
+ }
29
+ get(key) {
30
+ return this.#entries.get(key);
31
+ }
32
+ has(key) {
33
+ return this.#entries.has(key);
34
+ }
35
+ set(key, value) {
36
+ this.#entries.set(key, value);
37
+ return this;
38
+ }
39
+ delete(key) {
40
+ return this.#entries.delete(key);
41
+ }
42
+ clear() {
43
+ this.#entries.clear();
44
+ }
45
+ invalidate(predicate) {
46
+ return this.#entries.sweep(predicate);
47
+ }
48
+ sweep() {
49
+ return this.#entries.purge();
50
+ }
51
+ dispose() {}
52
+ values() {
53
+ return [...this.#entries.values()];
54
+ }
55
+ entries() {
56
+ return [...this.#entries.entries()];
57
+ }
58
+ }
59
+ // packages/collection/src/redis.ts
60
+ var PRELUDE = `
61
+ local exp, lru, clock, ep = KEYS[1], KEYS[2], KEYS[3], ARGV[1]
62
+ local t = redis.call('TIME')
63
+ local now = tonumber(t[1]) * 1000 + math.floor(tonumber(t[2]) / 1000)
64
+ local out = {}
65
+ local function drop(m, reason)
66
+ local v = redis.call('GET', ep .. m)
67
+ redis.call('DEL', ep .. m)
68
+ redis.call('ZREM', exp, m)
69
+ redis.call('ZREM', lru, m)
70
+ if reason then
71
+ table.insert(out, m)
72
+ table.insert(out, v or false)
73
+ table.insert(out, reason)
74
+ end
75
+ end
76
+ local gone = redis.call('ZRANGEBYSCORE', exp, '-inf', now, 'LIMIT', 0, 1000)
77
+ for _, m in ipairs(gone) do drop(m, 'expired') end
78
+ local function touch(m) redis.call('ZADD', lru, redis.call('INCR', clock), m) end
79
+ `;
80
+ var SET_SCRIPT = `${PRELUDE}
81
+ local m, payload, ttl, max, mode = ARGV[2], ARGV[3], tonumber(ARGV[4]), tonumber(ARGV[5]), ARGV[6]
82
+ if mode == 'nx' then
83
+ local cur = redis.call('GET', ep .. m)
84
+ if cur then
85
+ touch(m)
86
+ table.insert(out, 1, cur)
87
+ return out
88
+ end
89
+ end
90
+ local env = ttl .. ':' .. payload
91
+ if ttl > 0 then
92
+ -- The key outlives its logical expiry by a grace second, so the prune
93
+ -- that reports the expiry can still hand the value to onEvict.
94
+ redis.call('SET', ep .. m, env, 'PX', ttl + 1000)
95
+ redis.call('ZADD', exp, now + ttl, m)
96
+ else
97
+ redis.call('SET', ep .. m, env)
98
+ redis.call('ZREM', exp, m)
99
+ end
100
+ touch(m)
101
+ if max > 0 then
102
+ local n = redis.call('ZCARD', lru)
103
+ while n > max do
104
+ local popped = redis.call('ZPOPMIN', lru)
105
+ local victim = popped[1]
106
+ if victim == nil then break end
107
+ if victim ~= m then drop(victim, 'evicted') end
108
+ n = n - 1
109
+ end
110
+ end
111
+ table.insert(out, 1, false)
112
+ return out
113
+ `;
114
+ var GET_SCRIPT = `${PRELUDE}
115
+ local m, slide, mark = ARGV[2], ARGV[3], ARGV[4]
116
+ local env = redis.call('GET', ep .. m)
117
+ if not env then
118
+ redis.call('ZREM', exp, m)
119
+ redis.call('ZREM', lru, m)
120
+ table.insert(out, 1, false)
121
+ return out
122
+ end
123
+ if mark == '1' then touch(m) end
124
+ if slide == '1' then
125
+ local ttl = tonumber(string.match(env, '^(%d+):'))
126
+ if ttl and ttl > 0 then
127
+ redis.call('PEXPIRE', ep .. m, ttl + 1000)
128
+ redis.call('ZADD', exp, now + ttl, m)
129
+ end
130
+ end
131
+ table.insert(out, 1, env)
132
+ return out
133
+ `;
134
+ var DELETE_SCRIPT = `${PRELUDE}
135
+ local m = ARGV[2]
136
+ local existed = redis.call('EXISTS', ep .. m)
137
+ drop(m, nil)
138
+ table.insert(out, 1, existed)
139
+ return out
140
+ `;
141
+ var LIST_SCRIPT = `${PRELUDE}
142
+ local what = ARGV[2]
143
+ if what == 'clear' then
144
+ local n = 0
145
+ repeat
146
+ local batch = redis.call('ZRANGE', lru, 0, 999)
147
+ for _, m in ipairs(batch) do drop(m, nil) end
148
+ n = n + #batch
149
+ until #batch == 0
150
+ redis.call('DEL', exp, lru, clock)
151
+ return {n}
152
+ end
153
+ local result = what == 'size' and redis.call('ZCARD', lru) or redis.call('ZRANGE', lru, 0, -1)
154
+ return {result, unpack(out)}
155
+ `;
156
+ var EXPIRY_GRACE_MS = 1000;
157
+ var JSON_SERIALIZER = {
158
+ serialize: (value) => JSON.stringify(value),
159
+ deserialize: (raw) => JSON.parse(raw)
160
+ };
161
+
162
+ class RedisCollection2 {
163
+ #redis;
164
+ #keys;
165
+ #ep;
166
+ #ttl;
167
+ #slide;
168
+ #maxSize;
169
+ #serializer;
170
+ #onEvict;
171
+ #stats = {
172
+ hits: 0,
173
+ misses: 0,
174
+ expired: 0,
175
+ evicted: 0
176
+ };
177
+ name;
178
+ constructor(options) {
179
+ if (typeof options.name !== "string" || !/^[\w.:-]{1,100}$/.test(options.name))
180
+ throw new TypeError("name must be 1-100 letters, digits, '_', '.', ':' or '-'.");
181
+ checkTTL(options.ttl);
182
+ if (options.maxSize !== undefined && !(Number.isInteger(options.maxSize) && options.maxSize > 0))
183
+ throw new RangeError("maxSize must be a positive integer.");
184
+ this.#redis = options.client;
185
+ this.name = options.name;
186
+ const base = `${options.prefix ?? "lunibee:collection:"}v1:{${options.name}}:`;
187
+ this.#keys = [`${base}exp`, `${base}lru`, `${base}clock`];
188
+ this.#ep = `${base}e:`;
189
+ this.#ttl = options.ttl ?? 0;
190
+ this.#slide = options.slide ?? true;
191
+ this.#maxSize = options.maxSize ?? 0;
192
+ this.#serializer = options.serializer ?? JSON_SERIALIZER;
193
+ this.#onEvict = options.onEvict;
194
+ }
195
+ get stats() {
196
+ return { ...this.#stats };
197
+ }
198
+ async#run(script, ...argv) {
199
+ const reply = await this.#redis.send("EVAL", [
200
+ script,
201
+ "3",
202
+ ...this.#keys,
203
+ this.#ep,
204
+ ...argv
205
+ ]);
206
+ if (!Array.isArray(reply))
207
+ throw new Error("Unexpected reply from a RedisCollection script.");
208
+ return reply;
209
+ }
210
+ #settle(reply, skip) {
211
+ for (let i = skip;i + 2 < reply.length + 0; i += 3) {
212
+ const key = String(reply[i]);
213
+ const raw = reply[i + 1];
214
+ const reason = reply[i + 2];
215
+ if (reason === "expired")
216
+ this.#stats.expired++;
217
+ else
218
+ this.#stats.evicted++;
219
+ if (!this.#onEvict)
220
+ continue;
221
+ let value;
222
+ try {
223
+ value = typeof raw === "string" ? this.#decode(raw) : undefined;
224
+ } catch {
225
+ value = undefined;
226
+ }
227
+ try {
228
+ this.#onEvict(key, value, reason);
229
+ } catch {}
230
+ }
231
+ return reply[0];
232
+ }
233
+ #decode(envelope) {
234
+ const colon = envelope.indexOf(":");
235
+ return this.#serializer.deserialize(envelope.slice(colon + 1));
236
+ }
237
+ async get(key) {
238
+ const raw = this.#settle(await this.#run(GET_SCRIPT, String(key), this.#slide ? "1" : "0", "1"), 1);
239
+ if (typeof raw !== "string") {
240
+ this.#stats.misses++;
241
+ return;
242
+ }
243
+ this.#stats.hits++;
244
+ return this.#decode(raw);
245
+ }
246
+ async peek(key) {
247
+ const raw = this.#settle(await this.#run(GET_SCRIPT, String(key), "0", "0"), 1);
248
+ return typeof raw === "string" ? this.#decode(raw) : undefined;
249
+ }
250
+ async has(key) {
251
+ return await this.peek(key) !== undefined;
252
+ }
253
+ async set(key, value, ttl) {
254
+ checkTTL(ttl, true);
255
+ this.#settle(await this.#run(SET_SCRIPT, String(key), this.#serializer.serialize(value), String(Math.ceil(ttl ?? this.#ttl)), String(this.#maxSize), "set"), 1);
256
+ return this;
257
+ }
258
+ setWithoutTTL(key, value) {
259
+ return this.set(key, value, 0);
260
+ }
261
+ async ensure(key, factory, ttl) {
262
+ const existing = await this.get(key);
263
+ if (existing !== undefined)
264
+ return existing;
265
+ checkTTL(ttl, true);
266
+ const value = await factory(String(key));
267
+ const raw = this.#settle(await this.#run(SET_SCRIPT, String(key), this.#serializer.serialize(value), String(Math.ceil(ttl ?? this.#ttl)), String(this.#maxSize), "nx"), 1);
268
+ return typeof raw === "string" ? this.#decode(raw) : value;
269
+ }
270
+ async delete(key) {
271
+ const reply = await this.#run(DELETE_SCRIPT, String(key));
272
+ return Number(this.#settle(reply, 1)) === 1;
273
+ }
274
+ async clear() {
275
+ const reply = await this.#run(LIST_SCRIPT, "clear");
276
+ return Number(reply[0]);
277
+ }
278
+ async size() {
279
+ return Number(this.#settle(await this.#run(LIST_SCRIPT, "size"), 1));
280
+ }
281
+ async keys() {
282
+ return this.#settle(await this.#run(LIST_SCRIPT, "keys"), 1).map(String);
283
+ }
284
+ async entries() {
285
+ const keys = await this.keys();
286
+ if (keys.length === 0)
287
+ return [];
288
+ const out = [];
289
+ for (let i = 0;i < keys.length; i += 1000) {
290
+ const batch = keys.slice(i, i + 1000);
291
+ const raws = await this.#redis.send("MGET", batch.map((k) => this.#ep + k));
292
+ raws.forEach((raw, j) => {
293
+ if (typeof raw === "string")
294
+ out.push([batch[j], this.#decode(raw)]);
295
+ });
296
+ }
297
+ return out;
298
+ }
299
+ async values() {
300
+ return (await this.entries()).map(([, value]) => value);
301
+ }
302
+ async ttlRemaining(key) {
303
+ const ms = Number(await this.#redis.send("PTTL", [this.#ep + String(key)]));
304
+ return ms >= 0 ? Math.max(0, ms - EXPIRY_GRACE_MS) : undefined;
305
+ }
306
+ }
307
+ function checkTTL(ttl, allowZero = false) {
308
+ if (ttl === undefined)
309
+ return;
310
+ if (!Number.isFinite(ttl) || ttl < 0 || !allowZero && ttl === 0)
311
+ throw new RangeError(allowZero ? "ttl must be 0 or a positive number." : "ttl must be a positive number.");
312
+ }
313
+
314
+ // packages/collection/src/index.ts
315
+ function newPolicy(options = {}) {
316
+ return {
317
+ ttl: options.ttl,
318
+ jitter: options.jitter ?? 0,
319
+ maxSize: options.maxSize,
320
+ slide: options.slide ?? true,
321
+ onEvict: options.onEvict,
322
+ expired: 0,
323
+ evicted: 0,
324
+ entries: new Map,
325
+ oldest: undefined,
326
+ newest: undefined,
327
+ lruSize: 0,
328
+ heap: [],
329
+ armedFor: Infinity
330
+ };
331
+ }
332
+ function peekOf(collection, key) {
333
+ return collection instanceof Map ? Map.prototype.get.call(collection, key) : collection.get(key);
334
+ }
335
+ var mapGet = Map.prototype.get;
336
+ var mapHas = Map.prototype.has;
337
+ function sample(items, amount) {
338
+ if (!Number.isInteger(amount) || amount < 0)
339
+ throw new RangeError("amount must be a non-negative integer.");
340
+ const count = Math.min(amount, items.length);
341
+ for (let i = 0;i < count; i++) {
342
+ const j = i + Math.floor(Math.random() * (items.length - i));
343
+ [items[i], items[j]] = [items[j], items[i]];
344
+ }
345
+ items.length = count;
346
+ return items;
347
+ }
348
+ function assertTTL(ttl) {
349
+ if (ttl !== undefined && (!Number.isFinite(ttl) || ttl <= 0))
350
+ throw new RangeError("TTL must be a positive number, or omitted.");
351
+ }
352
+
353
+ class Collection2 extends Map {
354
+ #policy;
355
+ #hits = 0;
356
+ #misses = 0;
357
+ constructor(entries, options = {}) {
358
+ super();
359
+ assertTTL(options.ttl);
360
+ if (options.jitter !== undefined && !(options.jitter >= 0 && options.jitter <= 1))
361
+ throw new RangeError("jitter must be between 0 and 1.");
362
+ if (options.maxSize !== undefined && (!Number.isInteger(options.maxSize) || options.maxSize <= 0))
363
+ throw new RangeError("maxSize must be a positive integer.");
364
+ if (options.ttl !== undefined || options.jitter !== undefined || options.maxSize !== undefined || options.slide !== undefined || options.onEvict !== undefined)
365
+ this.#policy = newPolicy(options);
366
+ if (entries)
367
+ for (const [key, value] of entries)
368
+ this.set(key, value);
369
+ }
370
+ set(key, value, ttl) {
371
+ let policy = this.#policy;
372
+ if (ttl === undefined && policy === undefined)
373
+ return super.set(key, value);
374
+ if (ttl !== undefined)
375
+ assertTTL(ttl);
376
+ let window = ttl ?? policy?.ttl;
377
+ if (window !== undefined && policy !== undefined && policy.jitter > 0)
378
+ window = Math.max(1, window * (1 - policy.jitter * Math.random()));
379
+ if (policy === undefined) {
380
+ if (window === undefined)
381
+ return super.set(key, value);
382
+ policy = this.#policy = newPolicy();
383
+ }
384
+ const entry = policy.entries.get(key);
385
+ super.set(key, value);
386
+ if (entry !== undefined && window !== undefined && entry.window !== 0) {
387
+ const deadline = Date.now() + window;
388
+ if (deadline >= entry.filed) {
389
+ entry.value = value;
390
+ entry.deadline = deadline;
391
+ entry.window = window;
392
+ if (entry.inLru)
393
+ this.#promote(policy, entry);
394
+ return this;
395
+ }
396
+ }
397
+ this.#track(key, value, window, entry);
398
+ if (policy.maxSize !== undefined && policy.lruSize > policy.maxSize)
399
+ this.#enforceCap();
400
+ return this;
401
+ }
402
+ setWithoutTTL(key, value) {
403
+ if (this.#policy)
404
+ this.#forget(key);
405
+ super.set(key, value);
406
+ return this;
407
+ }
408
+ get(key) {
409
+ const policy = this.#policy;
410
+ const entry = policy?.entries.get(key);
411
+ if (entry === undefined) {
412
+ const value = mapGet.call(this, key);
413
+ if (value !== undefined || mapHas.call(this, key)) {
414
+ this.#hits++;
415
+ return value;
416
+ }
417
+ this.#misses++;
418
+ return;
419
+ }
420
+ const timed = entry.window !== 0;
421
+ const now = timed ? Date.now() : 0;
422
+ if (timed && entry.deadline <= now) {
423
+ this.#expire(entry);
424
+ this.#misses++;
425
+ return;
426
+ }
427
+ this.#hits++;
428
+ if (timed && policy.slide)
429
+ entry.deadline = now + entry.window;
430
+ if (entry.inLru)
431
+ this.#promote(policy, entry);
432
+ return entry.value;
433
+ }
434
+ ensure(key, factory, ttl) {
435
+ const existing = this.get(key);
436
+ if (existing !== undefined || super.has(key))
437
+ return existing;
438
+ const created = factory(key, this);
439
+ this.set(key, created, ttl);
440
+ return created;
441
+ }
442
+ peek(key) {
443
+ if (!this.#expireIfDue(key) && super.has(key)) {
444
+ this.#hits++;
445
+ return super.get(key);
446
+ }
447
+ this.#misses++;
448
+ return;
449
+ }
450
+ get stats() {
451
+ return {
452
+ hits: this.#hits,
453
+ misses: this.#misses,
454
+ expired: this.#policy?.expired ?? 0,
455
+ evicted: this.#policy?.evicted ?? 0
456
+ };
457
+ }
458
+ has(key) {
459
+ return !this.#expireIfDue(key) && super.has(key);
460
+ }
461
+ delete(key) {
462
+ if (this.#expireIfDue(key))
463
+ return false;
464
+ if (this.#policy)
465
+ this.#forget(key);
466
+ return super.delete(key);
467
+ }
468
+ clear() {
469
+ super.clear();
470
+ const policy = this.#policy;
471
+ if (!policy)
472
+ return;
473
+ policy.entries.clear();
474
+ policy.oldest = policy.newest = undefined;
475
+ policy.lruSize = 0;
476
+ policy.heap.length = 0;
477
+ if (policy.timer)
478
+ clearTimeout(policy.timer);
479
+ policy.timer = undefined;
480
+ policy.armedFor = Infinity;
481
+ }
482
+ get size() {
483
+ this.purge();
484
+ return super.size;
485
+ }
486
+ entries() {
487
+ this.purge();
488
+ return super.entries();
489
+ }
490
+ keys() {
491
+ this.purge();
492
+ return super.keys();
493
+ }
494
+ values() {
495
+ this.purge();
496
+ return super.values();
497
+ }
498
+ [Symbol.iterator]() {
499
+ return this.entries();
500
+ }
501
+ forEach(callback, thisArg) {
502
+ this.purge();
503
+ super.forEach(callback, thisArg);
504
+ }
505
+ ttlRemaining(key) {
506
+ if (this.#expireIfDue(key))
507
+ return;
508
+ const entry = this.#policy?.entries.get(key);
509
+ return entry && entry.window !== 0 ? Math.max(0, entry.deadline - Date.now()) : undefined;
510
+ }
511
+ purge() {
512
+ if (!this.#policy || this.#policy.heap.length === 0)
513
+ return 0;
514
+ const now = Date.now();
515
+ let removed = 0;
516
+ const dropped = [];
517
+ while (this.#nextDeadline() <= now) {
518
+ const due = this.#heapPop();
519
+ dropped.push([due.key, super.get(due.key)]);
520
+ this.#remove(due.key);
521
+ removed++;
522
+ }
523
+ this.#policy.expired += removed;
524
+ this.#rearm();
525
+ for (const [key, value] of dropped)
526
+ this.#notify(key, value, "expired");
527
+ return removed;
528
+ }
529
+ #expireIfDue(key) {
530
+ const entry = this.#policy?.entries.get(key);
531
+ if (!entry || entry.window === 0 || entry.deadline > Date.now())
532
+ return false;
533
+ this.#expire(entry);
534
+ return true;
535
+ }
536
+ #expire(entry) {
537
+ const value = super.get(entry.key);
538
+ this.#remove(entry.key);
539
+ this.#policy.expired++;
540
+ this.#notify(entry.key, value, "expired");
541
+ }
542
+ #remove(key) {
543
+ this.#forget(key);
544
+ super.delete(key);
545
+ }
546
+ #forget(key) {
547
+ const policy = this.#policy;
548
+ const entry = policy.entries.get(key);
549
+ if (!entry)
550
+ return;
551
+ if (entry.inLru)
552
+ this.#unlink(policy, entry);
553
+ policy.entries.delete(key);
554
+ }
555
+ #track(key, value, window, existing) {
556
+ const policy = this.#policy;
557
+ const lru = policy.maxSize !== undefined;
558
+ let entry = existing;
559
+ if (entry)
560
+ entry.value = value;
561
+ if (window === undefined) {
562
+ if (entry && entry.window !== 0) {
563
+ if (lru)
564
+ entry = this.#replace(policy, entry, 0, 0);
565
+ else {
566
+ this.#forget(key);
567
+ return;
568
+ }
569
+ }
570
+ if (!entry && lru) {
571
+ entry = this.#create(key, value, 0, 0);
572
+ policy.entries.set(key, entry);
573
+ }
574
+ if (entry)
575
+ this.#promote(policy, entry);
576
+ return;
577
+ }
578
+ const deadline = Date.now() + window;
579
+ if (entry && entry.window !== 0) {
580
+ entry.deadline = deadline;
581
+ entry.window = window;
582
+ if (deadline < entry.filed)
583
+ entry = this.#replace(policy, entry, window, deadline);
584
+ else {
585
+ if (entry.inLru)
586
+ this.#promote(policy, entry);
587
+ return;
588
+ }
589
+ } else if (entry) {
590
+ entry.window = window;
591
+ entry.deadline = entry.filed = deadline;
592
+ } else {
593
+ entry = this.#create(key, value, window, deadline);
594
+ policy.entries.set(key, entry);
595
+ }
596
+ if (lru)
597
+ this.#promote(policy, entry);
598
+ this.#heapPush(entry);
599
+ if (policy.heap.length > 2 * policy.entries.size + 8)
600
+ this.#compact();
601
+ if (policy.timer === undefined || deadline < policy.armedFor)
602
+ this.#rearm();
603
+ }
604
+ #create(key, value, window, deadline) {
605
+ return {
606
+ key,
607
+ value,
608
+ older: undefined,
609
+ newer: undefined,
610
+ inLru: false,
611
+ window,
612
+ deadline,
613
+ filed: deadline
614
+ };
615
+ }
616
+ #replace(policy, old, window, deadline) {
617
+ const entry = {
618
+ ...old,
619
+ window,
620
+ deadline,
621
+ filed: deadline
622
+ };
623
+ if (old.inLru) {
624
+ if (old.older)
625
+ old.older.newer = entry;
626
+ else
627
+ policy.oldest = entry;
628
+ if (old.newer)
629
+ old.newer.older = entry;
630
+ else
631
+ policy.newest = entry;
632
+ }
633
+ policy.entries.set(old.key, entry);
634
+ return entry;
635
+ }
636
+ #promote(policy, entry) {
637
+ if (entry === policy.newest)
638
+ return;
639
+ if (entry.inLru)
640
+ this.#unlink(policy, entry, true);
641
+ else {
642
+ entry.inLru = true;
643
+ policy.lruSize++;
644
+ }
645
+ entry.older = policy.newest;
646
+ entry.newer = undefined;
647
+ if (policy.newest)
648
+ policy.newest.newer = entry;
649
+ else
650
+ policy.oldest = entry;
651
+ policy.newest = entry;
652
+ }
653
+ #unlink(policy, entry, keepCount = false) {
654
+ if (entry.older)
655
+ entry.older.newer = entry.newer;
656
+ else
657
+ policy.oldest = entry.newer;
658
+ if (entry.newer)
659
+ entry.newer.older = entry.older;
660
+ else
661
+ policy.newest = entry.older;
662
+ entry.older = entry.newer = undefined;
663
+ if (!keepCount) {
664
+ entry.inLru = false;
665
+ policy.lruSize--;
666
+ }
667
+ }
668
+ #derived() {
669
+ const Species = this.constructor[Symbol.species] ?? Collection2;
670
+ return new Species;
671
+ }
672
+ #notify(key, value, reason) {
673
+ const onEvict = this.#policy?.onEvict;
674
+ if (!onEvict)
675
+ return;
676
+ try {
677
+ onEvict(key, value, reason);
678
+ } catch {}
679
+ }
680
+ #enforceCap() {
681
+ const policy = this.#policy;
682
+ const max = policy.maxSize;
683
+ if (max === undefined)
684
+ return;
685
+ if (policy.lruSize > max && policy.heap.length > 0 && policy.heap[0].filed <= Date.now())
686
+ this.purge();
687
+ while (policy.lruSize > max) {
688
+ const oldest = policy.oldest;
689
+ const value = policy.onEvict ? super.get(oldest.key) : undefined;
690
+ const next = oldest.newer;
691
+ policy.oldest = next;
692
+ if (next)
693
+ next.older = undefined;
694
+ else
695
+ policy.newest = undefined;
696
+ oldest.newer = undefined;
697
+ oldest.inLru = false;
698
+ policy.lruSize--;
699
+ policy.entries.delete(oldest.key);
700
+ super.delete(oldest.key);
701
+ policy.evicted++;
702
+ if (policy.onEvict)
703
+ this.#notify(oldest.key, value, "evicted");
704
+ }
705
+ }
706
+ #nextDeadline() {
707
+ const policy = this.#policy;
708
+ for (;; ) {
709
+ const top = policy.heap[0];
710
+ if (top === undefined)
711
+ return Infinity;
712
+ if (policy.entries.get(top.key) !== top) {
713
+ this.#heapPop();
714
+ continue;
715
+ }
716
+ if (top.deadline === top.filed)
717
+ return top.filed;
718
+ this.#heapPop();
719
+ top.filed = top.deadline;
720
+ this.#heapPush(top);
721
+ }
722
+ }
723
+ #compact() {
724
+ const policy = this.#policy;
725
+ const live = policy.heap.filter((entry) => policy.entries.get(entry.key) === entry);
726
+ policy.heap.length = 0;
727
+ for (const entry of live)
728
+ this.#heapPush(entry);
729
+ }
730
+ #rearm() {
731
+ const p = this.#policy;
732
+ const deadline = this.#nextDeadline();
733
+ if (p.timer !== undefined && deadline >= p.armedFor)
734
+ return;
735
+ if (p.timer)
736
+ clearTimeout(p.timer);
737
+ p.timer = undefined;
738
+ p.armedFor = deadline;
739
+ if (deadline === Infinity)
740
+ return;
741
+ p.timer = setTimeout(() => {
742
+ p.timer = undefined;
743
+ p.armedFor = Infinity;
744
+ this.purge();
745
+ }, Math.max(0, deadline - Date.now()));
746
+ p.timer.unref?.();
747
+ }
748
+ #heapPush(entry) {
749
+ const heap = this.#policy.heap;
750
+ let i = heap.length;
751
+ heap.push(entry);
752
+ while (i > 0) {
753
+ const parent = i - 1 >> 1;
754
+ const above = heap[parent];
755
+ if (above.filed <= entry.filed)
756
+ break;
757
+ heap[i] = above;
758
+ i = parent;
759
+ }
760
+ heap[i] = entry;
761
+ }
762
+ #heapPop() {
763
+ const heap = this.#policy.heap;
764
+ const top = heap[0];
765
+ const last = heap.pop();
766
+ if (top === undefined || heap.length === 0)
767
+ return top;
768
+ let i = 0;
769
+ for (;; ) {
770
+ let child = 2 * i + 1;
771
+ if (child >= heap.length)
772
+ break;
773
+ if (child + 1 < heap.length && heap[child + 1].filed < heap[child].filed)
774
+ child++;
775
+ if (heap[child].filed >= last.filed)
776
+ break;
777
+ heap[i] = heap[child];
778
+ i = child;
779
+ }
780
+ heap[i] = last;
781
+ return top;
782
+ }
783
+ first() {
784
+ for (const value of this.values())
785
+ return value;
786
+ return;
787
+ }
788
+ firstKey() {
789
+ for (const key of this.keys())
790
+ return key;
791
+ return;
792
+ }
793
+ last() {
794
+ let value;
795
+ for (const item of this.values())
796
+ value = item;
797
+ return value;
798
+ }
799
+ lastKey() {
800
+ let key;
801
+ for (const item of this.keys())
802
+ key = item;
803
+ return key;
804
+ }
805
+ find(predicate) {
806
+ for (const [key, value] of this) {
807
+ if (predicate(value, key, this))
808
+ return value;
809
+ }
810
+ return;
811
+ }
812
+ findLast(predicate) {
813
+ const keys = this.keyArray();
814
+ const values = this.array();
815
+ for (let i = values.length - 1;i >= 0; i--)
816
+ if (predicate(values[i], keys[i], this))
817
+ return values[i];
818
+ return;
819
+ }
820
+ findLastKey(predicate) {
821
+ const keys = this.keyArray();
822
+ const values = this.array();
823
+ for (let i = values.length - 1;i >= 0; i--)
824
+ if (predicate(values[i], keys[i], this))
825
+ return keys[i];
826
+ return;
827
+ }
828
+ filter(predicate) {
829
+ const result = this.#derived();
830
+ this.forEach((value, key) => {
831
+ if (predicate(value, key, this))
832
+ result.set(key, value);
833
+ });
834
+ return result;
835
+ }
836
+ map(transform) {
837
+ const result = [];
838
+ this.forEach((value, key) => {
839
+ result.push(transform(value, key, this));
840
+ });
841
+ return result;
842
+ }
843
+ some(predicate) {
844
+ for (const [key, value] of this) {
845
+ if (predicate(value, key, this))
846
+ return true;
847
+ }
848
+ return false;
849
+ }
850
+ every(predicate) {
851
+ for (const [key, value] of this) {
852
+ if (!predicate(value, key, this))
853
+ return false;
854
+ }
855
+ return true;
856
+ }
857
+ each(callback) {
858
+ this.forEach((value, key) => {
859
+ callback(value, key, this);
860
+ });
861
+ return this;
862
+ }
863
+ array() {
864
+ return [...this.values()];
865
+ }
866
+ keyArray() {
867
+ return [...this.keys()];
868
+ }
869
+ entriesArray() {
870
+ return [...this.entries()];
871
+ }
872
+ clone() {
873
+ const copy = this.#derived();
874
+ this.forEach((value, key) => {
875
+ copy.set(key, value);
876
+ });
877
+ return copy;
878
+ }
879
+ hasAll(...keys) {
880
+ for (let i = 0;i < keys.length; i++) {
881
+ if (!this.has(keys[i]))
882
+ return false;
883
+ }
884
+ return true;
885
+ }
886
+ hasAny(...keys) {
887
+ for (let i = 0;i < keys.length; i++) {
888
+ if (this.has(keys[i]))
889
+ return true;
890
+ }
891
+ return false;
892
+ }
893
+ findKey(predicate) {
894
+ for (const [key, value] of this) {
895
+ if (predicate(value, key, this))
896
+ return key;
897
+ }
898
+ return;
899
+ }
900
+ someEntry(predicate) {
901
+ return this.some(predicate);
902
+ }
903
+ sweep(predicate) {
904
+ let removed = 0;
905
+ for (const [key, value] of this) {
906
+ if (predicate(value, key, this) && this.delete(key))
907
+ removed++;
908
+ }
909
+ return removed;
910
+ }
911
+ firstEntry() {
912
+ for (const [key, value] of this)
913
+ return [key, value];
914
+ return;
915
+ }
916
+ lastEntry() {
917
+ let entry;
918
+ for (const item of this)
919
+ entry = [item[0], item[1]];
920
+ return entry;
921
+ }
922
+ union(other) {
923
+ const result = this.clone();
924
+ for (const [key, value] of other)
925
+ result.set(key, value);
926
+ return result;
927
+ }
928
+ intersection(other) {
929
+ const result = this.#derived();
930
+ for (const [key, value] of this) {
931
+ if (other.has(key))
932
+ result.set(key, value);
933
+ }
934
+ return result;
935
+ }
936
+ difference(other) {
937
+ const result = this.#derived();
938
+ for (const [key, value] of this) {
939
+ if (!other.has(key))
940
+ result.set(key, value);
941
+ }
942
+ return result;
943
+ }
944
+ partition(predicate) {
945
+ const pass = this.#derived();
946
+ const fail = this.#derived();
947
+ for (const [key, value] of this) {
948
+ if (predicate(value, key, this))
949
+ pass.set(key, value);
950
+ else
951
+ fail.set(key, value);
952
+ }
953
+ return [pass, fail];
954
+ }
955
+ symmetricDifference(other) {
956
+ const result = this.#derived();
957
+ for (const [key, value] of this)
958
+ if (!other.has(key))
959
+ result.set(key, value);
960
+ for (const [key, value] of other)
961
+ if (!this.has(key))
962
+ result.set(key, value);
963
+ return result;
964
+ }
965
+ concat(...collections) {
966
+ const result = this.clone();
967
+ for (const collection of collections)
968
+ for (const [key, value] of collection)
969
+ result.set(key, value);
970
+ return result;
971
+ }
972
+ merge(other, whenInSelf, whenInOther, whenInBoth) {
973
+ const result = this.#derived();
974
+ const decide = (key, kept) => {
975
+ if (kept.keep)
976
+ result.set(key, kept.value);
977
+ };
978
+ for (const [key, value] of this) {
979
+ decide(key, other.has(key) ? whenInBoth(value, peekOf(other, key), key) : whenInSelf(value, key));
980
+ }
981
+ for (const [key, value] of other)
982
+ if (!this.has(key))
983
+ decide(key, whenInOther(value, key));
984
+ return result;
985
+ }
986
+ equals(other) {
987
+ if (!other)
988
+ return false;
989
+ if (other === this)
990
+ return true;
991
+ if (this.size !== other.size)
992
+ return false;
993
+ for (const [key, value] of this) {
994
+ if (!other.has(key))
995
+ return false;
996
+ if (value !== peekOf(other, key))
997
+ return false;
998
+ }
999
+ return true;
1000
+ }
1001
+ mapValues(transform) {
1002
+ const result = this.#derived();
1003
+ for (const [key, value] of this)
1004
+ result.set(key, transform(value, key, this));
1005
+ return result;
1006
+ }
1007
+ toReversed() {
1008
+ const result = this.#derived();
1009
+ const entries = [...this];
1010
+ for (let i = entries.length - 1;i >= 0; i--)
1011
+ result.set(entries[i][0], entries[i][1]);
1012
+ return result;
1013
+ }
1014
+ toSorted(comparator) {
1015
+ return this.sorted(comparator);
1016
+ }
1017
+ static groupBy(items, keySelector) {
1018
+ const groups = new Collection2;
1019
+ let index = 0;
1020
+ for (const item of items)
1021
+ groups.ensure(keySelector(item, index++), () => []).push(item);
1022
+ return groups;
1023
+ }
1024
+ static combineEntries(entries, combine) {
1025
+ const result = new Collection2;
1026
+ for (const [key, value] of entries)
1027
+ result.set(key, result.has(key) ? combine(result.get(key), value, key) : value);
1028
+ return result;
1029
+ }
1030
+ tap(fn) {
1031
+ fn(this);
1032
+ return this;
1033
+ }
1034
+ flatMap(transform) {
1035
+ const result = [];
1036
+ for (const [key, value] of this) {
1037
+ for (const item of transform(value, key, this))
1038
+ result.push(item);
1039
+ }
1040
+ return result;
1041
+ }
1042
+ reduce(fn, initialValue) {
1043
+ let acc = initialValue;
1044
+ for (const [key, value] of this)
1045
+ acc = fn(acc, value, key, this);
1046
+ return acc;
1047
+ }
1048
+ reduceRight(fn, initialValue) {
1049
+ const entries = [...this];
1050
+ let acc = initialValue;
1051
+ for (let i = entries.length - 1;i >= 0; i--)
1052
+ acc = fn(acc, entries[i][1], entries[i][0], this);
1053
+ return acc;
1054
+ }
1055
+ sorted(comparator) {
1056
+ const decorated = [...this.entries()].map((entry, index) => ({
1057
+ entry,
1058
+ index
1059
+ }));
1060
+ if (comparator)
1061
+ decorated.sort((x, y) => {
1062
+ const comparison = comparator(x.entry[1], y.entry[1], x.entry[0], y.entry[0]);
1063
+ return comparison !== 0 ? comparison : x.index - y.index;
1064
+ });
1065
+ const result = this.#derived();
1066
+ for (const { entry } of decorated)
1067
+ result.set(entry[0], entry[1]);
1068
+ return result;
1069
+ }
1070
+ random(amount) {
1071
+ if (amount !== undefined)
1072
+ return sample([...this.values()], amount);
1073
+ const size = this.size;
1074
+ if (size === 0)
1075
+ return;
1076
+ let index = Math.floor(Math.random() * size);
1077
+ for (const value of this.values())
1078
+ if (index-- === 0)
1079
+ return value;
1080
+ return;
1081
+ }
1082
+ randomKey(amount) {
1083
+ if (amount !== undefined)
1084
+ return sample([...this.keys()], amount);
1085
+ const size = this.size;
1086
+ if (size === 0)
1087
+ return;
1088
+ let index = Math.floor(Math.random() * size);
1089
+ for (const key of this.keys())
1090
+ if (index-- === 0)
1091
+ return key;
1092
+ return;
1093
+ }
1094
+ at(index) {
1095
+ let remaining = index < 0 ? this.size + index : index;
1096
+ if (remaining < 0)
1097
+ return;
1098
+ for (const value of this.values())
1099
+ if (remaining-- === 0)
1100
+ return value;
1101
+ return;
1102
+ }
1103
+ keyAt(index) {
1104
+ let remaining = index < 0 ? this.size + index : index;
1105
+ if (remaining < 0)
1106
+ return;
1107
+ for (const key of this.keys())
1108
+ if (remaining-- === 0)
1109
+ return key;
1110
+ return;
1111
+ }
1112
+ toJSON() {
1113
+ return [...this.entries()];
1114
+ }
1115
+ }
1116
+
1117
+ export { Cache2, RedisCollection2, Collection2 };
1118
+
1119
+ //# debugId=8210ED8C141EF20B64756E2164756E21