Files
erika/lib/redis.ts
T

64 lines
1.4 KiB
TypeScript

import type { RedisClient } from "bun";
type RedisConnections = {
client: RedisClient;
publisher?: Promise<RedisClient>;
subscriber?: Promise<RedisClient>;
};
const globalForRedis = globalThis as typeof globalThis & {
erikaRedis?: RedisConnections;
};
function getRedisConnections() {
if (typeof Bun === "undefined") {
throw new Error("Redis is only available on the Bun server runtime.");
}
if (!globalForRedis.erikaRedis) {
globalForRedis.erikaRedis = { client: Bun.redis };
}
return globalForRedis.erikaRedis;
}
async function connect(client: RedisClient) {
if (!client.connected) {
await client.connect();
}
return client;
}
function duplicateConnection(kind: "publisher" | "subscriber") {
const connections = getRedisConnections();
const existing = connections[kind];
if (existing) {
return existing;
}
const pending = connect(connections.client)
.then((client) => client.duplicate())
.then(connect);
connections[kind] = pending;
void pending.catch(() => {
if (connections[kind] === pending) {
connections[kind] = undefined;
}
});
return pending;
}
export async function getRedisClient() {
return connect(getRedisConnections().client);
}
export function getRedisPublisher() {
return duplicateConnection("publisher");
}
export function getRedisSubscriber() {
return duplicateConnection("subscriber");
}