All files / apps/web/src/providers cache-db.ts

15% Statements 3/20
0% Branches 0/6
0% Functions 0/4
15% Lines 3/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61                                    6x                                             6x   6x                                  
import { createClient } from "redis";
 
import type { UnauthorizedContext } from "~web/handlers/context";
import { env } from "~web/utils/env";
 
export type CacheDbOptions = {
	mock?: CacheInstance;
};
 
export type CacheInstance = {
	getValue: (key: string) => Promise<string | null>;
	setValue: (
		key: string,
		value: string,
		opts?: { expiryInS?: number },
	) => Promise<void>;
};
 
const getRedisInstance = async (): Promise<CacheInstance> => {
	const database = createClient({
		url: env.CACHE_DATABASE_URL,
		socket: {
			reconnectStrategy: false,
		},
	});
	try {
		await database.connect();
		return {
			getValue: (key) => database.get(key),
			setValue: async (key, value, opts) => {
				if (opts?.expiryInS) {
					await database.setEx(key, opts.expiryInS, value);
				}
				await database.set(key, value);
			},
		};
	} catch {
		throw new Error(`Cache DB did not response to ping`);
	}
};
 
let cacheInstance: CacheInstance | undefined = undefined;
 
export const getCacheInstance = async (
	ctx: UnauthorizedContext,
): Promise<CacheInstance> => {
	if (ctx.cacheDbOptions.mock) {
		return ctx.cacheDbOptions.mock;
	}
 
	if (!cacheInstance) {
		try {
			cacheInstance = await getRedisInstance();
			return cacheInstance;
		} catch {
			throw new Error(`Cache DB did not response to ping`);
		}
	}
	return cacheInstance;
};