Skip to content

Commit f451216

Browse files
committed
The "module" is now an async function that loads and initializes Sql.js
I am purposefully not checking in the compiled assets just yet until this stabilizes
1 parent b4b749a commit f451216

File tree

7 files changed

+77
-52
lines changed

7 files changed

+77
-52
lines changed

coffee/output-post.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11

2-
}.bind(this));
2+
}).bind(this);
3+
4+
Module['preRun'] = Module['preRun'] || [];
5+
Module['preRun'].push(runCompiledCode);

coffee/output-pre.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11

22

33
// Wait for preRun to run, and then finish our initialization
4-
Module['preRunHasRun'].then(function(){
4+
var runCompiledCode = (function() {

js/shell-post.js

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
2-
return Module;
3-
})(Module);
4-
5-
if (typeof exports === 'object' && typeof module === 'object')
6-
module.exports = Module;
7-
else if (typeof define === 'function' && define['amd'])
8-
define([], function() { return Module; });
9-
else if (typeof exports === 'object')
10-
exports["Module"] = Module;
1+
2+
3+
// The shell-pre.js and emcc-generated code goes above
4+
return Module;
5+
}); // The end of the promise being returned
6+
7+
return initSqlJsPromise;
8+
} // The end of our initSqlJs function
9+
10+
// This will allow the module to be used in ES6 or CommonJS
11+
initSqlJs.default = initSqlJs;
12+
if (typeof exports === 'object' && typeof module === 'object'){
13+
module.exports = initSqlJs;
14+
}
15+

js/shell-pre.js

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,52 @@
1+
12
// We are modularizing this manually because the current modularize setting in Emscripten has some issues:
23
// https://github.com/kripken/emscripten/issues/5820
3-
var Module = (function(Module) {
4-
5-
// If Module already exists, use it
6-
var Module = typeof Module !== 'undefined' ? Module : {};
7-
8-
Module['preRunHasRun'] = new Promise(function(resolve){
9-
// TODO: Add on to any postRun objects already there
10-
Module['preRun'] = function(){
11-
// When Emscripted calls preRun, this resolves
12-
resolve();
13-
}
14-
}.bind(this));
15-
16-
var postRunHasRun = Module['postRunHasRun'] = new Promise(function(resolve){
17-
// TODO: Add on to any postRun objects already there
18-
Module['postRun'] = function(){
19-
// When Emscripted calls postRun, this resolves
20-
resolve();
21-
}
22-
}.bind(this));
23-
24-
// This is a promise that a module loader can listen for
25-
Module['ready'] = new Promise(function(resolve, reject){
26-
// TODO: Add on to any onAbort function already there
27-
Module['onAbort'] = function(what){
28-
reject(new Error(what));
29-
}
30-
31-
return postRunHasRun.then(function(){
32-
resolve(Module);
33-
}.bind(this));
34-
35-
}.bind(this));
4+
// This module exports a promise that loads and resolves to the actual sql.js module.
5+
// That way, this module can't be used before the WASM is finished loading.
6+
7+
8+
// So the first thing that this module does is define a place for the loadedModule to reside
9+
10+
// We are going to define a function that a user will call to start loading initializing our Sql.js library
11+
// However, that function might be called multiple times, and on subsequent calls, we want it to return the same module that it's already loaded once before.
12+
13+
var initSqlJsPromise = undefined;
14+
15+
var initSqlJs = function (moduleConfig) {
16+
17+
if (initSqlJsPromise){
18+
return initSqlJsPromise;
19+
}
20+
// If we're here, we've never called this function before
21+
initSqlJsPromise = new Promise((resolveModule) => {
22+
23+
// We are modularizing this manually because the current modularize setting in Emscripten has some issues:
24+
// https://github.com/kripken/emscripten/issues/5820
25+
26+
// The way to affect the loading of emcc compiled modules is to create a variable called `Module` and add
27+
// properties to it, like `preRun`, `postRun`, etc
28+
// We are using that to get notified when the WASM has finished loading.
29+
// Only then will we return our promise
30+
31+
// If they passed in a moduleConfig object, use that
32+
// Otherwise, initialize Module to the empty object
33+
var Module = typeof moduleConfig !== 'undefined' ? moduleConfig : {};
34+
35+
// EMCC only allows for a single onAbort function (not an array of functions)
36+
// So if the user defined their own onAbort function, we remember it and call it
37+
var originalOnAbortFunction = Module['onAbort'];
38+
Module['onAbort'] = function (errorThatCausedAbort) {
39+
reject(new Error(errorThatCausedAbort));
40+
if (originalOnAbortFunction){
41+
originalOnAbortFunction(errorThatCausedAbort);
42+
}
43+
};
3644

45+
Module['postRun'] = Module['postRun'] || [];
46+
Module['postRun'].push(function () {
47+
// When Emscripted calls postRun, this promise resolves with the built Module
48+
resolveModule(Module);
49+
});
50+
51+
// The emcc-generated code and shell-post.js code goes below,
52+
// meaning that all of it runs inside of this promise. If anything throws an exception, our promise will abort

test/all.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ var fs = require("fs");
22
Error.stackTraceLimit = 200;
33
var target = process.argv[2];
44
var file = target ? "../js/sql-"+target+".js" : "../js/sql.js";
5-
var sqlModule = require(file);
6-
sqlModule.ready.then((sql)=>{
5+
var initSqlJs = require(file);
6+
7+
initSqlJs().then((sql)=>{
78
var files = fs.readdirSync(__dirname);
89
for (var i=0; i<files.length; i++) {
910
var file = files[i];

test/load_sql_file.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
module.exports = function(sqlFileTarget){
22
var sqlFileTarget = process.argv[2];
3-
var file = sqlFileTarget ? "../js/sql-"+sqlFileTarget+".js" : "../js/sql.js";
3+
var sqlJsLib = sqlFileTarget ? "../js/sql-"+sqlFileTarget+".js" : "../js/sql.js";
44
begin = new Date();
5-
var sqlModule = require(file);
6-
return sqlModule.ready.then((sql)=>{
5+
var initSqlJs = require(sqlJsLib);
6+
return initSqlJs().then((sql)=>{
77
end = new Date();
8-
console.log(`Loaded and inited ${file} in ${end -begin}ms`);
8+
console.log(`Loaded and inited ${sqlJsLib} in ${end -begin}ms`);
99
return sql;
1010
});
1111
}

test/test_errors.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ exports.test = function(sql, assert) {
5050

5151
assert.throws(function(){
5252
stmt.run([3]);
53-
}, "Statements should'nt be able to execute after the database is closed");
53+
}, "Statements shouldn't be able to execute after the database is closed");
5454
};
5555

5656
if (module == require.main) {

0 commit comments

Comments
 (0)