rxjs-websockets
Version:
rxjs 7 websockets library
72 lines • 2.51 kB
JavaScript
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