'use strict'; var errors = require('@solana/errors'); var events = require('events'); var subscribable = require('@solana/subscribable'); var e2 = require('ws'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var e2__default = /*#__PURE__*/_interopDefault(e2); // src/websocket-channel.ts var s = class extends globalThis.EventTarget { constructor(...t) { super(...t), events.setMaxListeners(Number.MAX_SAFE_INTEGER, this); } }; var l = globalThis.WebSocket ? globalThis.WebSocket : e2__default.default; // src/websocket-channel.ts var NORMAL_CLOSURE_CODE = 1e3; function createWebSocketChannel({ sendBufferHighWatermark, signal, url }) { if (signal.aborted) { return Promise.reject(signal.reason); } let bufferDrainWatcher; let hasConnected = false; const listenerRemovers = /* @__PURE__ */ new Set(); function cleanupListeners() { listenerRemovers.forEach((r) => { r(); }); listenerRemovers.clear(); } function handleAbort() { cleanupListeners(); if (!hasConnected) { rejectOpen(signal.reason); } if (webSocket.readyState !== l.CLOSED && webSocket.readyState !== l.CLOSING) { webSocket.close(NORMAL_CLOSURE_CODE); } } function handleClose(ev) { cleanupListeners(); bufferDrainWatcher?.onCancel(); signal.removeEventListener("abort", handleAbort); webSocket.removeEventListener("close", handleClose); webSocket.removeEventListener("error", handleError); webSocket.removeEventListener("message", handleMessage); webSocket.removeEventListener("open", handleOpen); if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) { eventTarget.dispatchEvent( new CustomEvent("error", { detail: new errors.SolanaError(errors.SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, { cause: ev }) }) ); } } function handleError(ev) { if (signal.aborted) { return; } if (!hasConnected) { const failedToConnectError = new errors.SolanaError(errors.SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, { errorEvent: ev }); rejectOpen(failedToConnectError); eventTarget.dispatchEvent( new CustomEvent("error", { detail: failedToConnectError }) ); } } function handleMessage(ev) { if (signal.aborted) { return; } eventTarget.dispatchEvent(new CustomEvent("message", { detail: ev.data })); } const eventTarget = new s(); const dataPublisher = subscribable.getDataPublisherFromEventEmitter(eventTarget); function handleOpen() { hasConnected = true; resolveOpen({ ...dataPublisher, async send(message) { if (webSocket.readyState !== l.OPEN) { throw new errors.SolanaError(errors.SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED); } if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) { let onCancel; const promise = new Promise((resolve, reject) => { const intervalId = setInterval(() => { if (webSocket.readyState !== l.OPEN || !(webSocket.bufferedAmount > sendBufferHighWatermark)) { clearInterval(intervalId); bufferDrainWatcher = void 0; resolve(); } }, 16); onCancel = () => { bufferDrainWatcher = void 0; clearInterval(intervalId); reject( new errors.SolanaError( errors.SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED ) ); }; }); bufferDrainWatcher = { onCancel, promise }; } if (bufferDrainWatcher) { if (ArrayBuffer.isView(message) && !(message instanceof DataView)) { const TypedArrayConstructor = message.constructor; message = new TypedArrayConstructor(message); } await bufferDrainWatcher.promise; } webSocket.send(message); } }); } const webSocket = new l(url); signal.addEventListener("abort", handleAbort); webSocket.addEventListener("close", handleClose); webSocket.addEventListener("error", handleError); webSocket.addEventListener("message", handleMessage); webSocket.addEventListener("open", handleOpen); let rejectOpen; let resolveOpen; return new Promise((resolve, reject) => { rejectOpen = reject; resolveOpen = resolve; }); } exports.createWebSocketChannel = createWebSocketChannel; //# sourceMappingURL=index.node.cjs.map //# sourceMappingURL=index.node.cjs.map