fuse-box
Version:
Fuse-Box a bundler that does it right
80 lines (76 loc) • 2.1 kB
JavaScript
const events = require('events');
function log(text) {
console.info(`%c${text}`, 'color: #237abe');
}
export class SocketClient {
constructor(opts) {
opts = opts || {};
const port = opts.port || window.location.port;
const protocol = location.protocol === 'https:' ? 'wss://' : 'ws://';
const domain = location.hostname || 'localhost';
if (opts.connectionURL) {
this.url = opts.connectionURL;
} else {
if (opts.useCurrentURL) {
this.url = protocol + location.hostname + (location.port ? ':' + location.port : '');
}
if (opts.port) {
this.url = `${protocol}${domain}:${opts.port}`;
}
}
this.authSent = false;
this.emitter = new events.EventEmitter();
}
reconnect(fn) {
setTimeout(() => {
this.emitter.emit('reconnect', { message: 'Trying to reconnect' });
this.connect(fn);
}, 5000);
}
on(event, fn) {
this.emitter.on(event, fn);
}
connect(fn) {
setTimeout(() => {
log(`Connecting to FuseBox HMR at ${this.url}`);
this.client = new WebSocket(this.url);
this.bindEvents(fn);
}, 0);
}
close() {
this.client.close();
}
send(eventName, data) {
if (this.client.readyState === 1) {
this.client.send(JSON.stringify({ name: eventName, payload: data || {} }));
}
}
error(data) {
this.emitter.emit('error', data);
}
/** Wires up the socket client messages to be emitted on our event emitter */
bindEvents(fn) {
this.client.onopen = event => {
log('Connection successful');
if (fn) {
fn(this);
}
};
this.client.onerror = event => {
this.error({ reason: event.reason, message: 'Socket error' });
};
this.client.onclose = event => {
this.emitter.emit('close', { message: 'Socket closed' });
if (event.code !== 1011) {
this.reconnect(fn);
}
};
this.client.onmessage = event => {
let data = event.data;
if (data) {
let item = JSON.parse(data);
this.emitter.emit(item.name, item.payload);
}
};
}
}