60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
import type { Handler, PubSubDriver } from "./index.ts";
|
|
|
|
export interface NatsClient {
|
|
publish(subject: string, data: Uint8Array): void | Promise<void>;
|
|
subscribe(subject: string, handler: (data: Uint8Array, subject: string) => void): () => void;
|
|
close?(): void | Promise<void>;
|
|
}
|
|
|
|
export function natsDriver(client: NatsClient): PubSubDriver {
|
|
const encoder = new TextEncoder();
|
|
const decoder = new TextDecoder();
|
|
return {
|
|
publish(topic, message) {
|
|
return client.publish(topic, encoder.encode(JSON.stringify(message)));
|
|
},
|
|
subscribe(pattern, handler) {
|
|
const subject =
|
|
pattern === "*" ? ">" : pattern.endsWith(":*") ? `${pattern.slice(0, -2)}:>` : pattern;
|
|
return client.subscribe(subject, (data, topic) => {
|
|
const raw = decoder.decode(data);
|
|
let value: unknown = raw;
|
|
try {
|
|
value = JSON.parse(raw);
|
|
} catch {
|
|
/* raw broker payload */
|
|
}
|
|
void handler(value, topic);
|
|
});
|
|
},
|
|
close: () => client.close?.(),
|
|
};
|
|
}
|
|
|
|
export interface KafkaClient {
|
|
publish(topic: string, value: string): void | Promise<void>;
|
|
subscribe(pattern: string, handler: (value: string, topic: string) => void): () => void;
|
|
close?(): void | Promise<void>;
|
|
}
|
|
|
|
/** Kafka adapter contract; consumer-group/rebalance policy remains owned by the selected client. */
|
|
export function kafkaDriver(client: KafkaClient): PubSubDriver {
|
|
return {
|
|
publish(topic, message) {
|
|
return client.publish(topic, JSON.stringify(message));
|
|
},
|
|
subscribe(pattern, handler: Handler) {
|
|
return client.subscribe(pattern, (raw, topic) => {
|
|
let value: unknown = raw;
|
|
try {
|
|
value = JSON.parse(raw);
|
|
} catch {
|
|
/* raw broker payload */
|
|
}
|
|
void handler(value, topic);
|
|
});
|
|
},
|
|
close: () => client.close?.(),
|
|
};
|
|
}
|