UNPKG

capacitor-cors-bypass-enhanced

Version:

Enhanced Capacitor plugin for CORS bypass with HTTP/2, HTTP/3, gRPC, GraphQL, file operations, and advanced networking features. Modular TypeScript definitions for better maintainability.

157 lines (156 loc) 5.57 kB
import { isCrossOrigin } from './utils'; /** * SSE Manager * Handles Server-Sent Events connections with CORS bypass */ export class SSEManager { constructor(proxyServerUrl, notifyListeners) { this.sseConnections = new Map(); this.connectionCounter = 0; this.proxyServerUrl = proxyServerUrl; this.notifyListeners = notifyListeners; } /** * Start listening to Server-Sent Events (legacy method) */ async startSSE(options) { const connectionId = `sse_${++this.connectionCounter}`; const { url, headers = {}, withCredentials = false, reconnectTimeout = 3000 } = options; // Use proxy server for SSE if available and cross-origin let sseUrl = url; if (this.proxyServerUrl && isCrossOrigin(url)) { console.log(`🔧 Using SSE proxy for: ${url}`); sseUrl = `${this.proxyServerUrl}/sse-proxy/${encodeURIComponent(url)}`; } const eventSource = new EventSource(sseUrl); this.sseConnections.set(connectionId, eventSource); eventSource.onopen = () => { this.notifyListeners('sseOpen', { connectionId, status: 'connected', }); }; eventSource.onmessage = (event) => { this.notifyListeners('sseMessage', { connectionId, type: 'message', data: event.data, id: event.lastEventId, }); }; eventSource.onerror = () => { this.notifyListeners('sseError', { connectionId, error: 'Connection error', }); }; return { connectionId }; } /** * Stop listening to Server-Sent Events */ async stopSSE(options) { const { connectionId } = options; const connection = this.sseConnections.get(connectionId); if (connection) { connection.close(); this.sseConnections.delete(connectionId); this.notifyListeners('sseClose', { connectionId, status: 'disconnected', }); } } /** * Create a Server-Sent Events connection with reconnection support */ async createSSEConnection(options) { const connectionId = `sse_${++this.connectionCounter}`; const { url, headers = {}, reconnect = {} } = options; const { enabled: reconnectEnabled = true, initialDelay = 1000, maxDelay = 30000, maxAttempts = 10, } = reconnect; let retryCount = 0; let retryDelay = initialDelay; const createConnection = () => { // Use proxy server for SSE if available and cross-origin let sseUrl = url; if (this.proxyServerUrl && isCrossOrigin(url)) { console.log(`🔧 Using SSE proxy for: ${url}`); sseUrl = `${this.proxyServerUrl}/sse-proxy/${encodeURIComponent(url)}`; } const eventSource = new EventSource(sseUrl); this.sseConnections.set(connectionId, eventSource); eventSource.onopen = () => { retryCount = 0; retryDelay = initialDelay; this.notifyListeners('sseConnectionChange', { connectionId, status: 'connected', }); }; eventSource.onmessage = (event) => { this.notifyListeners('sseMessage', { connectionId, type: 'message', data: event.data, id: event.lastEventId, }); }; eventSource.onerror = () => { this.notifyListeners('sseConnectionChange', { connectionId, status: 'error', error: 'Connection error', }); if (reconnectEnabled && retryCount < maxAttempts) { setTimeout(() => { retryCount++; retryDelay = Math.min(retryDelay * 2, maxDelay); eventSource.close(); createConnection(); }, retryDelay); } else { this.sseConnections.delete(connectionId); } }; // Add custom event listeners eventSource.addEventListener('error', (event) => { this.notifyListeners('sseMessage', { connectionId, type: 'error', data: 'Connection error', }); }); }; this.notifyListeners('sseConnectionChange', { connectionId, status: 'connecting', }); createConnection(); return { connectionId, status: 'connecting', }; } /** * Close an SSE connection */ async closeSSEConnection(options) { const { connectionId } = options; const connection = this.sseConnections.get(connectionId); if (connection) { connection.close(); this.sseConnections.delete(connectionId); this.notifyListeners('sseConnectionChange', { connectionId, status: 'disconnected', }); } } /** * Get all active SSE connections */ getSSEConnections() { return this.sseConnections; } }