import userWasm from "./__WASM_NAME__.wasm";
let exports = null;
let instancePromise = null;
let pendingReq = null;
let pendingBody = "";
let pendingResponse = null;
const encoder = new TextEncoder();
const decoder = new TextDecoder("utf-8");
function memU8() {
return new Uint8Array(exports.memory.buffer);
}
function ensurePages(needed) {
const current = exports.__rt_memory_pages();
if (needed > current) exports.__rt_memory_grow(needed - current);
}
function jsToAver(text) {
const s = text ?? "";
const upperBytes = s.length * 3;
ensurePages(((upperBytes + 65535) >> 16) || 1);
const { written } = encoder.encodeInto(s, memU8());
return exports.__rt_string_from_lm(written);
}
function averToJs(s) {
const len = exports.__rt_string_to_lm(s);
return decoder.decode(memU8().subarray(0, len));
}
function buildHeadersMap(jsHeaders) {
const grouped = new Map();
for (const [name, value] of jsHeaders) {
const lower = name.toLowerCase();
if (lower === "set-cookie") continue; if (!grouped.has(lower)) grouped.set(lower, [value]);
else grouped.get(lower).push(value);
}
if (typeof jsHeaders.getSetCookie === "function") {
const cookies = jsHeaders.getSetCookie();
if (cookies.length > 0) grouped.set("set-cookie", cookies);
}
let map = exports.__rt_map_string_list_string_empty();
for (const [name, values] of grouped) {
let list = null;
for (let i = values.length - 1; i >= 0; i--) {
list = exports.__rt_list_string_cons(jsToAver(values[i]), list);
}
map = exports.__rt_map_string_list_string_set(map, jsToAver(name), list);
}
return map;
}
async function init() {
const imports = {
aver: {
time_unix_ms: (_caller) => BigInt(Date.now()),
request_method: (_caller) => jsToAver(pendingReq.method),
request_url: (_caller) => jsToAver(new URL(pendingReq.url).pathname),
request_query: (_caller) => jsToAver(new URL(pendingReq.url).search.slice(1)),
request_body: (_caller) => jsToAver(pendingBody),
request_headers_load: (_caller) => buildHeadersMap(pendingReq.headers),
response_text: (status, bodyRef, _caller) => {
pendingResponse.status = Number(status);
pendingResponse.body = averToJs(bodyRef);
},
response_set_header: (nameRef, valueRef, _caller) => {
pendingResponse.headers.push([averToJs(nameRef), averToJs(valueRef)]);
},
console_print: (msgRef, _caller) => { console.log(averToJs(msgRef)); },
console_error: (msgRef, _caller) => { console.error(averToJs(msgRef)); },
console_warn: (msgRef, _caller) => { console.warn(averToJs(msgRef)); },
},
};
const instance = await WebAssembly.instantiate(userWasm, imports);
exports = instance.exports;
}
export default {
async fetch(request) {
if (!instancePromise) instancePromise = init();
await instancePromise;
pendingBody = await request.text();
pendingReq = request;
pendingResponse = { status: 200, body: "", headers: [] };
try {
exports.aver_http_handle();
} finally {
pendingReq = null;
pendingBody = "";
}
const r = pendingResponse;
pendingResponse = null;
const headers = new Headers();
for (const [name, value] of r.headers) headers.append(name, value);
if (!headers.has("content-type")) {
headers.set("content-type", "text/plain;charset=utf-8");
}
return new Response(r.body, { status: r.status, headers });
},
};