alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
99 lines (85 loc) • 2.61 kB
text/typescript
import { $hook, $inject, Alepha, AlephaError } from "alepha";
import { $logger } from "alepha/logger";
import {
type NodeRedisClient,
NodeRedisProvider,
} from "./NodeRedisProvider.ts";
import {
RedisSubscriberProvider,
type SubscribeCallback,
} from "./RedisSubscriberProvider.ts";
/**
* Node.js Redis subscriber provider using `@redis/client`.
*
* This provider creates a dedicated Redis connection for subscriptions,
* as Redis requires separate connections for pub/sub operations.
*
* @example
* ```ts
* const subscriber = alepha.inject(RedisSubscriberProvider);
* await subscriber.subscribe("channel", (message, channel) => {
* console.log(`Received: ${message} on ${channel}`);
* });
* ```
*/
export class NodeRedisSubscriberProvider extends RedisSubscriberProvider {
protected readonly log = $logger();
protected readonly alepha = $inject(Alepha);
protected readonly redisProvider = $inject(NodeRedisProvider);
protected readonly client: NodeRedisClient = this.createClient();
public get subscriber(): NodeRedisClient {
if (!this.client.isReady) {
throw new AlephaError("Redis subscriber client is not ready");
}
return this.client;
}
public override get isReady(): boolean {
return this.client.isReady;
}
protected readonly start = $hook({
on: "start",
handler: () => this.connect(),
});
protected readonly stop = $hook({
on: "stop",
handler: () => this.close(),
});
public override async connect(): Promise<void> {
this.log.debug("Connecting subscriber...");
await this.client.connect();
this.log.info("Subscriber connection OK");
}
public override async close(): Promise<void> {
if (!this.client.isReady) {
this.log.debug("Subscriber client not ready, skipping close");
return;
}
this.log.debug("Closing subscriber connection...");
await this.client.close();
this.log.info("Subscriber connection closed");
}
public override async subscribe(
channel: string,
callback: SubscribeCallback,
): Promise<void> {
await this.subscriber.subscribe(channel, callback);
}
public override async unsubscribe(
channel: string,
callback?: SubscribeCallback,
): Promise<void> {
await this.subscriber.unsubscribe(channel, callback);
}
/**
* Redis subscriber client factory method.
*/
protected createClient(): NodeRedisClient {
const client = this.redisProvider.duplicate();
client.on("error", (error) => {
if (this.alepha.isStarted()) {
this.log.error(error);
}
});
return client;
}
}