UNPKG

@aptpod/iscp-ts

Version:

iSCP 2.0 client library for TypeScript

377 lines 22.8 kB
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; import { TransformStream } from 'web-streams-polyfill'; import { ISCPException, ISCPTimeoutError, ISCPTransportClosedError } from './exceptions'; import { RequestMessage, ConnectResponse, Disconnect, DownstreamOpenResponse, DownstreamChunkAckComplete, DownstreamChunk, DownstreamMetadata, Ping, Pong, PingExtensionFields, DownstreamCloseResponse, DownstreamResumeResponse, UpstreamOpenResponse, UpstreamResumeResponse, UpstreamCloseResponse, UpstreamChunkAck, UpstreamMetadataAck, PongExtensionFields, UpstreamCallAck, DownstreamCall, } from './message'; import { LOGGER_TAG } from './constant'; import { Ticker } from './utils/ticker'; import { Timeout } from './utils/timeout'; import { Resolver } from './utils/resolver'; import { AbortSignalListener } from './utils/signal-abort-listener'; const CANCEL = 'cancel'; export 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(), "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(LOGGER_TAG.CONN, `send ConnectRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: ConnectResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `recv ConnectResponse. [requestId=${response.requestId}]`); return response; } async disconnect(request) { __classPrivateFieldGet(this, _Wire_logger, "f").info(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(LOGGER_TAG.CONN, `send UpstreamOpenRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: UpstreamOpenResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(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(LOGGER_TAG.CONN, `send UpstreamResumeRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: UpstreamResumeResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(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(LOGGER_TAG.CONN, `send UpstreamCloseRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: UpstreamCloseResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, // @todo set timeout timeout: 2, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `receive UpstreamCloseResponse. [requestId=${response.requestId}]`); return response; } async sendUpstreamChunk(message) { __classPrivateFieldGet(this, _Wire_logger, "f").info(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(LOGGER_TAG.CONN, `send UpstreamMetadata. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: UpstreamMetadataAck, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(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(LOGGER_TAG.CONN, `send DownstreamOpenRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: DownstreamOpenResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(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(LOGGER_TAG.CONN, `send DownstreamResumeRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: DownstreamResumeResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(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(LOGGER_TAG.CONN, `send DownstreamCloseRequest. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: DownstreamCloseResponse, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, // @todo set timeout timeout: 2, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `receive DownstreamCloseResponse. [requestId=${response.requestId}]`); return response; } async sendDownstreamChunkAck(message) { __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `send DownstreamChunkAck.`); await __classPrivateFieldGet(this, _Wire_writer, "f").call(this, message); } async sendDownstreamMetadataAck(message) { __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `send DownstreamMetadataAck.`); await __classPrivateFieldGet(this, _Wire_writer, "f").call(this, message); } async sendUpstreamCall(message, timeout) { __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `send UpstreamCall. [callId=${message.callId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message, expectedResponseClass: UpstreamCallAck, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyCallTransformStreamMap, "f"), replayIdGetter: ({ callId }) => callId, timeout, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `receive UpstreamCallAck. [callId=${message.callId}]`); return response; } } _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(LOGGER_TAG.CONN, `send Ping. [requestId=${request.requestId}]`); const response = await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendMessageAndWaitResponse).call(this, { message: request, expectedResponseClass: Pong, replayTransformStreamMap: __classPrivateFieldGet(this, _Wire_replyMessageTransformStreamMap, "f"), replayIdGetter: ({ requestId }) => requestId, timeout, }); __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `receive Pong. [requestId=${response.requestId}]`); return response; }, _Wire_sendPong = async function _Wire_sendPong(message) { try { __classPrivateFieldGet(this, _Wire_logger, "f").debug(LOGGER_TAG.CONN, `send Pong. [requestId=${message.requestId}].`); await __classPrivateFieldGet(this, _Wire_writer, "f").call(this, new Pong({ requestId: message.requestId, extensionFields: new PongExtensionFields(), })); } catch (error) { __classPrivateFieldGet(this, _Wire_logger, "f").warn(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 TransformStream(); replayTransformStreamMap.set(replayId, replayTransformStream); await __classPrivateFieldGet(this, _Wire_writer, "f").call(this, message); const run = replayTransformStream.readable.getReader().read(); const timeout_ = new Timeout(); const response = typeof timeout === 'undefined' ? await run : await Promise.race([run, timeout_.run(new ISCPTimeoutError(), timeout * 1e3)]).finally(() => { timeout_.cancel(); }); if (response instanceof ISCPTimeoutError) { throw response; } if (response.done) { throw new ISCPException('Cancelled'); } if (!(response.value instanceof expectedResponseClass)) { throw new ISCPException(); } return response.value; } finally { replayTransformStreamMap.delete(replayId); } }, _Wire_readLoop = async function _Wire_readLoop() { const abortSignalListener = new 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 Disconnect) { __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `receive Disconnect.`); await this.onDisconnect(message); } if (message instanceof Ping) { __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `receive Ping.`); await __classPrivateFieldGet(this, _Wire_instances, "m", _Wire_sendPong).call(this, message); } if (message instanceof UpstreamChunkAck) { __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `receive UpstreamChunkAck.`); await this.onUpstreamChunkAck(message); } if (message instanceof DownstreamChunk) { __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `receive DownstreamChunk.`); await this.onDownstreamChunk(message); } if (message instanceof DownstreamMetadata) { __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `receive DownstreamMetadata.`); await this.onDownstreamMetadata(message); } if (message instanceof DownstreamChunkAckComplete) { __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `receive DownstreamChunkAckComplete.`); await this.onDownstreamChunkAckComplete(message); } if (message instanceof 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 DownstreamCall) { __classPrivateFieldGet(this, _Wire_logger, "f").info(LOGGER_TAG.CONN, `receive DownstreamCall.`); await this.onDownstreamCall(message); } if (message instanceof 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 ISCPTransportClosedError) { break; } throw error; } } }, _Wire_readUnreliableLoop = async function _Wire_readUnreliableLoop() { if (__classPrivateFieldGet(this, _Wire_unreliableReader, "f")) { const abortSignalListener = new 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 DownstreamChunk) { await this.onDownstreamChunk(message); } } catch (error) { if (error instanceof ISCPTransportClosedError) { break; } throw error; } } } }, _Wire_keepAliveLoop = async function _Wire_keepAliveLoop() { const abortSignalListener = new AbortSignalListener({ signal: __classPrivateFieldGet(this, _Wire_abortController, "f").signal, }); const ticker = 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 Ping({ requestId: 0, extensionFields: new PingExtensionFields(), }), __classPrivateFieldGet(this, _Wire_pingTimeout, "f")), promiseAbort.resolve(), ]).finally(() => { promiseAbort.cancel(); }); if (result === CANCEL) { break; } } catch (error) { if (error instanceof ISCPTimeoutError) { __classPrivateFieldGet(this, _Wire_logger, "f").error(LOGGER_TAG.CONN, `ping pong timeout. [timeout=${__classPrivateFieldGet(this, _Wire_pingTimeout, "f")}]`); this.onPingTimeout(); continue; } __classPrivateFieldGet(this, _Wire_logger, "f").error(LOGGER_TAG.CONN, error); } } }; //# sourceMappingURL=wire.js.map