ipfs-http-client
Version:
A client library for the IPFS HTTP API
93 lines (86 loc) • 2.69 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var fromString = require('uint8arrays/from-string');
var toString = require('uint8arrays/to-string');
var debug = require('debug');
var configure = require('../lib/configure.js');
var toUrlSearchParams = require('../lib/to-url-search-params.js');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var debug__default = /*#__PURE__*/_interopDefaultLegacy(debug);
const log = debug__default["default"]('ipfs-http-client:pubsub:subscribe');
const createSubscribe = (options, subsTracker) => {
return configure.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.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: toString.toString(fromString.fromString(msg.from, 'base64pad'), 'base58btc'),
data: fromString.fromString(msg.data, 'base64pad'),
seqno: fromString.fromString(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';
}
};
exports.createSubscribe = createSubscribe;