UNPKG

@onesy/redis

Version:
175 lines (174 loc) 6.44 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.optionsDefault = void 0; const redis_1 = require("redis"); const merge_1 = __importDefault(require("@onesy/utils/merge")); const stringify_1 = __importDefault(require("@onesy/utils/stringify")); const parse_1 = __importDefault(require("@onesy/utils/parse")); const errors_1 = require("@onesy/errors"); const log_1 = __importDefault(require("@onesy/log")); const subscription_1 = __importDefault(require("@onesy/subscription")); exports.optionsDefault = {}; class OnesyRedis { get options() { return this.options_; } set options(options) { var _a; this.options_ = (0, merge_1.default)(options, exports.optionsDefault); this.namespace = (_a = this.options.namespace) !== null && _a !== void 0 ? _a : this.namespace; } constructor(options = exports.optionsDefault) { this.connected = false; this.namespace = ''; this.options_ = exports.optionsDefault; // For listening on redis events this.subscription = new subscription_1.default(); // alias this.set = this.add; // alias this.delete = this.remove; // alias this.deleteMany = this.removeMany; this.options = options; this.amalog = new log_1.default({ arguments: { pre: [ 'Redis' ] } }); } async query(queryProps = '*') { const client = await this.client; const query = this.namespace ? `${this.namespace}:${queryProps}` : queryProps; const value = await client.keys(query); return value; } async get(keyProps, options = { parse: true }) { const client = await this.client; const key = this.namespace ? `${this.namespace}:${keyProps}` : keyProps; const value = await client.get(key); return options.parse ? (0, parse_1.default)(value) : value; } async add(keyProps, value) { const client = await this.client; const key = this.namespace ? `${this.namespace}:${keyProps}` : keyProps; return client.set(key, value); } async remove(keyProps) { const client = await this.client; const key = this.namespace ? `${this.namespace}:${keyProps}` : keyProps; return client.del(key); } async removeMany(query) { const keys = await this.query(query); return Promise.allSettled((keys || []).map(key => { const keyProp = this.namespace ? key.replace(`${this.namespace}:`, '') : key; return this.remove(keyProp); })); } async subscribe(channels, method, bufferMode) { await this.connection; // we have to separate subscribe, publish client context const client = this.clientSubscriber; return client.subscribe(channels, method, bufferMode); } async unsubscribe(channels, method, bufferMode) { const client = await this.client; return client.unsubscribe(channels, method, bufferMode); } messageData(message, options = { parse: true }) { if (message) { const data = message; return options.parse ? (0, parse_1.default)(data) : data; } } async publish(channel, data, options = { serialize: true }) { const client = await this.client; const message = options.serialize ? (0, stringify_1.default)(data) : data; return client.publish(channel, message); } get client() { return new Promise(async (resolve, reject) => { if (this.connected && this.client_) return resolve(this.client_); try { return resolve(await this.connect()); } catch (error) { throw error; } }); } // alias for the client get connection() { return new Promise(async (resolve, reject) => { if (this.connected && this.client_) return resolve(this.client_); try { return resolve(await this.connect()); } catch (error) { throw error; } }); } get disconnect() { return new Promise(async (resolve) => { if (this.connected) { try { await this.client_.disconnect(); this.amalog.important(`Disconnected`); this.connected = false; this.client_ = undefined; this.clientSubscriber = undefined; this.subscription.emit('disconnected'); return resolve(); } catch (error) { this.amalog.warn(`Connection close error`, error); this.subscription.emit('disconnect:error', error); throw new errors_1.ConnectionError(error); } } return resolve(); }); } async connect() { const { uri } = this.options; try { this.client_ = (0, redis_1.createClient)({ url: uri }); await this.client_.connect(); this.clientSubscriber = this.client_.duplicate(); await this.clientSubscriber.connect(); this.amalog.info(`Connected`); this.connected = true; this.subscription.emit('connected'); this.client_.on('end', () => this.amalog.important('Client closed')); return this.client_; } catch (error) { this.amalog.warn(`Connection error`, error); this.connected = false; this.subscription.emit('connect:error', error); throw new errors_1.ConnectionError(error); } } // Be very careful with this one, // it removes all data in the redis, // usually used for testing only async reset() { if (this.connected) { const client = await this.client; if (client) return client.flushDb(); } this.amalog.important(`All cleaned`); this.subscription.emit('reset'); } } exports.default = OnesyRedis;