64 lines
1.4 KiB
TypeScript
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");
|
|
}
|