Further refactoring of opfs-sahpool and start integrating it into tester1.c-pp.js.

FossilOrigin-Name: 91c789234963b660ae900f0738906b28a477993709e286d8125b2f4d6101601c
This commit is contained in:
stephan 2023-07-18 18:52:41 +00:00
parent d69e6e6efb
commit b0dd9d427f
7 changed files with 149 additions and 80 deletions

View File

@ -59,7 +59,7 @@ const toExportForESM =
initModuleState.sqlite3Dir = li.join('/') + '/'; initModuleState.sqlite3Dir = li.join('/') + '/';
} }
globalThis.sqlite3InitModule = function ff(...args){ globalThis.sqlite3InitModule = async function ff(...args){
//console.warn("Using replaced sqlite3InitModule()",globalThis.location); //console.warn("Using replaced sqlite3InitModule()",globalThis.location);
return originalInit(...args).then((EmscriptenModule)=>{ return originalInit(...args).then((EmscriptenModule)=>{
if('undefined'!==typeof WorkerGlobalScope && if('undefined'!==typeof WorkerGlobalScope &&

View File

@ -1876,26 +1876,28 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
then it must be called by client-level code, which must not use then it must be called by client-level code, which must not use
the library until the returned promise resolves. the library until the returned promise resolves.
Bug: if called while a prior call is still resolving, the 2nd If called multiple times it will return the same promise on
call will resolve prematurely, before the 1st call has finished subsequent calls. The current build setup precludes that
resolving. The current build setup precludes that possibility, possibility, so it's only a hypothetical problem if/when this
so it's only a hypothetical problem if/when this function function ever needs to be invoked by clients.
ever needs to be invoked by clients.
In Emscripten-based builds, this function is called In Emscripten-based builds, this function is called
automatically and deleted from this object. automatically and deleted from this object.
*/ */
asyncPostInit: async function(){ asyncPostInit: function ff(){
if(ff.ready instanceof Promise) return ff.ready;
let lip = sqlite3ApiBootstrap.initializersAsync; let lip = sqlite3ApiBootstrap.initializersAsync;
delete sqlite3ApiBootstrap.initializersAsync; delete sqlite3ApiBootstrap.initializersAsync;
if(!lip || !lip.length) return Promise.resolve(sqlite3); if(!lip || !lip.length){
return ff.ready = Promise.resolve(sqlite3);
}
lip = lip.map((f)=>{ lip = lip.map((f)=>{
const p = (f instanceof Promise) ? f : f(sqlite3); return (f instanceof Promise) ? f : f(sqlite3);
return p.catch((e)=>{ });
console.error("an async sqlite3 initializer failed:",e); const catcher = (e)=>{
config.error("an async sqlite3 initializer failed:",e);
throw e; throw e;
}); };
});
const postInit = ()=>{ const postInit = ()=>{
if(!sqlite3.__isUnderTest){ if(!sqlite3.__isUnderTest){
/* Delete references to internal-only APIs which are used by /* Delete references to internal-only APIs which are used by
@ -1911,16 +1913,16 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
return sqlite3; return sqlite3;
}; };
if(1){ if(1){
/* Run all initializers in sequence. The advantage is that it /* Run all initializers in the sequence they were added. The
allows us to have post-init cleanup defined outside of this advantage is that it allows us to have post-init cleanup
routine at the end of the list and have it run at a defined outside of this routine at the end of the list and
well-defined time. */ have it run at a well-defined time. */
let p = lip.shift(); let p = lip.shift();
while(lip.length) p = p.then(lip.shift()); while(lip.length) p = p.then(lip.shift());
return p.then(postInit); return ff.ready = p.then(postInit).catch(catcher);
}else{ }else{
/* Run them in an arbitrary order. */ /* Run them in an arbitrary order. */
return Promise.all(lip).then(postInit); return ff.ready = Promise.all(lip).then(postInit).catch(catcher);
} }
}, },
/** /**

View File

@ -52,7 +52,7 @@
is not detected, the VFS is not registered. is not detected, the VFS is not registered.
*/ */
'use strict'; 'use strict';
globalThis.sqlite3ApiBootstrap.initializersAsync.push(async function(sqlite3){ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
const toss = sqlite3.util.toss; const toss = sqlite3.util.toss;
const toss3 = sqlite3.util.toss3; const toss3 = sqlite3.util.toss3;
const initPromises = Object.create(null); const initPromises = Object.create(null);
@ -400,46 +400,47 @@ globalThis.sqlite3ApiBootstrap.initializersAsync.push(async function(sqlite3){
/** /**
A SAHPoolUtil instance is exposed to clients in order to A SAHPoolUtil instance is exposed to clients in order to manipulate an OpfsSAHPool object without directly exposing that
manipulate an OpfsSAHPool object without directly exposing that
object and allowing for some semantic changes compared to that object and allowing for some semantic changes compared to that
class. class.
Class docs are in the client-level docs for installOpfsSAHPoolVfs().
*/ */
class SAHPoolUtil { class SAHPoolUtil {
/* This object's associated OpfsSAHPool. */
#p;
constructor(sahPool){ constructor(sahPool){
/* TODO: move the this-to-sahPool mapping into an external this.#p = sahPool;
WeakMap so as to not expose it to downstream clients. */
this.$p = sahPool;
this.vfsName = sahPool.vfsName; this.vfsName = sahPool.vfsName;
} }
addCapacity = async function(n){ async addCapacity(n){
return this.$p.addCapacity(n); return this.#p.addCapacity(n);
} }
reduceCapacity = async function(n){ async reduceCapacity(n){
return this.$p.reduceCapacity(n); return this.#p.reduceCapacity(n);
} }
getCapacity = function(){ getCapacity(){
return this.$p.getCapacity(this.$p); return this.#p.getCapacity(this.#p);
} }
getActiveFileCount = function(){ getActiveFileCount(){
return this.$p.getFileCount(); return this.#p.getFileCount();
} }
reserveMinimumCapacity = async function(min){ async reserveMinimumCapacity(min){
const c = this.$p.getCapacity(); const c = this.#p.getCapacity();
return (c < min) ? this.$p.addCapacity(min - c) : c; return (c < min) ? this.#p.addCapacity(min - c) : c;
} }
exportFile = function(name){ exportFile(name){
const sah = this.$p.mapFilenameToSAH.get(name) || toss("File not found:",name); const sah = this.#p.mapFilenameToSAH.get(name) || toss("File not found:",name);
const n = sah.getSize() - HEADER_OFFSET_DATA; const n = sah.getSize() - HEADER_OFFSET_DATA;
const b = new Uint8Array(n>=0 ? n : 0); const b = new Uint8Array(n>=0 ? n : 0);
if(n>0) sah.read(b, {at: HEADER_OFFSET_DATA}); if(n>0) sah.read(b, {at: HEADER_OFFSET_DATA});
return b; return b;
} }
importDb = function(name, bytes){ importDb(name, bytes){
const n = bytes.byteLength; const n = bytes.byteLength;
if(n<512 || n%512!=0){ if(n<512 || n%512!=0){
toss("Byte array size is invalid for an SQLite db."); toss("Byte array size is invalid for an SQLite db.");
@ -450,35 +451,33 @@ globalThis.sqlite3ApiBootstrap.initializersAsync.push(async function(sqlite3){
toss("Input does not contain an SQLite database header."); toss("Input does not contain an SQLite database header.");
} }
} }
const sah = this.$p.mapFilenameToSAH.get(name) const sah = this.#p.mapFilenameToSAH.get(name)
|| this.$p.nextAvailableSAH() || this.#p.nextAvailableSAH()
|| toss("No available handles to import to."); || toss("No available handles to import to.");
sah.write(bytes, {at: HEADER_OFFSET_DATA}); sah.write(bytes, {at: HEADER_OFFSET_DATA});
this.$p.setAssociatedPath(sah, name, capi.SQLITE_OPEN_MAIN_DB); this.#p.setAssociatedPath(sah, name, capi.SQLITE_OPEN_MAIN_DB);
} }
wipeFiles = async function(){ async wipeFiles(){return this.#p.reset(true)}
return this.$p.reset(true);
unlink(filename){
return this.#p.deletePath(filename);
} }
unlink = function(filename){ async removeVfs(){
return this.$p.deletePath(filename); if(!this.#p.cVfs.pointer) return false;
} capi.sqlite3_vfs_unregister(this.#p.cVfs.pointer);
this.#p.cVfs.dispose();
removeVfs = async function(){
if(!this.$p.cVfs.pointer) return false;
capi.sqlite3_vfs_unregister(this.$p.cVfs.pointer);
this.$p.cVfs.dispose();
try{ try{
this.$p.releaseAccessHandles(); this.#p.releaseAccessHandles();
if(this.$p.parentDirHandle){ if(this.#p.parentDirHandle){
await this.$p.parentDirHandle.removeEntry( await this.#p.parentDirHandle.removeEntry(
this.$p.dirHandle.name, {recursive: true} this.#p.dirHandle.name, {recursive: true}
); );
this.$p.dirHandle = this.$p.parentDirHandle = undefined; this.#p.dirHandle = this.#p.parentDirHandle = undefined;
} }
}catch(e){ }catch(e){
console.error(this.$p.vfsName,"removeVfs() failed:",e); sqlite3.config.error(this.#p.vfsName,"removeVfs() failed:",e);
/*otherwise ignored - there is no recovery strategy*/ /*otherwise ignored - there is no recovery strategy*/
} }
return true; return true;
@ -679,7 +678,7 @@ globalThis.sqlite3ApiBootstrap.initializersAsync.push(async function(sqlite3){
throw new Error("Just testing rejection."); throw new Error("Just testing rejection.");
} }
if(initPromises[vfsName]){ if(initPromises[vfsName]){
//console.warn("Returning same OpfsSAHPool result",vfsName,initPromises[vfsName]); console.warn("Returning same OpfsSAHPool result",options,vfsName,initPromises[vfsName]);
return initPromises[vfsName]; return initPromises[vfsName];
} }
if(!globalThis.FileSystemHandle || if(!globalThis.FileSystemHandle ||
@ -743,6 +742,9 @@ globalThis.sqlite3ApiBootstrap.initializersAsync.push(async function(sqlite3){
ensues. ensues.
*/ */
return initPromises[vfsName] = apiVersionCheck().then(async function(){ return initPromises[vfsName] = apiVersionCheck().then(async function(){
if(options.$testThrowInInit){
throw options.$testThrowInInit;
}
const thePool = new OpfsSAHPool(opfsVfs, options); const thePool = new OpfsSAHPool(opfsVfs, options);
return thePool.isReady.then(async()=>{ return thePool.isReady.then(async()=>{
/** /**
@ -1025,4 +1027,4 @@ globalThis.sqlite3ApiBootstrap.initializersAsync.push(async function(sqlite3){
}); });
}).catch(promiseReject); }).catch(promiseReject);
}/*installOpfsSAHPoolVfs()*/; }/*installOpfsSAHPoolVfs()*/;
}/*sqlite3ApiBootstrap.initializersAsync*/); }/*sqlite3ApiBootstrap.initializers*/);

View File

@ -23,7 +23,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
installOpfsVfs() returns a Promise which, on success, installs an installOpfsVfs() returns a Promise which, on success, installs an
sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
which accept a VFS. It is intended to be called via which accept a VFS. It is intended to be called via
sqlite3ApiBootstrap.initializersAsync or an equivalent mechanism. sqlite3ApiBootstrap.initializers or an equivalent mechanism.
The installed VFS uses the Origin-Private FileSystem API for The installed VFS uses the Origin-Private FileSystem API for
all file storage. On error it is rejected with an exception all file storage. On error it is rejected with an exception

View File

@ -65,6 +65,14 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
const haveWasmCTests = ()=>{ const haveWasmCTests = ()=>{
return !!wasm.exports.sqlite3_wasm_test_intptr; return !!wasm.exports.sqlite3_wasm_test_intptr;
}; };
const hasOpfs = ()=>{
return globalThis.FileSystemHandle
&& globalThis.FileSystemDirectoryHandle
&& globalThis.FileSystemFileHandle
&& globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle
&& navigator?.storage?.getDirectory;
};
{ {
const mapToString = (v)=>{ const mapToString = (v)=>{
switch(typeof v){ switch(typeof v){
@ -277,7 +285,14 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
} }
} }
const tc = TestUtil.counter, now = performance.now(); const tc = TestUtil.counter, now = performance.now();
await t.test.call(groupState, sqlite3); let rc = t.test.call(groupState, sqlite3);
/*if(rc instanceof Promise){
rc = rc.catch((e)=>{
error("Test failure:",e);
throw e;
});
}*/
await rc;
const then = performance.now(); const then = performance.now();
runtime += then - now; runtime += then - now;
logClass('faded',indent, indent, logClass('faded',indent, indent,
@ -339,6 +354,11 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
T.g = T.addGroup; T.g = T.addGroup;
T.t = T.addTest; T.t = T.addTest;
let capi, wasm/*assigned after module init*/; let capi, wasm/*assigned after module init*/;
const sahPoolConfig = {
name: 'opfs-sahpool-tester1',
clearOnInit: true,
initialCapacity: 3
};
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// End of infrastructure setup. Now define the tests... // End of infrastructure setup. Now define the tests...
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -1288,7 +1308,6 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
if(1){ if(1){
const vfsList = capi.sqlite3_js_vfs_list(); const vfsList = capi.sqlite3_js_vfs_list();
T.assert(vfsList.length>1); T.assert(vfsList.length>1);
//log("vfsList =",vfsList);
wasm.scopedAllocCall(()=>{ wasm.scopedAllocCall(()=>{
const vfsArg = (v)=>wasm.xWrap.testConvertArg('sqlite3_vfs*',v); const vfsArg = (v)=>wasm.xWrap.testConvertArg('sqlite3_vfs*',v);
for(const v of vfsList){ for(const v of vfsList){
@ -2617,8 +2636,8 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
T.g('OPFS: Origin-Private File System', T.g('OPFS: Origin-Private File System',
(sqlite3)=>(sqlite3.opfs (sqlite3)=>(sqlite3.capi.sqlite3_vfs_find("opfs")
? true : "requires Worker thread in a compatible browser")) || 'requires "opfs" VFS'))
.t({ .t({
name: 'OPFS db sanity checks', name: 'OPFS db sanity checks',
test: async function(sqlite3){ test: async function(sqlite3){
@ -2737,6 +2756,48 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
}/*OPFS util sanity checks*/) }/*OPFS util sanity checks*/)
;/* end OPFS tests */ ;/* end OPFS tests */
////////////////////////////////////////////////////////////////////////
T.g('OPFS SyncAccessHandle Pool VFS',
(sqlite3)=>(hasOpfs() || "requires OPFS APIs"))
.t({
name: 'SAH sanity checks',
test: async function(sqlite3){
T.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
.assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) < 0)
const inst = sqlite3.installOpfsSAHPoolVfs,
catcher = (e)=>{
error("Cannot load SAH pool VFS.",
"This might not be a problem,",
"depending on the environment.");
return false;
};
let u1, u2;
const P1 = inst(sahPoolConfig).then(u=>u1 = u).catch(catcher),
P2 = inst(sahPoolConfig).then(u=>u2 = u).catch(catcher);
await Promise.all([P1, P2]);
if(!P1) return;
T.assert(u1 === u2)
.assert(sahPoolConfig.name === u1.vfsName)
.assert(sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
.assert(u1.getCapacity() === sahPoolConfig.initialCapacity)
.assert(5 === (await u2.addCapacity(2)))
.assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) >= 0)
.assert(true === await u2.removeVfs())
.assert(false === await u1.removeVfs())
.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name));
let cErr, u3;
const conf2 = JSON.parse(JSON.stringify(sahPoolConfig));
conf2.$testThrowInInit = new Error("Testing throwing during init.");
conf2.name = sahPoolConfig.name+'-err';
const P3 = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e);
T.assert(P3 === conf2.$testThrowInInit)
.assert(cErr === P3)
.assert(undefined === u3)
.assert(!sqlite3.capi.sqlite3_vfs_find(conf2.name));
}
}/*OPFS SAH Pool sanity checks*/)
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
T.g('Hook APIs') T.g('Hook APIs')
.t({ .t({
@ -2942,8 +3003,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
.assert( capi.sqlite3session_enable(pSession, -1) > 0 ) .assert( capi.sqlite3session_enable(pSession, -1) > 0 )
.assert(undefined === db1.selectValue('select a from t where rowid=2')); .assert(undefined === db1.selectValue('select a from t where rowid=2'));
}else{ }else{
warn("sqlite3session_enable() tests disabled due to unexpected results.", warn("sqlite3session_enable() tests are currently disabled.");
"(Possibly a tester misunderstanding, as opposed to a bug.)");
} }
let db1Count = db1.selectValue("select count(*) from t"); let db1Count = db1.selectValue("select count(*) from t");
T.assert( db1Count === (testSessionEnable ? 2 : 3) ); T.assert( db1Count === (testSessionEnable ? 2 : 3) );
@ -3088,11 +3148,15 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
globalThis.sqlite3InitModule({ globalThis.sqlite3InitModule({
print: log, print: log,
printErr: error printErr: error
}).then(function(sqlite3){ }).then(async function(sqlite3){
//console.log('sqlite3 =',sqlite3);
log("Done initializing WASM/JS bits. Running tests..."); log("Done initializing WASM/JS bits. Running tests...");
sqlite3.config.warn("Installing sqlite3 bits as global S for local dev/test purposes."); sqlite3.config.warn("Installing sqlite3 bits as global S for local dev/test purposes.");
globalThis.S = sqlite3; globalThis.S = sqlite3;
/*await sqlite3.installOpfsSAHPoolVfs(sahPoolConfig)
.then((u)=>log("Loaded",u.vfsName,"VFS"))
.catch(e=>{
log("Cannot install OpfsSAHPool.",e);
});*/
capi = sqlite3.capi; capi = sqlite3.capi;
wasm = sqlite3.wasm; wasm = sqlite3.wasm;
log("sqlite3 version:",capi.sqlite3_libversion(), log("sqlite3 version:",capi.sqlite3_libversion(),
@ -3107,6 +3171,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
}else{ }else{
logClass('warning',"sqlite3_wasm_test_...() APIs unavailable."); logClass('warning',"sqlite3_wasm_test_...() APIs unavailable.");
} }
log("registered vfs list =",capi.sqlite3_js_vfs_list());
TestUtil.runTests(sqlite3); TestUtil.runTests(sqlite3);
}); });
})(self); })(self);

View File

@ -1,5 +1,5 @@
C Major\srestructuring\sof\sthe\sopfs-sahpool\sbits\sto\sbetter\ssupport\smultiple\sinstances\sper\sapp\s(each\ssandboxed\sfrom\seach\sother).\sEliminate\sthe\spesky\spromise\sresolution\srace\scondition\swhen\stwo\ssuch\sinstances\sare\sloaded\sin\sparallel. C Further\srefactoring\sof\sopfs-sahpool\sand\sstart\sintegrating\sit\sinto\stester1.c-pp.js.
D 2023-07-18T16:24:51.703 D 2023-07-18T18:52:41.004
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -489,7 +489,7 @@ F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api d6a5078f48a5301ed17b9a30331075d9b2
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/api/README.md f6cec6b0ce122cdff9440b30a3132dea3665b5b7baace910b43cbccdaaa376b9 F ext/wasm/api/README.md f6cec6b0ce122cdff9440b30a3132dea3665b5b7baace910b43cbccdaaa376b9
F ext/wasm/api/extern-post-js.c-pp.js 116749b7e55b7519129de06d3d353e19df68cfb24b12204aa4dc30c9a83023fe F ext/wasm/api/extern-post-js.c-pp.js 80f288131f9f4486a66e79dbf42d4402dc23e3cb4ef605377ae69f0545a6b8e6
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41 F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1 F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
@ -497,13 +497,13 @@ F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057af
F ext/wasm/api/sqlite3-api-cleanup.js 23ceec5ef74a0e649b19694ca985fd89e335771e21f24f50df352a626a8c81bf F ext/wasm/api/sqlite3-api-cleanup.js 23ceec5ef74a0e649b19694ca985fd89e335771e21f24f50df352a626a8c81bf
F ext/wasm/api/sqlite3-api-glue.js f1b2dcb944de5138bb5bd9a1559d2e76a4f3ec25260963d709e8237476688803 F ext/wasm/api/sqlite3-api-glue.js f1b2dcb944de5138bb5bd9a1559d2e76a4f3ec25260963d709e8237476688803
F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8 F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8
F ext/wasm/api/sqlite3-api-prologue.js f68e87edc049793c4ed46b0ec8f3a3d8013eeb3fd56481029dda916d4d5fa3a3 F ext/wasm/api/sqlite3-api-prologue.js d747cbb379e13881c9edf39dce019cbbbae860c456ababe9d550b4b27666a1c9
F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379 F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
F ext/wasm/api/sqlite3-v-helper.js fc9ed95433d943a65905d16b7ed51515ddb6667d2a2c5a711c7ce33b29d3be31 F ext/wasm/api/sqlite3-v-helper.js fc9ed95433d943a65905d16b7ed51515ddb6667d2a2c5a711c7ce33b29d3be31
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js fc6d12298919652eacc6b51138011277be2598d60fbcb086049967621db74e2c F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js cd4d26fd8bf6c6b5bcb1666e8447c5388eb10ebfee57684e3658ee995f5a9645
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 842d55b35a871ee5483cc5e0cf067a968362b4d61321f08c71aab5505c72f556 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 4946af0d6fbd395aa39966562ca85900664605a5f0cc10fff50146dee527812c
F ext/wasm/api/sqlite3-wasm.c 8867f1d41c112fb4a2cfe22ff224eccaf309fcdea266cee0ec554f85db72ef0f F ext/wasm/api/sqlite3-wasm.c 8867f1d41c112fb4a2cfe22ff224eccaf309fcdea266cee0ec554f85db72ef0f
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75 F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75
@ -549,7 +549,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
F ext/wasm/tester1.c-pp.js 4420eb97b6b4fc79e4e156b4b8010dd9f373365f4230dd76d823fb04ce28ffde F ext/wasm/tester1.c-pp.js 76607c9821e7854c061121b89337ca244f683b3a16c5415d078d361a8ec9e22f
F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1 F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1
F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@ -2044,8 +2044,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P d036eaf6ac60c576428db40f015733c5d5425f7d613194fd8d9d4d98659077c4 P 95e5fa498f71708caeb3394636c4853530a8b2d54406e503f32750732d6815d5
R f91cd88307b7706bc464075e9268cd3a R b629bc29f8d41e1b5f3ab58dda955102
U stephan U stephan
Z 4affd9934809bcbe1d4716ea36d23534 Z c2f2230ed00c70ba745095d2d4043967
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
95e5fa498f71708caeb3394636c4853530a8b2d54406e503f32750732d6815d5 91c789234963b660ae900f0738906b28a477993709e286d8125b2f4d6101601c