urbi-exhibitions
Version:
2,404 lines • 83.5 kB
JavaScript
import { g as getRouteKey } from "./getRouteKey-BSdUqT6h.js";
import { t as toChunks } from "./toChunks-DRfoi4L8.js";
import { g as getDefaultExportFromCjs } from "./_commonjsHelpers-DaMA6jEr.js";
var parser = {}, hasRequiredParser;
function requireParser() {
return hasRequiredParser || (hasRequiredParser = 1, parser.load = function(t, c, n = {}) {
var a, e, i;
for (a in c)
i = c[a], n[a] = (e = t[a]) != null ? e : i;
return n;
}, parser.overwrite = function(t, c, n = {}) {
var a, e;
for (a in t)
e = t[a], c[a] !== void 0 && (n[a] = e);
return n;
}), parser;
}
var DLList_1, hasRequiredDLList;
function requireDLList() {
if (hasRequiredDLList) return DLList_1;
hasRequiredDLList = 1;
var t;
return t = class {
constructor(n, a) {
this.incr = n, this.decr = a, this._first = null, this._last = null, this.length = 0;
}
push(n) {
var a;
this.length++, typeof this.incr == "function" && this.incr(), a = {
value: n,
prev: this._last,
next: null
}, this._last != null ? (this._last.next = a, this._last = a) : this._first = this._last = a;
}
shift() {
var n;
if (this._first != null)
return this.length--, typeof this.decr == "function" && this.decr(), n = this._first.value, (this._first = this._first.next) != null ? this._first.prev = null : this._last = null, n;
}
first() {
if (this._first != null)
return this._first.value;
}
getArray() {
var n, a, e;
for (n = this._first, e = []; n != null; )
e.push((a = n, n = n.next, a.value));
return e;
}
forEachShift(n) {
var a;
for (a = this.shift(); a != null; )
n(a), a = this.shift();
}
debug() {
var n, a, e, i, r;
for (n = this._first, r = []; n != null; )
r.push((a = n, n = n.next, {
value: a.value,
prev: (e = a.prev) != null ? e.value : void 0,
next: (i = a.next) != null ? i.value : void 0
}));
return r;
}
}, DLList_1 = t, DLList_1;
}
var Events_1, hasRequiredEvents;
function requireEvents() {
if (hasRequiredEvents) return Events_1;
hasRequiredEvents = 1;
function t(a, e, i, r, u, l, v) {
try {
var m = a[l](v), p = m.value;
} catch (s) {
i(s);
return;
}
m.done ? e(p) : Promise.resolve(p).then(r, u);
}
function c(a) {
return function() {
var e = this, i = arguments;
return new Promise(function(r, u) {
var l = a.apply(e, i);
function v(p) {
t(l, r, u, v, m, "next", p);
}
function m(p) {
t(l, r, u, v, m, "throw", p);
}
v(void 0);
});
};
}
var n;
return n = class {
constructor(e) {
if (this.instance = e, this._events = {}, this.instance.on != null || this.instance.once != null || this.instance.removeAllListeners != null)
throw new Error("An Emitter already exists for this object");
this.instance.on = (i, r) => this._addListener(i, "many", r), this.instance.once = (i, r) => this._addListener(i, "once", r), this.instance.removeAllListeners = (i = null) => i != null ? delete this._events[i] : this._events = {};
}
_addListener(e, i, r) {
var u;
return (u = this._events)[e] == null && (u[e] = []), this._events[e].push({
cb: r,
status: i
}), this.instance;
}
listenerCount(e) {
return this._events[e] != null ? this._events[e].length : 0;
}
trigger(e, ...i) {
var r = this;
return c(function* () {
var u, l;
try {
return e !== "debug" && r.trigger("debug", `Event triggered: ${e}`, i), r._events[e] == null ? void 0 : (r._events[e] = r._events[e].filter(function(v) {
return v.status !== "none";
}), l = r._events[e].map(
/* @__PURE__ */ function() {
var v = c(function* (m) {
var p, s;
if (m.status !== "none") {
m.status === "once" && (m.status = "none");
try {
return s = typeof m.cb == "function" ? m.cb(...i) : void 0, typeof (s != null ? s.then : void 0) == "function" ? yield s : s;
} catch (d) {
return p = d, r.trigger("error", p), null;
}
}
});
return function(m) {
return v.apply(this, arguments);
};
}()
), (yield Promise.all(l)).find(function(v) {
return v != null;
}));
} catch (v) {
return u = v, r.trigger("error", u), null;
}
})();
}
}, Events_1 = n, Events_1;
}
var Queues_1, hasRequiredQueues;
function requireQueues() {
if (hasRequiredQueues) return Queues_1;
hasRequiredQueues = 1;
var t, c, n;
return t = requireDLList(), c = requireEvents(), n = class {
constructor(e) {
this.Events = new c(this), this._length = 0, this._lists = (function() {
var i, r, u;
for (u = [], i = 1, r = e; 1 <= r ? i <= r : i >= r; 1 <= r ? ++i : --i)
u.push(new t(() => this.incr(), () => this.decr()));
return u;
}).call(this);
}
incr() {
if (this._length++ === 0)
return this.Events.trigger("leftzero");
}
decr() {
if (--this._length === 0)
return this.Events.trigger("zero");
}
push(e) {
return this._lists[e.options.priority].push(e);
}
queued(e) {
return e != null ? this._lists[e].length : this._length;
}
shiftAll(e) {
return this._lists.forEach(function(i) {
return i.forEachShift(e);
});
}
getFirst(e = this._lists) {
var i, r, u;
for (i = 0, r = e.length; i < r; i++)
if (u = e[i], u.length > 0)
return u;
return [];
}
shiftLastFrom(e) {
return this.getFirst(this._lists.slice(e).reverse()).shift();
}
}, Queues_1 = n, Queues_1;
}
var BottleneckError_1, hasRequiredBottleneckError;
function requireBottleneckError() {
if (hasRequiredBottleneckError) return BottleneckError_1;
hasRequiredBottleneckError = 1;
var t;
return t = class extends Error {
}, BottleneckError_1 = t, BottleneckError_1;
}
var Job_1, hasRequiredJob;
function requireJob() {
if (hasRequiredJob) return Job_1;
hasRequiredJob = 1;
function t(u, l, v, m, p, s, d) {
try {
var o = u[s](d), _ = o.value;
} catch (b) {
v(b);
return;
}
o.done ? l(_) : Promise.resolve(_).then(m, p);
}
function c(u) {
return function() {
var l = this, v = arguments;
return new Promise(function(m, p) {
var s = u.apply(l, v);
function d(_) {
t(s, m, p, d, o, "next", _);
}
function o(_) {
t(s, m, p, d, o, "throw", _);
}
d(void 0);
});
};
}
var n, a, e, i, r;
return i = 10, a = 5, r = requireParser(), n = requireBottleneckError(), e = class {
constructor(l, v, m, p, s, d, o, _) {
this.task = l, this.args = v, this.rejectOnDrop = s, this.Events = d, this._states = o, this.Promise = _, this.options = r.load(m, p), this.options.priority = this._sanitizePriority(this.options.priority), this.options.id === p.id && (this.options.id = `${this.options.id}-${this._randomIndex()}`), this.promise = new this.Promise((b, R) => {
this._resolve = b, this._reject = R;
}), this.retryCount = 0;
}
_sanitizePriority(l) {
var v;
return v = ~~l !== l ? a : l, v < 0 ? 0 : v > i - 1 ? i - 1 : v;
}
_randomIndex() {
return Math.random().toString(36).slice(2);
}
doDrop({
error: l,
message: v = "This job has been dropped by Bottleneck"
} = {}) {
return this._states.remove(this.options.id) ? (this.rejectOnDrop && this._reject(l ?? new n(v)), this.Events.trigger("dropped", {
args: this.args,
options: this.options,
task: this.task,
promise: this.promise
}), !0) : !1;
}
_assertStatus(l) {
var v;
if (v = this._states.jobStatus(this.options.id), !(v === l || l === "DONE" && v === null))
throw new n(`Invalid job status ${v}, expected ${l}. Please open an issue at https://github.com/SGrondin/bottleneck/issues`);
}
doReceive() {
return this._states.start(this.options.id), this.Events.trigger("received", {
args: this.args,
options: this.options
});
}
doQueue(l, v) {
return this._assertStatus("RECEIVED"), this._states.next(this.options.id), this.Events.trigger("queued", {
args: this.args,
options: this.options,
reachedHWM: l,
blocked: v
});
}
doRun() {
return this.retryCount === 0 ? (this._assertStatus("QUEUED"), this._states.next(this.options.id)) : this._assertStatus("EXECUTING"), this.Events.trigger("scheduled", {
args: this.args,
options: this.options
});
}
doExecute(l, v, m, p) {
var s = this;
return c(function* () {
var d, o, _;
s.retryCount === 0 ? (s._assertStatus("RUNNING"), s._states.next(s.options.id)) : s._assertStatus("EXECUTING"), o = {
args: s.args,
options: s.options,
retryCount: s.retryCount
}, s.Events.trigger("executing", o);
try {
if (_ = yield l != null ? l.schedule(s.options, s.task, ...s.args) : s.task(...s.args), v())
return s.doDone(o), yield p(s.options, o), s._assertStatus("DONE"), s._resolve(_);
} catch (b) {
return d = b, s._onFailure(d, o, v, m, p);
}
})();
}
doExpire(l, v, m) {
var p, s;
return this._states.jobStatus(this.options.id === "RUNNING") && this._states.next(this.options.id), this._assertStatus("EXECUTING"), s = {
args: this.args,
options: this.options,
retryCount: this.retryCount
}, p = new n(`This job timed out after ${this.options.expiration} ms.`), this._onFailure(p, s, l, v, m);
}
_onFailure(l, v, m, p, s) {
var d = this;
return c(function* () {
var o, _;
if (m())
return o = yield d.Events.trigger("failed", l, v), o != null ? (_ = ~~o, d.Events.trigger("retry", `Retrying ${d.options.id} after ${_} ms`, v), d.retryCount++, p(_)) : (d.doDone(v), yield s(d.options, v), d._assertStatus("DONE"), d._reject(l));
})();
}
doDone(l) {
return this._assertStatus("EXECUTING"), this._states.next(this.options.id), this.Events.trigger("done", l);
}
}, Job_1 = e, Job_1;
}
var LocalDatastore_1, hasRequiredLocalDatastore;
function requireLocalDatastore() {
if (hasRequiredLocalDatastore) return LocalDatastore_1;
hasRequiredLocalDatastore = 1;
function t(i, r, u, l, v, m, p) {
try {
var s = i[m](p), d = s.value;
} catch (o) {
u(o);
return;
}
s.done ? r(d) : Promise.resolve(d).then(l, v);
}
function c(i) {
return function() {
var r = this, u = arguments;
return new Promise(function(l, v) {
var m = i.apply(r, u);
function p(d) {
t(m, l, v, p, s, "next", d);
}
function s(d) {
t(m, l, v, p, s, "throw", d);
}
p(void 0);
});
};
}
var n, a, e;
return e = requireParser(), n = requireBottleneckError(), a = class {
constructor(r, u, l) {
this.instance = r, this.storeOptions = u, this.clientId = this.instance._randomIndex(), e.load(l, l, this), this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now(), this._running = 0, this._done = 0, this._unblockTime = 0, this.ready = this.Promise.resolve(), this.clients = {}, this._startHeartbeat();
}
_startHeartbeat() {
var r;
return this.heartbeat == null && (this.storeOptions.reservoirRefreshInterval != null && this.storeOptions.reservoirRefreshAmount != null || this.storeOptions.reservoirIncreaseInterval != null && this.storeOptions.reservoirIncreaseAmount != null) ? typeof (r = this.heartbeat = setInterval(() => {
var u, l, v, m, p;
if (m = Date.now(), this.storeOptions.reservoirRefreshInterval != null && m >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval && (this._lastReservoirRefresh = m, this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount, this.instance._drainAll(this.computeCapacity())), this.storeOptions.reservoirIncreaseInterval != null && m >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) {
var s = this.storeOptions;
if (u = s.reservoirIncreaseAmount, v = s.reservoirIncreaseMaximum, p = s.reservoir, this._lastReservoirIncrease = m, l = v != null ? Math.min(u, v - p) : u, l > 0)
return this.storeOptions.reservoir += l, this.instance._drainAll(this.computeCapacity());
}
}, this.heartbeatInterval)).unref == "function" ? r.unref() : void 0 : clearInterval(this.heartbeat);
}
__publish__(r) {
var u = this;
return c(function* () {
return yield u.yieldLoop(), u.instance.Events.trigger("message", r.toString());
})();
}
__disconnect__(r) {
var u = this;
return c(function* () {
return yield u.yieldLoop(), clearInterval(u.heartbeat), u.Promise.resolve();
})();
}
yieldLoop(r = 0) {
return new this.Promise(function(u, l) {
return setTimeout(u, r);
});
}
computePenalty() {
var r;
return (r = this.storeOptions.penalty) != null ? r : 15 * this.storeOptions.minTime || 5e3;
}
__updateSettings__(r) {
var u = this;
return c(function* () {
return yield u.yieldLoop(), e.overwrite(r, r, u.storeOptions), u._startHeartbeat(), u.instance._drainAll(u.computeCapacity()), !0;
})();
}
__running__() {
var r = this;
return c(function* () {
return yield r.yieldLoop(), r._running;
})();
}
__queued__() {
var r = this;
return c(function* () {
return yield r.yieldLoop(), r.instance.queued();
})();
}
__done__() {
var r = this;
return c(function* () {
return yield r.yieldLoop(), r._done;
})();
}
__groupCheck__(r) {
var u = this;
return c(function* () {
return yield u.yieldLoop(), u._nextRequest + u.timeout < r;
})();
}
computeCapacity() {
var r, u, l = this.storeOptions;
return r = l.maxConcurrent, u = l.reservoir, r != null && u != null ? Math.min(r - this._running, u) : r != null ? r - this._running : u ?? null;
}
conditionsCheck(r) {
var u;
return u = this.computeCapacity(), u == null || r <= u;
}
__incrementReservoir__(r) {
var u = this;
return c(function* () {
var l;
return yield u.yieldLoop(), l = u.storeOptions.reservoir += r, u.instance._drainAll(u.computeCapacity()), l;
})();
}
__currentReservoir__() {
var r = this;
return c(function* () {
return yield r.yieldLoop(), r.storeOptions.reservoir;
})();
}
isBlocked(r) {
return this._unblockTime >= r;
}
check(r, u) {
return this.conditionsCheck(r) && this._nextRequest - u <= 0;
}
__check__(r) {
var u = this;
return c(function* () {
var l;
return yield u.yieldLoop(), l = Date.now(), u.check(r, l);
})();
}
__register__(r, u, l) {
var v = this;
return c(function* () {
var m, p;
return yield v.yieldLoop(), m = Date.now(), v.conditionsCheck(u) ? (v._running += u, v.storeOptions.reservoir != null && (v.storeOptions.reservoir -= u), p = Math.max(v._nextRequest - m, 0), v._nextRequest = m + p + v.storeOptions.minTime, {
success: !0,
wait: p,
reservoir: v.storeOptions.reservoir
}) : {
success: !1
};
})();
}
strategyIsBlock() {
return this.storeOptions.strategy === 3;
}
__submit__(r, u) {
var l = this;
return c(function* () {
var v, m, p;
if (yield l.yieldLoop(), l.storeOptions.maxConcurrent != null && u > l.storeOptions.maxConcurrent)
throw new n(`Impossible to add a job having a weight of ${u} to a limiter having a maxConcurrent setting of ${l.storeOptions.maxConcurrent}`);
return m = Date.now(), p = l.storeOptions.highWater != null && r === l.storeOptions.highWater && !l.check(u, m), v = l.strategyIsBlock() && (p || l.isBlocked(m)), v && (l._unblockTime = m + l.computePenalty(), l._nextRequest = l._unblockTime + l.storeOptions.minTime, l.instance._dropAllQueued()), {
reachedHWM: p,
blocked: v,
strategy: l.storeOptions.strategy
};
})();
}
__free__(r, u) {
var l = this;
return c(function* () {
return yield l.yieldLoop(), l._running -= u, l._done += u, l.instance._drainAll(l.computeCapacity()), {
running: l._running
};
})();
}
}, LocalDatastore_1 = a, LocalDatastore_1;
}
var Scripts = {};
const require$$0 = {
"blacklist_client.lua": `local blacklist = ARGV[num_static_argv + 1]
if redis.call('zscore', client_last_seen_key, blacklist) then
redis.call('zadd', client_last_seen_key, 0, blacklist)
end
return {}
`,
"check.lua": `local weight = tonumber(ARGV[num_static_argv + 1])
local capacity = process_tick(now, false)['capacity']
local nextRequest = tonumber(redis.call('hget', settings_key, 'nextRequest'))
return conditions_check(capacity, weight) and nextRequest - now <= 0
`,
"conditions_check.lua": `local conditions_check = function (capacity, weight)
return capacity == nil or weight <= capacity
end
`,
"current_reservoir.lua": `return process_tick(now, false)['reservoir']
`,
"done.lua": `process_tick(now, false)
return tonumber(redis.call('hget', settings_key, 'done'))
`,
"free.lua": `local index = ARGV[num_static_argv + 1]
redis.call('zadd', job_expirations_key, 0, index)
return process_tick(now, false)['running']
`,
"get_time.lua": `redis.replicate_commands()
local get_time = function ()
local time = redis.call('time')
return tonumber(time[1]..string.sub(time[2], 1, 3))
end
`,
"group_check.lua": `return not (redis.call('exists', settings_key) == 1)
`,
"heartbeat.lua": `process_tick(now, true)
`,
"increment_reservoir.lua": `local incr = tonumber(ARGV[num_static_argv + 1])
redis.call('hincrby', settings_key, 'reservoir', incr)
local reservoir = process_tick(now, true)['reservoir']
local groupTimeout = tonumber(redis.call('hget', settings_key, 'groupTimeout'))
refresh_expiration(0, 0, groupTimeout)
return reservoir
`,
"init.lua": `local clear = tonumber(ARGV[num_static_argv + 1])
local limiter_version = ARGV[num_static_argv + 2]
local num_local_argv = num_static_argv + 2
if clear == 1 then
redis.call('del', unpack(KEYS))
end
if redis.call('exists', settings_key) == 0 then
-- Create
local args = {'hmset', settings_key}
for i = num_local_argv + 1, #ARGV do
table.insert(args, ARGV[i])
end
redis.call(unpack(args))
redis.call('hmset', settings_key,
'nextRequest', now,
'lastReservoirRefresh', now,
'lastReservoirIncrease', now,
'running', 0,
'done', 0,
'unblockTime', 0,
'capacityPriorityCounter', 0
)
else
-- Apply migrations
local settings = redis.call('hmget', settings_key,
'id',
'version'
)
local id = settings[1]
local current_version = settings[2]
if current_version ~= limiter_version then
local version_digits = {}
for k, v in string.gmatch(current_version, "([^.]+)") do
table.insert(version_digits, tonumber(k))
end
-- 2.10.0
if version_digits[2] < 10 then
redis.call('hsetnx', settings_key, 'reservoirRefreshInterval', '')
redis.call('hsetnx', settings_key, 'reservoirRefreshAmount', '')
redis.call('hsetnx', settings_key, 'lastReservoirRefresh', '')
redis.call('hsetnx', settings_key, 'done', 0)
redis.call('hset', settings_key, 'version', '2.10.0')
end
-- 2.11.1
if version_digits[2] < 11 or (version_digits[2] == 11 and version_digits[3] < 1) then
if redis.call('hstrlen', settings_key, 'lastReservoirRefresh') == 0 then
redis.call('hmset', settings_key,
'lastReservoirRefresh', now,
'version', '2.11.1'
)
end
end
-- 2.14.0
if version_digits[2] < 14 then
local old_running_key = 'b_'..id..'_running'
local old_executing_key = 'b_'..id..'_executing'
if redis.call('exists', old_running_key) == 1 then
redis.call('rename', old_running_key, job_weights_key)
end
if redis.call('exists', old_executing_key) == 1 then
redis.call('rename', old_executing_key, job_expirations_key)
end
redis.call('hset', settings_key, 'version', '2.14.0')
end
-- 2.15.2
if version_digits[2] < 15 or (version_digits[2] == 15 and version_digits[3] < 2) then
redis.call('hsetnx', settings_key, 'capacityPriorityCounter', 0)
redis.call('hset', settings_key, 'version', '2.15.2')
end
-- 2.17.0
if version_digits[2] < 17 then
redis.call('hsetnx', settings_key, 'clientTimeout', 10000)
redis.call('hset', settings_key, 'version', '2.17.0')
end
-- 2.18.0
if version_digits[2] < 18 then
redis.call('hsetnx', settings_key, 'reservoirIncreaseInterval', '')
redis.call('hsetnx', settings_key, 'reservoirIncreaseAmount', '')
redis.call('hsetnx', settings_key, 'reservoirIncreaseMaximum', '')
redis.call('hsetnx', settings_key, 'lastReservoirIncrease', now)
redis.call('hset', settings_key, 'version', '2.18.0')
end
end
process_tick(now, false)
end
local groupTimeout = tonumber(redis.call('hget', settings_key, 'groupTimeout'))
refresh_expiration(0, 0, groupTimeout)
return {}
`,
"process_tick.lua": `local process_tick = function (now, always_publish)
local compute_capacity = function (maxConcurrent, running, reservoir)
if maxConcurrent ~= nil and reservoir ~= nil then
return math.min((maxConcurrent - running), reservoir)
elseif maxConcurrent ~= nil then
return maxConcurrent - running
elseif reservoir ~= nil then
return reservoir
else
return nil
end
end
local settings = redis.call('hmget', settings_key,
'id',
'maxConcurrent',
'running',
'reservoir',
'reservoirRefreshInterval',
'reservoirRefreshAmount',
'lastReservoirRefresh',
'reservoirIncreaseInterval',
'reservoirIncreaseAmount',
'reservoirIncreaseMaximum',
'lastReservoirIncrease',
'capacityPriorityCounter',
'clientTimeout'
)
local id = settings[1]
local maxConcurrent = tonumber(settings[2])
local running = tonumber(settings[3])
local reservoir = tonumber(settings[4])
local reservoirRefreshInterval = tonumber(settings[5])
local reservoirRefreshAmount = tonumber(settings[6])
local lastReservoirRefresh = tonumber(settings[7])
local reservoirIncreaseInterval = tonumber(settings[8])
local reservoirIncreaseAmount = tonumber(settings[9])
local reservoirIncreaseMaximum = tonumber(settings[10])
local lastReservoirIncrease = tonumber(settings[11])
local capacityPriorityCounter = tonumber(settings[12])
local clientTimeout = tonumber(settings[13])
local initial_capacity = compute_capacity(maxConcurrent, running, reservoir)
--
-- Process 'running' changes
--
local expired = redis.call('zrangebyscore', job_expirations_key, '-inf', '('..now)
if #expired > 0 then
redis.call('zremrangebyscore', job_expirations_key, '-inf', '('..now)
local flush_batch = function (batch, acc)
local weights = redis.call('hmget', job_weights_key, unpack(batch))
redis.call('hdel', job_weights_key, unpack(batch))
local clients = redis.call('hmget', job_clients_key, unpack(batch))
redis.call('hdel', job_clients_key, unpack(batch))
-- Calculate sum of removed weights
for i = 1, #weights do
acc['total'] = acc['total'] + (tonumber(weights[i]) or 0)
end
-- Calculate sum of removed weights by client
local client_weights = {}
for i = 1, #clients do
local removed = tonumber(weights[i]) or 0
if removed > 0 then
acc['client_weights'][clients[i]] = (acc['client_weights'][clients[i]] or 0) + removed
end
end
end
local acc = {
['total'] = 0,
['client_weights'] = {}
}
local batch_size = 1000
-- Compute changes to Zsets and apply changes to Hashes
for i = 1, #expired, batch_size do
local batch = {}
for j = i, math.min(i + batch_size - 1, #expired) do
table.insert(batch, expired[j])
end
flush_batch(batch, acc)
end
-- Apply changes to Zsets
if acc['total'] > 0 then
redis.call('hincrby', settings_key, 'done', acc['total'])
running = tonumber(redis.call('hincrby', settings_key, 'running', -acc['total']))
end
for client, weight in pairs(acc['client_weights']) do
redis.call('zincrby', client_running_key, -weight, client)
end
end
--
-- Process 'reservoir' changes
--
local reservoirRefreshActive = reservoirRefreshInterval ~= nil and reservoirRefreshAmount ~= nil
if reservoirRefreshActive and now >= lastReservoirRefresh + reservoirRefreshInterval then
reservoir = reservoirRefreshAmount
redis.call('hmset', settings_key,
'reservoir', reservoir,
'lastReservoirRefresh', now
)
end
local reservoirIncreaseActive = reservoirIncreaseInterval ~= nil and reservoirIncreaseAmount ~= nil
if reservoirIncreaseActive and now >= lastReservoirIncrease + reservoirIncreaseInterval then
local num_intervals = math.floor((now - lastReservoirIncrease) / reservoirIncreaseInterval)
local incr = reservoirIncreaseAmount * num_intervals
if reservoirIncreaseMaximum ~= nil then
incr = math.min(incr, reservoirIncreaseMaximum - (reservoir or 0))
end
if incr > 0 then
reservoir = (reservoir or 0) + incr
end
redis.call('hmset', settings_key,
'reservoir', reservoir,
'lastReservoirIncrease', lastReservoirIncrease + (num_intervals * reservoirIncreaseInterval)
)
end
--
-- Clear unresponsive clients
--
local unresponsive = redis.call('zrangebyscore', client_last_seen_key, '-inf', (now - clientTimeout))
local unresponsive_lookup = {}
local terminated_clients = {}
for i = 1, #unresponsive do
unresponsive_lookup[unresponsive[i]] = true
if tonumber(redis.call('zscore', client_running_key, unresponsive[i])) == 0 then
table.insert(terminated_clients, unresponsive[i])
end
end
if #terminated_clients > 0 then
redis.call('zrem', client_running_key, unpack(terminated_clients))
redis.call('hdel', client_num_queued_key, unpack(terminated_clients))
redis.call('zrem', client_last_registered_key, unpack(terminated_clients))
redis.call('zrem', client_last_seen_key, unpack(terminated_clients))
end
--
-- Broadcast capacity changes
--
local final_capacity = compute_capacity(maxConcurrent, running, reservoir)
if always_publish or (initial_capacity ~= nil and final_capacity == nil) then
-- always_publish or was not unlimited, now unlimited
redis.call('publish', 'b_'..id, 'capacity:'..(final_capacity or ''))
elseif initial_capacity ~= nil and final_capacity ~= nil and final_capacity > initial_capacity then
-- capacity was increased
-- send the capacity message to the limiter having the lowest number of running jobs
-- the tiebreaker is the limiter having not registered a job in the longest time
local lowest_concurrency_value = nil
local lowest_concurrency_clients = {}
local lowest_concurrency_last_registered = {}
local client_concurrencies = redis.call('zrange', client_running_key, 0, -1, 'withscores')
for i = 1, #client_concurrencies, 2 do
local client = client_concurrencies[i]
local concurrency = tonumber(client_concurrencies[i+1])
if (
lowest_concurrency_value == nil or lowest_concurrency_value == concurrency
) and (
not unresponsive_lookup[client]
) and (
tonumber(redis.call('hget', client_num_queued_key, client)) > 0
) then
lowest_concurrency_value = concurrency
table.insert(lowest_concurrency_clients, client)
local last_registered = tonumber(redis.call('zscore', client_last_registered_key, client))
table.insert(lowest_concurrency_last_registered, last_registered)
end
end
if #lowest_concurrency_clients > 0 then
local position = 1
local earliest = lowest_concurrency_last_registered[1]
for i,v in ipairs(lowest_concurrency_last_registered) do
if v < earliest then
position = i
earliest = v
end
end
local next_client = lowest_concurrency_clients[position]
redis.call('publish', 'b_'..id,
'capacity-priority:'..(final_capacity or '')..
':'..next_client..
':'..capacityPriorityCounter
)
redis.call('hincrby', settings_key, 'capacityPriorityCounter', '1')
else
redis.call('publish', 'b_'..id, 'capacity:'..(final_capacity or ''))
end
end
return {
['capacity'] = final_capacity,
['running'] = running,
['reservoir'] = reservoir
}
end
`,
"queued.lua": `local clientTimeout = tonumber(redis.call('hget', settings_key, 'clientTimeout'))
local valid_clients = redis.call('zrangebyscore', client_last_seen_key, (now - clientTimeout), 'inf')
local client_queued = redis.call('hmget', client_num_queued_key, unpack(valid_clients))
local sum = 0
for i = 1, #client_queued do
sum = sum + tonumber(client_queued[i])
end
return sum
`,
"refresh_expiration.lua": `local refresh_expiration = function (now, nextRequest, groupTimeout)
if groupTimeout ~= nil then
local ttl = (nextRequest + groupTimeout) - now
for i = 1, #KEYS do
redis.call('pexpire', KEYS[i], ttl)
end
end
end
`,
"refs.lua": `local settings_key = KEYS[1]
local job_weights_key = KEYS[2]
local job_expirations_key = KEYS[3]
local job_clients_key = KEYS[4]
local client_running_key = KEYS[5]
local client_num_queued_key = KEYS[6]
local client_last_registered_key = KEYS[7]
local client_last_seen_key = KEYS[8]
local now = tonumber(ARGV[1])
local client = ARGV[2]
local num_static_argv = 2
`,
"register.lua": `local index = ARGV[num_static_argv + 1]
local weight = tonumber(ARGV[num_static_argv + 2])
local expiration = tonumber(ARGV[num_static_argv + 3])
local state = process_tick(now, false)
local capacity = state['capacity']
local reservoir = state['reservoir']
local settings = redis.call('hmget', settings_key,
'nextRequest',
'minTime',
'groupTimeout'
)
local nextRequest = tonumber(settings[1])
local minTime = tonumber(settings[2])
local groupTimeout = tonumber(settings[3])
if conditions_check(capacity, weight) then
redis.call('hincrby', settings_key, 'running', weight)
redis.call('hset', job_weights_key, index, weight)
if expiration ~= nil then
redis.call('zadd', job_expirations_key, now + expiration, index)
end
redis.call('hset', job_clients_key, index, client)
redis.call('zincrby', client_running_key, weight, client)
redis.call('hincrby', client_num_queued_key, client, -1)
redis.call('zadd', client_last_registered_key, now, client)
local wait = math.max(nextRequest - now, 0)
local newNextRequest = now + wait + minTime
if reservoir == nil then
redis.call('hset', settings_key,
'nextRequest', newNextRequest
)
else
reservoir = reservoir - weight
redis.call('hmset', settings_key,
'reservoir', reservoir,
'nextRequest', newNextRequest
)
end
refresh_expiration(now, newNextRequest, groupTimeout)
return {true, wait, reservoir}
else
return {false}
end
`,
"register_client.lua": `local queued = tonumber(ARGV[num_static_argv + 1])
-- Could have been re-registered concurrently
if not redis.call('zscore', client_last_seen_key, client) then
redis.call('zadd', client_running_key, 0, client)
redis.call('hset', client_num_queued_key, client, queued)
redis.call('zadd', client_last_registered_key, 0, client)
end
redis.call('zadd', client_last_seen_key, now, client)
return {}
`,
"running.lua": `return process_tick(now, false)['running']
`,
"submit.lua": `local queueLength = tonumber(ARGV[num_static_argv + 1])
local weight = tonumber(ARGV[num_static_argv + 2])
local capacity = process_tick(now, false)['capacity']
local settings = redis.call('hmget', settings_key,
'id',
'maxConcurrent',
'highWater',
'nextRequest',
'strategy',
'unblockTime',
'penalty',
'minTime',
'groupTimeout'
)
local id = settings[1]
local maxConcurrent = tonumber(settings[2])
local highWater = tonumber(settings[3])
local nextRequest = tonumber(settings[4])
local strategy = tonumber(settings[5])
local unblockTime = tonumber(settings[6])
local penalty = tonumber(settings[7])
local minTime = tonumber(settings[8])
local groupTimeout = tonumber(settings[9])
if maxConcurrent ~= nil and weight > maxConcurrent then
return redis.error_reply('OVERWEIGHT:'..weight..':'..maxConcurrent)
end
local reachedHWM = (highWater ~= nil and queueLength == highWater
and not (
conditions_check(capacity, weight)
and nextRequest - now <= 0
)
)
local blocked = strategy == 3 and (reachedHWM or unblockTime >= now)
if blocked then
local computedPenalty = penalty
if computedPenalty == nil then
if minTime == 0 then
computedPenalty = 5000
else
computedPenalty = 15 * minTime
end
end
local newNextRequest = now + computedPenalty + minTime
redis.call('hmset', settings_key,
'unblockTime', now + computedPenalty,
'nextRequest', newNextRequest
)
local clients_queued_reset = redis.call('hkeys', client_num_queued_key)
local queued_reset = {}
for i = 1, #clients_queued_reset do
table.insert(queued_reset, clients_queued_reset[i])
table.insert(queued_reset, 0)
end
redis.call('hmset', client_num_queued_key, unpack(queued_reset))
redis.call('publish', 'b_'..id, 'blocked:')
refresh_expiration(now, newNextRequest, groupTimeout)
end
if not blocked and not reachedHWM then
redis.call('hincrby', client_num_queued_key, client, 1)
end
return {reachedHWM, blocked, strategy}
`,
"update_settings.lua": `local args = {'hmset', settings_key}
for i = num_static_argv + 1, #ARGV do
table.insert(args, ARGV[i])
end
redis.call(unpack(args))
process_tick(now, true)
local groupTimeout = tonumber(redis.call('hget', settings_key, 'groupTimeout'))
refresh_expiration(0, 0, groupTimeout)
return {}
`,
"validate_client.lua": `if not redis.call('zscore', client_last_seen_key, client) then
return redis.error_reply('UNKNOWN_CLIENT')
end
redis.call('zadd', client_last_seen_key, now, client)
`,
"validate_keys.lua": `if not (redis.call('exists', settings_key) == 1) then
return redis.error_reply('SETTINGS_KEY_NOT_FOUND')
end
`
};
var hasRequiredScripts;
function requireScripts() {
return hasRequiredScripts || (hasRequiredScripts = 1, function(t) {
var c, n, a;
n = require$$0, c = {
refs: n["refs.lua"],
validate_keys: n["validate_keys.lua"],
validate_client: n["validate_client.lua"],
refresh_expiration: n["refresh_expiration.lua"],
process_tick: n["process_tick.lua"],
conditions_check: n["conditions_check.lua"],
get_time: n["get_time.lua"]
}, t.allKeys = function(e) {
return [
/*
HASH
*/
`b_${e}_settings`,
/*
HASH
job index -> weight
*/
`b_${e}_job_weights`,
/*
ZSET
job index -> expiration
*/
`b_${e}_job_expirations`,
/*
HASH
job index -> client
*/
`b_${e}_job_clients`,
/*
ZSET
client -> sum running
*/
`b_${e}_client_running`,
/*
HASH
client -> num queued
*/
`b_${e}_client_num_queued`,
/*
ZSET
client -> last job registered
*/
`b_${e}_client_last_registered`,
/*
ZSET
client -> last seen
*/
`b_${e}_client_last_seen`
];
}, a = {
init: {
keys: t.allKeys,
headers: ["process_tick"],
refresh_expiration: !0,
code: n["init.lua"]
},
group_check: {
keys: t.allKeys,
headers: [],
refresh_expiration: !1,
code: n["group_check.lua"]
},
register_client: {
keys: t.allKeys,
headers: ["validate_keys"],
refresh_expiration: !1,
code: n["register_client.lua"]
},
blacklist_client: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client"],
refresh_expiration: !1,
code: n["blacklist_client.lua"]
},
heartbeat: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client", "process_tick"],
refresh_expiration: !1,
code: n["heartbeat.lua"]
},
update_settings: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client", "process_tick"],
refresh_expiration: !0,
code: n["update_settings.lua"]
},
running: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client", "process_tick"],
refresh_expiration: !1,
code: n["running.lua"]
},
queued: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client"],
refresh_expiration: !1,
code: n["queued.lua"]
},
done: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client", "process_tick"],
refresh_expiration: !1,
code: n["done.lua"]
},
check: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client", "process_tick", "conditions_check"],
refresh_expiration: !1,
code: n["check.lua"]
},
submit: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client", "process_tick", "conditions_check"],
refresh_expiration: !0,
code: n["submit.lua"]
},
register: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client", "process_tick", "conditions_check"],
refresh_expiration: !0,
code: n["register.lua"]
},
free: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client", "process_tick"],
refresh_expiration: !0,
code: n["free.lua"]
},
current_reservoir: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client", "process_tick"],
refresh_expiration: !1,
code: n["current_reservoir.lua"]
},
increment_reservoir: {
keys: t.allKeys,
headers: ["validate_keys", "validate_client", "process_tick"],
refresh_expiration: !0,
code: n["increment_reservoir.lua"]
}
}, t.names = Object.keys(a), t.keys = function(e, i) {
return a[e].keys(i);
}, t.payload = function(e) {
var i;
return i = a[e], Array.prototype.concat(c.refs, i.headers.map(function(r) {
return c[r];
}), i.refresh_expiration ? c.refresh_expiration : "", i.code).join(`
`);
};
}(Scripts)), Scripts;
}
var RedisConnection_1, hasRequiredRedisConnection;
function requireRedisConnection() {
if (hasRequiredRedisConnection) return RedisConnection_1;
hasRequiredRedisConnection = 1;
function asyncGeneratorStep(t, c, n, a, e, i, r) {
try {
var u = t[i](r), l = u.value;
} catch (v) {
n(v);
return;
}
u.done ? c(l) : Promise.resolve(l).then(a, e);
}
function _asyncToGenerator(t) {
return function() {
var c = this, n = arguments;
return new Promise(function(a, e) {
var i = t.apply(c, n);
function r(l) {
asyncGeneratorStep(i, a, e, r, u, "next", l);
}
function u(l) {
asyncGeneratorStep(i, a, e, r, u, "throw", l);
}
r(void 0);
});
};
}
var Events, RedisConnection, Scripts, parser;
return parser = requireParser(), Events = requireEvents(), Scripts = requireScripts(), RedisConnection = (function() {
class RedisConnection {
constructor(options = {}) {
parser.load(options, this.defaults, this), this.Redis == null && (this.Redis = eval("require")("redis")), this.Events == null && (this.Events = new Events(this)), this.terminated = !1, this.client == null && (this.client = this.Redis.createClient(this.clientOptions)), this.subscriber = this.client.duplicate(), this.limiters = {}, this.shas = {}, this.ready = this.Promise.all([this._setup(this.client, !1), this._setup(this.subscriber, !0)]).then(() => this._loadScripts()).then(() => ({
client: this.client,
subscriber: this.subscriber
}));
}
_setup(t, c) {
return t.setMaxListeners(0), new this.Promise((n, a) => (t.on("error", (e) => this.Events.trigger("error", e)), c && t.on("message", (e, i) => {
var r;
return (r = this.limiters[e]) != null ? r._store.onMessage(e, i) : void 0;
}), t.ready ? n() : t.once("ready", n)));
}
_loadScript(t) {
return new this.Promise((c, n) => {
var a;
return a = Scripts.payload(t), this.client.multi([["script", "load", a]]).exec((e, i) => e != null ? n(e) : (this.shas[t] = i[0], c(i[0])));
});
}
_loadScripts() {
return this.Promise.all(Scripts.names.map((t) => this._loadScript(t)));
}
__runCommand__(t) {
var c = this;
return _asyncToGenerator(function* () {
return yield c.ready, new c.Promise((n, a) => c.client.multi([t]).exec_atomic(function(e, i) {
return e != null ? a(e) : n(i[0]);
}));
})();
}
__addLimiter__(t) {
return this.Promise.all([t.channel(), t.channel_client()].map((c) => new this.Promise((n, a) => {
var e;
return e = (i) => {
if (i === c)
return this.subscriber.removeListener("subscribe", e), this.limiters[c] = t, n();
}, this.subscriber.on("subscribe", e), this.subscriber.subscribe(c);
})));
}
__removeLimiter__(t) {
var c = this;
return this.Promise.all([t.channel(), t.channel_client()].map(
/* @__PURE__ */ function() {
var n = _asyncToGenerator(function* (a) {
return c.terminated || (yield new c.Promise((e, i) => c.subscriber.unsubscribe(a, function(r, u) {
if (r != null)
return i(r);
if (u === a)
return e();
}))), delete c.limiters[a];
});
return function(a) {
return n.apply(this, arguments);
};
}()
));
}
__scriptArgs__(t, c, n, a) {
var e;
return e = Scripts.keys(t, c), [this.shas[t], e.length].concat(e, n, a);
}
__scriptFn__(t) {
return this.client.evalsha.bind(this.client);
}
disconnect(t = !0) {
var c, n, a, e;
for (e = Object.keys(this.limiters), c = 0, a = e.length; c < a; c++)
n = e[c], clearInterval(this.limiters[n]._store.heartbeat);
return this.limiters = {}, this.terminated = !0, this.client.end(t), this.subscriber.end(t), this.Promise.resolve();
}
}
return RedisConnection.prototype.datastore = "redis", RedisConnection.prototype.defaults = {
Redis: null,
clientOptions: {},
client: null,
Promise,
Events: null
}, RedisConnection;
}).call(void 0), RedisConnection_1 = RedisConnection, RedisConnection_1;
}
var IORedisConnection_1, hasRequiredIORedisConnection;
function requireIORedisConnection() {
if (hasRequiredIORedisConnection) return IORedisConnection_1;
hasRequiredIORedisConnection = 1;
function _slicedToArray(t, c) {
return _arrayWithHoles(t) || _iterableToArrayLimit(t, c) || _nonIterableRest();
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
function _iterableToArrayLimit(t, c) {
var n = [], a = !0, e = !1, i = void 0;
try {
for (var r = t[Symbol.iterator](), u; !(a = (u = r.next()).done) && (n.push(u.value), !(c && n.length === c)); a = !0)
;
} catch (l) {
e = !0, i = l;
} finally {
try {
!a && r.return != null && r.return();
} finally {
if (e) throw i;
}
}
return n;
}
function _arrayWithHoles(t) {
if (Array.isArray(t)) return t;
}
function asyncGeneratorStep(t, c, n, a, e, i, r) {
try {
var u = t[i](r), l = u.value;
} catch (v) {
n(v);
return;
}
u.done ? c(l) : Promise.resolve(l).then(a, e);
}
function _asyncToGenerator(t) {
return function() {
var c = this, n = arguments;
return new Promise(function(a, e) {
var i = t.apply(c, n);
function r(l) {
asyncGeneratorStep(i, a, e, r, u, "next", l);
}
function u(l) {
asyncGeneratorStep(i, a, e, r, u, "throw", l);
}
r(void 0);
});
};
}
var Events, IORedisConnection, Scripts, parser;
return parser = requireParser(), Events = requireEvents(), Scripts = requireScripts(), IORedisConnection = (function() {
class IORedisConnection {
constructor(options = {}) {
parser.load(options, this.defaults, this), this.Redis == null && (this.Redis = eval("require")("ioredis")), this.Events == null && (this.Events = new Events(this)), this.terminated = !1, this.clusterNodes != null ? (this.client = new this.Redis.Cluster(this.clusterNodes, this.clientOptions), this.subscriber = new this.Redis.Cluster(this.clusterNodes, this.clientOptions)) : this.client != null && this.client.duplicate == null ? this.subscriber = new this.Redis.Cluster(this.client.startupNodes, this.client.options) : (this.client == null && (this.client = new this.Redis(this.clientOptions)), this.subscriber = this.client.duplicate()), this.limiters = {}, this.ready = this.Promise.all([this._setup(this.client, !1), this._setup(this.subscriber, !0)]).then(() => (this._loadScripts(), {
client: this.client,
subscriber: this.subscriber
}));
}
_setup(t, c) {
return t.setMaxListeners(0), new this.Promise((n, a) => (t.on("error", (e) => this.Events.trigger("error", e)), c && t.on("message", (e, i) => {
var r;
return (r = this.limiters[e]) != null ? r._store.onMessage(e, i) : void 0;
}), t.status === "ready" ? n() : t.once("ready", n)));
}
_loadScripts() {
return Scripts.names.forEach((t) => this.client.defineCommand(t, {
lua: Scripts.payload(t)
}));
}
__runCommand__(t) {
var c = this;
return _asyncToGenerator(function* () {
var n;
yield c.ready;
var a = yield c.client.pipeline([t]).exec(), e = _slicedToArray(a, 1), i = _slicedToArray(e[0], 2);
return i[0], n = i[1], n;
})();
}
__addLimiter__(t) {
return this.Promise.all([t.channel(), t.channel_client()].map((c) => new this.Promise((n, a) => this.subscriber.subscribe(c, () => (this.limiters[c] = t, n())))));
}
__removeLimiter__(t) {
var c = this;
return [t.channel(), t.channel_client()].forEach(
/* @__PURE__ */ function() {
var n = _asyncToGenerator(function* (a) {
return c.terminated || (yield c.subscriber.unsubscribe(a)), delete c.limiters[a];
});
return function(a) {
return n.apply(this, arguments);
};
}()
);
}
__scriptArgs__(t, c, n, a) {
var e;
return e = Scripts.keys(t, c), [e.length].concat(e, n, a);
}
__scriptFn__(t) {
return this.client[t].bind(this.client);
}
disconnect(t = !0) {
var c, n, a, e;
for (e = Object.keys(this.limiters), c = 0, a = e.length; c < a; c++)
n = e[c], clearInterval(this.limiters[n]._store.heartbeat);
return this.limiters = {}, this.terminated = !0, t ? this.Promise.all([this.client.quit(), this.subscriber.quit()]) : (this.client.disconnect(), this.subscriber.disconnect(), this.Promise.resolve());
}
}
return IORedisConnection.prototype.datastore = "ioredis", IORedisConnection.prototype.defaults = {
Redis: null,
clientOptions: {},
clusterNodes: null,
client: null,
Promise,
Events: null
}, IORedisConnection;
}).call(void 0), IORedisConnection_1 = IORedisConnection, IORedisConnection_1;
}
var RedisDatastore_1, hasRequiredRedisDatastore;
function requireRedisDatastore() {
if (hasRequiredRedisDatastore) return RedisDatastore_1;
hasRequiredRedisDatastore = 1;
function t(p, s) {
return a(p) || n(p, s) || c();
}
function c() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
function n(p, s) {
var d = [], o = !0, _ = !1, b = void 0;
try {
for (var R = p[Symbol.iterator](), x; !(o = (x = R.next()).done) && (d.push(x.value), !(s && d.length === s)); o = !0)
;
} catch (E) {
_ = !0, b = E;
} finally {
try {
!o && R.return != null && R.return();
} finally {
if (_) throw b;
}
}
return d;
}
function a(p) {
if (Array.isArray(p)) return p;
}
function e(p, s, d, o, _, b, R) {
try {
var x = p[b](R), E = x.value;
} catch (f) {
d(f);
return;
}
x.done ? s(E) : Promise.resolve(E).then(o, _);
}
function i(p) {
return function() {
var s = this, d = arguments;
return new Promise(function(o, _) {
var b = p.apply(s, d);
function R(E) {
e(b, o, _, R, x, "next", E);
}
function x(E) {
e(b, o, _, R, x, "throw", E);
}
R(void 0);
});
};
}
var r, u, l, v, m;
return m = requireParser(), r = requireBottleneckError(), l = requireRedisConnection(), u = requireIORedisConnection(), v = class {
constructor(s, d, o) {
this.instance = s, this.storeOptions = d, this.originalId = this.instance.id, this.clientId = this.instance._randomIndex(), m.load(o, o, this), this.clients = {}, this.capacityPriorityCounters = {}, this.sharedConnection = this.connection != null, this.connection == null && (this.connection = this.instance.datastore === "redis" ? new l({
Redis: this.Redis,
clientOptions: this.clientOptions,
Promise: this.Promise,
Events: this.instance.Events
}) : this.instance.datastore === "ioredis" ? new u({
Redis: this.Redis,
clientOptions: this.clientOptions,
clusterNodes: this.clusterNodes,
Promise: this.Promise,
Events: this.instance.Events
}) : void 0), this.instance.connection = this.connection, this.instance.datastore = this.connection.datastore, this.ready = this.connection.ready.then((_) => (this.clients = _, this.runScript("init", this.prepareInitSettings(this.clearDatastore)))).then(() => this.connection.__addLimiter__(this.instance)).then(() => this.runScript("register_client", [this.instance.queued()])).then(() => {
var _;
return typeof (_ = this.heartbeat = setInterval(() => this.runScript("heartbeat", []).catch((b) => this.instance.Events.trigger("error", b)), this.heartbeatInterval)).unref == "function" && _.unref(), this.clients;
});
}
__publish__(s) {
var d = this;
return i(function* () {
var o, _ = yield d.ready;
return o = _.client, o.publish(d.instance.channel(), `message:${s.toString()}`);
})();
}
onMessage(s, d) {
var o = this;
return i(function* () {
var _, b, R, x, E, f, I, h, y, k;
try {
I = d.indexOf(":");
var w = [d.slice(0, I), d.slice(I + 1)];
if (k = w[0], R = w[1], k === "capacity")
return yield o.instance._drainAll(R.length > 0 ? ~~R : void 0);
if (k === "capacity-priority") {
var g = R.split(":"), q = t(g, 3);
return y = q[0], h = q[1], b = q[2], _ = y.length > 0 ? ~~y : void 0, h === o.clientId ? (x = yield o.instance._drainAll(_), f = _ != null ? _ - (x || 0) : "", yield o.clients.client.publish(o.instance.channel(), `capacity-priority:${f}::${b}`)) : h === "" ? (clearTimeout(o.capacityPriorityCounters[b]), delete o.capacityPriorityCounters[b], o.instance._drainAll(_)) : o.capacityPriorityCounters[b] = setTimeout(
/* @__PURE__ */ i(function* () {
var S;
try {
return delete o.capacityPriorityCounters[b], yield o.runScript("blacklist_client", [h]), yield o.instance._drainAll(_);
} catch (C) {
return S = C, o.instance.Events.trigger("error", S);
}
}),
1e3
);
} else {
if (k === "message")
return o.instance.Events.trigger("message", R);
if (k === "blocked")
return yield o.instance._dropAllQueued();
}
} catch (S) {
return E = S, o.instance.Events.trigger("error", E);
}
})();
}
__disconnect__(s) {
return clearInterval(this.heartbeat), this.sharedConnection ? this.connection.__removeLimiter__(this.instance) : this.connection.disconnect(s);
}
runScript(s, d) {
var o = this;
return i(function* () {
return s === "init" || s === "register_client" || (yield o.ready), new o.Promise((_, b) => {
var R, x;
return R = [Date.now(), o.clientId].concat(d), o.instance.Events.trigger("debug", `Calling Redis script: ${s}.lua`, R), x = o.connection.__scriptArgs__(s, o.originalId, R, function(E, f) {
return E != null ? b(E) : _(f);
}), o.connection.__scriptFn__(s)(...x);
}).catch((_) => _.message === "SETTINGS_KEY_NOT_FOUND" ? s === "heartbeat" ? o.Promise.resolve() : o.runScript("init", o.prepareInitSettings(!1)).then(() => o.runScript(s, d)) : _.message === "UNKNOWN_CLIENT" ? o.runScript("register_client", [o.instance.queued()]).then(() => o.runScript(s, d)) : o.Promise.reject(_));
})();
}
prepareArray(s) {
var d, o, _, b;
for (_ = [], d = 0, o = s.length; d < o; d++)
b = s[d], _.push(b != null ? b.toString() : "");
return _;
}
prepareObject(s) {
var d, o, _;
d = [];
for (o in s)
_ = s[o], d.push(o, _ != null ? _.toString() : "");
return d;
}
prepareInitSettings(s) {
var d;
return d = this.prepareObject(Object.assign({}, this.storeOptions, {
id: this.originalId,
version: this.instance.version,
groupTimeout: this.timeout,
clientTimeout: this.clientTimeout
})), d.unshift(s ? 1 : 0, this.instance.version), d;
}
convertBool(s) {
return !!s;
}
__updateSettings__(s) {
var d = this;
return i(function* () {
return yield d.runScript("update_settings", d.prepareObject(s)), m.overwrite(s, s, d.storeOptions);
})();
}
__running__() {
return this.runScript("running", []);
}
__queued__() {
return this.runScript("queued", []);
}
__done__() {
return this.runScript("done", []);
}
__groupCheck__() {
var s = this;
return i(function* () {
return s.convertBool(yield s.runScript("group_check", []));
})();
}
__incrementReservoir__(s) {
return this.runScript("increment_reservoir", [s]);
}
__currentReservoir__() {
return this.runScript("current_reservoir", []);
}
__check__(s) {
var d = this;
return i(function* () {
return d.convertBool(yield d.runScript("check", d.prepareArray([s])));
})();
}
__register__(s, d, o) {
var _ = this;
return i(function* () {
var b, R, x, E = yield _.runScript("register", _.prepareArray([s, d, o])), f = t(E, 3);
return R = f[0], x = f[1], b = f[2], {
success: _.convertBool(R),
wait: x,
reservoir: b
};
})();
}
__submit__(s, d) {
var o = this;
return i(function* () {
var _, b, R, x, E;
try {
var f = yield o.runScript("submit", o.prepareArray([s, d])), I = t(f, 3);
return x = I[0], _ = I[1], E = I[2], {
reachedHWM: o.convertBool(x),
blocked: o.convertBool(_),
strategy: E
};
} catch (k) {
if (b = k, b.message.indexOf("OVERWEIGHT") === 0) {
var h = b.message.split(":"), y = t(h, 3);
throw y[0], d = y[1], R = y[2], new r(`Impossible to add a job having a weight of ${d} to a limiter having a maxConcurrent setting of ${R}`);
} else
throw b;
}
})();
}
__free__(s, d) {
var o = this;
return i(function* () {
var _;
return _ = yield o.runScript("free", o.prepareArray([s])), {
running: _
};
})();
}
}, RedisDatastore_1 = v, RedisDatastore_1;
}
var States_1, hasRequiredStates;
function requireStates() {
if (hasRequiredStates) return States_1;
hasRequiredStates = 1;
var t, c;
return t = requireBottleneckError(), c = class {
constructor(a) {
this.status = a, this._jobs = {}, this.counts = this.status.map(function() {
return 0;
});
}
next(a) {
var e, i;
if (e = this._jobs[a], i = e + 1, e != null && i < this.status.length)
return this.counts[e]--, this.counts[i]++, this._jobs[a]++;
if (e != null)
return this.counts[e]--, delete this._jobs[a];
}
start(a) {
var e;
return e = 0, this._jobs[a] = e, this.counts[e]++;
}
remove(a) {
var e;
return e = this._jobs[a], e != null && (this.counts[e]--, delete this._jobs[a]), e != null;
}
jobStatus(a) {
var e;
return (e = this.status[this._jobs[a]]) != null ? e : null;
}
statusJobs(a) {
var e, i, r, u, l;
if (a != null) {
if (i = this.status.indexOf(a), i < 0)
throw new t(`status must be one of ${this.status.join(", ")}`);
r = this._jobs, u = [];
for (e in r)
l = r[e], l === i && u.push(e);
return u;
} else
return Object.keys(this._jobs);
}
statusCounts() {
return this.counts.reduce((a, e, i) => (a[this.status[i]] = e, a), {});
}
}, States_1 = c, States_1;
}
var Sync_1, hasRequiredSync;
function requireSync() {
if (hasRequiredSync) return Sync_1;
hasRequiredSync = 1;
function t(e, i, r, u, l, v, m) {
try {
var p = e[v](m), s = p.value;
} catch (d) {
r(d);
return;
}
p.done ? i(s) : Promise.resolve(s).then(u, l);
}
function c(e) {
return function() {
var i = this, r = arguments;
return new Promise(function(u, l) {
var v = e.apply(i, r);
function m(s) {
t(v, u, l, m, p, "next", s);
}
function p(s) {
t(v, u, l, m, p, "throw", s);
}
m(void 0);
});
};
}
var n, a;
return n = requireDLList(), a = class {
constructor(i, r) {
this.schedule = this.schedule.bind(this), this.name = i, this.Promise = r, this._running = 0, this._queue = new n();
}
isEmpty() {
return this._queue.length === 0;
}
_tryToRun() {
var i = this;
return c(function* () {
var r, u, l, v, m, p, s;
if (i._running < 1 && i._queue.length > 0) {
i._running++;
var d = i._queue.shift();
return s = d.task, r = d.args, m = d.resolve, v = d.reject, u = yield c(function* () {
try {
return p = yield s(...r), function() {
return m(p);
};
} catch (o) {
return l = o, function() {
return v(l);
};
}
})(), i._running--, i._tryToRun(), u();
}
})();
}
schedule(i, ...r) {
var u, l, v;
return v = l = null, u = new this.Promise(function(m, p) {
return v = m, l = p;
}), this._queue.push({
task: i,
args: r,
resolve: v,
reject: l
}), this._tryToRun(), u;
}
}, Sync_1 = a, Sync_1;
}
const version = "2.19.5", require$$8 = {
version
};
var Group_1, hasRequiredGroup;
function requireGroup() {
if (hasRequiredGroup) return Group_1;
hasRequiredGroup = 1;
function t(s, d) {
return a(s) || n(s, d) || c();
}
function c() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
function n(s, d) {
var o = [], _ = !0, b = !1, R = void 0;
try {
for (var x = s[Symbol.iterator](), E; !(_ = (E = x.next()).done) && (o.push(E.value), !(d && o.length === d)); _ = !0)
;
} catch (f) {
b = !0, R = f;
} finally {
try {
!_ && x.return != null && x.return();
} finally {
if (b) throw R;
}
}
return o;
}
function a(s) {
if (Array.isArray(s)) return s;
}
function e(s, d, o, _, b, R, x) {
try {
var E = s[R](x), f = E.value;
} catch (I) {
o(I);
return;
}
E.done ? d(f) : Promise.resolve(f).then(_, b);
}
function i(s) {
return function() {
var d = this, o = arguments;
return new Promise(function(_, b) {
var R = s.apply(d, o);
function x(f) {
e(R, _, b, x, E, "next", f);
}
function E(f) {
e(R, _, b, x, E, "throw", f);
}
x(void 0);
});
};
}
var r, u, l, v, m, p;
return p = requireParser(), r = requireEvents(), v = requireRedisConnection(), l = requireIORedisConnection(), m = requireScripts(), u = (function() {
class s {
constructor(o = {}) {
this.deleteKey = this.deleteKey.bind(this), this.limiterOptions = o, p.load(this.limiterOptions, this.defaults, this), this.Events = new r(this), this.instances = {}, this.Bottleneck = requireBottleneck(), this._startAutoCleanup(), this.sharedConnection = this.connection != null, this.connection == null && (this.limiterOptions.datastore === "redis" ? this.connection = new v(Object.assign({}, this.limiterOptions, {
Events: this.Events
})) : this.limiterOptions.datastore === "ioredis" && (this.connection = new l(Object.assign({}, this.limiterOptions, {
Events: this.Events
}))));
}
key(o = "") {
var _;
return (_ = this.instances[o]) != null ? _ : (() => {
var b;
return b = this.instances[o] = new this.Bottleneck(Object.assign(this.limiterOptions, {
id: `${this.id}-${o}`,
timeout: this.timeout,
connection: this.connection
})), this.Events.trigger("created", b, o), b;
})();
}
deleteKey(o = "") {
var _ = this;
return i(function* () {
var b, R;
return R = _.instances[o], _.connection && (b = yield _.connection.__runCommand__(["del", ...m.allKeys(`${_.id}-${o}`)])), R != null && (delete _.instances[o], yield R.disconnect()), R != null || b > 0;
})();
}
limiters() {
var o, _, b, R;
_ = this.instances, b = [];
for (o in _)
R = _[o], b.push({
key: o,
limiter: R
});
return b;
}
keys() {
return Object.keys(this.instances);
}
clusterKeys() {
var o = this;
return i(function* () {
var _, b, R, x, E, f, I, h, y;
if (o.connection == null)
return o.Promise.resolve(o.keys());
for (f = [], _ = null, y = `b_${o.id}-`.length, b = 9; _ !== 0; ) {
var k = yield o.connection.__runCommand__(["scan", _ ?? 0, "match", `b_${o.id}-*_settings`, "count", 1e4]), w = t(k, 2);
for (h = w[0], R = w[1], _ = ~~h, x = 0, I = R.length; x < I; x++)
E = R[x], f.push(E.slice(y, -b));
}
return f;
})();
}
_startAutoCleanup() {
var o = this, _;
return clearInterval(this.interval), typeof (_ = this.interval = setInterval(
/* @__PURE__ */ i(function* () {
var b, R, x, E, f, I;
f = Date.now(), x = o.instances, E = [];
for (R in x) {
I = x[R];
try {
(yield I._store.__groupCheck__(f)) ? E.push(o.deleteKey(R)) : E.push(void 0);
} catch (h) {
b = h, E.push(I.Events.trigger("error", b));
}
}
return E;
}),
this.timeout / 2
)).unref == "function" ? _.unref() : void 0;
}
updateSettings(o = {}) {
if (p.overwrite(o, this.defaults, this), p.overwrite(o, o, this.limiterOptions), o.timeout != null)
return this._startAutoCleanup();
}
disconnect(o = !0) {
var _;
if (!this.sharedConnection)
return (_ = this.connection) != null ? _.disconnect(o) : void 0;
}
}
return s.prototype.defaults = {
timeout: 1e3 * 60 * 5,
connection: null,
Promise,
id: "group-key"
}, s;
}).call(void 0), Group_1 = u, Group_1;
}
var Batcher_1, hasRequiredBatcher;
function requireBatcher() {
if (hasRequiredBatcher) return Batcher_1;
hasRequiredBatcher = 1;
var t, c, n;
return n = requireParser(), c = requireEvents(), t = (function() {
class a {
constructor(i = {}) {
this.options = i, n.load(this.options, this.defaults, this), this.Events = new c(this), this._arr = [], this._resetPromise(), this._lastFlush = Date.now();
}
_resetPromise() {
return this._promise = new this.Promise((i, r) => this._resolve = i);
}
_flush() {
return clearTimeout(this._timeout), this._lastFlush = Date.now(), this._resolve(), this.Events.trigger("batch", this._arr), this._arr = [], this._resetPromise();
}
add(i) {
var r;
return this._arr.push(i), r = this._promise, this._arr.length === this.maxSize ? this._flush() : this.maxTime != null && this._arr.length === 1 && (this._timeout = setTimeout(() => this._flush(), this.maxTime)), r;
}
}
return a.prototype.defaults = {
maxTime: null,
maxSize: null,
Promise
}, a;
}).call(void 0), Batcher_1 = t, Batcher_1;
}
var Bottleneck_1, hasRequiredBottleneck;
function requireBottleneck() {
if (hasRequiredBottleneck) return Bottleneck_1;
hasRequiredBottleneck = 1;
function t(f, I) {
return i(f) || c(f, I) || a();
}
function c(f, I) {
var h = [], y = !0, k = !1, w = void 0;
try {
for (var g = f[Symbol.iterator](), q; !(y = (q = g.next()).done) && (h.push(q.value), !(I && h.length === I)); y = !0)
;
} catch (S) {
k = !0, w = S;
} finally {
try {
!y && g.return != null && g.return();
} finally {
if (k) throw w;
}
}
return h;
}
function n(f) {
return i(f) || e(f) || a();
}
function a() {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
function e(f) {
if (Symbol.iterator in Object(f) || Object.prototype.toString.call(f) === "[object Arguments]") return Array.from(f);
}
function i(f) {
if (Array.isArray(f)) return f;
}
function r(f, I, h, y, k, w, g) {
try {
var q = f[w](g), S = q.value;
} catch (C) {
h(C);
return;
}
q.done ? I(S) : Promise.resolve(S).then(y, k);
}
function u(f) {
return function() {
var I = this, h = arguments;
return new Promise(function(y, k) {
var w = f.apply(I, h);
function g(S) {
r(w, y, k, g, q, "next", S);
}
function q(S) {
r(w, y, k, g, q, "throw", S);
}
g(void 0);
});
};
}
var l, v, m, p, s, d, o, _, b, R, x, E = [].splice;
return d = 10, v = 5, x = requireParser(), o = requireQueues(), p = requireJob(), s = requireLocalDatastore(), _ = requireRedisDatastore(), m = requireEvents(), b = requireStates(), R = requireSync(), l = (function() {
class f {
constructor(h = {}, ...y) {
var k, w;
this._addToQueue = this._addToQueue.bind(this), this._validateOptions(h, y), x.load(h, this.instanceDefaults, this), this._queues = new o(d), this._scheduled = {}, this._states = new b(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])), this._limiter = null, this.Events = new m(this), this._submitLock = new R("submit", this.Promise), this._registerLock = new R("register", this.Promise), w = x.load(h, this.storeDefaults, {}), this._store = (function() {
if (this.datastore === "redis" || this.datastore === "ioredis" || this.connection != null)
return k = x.load(h, this.redisStoreDefaults, {}), new _(this, w, k);
if (this.datastore === "local")
return k = x.load(h, this.localStoreDefaults, {}), new s(this, w, k);
throw new f.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`);
}).call(this), this._queues.on("leftzero", () => {
var g;
return (g = this._store.heartbeat) != null && typeof g.ref == "function" ? g.ref() : void 0;
}), this._queues.on("zero", () => {
var g;
return (g = this._store.heartbeat) != null && typeof g.unref == "function" ? g.unref() : void 0;
});
}
_validateOptions(h, y) {
if (!(h != null && typeof h == "object" && y.length === 0))
throw new f.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1.");
}
ready() {
return this._store.ready;
}
clients() {
return this._store.clients;
}
channel() {
return `b_${this.id}`;
}
channel_client() {
return `b_${this.id}_${this._store.clientId}`;
}
publish(h) {
return this._store.__publish__(h);
}
disconnect(h = !0) {
return this._store.__disconnect__(h);
}
chain(h) {
return this._limiter = h, this;
}
queued(h) {
return this._queues.queued(h);
}
clusterQueued() {
return this._store.__queued__();
}
empty() {
return this.queued() === 0 && this._submitLock.isEmpty();
}
running() {
return this._store.__running__();
}
done() {
return this._store.__done__();
}
jobStatus(h) {
return this._states.jobStatus(h);
}
jobs(h) {
return this._states.statusJobs(h);
}
counts() {
return this._states.statusCounts();
}
_randomIndex() {
return Math.random().toString(36).slice(2);
}
check(h = 1) {
return this._store.__check__(h);
}
_clearGlobalState(h) {
return this._scheduled[h] != null ? (clearTimeout(this._scheduled[h].expiration), delete this._scheduled[h], !0) : !1;
}
_free(h, y, k, w) {
var g = this;
return u(function* () {
var q, S;
try {
var C = yield g._store.__free__(h, k.weight);
if (S = C.running, g.Events.trigger("debug", `Freed ${k.id}`, w), S === 0 && g.empty())
return g.Events.trigger("idle");
} catch (O) {
return q = O, g.Events.trigger("error", q);
}
})();
}
_run(h, y, k) {
var w, g, q;
return y.doRun(), w = this._clearGlobalState.bind(this, h), q = this._run.bind(this, h, y), g = this._free.bind(this, h, y), this._scheduled[h] = {
timeout: setTimeout(() => y.doExecute(this._limiter, w, q, g), k),
expiration: y.options.expiration != null ? setTimeout(function() {
return y.doExpire(w, q, g);
}, k + y.options.expiration) : void 0,
job: y
};
}
_drainOne(h) {
return this._registerLock.schedule(() => {
var y, k, w, g, q;
if (this.queued() === 0)
return this.Promise.resolve(null);
q = this._queues.getFirst();
var S = w = q.first();
return g = S.options, y = S.args, h != null && g.weight > h ? this.Promise.resolve(null) : (this.Events.trigger("debug", `Draining ${g.id}`, {
args: y,
options: g
}), k = this._randomIndex(), this._store.__register__(k, g.weight, g.expiration).then(({
success: C,
wait: O,
reservoir: P
}) => {
var T;
return this.Events.trigger("debug", `Drained ${g.id}`, {
success: C,
args: y,
options: g
}), C ? (q.shift(), T = this.empty(), T && this.Events.trigger("empty"), P === 0 && this.Events.trigger("depleted", T), this._run(k, w, O), this.Promise.resolve(g.weight)) : this.Promise.resolve(null);
}));
});
}
_drainAll(h, y = 0) {
return this._drainOne(h).then((k) => {
var w;
return k != null ? (w = h != null ? h - k : h, this._drainAll(w, y + k)) : this.Promise.resolve(y);
}).catch((k) => this.Events.trigger("error", k));
}
_dropAllQueued(h) {
return this._queues.shiftAll(function(y) {
return y.doDrop({
message: h
});
});
}
stop(h = {}) {
var y, k;
return h = x.load(h, this.stopDefaults), k = (w) => {
var g;
return g = () => {
var q;
return q = this._states.counts, q[0] + q[1] + q[2] + q[3] === w;
}, new this.Promise((q, S) => g() ? q() : this.on("done", () => {
if (g())
return this.removeAllListeners("done"), q();
}));
}, y = h.dropWaitingJobs ? (this._run = function(w, g) {
return g.doDrop({
message: h.dropErrorMessage
});
}, this._drainOne = () => this.Promise.resolve(null), this._registerLock.schedule(() => this._submitLock.schedule(() => {
var w, g, q;
g = this._scheduled;
for (w in g)
q = g[w], this.jobStatus(q.job.options.id) === "RUNNING" && (clearTimeout(q.timeout), clearTimeout(q.expiration), q.job.doDrop({
message: h.dropErrorMessage
}));
return this._dropAllQueued(h.dropErrorMessage), k(0);
}))) : this.schedule({
priority: d - 1,
weight: 0
}, () => k(1)), this._receive = function(w) {
return w._reject(new f.prototype.BottleneckError(h.enqueueErrorMessage));
}, this.stop = () => this.Promise.reject(new f.prototype.BottleneckError("stop() has already been called")), y;
}
_addToQueue(h) {
var y = this;
return u(function* () {
var k, w, g, q, S, C, O;
k = h.args, q = h.options;
try {
var P = yield y._store.__submit__(y.queued(), q.weight);
S = P.reachedHWM, w = P.blocked, O = P.strategy;
} catch (T) {
return g = T, y.Events.trigger("debug", `Could not queue ${q.id}`, {
args: k,
options: q,
error: g
}), h.doDrop({
error: g
}), !1;
}
return w ? (h.doDrop(), !0) : S && (C = O === f.prototype.strategy.LEAK ? y._queues.shiftLastFrom(q.priority) : O === f.prototype.strategy.OVERFLOW_PRIORITY ? y._queues.shiftLastFrom(q.priority + 1) : O === f.prototype.strategy.OVERFLOW ? h : void 0, C != null && C.doDrop(), C == null || O === f.prototype.strategy.OVERFLOW) ? (C == null && h.doDrop(), S) : (h.doQueue(S, w), y._queues.push(h), yield y._drainAll(), S);
})();
}
_receive(h) {
return this._states.jobStatus(h.options.id) != null ? (h._reject(new f.prototype.BottleneckError(`A job with the same id already exists (id=${h.options.id})`)), !1) : (h.doReceive(), this._submitLock.schedule(this._addToQueue, h));
}
submit(...h) {
var y, k, w, g, q, S, C;
if (typeof h[0] == "function") {
var O, P, T, j;
q = h, O = q, P = n(O), k = P[0], h = P.slice(1), T = E.call(h, -1), j = t(T, 1), y = j[0], g = x.load({}, this.jobDefaults);
} else {
var D, L, G, B;
S = h, D = S, L = n(D), g = L[0], k = L[1], h = L.slice(2), G = E.call(h, -1), B = t(G, 1), y = B[0], g = x.load(g, this.jobDefaults);
}
return C = (...A) => new this.Promise(function(K, M) {
return k(...A, function(...N) {
return (N[0] != null ? M : K)(N);
});
}), w = new p(C, h, g, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise), w.promise.then(function(A) {
return typeof y == "function" ? y(...A) : void 0;
}).catch(function(A) {
return Array.isArray(A) ? typeof y == "function" ? y(...A) : void 0 : typeof y == "function" ? y(A) : void 0;
}), this._receive(w);
}
schedule(...h) {
var y, k, w;
if (typeof h[0] == "function") {
var g = h, q = n(g);
w = q[0], h = q.slice(1), k = {};
} else {
var S = h, C = n(S);
k = C[0], w = C[1], h = C.slice(2);
}
return y = new p(w, h, k, this.jobDefaults, this.rejectOnDrop, this.Events, this._states, this.Promise), this._receive(y), y.promise;
}
wrap(h) {
var y, k;
return y = this.schedule.bind(this), k = function(...g) {
return y(h.bind(this), ...g);
}, k.withOptions = function(w, ...g) {
return y(w, h, ...g);
}, k;
}
updateSettings(h = {}) {
var y = this;
return u(function* () {
return yield y._store.__updateSettings__(x.overwrite(h, y.storeDefaults)), x.overwrite(h, y.instanceDefaults, y), y;
})();
}
currentReservoir() {
return this._store.__currentReservoir__();
}
incrementReservoir(h = 0) {
return this._store.__incrementReservoir__(h);
}
}
return f.default = f, f.Events = m, f.version = f.prototype.version = require$$8.version, f.strategy = f.prototype.strategy = {
LEAK: 1,
OVERFLOW: 2,
OVERFLOW_PRIORITY: 4,
BLOCK: 3
}, f.BottleneckError = f.prototype.BottleneckError = requireBottleneckError(), f.Group = f.prototype.Group = requireGroup(), f.RedisConnection = f.prototype.RedisConnection = requireRedisConnection(), f.IORedisConnection = f.prototype.IORedisConnection = requireIORedisConnection(), f.Batcher = f.prototype.Batcher = requireBatcher(), f.prototype.jobDefaults = {
priority: v,
weight: 1,
expiration: null,
id: "<no-id>"
}, f.prototype.storeDefaults = {
maxConcurrent: null,
minTime: 0,
highWater: null,
strategy: f.prototype.strategy.LEAK,
penalty: null,
reservoir: null,
reservoirRefreshInterval: null,
reservoirRefreshAmount: null,
reservoirIncreaseInterval: null,
reservoirIncreaseAmount: null,
reservoirIncreaseMaximum: null
}, f.prototype.localStoreDefaults = {
Promise,
timeout: null,
heartbeatInterval: 250
}, f.prototype.redisStoreDefaults = {
Promise,
timeout: null,
heartbeatInterval: 5e3,
clientTimeout: 1e4,
Redis: null,
clientOptions: {},
clusterNodes: null,
clearDatastore: !1,
connection: null
}, f.prototype.instanceDefaults = {
datastore: "local",
connection: null,
id: "<no-id>",
rejectOnDrop: !0,
trackDoneStatus: !1,
Promise
}, f.prototype.stopDefaults = {
enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.",
dropWaitingJobs: !0,
dropErrorMessage: "This limiter has been stopped."
}, f;
}).call(void 0), Bottleneck_1 = l, Bottleneck_1;
}
var lib, hasRequiredLib;
function requireLib() {
return hasRequiredLib || (hasRequiredLib = 1, lib = requireBottleneck()), lib;
}
var libExports = requireLib();
const Bottleneck = /* @__PURE__ */ getDefaultExportFromCjs(libExports);
function promisifyRequest(t) {
return new Promise((c, n) => {
t.oncomplete = t.onsuccess = () => c(t.result), t.onabort = t.onerror = () => n(t.error);
});
}
function createStore(t, c) {
const n = indexedDB.open(t);
n.onupgradeneeded = () => n.result.createObjectStore(c);
const a = promisifyRequest(n);
return (e, i) => a.then((r) => i(r.transaction(c, e).objectStore(c)));
}
let defaultGetStoreFunc;
function defaultGetStore() {
return defaultGetStoreFunc || (defaultGetStoreFunc = createStore("keyval-store", "keyval")), defaultGetStoreFunc;
}
function get(t, c = defaultGetStore()) {
return c("readonly", (n) => promisifyRequest(n.get(t)));
}
function set(t, c, n = defaultGetStore()) {
return n("readwrite", (a) => (a.put(c, t), promisifyRequest(a.transaction)));
}
function clear(t = defaultGetStore()) {
return t("readwrite", (c) => (c.clear(), promisifyRequest(c.transaction)));
}
const routesCache = createStore("navigation-db", "routes-cache"), getRouteStringKey = (t) => `route_${JSON.stringify(t)}`, prefetchRoutes = async (t) => {
const {
routes: c,
chunkSize: n = 100,
maxConcurrent: a = 10,
maxRequestsPerMinute: e = 2e3,
maxRequestsPerSecond: i,
onProgress: r,
getRoute: u
} = t, l = new Bottleneck({
reservoir: e,
reservoirRefreshAmount: e,
reservoirRefreshInterval: 60 * 1e3,
maxConcurrent: a
});
if (i) {
const s = new Bottleneck({
reservoir: i,
reservoirRefreshInterval: 1e3,
reservoirRefreshAmount: i,
maxConcurrent: a
});
l.chain(s);
}
const v = c.length;
let m = 0;
const p = toChunks(c, n);
await Promise.all(
p.map(async (s) => {
await Promise.all(
s.map(
(d) => l.schedule(async () => {
const o = await u(d);
if (o) {
const _ = getRouteStringKey(getRouteKey(d));
await set(_, o, routesCache);
}
m += 1, r == null || r(m, v);
})
)
);
})
);
}, clearRoutesCache = async () => clear(routesCache), getRouteCache = async (t) => get(getRouteStringKey(t), routesCache);
export {
getRouteCache as a,
clearRoutesCache as c,
getRouteStringKey as g,
prefetchRoutes as p,
routesCache as r
};