+//#ifnot omit-oo1
/*
2022-08-24
- `onready` (optional, but...): this callback is called with no
arguments when the worker fires its initial
'sqlite3-api'/'worker1-ready' message, which it does when
- sqlite3.initWorker1API() completes its initialization. This is
- the simplest way to tell the worker to kick off work at the
- earliest opportunity.
+ sqlite3.initWorker1API() completes its initialization. This is the
+ simplest way to tell the worker to kick off work at the earliest
+ opportunity, and the only way to know when the worker module has
+ completed loading. The irony of using a callback for this, instead
+ of returning a promise from sqlite3Worker1Promiser() is not lost on
+ the developers: see sqlite3Worker1Promiser.v2() which uses a
+ Promise instead.
- `onunhandled` (optional): a callback which gets passed the
message event object for any worker.onmessage() events which
by all client code except that which tests this API. The `row`
property contains the row result in the form implied by the
`rowMode` option (defaulting to `'array'`). The `rowNumber` is a
- 1-based integer value incremented by 1 on each call into th
+ 1-based integer value incremented by 1 on each call into the
callback.
At the end of the result set, the same event is fired with
the end of the result set has been reached. Note that the rows
arrive via worker-posted messages, with all the implications
of that.
+
+ Notable shortcomings:
+
+ - This API was not designed with ES6 modules in mind. Neither Firefox
+ nor Safari support, as of March 2023, the {type:"module"} flag to the
+ Worker constructor, so that particular usage is not something we're going
+ to target for the time being:
+
+ https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker
*/
-self.sqlite3Worker1Promiser = function callee(config = callee.defaultConfig){
+globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfig){
// Inspired by: https://stackoverflow.com/a/52439530
if(1===arguments.length && 'function'===typeof arguments[0]){
const f = config;
if(!config.worker) config.worker = callee.defaultConfig.worker;
if('function'===typeof config.worker) config.worker = config.worker();
let dbId;
+ let promiserFunc;
config.worker.onmessage = function(ev){
ev = ev.data;
debug('worker1.onmessage',ev);
if(!msgHandler){
if(ev && 'sqlite3-api'===ev.type && 'worker1-ready'===ev.result) {
/*fired one time when the Worker1 API initializes*/
- if(config.onready) config.onready();
+ if(config.onready) config.onready(promiserFunc);
return;
}
msgHandler = handlerMap[ev.type] /* check for exec per-row callback */;
if(msgHandler && msgHandler.onrow){
msgHandler.onrow(ev);
return;
- }
+ }
if(config.onunhandled) config.onunhandled(arguments[0]);
else err("sqlite3Worker1Promiser() unhandled worker message:",ev);
return;
try {msgHandler.resolve(ev)}
catch(e){msgHandler.reject(e)}
}/*worker.onmessage()*/;
- return function(/*(msgType, msgArgs) || (msgEnvelope)*/){
+ return promiserFunc = function(/*(msgType, msgArgs) || (msgEnvelope)*/){
let msg;
if(1===arguments.length){
msg = arguments[0];
}else if(2===arguments.length){
- msg = {
- type: arguments[0],
- args: arguments[1]
- };
+ msg = Object.create(null);
+ msg.type = arguments[0];
+ msg.args = arguments[1];
+ msg.dbId = msg.args.dbId;
}else{
- toss("Invalid arugments for sqlite3Worker1Promiser()-created factory.");
+ toss("Invalid arguments for sqlite3Worker1Promiser()-created factory.");
}
- if(!msg.dbId) msg.dbId = dbId;
+ if(!msg.dbId && msg.type!=='open') msg.dbId = dbId;
msg.messageId = genMsgId(msg);
msg.departureTime = performance.now();
const proxy = Object.create(null);
return p;
};
}/*sqlite3Worker1Promiser()*/;
-self.sqlite3Worker1Promiser.defaultConfig = {
+
+globalThis.sqlite3Worker1Promiser.defaultConfig = {
worker: function(){
-//#if target=es6-bundler-friendly
- return new Worker("sqlite3-worker1.js");
+//#if target=es6-module
+ return new Worker(new URL("sqlite3-worker1-bundler-friendly.mjs", import.meta.url),{
+ type: 'module'
+ });
//#else
let theJs = "sqlite3-worker1.js";
if(this.currentScript){
src.pop();
theJs = src.join('/')+'/' + theJs;
//sqlite3.config.warn("promiser currentScript, theJs =",this.currentScript,theJs);
- }else{
- //sqlite3.config.warn("promiser self.location =",self.location);
- const urlParams = new URL(self.location.href).searchParams;
+ }else if(globalThis.location){
+ //sqlite3.config.warn("promiser globalThis.location =",globalThis.location);
+ const urlParams = new URL(globalThis.location.href).searchParams;
if(urlParams.has('sqlite3.dir')){
theJs = urlParams.get('sqlite3.dir') + '/' + theJs;
}
}
- return new Worker(theJs + self.location.search);
+ return new Worker(theJs + globalThis.location.search);
+//#endif
+ }
+//#ifnot target=es6-module
+ .bind({
+ currentScript: globalThis?.document?.currentScript
+ })
//#endif
- }.bind({
- currentScript: self?.document?.currentScript
- }),
+ ,
onerror: (...args)=>console.error('worker1 promiser error',...args)
-};
+}/*defaultConfig*/;
+
+/**
+ sqlite3Worker1Promiser.v2(), added in 3.46, works identically to
+ sqlite3Worker1Promiser() except that it returns a Promise instead
+ of relying an an onready callback in the config object. The Promise
+ resolves to the same factory function which
+ sqlite3Worker1Promiser() returns.
+
+ If config is-a function or is an object which contains an onready
+ function, that function is replaced by a proxy which will resolve
+ after calling the original function and will reject if that
+ function throws.
+*/
+sqlite3Worker1Promiser.v2 = function(config){
+ let oldFunc;
+ if( 'function' == typeof config ){
+ oldFunc = config;
+ config = {};
+ }else if('function'===typeof config?.onready){
+ oldFunc = config.onready;
+ delete config.onready;
+ }
+ const promiseProxy = Object.create(null);
+ config = Object.assign((config || Object.create(null)),{
+ onready: async function(func){
+ try {
+ if( oldFunc ) await oldFunc(func);
+ promiseProxy.resolve(func);
+ }
+ catch(e){promiseProxy.reject(e)}
+ }
+ });
+ const p = new Promise(function(resolve,reject){
+ promiseProxy.resolve = resolve;
+ promiseProxy.reject = reject;
+ });
+ try{
+ this.original(config);
+ }catch(e){
+ promiseProxy.reject(e);
+ }
+ return p;
+}.bind({
+ /* We do this because clients are
+ recommended to delete globalThis.sqlite3Worker1Promiser. */
+ original: sqlite3Worker1Promiser
+});
+
+//#if target=es6-module
+/**
+ When built as a module, we export sqlite3Worker1Promiser.v2()
+ instead of sqlite3Worker1Promise() because (A) its interface is more
+ conventional for ESM usage and (B) the ESM option export option for
+ this API did not exist until v2 was created, so there's no backwards
+ incompatibility.
+*/
+export default sqlite3Worker1Promiser.v2;
+//#endif /* target=es6-module */
+//#else
+/* Built with the omit-oo1 flag. */
+//#endif ifnot omit-oo1
-C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\sbegin-concurrent\sbranch.
-D 2024-11-18T15:18:45.241
+C Attempt\sto\sreduce\sdivergence\sfrom\strunk.
+D 2024-11-18T16:44:45.315
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 9b86ca2d8276cf919fbc9ba2a10e9786033b64f92c2db844d951804dee6c4b4e
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js e809739d71e8b35dfe1b55d24d91f02d04239e6aef7ca1ea92a15a29e704f616
F ext/wasm/api/sqlite3-wasm.c 83f5e9f998e9fa4261eb84e9f092210e3ffe03895119f5ded0429eb34ab9d2be
-F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js c5ac33e39f21a3481812d7333ca6e18853640d423a01960ca8dbc6e7c5c3c21c
+F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 46f303ba8ddd1b2f0a391798837beddfa72e8c897038c8047eda49ce7d5ed46b
F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5
F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7
F ext/wasm/batch-runner-sahpool.js 54a3ac228e6c4703fe72fb65c897e19156263a51fe9b7e21d2834a45e876aabd
F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9
-F tool/tclConfigShToAutoDef.sh 44ec55046d86a3febb2cb3e099399b41794e80e9cd138eee7b9b016f819e882b x tool/tclConfigShToTcl.sh
+F tool/tclConfigShToAutoDef.sh 44ec55046d86a3febb2cb3e099399b41794e80e9cd138eee7b9b016f819e882b x
F tool/tclConfigShToMake.sh 7c065d81c2d178e15e45a77372c6e5a38b5a1b08755301cd6f20a3a862db7312 x
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
F tool/vdbe-compress.tcl fa2f37ab39b2a0087fafb6a7f3ce19503e25e624ffa8ed9951717ab72920c088
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 0812161025272851af6233f183a6abdee5c583decc688c4763965b50e7ab1b9d e1330ecf170436678c5c235557fb95b8acbf4fad62583edba4af03aff49afbc5
-R 9a4e43379d9c2fcaaa307e099edd9167
+P 680a2eaabb2a2fa5d52e89c99a37637aba2734ab782f63bd8cc1fb9802c3d9e0
+R 915c205e7d3ee7a75d7840f0cc912bd8
U drh
-Z 5ad00ac21e27e2085f1e605551ac79a6
+Z ca371cf98e0e7f7c0063c8e9abafbf19
# Remove this line to create a well-formed Fossil manifest.