UNPKG

ipfs-http-client

Version:
81 lines 2.39 kB
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'; import { toString as uint8ArrayToString } from 'uint8arrays/to-string'; import debug from 'debug'; import { configure } from '../lib/configure.js'; import { toUrlSearchParams } from '../lib/to-url-search-params.js'; const log = debug('ipfs-http-client:pubsub:subscribe'); export const createSubscribe = (options, subsTracker) => { return configure(api => { async function subscribe(topic, handler, options = {}) { options.signal = subsTracker.subscribe(topic, handler, options.signal); let done; let fail; const result = new Promise((resolve, reject) => { done = resolve; fail = reject; }); const ffWorkaround = setTimeout(() => done(), 1000); api.post('pubsub/sub', { signal: options.signal, searchParams: toUrlSearchParams({ arg: topic, ...options }), headers: options.headers }).catch(err => { subsTracker.unsubscribe(topic, handler); fail(err); }).then(response => { clearTimeout(ffWorkaround); if (!response) { return; } readMessages(response, { onMessage: handler, onEnd: () => subsTracker.unsubscribe(topic, handler), onError: options.onError }); done(); }); return result; } return subscribe; })(options); }; async function readMessages(response, {onMessage, onEnd, onError}) { onError = onError || log; try { for await (const msg of response.ndjson()) { try { if (!msg.from) { continue; } onMessage({ from: uint8ArrayToString(uint8ArrayFromString(msg.from, 'base64pad'), 'base58btc'), data: uint8ArrayFromString(msg.data, 'base64pad'), seqno: uint8ArrayFromString(msg.seqno, 'base64pad'), topicIDs: msg.topicIDs }); } catch (err) { err.message = `Failed to parse pubsub message: ${ err.message }`; onError(err, false, msg); } } } catch (err) { if (!isAbortError(err)) { onError(err, true); } } finally { onEnd(); } } const isAbortError = error => { switch (error.type) { case 'aborted': return true; case 'abort': return true; default: return error.name === 'AbortError'; } };