feat: add Redis-backed SSE updates
This commit is contained in:
+56
-8
@@ -1,15 +1,63 @@
|
||||
// @ts-expect-error Bun exposes RedisClient at runtime.
|
||||
import { RedisClient } from "bun";
|
||||
import type { RedisClient } from "bun";
|
||||
|
||||
const globalForRedis = global as unknown as { redis: RedisClient };
|
||||
type RedisConnections = {
|
||||
client: RedisClient;
|
||||
publisher?: Promise<RedisClient>;
|
||||
subscriber?: Promise<RedisClient>;
|
||||
};
|
||||
|
||||
export const getRedisClient = async () => {
|
||||
if (!globalForRedis.redis) {
|
||||
globalForRedis.redis = new RedisClient(process.env.REDIS_URL || "");
|
||||
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.");
|
||||
}
|
||||
const client = globalForRedis.redis;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user