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.
- package/README.md +1 -1
- package/dist/builders/commands.d.ts +1 -1
- package/dist/builders/components.d.ts +9 -11
- package/dist/builders/embed.d.ts +1 -1
- package/dist/builders/index.d.ts +1 -1
- package/dist/builders/index.js +87 -1298
- package/dist/builders/index.js.map +3 -11
- package/dist/chunks/index-0wn81eng.js +2492 -0
- package/dist/chunks/index-0wn81eng.js.map +17 -0
- package/dist/chunks/index-2en489j6.js +40 -0
- package/dist/chunks/index-2en489j6.js.map +10 -0
- package/dist/chunks/index-3hyps48a.js +203 -0
- package/dist/chunks/index-3hyps48a.js.map +11 -0
- package/dist/chunks/index-57c5n3ms.js +2274 -0
- package/dist/chunks/index-57c5n3ms.js.map +19 -0
- package/dist/chunks/index-5yx92e36.js +1170 -0
- package/dist/chunks/index-5yx92e36.js.map +14 -0
- package/dist/chunks/index-690bp093.js +95 -0
- package/dist/chunks/index-690bp093.js.map +10 -0
- package/dist/chunks/index-7fp2hvmg.js +2155 -0
- package/dist/chunks/index-7fp2hvmg.js.map +24 -0
- package/dist/chunks/index-cnmsajvk.js +1119 -0
- package/dist/chunks/index-cnmsajvk.js.map +12 -0
- package/dist/chunks/index-fdvgk2sw.js +1310 -0
- package/dist/chunks/index-fdvgk2sw.js.map +21 -0
- package/dist/chunks/index-gyvps8b9.js +214 -0
- package/dist/chunks/index-gyvps8b9.js.map +12 -0
- package/dist/chunks/index-jzg4bh99.js +1533 -0
- package/dist/chunks/index-jzg4bh99.js.map +21 -0
- package/dist/chunks/index-mgw2yvrm.js +3547 -0
- package/dist/chunks/index-mgw2yvrm.js.map +25 -0
- package/dist/chunks/index-yh76b55h.js +3449 -0
- package/dist/chunks/index-yh76b55h.js.map +29 -0
- package/dist/collection/index.js +9 -1118
- package/dist/collection/index.js.map +3 -6
- package/dist/core/api.d.ts +3 -3
- package/dist/core/channel-create.d.ts +2 -2
- package/dist/core/commands.d.ts +3 -3
- package/dist/core/events.d.ts +4 -4
- package/dist/core/handles.d.ts +4 -4
- package/dist/core/index.d.ts +25 -20
- package/dist/core/index.js +68 -10130
- package/dist/core/index.js.map +3 -65
- package/dist/core/permissions.d.ts +1 -1
- package/dist/core/redis-cache.d.ts +1 -1
- package/dist/formatters/index.js +41 -110
- package/dist/formatters/index.js.map +3 -4
- package/dist/handlers/index.js +5 -37
- package/dist/handlers/index.js.map +3 -4
- package/dist/index.d.ts +21 -21
- package/dist/index.js +641 -16325
- package/dist/index.js.map +3 -92
- package/dist/managers/advanced.d.ts +3 -3
- package/dist/managers/application.d.ts +2 -2
- package/dist/managers/base.d.ts +1 -1
- package/dist/managers/emoji.d.ts +2 -2
- package/dist/managers/guild-resources.d.ts +6 -6
- package/dist/managers/guild.d.ts +3 -3
- package/dist/managers/index.d.ts +4 -8
- package/dist/managers/index.js +51 -4060
- package/dist/managers/index.js.map +3 -29
- package/dist/managers/member.d.ts +2 -2
- package/dist/managers/message.d.ts +14 -6
- package/dist/managers/role.d.ts +2 -2
- package/dist/managers/thread.d.ts +3 -3
- package/dist/managers/user.d.ts +7 -4
- package/dist/rest/index.d.ts +10 -35
- package/dist/rest/index.js +57 -2184
- package/dist/rest/index.js.map +3 -18
- package/dist/rest/limiter.d.ts +9 -1
- package/dist/rest/webhook.d.ts +2 -8
- package/dist/sharding/bus.d.ts +2 -2
- package/dist/sharding/cluster.d.ts +45 -5
- package/dist/sharding/context.d.ts +45 -3
- package/dist/sharding/gateway-bot.d.ts +2 -1
- package/dist/sharding/health.d.ts +1 -1
- package/dist/sharding/identify.d.ts +12 -0
- package/dist/sharding/index.d.ts +44 -11
- package/dist/sharding/index.js +60 -4620
- package/dist/sharding/index.js.map +3 -33
- package/dist/sharding/supervisor.d.ts +4 -2
- package/dist/structures/audit-log.d.ts +1 -1
- package/dist/structures/base.d.ts +6 -6
- package/dist/structures/channels.d.ts +1 -1
- package/dist/structures/embed.d.ts +1 -1
- package/dist/structures/index.d.ts +14 -14
- package/dist/structures/index.js +109 -2382
- package/dist/structures/index.js.map +3 -16
- package/dist/structures/interactions.d.ts +13 -9
- package/dist/structures/options.d.ts +1 -1
- package/dist/structures/permissions.d.ts +2 -2
- package/dist/structures/resources.d.ts +10 -10
- package/dist/structures/sticker.d.ts +1 -1
- package/dist/types/gateway.d.ts +2 -79
- package/dist/types/index.d.ts +0 -6
- package/dist/types/index.js +41 -272
- package/dist/types/index.js.map +3 -6
- package/dist/utils/index.js +23 -209
- package/dist/utils/index.js.map +3 -5
- package/dist/voice/connection.d.ts +200 -0
- package/dist/voice/crypto.d.ts +50 -0
- package/dist/voice/dave.d.ts +85 -0
- package/dist/voice/effects.d.ts +31 -0
- package/dist/voice/emitter.d.ts +14 -0
- package/dist/voice/gateway.d.ts +59 -0
- package/dist/voice/index.d.ts +25 -228
- package/dist/voice/index.js +111 -442
- package/dist/voice/index.js.map +3 -4
- package/dist/voice/libopus.d.ts +88 -0
- package/dist/voice/networking.d.ts +80 -0
- package/dist/voice/ogg.d.ts +24 -0
- package/dist/voice/opus.d.ts +18 -0
- package/dist/voice/player.d.ts +79 -0
- package/dist/voice/protocol.d.ts +76 -0
- package/dist/voice/receiver.d.ts +59 -0
- package/dist/voice/resource.d.ts +102 -0
- package/dist/voice/udp.d.ts +40 -0
- package/dist/ws/close-codes.d.ts +1 -1
- package/dist/ws/index.d.ts +25 -4
- package/dist/ws/index.js +47 -1336
- package/dist/ws/index.js.map +3 -17
- package/dist/ws/protocol.d.ts +1 -1
- package/dist/ws/send-budget.d.ts +0 -2
- package/dist/ws/state.d.ts +0 -10
- package/package.json +19 -16
package/dist/collection/index.js
CHANGED
|
@@ -1,1122 +1,13 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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 Collection(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 RedisCollection {
|
|
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 Collection 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] ?? Collection;
|
|
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 Collection;
|
|
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 Collection;
|
|
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
|
-
}
|
|
2
|
+
import {
|
|
3
|
+
Cache2,
|
|
4
|
+
RedisCollection2,
|
|
5
|
+
Collection2
|
|
6
|
+
} from "../chunks/index-cnmsajvk.js";
|
|
1116
7
|
export {
|
|
1117
|
-
Cache,
|
|
1118
|
-
Collection,
|
|
1119
|
-
RedisCollection
|
|
8
|
+
Cache2 as Cache,
|
|
9
|
+
Collection2 as Collection,
|
|
10
|
+
RedisCollection2 as RedisCollection
|
|
1120
11
|
};
|
|
1121
12
|
|
|
1122
|
-
//# debugId=
|
|
13
|
+
//# debugId=694EF185C42CBF7E64756E2164756E21
|