UNPKG

@graphql-mesh/cache-redis

Version:
79 lines (78 loc) 2.95 kB
import Redis from 'ioredis'; import RedisMock from 'ioredis-mock'; import { process } from '@graphql-mesh/cross-helpers'; import { stringInterpolator } from '@graphql-mesh/string-interpolation'; function interpolateStrWithEnv(str) { return stringInterpolator.parse(str, { env: process.env }); } export default class RedisCache { constructor(options) { const lazyConnect = options.lazyConnect !== false; if (options.url) { const redisUrl = new URL(interpolateStrWithEnv(options.url)); if (!['redis:', 'rediss:'].includes(redisUrl.protocol)) { throw new Error('Redis URL must use either redis:// or rediss://'); } if (lazyConnect) { redisUrl.searchParams.set('lazyConnect', 'true'); } redisUrl.searchParams.set('enableAutoPipelining', 'true'); redisUrl.searchParams.set('enableOfflineQueue', 'true'); options.logger.debug(`Connecting to Redis at ${redisUrl.toString()}`); this.client = new Redis(redisUrl?.toString()); } else { const parsedHost = interpolateStrWithEnv(options.host?.toString()); const parsedPort = interpolateStrWithEnv(options.port?.toString()); const parsedPassword = interpolateStrWithEnv(options.password?.toString()); if (parsedHost) { options.logger.debug(`Connecting to Redis at ${parsedHost}:${parsedPort}`); this.client = new Redis({ host: parsedHost, port: parseInt(parsedPort), password: parsedPassword, ...(lazyConnect ? { lazyConnect: true } : {}), enableAutoPipelining: true, enableOfflineQueue: true, }); } else { options.logger.debug(`Connecting to Redis mock`); this.client = new RedisMock(); } } const id = options.pubsub.subscribe('destroy', () => { this.client.disconnect(false); options.pubsub.unsubscribe(id); }); } async set(key, value, options) { const stringifiedValue = JSON.stringify(value); if (options?.ttl) { await this.client.set(key, stringifiedValue, 'EX', options.ttl); } else { await this.client.set(key, stringifiedValue); } } async get(key) { const reply = await this.client.get(key); if (reply !== null) { const value = JSON.parse(reply); return value; } return undefined; } async getKeysByPrefix(prefix) { return this.client.keys(`${prefix}*`); } async delete(key) { try { await this.client.del(key); return true; } catch (e) { return false; } } }