mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-13 11:43:31 +00:00
This ports TGUI, and makes the old nano crew monitor and the disposal bins use it as first examples.
162 lines
4.0 KiB
JavaScript
162 lines
4.0 KiB
JavaScript
let socket;
|
|
const queue = [];
|
|
const subscribers = [];
|
|
|
|
const ensureConnection = () => {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
if (!window.WebSocket) {
|
|
return;
|
|
}
|
|
if (!socket || socket.readyState === WebSocket.CLOSED) {
|
|
const DEV_SERVER_IP = process.env.DEV_SERVER_IP || '127.0.0.1';
|
|
socket = new WebSocket(`ws://${DEV_SERVER_IP}:3000`);
|
|
socket.onopen = () => {
|
|
// Empty the message queue
|
|
while (queue.length !== 0) {
|
|
const msg = queue.shift();
|
|
socket.send(msg);
|
|
}
|
|
};
|
|
socket.onmessage = event => {
|
|
const msg = JSON.parse(event.data);
|
|
for (let subscriber of subscribers) {
|
|
subscriber(msg);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
};
|
|
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
window.onunload = () => socket && socket.close();
|
|
}
|
|
|
|
const subscribe = fn => subscribers.push(fn);
|
|
|
|
/**
|
|
* A json serializer which handles circular references and other junk.
|
|
*/
|
|
const serializeObject = obj => {
|
|
let refs = [];
|
|
const primitiveReviver = value => {
|
|
if (typeof value === 'number' && !Number.isFinite(value)) {
|
|
return {
|
|
__number__: String(value),
|
|
};
|
|
}
|
|
if (typeof value === 'undefined') {
|
|
return {
|
|
__undefined__: true,
|
|
};
|
|
}
|
|
return value;
|
|
};
|
|
const objectReviver = (key, value) => {
|
|
if (typeof value === 'object') {
|
|
if (value === null) {
|
|
return value;
|
|
}
|
|
// Circular reference
|
|
if (refs.includes(value)) {
|
|
return '[circular ref]';
|
|
}
|
|
refs.push(value);
|
|
// Error object
|
|
if (value instanceof Error) {
|
|
return {
|
|
__error__: true,
|
|
string: String(value),
|
|
stack: value.stack,
|
|
};
|
|
}
|
|
// Array
|
|
if (Array.isArray(value)) {
|
|
return value.map(primitiveReviver);
|
|
}
|
|
return value;
|
|
}
|
|
return primitiveReviver(value);
|
|
};
|
|
const json = JSON.stringify(obj, objectReviver);
|
|
refs = null;
|
|
return json;
|
|
};
|
|
|
|
const sendRawMessage = msg => {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
const json = serializeObject(msg);
|
|
// Send message using WebSocket
|
|
if (window.WebSocket) {
|
|
ensureConnection();
|
|
if (socket.readyState === WebSocket.OPEN) {
|
|
socket.send(json);
|
|
}
|
|
else {
|
|
// Keep only 10 latest messages in the queue
|
|
if (queue.length > 10) {
|
|
queue.shift();
|
|
}
|
|
queue.push(json);
|
|
}
|
|
}
|
|
// Send message using plain HTTP request.
|
|
else {
|
|
const DEV_SERVER_IP = process.env.DEV_SERVER_IP || '127.0.0.1';
|
|
const req = new XMLHttpRequest();
|
|
req.open('POST', `http://${DEV_SERVER_IP}:3001`);
|
|
req.timeout = 500;
|
|
req.send(json);
|
|
}
|
|
}
|
|
};
|
|
|
|
export const sendLogEntry = (level, ns, ...args) => {
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
try {
|
|
sendRawMessage({
|
|
type: 'log',
|
|
payload: {
|
|
level,
|
|
ns: ns || 'client',
|
|
args,
|
|
},
|
|
});
|
|
}
|
|
catch (err) {}
|
|
}
|
|
};
|
|
|
|
export const setupHotReloading = () => {
|
|
if (process.env.NODE_ENV !== 'production'
|
|
&& process.env.WEBPACK_HMR_ENABLED
|
|
&& window.WebSocket) {
|
|
if (module.hot) {
|
|
ensureConnection();
|
|
sendLogEntry(0, null, 'setting up hot reloading');
|
|
subscribe(msg => {
|
|
const { type } = msg;
|
|
sendLogEntry(0, null, 'received', type);
|
|
if (type === 'hotUpdate') {
|
|
const status = module.hot.status();
|
|
if (status !== 'idle') {
|
|
sendLogEntry(0, null, 'hot reload status:', status);
|
|
return;
|
|
}
|
|
module.hot
|
|
.check({
|
|
ignoreUnaccepted: true,
|
|
ignoreDeclined: true,
|
|
ignoreErrored: true,
|
|
})
|
|
.then(modules => {
|
|
sendLogEntry(0, null, 'outdated modules', modules);
|
|
})
|
|
.catch(err => {
|
|
sendLogEntry(0, null, 'reload error', err);
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
};
|