{
  "version": 3,
  "sources": ["../src/index.ts"],
  "sourcesContent": ["import { Redis, Cluster, type ClusterNode, type ClusterOptions, type RedisOptions } from 'ioredis';\nimport type { Presence } from '@colyseus/core';\nimport EventEmitter from 'events';\n\ntype Callback = (...args: any[]) => void;\n\nexport class RedisPresence implements Presence {\n    protected sub: Redis | Cluster;\n    protected pub: Redis | Cluster;\n\n    protected subscriptions = new EventEmitter();\n\n    constructor(options?: number | string | RedisOptions | ClusterNode[] | Redis | Cluster, clusterOptions?: ClusterOptions) {\n        if (options instanceof Redis || options instanceof Cluster) {\n            this.pub = options;\n            this.sub = options.duplicate();\n        } else if (Array.isArray(options)) {\n            this.sub = new Cluster(options, clusterOptions)\n            this.pub = new Cluster(options, clusterOptions);\n        } else {\n            this.sub = new Redis(options as RedisOptions);\n            this.pub = new Redis(options as RedisOptions);\n        }\n\n        // no listener limit\n        this.sub.setMaxListeners(0);\n    }\n\n    public async subscribe(topic: string, callback: Callback) {\n        this.subscriptions.addListener(topic, callback);\n\n        if (this.sub.listeners('message').length === 0) {\n          this.sub.on('message', this.handleSubscription);\n        }\n\n        await this.sub.subscribe(topic);\n\n        return this;\n    }\n\n    public async unsubscribe(topic: string, callback?: Callback) {\n        if (callback) {\n          this.subscriptions.removeListener(topic, callback);\n\n        } else {\n          this.subscriptions.removeAllListeners(topic);\n        }\n\n        if (this.subscriptions.listenerCount(topic) === 0) {\n          await this.sub.unsubscribe(topic);\n        }\n\n        return this;\n    }\n\n    public async publish(topic: string, data: any) {\n        if (data === undefined) {\n            data = false;\n        }\n\n        await this.pub.publish(topic, JSON.stringify(data));\n    }\n\n    public channels(pattern: string = '*') {\n      return this.pub.pubsub(\"CHANNELS\", pattern) as Promise<string[]>;\n    }\n\n    public async exists(key: string): Promise<boolean> {\n        return (await this.pub.exists(key)) === 1;\n    }\n\n    public async set(key: string, value: string) {\n      return new Promise((resolve) =>\n        this.pub.set(key, value, resolve));\n    }\n\n    public async setex(key: string, value: string, seconds: number) {\n      return new Promise((resolve) =>\n        this.pub.setex(key, seconds, value, resolve));\n    }\n\n    public async expire(key: string, seconds: number) {\n      return new Promise((resolve) =>\n        this.pub.expire(key, seconds, resolve));\n    }\n\n    public async get(key: string) {\n        return new Promise((resolve, reject) => {\n            this.pub.get(key, (err, data) => {\n                if (err) { return reject(err); }\n                resolve(data);\n            });\n        });\n    }\n\n    public async del(roomId: string) {\n        return new Promise((resolve) => {\n            this.pub.del(roomId, resolve);\n        });\n    }\n\n    public async sadd(key: string, value: any) {\n        return new Promise((resolve) => {\n            this.pub.sadd(key, value, resolve);\n        });\n    }\n\n    public async smembers(key: string): Promise<string[]> {\n        return await this.pub.smembers(key);\n    }\n\n    public async sismember(key: string, field: string): Promise<number> {\n        return await this.pub.sismember(key, field);\n    }\n\n    public async srem(key: string, value: any) {\n        return await this.pub.srem(key, value);\n    }\n\n    public async scard(key: string) {\n        return await this.pub.scard(key);\n    }\n\n    public async sinter(...keys: string[]) {\n        return await this.pub.sinter(...keys);\n    }\n\n    public async hset(key: string, field: string, value: string) {\n        return (await this.pub.hset(key, field, value)) > 0;\n    }\n\n    public async hincrby(key: string, field: string, value: number) {\n        return new Promise<number>((resolve, reject) => {\n          this.pub.hincrby(key, field, value, (err, result) => {\n            if (err) return reject(err);\n            resolve(result);\n          });\n        });\n    }\n\n    public async hincrbyex(key: string, field: string, value: number, expireInSeconds: number) {\n        return new Promise<number>((resolve, reject) => {\n          this.pub.multi()\n            .hincrby(key, field, value)\n            .expire(key, expireInSeconds)\n            .exec((err, results) => {\n              if (err) return reject(err);\n              resolve(results[0][1] as number);\n            });\n        });\n    }\n\n    public async hget(key: string, field: string) {\n        return await this.pub.hget(key, field);\n    }\n\n    public async hgetall(key: string) {\n        return await this.pub.hgetall(key);\n    }\n\n    public async hdel(key: string, field: string) {\n        return (await this.pub.hdel(key, field)) > 0;\n    }\n\n    public async hlen(key: string): Promise<number> {\n        return await this.pub.hlen(key);\n    }\n\n    public async incr(key: string): Promise<number> {\n        return await this.pub.incr(key);\n    }\n\n    public async decr(key: string): Promise<number> {\n        return await this.pub.decr(key);\n    }\n\n    public async llen(key: string): Promise<number> {\n      return await this.pub.llen(key);\n    }\n\n    public async rpush(key: string, value: string): Promise<number> {\n      return await this.pub.rpush(key, value);\n    }\n\n    public async lpush(key: string, value: string): Promise<number> {\n      return await this.pub.lpush(key, value);\n    }\n\n    public async rpop(key: string): Promise<string | null> {\n      return await this.pub.rpop(key);\n    }\n\n    public async lpop(key: string): Promise<string | null> {\n      return await this.pub.lpop(key);\n    }\n\n    public async brpop(...args: any): Promise<[string, string] | null> {\n      return await this.pub.brpop.apply(this.pub, args);\n    }\n\n    public shutdown() {\n        this.sub.quit();\n        this.pub.quit();\n    }\n\n    public setMaxListeners(number: number) {\n      this.subscriptions.setMaxListeners(number);\n    }\n\n    protected handleSubscription = (channel, message) => {\n        this.subscriptions.emit(channel, JSON.parse(message));\n    }\n\n}\n"],
  "mappings": "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",
  "names": ["EventEmitter"]
}
