UNPKG

@aptpod/iscp-ts

Version:

iSCP 2.0 client library for TypeScript

217 lines 12 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var _TransportWithReconnect_instances, _TransportWithReconnect_transportBuilder, _TransportWithReconnect_transport, _TransportWithReconnect_reconnectBaseIntervalMs, _TransportWithReconnect_reconnectMaxIntervalMs, _TransportWithReconnect_onReconnectRetryBefore, _TransportWithReconnect_onReconnectSucceeded, _TransportWithReconnect_openedResolver, _TransportWithReconnect_closedResolver, _TransportWithReconnect_lock, _TransportWithReconnect_abortController, _TransportWithReconnect_unreliableRead, _TransportWithReconnect_unreliableWrite; Object.defineProperty(exports, "__esModule", { value: true }); exports.TransportWithReconnect = void 0; const await_lock_1 = __importDefault(require("await-lock")); const constant_1 = require("./constant"); const exceptions_1 = require("./exceptions"); const transport_1 = require("./transport"); const exponential_backoff_1 = require("./utils/exponential-backoff"); const resolver_1 = require("./utils/resolver"); class TransportWithReconnect { constructor(config) { _TransportWithReconnect_instances.add(this); _TransportWithReconnect_transportBuilder.set(this, void 0); _TransportWithReconnect_transport.set(this, void 0); _TransportWithReconnect_reconnectBaseIntervalMs.set(this, void 0); _TransportWithReconnect_reconnectMaxIntervalMs.set(this, void 0); _TransportWithReconnect_onReconnectRetryBefore.set(this, void 0); _TransportWithReconnect_onReconnectSucceeded.set(this, void 0); _TransportWithReconnect_openedResolver.set(this, void 0); _TransportWithReconnect_closedResolver.set(this, void 0); _TransportWithReconnect_lock.set(this, void 0); _TransportWithReconnect_abortController.set(this, void 0); __classPrivateFieldSet(this, _TransportWithReconnect_transportBuilder, config.transportBuilder, "f"); __classPrivateFieldSet(this, _TransportWithReconnect_transport, null, "f"); __classPrivateFieldSet(this, _TransportWithReconnect_reconnectBaseIntervalMs, config.reconnectBaseIntervalMs, "f"); __classPrivateFieldSet(this, _TransportWithReconnect_reconnectMaxIntervalMs, config.reconnectMaxIntervalMs, "f"); __classPrivateFieldSet(this, _TransportWithReconnect_onReconnectRetryBefore, config.onReconnectRetryBefore, "f"); __classPrivateFieldSet(this, _TransportWithReconnect_onReconnectSucceeded, config.onReconnectSucceeded, "f"); __classPrivateFieldSet(this, _TransportWithReconnect_openedResolver, new resolver_1.Resolver(), "f"); __classPrivateFieldSet(this, _TransportWithReconnect_closedResolver, new resolver_1.Resolver(), "f"); __classPrivateFieldSet(this, _TransportWithReconnect_lock, { read: new await_lock_1.default(), write: new await_lock_1.default(), unreliableRead: new await_lock_1.default(), unreliableWrite: new await_lock_1.default(), reconnect: new await_lock_1.default(), }, "f"); __classPrivateFieldSet(this, _TransportWithReconnect_abortController, new AbortController(), "f"); } async open() { if (__classPrivateFieldGet(this, _TransportWithReconnect_openedResolver, "f").isDone) { throw new exceptions_1.ISCPException('Already opened.'); } __classPrivateFieldSet(this, _TransportWithReconnect_transport, await __classPrivateFieldGet(this, _TransportWithReconnect_transportBuilder, "f").call(this), "f"); __classPrivateFieldGet(this, _TransportWithReconnect_openedResolver, "f").resolve(); } async close() { if (!__classPrivateFieldGet(this, _TransportWithReconnect_openedResolver, "f").isDone) { return; } if (__classPrivateFieldGet(this, _TransportWithReconnect_closedResolver, "f").isDone) { return; } try { __classPrivateFieldGet(this, _TransportWithReconnect_abortController, "f").abort(); await __classPrivateFieldGet(this, _TransportWithReconnect_transport, "f")?.close(); } finally { __classPrivateFieldGet(this, _TransportWithReconnect_closedResolver, "f").resolve(); await forceReleaseLock(Object.values(__classPrivateFieldGet(this, _TransportWithReconnect_lock, "f"))); } } async reconnect() { if (__classPrivateFieldGet(this, _TransportWithReconnect_closedResolver, "f").isDone) { return; } const jitter = new exponential_backoff_1.Jitter({ ratioCreator: Math.random, min: constant_1.RECONNECT_JITTER_MIN, max: constant_1.RECONNECT_JITTER_MAX, }); const backoff = new exponential_backoff_1.ExponentialBackoff({ run: async () => { if (__classPrivateFieldGet(this, _TransportWithReconnect_closedResolver, "f").isDone) { return; } await __classPrivateFieldGet(this, _TransportWithReconnect_transport, "f")?.close(); __classPrivateFieldSet(this, _TransportWithReconnect_transport, await __classPrivateFieldGet(this, _TransportWithReconnect_transportBuilder, "f").call(this), "f"); await __classPrivateFieldGet(this, _TransportWithReconnect_onReconnectSucceeded, "f").call(this); }, signal: __classPrivateFieldGet(this, _TransportWithReconnect_abortController, "f").signal, baseTimeoutMs: __classPrivateFieldGet(this, _TransportWithReconnect_reconnectBaseIntervalMs, "f"), maxTimeoutMs: __classPrivateFieldGet(this, _TransportWithReconnect_reconnectMaxIntervalMs, "f"), numOfAttempts: constant_1.RECONNECT_NUM_OF_ATTEMPTS, jitter, }); backoff.onBeforeRetry = ({ error }) => { __classPrivateFieldGet(this, _TransportWithReconnect_onReconnectRetryBefore, "f").call(this, { error }); }; const { releaseLock } = await acquireLock([__classPrivateFieldGet(this, _TransportWithReconnect_lock, "f").reconnect]); try { const result = await backoff.start(); if (result instanceof exponential_backoff_1.AbortedError) { return; } if (result instanceof Error) { throw result; } } finally { await releaseLock(); } } async read() { const { releaseLock } = await acquireLock([__classPrivateFieldGet(this, _TransportWithReconnect_lock, "f").read]); try { return await asTransport(__classPrivateFieldGet(this, _TransportWithReconnect_transport, "f")).read(); } finally { await releaseLock(); } } async write(message) { const { releaseLock } = await acquireLock([__classPrivateFieldGet(this, _TransportWithReconnect_lock, "f").write]); try { await asTransport(__classPrivateFieldGet(this, _TransportWithReconnect_transport, "f")).write(message); } finally { await releaseLock(); } } getUnreliable() { const transport = asTransport(__classPrivateFieldGet(this, _TransportWithReconnect_transport, "f")); return transport instanceof transport_1.Unreliable ? { read: __classPrivateFieldGet(this, _TransportWithReconnect_instances, "m", _TransportWithReconnect_unreliableRead).bind(this), write: __classPrivateFieldGet(this, _TransportWithReconnect_instances, "m", _TransportWithReconnect_unreliableWrite).bind(this), } : false; } get address() { return asTransport(__classPrivateFieldGet(this, _TransportWithReconnect_transport, "f")).address; } get negotiationParams() { return asTransport(__classPrivateFieldGet(this, _TransportWithReconnect_transport, "f")).negotiationParams; } get name() { return asTransport(__classPrivateFieldGet(this, _TransportWithReconnect_transport, "f")).name; } } exports.TransportWithReconnect = TransportWithReconnect; _TransportWithReconnect_transportBuilder = new WeakMap(), _TransportWithReconnect_transport = new WeakMap(), _TransportWithReconnect_reconnectBaseIntervalMs = new WeakMap(), _TransportWithReconnect_reconnectMaxIntervalMs = new WeakMap(), _TransportWithReconnect_onReconnectRetryBefore = new WeakMap(), _TransportWithReconnect_onReconnectSucceeded = new WeakMap(), _TransportWithReconnect_openedResolver = new WeakMap(), _TransportWithReconnect_closedResolver = new WeakMap(), _TransportWithReconnect_lock = new WeakMap(), _TransportWithReconnect_abortController = new WeakMap(), _TransportWithReconnect_instances = new WeakSet(), _TransportWithReconnect_unreliableRead = // // Private Methods // async function _TransportWithReconnect_unreliableRead() { const { releaseLock } = await acquireLock([__classPrivateFieldGet(this, _TransportWithReconnect_lock, "f").unreliableRead]); try { const transport = asTransport(__classPrivateFieldGet(this, _TransportWithReconnect_transport, "f")); const { reader } = asUnreliable(transport).getUnreliable(); return await reader.read(); } finally { await releaseLock(); } }, _TransportWithReconnect_unreliableWrite = async function _TransportWithReconnect_unreliableWrite(message) { const { releaseLock } = await acquireLock([__classPrivateFieldGet(this, _TransportWithReconnect_lock, "f").unreliableWrite]); try { const transport = asTransport(__classPrivateFieldGet(this, _TransportWithReconnect_transport, "f")); const { writer } = asUnreliable(transport).getUnreliable(); return await writer.write(message); } finally { await releaseLock(); } }; // // Static Functions // const asTransport = (maybeTransport) => { if (!maybeTransport) { throw new exceptions_1.ISCPTransportClosedError(); } return maybeTransport; }; const asUnreliable = (maybeUnreliable) => { if (!(maybeUnreliable instanceof transport_1.Unreliable)) { throw new exceptions_1.ISCPException('Unsupported unreliable transport.'); } return maybeUnreliable; }; const acquireLock = async (awaitLocks) => { for (const awaitLock of awaitLocks) { await awaitLock.acquireAsync(); } const releaseLock = async () => { for (const awaitLock of awaitLocks) { awaitLock.release(); } }; return { releaseLock, }; }; const forceReleaseLock = async (awaitLocks) => { for (const awaitLock of awaitLocks) { if (awaitLock.acquired) { awaitLock.release(); } } }; //# sourceMappingURL=transport-with-reconnect.js.map