UNPKG

kubo-rpc-client-esm-cjs

Version:
179 lines 8.46 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __asyncValues = (this && this.__asyncValues) || function (o) { if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); var m = o[Symbol.asyncIterator], i; return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createSubscribe = void 0; const logger_1 = require("@libp2p/logger"); const configure_js_1 = require("../lib/configure.js"); const to_url_search_params_js_1 = require("../lib/to-url-search-params.js"); const http_rpc_wire_format_js_1 = require("../lib/http-rpc-wire-format.js"); const peer_id_1 = require("@libp2p/peer-id"); const log = (0, logger_1.logger)('js-kubo-rpc-client:pubsub:subscribe'); /** * @param {import('../types').Options} options * @param {import('./subscription-tracker').SubscriptionTracker} subsTracker */ const createSubscribe = (options, subsTracker) => { return (0, configure_js_1.configure)((api) => { /** * @type {import('../types').PubsubAPI["subscribe"]} */ function subscribe(topic, handler, options = {}) { return __awaiter(this, void 0, void 0, function* () { options.signal = subsTracker.subscribe(topic, handler, options.signal); /** @type {(value?: any) => void} */ let done; /** @type {(error: Error) => void} */ let fail; const result = new Promise((resolve, reject) => { done = resolve; fail = reject; }); // In Firefox, the initial call to fetch does not resolve until some data // is received. If this doesn't happen within 1 second assume success const ffWorkaround = setTimeout(() => done(), 1000); // Do this async to not block Firefox api.post('pubsub/sub', { signal: options.signal, searchParams: (0, to_url_search_params_js_1.toUrlSearchParams)(Object.assign({ arg: (0, http_rpc_wire_format_js_1.textToUrlSafeRpc)(topic) }, options)), headers: options.headers }) .catch((err) => { // Initial subscribe fail, ensure we clean up subsTracker.unsubscribe(topic, handler); fail(err); }) .then((response) => { clearTimeout(ffWorkaround); if (!response) { // if there was no response, the subscribe failed return; } readMessages(response, { onMessage: (message) => { if (!handler) { return; } if (typeof handler === 'function') { handler(message); return; } if (typeof handler.handleEvent === 'function') { handler.handleEvent(message); } }, onEnd: () => subsTracker.unsubscribe(topic, handler), onError: options.onError }); done(); }); return result; }); } return subscribe; })(options); }; exports.createSubscribe = createSubscribe; /** * @param {import('../types').ExtendedResponse} response * @param {object} options * @param {(message: import('../types').Message) => void} options.onMessage * @param {() => void} options.onEnd * @param {import('../types').PubsubApiErrorHandlerFn} [options.onError] */ function readMessages(response, { onMessage, onEnd, onError }) { var _a, e_1, _b, _c; var _d, _e; return __awaiter(this, void 0, void 0, function* () { onError = onError || log; try { try { for (var _f = true, _g = __asyncValues(response.ndjson()), _h; _h = yield _g.next(), _a = _h.done, !_a;) { _c = _h.value; _f = false; try { const msg = _c; try { if (!msg.from) { // eslint-disable-next-line no-continue continue; } if (msg.from != null && msg.seqno != null) { onMessage({ type: 'signed', from: (0, peer_id_1.peerIdFromString)(msg.from), data: (0, http_rpc_wire_format_js_1.rpcToBytes)(msg.data), sequenceNumber: (0, http_rpc_wire_format_js_1.rpcToBigInt)(msg.seqno), topic: (0, http_rpc_wire_format_js_1.rpcToText)(msg.topicIDs[0]), key: (0, http_rpc_wire_format_js_1.rpcToBytes)((_d = msg.key) !== null && _d !== void 0 ? _d : 'u'), signature: (0, http_rpc_wire_format_js_1.rpcToBytes)((_e = msg.signature) !== null && _e !== void 0 ? _e : 'u') }); } else { onMessage({ type: 'unsigned', data: (0, http_rpc_wire_format_js_1.rpcToBytes)(msg.data), topic: (0, http_rpc_wire_format_js_1.rpcToText)(msg.topicIDs[0]) }); } } catch ( /** @type {any} */err) { err.message = `Failed to parse pubsub message: ${err.message}`; onError(err, false, msg); // Not fatal } } finally { _f = true; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (!_f && !_a && (_b = _g.return)) yield _b.call(_g); } finally { if (e_1) throw e_1.error; } } } catch ( /** @type {any} */err) { if (!isAbortError(err)) { onError(err, true); // Fatal } } finally { onEnd(); } }); } /** * @param {Error & {type?:string}} error * @returns {boolean} */ const isAbortError = error => { switch (error.type) { case 'aborted': return true; // It is `abort` in Electron instead of `aborted` case 'abort': return true; default: // FIXME: In testing with Chrome, err.type is undefined (should not be!) // Temporarily use the name property instead. return error.name === 'AbortError'; } }; //# sourceMappingURL=subscribe.js.map