UNPKG

@drift-labs/sdk

Version:
122 lines (121 loc) 4.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EventsServerLogProvider = void 0; const events_1 = require("events"); // browser support let WebSocketImpl; if (typeof window !== 'undefined' && window.WebSocket) { WebSocketImpl = window.WebSocket; } else { WebSocketImpl = require('ws'); } const EVENT_SERVER_HEARTBEAT_INTERVAL_MS = 5000; const ALLOWED_MISSED_HEARTBEATS = 3; class EventsServerLogProvider { constructor(url, eventTypes, userAccount) { this.url = url; this.eventTypes = eventTypes; this.userAccount = userAccount; this.isUnsubscribing = false; this.externalUnsubscribe = false; this.lastHeartbeat = 0; this.reconnectAttempts = 0; this.eventEmitter = new events_1.EventEmitter(); } isSubscribed() { return this.ws !== undefined; } async subscribe(callback) { if (this.ws !== undefined) { return true; } this.ws = new WebSocketImpl(this.url); this.callback = callback; this.ws.addEventListener('open', () => { for (const channel of this.eventTypes) { const subscribeMessage = { type: 'subscribe', channel: channel, }; if (this.userAccount) { subscribeMessage['user'] = this.userAccount; } this.ws.send(JSON.stringify(subscribeMessage)); } this.reconnectAttempts = 0; }); this.ws.addEventListener('message', (data) => { try { if (!this.isUnsubscribing) { clearTimeout(this.timeoutId); this.setTimeout(); if (this.reconnectAttempts > 0) { console.log('eventsServerLogProvider: Resetting reconnect attempts to 0'); } this.reconnectAttempts = 0; } const parsedData = JSON.parse(data.data.toString()); if (parsedData.channel === 'heartbeat') { this.lastHeartbeat = Date.now(); return; } if (parsedData.message !== undefined) { return; } const event = JSON.parse(parsedData.data); this.callback(event.txSig, event.slot, [ 'Program dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH invoke [1]', event.rawLog, 'Program dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH success', ], undefined, event.txSigIndex); } catch (error) { console.error('Error parsing message:', error); } }); this.ws.addEventListener('close', () => { console.log('eventsServerLogProvider: WebSocket closed'); }); this.ws.addEventListener('error', (error) => { console.error('eventsServerLogProvider: WebSocket error:', error); }); this.setTimeout(); return true; } async unsubscribe(external = false) { this.isUnsubscribing = true; this.externalUnsubscribe = external; if (this.timeoutId) { clearInterval(this.timeoutId); this.timeoutId = undefined; } if (this.ws !== undefined) { this.ws.close(); this.ws = undefined; return true; } else { this.isUnsubscribing = false; return true; } } setTimeout() { this.timeoutId = setTimeout(async () => { if (this.isUnsubscribing || this.externalUnsubscribe) { // If we are in the process of unsubscribing, do not attempt to resubscribe return; } const timeSinceLastHeartbeat = Date.now() - this.lastHeartbeat; if (timeSinceLastHeartbeat > EVENT_SERVER_HEARTBEAT_INTERVAL_MS * ALLOWED_MISSED_HEARTBEATS) { console.log(`eventServerLogProvider: No heartbeat in ${timeSinceLastHeartbeat}ms, resubscribing on attempt ${this.reconnectAttempts + 1}`); await this.unsubscribe(); this.reconnectAttempts++; this.eventEmitter.emit('reconnect', this.reconnectAttempts); this.subscribe(this.callback); } }, EVENT_SERVER_HEARTBEAT_INTERVAL_MS * 2); } } exports.EventsServerLogProvider = EventsServerLogProvider;