_sqlite3_value_type
_sqlite3_vfs_find
_sqlite3_vfs_register
+_sqlite3_vfs_unregister
_malloc
_free
try{
const funcArgs = __xWrapFuncs({xStep, xFinal, xValue, xInverse, xDestroy},
uninstall);
- rc = sqlite3CreateFunction(pDb, funcName, nArg, eTextRep,
- pApp, ...funcArgs);
+ rc = sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep,
+ pApp, ...funcArgs);
}catch(e){
- console.error("sqlite3_create_function_v2() setup threw:",e);
+ console.error("sqlite3_create_window_function() setup threw:",e);
for(let v of uninstall){
wasm.uninstallFunction(v);
}
// Structs NOT to register
WasmTestStruct: true
});
+ if(!util.isUIThread()){
+ /* We remove the kvvfs VFS from Worker threads below. */
+ notThese.sqlite3_kvvfs_methods = true;
+ }
for(const s of wasm.ctype.structs){
if(!notThese[s.name]){
capi[s.name] = sqlite3.StructBinder(s);
}
}/*end C constant imports*/
- if( util.isMainWindow()
- && 0!==capi.sqlite3_vfs_find("kvvfs") ){/* kvvfs-specific glue */
- const kvvfsMethods = new capi.sqlite3_kvvfs_methods(
- wasm.exports.sqlite3_wasm_kvvfs_methods()
- );
- delete capi.sqlite3_kvvfs_methods;
-
- const kvvfsMakeKey = wasm.exports.sqlite3_wasm_kvvfsMakeKeyOnPstack,
- pstack = wasm.pstack,
- pAllocRaw = wasm.exports.sqlite3_wasm_pstack_alloc;
-
- const kvvfsStorage = (zClass)=>
- ((115/*=='s'*/===wasm.getMemValue(zClass))
- ? sessionStorage : localStorage);
-
- const kvvfsImpls = {
- xRead: (zClass, zKey, zBuf, nBuf)=>{
- const stack = pstack.pointer,
- astack = wasm.scopedAllocPush();
- try {
- const zXKey = kvvfsMakeKey(zClass,zKey);
- if(!zXKey) return -3/*OOM*/;
- const jKey = wasm.cstringToJs(zXKey);
- const jV = kvvfsStorage(zClass).getItem(jKey);
- if(!jV) return -1;
- const nV = jV.length /* Note that we are relying 100% on v being
- ASCII so that jV.length is equal to the
- C-string's byte length. */;
- if(nBuf<=0) return nV;
- else if(1===nBuf){
- wasm.setMemValue(zBuf, 0);
- return nV;
+ const pKvvfs = capi.sqlite3_vfs_find("kvvfs");
+ if( pKvvfs ){/* kvvfs-specific glue */
+ if(util.isUIThread()){
+ const kvvfsMethods = new capi.sqlite3_kvvfs_methods(
+ wasm.exports.sqlite3_wasm_kvvfs_methods()
+ );
+ delete capi.sqlite3_kvvfs_methods;
+
+ const kvvfsMakeKey = wasm.exports.sqlite3_wasm_kvvfsMakeKeyOnPstack,
+ pstack = wasm.pstack,
+ pAllocRaw = wasm.exports.sqlite3_wasm_pstack_alloc;
+
+ const kvvfsStorage = (zClass)=>
+ ((115/*=='s'*/===wasm.getMemValue(zClass))
+ ? sessionStorage : localStorage);
+
+ const kvvfsImpls = {
+ xRead: (zClass, zKey, zBuf, nBuf)=>{
+ const stack = pstack.pointer,
+ astack = wasm.scopedAllocPush();
+ try {
+ const zXKey = kvvfsMakeKey(zClass,zKey);
+ if(!zXKey) return -3/*OOM*/;
+ const jKey = wasm.cstringToJs(zXKey);
+ const jV = kvvfsStorage(zClass).getItem(jKey);
+ if(!jV) return -1;
+ const nV = jV.length /* Note that we are relying 100% on v being
+ ASCII so that jV.length is equal to the
+ C-string's byte length. */;
+ if(nBuf<=0) return nV;
+ else if(1===nBuf){
+ wasm.setMemValue(zBuf, 0);
+ return nV;
+ }
+ const zV = wasm.scopedAllocCString(jV);
+ if(nBuf > nV + 1) nBuf = nV + 1;
+ wasm.heap8u().copyWithin(zBuf, zV, zV + nBuf - 1);
+ wasm.setMemValue(zBuf + nBuf - 1, 0);
+ return nBuf - 1;
+ }catch(e){
+ console.error("kvstorageRead()",e);
+ return -2;
+ }finally{
+ pstack.restore(stack);
+ wasm.scopedAllocPop(astack);
+ }
+ },
+ xWrite: (zClass, zKey, zData)=>{
+ const stack = pstack.pointer;
+ try {
+ const zXKey = kvvfsMakeKey(zClass,zKey);
+ if(!zXKey) return 1/*OOM*/;
+ const jKey = wasm.cstringToJs(zXKey);
+ kvvfsStorage(zClass).setItem(jKey, wasm.cstringToJs(zData));
+ return 0;
+ }catch(e){
+ console.error("kvstorageWrite()",e);
+ return capi.SQLITE_IOERR;
+ }finally{
+ pstack.restore(stack);
+ }
+ },
+ xDelete: (zClass, zKey)=>{
+ const stack = pstack.pointer;
+ try {
+ const zXKey = kvvfsMakeKey(zClass,zKey);
+ if(!zXKey) return 1/*OOM*/;
+ kvvfsStorage(zClass).removeItem(wasm.cstringToJs(zXKey));
+ return 0;
+ }catch(e){
+ console.error("kvstorageDelete()",e);
+ return capi.SQLITE_IOERR;
+ }finally{
+ pstack.restore(stack);
}
- const zV = wasm.scopedAllocCString(jV);
- if(nBuf > nV + 1) nBuf = nV + 1;
- wasm.heap8u().copyWithin(zBuf, zV, zV + nBuf - 1);
- wasm.setMemValue(zBuf + nBuf - 1, 0);
- return nBuf - 1;
- }catch(e){
- console.error("kvstorageRead()",e);
- return -2;
- }finally{
- pstack.restore(stack);
- wasm.scopedAllocPop(astack);
- }
- },
- xWrite: (zClass, zKey, zData)=>{
- const stack = pstack.pointer;
- try {
- const zXKey = kvvfsMakeKey(zClass,zKey);
- if(!zXKey) return 1/*OOM*/;
- const jKey = wasm.cstringToJs(zXKey);
- kvvfsStorage(zClass).setItem(jKey, wasm.cstringToJs(zData));
- return 0;
- }catch(e){
- console.error("kvstorageWrite()",e);
- return capi.SQLITE_IOERR;
- }finally{
- pstack.restore(stack);
- }
- },
- xDelete: (zClass, zKey)=>{
- const stack = pstack.pointer;
- try {
- const zXKey = kvvfsMakeKey(zClass,zKey);
- if(!zXKey) return 1/*OOM*/;
- kvvfsStorage(zClass).removeItem(wasm.cstringToJs(zXKey));
- return 0;
- }catch(e){
- console.error("kvstorageDelete()",e);
- return capi.SQLITE_IOERR;
- }finally{
- pstack.restore(stack);
}
+ }/*kvvfsImpls*/;
+ for(let k of Object.keys(kvvfsImpls)){
+ kvvfsMethods[kvvfsMethods.memberKey(k)] =
+ wasm.installFunction(
+ kvvfsMethods.memberSignature(k),
+ kvvfsImpls[k]
+ );
}
- }/*kvvfsImpls*/;
- for(let k of Object.keys(kvvfsImpls)){
- kvvfsMethods[kvvfsMethods.memberKey(k)] =
- wasm.installFunction(
- kvvfsMethods.memberSignature(k),
- kvvfsImpls[k]
- );
+ }else{
+ /* Worker thread: unregister kvvfs to avoid it being used
+ for anything other than local/sessionStorage. It "can"
+ be used that way but it's not really intended to be. */
+ capi.sqlite3_vfs_unregister(pKvvfs);
}
- }/*kvvfs*/
+ }/*pKvvfs*/
});
case 1:
if('string'===typeof args[0] || util.isSQLableTypedArray(args[0])){
out.sql = args[0];
+ }else if(Array.isArray(args[0])){
+ out.sql = args[0];
}else if(args[0] && 'object'===typeof args[0]){
out.opt = args[0];
out.sql = out.opt.sql;
- }else if(Array.isArray(args[0])){
- out.sql = args[0];
}
break;
case 2:
}else if(Array.isArray(out.sql)){
out.sql = out.sql.join('');
}else if('string'!==typeof out.sql){
- toss3("Missing SQL argument.");
+ toss3("Missing SQL argument or unsupported SQL value type.");
}
if(out.opt.callback || out.opt.resultRows){
switch((undefined===out.opt.rowMode)
case, the function's name must be the 'name' property.
The first two call forms can only be used for creating scalar
- functions. Creating an aggregate function requires the
- options-object form (see below for details).
+ functions. Creating an aggregate or window function requires
+ the options-object form (see below for details).
UDFs cannot currently be removed from a DB handle after they're
added. More correctly, they can be removed as documented for
properties to the "step" and "final" callbacks for the
aggregate. Do not set the `xFunc` property.
- The options object may optionally have an `xDestroy`
- function-type property, as per
- sqlite3_create_function_v2(). Its argument will be the
- WASM-pointer-type value of the `pApp` property, and this
- function will throw if `pApp` is defined but is not null,
- undefined, or a numeric (WASM pointer) value.
+ - Window: set the `xStep`, `xFinal`, `xValue`, and `xInverse`
+ function-type properties. Do not set the `xFunc` property.
- The optional options object may contain flags to modify how
+ The options object may optionally have an `xDestroy`
+ function-type property, as per sqlite3_create_function_v2().
+ Its argument will be the WASM-pointer-type value of the `pApp`
+ property, and this function will throw if `pApp` is defined but
+ is not null, undefined, or a numeric (WASM pointer)
+ value. i.e. `pApp`, if set, must be value suitable for use as a
+ WASM pointer argument, noting that `null` or `undefined` will
+ translate to 0 for that purpose.
+
+ The options object may contain flags to modify how
the function is defined:
- `arity`: the number of arguments which SQL calls to this
arity value means that the function is variadic and may accept
any number of arguments, up to sqlite3's compile-time
limits. sqlite3 will enforce the argument count if is zero or
- greater.
-
- The callback always receives a pointer to an `sqlite3_context`
- object as its first argument. Any arguments after that are from
- SQL code. The leading context argument does _not_ count towards
- the function's arity. See the docs for
+ greater. The callback always receives a pointer to an
+ `sqlite3_context` object as its first argument. Any arguments
+ after that are from SQL code. The leading context argument does
+ _not_ count towards the function's arity. See the docs for
sqlite3.capi.sqlite3_create_function_v2() for why that argument
is needed in the interface.
- The following properties correspond to flags documented at:
+ The following options-object properties correspond to flags
+ documented at:
https://sqlite.org/c3ref/create_function.html
- - .deterministic = SQLITE_DETERMINISTIC
- - .directOnly = SQLITE_DIRECTONLY
- - .innocuous = SQLITE_INNOCUOUS
+ - `deterministic` = sqlite3.capi.SQLITE_DETERMINISTIC
+ - `directOnly` = sqlite3.capi.SQLITE_DIRECTONLY
+ - `innocuous` = sqlite3.capi.SQLITE_INNOCUOUS
+
+ Sidebar: the ability to add new WASM-accessible functions to
+ the runtime requires that the WASM build is compiled with the
+ equivalent functionality as that provided by Emscripten's
+ `-sALLOW_TABLE_GROWTH` flag.
*/
createFunction: function f(name, xFunc, opt){
- let xStep, xFinal;
const isFunc = (f)=>(f instanceof Function);
switch(arguments.length){
case 1: /* (optionsObject) */
opt = name;
name = opt.name;
- xFunc = opt.xFunc;
+ xFunc = opt.xFunc || 0;
break;
case 2: /* (name, callback|optionsObject) */
if(!isFunc(xFunc)){
opt = xFunc;
- xFunc = opt.xFunc;
+ xFunc = opt.xFunc || 0;
}
break;
case 3: /* name, xFunc, opt */
if('string' !== typeof name){
toss3("Invalid arguments: missing function name.");
}
- xStep = opt.xStep;
- xFinal = opt.xFinal;
+ let xStep = opt.xStep || 0;
+ let xFinal = opt.xFinal || 0;
+ const xValue = opt.xValue || 0;
+ const xInverse = opt.xInverse || 0;
+ let isWindow = undefined;
if(isFunc(xFunc)){
+ isWindow = false;
if(isFunc(xStep) || isFunc(xFinal)){
toss3("Ambiguous arguments: scalar or aggregate?");
}
xStep = xFinal = null;
}else if(isFunc(xStep)){
if(!isFunc(xFinal)){
- toss3("Missing xFinal() callback for aggregate UDF.");
+ toss3("Missing xFinal() callback for aggregate or window UDF.");
}
xFunc = null;
}else if(isFunc(xFinal)){
- toss3("Missing xStep() callback for aggregate UDF.");
+ toss3("Missing xStep() callback for aggregate or window UDF.");
}else{
toss3("Missing function-type properties.");
}
+ if(false === isWindow){
+ if(isFunc(xValue) || isFunc(xInverse)){
+ toss3("xValue and xInverse are not permitted for non-window UDFs.");
+ }
+ }else if(isFunc(xValue)){
+ if(!isFunc(xInverse)){
+ toss3("xInverse must be provided if xValue is.");
+ }
+ isWindow = true;
+ }else if(isFunc(xInverse)){
+ toss3("xValue must be provided if xInverse is.");
+ }
const pApp = opt.pApp;
if(undefined!==pApp &&
null!==pApp &&
(('number'!==typeof pApp) || !capi.util.isInt32(pApp))){
toss3("Invalid value for pApp property. Must be a legal WASM pointer value.");
}
- const xDestroy = opt.xDestroy;
+ const xDestroy = opt.xDestroy || 0;
if(xDestroy && !isFunc(xDestroy)){
toss3("xDestroy property must be a function.");
}
name = name.toLowerCase();
const xArity = xFunc || xStep;
const arity = getOwnOption(opt, 'arity');
- DB.checkRc(this, capi.sqlite3_create_function_v2(
- this.pointer, name,
- ('number'===typeof arity
- ? arity
- : (xArity.length ? xArity.length-1/*for pCtx arg*/ : 0)),
- capi.SQLITE_UTF8 | fFlags, pApp,
- xFunc, xStep, xFinal, xDestroy));
+ const arityArg = ('number'===typeof arity
+ ? arity
+ : (xArity.length ? xArity.length-1/*for pCtx arg*/ : 0));
+ let rc;
+ if( isWindow ){
+ rc = capi.sqlite3_create_window_function(
+ this.pointer, name, arityArg,
+ capi.SQLITE_UTF8 | fFlags, pApp || 0,
+ xStep, xFinal, xValue, xInverse, xDestroy);
+ }else{
+ rc = capi.sqlite3_create_function_v2(
+ this.pointer, name, arityArg,
+ capi.SQLITE_UTF8 | fFlags, pApp || 0,
+ xFunc, xStep, xFinal, xDestroy);
+ }
+ DB.checkRc(this, rc);
return this;
}/*createFunction()*/,
/**
dbCtorHelper
}/*oo1 object*/;
- if(util.isMainWindow()){
+ if(util.isUIThread()){
/**
Functionally equivalent to DB(storageName,'c','kvvfs') except
that it throws if the given storage name is not one of 'local'
```
*/
WasmAllocError.toss = (...args)=>{
- throw new WasmAllocError(args.join(' '));
+ throw new WasmAllocError(...args);
};
/**
isBindableTypedArray,
isInt32, isSQLableTypedArray, isTypedArray,
typedArrayToString,
- isMainWindow: ()=>{
- return 'undefined' === typeof WorkerGlobalScope
- }
+ isUIThread: ()=>'undefined'===typeof WorkerGlobalScope
},
/**
["sqlite3_value_text", "string", "sqlite3_value*"],
["sqlite3_value_type", "int", "sqlite3_value*"],
["sqlite3_vfs_find", "*", "string"],
- ["sqlite3_vfs_register", "int", "*", "int"]
+ ["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],
+ ["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"]
]/*wasm.bindingSignatures*/;
if(false && wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){
class SQLite3Error extends Error {
/**
Constructs this object with a message equal to all arguments
- concatenated with a space between each one.
+ concatenated with a space between each one. As a special case,
+ if it's passed only a single integer argument, the string form
+ of that argument is the result of
+ sqlite3.capi.sqlite3_js_rc_str() or (if that returns falsy), a
+ synthesized string which contains that integer.
*/
constructor(...args){
- super(args.join(' '));
+ if(1===args.length && 'number'===typeof args[0] && args[0]===(args[0] | 0)){
+ super(capi.sqlite3_js_rc_str(args[0]) || ("Unknown result code #"+args[0]));
+ }else{
+ super(args.join(' '));
+ }
this.name = 'SQLite3Error';
}
};
```
*/
SQLite3Error.toss = (...args)=>{
- throw new SQLite3Error(args.join(' '));
+ throw new SQLite3Error(...args);
};
/** State for sqlite3_wasmfs_opfs_dir(). */
: 0);
};
- if( capi.util.isMainWindow() ){
+ if( capi.util.isUIThread() ){
/* Features specific to the main window thread... */
/**
const mapToString = (v)=>{
switch(typeof v){
case 'number': case 'string': case 'boolean':
- case 'undefined':
+ case 'undefined': case 'bigint':
return ''+v;
default: break;
}
}
log(TestUtil.separator);
logClass('group-start',"Group #"+this.number+':',this.name);
- const indent = '....';
+ const indent = ' ';
const assertCount = TestUtil.counter;
const groupState = Object.create(null);
const skipped = [];
const tc = TestUtil.counter
log(indent, n+":", t.name);
await t.test.call(groupState, sqlite3);
- //log(indent, indent, 'assertion count:',TestUtil.counter - tc);
+ log(indent, indent, TestUtil.counter - tc, 'assertion(s)');
}
}
logClass('green',
T.assert(e instanceof Error)
.assert(e instanceof sqlite3.WasmAllocError);
}
+ try{ throw new sqlite3.SQLite3Error(capi.SQLITE_SCHEMA) }
+ catch(e){ T.assert('SQLITE_SCHEMA' === e.message) }
})
////////////////////////////////////////////////////////////////////
.t('strglob/strlike', function(sqlite3){
const vfsList = capi.sqlite3_js_vfs_list();
T.assert(vfsList.length>1);
T.assert('string'===typeof vfsList[0]);
-
+ //log("vfsList =",vfsList);
for(const v of vfsList){
T.assert('string' === typeof v)
.assert(capi.sqlite3_vfs_find(v) > 0);
const sjac = capi.sqlite3_js_aggregate_context;
db.createFunction({
name: 'summer',
- xStep: function(pCtx, n){
+ xStep: (pCtx, n)=>{
const ac = sjac(pCtx, 4);
wasm.setMemValue(ac, wasm.getMemValue(ac,'i32') + Number(n), 'i32');
},
db.createFunction({
name: 'summerN',
arity: -1,
- xStep: function(pCtx, ...args){
- const pAgg = sjac(pCtx, 4);
- let sum = wasm.getMemValue(pAgg, 'i32');
+ xStep: (pCtx, ...args)=>{
+ const ac = sjac(pCtx, 4);
+ let sum = wasm.getMemValue(ac, 'i32');
for(const v of args) sum += Number(v);
- wasm.setMemValue(pAgg, sum, 'i32');
+ wasm.setMemValue(ac, sum, 'i32');
},
xFinal: (pCtx)=>{
const ac = sjac(pCtx, 0);
const sjac = capi.sqlite3_js_aggregate_context;
db.createFunction({
name: 'summer64',
- xStep: function(pCtx, n){
- const pAgg = sjac(pCtx, 8);
- wasm.setMemValue(pAgg, wasm.getMemValue(pAgg,'i64') + BigInt(n), 'i64');
+ xStep: (pCtx, n)=>{
+ const ac = sjac(pCtx, 8);
+ wasm.setMemValue(ac, wasm.getMemValue(ac,'i64') + BigInt(n), 'i64');
},
xFinal: (pCtx)=>{
const ac = sjac(pCtx, 0);
}
});
let v = db.selectValue([
- "with cte(v) as (",
- "select 3 union all select 5 union all select 7",
- ") select summer64(v*10), summer64(v+1) from cte"
+ "with cte(v) as (",
+ "select 9007199254740991 union all select 1 union all select 2",
+ ") select summer64(v), summer64(v+1) from cte"
]);
- T.assert(150n===BigInt(v));
+ T.assert(9007199254740994n===v);
}
}/*aggregate UDFs*/)
////////////////////////////////////////////////////////////////////
.t({
- name: 'Window UDFs (tests are TODO)',
- predicate: testIsTodo
- })
+ name: 'Window UDFs',
+ test: function(){
+ /* Example window function, table, and results taken from:
+ https://sqlite.org/windowfunctions.html#udfwinfunc */
+ const db = this.db;
+ const sjac = (cx,n=4)=>capi.sqlite3_js_aggregate_context(cx,n);
+ const xValueFinal = (pCtx)=>{
+ const ac = sjac(pCtx, 0);
+ return ac ? wasm.getMemValue(ac,'i32') : 0;
+ };
+ const xStepInverse = (pCtx, n)=>{
+ const ac = sjac(pCtx);
+ wasm.setMemValue(ac, wasm.getMemValue(ac,'i32') + Number(n), 'i32');
+ };
+ db.createFunction({
+ name: 'winsumint',
+ xStep: (pCtx, n)=>xStepInverse(pCtx, n),
+ xInverse: (pCtx, n)=>xStepInverse(pCtx, -n),
+ xFinal: xValueFinal,
+ xValue: xValueFinal
+ });
+ db.exec([
+ "CREATE TABLE twin(x, y); INSERT INTO twin VALUES",
+ "('a', 4),('b', 5),('c', 3),('d', 8),('e', 1)"
+ ]);
+ let count = 0;
+ db.exec({
+ sql:[
+ "SELECT x, winsumint(y) OVER (",
+ "ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING",
+ ") AS sum_y ",
+ "FROM twin ORDER BY x;",
+ "DROP TABLE twin;"
+ ],
+ callback: function(row){
+ switch(++count){
+ case 1: T.assert('a'===row[0] && 9===row[1]); break;
+ case 2: T.assert('b'===row[0] && 12===row[1]); break;
+ case 3: T.assert('c'===row[0] && 16===row[1]); break;
+ case 4: T.assert('d'===row[0] && 12===row[1]); break;
+ case 5: T.assert('e'===row[0] && 9===row[1]); break;
+ default: toss("Too many rows to window function.");
+ }
+ }
+ });
+ T.assert(5 === count);
+ }
+ }/*window UDFs*/)
////////////////////////////////////////////////////////////////////
.t("ATTACH", function(){
-C Make\ssemantics\sfor\sUDF\sxFinal()\sresult\shandling\sand\serror\sreporting\shandling\smore\sflexible.
-D 2022-10-20T23:48:38.866
+C Expose\ssqlite3_vfs_unregister()\sto\sWASM\sand\sunregister\skvvfs\sin\sWorker\sthreads\sto\savoid\sits\sunintended\suse\sthere\s(in\scontexts\sother\sthan\slocal/sessionStorage).\sCorrect\sregistration\sof\swindow\sfunctions,\sextend\soo1.DB.createFunction()\sto\ssupport\swindow\sfunctions,\sand\sadd\swindow\sfunction\stests\sto\stester1.js.\sCorrect\san\sincorrect\s1-arg\shandling\scase\sfor\sDB.exec().\sAdd\sper-test\sassertion\scounts\sto\stester1.js.
+D 2022-10-21T05:27:40.995
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/wasm/GNUmakefile 645bd5670a56acf2c8f1e969c427555e3e8e74dfd6eac8c948858f530617c7d5
F ext/wasm/README-dist.txt e78e44a58772d5b5d7a5a179b5bf639cd67b62249aac66138e2c319bd02dd243
F ext/wasm/README.md 1e5b28158b74ab3ffc9d54fcbc020f0bbeb82c2ff8bbd904214c86c70e8a3066
-F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 89983a8d122c35a90c65ec667844b95a78bcd04f3198a99c1e0c8368c1a0b03a
+F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 36f413ab4dbb057d2dec938fb366ac0a4c5e85ba14660a8d672f0277602c0fc5
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/api/README.md 1350088aee90e959ad9a94fab1bb6bcb5e99d4d27f976db389050f54f2640c78
F ext/wasm/api/extern-post-js.js efbed835f290b3741259acc5faf68714a60d38e6834e6cfe172d5354c87566d2
F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b
F ext/wasm/api/pre-js.js 151e0616614a49f3db19ed544fa13b38c87c108959fbcd4029ea8399a562d94f
F ext/wasm/api/sqlite3-api-cleanup.js 4d07a7524dc9b7b050acfde57163e839243ad2383bd7ee0de0178b1b3e988588
-F ext/wasm/api/sqlite3-api-glue.js ea760df5991cee48e29aa6ced503027760462d5696d50521f7273a91e0e1430c
-F ext/wasm/api/sqlite3-api-oo1.js 0e278d131dad72e9eb348a3dda6a4ff734a9e08925b4ed7e6e5a688d2edaf525
+F ext/wasm/api/sqlite3-api-glue.js 6e4e472eb5afc732a695cd7c5ded6dee6ef8b480e61aa0d648a3fc9033c84745
+F ext/wasm/api/sqlite3-api-oo1.js 5016f6dd4b6b461bb6047fe6a2d3d7cbe85aa6b110c263ebf0347672a0cd897e
F ext/wasm/api/sqlite3-api-opfs.js 22d60ba956e873b65e2e0591e239178082bd53a6d563c3c58db7dc03e562e8f7
-F ext/wasm/api/sqlite3-api-prologue.js e4fbfa66eb6c5c544c52dea6cb48051eddcdc21c276c39a80801f5e76e6c5b56
+F ext/wasm/api/sqlite3-api-prologue.js fa00d55f927e5a4ec51cf2c80f6f0eaed2f4f5774341ecf3d63a0ea4c738f8f5
F ext/wasm/api/sqlite3-api-worker1.js a7f38f03275d6c27ab2aef3e83215d3c97ce09c43e6904df47c3764d9d4572b4
F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
F ext/wasm/api/sqlite3-opfs-async-proxy.js 206ce6bbc3c30ad51a37d9c25e3a2712e70b586e0f9a2cf8cb0b9619017c2671
F ext/wasm/test-opfs-vfs.js 48fc59110e8775bb43c9be25b6d634fc07ebadab7da8fbd44889e8129c6e2548
F ext/wasm/tester1-worker.html 048c341f124fdb61ca14dfd1bd1f78742490f208aa3bb1e84399f83f1e7e6a74
F ext/wasm/tester1.html 37ccc958fa0d95074af2d72b7241c8e2d982bbec6dda4dc790241af3d933c3b6
-F ext/wasm/tester1.js 5533cd100dc663dbe548fb04aefc490aa4b3d2e0ec2212f79881bb4893266e39
+F ext/wasm/tester1.js 3fc539001b861d6360ea8c4825351157251204781b7a45389527574ad338c7e1
F ext/wasm/version-info.c 5fa356d38859d71a0369b5c37e1935def7413fcc8a4e349a39d9052c1d0479f4
F ext/wasm/wasmfs.make ee0004813e16c283ff633e08b482008d56adf9b7d42f6c5612f7ab002b924f69
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 9d034ef5e1bab7c9651c2450dc85765fa6365d3f1414c711550de858ff8b3ece
-R dfb3978c0632c8b69ab9fb0976c9a2ee
+P 89f3e1982ec32c010af67d15ef780847df20de568669e5c9d02f3cf084f51330
+R 8a68d8975e926edd4ad048c9589fdc73
U stephan
-Z c86f3e45c75ca0a38f433f4183ca8f53
+Z 78e197950cf91aa30272843b46106df8
# Remove this line to create a well-formed Fossil manifest.
-89f3e1982ec32c010af67d15ef780847df20de568669e5c9d02f3cf084f51330
\ No newline at end of file
+f07ce15479b7224b0d1ba9f147a433136e70c1461aa667d2737d4a918f778f55
\ No newline at end of file