'use strict'; var node_events = require('node:events'); var ioredis = require('ioredis'); class Watcher extends node_events.EventEmitter { on(event, listener) { return super.on(event, listener); } /* istanbul ignore next */ async start() { if (this.subscriberClient) { return; } const subscriber = this.client.duplicate(); await subscriber.config('SET', 'notify-keyspace-events', 'KA'); await subscriber.psubscribe(...this.subscribePatterns); subscriber.on('error', (error)=>{ this.emit('error', error); }); subscriber.on('pmessage', (_pattern, _channel, event)=>{ if (this.subscribePatterns.indexOf(_pattern) === -1) { return; } if (!_channel.startsWith('__keyspace')) { return; } const key = _channel.split('__:').pop(); if (key && key.length > 0) { this.emit(event, key); } }); this.subscriberClient = subscriber; } /* istanbul ignore next */ async stop() { if (!this.subscriberClient) return; await this.subscriberClient.punsubscribe(...this.subscribePatterns); this.subscriberClient.disconnect(); this.subscriberClient = undefined; } //-------------------------------------------------------------------- constructor(client, options = {}){ super(); this.client = client; this.options = options; let patterns; if (this.options.pattern) { if (Array.isArray(this.options.pattern)) { patterns = this.options.pattern.map((pattern)=>`__key*__:${pattern}`); } else { patterns = [ `__key*__:${this.options.pattern}` ]; } } else { patterns = [ '__key*__:*' ]; } this.subscribePatterns = patterns; } } /* * Copyright (c) 2023. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ function buildConfigWithDefaults(input) { input = input || {}; input.options = { enableReadyCheck: true, retryStrategy (times) { /* istanbul ignore next */ return times === 3 ? null : Math.min(times * 50, 2000); }, reconnectOnError (error) { /* istanbul ignore next */ return error.message.includes('ECONNRESET'); } }; return buildConfig(input); } function buildConfig(input) { input = input || {}; return { ...input, clusterNodes: input.clusterNodes || [], clusterOptions: input.clusterOptions || {}, options: input.options || {} }; } const getAlias$2 = (alias)=>alias || 'default'; const instances$2 = {}; function setConfig(value, alias) { alias = getAlias$2(alias); instances$2[alias] = buildConfig(value); } function hasConfig(alias) { alias = getAlias$2(alias); return Object.prototype.hasOwnProperty.call(instances$2, alias); } function useConfig(alias) { alias = getAlias$2(alias); if (Object.prototype.hasOwnProperty.call(instances$2, alias)) { return instances$2[alias]; } return buildConfigWithDefaults(); } function unsetConfig(alias) { alias = getAlias$2(alias); if (Object.prototype.hasOwnProperty.call(instances$2, alias)) { delete instances$2[alias]; } } const getAlias$1 = (key)=>key || 'default'; const instances$1 = {}; function useClient(alias) { alias = getAlias$1(alias); if (Object.prototype.hasOwnProperty.call(instances$1, alias)) { return instances$1[alias]; } const config = useConfig(alias); instances$1[alias] = createClient(config); return instances$1[alias]; } function unsetClient(alias) { alias = getAlias$1(alias); if (Object.prototype.hasOwnProperty.call(instances$1, alias)) { instances$1[alias].disconnect(); delete instances$1[alias]; } } function hasClient(alias) { alias = getAlias$1(alias); return Object.prototype.hasOwnProperty.call(instances$1, alias); } function setClient(value, alias) { alias = getAlias$1(alias); instances$1[alias] = value; return instances$1[alias]; } function createClient(config) { config = config || {}; if (config.connectionString && config.options) { return new ioredis.Redis(config.connectionString, config.options); } if (config.options) { return new ioredis.Redis(config.options); } if (config.connectionString) { return new ioredis.Redis(config.connectionString); } return new ioredis.Redis(); } const getAlias = (alias)=>alias || 'default'; const instances = {}; function useCluster(alias) { alias = getAlias(alias); const config = useConfig(alias); if (Object.prototype.hasOwnProperty.call(instances, alias)) { return instances[alias]; } instances[alias] = createCluster(config); return instances[alias]; } function setCluster(value, alias) { alias = getAlias(alias); instances[alias] = value; return instances[alias]; } function hasCluster(alias) { alias = getAlias(alias); return Object.prototype.hasOwnProperty.call(instances, alias); } function createCluster(input) { const config = buildConfig(input); let nodes = []; if (config.clusterNodes) { nodes = config.clusterNodes; } if (nodes.length === 0 && config.connectionString) { nodes = [ config.connectionString ]; } return new ioredis.Cluster(nodes, config.clusterOptions); } /* * Copyright (c) 2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ class JsonAdapter { async set(key, value, options = {}) { let milliseconds; if (options.milliseconds) { milliseconds = options.milliseconds; } else if (options.seconds) { milliseconds = options.seconds * 1000; } /* istanbul ignore next */ if (options.keepTTL) { if (options.ifExists) { await this.client.set(key, JSON.stringify(value), 'KEEPTTL', 'XX'); } else if (options.ifNotExists) { await this.client.set(key, JSON.stringify(value), 'KEEPTTL', 'NX'); } else { await this.client.set(key, JSON.stringify(value), 'KEEPTTL'); } return; } if (milliseconds) { if (options.ifExists) { await this.client.set(key, JSON.stringify(value), 'PX', milliseconds, 'XX'); } else if (options.ifNotExists) { await this.client.set(key, JSON.stringify(value), 'PX', milliseconds, 'NX'); } else { await this.client.set(key, JSON.stringify(value), 'PX', milliseconds); } return; } await this.client.set(key, JSON.stringify(value)); } async get(key) { try { const entry = await this.client.get(key); if (entry === null || typeof entry === 'undefined') { return undefined; } return JSON.parse(entry); } catch (e) { /* istanbul ignore next */ return undefined; } } async drop(key) { return await this.client.del(key) === 1; } constructor(client){ this.client = client; } } /* * Copyright (c) 2024-2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ function escapeKey(input) { return input.replace(/([*?[\]\\])/g, '\\$1'); } /* * Copyright (c) 2024. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ exports.KeyPathSeparator = void 0; (function(KeyPathSeparator) { KeyPathSeparator["PREFIX"] = "#p#"; KeyPathSeparator["SUFFIX"] = "#s#"; })(exports.KeyPathSeparator || (exports.KeyPathSeparator = {})); function buildKeyPath(options) { const parts = []; if (options.prefix) { parts.push(options.prefix); parts.push(exports.KeyPathSeparator.PREFIX); } parts.push(options.key); if (options.suffix) { parts.push(exports.KeyPathSeparator.SUFFIX); parts.push(options.suffix); } return parts.join(''); } function parseKeyPath(keyPath) { keyPath = keyPath.replace(/\s/g, ''); let prefix; let suffix; const prefixSeparatorIndex = keyPath.indexOf(exports.KeyPathSeparator.PREFIX); if (prefixSeparatorIndex !== -1) { prefix = keyPath.substring(0, prefixSeparatorIndex); keyPath = keyPath.substring(prefixSeparatorIndex + exports.KeyPathSeparator.PREFIX.length); } const suffixSeparatorIndex = keyPath.lastIndexOf(exports.KeyPathSeparator.SUFFIX); if (suffixSeparatorIndex !== -1) { suffix = keyPath.substring(suffixSeparatorIndex + exports.KeyPathSeparator.SUFFIX.length); keyPath = keyPath.substring(0, suffixSeparatorIndex); } return { ...prefix ? { prefix } : {}, key: keyPath, ...suffix ? { suffix } : {} }; } /* * Copyright (c) 2021-2021. * Author Peter Placzek (tada5hi) * For the full copyright and license information, * view the LICENSE file that was distributed with this source code. */ class ScoreBoard { //-------------------------------------------------------------------- async get(options = {}) { options.sort = options.sort || 'DESC'; let data; if (typeof options.limit === 'undefined') { if (options.sort === 'DESC') { data = await this.client.zrevrangebyscore(this.options.key, '+inf', '-inf', 'WITHSCORES'); } else { data = await this.client.zrangebyscore(this.options.key, '-inf', '+inf', 'WITHSCORES'); } } else { var _options; (_options = options).offset ?? (_options.offset = 0); if (options.sort === 'DESC') { data = await this.client.zrevrangebyscore(this.options.key, '+inf', '-inf', 'WITHSCORES', 'LIMIT', options.offset, options.limit); } else { data = await this.client.zrangebyscore(this.options.key, '-inf', '+inf', 'WITHSCORES', 'LIMIT', options.offset, options.limit); } } const items = []; for(let i = 0; i < data.length; i += 2){ items.push({ id: data[i], score: parseInt(data[i + 1], 10) }); } const total = await this.client.zcard(this.options.key); return { data: items, meta: { total: total || 0, ...options.limit ? { limit: options.limit } : {}, ...options.offset ? { offset: options.offset } : {} } }; } async clear() { this.client.del(this.options.key); } //-------------------------------------------------------------------- /** * Set the score for a given key. * THe score will be set on default to performance.now() * * @param id * @param score */ async add(id, score) { await this.client.zadd(this.options.key, score || performance.now(), `${id}`); } /** * Clear the score for a given key. * * @param id */ async drop(id) { await this.client.zrem(this.options.key, `${id}`); } constructor(client, options = {}){ this.client = client; this.options = { ...options, key: 'score-board' }; } } Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return ioredis.Redis; } }); Object.defineProperty(exports, "ClientOptions", { enumerable: true, get: function () { return ioredis.RedisOptions; } }); Object.defineProperty(exports, "Cluster", { enumerable: true, get: function () { return ioredis.Cluster; } }); Object.defineProperty(exports, "ClusterNode", { enumerable: true, get: function () { return ioredis.ClusterNode; } }); Object.defineProperty(exports, "ClusterOptions", { enumerable: true, get: function () { return ioredis.ClusterOptions; } }); exports.JsonAdapter = JsonAdapter; exports.ScoreBoard = ScoreBoard; exports.Watcher = Watcher; exports.buildConfig = buildConfig; exports.buildConfigWithDefaults = buildConfigWithDefaults; exports.buildKeyPath = buildKeyPath; exports.createClient = createClient; exports.createCluster = createCluster; exports.escapeKey = escapeKey; exports.hasClient = hasClient; exports.hasCluster = hasCluster; exports.hasConfig = hasConfig; exports.parseKeyPath = parseKeyPath; exports.setClient = setClient; exports.setCluster = setCluster; exports.setConfig = setConfig; exports.unsetClient = unsetClient; exports.unsetConfig = unsetConfig; exports.useClient = useClient; exports.useCluster = useCluster; exports.useConfig = useConfig; //# sourceMappingURL=index.cjs.map