UNPKG

@roochnetwork/rooch-sdk

Version:
186 lines (185 loc) 6.54 kB
var __accessCheck = (obj, member, msg) => { if (!member.has(obj)) throw TypeError("Cannot " + msg); }; var __privateGet = (obj, member, getter) => { __accessCheck(obj, member, "read from private field"); return getter ? getter.call(obj) : member.get(obj); }; var __privateAdd = (obj, member, value) => { if (member.has(obj)) throw TypeError("Cannot add the same private member more than once"); member instanceof WeakSet ? member.add(obj) : member.set(obj, value); }; var __privateSet = (obj, member, value, setter) => { __accessCheck(obj, member, "write to private field"); setter ? setter.call(obj, value) : member.set(obj, value); return value; }; var __privateWrapper = (obj, member, setter, getter) => ({ set _(value) { __privateSet(obj, member, value, setter); }, get _() { return __privateGet(obj, member, getter); } }); var __privateMethod = (obj, member, method) => { __accessCheck(obj, member, "access private method"); return method; }; var _requestId, _disconnects, _eventSource, _connectionPromise, _subscriptionRequests, _subscriptions, _reconnect, reconnect_fn; import { EventSource } from "eventsource"; const DEFAULT_CLIENT_OPTIONS = { callTimeout: 3e4, reconnectTimeout: 3e3, maxReconnects: 5 }; class SSEClient { constructor(endpoint, options = {}) { __privateAdd(this, _reconnect); __privateAdd(this, _requestId, 0); __privateAdd(this, _disconnects, 0); __privateAdd(this, _eventSource, /* @__PURE__ */ new Map()); __privateAdd(this, _connectionPromise, /* @__PURE__ */ new Map()); __privateAdd(this, _subscriptionRequests, /* @__PURE__ */ new Map()); __privateAdd(this, _subscriptions, /* @__PURE__ */ new Set()); this.endpoint = endpoint; this.options = { ...DEFAULT_CLIENT_OPTIONS, ...options }; } async disconnect(id) { const eventSource = __privateGet(this, _eventSource).get(id); if (eventSource) { eventSource.close(); __privateGet(this, _eventSource).delete(id); __privateGet(this, _connectionPromise).delete(id); } return Promise.resolve(eventSource !== void 0); } getSubscribeId() { return __privateGet(this, _requestId); } setupEventSource(request) { __privateSet(this, _requestId, __privateGet(this, _requestId) + 1); __privateGet(this, _subscriptionRequests).set(__privateGet(this, _requestId), request); const promise = new Promise((resolve) => { if (__privateGet(this, _eventSource).has(__privateGet(this, _requestId))) { __privateGet(this, _eventSource).get(__privateGet(this, _requestId))?.close(); } const url = new URL(`${this.endpoint}${request.method}`); url.searchParams.set("filter", JSON.stringify(request.params)); const eventSource = new EventSource(url.toString()); eventSource.onopen = () => { __privateSet(this, _disconnects, 0); resolve(eventSource); }; eventSource.onerror = (error) => { __privateWrapper(this, _disconnects)._++; if (__privateGet(this, _disconnects) <= this.options.maxReconnects) { setTimeout(() => { __privateMethod(this, _reconnect, reconnect_fn).call(this, __privateGet(this, _requestId)); }, this.options.reconnectTimeout); } else { console.error( `Failed to connect after ${this.options.maxReconnects} attempts`, error.message ); __privateGet(this, _subscriptions).forEach((subscription) => { if (subscription.subscriptionId === __privateGet(this, _requestId)) { subscription.onError?.( new Error(`Failed to connect after ${this.options.maxReconnects} attempts`) ); } }); } }; eventSource.onmessage = (data) => { let json; try { json = typeof data.data === "string" ? JSON.parse(data.data) : data.data; } catch (error) { console.error(new Error(`Failed to parse RPC message: ${data.data}`, { cause: error })); return; } __privateGet(this, _subscriptions).forEach((subscription) => { subscription.onMessage(json); }); }; }); __privateGet(this, _connectionPromise).set(__privateGet(this, _requestId), promise); return promise; } async subscribe(input) { const subscription = new RpcSubscription(input); __privateGet(this, _subscriptions).add(subscription); await subscription.subscribe(this); return () => subscription.unsubscribe(this); } } _requestId = new WeakMap(); _disconnects = new WeakMap(); _eventSource = new WeakMap(); _connectionPromise = new WeakMap(); _subscriptionRequests = new WeakMap(); _subscriptions = new WeakMap(); _reconnect = new WeakSet(); reconnect_fn = async function(id) { if (__privateGet(this, _eventSource).has(id)) { __privateGet(this, _eventSource).get(id)?.close(); __privateGet(this, _eventSource).delete(id); __privateGet(this, _connectionPromise).delete(id); } try { if (!__privateGet(this, _subscriptionRequests).has(id)) { return; } const eventSource = await this.setupEventSource(__privateGet(this, _subscriptionRequests).get(id)); __privateGet(this, _eventSource).set(id, eventSource); return Promise.allSettled( [...__privateGet(this, _subscriptions)].filter((subscription) => subscription.subscriptionId === id).map((subscription) => subscription.subscribe(this)) ); } catch (error) { console.error(`Failed to reconnect: ${error}`); throw error; } }; class RpcSubscription { constructor(input) { this.subscriptionId = null; this.subscribed = false; this.input = input; this.onError = input.onError; } onMessage(message) { if (this.subscribed) { this.input.onMessage(message); } } async unsubscribe(client) { const { subscriptionId } = this; this.subscribed = false; if (subscriptionId == null) return false; this.subscriptionId = null; await client.disconnect(subscriptionId); return Promise.resolve(true); } async subscribe(client) { this.subscriptionId = null; try { const es = await client.setupEventSource(this.input); if (es) { this.subscribed = true; this.subscriptionId = client.getSubscribeId(); } } catch (error) { this.subscribed = false; throw error; } } } export { DEFAULT_CLIENT_OPTIONS, SSEClient }; //# sourceMappingURL=sseTransport.js.map