import { Collection } from '../utils/collection.ts' import { connect, Redis, RedisConnectOptions } from 'https://denopkg.com/keroxp/deno-redis/mod.ts' export interface ICacheAdapter { get: (cacheName: string, key: string) => Promise | any set: (cacheName: string, key: string, value: any) => Promise | any delete: (cacheName: string, key: string) => Promise | boolean array: (cacheName: string) => undefined | any[] | Promise deleteCache: (cacheName: string) => any } export class DefaultCacheAdapter implements ICacheAdapter { data: { [name: string]: Collection } = {} async get (cacheName: string, key: string): Promise { const cache = this.data[cacheName] if (cache === undefined) return return cache.get(key) } async set (cacheName: string, key: string, value: any): Promise { let cache = this.data[cacheName] if (cache === undefined) { this.data[cacheName] = new Collection() cache = this.data[cacheName] } return cache.set(key, value) } async delete (cacheName: string, key: string): Promise { const cache = this.data[cacheName] if (cache === undefined) return false return cache.delete(key) } async array (cacheName: string): Promise { const cache = this.data[cacheName] if (cache === undefined) return return cache.array() } async deleteCache(cacheName: string): Promise { // eslint-disable-next-line @typescript-eslint/no-dynamic-delete return delete this.data[cacheName] } } export class RedisCacheAdapter implements ICacheAdapter { _redis: Promise redis?: Redis ready: boolean = false constructor (options: RedisConnectOptions) { this._redis = connect(options) this._redis.then( redis => { this.redis = redis this.ready = true }, () => { // TODO: Make error for this } ) } async _checkReady (): Promise { if (!this.ready) await this._redis } async get (cacheName: string, key: string): Promise { await this._checkReady() const cache = await this.redis?.hget(cacheName, key) if (cache === undefined) return try { return JSON.parse(cache) } catch (e) { return cache } } async set ( cacheName: string, key: string, value: any ): Promise { await this._checkReady() const result = await this.redis?.hset( cacheName, key, typeof value === 'object' ? JSON.stringify(value) : value ) return result } async delete (cacheName: string, key: string): Promise { await this._checkReady() const exists = await this.redis?.hexists(cacheName, key) if (exists === 0) return false await this.redis?.hdel(cacheName, key) return true } async array (cacheName: string): Promise { await this._checkReady() const data = await this.redis?.hvals(cacheName) return data?.map((e: string) => JSON.parse(e)) } async deleteCache(cacheName: string): Promise { await this._checkReady() return await this.redis?.del(cacheName) !== 0 } }