1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-12-20 01:22:32 +03:00

Move sqlite3-api-cleanup.js into post-js-footer.js to remove the final direct Emscripten dependency from the intermediary build product sqlite3-api.js (the whole library, waiting to be bootstrapped). This is partly in response to [forum:4b7d45433731d2e0|forum post 4b7d45433731d2e0], which demonstrates a potential use case for a standalone sqlite3-api.js. This is a build/doc change, not a functional one.

FossilOrigin-Name: 2fcbd8e17d8f1dd7e9d45168805dba718777e46803d9375a4212296d3d0cd89c
This commit is contained in:
stephan
2025-11-15 09:19:03 +00:00
parent 5279cbd353
commit a804a65617
10 changed files with 143 additions and 135 deletions

View File

@@ -60,14 +60,14 @@ maintenance point of view.
At the center of the onion is `sqlite3-api.js`, which gets generated
by concatenating the following files together in their listed order:
- **`sqlite3-api-prologue.js`**\
- **`sqlite3-api-prologue.js`**
Contains the initial bootstrap setup of the sqlite3 API
objects. This is exposed as a function, rather than objects, so that
the next step can pass in a config object which abstracts away parts
of the WASM environment, to facilitate plugging it in to arbitrary
WASM toolchains. The bootstrapping function gets removed from the
global scope in a later stage of the bootstrapping process.
- **`../common/whwasmutil.js`**\
- **`../common/whwasmutil.js`**
A semi-third-party collection of JS/WASM utility code intended to
replace much of the Emscripten glue. The sqlite3 APIs internally use
these APIs instead of their Emscripten counterparts, in order to be
@@ -77,79 +77,78 @@ by concatenating the following files together in their listed order:
toolchains. It is "semi-third-party" in that it was created in order
to support this tree but is standalone and maintained together
with...
- **`../jaccwabyt/jaccwabyt.js`**\
- **`../jaccwabyt/jaccwabyt.js`**
Another semi-third-party API which creates bindings between JS
and C structs, such that changes to the struct state from either JS
or C are visible to the other end of the connection. This is also an
independent spinoff project, conceived for the sqlite3 project but
maintained separately.
- **`sqlite3-api-glue.js`**\
- **`sqlite3-api-glue.js`**
Invokes functionality exposed by the previous two files to flesh out
low-level parts of `sqlite3-api-prologue.js`. Most of these pieces
involve populating the `sqlite3.capi.wasm` object and creating
`sqlite3.capi.sqlite3_...()` bindings. This file also deletes most
global-scope symbols the above files create, effectively moving them
into the scope being used for initializing the API.
- **`<build>/sqlite3-api-build-version.js`**\
- **`<build>/sqlite3-api-build-version.js`**
Gets created by the build process and populates the
`sqlite3.version` object. This part is not critical, but records the
version of the library against which this module was built.
- **`sqlite3-api-oo1.js`**\
- **`sqlite3-api-oo1.js`**
Provides a high-level object-oriented wrapper to the lower-level C
API, colloquially known as OO API #1. Its API is similar to other
high-level sqlite3 JS wrappers and should feel relatively familiar
to anyone familiar with such APIs. It is not a "required component"
and can be elided from builds which do not want it.
- **`sqlite3-api-worker1.js`**\
- **`sqlite3-api-worker1.js`**
A Worker-thread-based API which uses OO API #1 to provide an
interface to a database which can be driven from the main Window
thread via the Worker message-passing interface. Like OO API #1,
this is an optional component, offering one of any number of
potential implementations for such an API.
- **`sqlite3-worker1.js`**\
- **`sqlite3-worker1.js`**
Is not part of the amalgamated sources and is intended to be
loaded by a client Worker thread. It loads the sqlite3 module
and runs the Worker #1 API which is implemented in
`sqlite3-api-worker1.js`.
- **`sqlite3-worker1-promiser.js`**\
- **`sqlite3-worker1-promiser.js`**
Is likewise not part of the amalgamated sources and provides
a Promise-based interface into the Worker #1 API. This is
a far user-friendlier way to interface with databases running
in a Worker thread.
- **`sqlite3-vfs-helper.js`**\
- **`sqlite3-vfs-helper.js`**
Installs the `sqlite3.vfs` namespace, which contain helpers for use
by downstream code which creates `sqlite3_vfs` implementations.
- **`sqlite3-vtab-helper.js`**\
- **`sqlite3-vtab-helper.js`**
Installs the `sqlite3.vtab` namespace, which contain helpers for use
by downstream code which creates `sqlite3_module` implementations.
- **`sqlite3-vfs-opfs.c-pp.js`**\
- **`sqlite3-vfs-opfs.c-pp.js`**
is an sqlite3 VFS implementation which supports the [Origin-Private
FileSystem (OPFS)][OPFS] as a storage layer to provide persistent
storage for database files in a browser. It requires...
- **`sqlite3-opfs-async-proxy.js`**\
- **`sqlite3-opfs-async-proxy.js`**
is the asynchronous backend part of the [OPFS][] proxy. It
speaks directly to the (async) OPFS API and channels those
results back to its synchronous counterpart. This file, because
it must be started in its own Worker, is not part of the
amalgamation.
- **`sqlite3-vfs-opfs-sahpool.c-pp.js`**\
- **`sqlite3-vfs-opfs-sahpool.c-pp.js`**
is another sqlite3 VFS supporting the [OPFS][], but uses a
completely different approach than the above-listed one.
- **`sqlite3-api-cleanup.js`**\
The previous files do not immediately extend the library. Instead
they add callback functions to be called during its
bootstrapping. Some also temporarily create global objects in order
to communicate their state to the files which follow them. This file
cleans up any dangling globals and runs the API bootstrapping
process, which is what finally executes the initialization code
installed by the previous files. As of this writing, this code
ensures that the previous files leave no more than a single global
symbol installed - `sqlite3InitModule()`. When adapting the API for
non-Emscripten toolchains, this "should" be the only file, of those
in this list, where changes are needed. The Emscripten-specific
pieces described below may also require counterparts in any as-yet
hypothetical alternative build.
The previous files do not immediately extend the library. Instead they
install a global function `sqlite3ApiBootstrap()`, which downstream
code must call to configure the library for the current JS/WASM
environment. Each file listed above pushes a callback into the
bootstrapping queue, to be called as part of `sqlite3ApiBootstrap()`.
Some files also temporarily create global objects in order to
communicate their state to the files which follow them. Those
get cleaned up vi `post-js-footer.js`, described below.
Adapting the build for non-Emscripten toolchains essentially requires packaging
the above files, concatated together, into that toolchain's "JS glue"
and, in the final stage of that glue, call `sqlite3ApiBootstrap()` and
return its result to the end user.
**Files with the extension `.c-pp.js`** are intended [to be processed
with `c-pp`](#c-pp), noting that such preprocessing may be applied
@@ -171,23 +170,27 @@ from this file rather than `sqlite3.c`.
The following Emscripten-specific files are injected into the
build-generated `sqlite3.js` along with `sqlite3-api.js`.
- **`extern-pre-js.js`**\
- **`extern-pre-js.js`**
Emscripten-specific header for Emscripten's `--extern-pre-js`
flag. As of this writing, that file is only used for experimentation
purposes and holds no code relevant to the production deliverables.
- **`pre-js.c-pp.js`**\
- **`pre-js.c-pp.js`**
Emscripten-specific header for Emscripten's `--pre-js` flag. This
file overrides certain Emscripten behavior before Emscripten does
most of its work.
- **`post-js-header.js`**\
- **`post-js-header.js`**
Emscripten-specific header for the `--post-js` input. It opens up,
but does not close, a function used for initializing the library.
- (**`sqlite3-api.js`** gets sandwiched between these &uarr; two
&darr; files.)
- **`post-js-footer.js`**\
- **`sqlite3-api.js`** gets sandwiched between these &uarr; two
&darr; files.
- **`post-js-footer.js`**
Emscripten-specific footer for the `--post-js` input. This closes
off the function opened by `post-js-header.js`.
- **`extern-post-js.c-pp.js`**\
off the function opened by `post-js-header.js`. This file cleans up
any dangling globals and runs `sqlite3ApiBootstrap()`. As of this
writing, this code ensures that the previous files leave no more
than a single global symbol installed - `sqlite3InitModule()`.
- **`extern-post-js.c-pp.js`**
Emscripten-specific header for Emscripten's `--extern-post-js`
flag. This file is run in the global scope. It overwrites the
Emscripten-installed `sqlite3InitModule()` function with one which

View File

@@ -1,3 +1,71 @@
/*
2022-07-22
The author disclaims copyright to this source code. In place of a
legal notice, here is a blessing:
* May you do good and not evil.
* May you find forgiveness for yourself and forgive others.
* May you share freely, never taking more than you give.
***********************************************************************
This file is the tail end of the sqlite3-api.js constellation,
intended to be appended after all other sqlite3-api-*.js files so
that it can finalize any setup and clean up any global symbols
temporarily used for setting up the API's various subsystems.
In terms of amalgamation code placement, this file is appended
immediately after the final sqlite3-api-*.js piece. Those files
cooperate to prepare sqlite3ApiBootstrap() and this file calls it.
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 state set up by
pre-js.c-pp.js and friends.
*/
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 */)
}
);
sqlite3InitScriptInfo.debugModule("Bootstrapping lib config", bootstrapConfig);
/**
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 /* the eventual result of globalThis.sqlite3InitModule() */;
}catch(e){
console.error("sqlite3ApiBootstrap() error:",e);
throw e;
}
//console.warn("This is the end of the Module.runSQLite3PostLoadInit handler.");
}/*Module.runSQLite3PostLoadInit(...)*/;
//console.warn("This is the end of the setup of the (pending) Module.runSQLite3PostLoadInit");

View File

@@ -9,7 +9,7 @@
Running this function will bootstrap the library and return
a Promise to the sqlite3 namespace object.
*/
Module.runSQLite3PostLoadInit = function(
Module.runSQLite3PostLoadInit = async function(
sqlite3InitScriptInfo /* populated by extern-post-js.c-pp.js */,
EmscriptenModule/*the Emscripten-style module object*/,
sqlite3IsUnderTest
@@ -35,7 +35,6 @@ Module.runSQLite3PostLoadInit = function(
- sqlite3-vtab-helper.c-pp.js => Utilities for virtual table impls
- sqlite3-vfs-opfs.c-pp.js => OPFS VFS
- sqlite3-vfs-opfs-sahpool.c-pp.js => OPFS SAHPool VFS
- sqlite3-api-cleanup.js => final bootstrapping phase
- post-js-footer.js => this file's epilogue
And all of that gets sandwiched between extern-pre-js.js and

View File

@@ -35,8 +35,12 @@
const sIMS =
globalThis.sqlite3InitModuleState/*from extern-post-js.c-pp.js*/
|| Object.assign(Object.create(null),{
debugModule: ()=>{
console.warn("globalThis.sqlite3InitModuleState is missing");
/* In WASMFS builds this file gets loaded once per thread,
but sqlite3InitModuleState is not getting set for the
worker threads? That those workers seem to function fine
despite that is curious. */
debugModule: function(){
console.warn("globalThis.sqlite3InitModuleState is missing",arguments);
}
});
delete globalThis.sqlite3InitModuleState;
@@ -89,8 +93,7 @@
//#endif target:es6-module
}.bind(sIMS);
//#if Module.instantiateWasm
//#if not wasmfs
//#if Module.instantiateWasm and not wasmfs
/**
Override Module.instantiateWasm().
@@ -126,7 +129,6 @@
.then(finalThen)
return loadWasm();
}.bind(sIMS);
//#endif not wasmfs
//#endif Module.instantiateWasm
//#endif Module.instantiateWasm and not wasmfs
})(Module);
/* END FILE: api/pre-js.js. */

View File

@@ -1,75 +0,0 @@
/*
2022-07-22
The author disclaims copyright to this source code. In place of a
legal notice, here is a blessing:
* May you do good and not evil.
* May you find forgiveness for yourself and forgive others.
* May you share freely, never taking more than you give.
***********************************************************************
This file is the tail end of the sqlite3-api.js constellation,
intended to be appended after all other sqlite3-api-*.js files so
that it can finalize any setup and clean up any global symbols
temporarily used for setting up the API's various subsystems.
In Emscripten builds it's run in the context of what amounts to a
Module.postRun handler, though it's no longer actually a postRun
handler because Emscripten 4.0 changed postRun semantics in an
incompatible way.
In terms of amalgamation code placement, this file is appended
immediately after the final sqlite3-api-*.js piece. Those files
cooperate to prepare sqlite3ApiBootstrap() and this file calls it.
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 state set up by
pre-js.c-pp.js and friends.
*/
'use strict';
if( 'undefined' !== typeof EmscriptenModule/*from post-js-header.js*/ ){
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 */)
}
);
sqlite3InitScriptInfo.debugModule("Bootstrapping lib config", bootstrapConfig);
/**
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 /* the eventual result of globalThis.sqlite3InitModule() */;
}catch(e){
console.error("sqlite3ApiBootstrap() error:",e);
throw e;
}
}/*Emscripten post-load lib init*/

View File

@@ -2130,6 +2130,19 @@ globalThis.sqlite3ApiBootstrap = async function sqlite3ApiBootstrap(
sqlite3InitScriptInfo /* from post-js-header.js */;
if( (sqlite3.__isUnderTest = sqlite3IsUnderTest /* from post-js-header.js */) ){
sqlite3.config.emscripten = EmscriptenModule;
/*
The problem with exposing these pieces (in non-testing runs) via
sqlite3.wasm is that it exposes non-SQLite pieces to the
clients, who may come to expect it to remain. _We_ only have
these data because we've overridden Emscripten's wasm file
loader, and if we lose that capability for some reason then
we'll lose access to this metadata.
These data are interesting for exploring how the wasm/JS
pieces connect, e.g. for exploring exactly what Emscripten
imports into WASM from its JS glue, but it's not
SQLite-related.
*/
const iw = sqlite3InitScriptInfo.instantiateWasm;
if( iw ){
/* Metadata injected by the custom Module.instantiateWasm()

View File

@@ -16,7 +16,7 @@
asynchronous Origin-Private FileSystem (OPFS) APIs using a second
Worker, implemented in sqlite3-opfs-async-proxy.js. This file is
intended to be appended to the main sqlite3 JS deliverable somewhere
after sqlite3-api-oo1.js and before sqlite3-api-cleanup.js.
after sqlite3-api-oo1.js.
*/
'use strict';
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){