@waku/sdk
Version:
A unified SDK for easy creation and management of js-waku nodes.
96 lines • 4.18 kB
JavaScript
import { FilterCore } from "@waku/core";
import { Logger } from "@waku/utils";
import { Subscription } from "./subscription.js";
const log = new Logger("sdk:filter");
export class Filter {
protocol;
peerManager;
config;
subscriptions = new Map();
constructor(params) {
this.config = {
numPeersToUse: 2,
pingsBeforePeerRenewed: 3,
keepAliveIntervalMs: 60_000,
...params.options
};
this.peerManager = params.peerManager;
this.protocol = new FilterCore(this.onIncomingMessage.bind(this), params.libp2p);
}
get multicodec() {
return this.protocol.multicodec;
}
unsubscribeAll() {
for (const subscription of this.subscriptions.values()) {
subscription.stop();
}
this.subscriptions.clear();
}
async subscribe(decoder, callback) {
const decoders = Array.isArray(decoder) ? decoder : [decoder];
if (decoders.length === 0) {
throw Error("Cannot subscribe with 0 decoders.");
}
const pubsubTopics = decoders.map((v) => v.pubsubTopic);
const singlePubsubTopic = pubsubTopics[0];
const contentTopics = decoders.map((v) => v.contentTopic);
log.info(`Subscribing to contentTopics: ${contentTopics}, pubsubTopic: ${singlePubsubTopic}`);
this.throwIfTopicNotSame(pubsubTopics);
let subscription = this.subscriptions.get(singlePubsubTopic);
if (!subscription) {
subscription = new Subscription({
pubsubTopic: singlePubsubTopic,
protocol: this.protocol,
config: this.config,
peerManager: this.peerManager
});
subscription.start();
}
const result = await subscription.add(decoders, callback);
this.subscriptions.set(singlePubsubTopic, subscription);
log.info(`Subscription ${result ? "successful" : "failed"} for content topic: ${contentTopics}`);
return result;
}
async unsubscribe(decoder) {
const decoders = Array.isArray(decoder) ? decoder : [decoder];
if (decoders.length === 0) {
throw Error("Cannot unsubscribe with 0 decoders.");
}
const pubsubTopics = decoders.map((v) => v.pubsubTopic);
const singlePubsubTopic = pubsubTopics[0];
const contentTopics = decoders.map((v) => v.contentTopic);
log.info(`Unsubscribing from contentTopics: ${contentTopics}, pubsubTopic: ${singlePubsubTopic}`);
this.throwIfTopicNotSame(pubsubTopics);
const subscription = this.subscriptions.get(singlePubsubTopic);
if (!subscription) {
log.warn("No subscriptions associated with the decoder.");
return false;
}
const result = await subscription.remove(decoders);
if (subscription.isEmpty()) {
log.warn("Subscription has no decoders anymore, terminating it.");
subscription.stop();
this.subscriptions.delete(singlePubsubTopic);
}
log.info(`Unsubscribing ${result ? "successful" : "failed"} for content topic: ${contentTopics}`);
return result;
}
async onIncomingMessage(pubsubTopic, message, peerId) {
log.info(`Received message for pubsubTopic:${pubsubTopic}, contentTopic:${message.contentTopic}, peerId:${peerId.toString()}`);
const subscription = this.subscriptions.get(pubsubTopic);
if (!subscription) {
log.error(`No subscription locally registered for topic ${pubsubTopic}`);
return;
}
subscription.invoke(message, peerId);
}
// Limiting to one pubsubTopic for simplicity reasons, we can enable subscription for more than one PubsubTopic at once later when requested
throwIfTopicNotSame(pubsubTopics) {
const first = pubsubTopics[0];
const isSameTopic = pubsubTopics.every((t) => t === first);
if (!isSameTopic) {
throw Error(`Cannot subscribe to more than one pubsub topic at the same time, got pubsubTopics:${pubsubTopics}`);
}
}
}
//# sourceMappingURL=filter.js.map