let wasmbuffers;

let wasmmodule = () => {
    const Module = { repeater: 0 };

    Module.decodeBlendInternal = blended => {
        const startTime = performance.now();
        const extra = new Uint8Array(blended);
        Module.asm.j(24, 132);
        const pos = Module.asm.j(228, 132);

        // The original version copied starting from the second byte of ‘extra’,
        // since it used ‘extra[i + 1]’. Adjusting the set operation accordingly.
        Module.HEAPU8.set(extra.subarray(1, 133), pos);

        Module.asm.j(172, 36);
        const index = Module.asm.j(4, 152);

        // Create a new ArrayBuffer to hold the 64-byte result.
        const arraybuffer = new ArrayBuffer(64);
        const list = new Uint8Array(arraybuffer);

        // Use ‘set’ method to copy 64 bytes from ‘index’ directly into ‘list’.
        // Now, since ‘list’ is created based on a new ArrayBuffer, ‘set’ operates like a memcpy.
        list.set(Module.HEAPU8.subarray(index, index + 64));

        // Peformance Benchmark
        const endTime = performance.now();
        const executionTime = endTime - startTime;
        console.log(`decodeBlendInternal execution time: ${executionTime} milliseconds`);

        return arraybuffer;
    };

    Module.onDecodeOpcode5 = (blended, hostname, callback) => {
        console.log(JSON.stringify(Array.from(new Uint8Array(blended))));
        console.log(hostname);

        Module.blended = blended;
        Module.hostname = hostname;

        // Decode the blended data
        const decoded = Module.decodeBlendInternal(blended);

        const mcs = Module.asm.j(187, 22);

        // Create opcode6Data as a Uint8Array instead of pushing into a regular array
        const opcode6Data = new Uint8Array(17);
        opcode6Data[0] = 6;
        opcode6Data.set(Module.HEAPU8.subarray(mcs, mcs + 16), 1);

        callback({ 5: new Uint8Array(decoded), 6: opcode6Data });
        console.log({ 5: new Uint8Array(decoded), 6: opcode6Data });
    };

    Module.finalizeOpcode10 = blended => {
        const decoded = Module.decodeBlendInternal(blended);
        const list = new Uint8Array(decoded);
        return Uint8Array.of(10, ...list);
    };

    function instantiate(wasmbuffers) {
        WebAssembly.instantiate(wasmbuffers, {
            "a": {
                'd': () => { },
                'f': () => { },
                'c': () => { },
                'e': () => { },
                'b': () => [0, 0, 1, 0, 24][(Module.repeater %= 5, Module.repeater++)],
                'a': () => (Module.HEAPU8.set(new Uint8Array([...new TextEncoder().encode(Module.hostname)]), 200), 200)
            }
        }).then(asm => {
            Module.asm = asm.instance.exports;
            Module.HEAPU8 = new Uint8Array(Module.asm.g.buffer)
            Module.asm.h();
            Module.asm.i(0, 0);
            Module.ready = true;
            if (Module.opcode5Callback) Module.onDecodeOpcode5(Module.blended, Module.hostname, Module.opcode5Callback);
        });
    }

    wasmbuffers ? instantiate(wasmbuffers) : fetch("https://cdn.glitch.global/ac6cfcd4-73cc-46ca-87ec-b913932b390f/zombs_wasm%20(4).wasm?v=1705666953205").then(e => e.arrayBuffer().then(r => {
        wasmbuffers = new Uint8Array(r);
        instantiate(wasmbuffers);
    }));

    return Module;
};

const Module = wasmmodule();

onmessage = async function (event) {
    const { action, data, hostname } = event.data;
    if (action === 'test') console.log(Module);
    if (action === 'finalizeOpcode10') {
        const result = Module.finalizeOpcode10(new Uint8Array(data));
        postMessage({ status: 'finalized', result: result });
    } else if (action === 'onDecodeOpcode5') {
        const result = onDecodeOpcode5(new Uint8Array(data), hostname);
        postMessage({ status: 'decoded', result: result });
    }
}

requesting finalizeOpcode10 causes the wasm to eventually overflow, why/