UNPKG

rxjs-websockets

Version:
72 lines 2.51 kB
import { Observable, Subject } from 'rxjs'; const defaultProtocols = []; const defaultWebsocketFactory = (url, protocols) => new WebSocket(url, protocols); export const normalClosureMessage = 'Normal closure'; export default function makeWebSocketObservable(url, { protocols = defaultProtocols, makeWebSocket = defaultWebsocketFactory } = { protocols: defaultProtocols, makeWebSocket: defaultWebsocketFactory, }) { return new Observable((observer) => { let inputSubscription; const messages = new Subject(); const socket = makeWebSocket(url, protocols); let isSocketClosed = false; let forcedClose = false; const setClosedStatus = () => { isSocketClosed = true; }; const getWebSocketResponses = (input) => { if (inputSubscription) { setClosedStatus(); const error = new Error('Web socket message factory function called more than once'); observer.error(error); throw error; } else { inputSubscription = input.subscribe((data) => { socket.send(data); }); return messages; } }; socket.onopen = () => { if (forcedClose) { isSocketClosed = true; socket.close(); } else { observer.next(getWebSocketResponses); } }; socket.onmessage = (message) => { messages.next(message.data); }; socket.onerror = (error) => { setClosedStatus(); observer.error(new Error(error.message)); }; socket.onclose = (event) => { // prevent observer.complete() being called after observer.error(...) if (isSocketClosed) return; setClosedStatus(); if (forcedClose) { observer.complete(); messages.complete(); } else { observer.error(new Error(event.code === 1000 ? normalClosureMessage : event.reason)); } }; return () => { forcedClose = true; if (inputSubscription) inputSubscription.unsubscribe(); if (!isSocketClosed) { setClosedStatus(); socket.close(); } }; }); } //# sourceMappingURL=index.js.map