1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-10-21 11:13:54 +03:00

Refactor and simplify the JS API bootstrap steps.

FossilOrigin-Name: a4f36fd93738f985d2c757c69eddca092732ce6148af98eb2595f9abe0d4fa44
This commit is contained in:
stephan
2025-09-22 21:04:24 +00:00
parent cfa48c17f7
commit e55a29f5fd
9 changed files with 127 additions and 111 deletions

View File

@@ -148,7 +148,7 @@ build-generated `sqlite3.js` along with `sqlite3-api.js`.
most of its work.
- **`post-js-header.js`**\
Emscripten-specific header for the `--post-js` input. It opens up,
but does not close, a function.
but does not close, a function used for initializing the library.
- (**`sqlite3-api.js`** gets sandwiched between these ↑ two
↓ files.)
- **`post-js-footer.js`**\

View File

@@ -64,29 +64,13 @@ const toExportForESM =
return originalInit(...args).then((EmscriptenModule)=>{
sIMS.debugModule("sqlite3InitModule() sIMS =",sIMS);
sIMS.debugModule("sqlite3InitModule() EmscriptenModule =",EmscriptenModule);
EmscriptenModule.runSQLite3PostLoadInit(
EmscriptenModule /* see post-js-header/footer.js */
const s = EmscriptenModule.runSQLite3PostLoadInit(
sIMS,
EmscriptenModule /* see post-js-header/footer.js */,
!!ff.__isUnderTest
);
delete EmscriptenModule.runSQLite3PostLoadInit;
const s = EmscriptenModule.sqlite3;
delete EmscriptenModule.sqlite3;
s.scriptInfo = sIMS /* needed by async init below */;
if(ff.__isUnderTest){
s.__isUnderTest = true;
s.emscripten = EmscriptenModule;
//#if custom-Module.instantiateWasm
const iw = sIMS.instantiateWasm;
if( iw ){
/* Metadata injected by the custom Module.instantiateWasm()
in pre-js.c-pp.js. */
s.wasm.module = iw.module;
s.wasm.instance = iw.instance;
s.wasm.imports = iw.imports;
}
//#endif custom-Module.instantiateWasm
}
const rv = s.asyncPostInit();
delete s.asyncPostInit;
//const rv = s.asyncPostInit();
//delete s.asyncPostInit;
//#if wasmfs
if('undefined'!==typeof WorkerGlobalScope &&
EmscriptenModule['ENVIRONMENT_IS_PTHREAD']){
@@ -99,7 +83,7 @@ const toExportForESM =
return EmscriptenModule;
}
//#endif
return rv;
return s;
}).catch((e)=>{
console.error("Exception loading sqlite3 module:",e);
throw e;
@@ -129,6 +113,9 @@ const toExportForESM =
glue... */
if (typeof exports === 'object' && typeof module === 'object'){
module.exports = sqlite3InitModule;
module.exports.default = sqlite3InitModule;
}else if( 'function'===typeof define && define.amd ){
define([], ()=>sqlite3InitModule);
}else if (typeof exports === 'object'){
exports["sqlite3InitModule"] = sqlite3InitModule;
}

View File

@@ -1,19 +1,26 @@
/**
post-js-header.js is to be prepended to other code to create
post-js.js for use with Emscripten's --post-js flag. This code
requires that it be running in that context. The Emscripten
environment must have been set up already but it will not have
loaded its WASM when the code in this file is run. The function this
file installs will be run after the WASM module is loaded, at which
point the sqlite3 JS API bits will get set up.
post-js.js for use with Emscripten's --post-js flag, so it gets
injected in the earliest stages of sqlite3InitModule().
This function wraps the whole SQLite3 library but does not
bootstrap it.
Running this function will bootstrap the library and return
a Promise to the sqlite3 namespace object.
*/
Module.runSQLite3PostLoadInit = function(EmscriptenModule/*the Emscripten-style module object*/){
Module.runSQLite3PostLoadInit = function(
sqlite3InitScriptInfo /* populated by extern-post-js.c-pp.js */,
EmscriptenModule/*the Emscripten-style module object*/,
sqlite3IsUnderTest
){
/** ^^^ Don't use Module.postRun, as that runs a different time
depending on whether this file is built with emcc 3.1.x or
4.0.x. This function name is intentionally obnoxiously verbose to
ensure that we don't collide with current and future Emscripten
symbol names. */
'use strict';
delete EmscriptenModule.runSQLite3PostLoadInit;
//console.warn("This is the start of Module.runSQLite3PostLoadInit()");
/* This function will contain at least the following:

View File

@@ -17,7 +17,9 @@
const sIMS =
globalThis.sqlite3InitModuleState/*from extern-post-js.c-pp.js*/
|| Object.assign(Object.create(null),{
debugModule: ()=>{}
debugModule: ()=>{
console.warn("globalThis.sqlite3InitModuleState is missing");
}
});
delete globalThis.sqlite3InitModuleState;
sIMS.debugModule('pre-js.js sqlite3InitModuleState =',sIMS);

View File

@@ -26,56 +26,57 @@
It is run within a context which gives it access to Emscripten's
Module object, after sqlite3.wasm is loaded but before
sqlite3ApiBootstrap() has been called.
Because this code resides (after building) inside the function
installed by post-js-header.js, it has access to the
*/
'use strict';
if( 'undefined' !== typeof Module ){ // presumably an Emscripten build
try{
const SABC = Object.assign(
/**
The WASM-environment-dependent configuration for
sqlite3ApiBootstrap().
*/
Object.create(null),
globalThis.sqlite3ApiConfig || {}, {
memory: ('undefined'!==typeof wasmMemory)
? wasmMemory
: Module['wasmMemory'],
exports: ('undefined'!==typeof wasmExports)
? wasmExports /* emscripten >=3.1.44 */
: (Object.prototype.hasOwnProperty.call(Module,'wasmExports')
? Module['wasmExports']
: Module['asm']/* emscripten <=3.1.43 */)
},
);
/** Figure out if this is a 32- or 64-bit WASM build. */
SABC.wasmPtrIR = 'number'===(typeof SABC.exports.sqlite3_libversion())
? 'i32' :'i64';
/**
For current (2022-08-22) purposes, automatically call
sqlite3ApiBootstrap(). That decision will be revisited at some
point, as we really want client code to be able to call this to
configure certain parts. Clients may modify
globalThis.sqlite3ApiBootstrap.defaultConfig to tweak the default
configuration used by a no-args call to sqlite3ApiBootstrap(),
but must have first loaded their WASM module in order to be
able to provide the necessary configuration state.
*/
//console.warn("globalThis.sqlite3ApiConfig = ",globalThis.sqlite3ApiConfig);
Module.sqlite3 = globalThis.sqlite3ApiBootstrap(SABC)
/* Our customized sqlite3InitModule() in extern-post-js.js needs
this to be able to pass the sqlite3 object off to the
client. */;
delete globalThis.sqlite3ApiBootstrap;
delete globalThis.sqlite3ApiConfig;
}catch(e){
console.error("sqlite3ApiBootstrap() error:",e);
throw e;
}
}else{
console.warn("This is not running in an Emscripten module context, so",
"globalThis.sqlite3ApiBootstrap() is _not_ being called due to lack",
"of config info for the WASM environment.",
"It must be called manually.");
if( 'undefined' === typeof EmscriptenModule/*from post-js-header.js*/ ){
console.warn("This is not running in the context of Module.runSQLite3PostLoadInit()");
throw new Error("sqlite3-api-cleanup.js expects to be running in the "+
"context of its Emscripten module loader.");
}
try{
/* Config options for sqlite3ApiBootstrap(). */
const bootstrapConfig = Object.assign(
Object.create(null),
globalThis.sqlite3ApiBootstrap.defaultConfig, // default options
globalThis.sqlite3ApiConfig || {}, // optional client-provided options
/** The WASM-environment-dependent configuration for sqlite3ApiBootstrap() */
{
memory: ('undefined'!==typeof wasmMemory)
? wasmMemory
: EmscriptenModule['wasmMemory'],
exports: ('undefined'!==typeof wasmExports)
? wasmExports /* emscripten >=3.1.44 */
: (Object.prototype.hasOwnProperty.call(EmscriptenModule,'wasmExports')
? EmscriptenModule['wasmExports']
: EmscriptenModule['asm']/* emscripten <=3.1.43 */)
}
);
/** Figure out if this is a 32- or 64-bit WASM build. */
bootstrapConfig.wasmPtrIR =
'number'===(typeof bootstrapConfig.exports.sqlite3_libversion())
? 'i32' :'i64';
/**
For purposes of the Emscripten build, call sqlite3ApiBootstrap().
Ideally clients should be able to inject their own config here,
but that's not practical in this particular build constellation
because of the order everything happens in. Clients may either
define globalThis.sqlite3ApiConfig or modify
globalThis.sqlite3ApiBootstrap.defaultConfig to tweak the default
configuration used by a no-args call to sqlite3ApiBootstrap(),
but must have first loaded their WASM module in order to be able
to provide the necessary configuration state.
*/
const p = globalThis.sqlite3ApiBootstrap(bootstrapConfig);
delete globalThis.sqlite3ApiBootstrap;
return p;
}catch(e){
console.error("sqlite3ApiBootstrap() error:",e);
throw e;
}
throw new Error("Maintenance required: this line should never be reached");

View File

@@ -127,17 +127,12 @@
because any changes to them made after that point would have no
useful effect.
This function bootstraps only the _synchronous_ pieces of the
library. After calling this, sqlite3.asyncPostInit() must be
called to initialize any async pieces (most notably the
OPFS-related pieces) and should then delete sqlite3.asyncPostInit.
That function is NOT part of the public interface, but is rather a
side-effect of how we need to finalize initialization. If we
include that part of the init from here, this function will need to
return a Promise instead of being synchronous.
This function returns a Promise to the sqlite3 namespace object,
which resolves after the async pieces of the library init are
complete.
*/
'use strict';
globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
apiConfig = (globalThis.sqlite3ApiConfig || sqlite3ApiBootstrap.defaultConfig)
){
if(sqlite3ApiBootstrap.sqlite3){ /* already initialized */
@@ -2076,8 +2071,6 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
clients build their own sqlite3.wasm which contains their
own C struct types. */
delete sqlite3.StructBinder;
delete sqlite3.scriptInfo;
delete sqlite3.emscripten;
}
return sqlite3;
};
@@ -2122,7 +2115,33 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
}
delete sqlite3ApiBootstrap.initializers;
sqlite3ApiBootstrap.sqlite3 = sqlite3;
return sqlite3;
delete globalThis.sqlite3ApiBootstrap;
delete globalThis.sqlite3ApiConfig;
sqlite3InitScriptInfo.debugModule(
"sqlite3ApiBootstrap() complete", sqlite3
);
sqlite3.scriptInfo /* used by some async init code */ =
sqlite3InitScriptInfo /* from post-js-header.js */;
if( (sqlite3.__isUnderTest = sqlite3IsUnderTest) ){
sqlite3.config.emscripten = EmscriptenModule;
const iw = sqlite3InitScriptInfo.instantiateWasm;
if( iw ){
/* Metadata injected by the custom Module.instantiateWasm()
in pre-js.c-pp.js. */
sqlite3.wasm.module = iw.module;
sqlite3.wasm.instance = iw.instance;
sqlite3.wasm.imports = iw.imports;
}
}
return sqlite3.asyncPostInit().then((s)=>{
sqlite3InitScriptInfo.debugModule(
"sqlite3.asyncPostInit() complete", sqlite3
);
delete s.asyncPostInit;
delete s.scriptInfo;
delete s.emscripten;
return s;
});
}/*sqlite3ApiBootstrap()*/;
/**

View File

@@ -39,13 +39,13 @@
* - `#stderr` outputs its file name, line number, and the remainder
** of that line to stderr.
**
** - `#//` acts as a single-line comment, noting that there must be as
** - `#//` acts as a single-line comment, noting that there must be no
** space after the `//` part because `//` is (despite appearances)
** parsed like a keyword.
**
** Note that "#" above is symbolic. The keyword delimiter is
** configurable and defaults to "##". Define CMPP_DEFAULT_DELIM to a
** string when compiling to define the default at build-time.
** The "#" above is symbolic. The keyword delimiter is configurable
** and defaults to "##". Define CMPP_DEFAULT_DELIM to a string when
** compiling to define the default at build-time.
**
** This preprocessor does no expansion of content except within the
** bounds of its `#keywords`.

View File

@@ -1,5 +1,5 @@
C Update\sext/wasm/api/README.md\sfor\srecent\schanges.
D 2025-09-22T18:05:10.957
C Refactor\sand\ssimplify\sthe\sJS\sAPI\sbootstrap\ssteps.
D 2025-09-22T21:04:24.057
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -590,16 +590,16 @@ F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core e5cf4fa7610a09d51017d75faf50be381
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras cb4fa8842c875b6ee99381523792975c5ebb7371bd27fbd1bd863a43c7f3505a
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/api/README.md 5fc27524cae0851ba577859dc464e432f2de8a633c30927d29e81b6904e699d5
F ext/wasm/api/extern-post-js.c-pp.js 36181698fa0a8dba6292d0659c8945941f7794d632883bd335c4a7c7d2981555
F ext/wasm/api/README.md dd7008fb495eabf46541c4422cc396b3705507c80d681e388e02969e3707dd27
F ext/wasm/api/extern-post-js.c-pp.js d3748c6bbdcef15d8e494e0558aad370b9c24242eb020042b3a73b4950562f5b
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
F ext/wasm/api/post-js-footer.js e617e5f81a907362de152576323155f02d24642e625fc05fb801b86b6a269444
F ext/wasm/api/post-js-header.js ada7c1efc3f72126cc10c5977dba1813f2b790fafed1a817fdea805d92bd2ae6
F ext/wasm/api/pre-js.c-pp.js 9926ffc97c1053b5605c1b46ada396d73c07c424dd3e1cd499bbe80dc1f838cb
F ext/wasm/api/sqlite3-api-cleanup.js 9d15f0593628c526a3eee4906a224b59d60f82e765b20c7277ffe109c3da4920
F ext/wasm/api/post-js-header.js 79d078aec33d93b640a19c574b504d88bb2446432f38e2fbb3bb8e36da436e70
F ext/wasm/api/pre-js.c-pp.js 664551f490d296e0f4590d3a029787ab0782b9a1fa5954d73bde4fb2c6bfc709
F ext/wasm/api/sqlite3-api-cleanup.js f91a2afdef19c350bce99784fff20310d4d060520001059822aa36c4ce80dc56
F ext/wasm/api/sqlite3-api-glue.c-pp.js 12f5b36775fab1e7bf5385689fded2b2a9f77360562515e9849acb5e66602e2d
F ext/wasm/api/sqlite3-api-oo1.c-pp.js db4c8ebb03bac60db32ce03f8c615b00f4e4ad53e7d5de5e63d2780cba052caa
F ext/wasm/api/sqlite3-api-prologue.js 0daf5f7c6ebbae3c21df19ede17114aad2643b7898f0ea1ae35abbd824b6e6cf
F ext/wasm/api/sqlite3-api-prologue.js 259c72c6a33ba1be2297c568cbc2ad53437d1d4b2613d7772c56a3aa00bf435d
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 760191cd13416e6f5adfd9fcc8a97fed5645c9e0a5fbac213a2d4ce2d79a4334
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9654b565b346dc609b75d15337f20acfa7af7d9d558da1afeb9b6d8eaa404966
@@ -614,7 +614,7 @@ F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0
F ext/wasm/batch-runner-sahpool.js 54a3ac228e6c4703fe72fb65c897e19156263a51fe9b7e21d2834a45e876aabd
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
F ext/wasm/batch-runner.js 05ec254f5dbfe605146d9640b3db17d6ef8c3fbef6aa8396051ca72bb5884e3f
F ext/wasm/c-pp.c cca55c5b55ebd8d29916adbedb0e40baa12caa9a2e8429f812683c308f9b0e9a
F ext/wasm/c-pp.c 75e23ad9ca3a3771e70d401ba79c0bacdf7b2169d1c17f9e2639d81067e5ab95
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
@@ -2175,8 +2175,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 35651d9ab5529da915500fc50ca3833a004d0b7a19d98e8fbf39234d94697aec
R 452146c528c5b88da8bcc9faecddbf7e
P 03b70686939e5f9ad984220a31674c23a1beb19f040c6327f24e23f0378555da
R 6a74008597b5313223f9fb216ce43e56
U stephan
Z 3d212d42a59ec4f93d36bc8b774364d4
Z 1035784c7ea8d2df82b4b0ed89892087
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
03b70686939e5f9ad984220a31674c23a1beb19f040c6327f24e23f0378555da
a4f36fd93738f985d2c757c69eddca092732ce6148af98eb2595f9abe0d4fa44