add redis client
This commit is contained in:
parent
6b4108bddf
commit
59dc2009a5
252
dist/index.cjs
vendored
252
dist/index.cjs
vendored
@ -31,6 +31,7 @@ __export(src_exports, {
|
||||
SINGLETON_KEY: () => SINGLETON_KEY,
|
||||
SyncLocker: () => SyncLocker,
|
||||
ZError: () => ZError,
|
||||
ZRedisClient: () => ZRedisClient,
|
||||
createAsyncQueue: () => createAsyncQueue,
|
||||
createAsyncQueues: () => createAsyncQueues,
|
||||
singleton: () => singleton
|
||||
@ -159,11 +160,262 @@ var DeferredPromise = class {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// src/redis/ZRedisClient.ts
|
||||
var import_redis = require("redis");
|
||||
var import_util = require("util");
|
||||
var ZRedisClient = class {
|
||||
constructor(opts) {
|
||||
this.subscriptions = {};
|
||||
this.handleSubscription = (channel, message) => {
|
||||
if (this.subscriptions[channel]) {
|
||||
for (let i = 0, l = this.subscriptions[channel].length; i < l; i++) {
|
||||
this.subscriptions[channel][i](JSON.parse(message));
|
||||
}
|
||||
}
|
||||
};
|
||||
this.sub = (0, import_redis.createClient)(opts);
|
||||
this.pub = (0, import_redis.createClient)(opts);
|
||||
this.sub.setMaxListeners(0);
|
||||
this.subscribeAsync = (0, import_util.promisify)(this.sub.subscribe).bind(this.sub);
|
||||
this.unsubscribeAsync = (0, import_util.promisify)(this.sub.unsubscribe).bind(this.sub);
|
||||
this.publishAsync = (0, import_util.promisify)(this.pub.publish).bind(this.pub);
|
||||
this.smembersAsync = (0, import_util.promisify)(this.pub.smembers).bind(this.pub);
|
||||
this.sismemberAsync = (0, import_util.promisify)(this.pub.sismember).bind(this.pub);
|
||||
this.hlenAsync = (0, import_util.promisify)(this.pub.hlen).bind(this.pub);
|
||||
this.hgetAsync = (0, import_util.promisify)(this.pub.hget).bind(this.pub);
|
||||
this.pubsubAsync = (0, import_util.promisify)(this.pub.pubsub).bind(this.pub);
|
||||
this.decrAsync = (0, import_util.promisify)(this.pub.decr).bind(this.pub);
|
||||
this.incrAsync = (0, import_util.promisify)(this.pub.incr).bind(this.pub);
|
||||
}
|
||||
async subscribe(topic, callback) {
|
||||
if (!this.subscriptions[topic]) {
|
||||
this.subscriptions[topic] = [];
|
||||
}
|
||||
this.subscriptions[topic].push(callback);
|
||||
if (this.sub.listeners("message").length === 0) {
|
||||
this.sub.addListener("message", this.handleSubscription);
|
||||
}
|
||||
await this.subscribeAsync(topic);
|
||||
return this;
|
||||
}
|
||||
async unsubscribe(topic, callback) {
|
||||
if (callback) {
|
||||
const index = this.subscriptions[topic].indexOf(callback);
|
||||
this.subscriptions[topic].splice(index, 1);
|
||||
} else {
|
||||
this.subscriptions[topic] = [];
|
||||
}
|
||||
if (this.subscriptions[topic].length === 0) {
|
||||
await this.unsubscribeAsync(topic);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
async publish(topic, data) {
|
||||
if (data === void 0) {
|
||||
data = false;
|
||||
}
|
||||
await this.publishAsync(topic, JSON.stringify(data));
|
||||
}
|
||||
async exists(roomId) {
|
||||
return (await this.pubsubAsync("channels", roomId)).length > 0;
|
||||
}
|
||||
async setex(key, value, seconds) {
|
||||
return new Promise((resolve) => this.pub.setex(key, seconds, value, resolve));
|
||||
}
|
||||
async expire(key, seconds) {
|
||||
return new Promise((resolve) => this.pub.expire(key, seconds, resolve));
|
||||
}
|
||||
async get(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.get(key, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async set(key, val) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.set(key, val, () => {
|
||||
resolve && resolve("");
|
||||
});
|
||||
});
|
||||
}
|
||||
async del(roomId) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.del(roomId, resolve);
|
||||
});
|
||||
}
|
||||
async sadd(key, value) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.sadd(key, value, resolve);
|
||||
});
|
||||
}
|
||||
async smembers(key) {
|
||||
return await this.smembersAsync(key);
|
||||
}
|
||||
async sismember(key, field) {
|
||||
return await this.sismemberAsync(key, field);
|
||||
}
|
||||
async srem(key, value) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.srem(key, value, resolve);
|
||||
});
|
||||
}
|
||||
async scard(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.scard(key, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async srandmember(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.srandmember(key, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async sinter(...keys) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.sinter(...keys, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zadd(key, value, member) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.zadd(key, value, member, resolve);
|
||||
});
|
||||
}
|
||||
async zincrby(key, value, member) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.zincrby(key, value, member, resolve);
|
||||
});
|
||||
}
|
||||
async zrangebyscore(key, min, max) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zrangebyscore(key, min, max, "withscores", (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zcard(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zcard(key, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zcount(key, min, max) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zcount(key, min, max, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zrevrank(key, member) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zrevrank(key, member, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zscore(key, member) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zscore(key, member, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zrevrange(key, start, end) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zrevrange(key, start, end, "withscores", (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async hset(key, field, value) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.hset(key, field, value, resolve);
|
||||
});
|
||||
}
|
||||
async hincrby(key, field, value) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.hincrby(key, field, value, resolve);
|
||||
});
|
||||
}
|
||||
async hget(key, field) {
|
||||
return await this.hgetAsync(key, field);
|
||||
}
|
||||
async hgetall(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.hgetall(key, (err, values) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(values);
|
||||
});
|
||||
});
|
||||
}
|
||||
async hdel(key, field) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.hdel(key, field, (err, ok) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(ok);
|
||||
});
|
||||
});
|
||||
}
|
||||
async hlen(key) {
|
||||
return await this.hlenAsync(key);
|
||||
}
|
||||
async incr(key) {
|
||||
return await this.incrAsync(key);
|
||||
}
|
||||
async decr(key) {
|
||||
return await this.decrAsync(key);
|
||||
}
|
||||
};
|
||||
ZRedisClient = __decorateClass([
|
||||
singleton
|
||||
], ZRedisClient);
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
SINGLETON_KEY,
|
||||
SyncLocker,
|
||||
ZError,
|
||||
ZRedisClient,
|
||||
createAsyncQueue,
|
||||
createAsyncQueues,
|
||||
singleton
|
||||
|
2
dist/index.cjs.map
vendored
2
dist/index.cjs.map
vendored
File diff suppressed because one or more lines are too long
58
dist/index.d.cts
vendored
58
dist/index.d.cts
vendored
@ -1,6 +1,7 @@
|
||||
export { ZError } from './common/ZError.cjs';
|
||||
export { SyncLocker } from './common/SyncLocker.cjs';
|
||||
export { AsyncQueue, createAsyncQueue, createAsyncQueues } from './common/AsyncQueue.cjs';
|
||||
import { RedisClient, ClientOpts } from 'redis';
|
||||
|
||||
/**
|
||||
* 单例化一个class
|
||||
@ -18,4 +19,59 @@ type Singleton<T extends new (...args: any[]) => any> = T & {
|
||||
};
|
||||
declare const singleton: <T extends new (...args: any[]) => any>(classTarget: T) => T;
|
||||
|
||||
export { SINGLETON_KEY, type Singleton, singleton };
|
||||
type Callback = (...args: any[]) => void;
|
||||
declare class ZRedisClient {
|
||||
pub: RedisClient;
|
||||
sub: RedisClient;
|
||||
protected subscribeAsync: any;
|
||||
protected unsubscribeAsync: any;
|
||||
protected publishAsync: any;
|
||||
protected subscriptions: {
|
||||
[channel: string]: Callback[];
|
||||
};
|
||||
protected smembersAsync: any;
|
||||
protected sismemberAsync: any;
|
||||
protected hgetAsync: any;
|
||||
protected hlenAsync: any;
|
||||
protected pubsubAsync: any;
|
||||
protected incrAsync: any;
|
||||
protected decrAsync: any;
|
||||
constructor(opts?: ClientOpts);
|
||||
subscribe(topic: string, callback: Callback): Promise<this>;
|
||||
unsubscribe(topic: string, callback?: Callback): Promise<this>;
|
||||
publish(topic: string, data: any): Promise<void>;
|
||||
exists(roomId: string): Promise<boolean>;
|
||||
setex(key: string, value: string, seconds: number): Promise<unknown>;
|
||||
expire(key: string, seconds: number): Promise<unknown>;
|
||||
get(key: string): Promise<string | null>;
|
||||
set(key: string, val: string): Promise<unknown>;
|
||||
del(roomId: string): Promise<unknown>;
|
||||
sadd(key: string, value: any): Promise<unknown>;
|
||||
smembers(key: string): Promise<string[]>;
|
||||
sismember(key: string, field: string): Promise<number>;
|
||||
srem(key: string, value: any): Promise<unknown>;
|
||||
scard(key: string): Promise<unknown>;
|
||||
srandmember(key: string): Promise<unknown>;
|
||||
sinter(...keys: string[]): Promise<string[]>;
|
||||
zadd(key: string, value: any, member: string): Promise<unknown>;
|
||||
zincrby(key: string, value: any, member: string): Promise<unknown>;
|
||||
zrangebyscore(key: string, min: number, max: number): Promise<unknown>;
|
||||
zcard(key: string): Promise<unknown>;
|
||||
zcount(key: string, min: number, max: number): Promise<unknown>;
|
||||
zrevrank(key: string, member: string): Promise<unknown>;
|
||||
zscore(key: string, member: string): Promise<unknown>;
|
||||
zrevrange(key: string, start: number, end: number): Promise<string[]>;
|
||||
hset(key: string, field: string, value: string): Promise<unknown>;
|
||||
hincrby(key: string, field: string, value: number): Promise<unknown>;
|
||||
hget(key: string, field: string): Promise<any>;
|
||||
hgetall(key: string): Promise<{
|
||||
[key: string]: string;
|
||||
}>;
|
||||
hdel(key: string, field: string): Promise<unknown>;
|
||||
hlen(key: string): Promise<number>;
|
||||
incr(key: string): Promise<number>;
|
||||
decr(key: string): Promise<number>;
|
||||
protected handleSubscription: (channel: string, message: string) => void;
|
||||
}
|
||||
|
||||
export { SINGLETON_KEY, type Singleton, ZRedisClient, singleton };
|
||||
|
58
dist/index.d.ts
vendored
58
dist/index.d.ts
vendored
@ -1,6 +1,7 @@
|
||||
export { ZError } from './common/ZError.js';
|
||||
export { SyncLocker } from './common/SyncLocker.js';
|
||||
export { AsyncQueue, createAsyncQueue, createAsyncQueues } from './common/AsyncQueue.js';
|
||||
import { RedisClient, ClientOpts } from 'redis';
|
||||
|
||||
/**
|
||||
* 单例化一个class
|
||||
@ -18,4 +19,59 @@ type Singleton<T extends new (...args: any[]) => any> = T & {
|
||||
};
|
||||
declare const singleton: <T extends new (...args: any[]) => any>(classTarget: T) => T;
|
||||
|
||||
export { SINGLETON_KEY, type Singleton, singleton };
|
||||
type Callback = (...args: any[]) => void;
|
||||
declare class ZRedisClient {
|
||||
pub: RedisClient;
|
||||
sub: RedisClient;
|
||||
protected subscribeAsync: any;
|
||||
protected unsubscribeAsync: any;
|
||||
protected publishAsync: any;
|
||||
protected subscriptions: {
|
||||
[channel: string]: Callback[];
|
||||
};
|
||||
protected smembersAsync: any;
|
||||
protected sismemberAsync: any;
|
||||
protected hgetAsync: any;
|
||||
protected hlenAsync: any;
|
||||
protected pubsubAsync: any;
|
||||
protected incrAsync: any;
|
||||
protected decrAsync: any;
|
||||
constructor(opts?: ClientOpts);
|
||||
subscribe(topic: string, callback: Callback): Promise<this>;
|
||||
unsubscribe(topic: string, callback?: Callback): Promise<this>;
|
||||
publish(topic: string, data: any): Promise<void>;
|
||||
exists(roomId: string): Promise<boolean>;
|
||||
setex(key: string, value: string, seconds: number): Promise<unknown>;
|
||||
expire(key: string, seconds: number): Promise<unknown>;
|
||||
get(key: string): Promise<string | null>;
|
||||
set(key: string, val: string): Promise<unknown>;
|
||||
del(roomId: string): Promise<unknown>;
|
||||
sadd(key: string, value: any): Promise<unknown>;
|
||||
smembers(key: string): Promise<string[]>;
|
||||
sismember(key: string, field: string): Promise<number>;
|
||||
srem(key: string, value: any): Promise<unknown>;
|
||||
scard(key: string): Promise<unknown>;
|
||||
srandmember(key: string): Promise<unknown>;
|
||||
sinter(...keys: string[]): Promise<string[]>;
|
||||
zadd(key: string, value: any, member: string): Promise<unknown>;
|
||||
zincrby(key: string, value: any, member: string): Promise<unknown>;
|
||||
zrangebyscore(key: string, min: number, max: number): Promise<unknown>;
|
||||
zcard(key: string): Promise<unknown>;
|
||||
zcount(key: string, min: number, max: number): Promise<unknown>;
|
||||
zrevrank(key: string, member: string): Promise<unknown>;
|
||||
zscore(key: string, member: string): Promise<unknown>;
|
||||
zrevrange(key: string, start: number, end: number): Promise<string[]>;
|
||||
hset(key: string, field: string, value: string): Promise<unknown>;
|
||||
hincrby(key: string, field: string, value: number): Promise<unknown>;
|
||||
hget(key: string, field: string): Promise<any>;
|
||||
hgetall(key: string): Promise<{
|
||||
[key: string]: string;
|
||||
}>;
|
||||
hdel(key: string, field: string): Promise<unknown>;
|
||||
hlen(key: string): Promise<number>;
|
||||
incr(key: string): Promise<number>;
|
||||
decr(key: string): Promise<number>;
|
||||
protected handleSubscription: (channel: string, message: string) => void;
|
||||
}
|
||||
|
||||
export { SINGLETON_KEY, type Singleton, ZRedisClient, singleton };
|
||||
|
251
dist/index.js
vendored
251
dist/index.js
vendored
@ -132,10 +132,261 @@ var DeferredPromise = class {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// src/redis/ZRedisClient.ts
|
||||
import { createClient } from "redis";
|
||||
import { promisify } from "util";
|
||||
var ZRedisClient = class {
|
||||
constructor(opts) {
|
||||
this.subscriptions = {};
|
||||
this.handleSubscription = (channel, message) => {
|
||||
if (this.subscriptions[channel]) {
|
||||
for (let i = 0, l = this.subscriptions[channel].length; i < l; i++) {
|
||||
this.subscriptions[channel][i](JSON.parse(message));
|
||||
}
|
||||
}
|
||||
};
|
||||
this.sub = createClient(opts);
|
||||
this.pub = createClient(opts);
|
||||
this.sub.setMaxListeners(0);
|
||||
this.subscribeAsync = promisify(this.sub.subscribe).bind(this.sub);
|
||||
this.unsubscribeAsync = promisify(this.sub.unsubscribe).bind(this.sub);
|
||||
this.publishAsync = promisify(this.pub.publish).bind(this.pub);
|
||||
this.smembersAsync = promisify(this.pub.smembers).bind(this.pub);
|
||||
this.sismemberAsync = promisify(this.pub.sismember).bind(this.pub);
|
||||
this.hlenAsync = promisify(this.pub.hlen).bind(this.pub);
|
||||
this.hgetAsync = promisify(this.pub.hget).bind(this.pub);
|
||||
this.pubsubAsync = promisify(this.pub.pubsub).bind(this.pub);
|
||||
this.decrAsync = promisify(this.pub.decr).bind(this.pub);
|
||||
this.incrAsync = promisify(this.pub.incr).bind(this.pub);
|
||||
}
|
||||
async subscribe(topic, callback) {
|
||||
if (!this.subscriptions[topic]) {
|
||||
this.subscriptions[topic] = [];
|
||||
}
|
||||
this.subscriptions[topic].push(callback);
|
||||
if (this.sub.listeners("message").length === 0) {
|
||||
this.sub.addListener("message", this.handleSubscription);
|
||||
}
|
||||
await this.subscribeAsync(topic);
|
||||
return this;
|
||||
}
|
||||
async unsubscribe(topic, callback) {
|
||||
if (callback) {
|
||||
const index = this.subscriptions[topic].indexOf(callback);
|
||||
this.subscriptions[topic].splice(index, 1);
|
||||
} else {
|
||||
this.subscriptions[topic] = [];
|
||||
}
|
||||
if (this.subscriptions[topic].length === 0) {
|
||||
await this.unsubscribeAsync(topic);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
async publish(topic, data) {
|
||||
if (data === void 0) {
|
||||
data = false;
|
||||
}
|
||||
await this.publishAsync(topic, JSON.stringify(data));
|
||||
}
|
||||
async exists(roomId) {
|
||||
return (await this.pubsubAsync("channels", roomId)).length > 0;
|
||||
}
|
||||
async setex(key, value, seconds) {
|
||||
return new Promise((resolve) => this.pub.setex(key, seconds, value, resolve));
|
||||
}
|
||||
async expire(key, seconds) {
|
||||
return new Promise((resolve) => this.pub.expire(key, seconds, resolve));
|
||||
}
|
||||
async get(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.get(key, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async set(key, val) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.set(key, val, () => {
|
||||
resolve && resolve("");
|
||||
});
|
||||
});
|
||||
}
|
||||
async del(roomId) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.del(roomId, resolve);
|
||||
});
|
||||
}
|
||||
async sadd(key, value) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.sadd(key, value, resolve);
|
||||
});
|
||||
}
|
||||
async smembers(key) {
|
||||
return await this.smembersAsync(key);
|
||||
}
|
||||
async sismember(key, field) {
|
||||
return await this.sismemberAsync(key, field);
|
||||
}
|
||||
async srem(key, value) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.srem(key, value, resolve);
|
||||
});
|
||||
}
|
||||
async scard(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.scard(key, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async srandmember(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.srandmember(key, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async sinter(...keys) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.sinter(...keys, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zadd(key, value, member) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.zadd(key, value, member, resolve);
|
||||
});
|
||||
}
|
||||
async zincrby(key, value, member) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.zincrby(key, value, member, resolve);
|
||||
});
|
||||
}
|
||||
async zrangebyscore(key, min, max) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zrangebyscore(key, min, max, "withscores", (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zcard(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zcard(key, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zcount(key, min, max) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zcount(key, min, max, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zrevrank(key, member) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zrevrank(key, member, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zscore(key, member) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zscore(key, member, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async zrevrange(key, start, end) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zrevrange(key, start, end, "withscores", (err, data) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
async hset(key, field, value) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.hset(key, field, value, resolve);
|
||||
});
|
||||
}
|
||||
async hincrby(key, field, value) {
|
||||
return new Promise((resolve) => {
|
||||
this.pub.hincrby(key, field, value, resolve);
|
||||
});
|
||||
}
|
||||
async hget(key, field) {
|
||||
return await this.hgetAsync(key, field);
|
||||
}
|
||||
async hgetall(key) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.hgetall(key, (err, values) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(values);
|
||||
});
|
||||
});
|
||||
}
|
||||
async hdel(key, field) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.hdel(key, field, (err, ok) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
resolve(ok);
|
||||
});
|
||||
});
|
||||
}
|
||||
async hlen(key) {
|
||||
return await this.hlenAsync(key);
|
||||
}
|
||||
async incr(key) {
|
||||
return await this.incrAsync(key);
|
||||
}
|
||||
async decr(key) {
|
||||
return await this.decrAsync(key);
|
||||
}
|
||||
};
|
||||
ZRedisClient = __decorateClass([
|
||||
singleton
|
||||
], ZRedisClient);
|
||||
export {
|
||||
SINGLETON_KEY,
|
||||
SyncLocker,
|
||||
ZError,
|
||||
ZRedisClient,
|
||||
createAsyncQueue,
|
||||
createAsyncQueues,
|
||||
singleton
|
||||
|
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
@ -17,7 +17,9 @@
|
||||
},
|
||||
"typesVersions": {
|
||||
"*": {
|
||||
"utils/*": ["dist/utils/*.d.ts"]
|
||||
"utils/*": [
|
||||
"dist/utils/*.d.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "module",
|
||||
@ -31,9 +33,11 @@
|
||||
"@metamask/eth-sig-util": "^4.0.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"ethereumjs-util": "^7.1.5",
|
||||
"redis": "^3.1.2",
|
||||
"web3": "^1.7.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/redis": "^2.8.28",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsup": "^8.0.1",
|
||||
"typescript": "^5.3.3"
|
||||
|
@ -1,4 +1,5 @@
|
||||
export { ZError } from './common/ZError'
|
||||
export { SyncLocker } from './common/SyncLocker'
|
||||
export * from './decorators/singleton'
|
||||
export * from './common/AsyncQueue'
|
||||
export * from './common/AsyncQueue'
|
||||
export { ZRedisClient } from './redis/ZRedisClient'
|
313
src/redis/ZRedisClient.ts
Normal file
313
src/redis/ZRedisClient.ts
Normal file
@ -0,0 +1,313 @@
|
||||
import { singleton } from 'decorators/singleton'
|
||||
import { ClientOpts, RedisClient, createClient } from 'redis'
|
||||
import { promisify } from 'util'
|
||||
|
||||
|
||||
type Callback = (...args: any[]) => void
|
||||
|
||||
@singleton
|
||||
export class ZRedisClient {
|
||||
public pub: RedisClient
|
||||
public sub: RedisClient
|
||||
|
||||
protected subscribeAsync: any
|
||||
protected unsubscribeAsync: any
|
||||
protected publishAsync: any
|
||||
|
||||
protected subscriptions: { [channel: string]: Callback[] } = {}
|
||||
|
||||
protected smembersAsync: any
|
||||
protected sismemberAsync: any
|
||||
protected hgetAsync: any
|
||||
protected hlenAsync: any
|
||||
protected pubsubAsync: any
|
||||
protected incrAsync: any
|
||||
protected decrAsync: any
|
||||
|
||||
constructor(opts?: ClientOpts) {
|
||||
this.sub = createClient(opts)
|
||||
this.pub = createClient(opts)
|
||||
|
||||
// no listener limit
|
||||
this.sub.setMaxListeners(0)
|
||||
|
||||
// create promisified pub/sub methods.
|
||||
this.subscribeAsync = promisify(this.sub.subscribe).bind(this.sub)
|
||||
this.unsubscribeAsync = promisify(this.sub.unsubscribe).bind(this.sub)
|
||||
|
||||
this.publishAsync = promisify(this.pub.publish).bind(this.pub)
|
||||
|
||||
// create promisified redis methods.
|
||||
this.smembersAsync = promisify(this.pub.smembers).bind(this.pub)
|
||||
this.sismemberAsync = promisify(this.pub.sismember).bind(this.pub)
|
||||
this.hlenAsync = promisify(this.pub.hlen).bind(this.pub)
|
||||
this.hgetAsync = promisify(this.pub.hget).bind(this.pub)
|
||||
this.pubsubAsync = promisify(this.pub.pubsub).bind(this.pub)
|
||||
this.decrAsync = promisify(this.pub.decr).bind(this.pub)
|
||||
this.incrAsync = promisify(this.pub.incr).bind(this.pub)
|
||||
}
|
||||
|
||||
public async subscribe(topic: string, callback: Callback) {
|
||||
if (!this.subscriptions[topic]) {
|
||||
this.subscriptions[topic] = []
|
||||
}
|
||||
|
||||
this.subscriptions[topic].push(callback)
|
||||
|
||||
if (this.sub.listeners('message').length === 0) {
|
||||
this.sub.addListener('message', this.handleSubscription)
|
||||
}
|
||||
|
||||
await this.subscribeAsync(topic)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
public async unsubscribe(topic: string, callback?: Callback) {
|
||||
if (callback) {
|
||||
const index = this.subscriptions[topic].indexOf(callback)
|
||||
this.subscriptions[topic].splice(index, 1)
|
||||
} else {
|
||||
this.subscriptions[topic] = []
|
||||
}
|
||||
|
||||
if (this.subscriptions[topic].length === 0) {
|
||||
await this.unsubscribeAsync(topic)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
public async publish(topic: string, data: any) {
|
||||
if (data === undefined) {
|
||||
data = false
|
||||
}
|
||||
|
||||
await this.publishAsync(topic, JSON.stringify(data))
|
||||
}
|
||||
|
||||
public async exists(roomId: string): Promise<boolean> {
|
||||
return (await this.pubsubAsync('channels', roomId)).length > 0
|
||||
}
|
||||
|
||||
public async setex(key: string, value: string, seconds: number) {
|
||||
return new Promise(resolve => this.pub.setex(key, seconds, value, resolve))
|
||||
}
|
||||
|
||||
public async expire(key: string, seconds: number) {
|
||||
return new Promise(resolve => this.pub.expire(key, seconds, resolve))
|
||||
}
|
||||
|
||||
public async get(key: string): Promise<string | null> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.get(key, (err, data: string | null) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async set(key: string, val: string) {
|
||||
return new Promise(resolve => {
|
||||
this.pub.set(key, val, () => {
|
||||
resolve && resolve('')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async del(roomId: string) {
|
||||
return new Promise(resolve => {
|
||||
this.pub.del(roomId, resolve)
|
||||
})
|
||||
}
|
||||
|
||||
public async sadd(key: string, value: any) {
|
||||
return new Promise(resolve => {
|
||||
this.pub.sadd(key, value, resolve)
|
||||
})
|
||||
}
|
||||
|
||||
public async smembers(key: string): Promise<string[]> {
|
||||
return await this.smembersAsync(key)
|
||||
}
|
||||
|
||||
public async sismember(key: string, field: string): Promise<number> {
|
||||
return await this.sismemberAsync(key, field)
|
||||
}
|
||||
|
||||
public async srem(key: string, value: any) {
|
||||
return new Promise(resolve => {
|
||||
this.pub.srem(key, value, resolve)
|
||||
})
|
||||
}
|
||||
|
||||
public async scard(key: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.scard(key, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
public async srandmember(key: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.srandmember(key, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async sinter(...keys: string[]) {
|
||||
return new Promise<string[]>((resolve, reject) => {
|
||||
this.pub.sinter(...keys, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async zadd(key: string, value: any, member: string) {
|
||||
return new Promise(resolve => {
|
||||
this.pub.zadd(key, value, member, resolve)
|
||||
})
|
||||
}
|
||||
|
||||
public async zincrby(key: string, value: any, member: string) {
|
||||
return new Promise(resolve => {
|
||||
this.pub.zincrby(key, value, member, resolve)
|
||||
})
|
||||
}
|
||||
|
||||
public async zrangebyscore(key: string, min: number, max: number) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zrangebyscore(key, min, max, 'withscores', (err, data) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async zcard(key: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zcard(key, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async zcount(key: string, min: number, max: number) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zcount(key, min, max, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async zrevrank(key: string, member: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zrevrank(key, member, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async zscore(key: string, member: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zscore(key, member, (err, data) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async zrevrange(key: string, start: number, end: number): Promise<string[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.zrevrange(key, start, end, 'withscores', (err, data) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async hset(key: string, field: string, value: string) {
|
||||
return new Promise(resolve => {
|
||||
this.pub.hset(key, field, value, resolve)
|
||||
})
|
||||
}
|
||||
|
||||
public async hincrby(key: string, field: string, value: number) {
|
||||
return new Promise(resolve => {
|
||||
this.pub.hincrby(key, field, value, resolve)
|
||||
})
|
||||
}
|
||||
|
||||
public async hget(key: string, field: string) {
|
||||
return await this.hgetAsync(key, field)
|
||||
}
|
||||
|
||||
public async hgetall(key: string) {
|
||||
return new Promise<{ [key: string]: string }>((resolve, reject) => {
|
||||
this.pub.hgetall(key, (err, values) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(values)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async hdel(key: string, field: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.pub.hdel(key, field, (err, ok) => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve(ok)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
public async hlen(key: string): Promise<number> {
|
||||
return await this.hlenAsync(key)
|
||||
}
|
||||
|
||||
public async incr(key: string): Promise<number> {
|
||||
return await this.incrAsync(key)
|
||||
}
|
||||
|
||||
public async decr(key: string): Promise<number> {
|
||||
return await this.decrAsync(key)
|
||||
}
|
||||
|
||||
protected handleSubscription = (channel: string, message: string) => {
|
||||
if (this.subscriptions[channel]) {
|
||||
for (let i = 0, l = this.subscriptions[channel].length; i < l; i++) {
|
||||
this.subscriptions[channel][i](JSON.parse(message))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
39
yarn.lock
39
yarn.lock
@ -623,6 +623,13 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/redis@^2.8.28":
|
||||
version "2.8.32"
|
||||
resolved "https://registry.yarnpkg.com/@types/redis/-/redis-2.8.32.tgz#1d3430219afbee10f8cfa389dad2571a05ecfb11"
|
||||
integrity sha512-7jkMKxcGq9p242exlbsVzuJb57KqHRhNl4dHoQu2Y5v9bCAbtIXXH0R3HleSQW4CTOqpHIYUW3t6tpUj4BVQ+w==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/responselike@^1.0.0":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50"
|
||||
@ -1218,6 +1225,11 @@ delayed-stream@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||
|
||||
denque@^1.5.0:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf"
|
||||
integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==
|
||||
|
||||
depd@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
|
||||
@ -2674,6 +2686,33 @@ readdirp@~3.6.0:
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
redis-commands@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89"
|
||||
integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==
|
||||
|
||||
redis-errors@^1.0.0, redis-errors@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad"
|
||||
integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==
|
||||
|
||||
redis-parser@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4"
|
||||
integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==
|
||||
dependencies:
|
||||
redis-errors "^1.0.0"
|
||||
|
||||
redis@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/redis/-/redis-3.1.2.tgz#766851117e80653d23e0ed536254677ab647638c"
|
||||
integrity sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==
|
||||
dependencies:
|
||||
denque "^1.5.0"
|
||||
redis-commands "^1.7.0"
|
||||
redis-errors "^1.2.0"
|
||||
redis-parser "^3.0.0"
|
||||
|
||||
request@^2.79.0:
|
||||
version "2.88.2"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||
|
Loading…
x
Reference in New Issue
Block a user