sql.js icon indicating copy to clipboard operation
sql.js copied to clipboard

Feature request: Support ES module

Open Gladear opened this issue 5 years ago • 8 comments

Hi,

It would be nice to add a module target to the project. This would allow to dynamically import the library with import() function, and would probably work better with some bundlers (thinking about rollup now). I'm trying to work on it, but I'm not used to work with coffeescript and make, so any help is welcome !

Gladear avatar Jul 13 '19 10:07 Gladear

I've had some luck with this adaption: https://pastebin.com/d70TyxZq

const sql = await import("../libs/sql.js/sql-wasm.js");
window.initSqlJs = sql.initSqlJs;

using it together with geopackage.js like this:
...

initSqlJs({ locateFile: filename => "../libs/sql.js/sql-wasm.wasm" })
.then(async (SQL) => {
		const u8 = new Uint8Array(buffer);
		const data = await geopackage.open(u8);
		...

EDIT: Okay, I'm not actually sure if this really works. It does seem to work but apparently geopackage.js bundles it's own sql.js. I still have to import sql.js or I will get an error. So I'm not sure if geopackage ends up using this ES module adaption, or it's own bundled sql.js.

m-schuetz avatar Oct 21 '19 11:10 m-schuetz

In the previous comment, the linked pastebin uses a modified sql-wasm.js. I think all it really does is add export {initSqlJs}; at the end so it's an easy hack, but it is not the distributed version.

The hack I use instead in the browser is to fetch the official sql-wasm.js as plain text and use that to create a Function that I can call to extract initSqlJs:

/**
 * Workaround lack of ES6 support in SQL.js.
 * 
 * https://github.com/sql-js/sql.js/issues/284
 *
 * Sample usage:
 * ```
 * import { initSqlJs } from './SqlJs';
 *
 * initSqlJs(file => `path/to/dist/${file}`).then(SQL => {
 *   const db = new SQL.Database();
 * });
 * ```
 * @param {function(string): string} fileMap 
 */
export async function initSqlJs(fileMap) {
  // Get the SqlJs code as a string.
  const response = await fetch(fileMap('sql-wasm.js'));
  const code = await response.text();

  // Instantiate the code and access its exports.
  const f = new Function('exports', code);
  const exports = {};
  f(exports);

  // Call the real initSqlJs().
  return exports.Module({ locateFile: fileMap });
}

This is still a hack - it may break if/when the SQL.js module wrapper code is changed - but it doesn't require changing the distributed files.

edit: Changed the workaround to provide the same initialization API as SQL.js itself.

rhashimoto avatar Jan 25 '21 21:01 rhashimoto

I think this makes sql.js unusable from Vite which uses rollup underneath. The page it creates just freezes the whole Google Chrome. Just with simple code:

import initSqlite from "sql.js";

initSqlite({
    locateFile: (file) => `https://sql.js.org/dist/${file}`,
}).then((SQL) => {
    const db = new SQL.Database();
    console.log("SQLite is loaded");
});

Ciantic avatar Sep 19 '21 17:09 Ciantic

This is still a hack

why is this still needed in 2022 ?? : (

skypack score

Maintainers, are there plans to improve this?

or any one working on a PR ?

gotjoshua avatar Jul 17 '22 09:07 gotjoshua

The absence of this feature has proved to be a real pain point for use of sql.js in typescript / angular.

johncardiologs avatar Aug 26 '22 18:08 johncardiologs

Also would love typescript and es modules. Would be nice to use rollup without the hack described above.

anaestheticsapp avatar Aug 30 '22 17:08 anaestheticsapp

I've attempted to make this work with https://github.com/sql-js/sql.js/pull/539.

I've published this as @stephen/sql.js for now to test in my own projects, though I can't promise that it will not have breaking changes (i.e. also added typescript types there...).

stephen avatar Jan 02 '23 14:01 stephen

Hi @stephen thanks for going to the trouble of making that!

I can't submit an issue on your fork but I'm hitting some issues and wondered if you can help. I'm finding that the WASM file import is blocked when running

SQL = await import("@stephen/sql.js")

Which causes the import to fail. Don't want to clutter this thread with unrelated error messages/debugging.

Where is appropriate for me to ask you for more info?

Robin-Lord avatar Jan 26 '23 09:01 Robin-Lord