@boringnode/bus
Version:
A simple and lean driver-based service bus implementation
100 lines (99 loc) • 2.97 kB
JavaScript
import {
JsonEncoder,
tryDecodeTransportMessage
} from "../../chunk-DZUPXJD3.js";
import {
debug_default
} from "../../chunk-6ST7Q25E.js";
// src/transports/redis.ts
import { Redis, Cluster } from "ioredis";
import { assert } from "@poppinss/utils/assert";
function redis(config, encoder) {
return () => new RedisTransport(config, encoder);
}
var RedisTransport = class {
#publisher;
#subscriber;
#encoder;
#useMessageBuffer = false;
#handlers = /* @__PURE__ */ new Map();
#id;
constructor(options, encoder, transportOptions) {
this.#encoder = encoder ?? new JsonEncoder();
if (options instanceof Redis || options instanceof Cluster) {
this.#publisher = options.duplicate();
this.#subscriber = options.duplicate();
this.#useMessageBuffer = transportOptions?.useMessageBuffer ?? false;
} else {
this.#publisher = new Redis(options);
this.#subscriber = new Redis(options);
if (typeof options === "object") {
this.#useMessageBuffer = options.useMessageBuffer ?? false;
}
}
const event = this.#useMessageBuffer ? "messageBuffer" : "message";
this.#subscriber.on(event, this.#onMessage);
}
setId(id) {
this.#id = id;
return this;
}
async disconnect() {
await Promise.all([this.#publisher.quit(), this.#subscriber.quit()]);
}
async publish(channel, message) {
assert(this.#id, "You must set an id before publishing a message");
const encoded = this.#encoder.encode({ payload: message, busId: this.#id });
await this.#publisher.publish(channel, encoded);
}
async subscribe(channel, handler) {
const handlers = this.#handlers.get(channel) ?? [];
handlers.push(handler);
this.#handlers.set(channel, handlers);
try {
await this.#subscriber.subscribe(channel);
} catch (error) {
handlers.splice(handlers.indexOf(handler), 1);
if (handlers.length === 0) {
this.#handlers.delete(channel);
}
throw error;
}
}
onReconnect(callback) {
this.#subscriber.on("reconnecting", callback);
}
async unsubscribe(channel) {
await this.#subscriber.unsubscribe(channel);
this.#handlers.delete(channel);
}
#onMessage = (receivedChannel, message) => {
const channel = receivedChannel.toString();
const handlers = this.#handlers.get(channel);
if (!handlers) return;
debug_default('received message for channel "%s"', channel);
const data = tryDecodeTransportMessage(this.#encoder, message);
if (!data) {
debug_default('ignoring invalid message for channel "%s"', channel);
return;
}
if (data.busId === this.#id) {
debug_default("ignoring message published by the same bus instance");
return;
}
for (const handler of handlers) {
handler(data.payload);
}
};
};
export {
RedisTransport,
redis
};
/**
* @boringnode/bus
*
* @license MIT
* @copyright BoringNode
*/
//# sourceMappingURL=redis.js.map