UNPKG

lakutata

Version:

An IoC-based universal application framework.

681 lines (660 loc) 19.4 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const e = require("@redis/client"); const t = require("./Package.65.cjs"); const r = require("cluster-key-slot"); require("buffer"); const s = e => e && e.__esModule ? e : { default: e }; const i = s(r); var n = class { _eventListeners; _maxListeners; _logger; constructor(e) { this._eventListeners = new Map, this._maxListeners = 100, this._logger = e?.logger; } once(e, t) { let r = (...s) => { this.off(e, r), t(...s); }; return this.on(e, r), this; } listenerCount(e) { if (!e) return this.getAllListeners().length; let t = this._eventListeners.get(e); return t ? t.length : 0; } eventNames() { return [ ...this._eventListeners.keys() ]; } rawListeners(e) { return e ? this._eventListeners.get(e) ?? [] : this.getAllListeners(); } prependListener(e, t) { let r = this._eventListeners.get(e) ?? []; return r.unshift(t), this._eventListeners.set(e, r), this; } prependOnceListener(e, t) { let r = (...s) => { this.off(e, r), t(...s); }; return this.prependListener(e, r), this; } maxListeners() { return this._maxListeners; } addListener(e, t) { return this.on(e, t), this; } on(e, t) { this._eventListeners.has(e) || this._eventListeners.set(e, []); let r = this._eventListeners.get(e); return r && (r.length >= this._maxListeners && console.warn(`MaxListenersExceededWarning: Possible event memory leak detected. ${r.length + 1} ${e} listeners added. Use setMaxListeners() to increase limit.`), r.push(t)), this; } removeListener(e, t) { return this.off(e, t), this; } off(e, t) { let r = this._eventListeners.get(e) ?? [], s = r.indexOf(t); return s !== -1 && r.splice(s, 1), r.length === 0 && this._eventListeners.delete(e), this; } emit(e, ...t) { let r = !1, s = this._eventListeners.get(e); if (s && s.length > 0) for (let e of s) e(...t), r = !0; return r; } listeners(e) { return this._eventListeners.get(e) ?? []; } removeAllListeners(e) { return e ? this._eventListeners.delete(e) : this._eventListeners.clear(), this; } setMaxListeners(e) { this._maxListeners = e; for (let t of this._eventListeners.values()) t.length > e && t.splice(e); } getAllListeners() { let e = new Array; for (let t of this._eventListeners.values()) e = [ ...e, ...t ]; return e; } }; var o = class extends n { _hooks; _throwHookErrors=!1; constructor(e) { super({ logger: e?.logger }), this._hooks = new Map, e?.throwHookErrors !== void 0 && (this._throwHookErrors = e.throwHookErrors); } get hooks() { return this._hooks; } get throwHookErrors() { return this._throwHookErrors; } set throwHookErrors(e) { this._throwHookErrors = e; } get logger() { return this._logger; } set logger(e) { this._logger = e; } onHook(e, t) { let r = this._hooks.get(e); r ? r.push(t) : this._hooks.set(e, [ t ]); } addHook(e, t) { this.onHook(e, t); } onHooks(e) { for (let t of e) this.onHook(t.event, t.handler); } prependHook(e, t) { let r = this._hooks.get(e); r ? r.unshift(t) : this._hooks.set(e, [ t ]); } prependOnceHook(e, t) { let r = async (...s) => (this.removeHook(e, r), t(...s)); this.prependHook(e, r); } onceHook(e, t) { let r = async (...s) => (this.removeHook(e, r), t(...s)); this.onHook(e, r); } removeHook(e, t) { let r = this._hooks.get(e); if (r) { let e = r.indexOf(t); e !== -1 && r.splice(e, 1); } } removeHooks(e) { for (let t of e) this.removeHook(t.event, t.handler); } async hook(e, ...t) { let r = this._hooks.get(e); if (r) for (let s of r) try { await s(...t); } catch (t) { let r = `${e}: ${t.message}`; if (this.emit("error", new Error(r)), this._logger && this._logger.error(r), this._throwHookErrors) throw new Error(r); } } async callHook(e, ...t) { await this.hook(e, ...t); } getHooks(e) { return this._hooks.get(e); } clearHooks() { this._hooks.clear(); } }; var a = (e => { e["RedisClientNotConnectedThrown"] = "Redis client is not connected or has failed to connect. This is thrown because throwOnConnectError is set to true."; return e; })(a || {}); var c = e => { const t = Math.min(2 ** e * 100, 2e3); const r = (Math.random() - .5) * 100; return t + r; }; var h = class extends o { _client=e.createClient(); _namespace; _keyPrefixSeparator="::"; _clearBatchSize=1e3; _useUnlink=true; _noNamespaceAffectsAll=false; _throwOnConnectError=true; _throwErrors=false; _connectionTimeout; constructor(t, r) { super(); const s = { reconnectStrategy: c }; if (t) { if (typeof t === "string") { this._client = e.createClient({ url: t, socket: s }); } else if (t.connect !== void 0) { this._client = this.isClientCluster(t) ? t : t; } else if (t instanceof Object) { this._client = t.rootNodes === void 0 ? e.createClient(t) : e.createCluster(t); } } this.setOptions(r); this.initClient(); } get client() { return this._client; } set client(e) { this._client = e; this.initClient(); } get opts() { let e = "redis://localhost:6379"; if (this._client.options) { const t = this._client.options?.url; if (t) { e = t; } } const t = { namespace: this._namespace, keyPrefixSeparator: this._keyPrefixSeparator, clearBatchSize: this._clearBatchSize, noNamespaceAffectsAll: this._noNamespaceAffectsAll, useUnlink: this._useUnlink, throwOnConnectError: this._throwOnConnectError, throwErrors: this._throwErrors, connectionTimeout: this._connectionTimeout, dialect: "redis", url: e }; return t; } set opts(e) { this.setOptions(e); } get namespace() { return this._namespace; } set namespace(e) { this._namespace = e; } get keyPrefixSeparator() { return this._keyPrefixSeparator; } set keyPrefixSeparator(e) { this._keyPrefixSeparator = e; } get clearBatchSize() { return this._clearBatchSize; } set clearBatchSize(e) { if (e > 0) { this._clearBatchSize = e; } else { this.emit("error", "clearBatchSize must be greater than 0"); } } get useUnlink() { return this._useUnlink; } set useUnlink(e) { this._useUnlink = e; } get noNamespaceAffectsAll() { return this._noNamespaceAffectsAll; } set noNamespaceAffectsAll(e) { this._noNamespaceAffectsAll = e; } get throwOnConnectError() { return this._throwOnConnectError; } set throwOnConnectError(e) { this._throwOnConnectError = e; } get throwErrors() { return this._throwErrors; } set throwErrors(e) { this._throwErrors = e; } get connectionTimeout() { return this._connectionTimeout; } set connectionTimeout(e) { this._connectionTimeout = e; } async getClient() { if (this._client.isOpen) { return this._client; } try { if (this._connectionTimeout === void 0) { await this._client.connect(); } else { await Promise.race([ this._client.connect(), this.createTimeoutPromise(this._connectionTimeout) ]); } } catch (e) { this.emit("error", e); if (this._throwOnConnectError) { throw new Error("Redis client is not connected or has failed to connect. This is thrown because throwOnConnectError is set to true."); } await this.disconnect(true); } this.initClient(); return this._client; } async set(e, t, r) { const s = await this.getClient(); try { e = this.createKeyPrefix(e, this._namespace); if (r) { await s.set(e, t, { PX: r }); } else { await s.set(e, t); } } catch (e) { this.emit("error", e); if (this._throwErrors) { throw e; } } } async setMany(e) { const t = await this.getClient(); try { const r = t.multi(); for (const {key: t, value: s, ttl: i} of e) { const e = this.createKeyPrefix(t, this._namespace); if (i) { r.set(e, s, { PX: i }); } else { r.set(e, s); } } await r.exec(); } catch (e) { this.emit("error", e); if (this._throwErrors) { throw e; } } } async has(e) { const t = await this.getClient(); try { e = this.createKeyPrefix(e, this._namespace); const r = await t.exists(e); return r === 1; } catch (e) { this.emit("error", e); if (this._throwErrors) { throw e; } return false; } } async hasMany(e) { const t = await this.getClient(); try { const r = t.multi(); for (const t of e) { const e = this.createKeyPrefix(t, this._namespace); r.exists(e); } const s = await r.exec(); return s.map((e => e === 1)); } catch (t) { this.emit("error", t); if (this._throwErrors) { throw t; } return Array.from({ length: e.length }).fill(false); } } async get(e) { const t = await this.getClient(); try { e = this.createKeyPrefix(e, this._namespace); const r = await t.get(e); if (r === null) { return void 0; } return r; } catch (e) { this.emit("error", e); if (this._throwErrors) { throw e; } return void 0; } } async getMany(e) { if (e.length === 0) { return []; } e = e.map((e => this.createKeyPrefix(e, this._namespace))); try { const t = await this.mget(e); return t; } catch (t) { this.emit("error", t); if (this._throwErrors) { throw t; } return Array.from({ length: e.length }).fill(void 0); } } async delete(e) { const t = await this.getClient(); try { e = this.createKeyPrefix(e, this._namespace); let r = 0; r = await (this._useUnlink ? t.unlink(e) : t.del(e)); return r > 0; } catch (e) { this.emit("error", e); if (this._throwErrors) { throw e; } return false; } } async deleteMany(e) { let t = false; const r = await this.getClient(); try { const s = r.multi(); for (const t of e) { const e = this.createKeyPrefix(t, this._namespace); if (this._useUnlink) { s.unlink(e); } else { s.del(e); } } const i = await s.exec(); for (const e of i) { if (typeof e === "number" && e > 0) { t = true; } } } catch (e) { this.emit("error", e); if (this._throwErrors) { throw e; } } return t; } async disconnect(e) { if (this._client.isOpen) { await (e ? this._client.disconnect() : this._client.quit()); } } createKeyPrefix(e, t) { if (t) { return `${t}${this._keyPrefixSeparator}${e}`; } return e; } getKeyWithoutPrefix(e, t) { if (t) { return e.replace(`${t}${this._keyPrefixSeparator}`, ""); } return e; } isCluster() { return this.isClientCluster(this._client); } async getMasterNodes() { if (this.isCluster()) { const e = await this.getClient(); return Promise.all(e.masters.map((async t => e.nodeClient(t)))); } return [ await this.getClient() ]; } async* iterator(e) { const t = await this.getMasterNodes(); for (const r of t) { const t = e ? `${e}${this._keyPrefixSeparator}*` : "*"; let s = "0"; do { const i = await r.scan(Number.parseInt(s, 10), { MATCH: t, TYPE: "string" }); s = i.cursor.toString(); let {keys: n} = i; if (!e && !this._noNamespaceAffectsAll) { n = n.filter((e => !e.includes(this._keyPrefixSeparator))); } if (n.length > 0) { const t = await this.mget(n); for (const r of n.keys()) { const s = this.getKeyWithoutPrefix(n[r], e); const i = t[r]; yield [ s, i ]; } } } while (s !== "0"); } } async clear() { try { const e = await this.getMasterNodes(); await Promise.all(e.map((async e => { if (!this._namespace && this._noNamespaceAffectsAll) { await e.flushDb(); return; } let t = "0"; const r = this._clearBatchSize; const s = this._namespace ? `${this._namespace}${this._keyPrefixSeparator}*` : "*"; const i = []; do { const n = await e.scan(Number.parseInt(t, 10), { MATCH: s, COUNT: r, TYPE: "string" }); t = n.cursor.toString(); let {keys: o} = n; if (o.length === 0) { continue; } if (!this._namespace) { o = o.filter((e => !e.includes(this._keyPrefixSeparator))); } i.push(this.clearWithClusterSupport(o)); } while (t !== "0"); await Promise.all(i); }))); } catch (e) { this.emit("error", e); } } async mget(e) { const t = this.getSlotMap(e); const r = new Map; await Promise.all(Array.from(t.entries(), (async ([e, t]) => { const s = await this.getSlotMaster(e); const i = await s.mGet(t); for (const [e, s] of i.entries()) { r.set(t[e], s ?? void 0); } }))); return e.map((e => r.get(e))); } async clearWithClusterSupport(e) { if (e.length > 0) { const t = this.getSlotMap(e); await Promise.all(Array.from(t.entries(), (async ([e, t]) => { const r = await this.getSlotMaster(e); return this._useUnlink ? r.unlink(t) : r.del(t); }))); } } async getSlotMaster(e) { const t = await this.getClient(); if (this.isCluster()) { const r = t; const s = r.slots[e].master; return r.nodeClient(s); } return t; } getSlotMap(e) { const t = new Map; if (this.isCluster()) { for (const r of e) { const e = i.default(r); const s = t.get(e) ?? []; s.push(r); t.set(e, s); } } else { t.set(0, e); } return t; } isClientCluster(e) { if (e.options === void 0 && e.scan === void 0) { return true; } return false; } setOptions(e) { if (!e) { return; } if (e.namespace) { this._namespace = e.namespace; } if (e.keyPrefixSeparator !== void 0) { this._keyPrefixSeparator = e.keyPrefixSeparator; } if (e.clearBatchSize !== void 0 && e.clearBatchSize > 0) { this._clearBatchSize = e.clearBatchSize; } if (e.useUnlink !== void 0) { this._useUnlink = e.useUnlink; } if (e.noNamespaceAffectsAll !== void 0) { this._noNamespaceAffectsAll = e.noNamespaceAffectsAll; } if (e.throwOnConnectError !== void 0) { this._throwOnConnectError = e.throwOnConnectError; } if (e.throwErrors !== void 0) { this._throwErrors = e.throwErrors; } if (e.connectionTimeout !== void 0) { this._connectionTimeout = e.connectionTimeout; } } initClient() { this._client.on("connect", (() => { this.emit("connect", this._client); })); this._client.on("disconnect", (() => { this.emit("disconnect", this._client); })); this._client.on("reconnecting", (e => { this.emit("reconnecting", e); })); } async createTimeoutPromise(e) { return new Promise(((t, r) => setTimeout((() => { r(new Error(`Redis timed out after ${e}ms`)); }), e))); } }; function l(e, r) { e ??= "redis://localhost:6379"; const s = new h(e, r); const i = new t.Keyv(s, { namespace: r?.namespace, useKeyPrefix: false }); return i; } Object.defineProperty(exports, "createClient", { enumerable: true, get: () => e.createClient }); Object.defineProperty(exports, "createCluster", { enumerable: true, get: () => e.createCluster }); exports.Keyv = t.Keyv; exports.RedisErrorMessages = a; exports.createKeyv = l; exports.default = h; exports.defaultReconnectStrategy = c;