UNPKG

@aptpod/iscp-ts

Version:

iSCP 2.0 client library for TypeScript

381 lines 23.3 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 _Wire_instances, _Wire_requestSequence, _Wire_reader, _Wire_writer, _Wire_unreliableReader, _Wire_unreliableWriter, _Wire_pingTimeout, _Wire_pingInterval, _Wire_logger, _Wire_replyMessageTransformStreamMap, _Wire_replyCallTransformStreamMap, _Wire_abortController, _Wire_cancelledResolver, _Wire_requestPing, _Wire_sendPong, _Wire_sendMessageAndWaitResponse, _Wire_readLoop, _Wire_readUnreliableLoop, _Wire_keepAliveLoop; Object.defineProperty(exports, "__esModule", { value: true }); exports.Wire = void 0; const web_streams_polyfill_1 = require("web-streams-polyfill"); const exceptions_1 = require("./exceptions"); const message_1 = require("./message"); const constant_1 = require("./constant"); const ticker_1 = require("./utils/ticker"); const timeout_1 = require("./utils/timeout"); const resolver_1 = require("./utils/resolver"); const signal_abort_listener_1 = require("./utils/signal-abort-listener"); const CANCEL = 'cancel'; class Wire { constructor(config) { _Wire_instances.add(this); _Wire_requestSequence.set(this, void 0); _Wire_reader.set(this, void 0); _Wire_writer.set(this, void 0); _Wire_unreliableReader.set(this, void 0); _Wire_unreliableWriter.set(this, void 0); _Wire_pingTimeout.set(this, void 0); _Wire_pingInterval.set(this, void 0); _Wire_logger.set(this, void 0); _Wire_replyMessageTransformStreamMap.set(this, void 0); _Wire_replyCallTransformStreamMap.set(this, void 0); _Wire_abortController.set(this, void 0); _Wire_cancelledResolver.set(this, void 0); __classPrivateFieldSet(this, _Wire_requestSequence, config.requestSequence, "f"); __classPrivateFieldSet(this, _Wire_reader, config.reader, "f"); __classPrivateFieldSet(this, _Wire_writer, config.writer, "f"); __classPrivateFieldSet(this, _Wire_unreliableReader, config.unreliableReader, "f"); __classPrivateFieldSet(this, _Wire_unreliableWriter, config.unreliableWriter, "f"); __classPrivateFieldSet(this, _Wire_pingInterval, config.pingInterval, "f"); __classPrivateFieldSet(this, _Wire_pingTimeout, config.pingTimeout, "f"); __classPrivateFieldSet(this, _Wire_logger, config.logger, "f"); __classPrivateFieldSet(this, _Wire_replyMessageTransformStreamMap, new Map(), "f"); __classPrivateFieldSet(this, _Wire_replyCallTransformStreamMap, new Map(), "f"); __classPrivateFieldSet(this, _Wire_abortController, new AbortController(), "f"); __classPrivateFieldSet(this, _Wire_cancelledResolver, new resolver_1.Resolver(), "f"); this.onDisconnect = async () => { }; this.onUpstreamChunkAck = async () => { }; this.onDownstreamChunk = async () => { }; this.onDownstreamMetadata = async () => { }; this.onDownstreamChunkAckComplete = async () => { }; this.onDownstreamCall = async () => { }; this.onPingTimeout = async () => { }; this.onError = async () => { }; } async start() { await Promise.all([__classPrivateFieldGet(this, _Wire_instances, "m", _Wire_readLoop).call(this), __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_readUnreliableLoop).call(this), __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_keepAliveLoop).call(this)]).finally(() => { __classPrivateFieldGet(this, _Wire_cancelledResolver, "f").resolve(); }); } async cancel() { __classPrivateFieldGet(this, _Wire_abortController, "f").abort(); await __classPrivateFieldGet(this, _Wire_cancelledResolver, "f").wait(); } async connect(request) { request.requestId = __classPrivateFieldGet(this, _Wire_requestSequence, "f").next(); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send ConnectRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: message_1.ConnectResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `recv ConnectResponse. [requestId=${response.requestId}]`); return response; } async disconnect(request) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, 'send Disconnect.'); await __classPrivateFieldGet(this, _Wire_writer, "f").call(this, request); } async openUpstream(request) { request.requestId = __classPrivateFieldGet(this, _Wire_requestSequence, "f").next(); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send UpstreamOpenRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: message_1.UpstreamOpenResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive UpstreamOpenResponse. [requestId=${response.requestId}]`); return response; } async resumeUpstream(request) { request.requestId = __classPrivateFieldGet(this, _Wire_requestSequence, "f").next(); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send UpstreamResumeRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: message_1.UpstreamResumeResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive UpstreamResumeResponse. [requestId=${response.requestId}]`); return response; } async closeUpstream(request) { request.requestId = __classPrivateFieldGet(this, _Wire_requestSequence, "f").next(); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send UpstreamCloseRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: message_1.UpstreamCloseResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, // @todo set timeout timeout: 2, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive UpstreamCloseResponse. [requestId=${response.requestId}]`); return response; } async sendUpstreamChunk(message) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send UpstreamChunk.`); if (__classPrivateFieldGet(this, _Wire_unreliableWriter, "f")) { await __classPrivateFieldGet(this, _Wire_unreliableWriter, "f").call(this, message); return; } await __classPrivateFieldGet(this, _Wire_writer, "f").call(this, message); } async upstreamMetadata(request) { request.requestId = __classPrivateFieldGet(this, _Wire_requestSequence, "f").next(); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send UpstreamMetadata. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: message_1.UpstreamMetadataAck, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive UpstreamMetadata. [requestId=${response.requestId}]`); return response; } async openDownstream(request) { request.requestId = __classPrivateFieldGet(this, _Wire_requestSequence, "f").next(); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send DownstreamOpenRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: message_1.DownstreamOpenResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive DownstreamOpenResponse. [requestId=${response.requestId}]`); return response; } async resumeDownstream(request) { request.requestId = __classPrivateFieldGet(this, _Wire_requestSequence, "f").next(); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send DownstreamResumeRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: message_1.DownstreamResumeResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive DownstreamResumeRequest. [requestId=${response.requestId}]`); return response; } async closeDownstream(request) { request.requestId = __classPrivateFieldGet(this, _Wire_requestSequence, "f").next(); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send DownstreamCloseRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: message_1.DownstreamCloseResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, // @todo set timeout timeout: 2, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive DownstreamCloseResponse. [requestId=${response.requestId}]`); return response; } async sendDownstreamChunkAck(message) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send DownstreamChunkAck.`); await __classPrivateFieldGet(this, _Wire_writer, "f").call(this, message); } async sendDownstreamMetadataAck(message) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send DownstreamMetadataAck.`); await __classPrivateFieldGet(this, _Wire_writer, "f").call(this, message); } async sendUpstreamCall(message, timeout) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send UpstreamCall. [callId=${message.callId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message, expectedResponseClass: message_1.UpstreamCallAck, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyCallTransformStreamMap, "f"), replayIdGetter: ({ callId }) => callId, timeout, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive UpstreamCallAck. [callId=${message.callId}]`); return response; } } exports.Wire = Wire; _Wire_requestSequence = new WeakMap(), _Wire_reader = new WeakMap(), _Wire_writer = new WeakMap(), _Wire_unreliableReader = new WeakMap(), _Wire_unreliableWriter = new WeakMap(), _Wire_pingTimeout = new WeakMap(), _Wire_pingInterval = new WeakMap(), _Wire_logger = new WeakMap(), _Wire_replyMessageTransformStreamMap = new WeakMap(), _Wire_replyCallTransformStreamMap = new WeakMap(), _Wire_abortController = new WeakMap(), _Wire_cancelledResolver = new WeakMap(), _Wire_instances = new WeakSet(), _Wire_requestPing = // // Private Methods // async function _Wire_requestPing(request, timeout) { request.requestId = __classPrivateFieldGet(this, _Wire_requestSequence, "f").next(); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `send Ping. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: message_1.Pong, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, timeout, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive Pong. [requestId=${response.requestId}]`); return response; }, _Wire_sendPong = async function _Wire_sendPong(message) { try { __classPrivateFieldGet(this, _Wire_logger, "f").debug(constant_1.LOGGER_TAG.CONN, `send Pong. [requestId=${message.requestId}].`); await __classPrivateFieldGet(this, _Wire_writer, "f").call(this, new message_1.Pong({ requestId: message.requestId, extensionFields: new message_1.PongExtensionFields(), })); } catch (error) { __classPrivateFieldGet(this, _Wire_logger, "f").warn(constant_1.LOGGER_TAG.CONN, `failed to send pong[${message.requestId}].`); } }, _Wire_sendMessageAndWaitResponse = async function _Wire_sendMessageAndWaitResponse(config) { const { message, expectedResponseClass, replayTransformStreamMap, replayIdGetter, timeout } = config; const replayId = replayIdGetter(message); try { const replayTransformStream = new web_streams_polyfill_1.TransformStream(); replayTransformStreamMap.set(replayId, replayTransformStream); await __classPrivateFieldGet(this, _Wire_writer, "f").call(this, message); const run = replayTransformStream.readable.getReader().read(); const timeout_ = new timeout_1.Timeout(); const response = typeof timeout === 'undefined' ? await run : await Promise.race([run, timeout_.run(new exceptions_1.ISCPTimeoutError(), timeout * 1e3)]).finally(() => { timeout_.cancel(); }); if (response instanceof exceptions_1.ISCPTimeoutError) { throw response; } if (response.done) { throw new exceptions_1.ISCPException('Cancelled'); } if (!(response.value instanceof expectedResponseClass)) { throw new exceptions_1.ISCPException(); } return response.value; } finally { replayTransformStreamMap.delete(replayId); } }, _Wire_readLoop = async function _Wire_readLoop() { const abortSignalListener = new signal_abort_listener_1.AbortSignalListener({ signal: __classPrivateFieldGet(this, _Wire_abortController, "f").signal, }); for (;;) { try { const promiseAbort = abortSignalListener.createPromise(CANCEL); const message = await Promise.race([__classPrivateFieldGet(this, _Wire_reader, "f").call(this), promiseAbort.resolve()]).finally(() => { promiseAbort.cancel(); }); if (message === CANCEL) { break; } if (message instanceof message_1.Disconnect) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive Disconnect.`); await this.onDisconnect(message); } if (message instanceof message_1.Ping) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive Ping.`); await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendPong).call(this, message); } if (message instanceof message_1.UpstreamChunkAck) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive UpstreamChunkAck.`); await this.onUpstreamChunkAck(message); } if (message instanceof message_1.DownstreamChunk) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive DownstreamChunk.`); await this.onDownstreamChunk(message); } if (message instanceof message_1.DownstreamMetadata) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive DownstreamMetadata.`); await this.onDownstreamMetadata(message); } if (message instanceof message_1.DownstreamChunkAckComplete) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive DownstreamChunkAckComplete.`); await this.onDownstreamChunkAckComplete(message); } if (message instanceof message_1.UpstreamCallAck) { const replayCallTransformStream = __classPrivateFieldGet(this, _Wire_replyCallTransformStreamMap, "f").get(message.callId); const writer = replayCallTransformStream?.writable.getWriter(); await writer?.write(message); await writer?.close(); } if (message instanceof message_1.DownstreamCall) { __classPrivateFieldGet(this, _Wire_logger, "f").info(constant_1.LOGGER_TAG.CONN, `receive DownstreamCall.`); await this.onDownstreamCall(message); } if (message instanceof message_1.RequestMessage) { const replayMessageTransformStream = __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f").get(message.requestId); const writer = replayMessageTransformStream?.writable.getWriter(); await writer?.write(message); await writer?.close(); } } catch (error) { if (error instanceof exceptions_1.ISCPTransportClosedError) { break; } throw error; } } }, _Wire_readUnreliableLoop = async function _Wire_readUnreliableLoop() { if (__classPrivateFieldGet(this, _Wire_unreliableReader, "f")) { const abortSignalListener = new signal_abort_listener_1.AbortSignalListener({ signal: __classPrivateFieldGet(this, _Wire_abortController, "f").signal, }); for (;;) { try { const promiseAbort = abortSignalListener.createPromise(CANCEL); const message = await Promise.race([__classPrivateFieldGet(this, _Wire_unreliableReader, "f").call(this), promiseAbort.resolve()]).finally(() => { promiseAbort.cancel(); }); if (message === CANCEL) { break; } if (message instanceof message_1.DownstreamChunk) { await this.onDownstreamChunk(message); } } catch (error) { if (error instanceof exceptions_1.ISCPTransportClosedError) { break; } throw error; } } } }, _Wire_keepAliveLoop = async function _Wire_keepAliveLoop() { const abortSignalListener = new signal_abort_listener_1.AbortSignalListener({ signal: __classPrivateFieldGet(this, _Wire_abortController, "f").signal, }); const ticker = ticker_1.Ticker.of({ delayMs: __classPrivateFieldGet(this, _Wire_pingInterval, "f") * 1e3, signal: __classPrivateFieldGet(this, _Wire_abortController, "f").signal, }); // eslint-disable-next-line @typescript-eslint/no-unused-vars for await (const _ of ticker) { try { const promiseAbort = abortSignalListener.createPromise(CANCEL); const result = await Promise.race([ __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_requestPing).call(this, new message_1.Ping({ requestId: 0, extensionFields: new message_1.PingExtensionFields(), }), __classPrivateFieldGet(this, _Wire_pingTimeout, "f")), promiseAbort.resolve(), ]).finally(() => { promiseAbort.cancel(); }); if (result === CANCEL) { break; } } catch (error) { if (error instanceof exceptions_1.ISCPTimeoutError) { __classPrivateFieldGet(this, _Wire_logger, "f").error(constant_1.LOGGER_TAG.CONN, `ping pong timeout. [timeout=${__classPrivateFieldGet(this, _Wire_pingTimeout, "f")}]`); this.onPingTimeout(); continue; } __classPrivateFieldGet(this, _Wire_logger, "f").error(constant_1.LOGGER_TAG.CONN, error); } } }; //# sourceMappingURL=wire.js.map