UNPKG

@daiso-tech/core

Version:

The library offers flexible, framework-agnostic solutions for modern web applications, built on adaptable components that integrate seamlessly with popular frameworks like Next Js.

124 lines (122 loc) 4.63 kB
/** * @module Cache */ import { TypeCacheError, } from "../../../../cache/contracts/_module-exports.js"; import { ReplyError } from "ioredis"; import { ClearIterable } from "../../../../cache/implementations/adapters/redis-cache-adapter/utilities.js"; import { RedisCacheAdapterSerde } from "../../../../cache/implementations/adapters/redis-cache-adapter/redis-cache-adapter-serde.js"; /** * To utilize the `RedisCacheAdapter`, you must install the `"ioredis"` package and supply a {@link ISerde | `ISerde<string>`}, with adapter like {@link SuperJsonSerdeAdapter | `SuperJsonSerdeAdapter `}. * * IMPORT_PATH: `"@daiso-tech/core/cache/adapters"` * @group Adapters */ export class RedisCacheAdapter { static isRedisTypeError( // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types value) { // eslint-disable-next-line @typescript-eslint/no-unsafe-return return (value instanceof ReplyError && // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access value.message.includes("ERR value is not a valid float")); } serde; database; /** * @example * ```ts * import { RedisCacheAdapter } from "@daiso-tech/core/cache/adapters"; * import { Serde } from "@daiso-tech/core/serde"; * import { SuperJsonSerdeAdapter } from "@daiso-tech/core/serde/adapters" * import Redis from "ioredis"; * * const database = new Redis("YOUR_REDIS_CONNECTION_STRING"); * const serde = new Serde(new SuperJsonSerdeAdapter()); * const cacheAdapter = new RedisCacheAdapter({ * database, * serde, * }); * ``` */ constructor(settings) { const { database, serde } = settings; this.database = database; this.serde = new RedisCacheAdapterSerde(serde); this.initIncrementCommand(); } initIncrementCommand() { if (typeof this.database.daiso_cache_increment === "function") { return; } this.database.defineCommand("daiso_cache_increment", { numberOfKeys: 1, lua: ` local hasKey = redis.call("exists", KEYS[1]) if hasKey == 1 then redis.call("incrbyfloat", KEYS[1], tonumber(ARGV[1])) end return hasKey `, }); } async get(key) { const value = await this.database.get(key); if (value === null) { return null; } return await this.serde.deserialize(value); } async getAndRemove(key) { const value = await this.database.getdel(key); if (value === null) { return null; } return this.serde.deserialize(value); } async add(key, value, ttl) { if (ttl === null) { const result = await this.database.set(key, this.serde.serialize(value), "NX"); return result === "OK"; } const result = await this.database.set(key, this.serde.serialize(value), "PX", ttl.toMilliseconds(), "NX"); return result === "OK"; } async put(key, value, ttl) { if (ttl === null) { const result = await this.database.set(key, this.serde.serialize(value), "GET"); return result !== null; } const result = await this.database.set(key, this.serde.serialize(value), "PX", ttl.toMilliseconds(), "GET"); return result !== null; } async update(key, value) { const result = await this.database.set(key, this.serde.serialize(value), "XX"); return result === "OK"; } async increment(key, value) { try { const redisResult = await this.database.daiso_cache_increment(key, this.serde.serialize(value)); const keyExists = redisResult === 1; return keyExists; } catch (error) { if (!RedisCacheAdapter.isRedisTypeError(error)) { throw error; } throw new TypeCacheError(`Unable to increment or decrement none number type key "${key}"`); } } async removeMany(keys) { const deleteResult = await this.database.del(...keys); return deleteResult > 0; } async removeAll() { await this.database.flushdb(); } async removeByKeyPrefix(prefix) { for await (const _ of new ClearIterable(this.database, prefix)) { /* Empty */ } } } //# sourceMappingURL=redis-cache-adapter.js.map