(() => { const self = reg_ns("streams"); self.STREAMS = {}; self.USER = null; self.define("user", ({ $ }, user_id) => { $.USER = user_id; }); self.define("sock", ({ $ }, stream) => { return $.STREAMS[stream]; }); self.define("get", ({ $ }, id) => { for (const stream of Object.values($.STREAMS)) { if (stream.id === id) { return stream; } } }); self.define("subscribe", ({ $ }, stream) => { if (!$.USER) { console.warn("cannot subscribe without user id"); return; } if ($.STREAMS[stream]) { console.warn("stream already exists"); return $.STREAMS[stream]; } const endpoint = `${window.location.origin.replace("http", "ws")}/api/v1/auth/user/${$.USER}/_connect/${stream}`; const socket = new WebSocket(endpoint); $.STREAMS[stream] = { id: null, socket, events: { message: () => {}, }, }; socket.addEventListener("message", (event) => { if (event.data === "Ping") { return socket.send("Pong"); } const data = JSON.parse(event.data); if (data.method.Forward === "Key") { $.STREAMS[stream].id = data.data; return console.info(`${stream} ${data.data}`); } return $.sock(stream).events.message(data); }); return $.STREAMS[stream]; }); self.define("close", ({ $ }, stream) => { const socket = $.sock(stream); if (!socket) { console.warn("no such stream to close"); return; } socket.socket.send("Close"); socket.socket.close(); }); self.define("event", ({ $ }, stream, event, handler) => { const socket = $.sock(stream); if (!socket) { console.warn("no such stream to add event to"); return; } socket.events[event] = handler; }); self.define("send_packet", async ({ $ }, stream, method, data) => { await ( await fetch(`/api/v1/auth/user/${$.USER}/_connect/${stream}/send`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ method, data: JSON.stringify(data), }), }) ).json(); }); })();