@onesy/redis
Version:
175 lines (174 loc) • 6.44 kB
JavaScript
"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;