lunibee 0.2.3 → 0.2.4

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 (61) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +225 -225
  3. package/dist/builders/attachment.d.ts +8 -0
  4. package/dist/builders/commands.d.ts +122 -65
  5. package/dist/builders/components.d.ts +10 -31
  6. package/dist/builders/embed.d.ts +66 -33
  7. package/dist/builders/index.js +97 -131
  8. package/dist/builders/index.js.map +8 -8
  9. package/dist/collection/cache.d.ts +13 -6
  10. package/dist/collection/index.d.ts +90 -17
  11. package/dist/collection/index.js +442 -266
  12. package/dist/collection/index.js.map +4 -4
  13. package/dist/core/index.d.ts +8 -0
  14. package/dist/core/index.js +607 -352
  15. package/dist/core/index.js.map +47 -47
  16. package/dist/core/permissions.d.ts +7 -3
  17. package/dist/formatters/index.js +9 -5
  18. package/dist/formatters/index.js.map +3 -3
  19. package/dist/handlers/index.js +5 -10
  20. package/dist/handlers/index.js.map +3 -3
  21. package/dist/index.js +769 -587
  22. package/dist/index.js.map +65 -65
  23. package/dist/managers/base.d.ts +22 -14
  24. package/dist/managers/index.d.ts +2 -1
  25. package/dist/managers/index.js +445 -276
  26. package/dist/managers/index.js.map +26 -26
  27. package/dist/managers/message.d.ts +7 -3
  28. package/dist/rest/errors.d.ts +14 -7
  29. package/dist/rest/index.d.ts +24 -12
  30. package/dist/rest/index.js +54 -17
  31. package/dist/rest/index.js.map +14 -14
  32. package/dist/rest/redis.d.ts +1 -1
  33. package/dist/rest/route.d.ts +8 -4
  34. package/dist/rest/routes.d.ts +102 -48
  35. package/dist/rest/transport.d.ts +10 -5
  36. package/dist/rest/webhook.d.ts +9 -5
  37. package/dist/sharding/bus.d.ts +34 -17
  38. package/dist/sharding/index.d.ts +34 -17
  39. package/dist/sharding/index.js +64 -32
  40. package/dist/sharding/index.js.map +17 -17
  41. package/dist/structures/base.d.ts +19 -10
  42. package/dist/structures/channels.d.ts +28 -14
  43. package/dist/structures/index.js +9 -59
  44. package/dist/structures/index.js.map +19 -18
  45. package/dist/structures/interactions.d.ts +96 -48
  46. package/dist/structures/resources.d.ts +88 -44
  47. package/dist/types/gateway.d.ts +1 -1
  48. package/dist/types/index.js +20 -22
  49. package/dist/types/index.js.map +4 -4
  50. package/dist/utils/index.js.map +2 -2
  51. package/dist/voice/index.d.ts +12 -4
  52. package/dist/voice/index.js +14 -18
  53. package/dist/voice/index.js.map +3 -3
  54. package/dist/ws/decoder.d.ts +6 -2
  55. package/dist/ws/index.d.ts +25 -13
  56. package/dist/ws/index.js +63 -31
  57. package/dist/ws/index.js.map +14 -14
  58. package/dist/ws/protocol.d.ts +10 -2
  59. package/dist/ws/session.d.ts +14 -4
  60. package/dist/ws/state.d.ts +22 -11
  61. package/package.json +15 -14
@@ -1,66 +1,36 @@
1
1
  // @bun
2
2
  // packages/collection/src/index.ts
3
- class RecencyList {
4
- #nodes = new Map;
5
- #oldest;
6
- #newest;
7
- get size() {
8
- return this.#nodes.size;
9
- }
10
- oldest() {
11
- return this.#oldest?.key;
12
- }
13
- touch(key) {
14
- const node = this.#nodes.get(key);
15
- if (node)
16
- return this.#moveNewest(node);
17
- const created = { key, older: this.#newest };
18
- if (this.#newest)
19
- this.#newest.newer = created;
20
- else
21
- this.#oldest = created;
22
- this.#newest = created;
23
- this.#nodes.set(key, created);
24
- }
25
- promote(key) {
26
- const node = this.#nodes.get(key);
27
- if (node)
28
- this.#moveNewest(node);
29
- }
30
- delete(key) {
31
- const node = this.#nodes.get(key);
32
- if (!node)
33
- return false;
34
- this.#unlink(node);
35
- this.#nodes.delete(key);
36
- return true;
37
- }
38
- clear() {
39
- this.#nodes.clear();
40
- this.#oldest = this.#newest = undefined;
41
- }
42
- #unlink(node) {
43
- if (node.older)
44
- node.older.newer = node.newer;
45
- else
46
- this.#oldest = node.newer;
47
- if (node.newer)
48
- node.newer.older = node.older;
49
- else
50
- this.#newest = node.older;
51
- node.older = node.newer = undefined;
52
- }
53
- #moveNewest(node) {
54
- if (node === this.#newest)
55
- return;
56
- this.#unlink(node);
57
- node.older = this.#newest;
58
- if (this.#newest)
59
- this.#newest.newer = node;
60
- else
61
- this.#oldest = node;
62
- this.#newest = node;
63
- }
3
+ function newPolicy(options = {}) {
4
+ return {
5
+ ttl: options.ttl,
6
+ maxSize: options.maxSize,
7
+ slide: options.slide ?? true,
8
+ onEvict: options.onEvict,
9
+ expired: 0,
10
+ evicted: 0,
11
+ entries: new Map,
12
+ oldest: undefined,
13
+ newest: undefined,
14
+ lruSize: 0,
15
+ heap: [],
16
+ armedFor: Infinity
17
+ };
18
+ }
19
+ function peekOf(collection, key) {
20
+ return collection instanceof Map ? Map.prototype.get.call(collection, key) : collection.get(key);
21
+ }
22
+ var mapGet = Map.prototype.get;
23
+ var mapHas = Map.prototype.has;
24
+ function sample(items, amount) {
25
+ if (!Number.isInteger(amount) || amount < 0)
26
+ throw new RangeError("amount must be a non-negative integer.");
27
+ const count = Math.min(amount, items.length);
28
+ for (let i = 0;i < count; i++) {
29
+ const j = i + Math.floor(Math.random() * (items.length - i));
30
+ [items[i], items[j]] = [items[j], items[i]];
31
+ }
32
+ items.length = count;
33
+ return items;
64
34
  }
65
35
  function assertTTL(ttl) {
66
36
  if (ttl !== undefined && (!Number.isFinite(ttl) || ttl <= 0))
@@ -68,81 +38,90 @@ function assertTTL(ttl) {
68
38
  }
69
39
 
70
40
  class Collection extends Map {
71
- #ttl;
72
- #maxSize;
73
- #onEvict;
74
- #expiry = new Map;
75
- #lru = new RecencyList;
76
- #stats = {
77
- hits: 0,
78
- misses: 0,
79
- expired: 0,
80
- evicted: 0
81
- };
82
- #heap = [];
83
- #timer;
84
- #armedFor = Infinity;
41
+ #policy;
42
+ #hits = 0;
43
+ #misses = 0;
85
44
  constructor(entries, options = {}) {
86
45
  super();
87
46
  assertTTL(options.ttl);
88
47
  if (options.maxSize !== undefined && (!Number.isInteger(options.maxSize) || options.maxSize <= 0))
89
48
  throw new RangeError("maxSize must be a positive integer.");
90
- this.#ttl = options.ttl;
91
- this.#maxSize = options.maxSize;
92
- this.#onEvict = options.onEvict;
49
+ if (options.ttl !== undefined || options.maxSize !== undefined || options.slide !== undefined || options.onEvict !== undefined)
50
+ this.#policy = newPolicy(options);
93
51
  if (entries)
94
52
  for (const [key, value] of entries)
95
53
  this.set(key, value);
96
54
  }
97
55
  set(key, value, ttl) {
56
+ if (ttl === undefined && this.#policy === undefined)
57
+ return super.set(key, value);
98
58
  assertTTL(ttl);
99
- const window = ttl ?? this.#ttl;
100
- if (this.#maxSize !== undefined) {
101
- this.#lru.touch(key);
102
- }
103
- super.set(key, value);
59
+ const window = ttl ?? this.#policy?.ttl;
104
60
  if (window !== undefined)
105
- this.#schedule(key, window);
106
- else if (this.#expiry.size > 0)
107
- this.#expiry.delete(key);
61
+ this.#policy ??= newPolicy();
62
+ if (!this.#policy)
63
+ return super.set(key, value);
64
+ const before = super.size;
65
+ super.set(key, value);
66
+ this.#track(key, value, window, super.size !== before);
108
67
  this.#enforceCap();
109
68
  return this;
110
69
  }
111
70
  setWithoutTTL(key, value) {
112
- if (this.#expiry.size > 0)
113
- this.#expiry.delete(key);
114
- if (this.#lru.size > 0)
115
- this.#lru.delete(key);
71
+ if (this.#policy)
72
+ this.#forget(key);
116
73
  super.set(key, value);
117
74
  return this;
118
75
  }
119
76
  get(key) {
120
- if (this.#expireIfDue(key)) {
121
- this.#stats.misses++;
77
+ const policy = this.#policy;
78
+ const entry = policy?.entries.get(key);
79
+ if (entry === undefined) {
80
+ const value = mapGet.call(this, key);
81
+ if (value !== undefined || mapHas.call(this, key)) {
82
+ this.#hits++;
83
+ return value;
84
+ }
85
+ this.#misses++;
122
86
  return;
123
87
  }
124
- const value = super.get(key);
125
- if (value === undefined && !super.has(key)) {
126
- this.#stats.misses++;
88
+ const timed = entry.window !== 0;
89
+ const now = timed ? Date.now() : 0;
90
+ if (timed && entry.deadline <= now) {
91
+ this.#expire(entry);
92
+ this.#misses++;
127
93
  return;
128
94
  }
129
- this.#stats.hits++;
130
- const expiry = this.#expiry.get(key);
131
- if (expiry)
132
- expiry.deadline = Date.now() + expiry.window;
133
- this.#lru.promote(key);
134
- return value;
95
+ this.#hits++;
96
+ if (timed && policy.slide)
97
+ entry.deadline = now + entry.window;
98
+ if (entry.inLru)
99
+ this.#promote(policy, entry);
100
+ return entry.value;
101
+ }
102
+ ensure(key, factory, ttl) {
103
+ const existing = this.get(key);
104
+ if (existing !== undefined || super.has(key))
105
+ return existing;
106
+ const created = factory(key, this);
107
+ this.set(key, created, ttl);
108
+ return created;
135
109
  }
136
110
  peek(key) {
137
111
  if (!this.#expireIfDue(key) && super.has(key)) {
138
- this.#stats.hits++;
112
+ this.#hits++;
139
113
  return super.get(key);
140
114
  }
141
- this.#stats.misses++;
115
+ this.#misses++;
142
116
  return;
143
117
  }
144
118
  get stats() {
145
- return { ...this.#stats };
119
+ return {
120
+ hits: this.#hits,
121
+ misses: this.#misses,
122
+ expired: this.#policy?.expired ?? 0,
123
+ evicted: this.#policy?.evicted ?? 0
124
+ };
146
125
  }
147
126
  has(key) {
148
127
  return !this.#expireIfDue(key) && super.has(key);
@@ -150,19 +129,23 @@ class Collection extends Map {
150
129
  delete(key) {
151
130
  if (this.#expireIfDue(key))
152
131
  return false;
153
- this.#expiry.delete(key);
154
- this.#lru.delete(key);
132
+ if (this.#policy)
133
+ this.#forget(key);
155
134
  return super.delete(key);
156
135
  }
157
136
  clear() {
158
137
  super.clear();
159
- this.#expiry.clear();
160
- this.#lru.clear();
161
- this.#heap.length = 0;
162
- if (this.#timer)
163
- clearTimeout(this.#timer);
164
- this.#timer = undefined;
165
- this.#armedFor = Infinity;
138
+ const policy = this.#policy;
139
+ if (!policy)
140
+ return;
141
+ policy.entries.clear();
142
+ policy.oldest = policy.newest = undefined;
143
+ policy.lruSize = 0;
144
+ policy.heap.length = 0;
145
+ if (policy.timer)
146
+ clearTimeout(policy.timer);
147
+ policy.timer = undefined;
148
+ policy.armedFor = Infinity;
166
149
  }
167
150
  get size() {
168
151
  this.purge();
@@ -190,11 +173,11 @@ class Collection extends Map {
190
173
  ttlRemaining(key) {
191
174
  if (this.#expireIfDue(key))
192
175
  return;
193
- const expiry = this.#expiry.get(key);
194
- return expiry && Math.max(0, expiry.deadline - Date.now());
176
+ const entry = this.#policy?.entries.get(key);
177
+ return entry && entry.window !== 0 ? Math.max(0, entry.deadline - Date.now()) : undefined;
195
178
  }
196
179
  purge() {
197
- if (this.#expiry.size === 0)
180
+ if (!this.#policy || this.#policy.heap.length === 0)
198
181
  return 0;
199
182
  const now = Date.now();
200
183
  let removed = 0;
@@ -205,133 +188,255 @@ class Collection extends Map {
205
188
  this.#remove(due.key);
206
189
  removed++;
207
190
  }
208
- this.#stats.expired += removed;
191
+ this.#policy.expired += removed;
209
192
  this.#rearm();
210
193
  for (const [key, value] of dropped)
211
194
  this.#notify(key, value, "expired");
212
195
  return removed;
213
196
  }
214
197
  #expireIfDue(key) {
215
- const expiry = this.#expiry.get(key);
216
- if (!expiry || expiry.deadline > Date.now())
198
+ const entry = this.#policy?.entries.get(key);
199
+ if (!entry || entry.window === 0 || entry.deadline > Date.now())
217
200
  return false;
218
- const value = super.get(key);
219
- this.#remove(key);
220
- this.#stats.expired++;
221
- this.#notify(key, value, "expired");
201
+ this.#expire(entry);
222
202
  return true;
223
203
  }
204
+ #expire(entry) {
205
+ const value = super.get(entry.key);
206
+ this.#remove(entry.key);
207
+ this.#policy.expired++;
208
+ this.#notify(entry.key, value, "expired");
209
+ }
224
210
  #remove(key) {
225
- this.#expiry.delete(key);
226
- this.#lru.delete(key);
211
+ this.#forget(key);
227
212
  super.delete(key);
228
213
  }
214
+ #forget(key) {
215
+ const policy = this.#policy;
216
+ const entry = policy.entries.get(key);
217
+ if (!entry)
218
+ return;
219
+ if (entry.inLru)
220
+ this.#unlink(policy, entry);
221
+ policy.entries.delete(key);
222
+ }
223
+ #track(key, value, window, isNew) {
224
+ const policy = this.#policy;
225
+ const lru = policy.maxSize !== undefined;
226
+ let entry = isNew ? undefined : policy.entries.get(key);
227
+ if (entry)
228
+ entry.value = value;
229
+ if (window === undefined) {
230
+ if (entry && entry.window !== 0) {
231
+ if (lru)
232
+ entry = this.#replace(policy, entry, 0, 0);
233
+ else {
234
+ this.#forget(key);
235
+ return;
236
+ }
237
+ }
238
+ if (!entry && lru) {
239
+ entry = this.#create(key, value, 0, 0);
240
+ policy.entries.set(key, entry);
241
+ }
242
+ if (entry)
243
+ this.#promote(policy, entry);
244
+ return;
245
+ }
246
+ const deadline = Date.now() + window;
247
+ if (entry && entry.window !== 0) {
248
+ entry.deadline = deadline;
249
+ entry.window = window;
250
+ if (deadline < entry.filed)
251
+ entry = this.#replace(policy, entry, window, deadline);
252
+ else {
253
+ if (entry.inLru)
254
+ this.#promote(policy, entry);
255
+ return;
256
+ }
257
+ } else if (entry) {
258
+ entry.window = window;
259
+ entry.deadline = entry.filed = deadline;
260
+ } else {
261
+ entry = this.#create(key, value, window, deadline);
262
+ policy.entries.set(key, entry);
263
+ }
264
+ if (lru)
265
+ this.#promote(policy, entry);
266
+ this.#heapPush(entry);
267
+ if (policy.heap.length > 2 * policy.entries.size + 8)
268
+ this.#compact();
269
+ if (policy.timer === undefined || deadline < policy.armedFor)
270
+ this.#rearm();
271
+ }
272
+ #create(key, value, window, deadline) {
273
+ return {
274
+ key,
275
+ value,
276
+ older: undefined,
277
+ newer: undefined,
278
+ inLru: false,
279
+ window,
280
+ deadline,
281
+ filed: deadline
282
+ };
283
+ }
284
+ #replace(policy, old, window, deadline) {
285
+ const entry = {
286
+ ...old,
287
+ window,
288
+ deadline,
289
+ filed: deadline
290
+ };
291
+ if (old.inLru) {
292
+ if (old.older)
293
+ old.older.newer = entry;
294
+ else
295
+ policy.oldest = entry;
296
+ if (old.newer)
297
+ old.newer.older = entry;
298
+ else
299
+ policy.newest = entry;
300
+ }
301
+ policy.entries.set(old.key, entry);
302
+ return entry;
303
+ }
304
+ #promote(policy, entry) {
305
+ if (entry === policy.newest)
306
+ return;
307
+ if (entry.inLru)
308
+ this.#unlink(policy, entry, true);
309
+ else {
310
+ entry.inLru = true;
311
+ policy.lruSize++;
312
+ }
313
+ entry.older = policy.newest;
314
+ entry.newer = undefined;
315
+ if (policy.newest)
316
+ policy.newest.newer = entry;
317
+ else
318
+ policy.oldest = entry;
319
+ policy.newest = entry;
320
+ }
321
+ #unlink(policy, entry, keepCount = false) {
322
+ if (entry.older)
323
+ entry.older.newer = entry.newer;
324
+ else
325
+ policy.oldest = entry.newer;
326
+ if (entry.newer)
327
+ entry.newer.older = entry.older;
328
+ else
329
+ policy.newest = entry.older;
330
+ entry.older = entry.newer = undefined;
331
+ if (!keepCount) {
332
+ entry.inLru = false;
333
+ policy.lruSize--;
334
+ }
335
+ }
336
+ #derived() {
337
+ const Species = this.constructor[Symbol.species] ?? Collection;
338
+ return new Species;
339
+ }
229
340
  #notify(key, value, reason) {
230
- if (!this.#onEvict)
341
+ const onEvict = this.#policy?.onEvict;
342
+ if (!onEvict)
231
343
  return;
232
344
  try {
233
- this.#onEvict(key, value, reason);
345
+ onEvict(key, value, reason);
234
346
  } catch {}
235
347
  }
236
348
  #enforceCap() {
237
- if (this.#maxSize === undefined)
349
+ const policy = this.#policy;
350
+ const max = policy.maxSize;
351
+ if (max === undefined)
238
352
  return;
239
- while (this.#lru.size > this.#maxSize) {
240
- const oldest = this.#lru.oldest();
241
- const value = super.get(oldest);
242
- this.#remove(oldest);
243
- this.#stats.evicted++;
244
- this.#notify(oldest, value, "evicted");
353
+ if (policy.lruSize > max && policy.heap.length > 0 && policy.heap[0].filed <= Date.now())
354
+ this.purge();
355
+ while (policy.lruSize > max) {
356
+ const oldest = policy.oldest;
357
+ const value = policy.onEvict ? super.get(oldest.key) : undefined;
358
+ this.#unlink(policy, oldest);
359
+ policy.entries.delete(oldest.key);
360
+ super.delete(oldest.key);
361
+ policy.evicted++;
362
+ this.#notify(oldest.key, value, "evicted");
245
363
  }
246
364
  }
247
- #schedule(key, window) {
248
- const deadline = Date.now() + window;
249
- const expiry = this.#expiry.get(key);
250
- if (expiry) {
251
- expiry.deadline = deadline;
252
- expiry.window = window;
253
- if (deadline >= expiry.filed)
254
- return;
255
- expiry.filed = deadline;
256
- } else
257
- this.#expiry.set(key, { deadline, window, filed: deadline });
258
- this.#heapPush({ key, deadline });
259
- if (this.#heap.length > 2 * this.#expiry.size + 8)
260
- this.#compact();
261
- this.#rearm();
262
- }
263
365
  #nextDeadline() {
366
+ const policy = this.#policy;
264
367
  for (;; ) {
265
- const top = this.#heap[0];
368
+ const top = policy.heap[0];
266
369
  if (top === undefined)
267
370
  return Infinity;
268
- const expiry = this.#expiry.get(top.key);
269
- if (!expiry || expiry.filed !== top.deadline) {
371
+ if (policy.entries.get(top.key) !== top) {
270
372
  this.#heapPop();
271
373
  continue;
272
374
  }
273
- if (expiry.deadline === top.deadline)
274
- return top.deadline;
375
+ if (top.deadline === top.filed)
376
+ return top.filed;
275
377
  this.#heapPop();
276
- expiry.filed = expiry.deadline;
277
- this.#heapPush({ key: top.key, deadline: expiry.deadline });
378
+ top.filed = top.deadline;
379
+ this.#heapPush(top);
278
380
  }
279
381
  }
280
382
  #compact() {
281
- const live = this.#heap.filter((record) => this.#expiry.get(record.key)?.filed === record.deadline);
282
- this.#heap.length = 0;
283
- for (const record of live)
284
- this.#heapPush(record);
383
+ const policy = this.#policy;
384
+ const live = policy.heap.filter((entry) => policy.entries.get(entry.key) === entry);
385
+ policy.heap.length = 0;
386
+ for (const entry of live)
387
+ this.#heapPush(entry);
285
388
  }
286
389
  #rearm() {
390
+ const p = this.#policy;
287
391
  const deadline = this.#nextDeadline();
288
- if (this.#timer !== undefined && deadline >= this.#armedFor)
392
+ if (p.timer !== undefined && deadline >= p.armedFor)
289
393
  return;
290
- if (this.#timer)
291
- clearTimeout(this.#timer);
292
- this.#timer = undefined;
293
- this.#armedFor = deadline;
394
+ if (p.timer)
395
+ clearTimeout(p.timer);
396
+ p.timer = undefined;
397
+ p.armedFor = deadline;
294
398
  if (deadline === Infinity)
295
399
  return;
296
- this.#timer = setTimeout(() => {
297
- this.#timer = undefined;
298
- this.#armedFor = Infinity;
400
+ p.timer = setTimeout(() => {
401
+ p.timer = undefined;
402
+ p.armedFor = Infinity;
299
403
  this.purge();
300
404
  }, Math.max(0, deadline - Date.now()));
301
- this.#timer.unref?.();
405
+ p.timer.unref?.();
302
406
  }
303
- #heapPush(record) {
304
- const heap = this.#heap;
305
- heap.push(record);
306
- let i = heap.length - 1;
407
+ #heapPush(entry) {
408
+ const heap = this.#policy.heap;
409
+ let i = heap.length;
410
+ heap.push(entry);
307
411
  while (i > 0) {
308
412
  const parent = i - 1 >> 1;
309
- if (heap[parent].deadline <= heap[i].deadline)
413
+ const above = heap[parent];
414
+ if (above.filed <= entry.filed)
310
415
  break;
311
- [heap[parent], heap[i]] = [heap[i], heap[parent]];
416
+ heap[i] = above;
312
417
  i = parent;
313
418
  }
419
+ heap[i] = entry;
314
420
  }
315
421
  #heapPop() {
316
- const heap = this.#heap;
422
+ const heap = this.#policy.heap;
317
423
  const top = heap[0];
318
424
  const last = heap.pop();
319
425
  if (top === undefined || heap.length === 0)
320
426
  return top;
321
- heap[0] = last;
322
- for (let i = 0;; ) {
323
- const left = 2 * i + 1;
324
- const right = left + 1;
325
- let smallest = i;
326
- if (left < heap.length && heap[left].deadline < heap[smallest].deadline)
327
- smallest = left;
328
- if (right < heap.length && heap[right].deadline < heap[smallest].deadline)
329
- smallest = right;
330
- if (smallest === i)
427
+ let i = 0;
428
+ for (;; ) {
429
+ let child = 2 * i + 1;
430
+ if (child >= heap.length)
431
+ break;
432
+ if (child + 1 < heap.length && heap[child + 1].filed < heap[child].filed)
433
+ child++;
434
+ if (heap[child].filed >= last.filed)
331
435
  break;
332
- [heap[smallest], heap[i]] = [heap[i], heap[smallest]];
333
- i = smallest;
436
+ heap[i] = heap[child];
437
+ i = child;
334
438
  }
439
+ heap[i] = last;
335
440
  return top;
336
441
  }
337
442
  first() {
@@ -363,8 +468,26 @@ class Collection extends Map {
363
468
  }
364
469
  return;
365
470
  }
471
+ findLast(predicate) {
472
+ const entries = [...this];
473
+ for (let i = entries.length - 1;i >= 0; i--) {
474
+ const [key, value] = entries[i];
475
+ if (predicate(value, key, this))
476
+ return value;
477
+ }
478
+ return;
479
+ }
480
+ findLastKey(predicate) {
481
+ const entries = [...this];
482
+ for (let i = entries.length - 1;i >= 0; i--) {
483
+ const [key, value] = entries[i];
484
+ if (predicate(value, key, this))
485
+ return key;
486
+ }
487
+ return;
488
+ }
366
489
  filter(predicate) {
367
- const result = new Collection;
490
+ const result = this.#derived();
368
491
  for (const [key, value] of this) {
369
492
  if (predicate(value, key, this))
370
493
  result.set(key, value);
@@ -408,7 +531,7 @@ class Collection extends Map {
408
531
  return [...this.entries()];
409
532
  }
410
533
  clone() {
411
- const copy = new Collection;
534
+ const copy = this.#derived();
412
535
  for (const [key, value] of this)
413
536
  copy.set(key, value);
414
537
  return copy;
@@ -463,7 +586,7 @@ class Collection extends Map {
463
586
  return result;
464
587
  }
465
588
  intersection(other) {
466
- const result = new Collection;
589
+ const result = this.#derived();
467
590
  for (const [key, value] of this) {
468
591
  if (other.has(key))
469
592
  result.set(key, value);
@@ -471,7 +594,7 @@ class Collection extends Map {
471
594
  return result;
472
595
  }
473
596
  difference(other) {
474
- const result = new Collection;
597
+ const result = this.#derived();
475
598
  for (const [key, value] of this) {
476
599
  if (!other.has(key))
477
600
  result.set(key, value);
@@ -479,8 +602,8 @@ class Collection extends Map {
479
602
  return result;
480
603
  }
481
604
  partition(predicate) {
482
- const pass = new Collection;
483
- const fail = new Collection;
605
+ const pass = this.#derived();
606
+ const fail = this.#derived();
484
607
  for (const [key, value] of this) {
485
608
  if (predicate(value, key, this))
486
609
  pass.set(key, value);
@@ -489,6 +612,81 @@ class Collection extends Map {
489
612
  }
490
613
  return [pass, fail];
491
614
  }
615
+ symmetricDifference(other) {
616
+ const result = this.#derived();
617
+ for (const [key, value] of this)
618
+ if (!other.has(key))
619
+ result.set(key, value);
620
+ for (const [key, value] of other)
621
+ if (!this.has(key))
622
+ result.set(key, value);
623
+ return result;
624
+ }
625
+ concat(...collections) {
626
+ const result = this.clone();
627
+ for (const collection of collections)
628
+ for (const [key, value] of collection)
629
+ result.set(key, value);
630
+ return result;
631
+ }
632
+ merge(other, whenInSelf, whenInOther, whenInBoth) {
633
+ const result = this.#derived();
634
+ const decide = (key, kept) => {
635
+ if (kept.keep)
636
+ result.set(key, kept.value);
637
+ };
638
+ for (const [key, value] of this) {
639
+ decide(key, other.has(key) ? whenInBoth(value, peekOf(other, key), key) : whenInSelf(value, key));
640
+ }
641
+ for (const [key, value] of other)
642
+ if (!this.has(key))
643
+ decide(key, whenInOther(value, key));
644
+ return result;
645
+ }
646
+ equals(other) {
647
+ if (!other)
648
+ return false;
649
+ if (other === this)
650
+ return true;
651
+ if (this.size !== other.size)
652
+ return false;
653
+ for (const [key, value] of this) {
654
+ if (!other.has(key))
655
+ return false;
656
+ if (value !== peekOf(other, key))
657
+ return false;
658
+ }
659
+ return true;
660
+ }
661
+ mapValues(transform) {
662
+ const result = this.#derived();
663
+ for (const [key, value] of this)
664
+ result.set(key, transform(value, key, this));
665
+ return result;
666
+ }
667
+ toReversed() {
668
+ const result = this.#derived();
669
+ const entries = [...this];
670
+ for (let i = entries.length - 1;i >= 0; i--)
671
+ result.set(entries[i][0], entries[i][1]);
672
+ return result;
673
+ }
674
+ toSorted(comparator) {
675
+ return this.sorted(comparator);
676
+ }
677
+ static groupBy(items, keySelector) {
678
+ const groups = new Collection;
679
+ let index = 0;
680
+ for (const item of items)
681
+ groups.ensure(keySelector(item, index++), () => []).push(item);
682
+ return groups;
683
+ }
684
+ static combineEntries(entries, combine) {
685
+ const result = new Collection;
686
+ for (const [key, value] of entries)
687
+ result.set(key, result.has(key) ? combine(result.get(key), value, key) : value);
688
+ return result;
689
+ }
492
690
  tap(fn) {
493
691
  fn(this);
494
692
  return this;
@@ -507,6 +705,13 @@ class Collection extends Map {
507
705
  acc = fn(acc, value, key, this);
508
706
  return acc;
509
707
  }
708
+ reduceRight(fn, initialValue) {
709
+ const entries = [...this];
710
+ let acc = initialValue;
711
+ for (let i = entries.length - 1;i >= 0; i--)
712
+ acc = fn(acc, entries[i][1], entries[i][0], this);
713
+ return acc;
714
+ }
510
715
  sorted(comparator) {
511
716
  const decorated = [...this.entries()].map((entry, index) => ({
512
717
  entry,
@@ -517,22 +722,34 @@ class Collection extends Map {
517
722
  const comparison = comparator(x.entry[1], y.entry[1], x.entry[0], y.entry[0]);
518
723
  return comparison !== 0 ? comparison : x.index - y.index;
519
724
  });
520
- const result = new Collection;
725
+ const result = this.#derived();
521
726
  for (const { entry } of decorated)
522
727
  result.set(entry[0], entry[1]);
523
728
  return result;
524
729
  }
525
- random() {
526
- const arr = [...this.values()];
527
- if (!arr.length)
730
+ random(amount) {
731
+ if (amount !== undefined)
732
+ return sample([...this.values()], amount);
733
+ const size = this.size;
734
+ if (size === 0)
528
735
  return;
529
- return arr[Math.floor(Math.random() * arr.length)];
736
+ let index = Math.floor(Math.random() * size);
737
+ for (const value of this.values())
738
+ if (index-- === 0)
739
+ return value;
740
+ return;
530
741
  }
531
- randomKey() {
532
- const arr = [...this.keys()];
533
- if (!arr.length)
742
+ randomKey(amount) {
743
+ if (amount !== undefined)
744
+ return sample([...this.keys()], amount);
745
+ const size = this.size;
746
+ if (size === 0)
534
747
  return;
535
- return arr[Math.floor(Math.random() * arr.length)];
748
+ let index = Math.floor(Math.random() * size);
749
+ for (const key of this.keys())
750
+ if (index-- === 0)
751
+ return key;
752
+ return;
536
753
  }
537
754
  at(index) {
538
755
  const arr = [...this.values()];
@@ -656,7 +873,7 @@ class ResourceManager extends Manager {
656
873
  // packages/rest/package.json
657
874
  var package_default = {
658
875
  name: "@lunibee/rest",
659
- version: "0.2.3",
876
+ version: "0.2.4",
660
877
  type: "module",
661
878
  module: "./src/index.ts",
662
879
  types: "./src/index.ts",
@@ -673,6 +890,9 @@ var Routes = {
673
890
  user: () => "/users/@me",
674
891
  userById: (userId) => `/users/${snowflake(userId, "User ID")}`,
675
892
  guild: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}`,
893
+ currentUserGuild: (guildId) => `/users/@me/guilds/${snowflake(guildId, "Guild ID")}`,
894
+ sticker: (stickerId) => `/stickers/${snowflake(stickerId, "Sticker ID")}`,
895
+ messageReactionUser: (channelId, messageId, emoji, userId) => `${Routes.messageReactions(channelId, messageId, emoji)}/${snowflake(userId, "User ID")}`,
676
896
  guildPreview: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/preview`,
677
897
  guildActiveThreads: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/threads/active`,
678
898
  guildWebhooks: (guildId) => `/guilds/${snowflake(guildId, "Guild ID")}/webhooks`,
@@ -785,7 +1005,7 @@ function cdnURL(path, hash, options = {}) {
785
1005
  const isAnimated = hash.startsWith("a_") && !options.forceStatic;
786
1006
  const ext = options.extension ?? (isAnimated ? "gif" : "png");
787
1007
  const size = options.size ? `?size=${options.size}` : "";
788
- return `${CDN_BASE}${path}/${hash}.${ext}${size}`;
1008
+ return `${CDN_BASE}${path}/${encodeURIComponent(hash)}.${ext}${size}`;
789
1009
  }
790
1010
 
791
1011
  class User extends BaseStructure {
@@ -1141,60 +1361,7 @@ var Permissions = {
1141
1361
  PinMessages: 1n << 51n,
1142
1362
  BypassSlowmode: 1n << 52n
1143
1363
  };
1144
- var PermissionFlagsBits = {
1145
- CreateInstantInvite: 1n << 0n,
1146
- KickMembers: 1n << 1n,
1147
- BanMembers: 1n << 2n,
1148
- Administrator: 1n << 3n,
1149
- ManageChannels: 1n << 4n,
1150
- ManageGuild: 1n << 5n,
1151
- AddReactions: 1n << 6n,
1152
- ViewAuditLog: 1n << 7n,
1153
- PrioritySpeaker: 1n << 8n,
1154
- Stream: 1n << 9n,
1155
- ViewChannel: 1n << 10n,
1156
- SendMessages: 1n << 11n,
1157
- SendTTSMessages: 1n << 12n,
1158
- ManageMessages: 1n << 13n,
1159
- EmbedLinks: 1n << 14n,
1160
- AttachFiles: 1n << 15n,
1161
- ReadMessageHistory: 1n << 16n,
1162
- MentionEveryone: 1n << 17n,
1163
- UseExternalEmojis: 1n << 18n,
1164
- ViewGuildInsights: 1n << 19n,
1165
- Connect: 1n << 20n,
1166
- Speak: 1n << 21n,
1167
- MuteMembers: 1n << 22n,
1168
- DeafenMembers: 1n << 23n,
1169
- MoveMembers: 1n << 24n,
1170
- UseVAD: 1n << 25n,
1171
- ChangeNickname: 1n << 26n,
1172
- ManageNicknames: 1n << 27n,
1173
- ManageRoles: 1n << 28n,
1174
- ManageWebhooks: 1n << 29n,
1175
- ManageGuildExpressions: 1n << 30n,
1176
- UseApplicationCommands: 1n << 31n,
1177
- RequestToSpeak: 1n << 32n,
1178
- ManageEvents: 1n << 33n,
1179
- ManageThreads: 1n << 34n,
1180
- CreatePublicThreads: 1n << 35n,
1181
- CreatePrivateThreads: 1n << 36n,
1182
- UseExternalStickers: 1n << 37n,
1183
- SendMessagesInThreads: 1n << 38n,
1184
- UseEmbeddedActivities: 1n << 39n,
1185
- ModerateMembers: 1n << 40n,
1186
- ViewCreatorMonetizationAnalytics: 1n << 41n,
1187
- UseSoundboard: 1n << 42n,
1188
- CreateGuildExpressions: 1n << 43n,
1189
- CreateEvents: 1n << 44n,
1190
- UseExternalSounds: 1n << 45n,
1191
- SendVoiceMessages: 1n << 46n,
1192
- SetVoiceChannelStatus: 1n << 48n,
1193
- SendPolls: 1n << 49n,
1194
- UseExternalApps: 1n << 50n,
1195
- PinMessages: 1n << 51n,
1196
- BypassSlowmode: 1n << 52n
1197
- };
1364
+ var PermissionFlagsBits = Permissions;
1198
1365
 
1199
1366
  class PermissionSet {
1200
1367
  bitfield;
@@ -1595,10 +1762,10 @@ class GuildMember {
1595
1762
  get permissions() {
1596
1763
  if (this.#suppliedPermissions)
1597
1764
  return this.#suppliedPermissions;
1598
- return new PermissionsBitField(this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds) ?? 0n);
1765
+ return new PermissionsBitField(this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds, undefined, this.timedOutUntil) ?? 0n);
1599
1766
  }
1600
1767
  permissionsIn(channelId) {
1601
- const computed = this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds, channelId);
1768
+ const computed = this.#context?.memberPermissions?.(this.guildId, this.user.id, this.roleIds, channelId, this.timedOutUntil);
1602
1769
  return computed ? new PermissionsBitField(computed) : null;
1603
1770
  }
1604
1771
  #action(name) {
@@ -2169,7 +2336,7 @@ class UserManager extends ResourceManager {
2169
2336
  return this.upsert(new User(data));
2170
2337
  }
2171
2338
  async leaveGuild(guildId) {
2172
- await this.#rest.delete(`/users/@me/guilds/${guildId}`);
2339
+ await this.#rest.delete(Routes.currentUserGuild(guildId));
2173
2340
  }
2174
2341
  async createDM(userId) {
2175
2342
  return this.#rest.post("/users/@me/channels", {
@@ -2458,20 +2625,15 @@ class RoleManager extends ResourceManager {
2458
2625
  }
2459
2626
  async create(options) {
2460
2627
  const { reason, ...payload } = options;
2461
- const data = await this.#rest.post(Routes.guildRoles(this.guildId), {
2462
- ...payload,
2463
- permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
2464
- }, { reason });
2465
- const role = new Role(data);
2466
- this.set(role.id, role);
2467
- return role;
2628
+ const data = await this.#rest.post(Routes.guildRoles(this.guildId), rolePayload(payload), { reason });
2629
+ return this.#store(data);
2468
2630
  }
2469
2631
  async edit(roleId, options) {
2470
2632
  const { reason, ...payload } = options;
2471
- const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), {
2472
- ...payload,
2473
- permissions: payload.permissions !== undefined ? String(payload.permissions) : undefined
2474
- }, { reason });
2633
+ const data = await this.#rest.patch(Routes.guildRole(this.guildId, roleId), rolePayload(payload), { reason });
2634
+ return this.#store(data);
2635
+ }
2636
+ #store(data) {
2475
2637
  const role = new Role(data);
2476
2638
  this.set(role.id, role);
2477
2639
  return role;
@@ -2494,6 +2656,13 @@ class RoleManager extends ResourceManager {
2494
2656
  return this.remove(roleId);
2495
2657
  }
2496
2658
  }
2659
+ function rolePayload(options) {
2660
+ const { permissions, ...rest } = options;
2661
+ return {
2662
+ ...rest,
2663
+ permissions: permissions !== undefined ? String(permissions) : undefined
2664
+ };
2665
+ }
2497
2666
 
2498
2667
  // packages/managers/src/guild-resources.ts
2499
2668
  function withQuery2(path, params) {
@@ -3130,7 +3299,7 @@ class ChannelManager extends Manager {
3130
3299
  await this.#rest.delete(`${Routes.messageReactions(channelId, messageId, emoji)}/@me`);
3131
3300
  }
3132
3301
  async removeReaction(channelId, messageId, emoji, userId) {
3133
- await this.#rest.delete(`${Routes.messageReactions(channelId, messageId, emoji)}/${userId}`);
3302
+ await this.#rest.delete(Routes.messageReactionUser(channelId, messageId, emoji, userId));
3134
3303
  }
3135
3304
  async removeAllReactions(channelId, messageId) {
3136
3305
  await this.#rest.delete(Routes.messageReactionsAll(channelId, messageId));
@@ -3202,4 +3371,4 @@ export {
3202
3371
  toRequest
3203
3372
  };
3204
3373
 
3205
- //# debugId=1B8C9372B2A05B6E64756E2164756E21
3374
+ //# debugId=B358201AAE38843564756E2164756E21