aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/api/sqlite3-api-prologue.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/wasm/api/sqlite3-api-prologue.js')
-rw-r--r--ext/wasm/api/sqlite3-api-prologue.js78
1 files changed, 59 insertions, 19 deletions
diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js
index b2d880937..30e626b67 100644
--- a/ext/wasm/api/sqlite3-api-prologue.js
+++ b/ext/wasm/api/sqlite3-api-prologue.js
@@ -698,8 +698,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
["sqlite3_wasm_vfs_unlink", "int", "string"]
];
- /** State for sqlite3_web_persistent_dir(). */
- let __persistentDir;
+ /** State for sqlite3_wasmfs_opfs_dir(). */
+ let __persistentDir = undefined;
/**
An experiment. Do not use in client code.
@@ -713,8 +713,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
This function currently only recognizes the WASMFS/OPFS storage
combination. "Plain" OPFS is provided via a separate VFS which
- can optionally be installed (if OPFS is available on the system)
- using sqlite3.installOpfsVfs().
+ is optionally be installed via sqlite3.asyncPostInit().
TODOs and caveats:
@@ -724,7 +723,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
happen when using the JS-native "opfs" VFS, as opposed to the
WASMFS/OPFS combination.
*/
- capi.sqlite3_web_persistent_dir = function(){
+ capi.sqlite3_wasmfs_opfs_dir = function(){
if(undefined !== __persistentDir) return __persistentDir;
// If we have no OPFS, there is no persistent dir
const pdir = config.wasmfsOpfsDir;
@@ -738,17 +737,6 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
if(pdir && 0===capi.wasm.xCallWrapped(
'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir
)){
- /** OPFS does not support locking and will trigger errors if
- we try to lock. We don't _really_ want to
- _unconditionally_ install a non-locking sqlite3 VFS as the
- default, but we do so here for simplicy's sake for the
- time being. That said: locking is a no-op on all of the
- current WASM storage, so this isn't (currently) as bad as
- it may initially seem. */
- const pVfs = sqlite3.capi.sqlite3_vfs_find("unix-none");
- if(pVfs){
- capi.sqlite3_vfs_register(pVfs,1);
- }
return __persistentDir = pdir;
}else{
return __persistentDir = "";
@@ -762,7 +750,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
/**
Experimental and subject to change or removal.
- Returns true if sqlite3.capi.sqlite3_web_persistent_dir() is a
+ Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a
non-empty string and the given name starts with (that string +
'/'), else returns false.
@@ -771,7 +759,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
kvvfs is available.
*/
capi.sqlite3_web_filename_is_persistent = function(name){
- const p = capi.sqlite3_web_persistent_dir();
+ const p = capi.sqlite3_wasmfs_opfs_dir();
return (p && name) ? name.startsWith(p+'/') : false;
};
@@ -922,11 +910,42 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
}/* main-window-only bits */
+
/* The remainder of the API will be set up in later steps. */
const sqlite3 = {
WasmAllocError: WasmAllocError,
capi,
- config
+ config,
+ /**
+ Performs any optional asynchronous library-level initialization
+ which might be required. This function returns a Promise which
+ resolves to the sqlite3 namespace object. It _ignores any
+ errors_ in the asynchronous init process, as such components
+ are all optional. If called more than once, the second and
+ subsequent calls are no-ops which return a pre-resolved
+ Promise.
+
+ If called at all, this function must be called by client-level
+ code, which must not use the library until the returned promise
+ resolves.
+
+ Bug: if called while a prior call is still resolving, the 2nd
+ call will resolve prematurely, before the 1st call has finished
+ resolving.
+ */
+ asyncPostInit: async function(){
+ let lip = sqlite3ApiBootstrap.initializersAsync;
+ delete sqlite3ApiBootstrap.initializersAsync;
+ if(!lip || !lip.length) return Promise.resolve(sqlite3);
+ // Is it okay to resolve these in parallel or do we need them
+ // to resolve in order? We currently only have 1, so it
+ // makes no difference.
+ lip = lip.map((f)=>f(sqlite3).catch(()=>{}));
+ //let p = lip.shift();
+ //while(lip.length) p = p.then(lip.shift());
+ //return p.then(()=>sqlite3);
+ return Promise.all(lip).then(()=>sqlite3);
+ }
};
sqlite3ApiBootstrap.initializers.forEach((f)=>f(sqlite3));
delete sqlite3ApiBootstrap.initializers;
@@ -946,9 +965,30 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
their features (noting that most will also require that certain
features alread have been installed). At the end of that process,
this array is deleted.
+
+ Note that the order of insertion into this array is significant for
+ some pieces. e.g. sqlite3.capi.wasm cannot be fully utilized until
+ the whwasmutil.js part is plugged in.
*/
self.sqlite3ApiBootstrap.initializers = [];
/**
+ self.sqlite3ApiBootstrap.initializersAsync is an internal detail
+ used by the sqlite3 API's amalgamation process. It must not be
+ modified by client code except when plugging such code into the
+ amalgamation process.
+
+ Counterpart of self.sqlite3ApiBootstrap.initializers, specifically
+ for initializers which are asynchronous. All functions in this list
+ take the sqlite3 object as their argument and MUST return a
+ Promise. Both the resolved value and rejection cases are ignored.
+
+ This list is not processed until the client calls
+ sqlite3.asyncPostInit(). This means, for example, that intializers
+ added to self.sqlite3ApiBootstrap.initializers may push entries to
+ this list.
+*/
+self.sqlite3ApiBootstrap.initializersAsync = [];
+/**
Client code may assign sqlite3ApiBootstrap.defaultConfig an
object-type value before calling sqlite3ApiBootstrap() (without
arguments) in order to tell that call to use this object as its