Search code examples
javascriptsqlitebase64webassembly

How do I load SQL.js WASM as base64 so that it can be loaded directly in HTML file


I am trying to load sql-wasm.wasm from https://github.com/sql-js/sql.js such that it does not need a server. Otherwise, trying to load wasm from HTML gives CORS error. I converted it to base64 (~800KB) which looks like this

const SQLBASE64 = "AGFzbQEAAAABrQRHYAJ/fwF/YAF/AX....AAJ4BAEHwogQLA4AWUQ==";

(link to full base64 string)

WebAssembly.Instance only works with very small binaries. WebAssembly.instantiate() and WebAssembly.instantiateStreaming() both end up with errors about incorrect object, format, or headers etc.

How do I do it properly?


Solution

  • So there were two problems.

    1. base64 string was incorrect. Used https://github.com/BillKek/wasm2js_let_static to convert sql-wasm.wasm v1.8.0 to base64 correctly.
    2. Don't need to call WebAssembly.instantiate directly, use initSqlJs() from sql.js instead.

    Then loaded it like this

        const wasm_strbuffer = atob(SQLBASE64);
        let wasm_codearray = new Uint8Array(wasm_strbuffer.length);
        for (var i in wasm_strbuffer) wasm_codearray[i] = wasm_strbuffer.charCodeAt(i);
    
        const sqlPromise = initSqlJs({
            locateFile: filename => URL.createObjectURL(new Blob([wasm_codearray], { type: 'application/wasm' }))
        });
        const dataPromise = fetch("mysqlite.db").then(res => res.arrayBuffer());
        Promise.all([sqlPromise, dataPromise]).then((data) => {
            const SQL = data[0];
            const buf = data[1];
            const db = new SQL.Database(new Uint8Array(buf));
            dbLoaded(db);
        });
    

    Base64 wasm gist https://gist.github.com/SMUsamaShah/358fba159cb41fe469fc61e7db444c0e