From: stephan Date: Wed, 2 Nov 2022 11:53:31 +0000 (+0000) Subject: Add sqlite3_wasm_vfs_create_file() to replace Emscripten's FS.createDataFile() in... X-Git-Tag: version-3.40.0~40 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f45c33701dde9412e6aeab464a8148ab112bb033;p=thirdparty%2Fsqlite.git Add sqlite3_wasm_vfs_create_file() to replace Emscripten's FS.createDataFile() in a (mostly) VFS-agnostic way. Add a test for worker1's export (to bytearray) support. Re-add worker1 open-from-bytearray using sqlite3_wasm_vfs_create_file() but it's untested (requires a new interactive test app or maybe reconsideration). FossilOrigin-Name: b35e1225c91a3cadc0d25af1e4e790237256d194990faa13190e343ed03e11c5 --- diff --git a/ext/wasm/api/sqlite3-api-opfs.js b/ext/wasm/api/sqlite3-api-opfs.js index 90337d5279..86285df1d3 100644 --- a/ext/wasm/api/sqlite3-api-opfs.js +++ b/ext/wasm/api/sqlite3-api-opfs.js @@ -316,6 +316,8 @@ const installOpfsVfs = function callee(options){ */ state.sq3Codes = Object.create(null); [ + 'SQLITE_ACCESS_EXISTS', + 'SQLITE_ACCESS_READWRITE', 'SQLITE_ERROR', 'SQLITE_IOERR', 'SQLITE_IOERR_ACCESS', @@ -939,7 +941,7 @@ const installOpfsVfs = function callee(options){ */ opfsUtil.entryExists = async function(fsEntryName){ try { - const [dh, fn] = await opfsUtil.getDirForFilename(filename); + const [dh, fn] = await opfsUtil.getDirForFilename(fsEntryName); await dh.getFileHandle(fn); return true; }catch(e){ diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 5e7f1bae2e..abee820cf9 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -162,33 +162,6 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( } }); - /** - An Error subclass specifically for reporting DB-level errors and - enabling clients to unambiguously identify such exceptions. - The C-level APIs never throw, but some of the higher-level - C-style APIs do and the object-oriented APIs use exceptions - exclusively to report errors. - */ - class SQLite3Error extends Error { - /** - Constructs this object with a message equal to all arguments - 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){ - if(1===args.length && 'number'===typeof args[0] && args[0]===(args[0] | 0)){ - super((capi.sqlite3_js_rc_str && capi.sqlite3_js_rc_str(args[0])) - || ("Unknown result code #"+args[0])); - }else{ - super(args.join(' ')); - } - this.name = 'SQLite3Error'; - } - }; - /** The main sqlite3 binding API gets installed into this object, mimicking the C API as closely as we can. The numerous members @@ -219,6 +192,52 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( */ const wasm = Object.create(null); + /** Internal helper for SQLite3Error ctor. */ + const __rcStr = (rc)=>{ + return (capi.sqlite3_js_rc_str && capi.sqlite3_js_rc_str(rc)) + || ("Unknown result code #"+rc); + }; + + /** Internal helper for SQLite3Error ctor. */ + const __isInt = (n)=>'number'===typeof n && n===(n | 0); + + /** + An Error subclass specifically for reporting DB-level errors and + enabling clients to unambiguously identify such exceptions. + The C-level APIs never throw, but some of the higher-level + C-style APIs do and the object-oriented APIs use exceptions + exclusively to report errors. + */ + class SQLite3Error extends Error { + /** + Constructs this object with a message depending on its arguments: + + - If it's passed only a single integer argument, it is assumed + to be an sqlite3 C API result code. The message becomes the + result of sqlite3.capi.sqlite3_js_rc_str() or (if that returns + falsy) a synthesized string which contains that integer. + + - If passed 2 arguments and the 2nd is a object, it bevaves + like the Error(string,object) constructor except that the first + argument is subject to the is-integer semantics from the + previous point. + + - Else all arguments are concatenated with a space between each + one, using args.join(' '), to create the error message. + */ + constructor(...args){ + if(1===args.length && __isInt(args[0])){ + super(__rcStr(args[0])); + }else if(2===args.length && 'object'===typeof args){ + if(__isInt(args[0])) super(__rcStr(args[0]), args[1]); + else super(...args); + }else{ + super(args.join(' ')); + } + this.name = 'SQLite3Error'; + } + }; + /** Functionally equivalent to the SQLite3Error constructor but may be used as part of an expression, e.g.: @@ -959,6 +978,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( wasm.bindingSignatures.wasm = [ ["sqlite3_wasm_db_reset", "int", "sqlite3*"], ["sqlite3_wasm_db_vfs", "sqlite3_vfs*", "sqlite3*","string"], + ["sqlite3_wasm_vfs_create_file", "int", + "sqlite3_vfs*","string","*", "int"], ["sqlite3_wasm_vfs_unlink", "int", "sqlite3_vfs*","string"] ]; diff --git a/ext/wasm/api/sqlite3-api-worker1.js b/ext/wasm/api/sqlite3-api-worker1.js index 532d61b67e..32fbc5bb17 100644 --- a/ext/wasm/api/sqlite3-api-worker1.js +++ b/ext/wasm/api/sqlite3-api-worker1.js @@ -423,6 +423,15 @@ sqlite3.initWorker1API = function(){ return wState.dbList[0] && getDbId(wState.dbList[0]); }; + const guessVfs = function(filename){ + const m = /^file:.+(vfs=(\w+))/.exec(filename); + return sqlite3.capi.sqlite3_vfs_find(m ? m[2] : 0); + }; + + const isSpecialDbFilename = (n)=>{ + return ''===n || ':'===n[0]; + }; + /** A level of "organizational abstraction" for the Worker1 API. Each method in this object must map directly to a Worker1 @@ -441,11 +450,35 @@ sqlite3.initWorker1API = function(){ } const rc = Object.create(null); const pDir = sqlite3.capi.sqlite3_wasmfs_opfs_dir(); - if(!args.filename || ':memory:'===args.filename){ + let byteArray, pVfs; + oargs.vfs = args.vfs; + if(isSpecialDbFilename(args.filename)){ oargs.filename = args.filename || ''; }else{ oargs.filename = args.filename; - oargs.vfs = args.vfs; + byteArray = args.byteArray; + if(byteArray) pVfs = guessVfs(args.filename); + } + if(pVfs){ + /* 2022-11-02: this feature is as-yet untested except that + sqlite3_wasm_vfs_create_file() has been tested from the + browser dev console. */ + let pMem; + try{ + pMem = sqlite3.wasm.allocFromTypedArray(byteArray); + const rc = sqlite3.wasm.sqlite3_wasm_vfs_create_file( + pVfs, oargs.filename, pMem, byteArray.byteLength + ); + if(rc) sqlite3.SQLite3Error.toss(rc); + }catch(e){ + throw new sqlite3.SQLite3Error( + e.name+' creating '+args.filename+": "+e.message, { + cause: e + } + ); + }finally{ + if(pMem) sqlite3.wasm.dealloc(pMem); + } } const db = wState.open(oargs); rc.filename = db.filename; @@ -462,10 +495,9 @@ sqlite3.initWorker1API = function(){ filename: db && db.filename }; if(db){ - // Keep the "unlink" flag undocumented until we figure out how - // to apply it consistently, independent of the db storage. - wState.close(db, ((ev.args && 'object'===typeof ev.args) - ? !!ev.args.unlink : false)); + const doUnlink = ((ev.args && 'object'===typeof ev.args) + ? !!ev.args.unlink : false); + wState.close(db, doUnlink); } return response; }, @@ -542,7 +574,7 @@ sqlite3.initWorker1API = function(){ sqlite3_serialize(). Response is an object: { - bytearray: Uint8Array (db file contents), + byteArray: Uint8Array (db file contents), filename: the current db filename, mimetype: 'application/x-sqlite3' } @@ -550,11 +582,11 @@ sqlite3.initWorker1API = function(){ export: function(ev){ const db = getMsgDb(ev); const response = { - bytearray: sqlite3.capi.sqlite3_js_db_export(db.pointer), + byteArray: sqlite3.capi.sqlite3_js_db_export(db.pointer), filename: db.filename, mimetype: 'application/x-sqlite3' }; - wState.xfer.push(response.bytearray.buffer); + wState.xfer.push(response.byteArray.buffer); return response; }/*export()*/, diff --git a/ext/wasm/api/sqlite3-opfs-async-proxy.js b/ext/wasm/api/sqlite3-opfs-async-proxy.js index e3c3b82146..86276910aa 100644 --- a/ext/wasm/api/sqlite3-opfs-async-proxy.js +++ b/ext/wasm/api/sqlite3-opfs-async-proxy.js @@ -230,6 +230,16 @@ const storeAndNotify = (opName, value)=>{ const affirmNotRO = function(opName,fh){ if(fh.readOnly) toss(opName+"(): File is read-only: "+fh.filenameAbs); }; +const affirmLocked = function(opName,fh){ + //if(!fh.syncHandle) toss(opName+"(): File does not have a lock: "+fh.filenameAbs); + /** + Currently a no-op, as speedtest1 triggers xRead() without a + lock (that seems like a bug but it's currently uninvestigated). + This means, however, that some OPFS VFS routines may trigger + acquisition of a lock but never let it go until xUnlock() is + called (which it likely won't be if xLock() was not called). + */ +}; /** We track 2 different timers: the "metrics" timer records how much @@ -395,6 +405,7 @@ const vfsAsyncImpls = { let rc; wTimeStart('xFileSize'); try{ + affirmLocked('xFileSize',fh); rc = await (await getSyncHandle(fh)).getSize(); state.s11n.serialize(Number(rc)); rc = 0; @@ -473,6 +484,7 @@ const vfsAsyncImpls = { let rc = 0, nRead; const fh = __openFiles[fid]; try{ + affirmLocked('xRead',fh); wTimeStart('xRead'); nRead = (await getSyncHandle(fh)).read( fh.sabView.subarray(0, n), @@ -515,6 +527,7 @@ const vfsAsyncImpls = { const fh = __openFiles[fid]; wTimeStart('xTruncate'); try{ + affirmLocked('xTruncate',fh); affirmNotRO('xTruncate', fh); await (await getSyncHandle(fh)).truncate(size); }catch(e){ @@ -547,9 +560,10 @@ const vfsAsyncImpls = { xWrite: async function(fid/*sqlite3_file pointer*/,n,offset64){ mTimeStart('xWrite'); let rc; + const fh = __openFiles[fid]; wTimeStart('xWrite'); try{ - const fh = __openFiles[fid]; + affirmLocked('xWrite',fh); affirmNotRO('xWrite', fh); rc = ( n === (await getSyncHandle(fh)) diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index 1ca51f0d2f..62082edda0 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -12,7 +12,6 @@ ** ** emcc -o sqlite3.wasm ... -I/path/to/sqlite3-c-and-h sqlite3-wasm.c */ - #define SQLITE_WASM #ifdef SQLITE_WASM_ENABLE_C_TESTS /* @@ -928,8 +927,8 @@ int sqlite3_wasm_db_export_chunked( sqlite3* pDb, ** sqlite3_free() to free it. */ SQLITE_WASM_KEEP -int sqlite3_wasm_db_serialize( sqlite3* pDb, unsigned char **pOut, - sqlite3_int64 * nOut, unsigned int mFlags ){ +int sqlite3_wasm_db_serialize( sqlite3 *pDb, unsigned char **pOut, + sqlite3_int64 *nOut, unsigned int mFlags ){ unsigned char * z; if( !pDb || !pOut ) return SQLITE_MISUSE; if(nOut) *nOut = 0; @@ -942,6 +941,103 @@ int sqlite3_wasm_db_serialize( sqlite3* pDb, unsigned char **pOut, } } +/* +** This function is NOT part of the sqlite3 public API. It is strictly +** for use by the sqlite project's own JS/WASM bindings. +** +** Creates a new file using the I/O API of the given VFS, containing +** the given number of bytes of the given data. If the file exists, +** it is truncated to the given length and populated with the given +** data. +** +** This function exists so that we can implement the equivalent of +** Emscripten's FS.createDataFile() in a VFS-agnostic way. This +** functionality is intended for use in uploading database files. +** +** If pVfs is NULL, sqlite3_vfs_find(0) is used. +** +** If zFile is NULL, pVfs is NULL (and sqlite3_vfs_find(0) returns +** NULL), or nData is negative, SQLITE_MISUSE are returned. +** +** On success, it creates a new file with the given name, populated +** with the fist nData bytes of pData. If pData is NULL, the file is +** created and/or truncated to nData bytes. +** +** Whether or not directory components of zFilename are created +** automatically or not is unspecified: that detail is left to the +** VFS. The "opfs" VFS, for example, create them. +** +** Not all VFSes support this functionality, e.g. the "kvvfs" does +** not. +** +** If an error happens while populating or truncating the file, the +** target file will be deleted (if needed) if this function created +** it. If this function did not create it, it is not deleted but may +** be left in an undefined state. +** +** Returns 0 on success. On error, it returns a code described above +** or propagates a code from one of the I/O methods. +** +** Design note: nData is an integer, instead of int64, for WASM +** portability, so that the API can still work in builds where BigInt +** support is disabled or unavailable. +*/ +SQLITE_WASM_KEEP +int sqlite3_wasm_vfs_create_file( sqlite3_vfs *pVfs, + const char *zFilename, + const unsigned char * pData, + int nData ){ + int rc; + sqlite3_file *pFile = 0; + sqlite3_io_methods const *pIo; + const int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + int flagsOut = 0; + int fileExisted = 0; + int doUnlock = 0; + const unsigned char *pPos = pData; + const int blockSize = 512 + /* Because we are using pFile->pMethods->xWrite() for writing, and + ** it may have a buffer limit related to sqlite3's pager size, we + ** conservatively write in 512-byte blocks (smallest page + ** size). */; + + if( !pVfs ) pVfs = sqlite3_vfs_find(0); + if( !pVfs || !zFilename || nData<0 ) return SQLITE_MISUSE; + pVfs->xAccess(pVfs, zFilename, SQLITE_ACCESS_EXISTS, &fileExisted); + rc = sqlite3OsOpenMalloc(pVfs, zFilename, &pFile, openFlags, &flagsOut); + if(rc) return rc; + pIo = pFile->pMethods; + if( pIo->xLock ) { + /* We need xLock() in order to accommodate the OPFS VFS, as it + ** obtains a writeable handle via the lock operation and releases + ** it in xUnlock(). If we don't do those here, we have to add code + ** to the VFS to account check whether it was locked before + ** xFileSize(), xTruncate(), and the like, and release the lock + ** only if it was unlocked when the op was started. */ + rc = pIo->xLock(pFile, SQLITE_LOCK_EXCLUSIVE); + doUnlock = 0==rc; + } + if( 0==rc) rc = pIo->xTruncate(pFile, nData); + if( 0==rc && 0!=pData && nData>0 ){ + while( 0==rc && nData>0 ){ + const int n = nData>=blockSize ? blockSize : nData; + rc = pIo->xWrite(pFile, pPos, n, (sqlite3_int64)(pPos - pData)); + nData -= n; + pPos += n; + } + if( 0==rc && nData>0 ){ + assert(nData<512); + rc = pIo->xWrite(pFile, pPos, nData, (sqlite3_int64)(pPos - pData)); + } + } + if( pIo->xUnlock && doUnlock!=0 ) pIo->xUnlock(pFile, SQLITE_LOCK_NONE); + pIo->xClose(pFile); + if( rc!=0 && 0==fileExisted ){ + pVfs->xDelete(pVfs, zFilename, 1); + } + return rc; +} + /* ** This function is NOT part of the sqlite3 public API. It is strictly ** for use by the sqlite project's own JS/WASM bindings. diff --git a/ext/wasm/demo-worker1-promiser.js b/ext/wasm/demo-worker1-promiser.js index 3f50ef9e08..a65cc31b6e 100644 --- a/ext/wasm/demo-worker1-promiser.js +++ b/ext/wasm/demo-worker1-promiser.js @@ -248,6 +248,14 @@ .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); diff --git a/ext/wasm/demo-worker1.js b/ext/wasm/demo-worker1.js index ac4e9f4234..cc63f3a7cc 100644 --- a/ext/wasm/demo-worker1.js +++ b/ext/wasm/demo-worker1.js @@ -229,16 +229,14 @@ T.assert(1===ev.resultRows.length) .assert(2===ev.resultRows[0][0]); }); - if(0){ - // export requires reimpl. for portability reasons. - runOneTest('export',{}, function(ev){ - ev = ev.result; - T.assert('string' === typeof ev.filename) - .assert(ev.buffer instanceof Uint8Array) - .assert(ev.buffer.length > 1024) - .assert('application/x-sqlite3' === ev.mimetype); - }); - } + runOneTest('export',{}, function(ev){ + ev = ev.result; + log("export result:",ev); + 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. *****/ runOneTest('close',{unlink:true},function(ev){ ev = ev.result; @@ -342,4 +340,6 @@ } }; log("Init complete, but async init bits may still be running."); + log("Installing Worker into global scope SW for dev purposes."); + self.SW = SW; })(); diff --git a/ext/wasm/tester1.js b/ext/wasm/tester1.js index 4f32368701..825d529f6f 100644 --- a/ext/wasm/tester1.js +++ b/ext/wasm/tester1.js @@ -346,6 +346,11 @@ } try{ throw new sqlite3.SQLite3Error(capi.SQLITE_SCHEMA) } catch(e){ T.assert('SQLITE_SCHEMA' === e.message) } + try{ sqlite3.SQLite3Error.toss(capi.SQLITE_CORRUPT,{cause: true}) } + catch(e){ + T.assert('SQLITE_CORRUPT'===e.message) + .assert(true===e.cause); + } }) //////////////////////////////////////////////////////////////////// .t('strglob/strlike', function(sqlite3){ @@ -1762,6 +1767,26 @@ unlink(); } + if(1){ + // Sanity-test sqlite3_wasm_vfs_create_file()... + const fSize = 1379; + let sh; + try{ + T.assert(!(await opfs.entryExists(filename))); + let rc = wasm.sqlite3_wasm_vfs_create_file( + pVfs, filename, null, fSize + ); + T.assert(0===rc) + .assert(await opfs.entryExists(filename)); + const fh = await opfs.rootDirectory.getFileHandle(filename); + sh = await fh.createSyncAccessHandle(); + T.assert(fSize === await sh.getSize()); + }finally{ + if(sh) sh.close(); + unlink(); + } + } + // Some sanity checks of the opfs utility functions... const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12); const aDir = testDir+'/test/dir'; diff --git a/manifest b/manifest index 618b053ced..d045e6e877 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Emcc\sseems\sconfused\sby\sSQLITE_DEBUG,\sfor\sreasons\sunknown.\s\sUse\sNDEBUG\sinstead\nto\ssimplify\sthe\s#ifdef\slogic\sin\ssqlite3recover.c. -D 2022-11-02T11:25:33.199 +C Add\ssqlite3_wasm_vfs_create_file()\sto\sreplace\sEmscripten's\sFS.createDataFile()\sin\sa\s(mostly)\sVFS-agnostic\sway.\sAdd\sa\stest\sfor\sworker1's\sexport\s(to\sbytearray)\ssupport.\sRe-add\sworker1\sopen-from-bytearray\susing\ssqlite3_wasm_vfs_create_file()\sbut\sit's\suntested\s(requires\sa\snew\sinteractive\stest\sapp\sor\smaybe\sreconsideration). +D 2022-11-02T11:53:31.000 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -501,13 +501,13 @@ F ext/wasm/api/pre-js.js 287e462f969342b032c03900e668099fa1471d852df7a472de5bc34 F ext/wasm/api/sqlite3-api-cleanup.js ecdc69dbfccfe26146f04799fcfd4a6f5790d46e7e3b9b6e9b0491f92ed8ae34 F ext/wasm/api/sqlite3-api-glue.js 9cfa26a9818532c80c2555bc98615de3b170d5db0cf4b141cc3aa83c33c8758f F ext/wasm/api/sqlite3-api-oo1.js e9a83489bbb4838ce0aee46eaaa9350e0e25a5b926b565e4f5ae8e840e4fbaed -F ext/wasm/api/sqlite3-api-opfs.js 59b278ed00764fc47ba88be0582ab3fc3ce725e02b6d86459464cc029b9ac356 -F ext/wasm/api/sqlite3-api-prologue.js 201b9ab9d101fdefa3175b02748ef39cba43bc7abe87a69b6faac24e58cd70f0 -F ext/wasm/api/sqlite3-api-worker1.js 4f920a54fb97d4ca50632d45bd7d011a55016eb5a5883725033abb450903bc6f +F ext/wasm/api/sqlite3-api-opfs.js cdcbb57acc66f4569ac9e18f9d13d5a3657d8aae195725c6324943da56c1005d +F ext/wasm/api/sqlite3-api-prologue.js 1f97261b4d8a60a48f30ee41261e1c4a0c3efff35ae08d7ece243fcf49b3eee3 +F ext/wasm/api/sqlite3-api-worker1.js cac2f5c63f950f69b5249c9880d4cd385e914c354c459d4096ed5dbb1248de76 F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3 -F ext/wasm/api/sqlite3-opfs-async-proxy.js 9815bd045b638af06350bfe04eaaae17ddf33c3593a9ca2d3f7fdbfd3c6a2205 +F ext/wasm/api/sqlite3-opfs-async-proxy.js 936f57737eb65afc0f4c3494b93f7b02208055226a7b3cb58f551c38b03ab083 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 -F ext/wasm/api/sqlite3-wasm.c 14ac9c03f6585332f882703f3427f11ffe8ffe8b6c0e252be2c518f7aac6ab6a +F ext/wasm/api/sqlite3-wasm.c 41f4c807d5e027d5dd61d507cb0a78d0cee5618220e100860ff4c45ed1bd7c78 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 @@ -522,9 +522,9 @@ F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb0 F ext/wasm/demo-jsstorage.html 409c4be4af5f207fb2877160724b91b33ea36a3cd8c204e8da1acb828ffe588e F ext/wasm/demo-jsstorage.js 44e3ae7ec2483b6c511384c3c290beb6f305c721186bcf5398ca4e00004a06b8 F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98ab22f5786620b3354ed15f -F ext/wasm/demo-worker1-promiser.js 988ce92220c1cf1dd95fcb6b59734f0ae677942469390ddd8a64f4bbb5f99821 +F ext/wasm/demo-worker1-promiser.js b85a2bb1b918db4f09dfa24419241cb3edad7791389425c2505092e9b715017d F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d -F ext/wasm/demo-worker1.js 117e4eedc62e103e287f0e4a694add7e13a200a4d7056e718645032288c4a8ab +F ext/wasm/demo-worker1.js a619adffc98b75b66c633b00f747b856449a134a9a0357909287d80a182d70fa F ext/wasm/dist.make 481289899a07958439d07ee4302ff86235fa0fbb72f17ea05db2be90a94abf90 F ext/wasm/fiddle.make e570ec1bfc7d803507a2e514fe32f673fe001b2114b85c73c3964a462ba8bcfc F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f @@ -549,7 +549,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac F ext/wasm/tester1-worker.html 51bf39e2b87f974ae3d5bc3086e2fb36d258f3698c54f6e21ba4b3b99636fa27 F ext/wasm/tester1.html 624ec41cd9f78a1f2b6d7df70aaa7a6394396b1f2455ecbd6de5775c1275b121 -F ext/wasm/tester1.js 157eb499aad3365e33a7d95d6847c1d58d533335bc19d79bd3bc700b6350d1a5 +F ext/wasm/tester1.js db50ca105d683d1089f540dae4c2baf89a3c101704a05f22cefdcb517587ae8c F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5 F ext/wasm/wasmfs.make fb2d3c4a298b12cf1ec994ad1d0f1d027ae297449b364cde43d2eb807d68048f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -2054,8 +2054,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5bc83d569594e104e90b1acef1a5fd23655b2089de393a6776e799fdef2082f5 -R 9c17a1415bba7769c29ae72a7a64647a -U drh -Z c15361b7db363b8dd30434361c36431b +P 2610779ac84ac4a1a6901b6244653faf0c49ac6f0a4710a19aaf2a13106ae742 +R 54447cdf301faadeadecf9cb178cd6b7 +U stephan +Z 0f92ea26c92634fd686db2350d9751fe # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 14e359d140..4b6ad41d7d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2610779ac84ac4a1a6901b6244653faf0c49ac6f0a4710a19aaf2a13106ae742 \ No newline at end of file +b35e1225c91a3cadc0d25af1e4e790237256d194990faa13190e343ed03e11c5 \ No newline at end of file