getting things going
This commit is contained in:
38
src/_/code/bridge/bridge.js
Normal file
38
src/_/code/bridge/bridge.js
Normal file
@@ -0,0 +1,38 @@
|
||||
const IS_NODE =
|
||||
typeof process !== "undefined" &&
|
||||
process.versions?.node != null
|
||||
|
||||
async function bridgeSend(name, args) {
|
||||
// Example browser implementation: send function call to server
|
||||
const res = await global.Socket.send({
|
||||
name: name,
|
||||
args: args
|
||||
})
|
||||
|
||||
const json = await res.json()
|
||||
if (!res.ok) throw new Error(json.error)
|
||||
return json.result
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an object of functions so that:
|
||||
* - Node calls the real function
|
||||
* - Browser calls bridgeSend
|
||||
*/
|
||||
export function createBridge(funcs) {
|
||||
return new Proxy(funcs, {
|
||||
get(target, prop) {
|
||||
const orig = target[prop]
|
||||
|
||||
if (typeof orig !== "function") return orig
|
||||
|
||||
return function (...args) {
|
||||
if (IS_NODE) {
|
||||
return orig(...args)
|
||||
} else {
|
||||
return bridgeSend(prop, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
11
src/_/code/bridge/serverFunctions.js
Normal file
11
src/_/code/bridge/serverFunctions.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import fs from "fs"
|
||||
import { createBridge } from "./bridge.js"
|
||||
|
||||
const handlers = {
|
||||
getProfile(one, two) {
|
||||
fs.writeFileSync("output.txt", `${one} ${two}`)
|
||||
return "written to disk"
|
||||
},
|
||||
}
|
||||
|
||||
export const { getProfile } = createBridge(handlers)
|
||||
61
src/_/code/ws/Connection.js
Normal file
61
src/_/code/ws/Connection.js
Normal file
@@ -0,0 +1,61 @@
|
||||
class Connection {
|
||||
connectionTries = 0;
|
||||
ws;
|
||||
receiveCB;
|
||||
|
||||
constructor(receiveCB) {
|
||||
this.receiveCB = receiveCB;
|
||||
}
|
||||
|
||||
init = async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const url = window.location.hostname.includes("local")
|
||||
? "ws://" + window.location.host
|
||||
: "wss://" + window.location.hostname + window.location.pathname;
|
||||
|
||||
this.ws = new WebSocket(url);
|
||||
|
||||
this.ws.addEventListener('open', () => {
|
||||
this.connectionTries = 0;
|
||||
console.log("WebSocket connection established.");
|
||||
this.ws.addEventListener('message', this.receiveCB);
|
||||
resolve(this.ws); // resolve when open
|
||||
});
|
||||
|
||||
this.ws.addEventListener('close', () => {
|
||||
console.log('WebSocket closed');
|
||||
this.checkOpen(); // attempt reconnection
|
||||
});
|
||||
|
||||
this.ws.addEventListener('error', (err) => {
|
||||
console.error('WebSocket error', err);
|
||||
reject(err); // reject if error occurs
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
checkOpen = async () => {
|
||||
if (this.ws.readyState === WebSocket.OPEN) {
|
||||
return true;
|
||||
} else {
|
||||
await this.sleep(this.connectionTries < 20 ? 5000 : 60000);
|
||||
this.connectionTries++;
|
||||
console.log('Reestablishing connection');
|
||||
await this.init();
|
||||
}
|
||||
}
|
||||
|
||||
sleep = (time) => new Promise(resolve => setTimeout(resolve, time));
|
||||
|
||||
send = (msg) => {
|
||||
if (this.ws.readyState === WebSocket.OPEN) {
|
||||
this.ws.send(msg);
|
||||
} else if (this.connectionTries === 0) {
|
||||
setTimeout(() => this.send(msg), 100);
|
||||
} else {
|
||||
console.error('No WebSocket connection: Cannot send message');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Connection;
|
||||
49
src/_/code/ws/Socket.js
Normal file
49
src/_/code/ws/Socket.js
Normal file
@@ -0,0 +1,49 @@
|
||||
import Connection from "./Connection.js";
|
||||
|
||||
export default class Socket {
|
||||
connection;
|
||||
disabled = true;
|
||||
requestID = 1;
|
||||
pending = new Map();
|
||||
|
||||
constructor() {
|
||||
this.connection = new Connection(this.receive);
|
||||
}
|
||||
|
||||
async init() {
|
||||
await this.connection.init()
|
||||
}
|
||||
|
||||
isOpen() {
|
||||
if(this.connection.checkOpen()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
send(msg) {
|
||||
return new Promise(resolve => {
|
||||
const id = (++this.requestID).toString();
|
||||
this.pending.set(id, resolve);
|
||||
this.connection.send(JSON.stringify({ id, ...msg }));
|
||||
});
|
||||
}
|
||||
|
||||
receive = (event) => {
|
||||
const msg = JSON.parse(event.data);
|
||||
if (msg.id && this.pending.has(msg.id)) {
|
||||
this.pending.get(msg.id)(msg);
|
||||
this.pending.delete(msg.id);
|
||||
return;
|
||||
} else {
|
||||
this.onBroadcast(msg)
|
||||
}
|
||||
}
|
||||
|
||||
onBroadcast(msg) {
|
||||
window.dispatchEvent(new CustomEvent(msg.event, {
|
||||
detail: msg.msg
|
||||
}));
|
||||
}
|
||||
}
|
||||
1
src/_/code/ws/shim/fs.js
Normal file
1
src/_/code/ws/shim/fs.js
Normal file
@@ -0,0 +1 @@
|
||||
export default {}
|
||||
Reference in New Issue
Block a user