@ceramicnetwork/core
Version:
Typescript implementation of the Ceramic protocol
76 lines • 3.24 kB
JavaScript
import { Observable } from 'rxjs';
import { pipe } from 'rxjs';
import { map, filter, concatMap, retryWhen, tap, delay } from 'rxjs/operators';
import { TaskQueue } from '../ancillary/task-queue.js';
export class PubsubIncoming extends Observable {
constructor(ipfs, topic, pubsubLogger, logger, tasks) {
super((subscriber) => {
const onMessage = (message) => subscriber.next(message);
const onError = (error) => subscriber.error(error);
this.tasks
.run(async () => {
const ipfsId = await this.ipfs.id();
const peerId = ipfsId.id;
await ipfs.pubsub.subscribe(topic, onMessage, { onError });
pubsubLogger.log({ peer: peerId, event: 'subscribed', topic: topic });
})
.catch(onError);
return () => {
this.tasks.clear();
this.tasks.add(async () => {
await ipfs.pubsub?.unsubscribe(topic, onMessage).catch((err) => {
this.logger.warn(err);
});
});
};
});
this.ipfs = ipfs;
this.topic = topic;
this.pubsubLogger = pubsubLogger;
this.logger = logger;
this.tasks = tasks;
this.tasks = new TaskQueue();
}
}
export class IncomingChannel extends Observable {
constructor(ipfs, topic, resubscribeEvery, lateMessageAfter, pubsubLogger, logger, tasks = new TaskQueue()) {
super((subscriber) => {
const subscription = new PubsubIncoming(ipfs, topic, pubsubLogger, logger, this.tasks)
.pipe(checkSlowObservable(lateMessageAfter, logger, 'IPFS did not provide any messages, please check your IPFS configuration and ensure your node is well connected to the rest of the Ceramic network.'), retryWhen((errors) => errors.pipe(tap((e) => logger.err(e)), delay(resubscribeEvery))))
.subscribe(subscriber);
return () => {
subscription.unsubscribe();
};
});
this.ipfs = ipfs;
this.topic = topic;
this.resubscribeEvery = resubscribeEvery;
this.lateMessageAfter = lateMessageAfter;
this.pubsubLogger = pubsubLogger;
this.logger = logger;
this.tasks = tasks;
}
}
export function filterExternal(ownPeerId$) {
return pipe(filter((message) => message.type === 'signed'), concatMap((data) => {
return ownPeerId$.pipe(map((peerId) => {
return { isOuter: data.from.toString() !== peerId, entry: data };
}));
}), filter((data) => data.isOuter), map((data) => data.entry));
}
export function checkSlowObservable(delay, logger, description) {
const createTimeout = () => {
return setTimeout(() => {
logger.warn(`Did not receive any pubsub messages in more than ${delay}ms. ${description}`);
}, delay);
};
let outstanding = createTimeout();
return pipe(tap({
next: () => {
clearTimeout(outstanding);
outstanding = createTimeout();
},
complete: () => clearTimeout(outstanding),
}));
}
//# sourceMappingURL=incoming-channel.js.map