let _Uint8Array = globalThis.Uint8Array;
let _ArrayBuffer = globalThis.ArrayBuffer;
let _byteLength = Object.getOwnPropertyDescriptor(_ArrayBuffer.prototype, 'byteLength').get;
let _Reflect = { ...Reflect };
let byteLength = (a) => Reflect.apply(_byteLength, a, []);
let set = Uint8Array.prototype.set.call.bind(Uint8Array.prototype.set);
function appendBuffers(buffer1, buffer2) {
var tmp = new _Uint8Array(byteLength(buffer1) + byteLength(buffer2));
set(tmp, new _Uint8Array(buffer1), 0);
set(tmp, new _Uint8Array(buffer2), byteLength(buffer1));
return tmp.buffer;
}
;
let _URL = globalThis.URL;
let _fetch = globalThis.fetch;
let _Promise = globalThis.Promise;
let _DataView = globalThis.DataView;
let _sliceProp = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'slice').get;
let _slice = (a, b, c) => Reflect.apply(_sliceProp, a, [b, c]);
let _requestAnimationFrame = globalThis.requestAnimationFrame.bind(globalThis);
let _decoder = new TextDecoder();
let decode = _decoder.decode.bind(_decoder);
let intOps = {
'getUint8': DataView.prototype.getUint8.call.bind(DataView.prototype.getUint8),
'getUint32': DataView.prototype.getUint32.call.bind(DataView.prototype.getUint32),
'setUint8': DataView.prototype.setUint8.call.bind(DataView.prototype.setUint8),
'setUint32': DataView.prototype.setUint32.call.bind(DataView.prototype.setUint32),
};
export class WebSocket extends EventTarget {
#url;
#messages;
#queueLength;
#proc;
constructor(url, opts = {}) {
super();
this.#proc = opts.proc ?? ((a, m) => a);
var u = typeof url === "string" ? new _URL(url) : url;
if (u.protocol == "ws:") {
u.protocol = "http:";
}
if (u.protocol == "wss:") {
u.protocol = "https:";
}
u.pathname += ".wist";
this.#url = u;
this.#queueLength = opts.queueLength ?? 0;
this.#messages = [];
this.#start();
}
async #start() {
let iid = await _fetch(this.#url).then(a => a.text());
while (1) {
var m = this.#messages;
if (m.length < this.#queueLength) {
await new _Promise(_requestAnimationFrame);
continue;
}
this.#messages = [];
var m2 = m.reduce(appendBuffers, new _ArrayBuffer(0));
var a = await _fetch(this.#url, {
method: "POST",
body: this.#proc(new _Uint8Array(m2), 'encrypt'),
headers: {
"X-Instance-Id": iid,
}
}).then(a => a.arrayBuffer());
a = this.#proc(new _Uint8Array(a), 'decrypt').buffer;
var len2 = byteLength(a);
var d = new _DataView(a);
var i = 0;
while (i != len2) {
var ty = intOps.getUint8(d, i);
if (ty == 0xff) {
return;
}
var len = intOps.getUint32(d, i + 1);
var b = _slice(a, i + 5, i + 5 + len);
i += len + 5;
if (ty & 1) {
this.dispatchEvent(new MessageEvent("message", { data: decode(b) }));
}
else {
this.dispatchEvent(new MessageEvent("message", { data: b }));
}
}
}
}
postMessage(message) {
var b = typeof message == "string" ? new TextEncoder().encode(message) : new Uint8Array(message);
var c = new _ArrayBuffer(b.byteLength + 5);
set(new Uint8Array(c, 5), b, 0);
var d = new _DataView(c);
intOps.setUint8(d, 0, typeof message == "string" ? 1 : 0);
intOps.setUint32(d, 1, b.byteLength);
this.#messages[this.#messages.length] = c;
}
close(...args) {
this.#messages[this.#messages.length] = new Uint8Array([0xff]).buffer;
}
}
const expiry = new WeakMap();
export class Server {
#ids;
#expiry;
#proc;
#init;
constructor(expiry, opts = {}) {
this.#ids = [];
this.#expiry = expiry;
this.#proc = opts.proc ?? ((a, m) => a);
this.#init = opts.init ?? (a => { });
}
async handle(r) {
if (r.method === "GET") {
let id = 0;
while (!(this.#ids?.[id]?.expired() ?? true)) {
id++;
}
let s = `${id}}`;
this.#init(this.#ids[id] = new ServerUser(Date.now() + this.#expiry));
return new Response(s);
}
let h = r.headers.get("X-Instance-Id");
if (h === null) {
return new Response(this.#proc(new Uint8Array([0xff]), 'encrypt'));
}
let user = (this.#ids[h] ??= new ServerUser(Date.now() + this.#expiry));
let s = user.takeMessages();
if (s === undefined) {
return new Response(this.#proc(new Uint8Array([0xff]), 'encrypt'));
}
user.onBuffer(this.#proc(new Uint8Array(await r.arrayBuffer()), 'decrypt').buffer);
expiry.set(user, Date.now() + this.#expiry);
return new Response(this.#proc(new Uint8Array(s.reduce(appendBuffers, new ArrayBuffer(0))), 'encrypt'));
}
}
export class ServerUser extends EventTarget {
#messages;
constructor(expiry_) {
super();
expiry.set(this, expiry_);
}
expired() {
return expiry.get(this) >= Date.now();
}
takeMessages() {
let m = this.#messages;
this.#messages = undefined;
return m;
}
postMessage(message) {
this.#messages ??= [];
var b = typeof message == "string" ? new TextEncoder().encode(message) : new Uint8Array(message);
var c = new _ArrayBuffer(b.byteLength + 5);
set(new Uint8Array(c, 5), b, 0);
var d = new _DataView(c);
intOps.setUint8(d, 0, typeof message == "string" ? 1 : 0);
intOps.setUint32(d, 1, b.byteLength);
this.#messages[this.#messages.length] = c;
}
onBuffer(a) {
var len2 = byteLength(a);
var d = new _DataView(a);
var i = 0;
while (i != len2) {
var ty = intOps.getUint8(d, i);
if (ty == 0xff) {
return;
}
var len = intOps.getUint32(d, i + 1);
var b = _slice(a, i + 5, i + 5 + len);
i += len + 5;
if (ty & 1) {
this.dispatchEvent(new MessageEvent("message", { data: decode(b) }));
}
else {
this.dispatchEvent(new MessageEvent("message", { data: b }));
}
}
}
}