skip to Main Content

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?

2

Answers


  1. Chosen as BEST ANSWER

    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


  2. You can try using the answer from this question (with your const it would be):

    const SQLBASE64 = "...";
    
    function asciiToBinary(str) {
      if (typeof atob === 'function') {
        return atob(str)
      } else {
        return new Buffer(str, 'base64').toString('binary');
      }
    }
    
    function decode(encoded) {
      var binaryString =  asciiToBinary(encoded);
      var bytes = new Uint8Array(binaryString.length);
      for (var i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
      }
      return bytes.buffer;
    }
    
    var instance = WebAssembly.instantiate(decode(SQLBASE64), {})
          .then(r => r.instance);
    

    Edit:

    I investigated more, and you need the sql-wasm.js file in order to instantiate the sql-wasm.wasm file. Your wasm module needs imports that sql-wasm.js would give, but the config it takes seems to only take a path, for now. Meaning, there is no way to tell it to load a binary module already in the html file.

    I think this can be changed though, with either a pull request or an issue on the official repo. I am, of course, hopeful to be proven wrong by somebody more knowledgeable.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search