UNPKG

homebridge-blaq

Version:

Control and view your garage door(s) remotely with real-time updates using Konnected's BlaQ hardware

100 lines 4.21 kB
import { EventSource } from 'eventsource'; const ONE_SECOND_IN_MS = 1000; const ONE_MINUTE_IN_MS = 60 * ONE_SECOND_IN_MS; export class AutoReconnectingEventSource { protocol; host; port; user; pass; path; logger; onLog; onStateUpdate; onPing; eventSource; lastEventSourceEventDate; maxIdleBeforeReconnect; idleCheckInterval; constructor({ protocol = 'http', host, port = 80, user, pass, path = 'events', maxIdleBeforeReconnect = ONE_MINUTE_IN_MS, logger, onLog = (log) => logger.warn('No onLog handler provided to AutoReconnectingEventsource. Got log:', log), onStateUpdate = (state) => logger.warn('No onStateUpdate handler provided to AutoReconnectingEventsource. Got state:', state), onPing = (ping) => logger.warn('No onPing handler provided to AutoReconnectingEventsource. Got ping:', ping), }) { this.logger = logger; this.logger.debug('Initializing AutoReconnectingEventSource...'); const correctedProtocol = protocol.split('://').shift(); this.protocol = correctedProtocol; this.host = host; this.port = port; this.user = user; this.pass = pass; const correctedPath = path.startsWith('/') ? path.slice(1) : path; this.path = correctedPath; this.onLog = onLog; this.onStateUpdate = onStateUpdate; this.onPing = onPing; this.maxIdleBeforeReconnect = maxIdleBeforeReconnect; this.connectEventSource(); this.logger.debug('Initialized AutoReconnectingEventSource!'); } connectEventSource() { if (!this.eventSource) { const basicCreds = `${this.user}:${this.pass}`; const eventSourceOptions = { fetch: (url, options) => { this.logger.debug(`Fetching EventSource URL: ${url} with options:`, options); return fetch(url, { ...options, headers: { ...options.headers, ...(this.user && this.pass ? { 'Authorization': `Basic ${Buffer.from(basicCreds).toString('base64')}`, } : {}), }, }); }, }; this.eventSource = new EventSource(`${this.protocol}://${this.host}:${this.port}/${this.path}`, eventSourceOptions); this.eventSource.addEventListener('error', error => { this.logger.error('EventSource got error', error); this.logger.error('Reinitializing EventSource...'); this.close(); if (error.code === 401) { this.logger.error('Please configure valid credentials for this device!'); } else { this.connectEventSource(); } }); this.eventSource.addEventListener('log', log => { this.lastEventSourceEventDate = new Date(); this.onLog(log); }); this.eventSource.addEventListener('state', state => { this.lastEventSourceEventDate = new Date(); this.onStateUpdate(state); }); this.eventSource.addEventListener('ping', ping => { this.lastEventSourceEventDate = new Date(); this.onPing(ping); }); } if (!this.idleCheckInterval) { this.idleCheckInterval = setInterval(() => this.checkIdleTooLong(), ONE_SECOND_IN_MS); } } checkIdleTooLong() { if (this.lastEventSourceEventDate && this.lastEventSourceEventDate.valueOf() < Date.now() - this.maxIdleBeforeReconnect) { this.close(); this.connectEventSource(); } } close() { if (this.eventSource) { clearInterval(this.idleCheckInterval); this.idleCheckInterval = undefined; this.eventSource.close(); this.eventSource = undefined; this.lastEventSourceEventDate = undefined; } } } //# sourceMappingURL=eventsource.js.map