1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Resolve duplicate loading of promiser v2 demo code (a side effect of having done precisely what it was told to do). Consolidate demo-worker1-promiser(-esm).html/(m)js variants into central copies processed with c-pp.

FossilOrigin-Name: 9347d9b9a69277e40ea2f3ec6e1ff37ea19d24b4af80c6230b10624173f2f17c
This commit is contained in:
stephan
2024-03-07 18:53:27 +00:00
parent ffa0fa69b6
commit 84016759dd
8 changed files with 62 additions and 344 deletions

View File

@ -954,11 +954,22 @@ $(eval $(call C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),$(sqlite3-worker1-pr
-Dtarget=es6-module -Dtarget=es6-bundler-friendly))
$(sqlite3-bundler-friendly.mjs): $(sqlite3-worker1-bundler-friendly.mjs) \
$(sqlite3-worker1-promiser-bundler-friendly.js)
$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.js,demo-worker1-promiser.js))
$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.js,demo-worker1-promiser.mjs,\
-Dtarget=es6-module))
$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.html,demo-worker1-promiser.html))
$(eval $(call C-PP.FILTER,demo-worker1-promiser.c-pp.html,demo-worker1-promiser-esm.html,\
-Dtarget=es6-module))
all: $(sqlite3-worker1.js) \
$(sqlite3-worker1-promiser.js) $(sqlite3-worker1-promiser.mjs)
demo-worker1-promiser.html: $(sqlite3-worker1-promiser.js) demo-worker1-promiser.js
demo-worker1-promiser-esm.html: $(sqlite3-worker1-promiser.mjs) demo-worker1-promiser.mjs
all: demo-worker1-promiser.html demo-worker1-promiser-esm.html
sqlite3-api.ext.jses += \
$(sqlite3-worker1-promiser.mjs) \
$(sqlite3-worker1-bundler-friendly.mjs) \
$(sqlite3-worker1.js)
all quick: $(sqlite3-api.ext.jses)
q: quick

View File

@ -320,12 +320,16 @@ sqlite3Worker1Promiser.v2 = function(config){
promiseProxy.reject = reject;
});
try{
sqlite3Worker1Promiser(config);
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
/**

View File

@ -1,311 +0,0 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
<link rel="stylesheet" href="common/emscripten.css"/>
<link rel="stylesheet" href="common/testing.css"/>
<title>worker-promise (via ESM) tests</title>
</head>
<body>
<header id='titlebar'><span>worker-promise (via ESM) tests</span></header>
<!-- emscripten bits -->
<figure id="module-spinner">
<div class="spinner"></div>
<div class='center'><strong>Initializing app...</strong></div>
<div class='center'>
On a slow internet connection this may take a moment. If this
message displays for "a long time", intialization may have
failed and the JavaScript console may contain clues as to why.
</div>
</figure>
<div class="emscripten" id="module-status">Downloading...</div>
<div class="emscripten">
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
</div><!-- /emscripten bits -->
<div>Most stuff on this page happens in the dev console.</div>
<hr>
<div id='test-output'></div>
<script src="common/SqliteTestUtil.js"></script>
<!--script src="demo-worker1-promiser.mjs"></script-->
<script type="module">
const T = globalThis.SqliteTestUtil;
import {default as promiserFactory} from "./jswasm/sqlite3-worker1-promiser.mjs";
console.log("promiserFactory =",promiserFactory);
const promiserConfig = {
debug: 1 ? undefined : (...args)=>console.debug('worker debug',...args),
onunhandled: function(ev){
error("Unhandled worker message:",ev.data);
},
onerror: function(ev){
error("worker1 error:",ev);
},
/**
The v1 interfaces uses an onready function. The v2 interface optionally
accepts one but does not require it. If provided, it is called _before_
the promise is resolved, and the promise is rejected if onready() throws.
*/
onready: function(f){
/* f === the function returned by promiserFactory().
Ostensibly (f === workerPromise) but this function is
called before the promiserFactory() Promise resolves, so
before workerPromise is set. */
console.warn("This is the v2 interface - you don't need an onready() function.");
}
};
const workerPromise = await promiserFactory(promiserConfig)
.then((func)=>{
console.log("Init complete. Starting tests momentarily.");
globalThis.sqlite3TestModule.setStatus(null)/*hide the HTML-side is-loading spinner*/;
return func;
});
// Just to demonstrate rejection via onready() throwing:
promiserFactory( function(f){
throw new Error("Testing onready throw..");
})
.catch(e=>{ console.log("caught expected promise rejection:",e); });
(async function(){
const eOutput = document.querySelector('#test-output');
const warn = console.warn.bind(console);
const error = console.error.bind(console);
const log = console.log.bind(console);
const logHtml = async function(cssClass,...args){
log.apply(this, args);
const ln = document.createElement('div');
if(cssClass) ln.classList.add(cssClass);
ln.append(document.createTextNode(args.join(' ')));
eOutput.append(ln);
};
let startTime;
const testCount = async ()=>{
logHtml("","Total test count:",T.counter+". Total time =",(performance.now() - startTime),"ms");
};
//why is this triggered even when we catch() a Promise?
//window.addEventListener('unhandledrejection', function(event) {
// warn('unhandledrejection',event);
//});
const wtest = async function(msgType, msgArgs, callback){
if(2===arguments.length && 'function'===typeof msgArgs){
callback = msgArgs;
msgArgs = undefined;
}
const p = 1
? workerPromise({type: msgType, args:msgArgs})
: workerPromise(msgType, msgArgs);
return callback ? p.then(callback).finally(testCount) : p;
};
let sqConfig;
const runTests = async function(){
const dbFilename = '/testing2.sqlite3';
startTime = performance.now();
await wtest('config-get', (ev)=>{
const r = ev.result;
log('sqlite3.config subset:', r);
T.assert('boolean' === typeof r.bigIntEnabled);
sqConfig = r;
});
logHtml('',
"Sending 'open' message and waiting for its response before continuing...");
await wtest('open', {
filename: dbFilename,
simulateError: 0 /* if true, fail the 'open' */,
}, function(ev){
const r = ev.result;
log("then open result",r);
T.assert(ev.dbId === r.dbId)
.assert(ev.messageId)
.assert('string' === typeof r.vfs);
promiserConfig.dbId = ev.dbId;
}).then(runTests2);
};
const runTests2 = async function(){
const mustNotReach = ()=>toss("This is not supposed to be reached.");
await wtest('exec',{
sql: ["create table t(a,b)",
"insert into t(a,b) values(1,2),(3,4),(5,6)"
].join(';'),
resultRows: [], columnNames: [],
countChanges: sqConfig.bigIntEnabled ? 64 : true
}, function(ev){
ev = ev.result;
T.assert(0===ev.resultRows.length)
.assert(0===ev.columnNames.length)
.assert(sqConfig.bigIntEnabled
? (3n===ev.changeCount)
: (3===ev.changeCount));
});
await wtest('exec',{
sql: 'select a a, b b from t order by a',
resultRows: [], columnNames: [],
}, function(ev){
ev = ev.result;
T.assert(3===ev.resultRows.length)
.assert(1===ev.resultRows[0][0])
.assert(6===ev.resultRows[2][1])
.assert(2===ev.columnNames.length)
.assert('b'===ev.columnNames[1]);
});
await wtest('exec',{
sql: 'select a a, b b from t order by a',
resultRows: [], columnNames: [],
rowMode: 'object',
countChanges: true
}, function(ev){
ev = ev.result;
T.assert(3===ev.resultRows.length)
.assert(1===ev.resultRows[0].a)
.assert(6===ev.resultRows[2].b)
.assert(0===ev.changeCount);
});
await wtest(
'exec',
{sql:'intentional_error'},
mustNotReach
).catch((e)=>{
warn("Intentional error:",e);
});
await wtest('exec',{
sql:'select 1 union all select 3',
resultRows: []
}, function(ev){
ev = ev.result;
T.assert(2 === ev.resultRows.length)
.assert(1 === ev.resultRows[0][0])
.assert(3 === ev.resultRows[1][0])
.assert(undefined === ev.changeCount);
});
const resultRowTest1 = function f(ev){
if(undefined === f.counter) f.counter = 0;
if(null === ev.rowNumber){
/* End of result set. */
T.assert(undefined === ev.row)
.assert(2===ev.columnNames.length)
.assert('a'===ev.columnNames[0])
.assert('B'===ev.columnNames[1]);
}else{
T.assert(ev.rowNumber > 0);
++f.counter;
}
log("exec() result row:",ev);
T.assert(null === ev.rowNumber || 'number' === typeof ev.row.B);
};
await wtest('exec',{
sql: 'select a a, b B from t order by a limit 3',
callback: resultRowTest1,
rowMode: 'object'
}, function(ev){
T.assert(3===resultRowTest1.counter);
resultRowTest1.counter = 0;
});
const resultRowTest2 = function f(ev){
if(null === ev.rowNumber){
/* End of result set. */
T.assert(undefined === ev.row)
.assert(1===ev.columnNames.length)
.assert('a'===ev.columnNames[0])
}else{
T.assert(ev.rowNumber > 0);
f.counter = ev.rowNumber;
}
log("exec() result row:",ev);
T.assert(null === ev.rowNumber || 'number' === typeof ev.row);
};
await wtest('exec',{
sql: 'select a a from t limit 3',
callback: resultRowTest2,
rowMode: 0
}, function(ev){
T.assert(3===resultRowTest2.counter);
});
const resultRowTest3 = function f(ev){
if(null === ev.rowNumber){
T.assert(3===ev.columnNames.length)
.assert('foo'===ev.columnNames[0])
.assert('bar'===ev.columnNames[1])
.assert('baz'===ev.columnNames[2]);
}else{
f.counter = ev.rowNumber;
T.assert('number' === typeof ev.row);
}
};
await wtest('exec',{
sql: "select 'foo' foo, a bar, 'baz' baz from t limit 2",
callback: resultRowTest3,
columnNames: [],
rowMode: '$bar'
}, function(ev){
log("exec() result row:",ev);
T.assert(2===resultRowTest3.counter);
});
await wtest('exec',{
sql:[
'pragma foreign_keys=0;',
// ^^^ arbitrary query with no result columns
'select a, b from t order by a desc; select a from t;'
// exec() only honors SELECT results from the first
// statement with result columns (regardless of whether
// it has any rows).
],
rowMode: 1,
resultRows: []
},function(ev){
const rows = ev.result.resultRows;
T.assert(3===rows.length).
assert(6===rows[0]);
});
await wtest('exec',{sql: 'delete from t where a>3'});
await wtest('exec',{
sql: 'select count(a) from t',
resultRows: []
},function(ev){
ev = ev.result;
T.assert(1===ev.resultRows.length)
.assert(2===ev.resultRows[0][0]);
});
await wtest('export', function(ev){
ev = ev.result;
T.assert('string' === typeof ev.filename)
.assert(ev.byteArray instanceof Uint8Array)
.assert(ev.byteArray.length > 1024)
.assert('application/x-sqlite3' === ev.mimetype);
});
/***** close() tests must come last. *****/
await wtest('close',{},function(ev){
T.assert('string' === typeof ev.result.filename);
});
await wtest('close', (ev)=>{
T.assert(undefined === ev.result.filename);
}).finally(()=>logHtml('',"That's all, folks!"));
}/*runTests2()*/;
runTests();
})();
</script>
</body>
</html>

View File

@ -6,7 +6,11 @@
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
<link rel="stylesheet" href="common/emscripten.css"/>
<link rel="stylesheet" href="common/testing.css"/>
//#if target=es6-module
<title>worker-promise (via ESM) tests</title>
//#else
<title>worker-promise tests</title>
//#endif
</head>
<body>
<header id='titlebar'><span>worker-promise tests</span></header>
@ -22,13 +26,17 @@
</figure>
<div class="emscripten" id="module-status">Downloading...</div>
<div class="emscripten">
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
</div><!-- /emscripten bits -->
<div>Most stuff on this page happens in the dev console.</div>
<hr>
<div id='test-output'></div>
<script src="common/SqliteTestUtil.js"></script>
//#if target=es6-module
<script src="demo-worker1-promiser.mjs" type="module"></script>
//#else
<script src="jswasm/sqlite3-worker1-promiser.js"></script>
<script src="demo-worker1-promiser.js"></script>
//#endif
</body>
</html>

View File

@ -13,7 +13,13 @@
Demonstration of the sqlite3 Worker API #1 Promiser: a Promise-based
proxy for for the sqlite3 Worker #1 API.
*/
'use strict';
//#if target=es6-module
import {default as promiserFactory} from "./jswasm/sqlite3-worker1-promiser.mjs";
//#else
"use strict";
const promiserFactory = globalThis.sqlite3Worker1Promiser.v2;
delete globalThis.sqlite3Worker1Promiser;
//#endif
(async function(){
const T = globalThis.SqliteTestUtil;
const eOutput = document.querySelector('#test-output');
@ -33,35 +39,35 @@
logHtml("","Total test count:",T.counter+". Total time =",(performance.now() - startTime),"ms");
};
//why is this triggered even when we catch() a Promise?
//window.addEventListener('unhandledrejection', function(event) {
// warn('unhandledrejection',event);
//});
const promiserConfig = {
worker: ()=>{
const w = new Worker("jswasm/sqlite3-worker1.js");
w.onerror = (event)=>error("worker.onerror",event);
return w;
//#ifnot target=es6-module
/**
The v1 interfaces uses an onready function. The v2 interface optionally
accepts one but does not require it. If provided, it is called _before_
the promise is resolved, and the promise is rejected if onready() throws.
*/
onready: function(f){
/* f === the function returned by promiserFactory().
Ostensibly (f === workerPromise) but this function is
called before the promiserFactory() Promise resolves, so
before workerPromise is set. */
console.warn("This is the v2 interface - you don't need an onready() function.");
},
//#endif
debug: 1 ? undefined : (...args)=>console.debug('worker debug',...args),
onunhandled: function(ev){
error("Unhandled worker message:",ev.data);
},
onerror: function(ev){
error("worker1 error:",ev);
},
onready: function(f){
warn("This is the v2 interface - don't pass an onready() function.");
}
};
const workerPromise = await globalThis.sqlite3Worker1Promiser.v2(promiserConfig)
const workerPromise = await promiserFactory(promiserConfig)
.then((func)=>{
log("Init complete. Starting tests momentarily.");
console.log("Init complete. Starting tests momentarily.");
globalThis.sqlite3TestModule.setStatus(null)/*hide the HTML-side is-loading spinner*/;
return func;
});
delete globalThis.sqlite3Worker1Promiser;
const wtest = async function(msgType, msgArgs, callback){
if(2===arguments.length && 'function'===typeof msgArgs){

View File

@ -50,8 +50,9 @@ dist.top.extras := \
demo-jsstorage.html demo-jsstorage.js \
demo-worker1.html demo-worker1.js \
demo-worker1-promiser.html demo-worker1-promiser.js \
demo-worker1-promiser-esm.html
dist.jswasm.extras := $(sqlite3-api.ext.jses) $(sqlite3.wasm)
demo-worker1-promiser-esm.html demo-worker1-promiser.mjs
dist.jswasm.extras := $(sqlite3.wasm) \
$(sqlite3-api.ext.jses)
dist.common.extras := \
$(wildcard $(dir.common)/*.css) \
$(dir.common)/SqliteTestUtil.js