]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Minor cleanups and doc improvements in the OPFS sqlite3_vfs proxy.
authorstephan <stephan@noemail.net>
Tue, 25 Oct 2022 08:06:17 +0000 (08:06 +0000)
committerstephan <stephan@noemail.net>
Tue, 25 Oct 2022 08:06:17 +0000 (08:06 +0000)
FossilOrigin-Name: 48645f7bcacf81c4149f26d20ee1752fbe93a02f96b85bd7e28bfa49322137e5

ext/wasm/api/extern-post-js.js
ext/wasm/api/sqlite3-api-opfs.js
ext/wasm/api/sqlite3-opfs-async-proxy.js
manifest
manifest.uuid

index 768696508ea2d756f35868428a15bf6b7fab5988..67b32e891296ab6e910eded5783a19e233010273 100644 (file)
@@ -1,6 +1,9 @@
 /* extern-post-js.js must be appended to the resulting sqlite3.js
-   file. It gets its name from being used as the value for
-   the --extern-post-js=... Emscripten flag. */
+   file. It gets its name from being used as the value for the
+   --extern-post-js=... Emscripten flag. Note that this code, unlike
+   most of the associated JS code, runs outside of the
+   Emscripten-generated module init scope, in the current
+   global scope. */
 (function(){
   /**
      In order to hide the sqlite3InitModule()'s resulting Emscripten
index 9f530245484c61b9a180552fbd0aac0dab2c803c..3f27941e8b9d26f803cabe8e5aea7c5c51e3874d 100644 (file)
   asynchronous Origin-Private FileSystem (OPFS) APIs using a second
   Worker, implemented in sqlite3-opfs-async-proxy.js.  This file is
   intended to be appended to the main sqlite3 JS deliverable somewhere
-  after sqlite3-api-glue.js and before sqlite3-api-cleanup.js.
+  after sqlite3-api-oo1.js and before sqlite3-api-cleanup.js.
 */
 'use strict';
 self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
 /**
-   installOpfsVfs() returns a Promise which, on success, installs
-   an sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
-   which accept a VFS. It uses the Origin-Private FileSystem API for
+   installOpfsVfs() returns a Promise which, on success, installs an
+   sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
+   which accept a VFS. It is intended to be called via
+   sqlite3ApiBootstrap.initializersAsync or an equivalent mechanism.
+
+   The installed VFS uses the Origin-Private FileSystem API for
    all file storage. On error it is rejected with an exception
    explaining the problem. Reasons for rejection include, but are
    not limited to:
@@ -48,31 +51,31 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     proxying OPFS's synchronous API via the synchronous interface
     required by the sqlite3_vfs API.
 
-  - This function may only be called a single time and it must be
-    called from the client, as opposed to the library initialization,
-    in case the client requires a custom path for this API's
-    "counterpart": this function's argument is the relative URI to
-    this module's "asynchronous half". When called, this function removes
-    itself from the sqlite3 object.
+  - This function may only be called a single time. When called, this
+    function removes itself from the sqlite3 object.
+
+  All arguments to this function are for internal/development purposes
+  only. They do not constitute a public API and may change at any
+  time.
 
-   The argument may optionally be a plain object with the following
-   configuration options:
+  The argument may optionally be a plain object with the following
+  configuration options:
 
-   - proxyUri: as described above
+  - proxyUri: as described above
 
-   - verbose (=2): an integer 0-3. 0 disables all logging, 1 enables
-     logging of errors. 2 enables logging of warnings and errors. 3
-     additionally enables debugging info.
+  - verbose (=2): an integer 0-3. 0 disables all logging, 1 enables
+    logging of errors. 2 enables logging of warnings and errors. 3
+    additionally enables debugging info.
 
-   - sanityChecks (=false): if true, some basic sanity tests are
-     run on the OPFS VFS API after it's initialized, before the
-     returned Promise resolves.
+  - sanityChecks (=false): if true, some basic sanity tests are
+    run on the OPFS VFS API after it's initialized, before the
+    returned Promise resolves.
 
-   On success, the Promise resolves to the top-most sqlite3 namespace
-   object and that object gets a new object installed in its
-   `opfs` property, containing several OPFS-specific utilities.
+  On success, the Promise resolves to the top-most sqlite3 namespace
+  object and that object gets a new object installed in its
+  `opfs` property, containing several OPFS-specific utilities.
 */
-const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
+const installOpfsVfs = function callee(options){
   if(!self.SharedArrayBuffer ||
      !self.Atomics ||
      !self.FileSystemHandle ||
@@ -84,9 +87,9 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
       new Error("This environment does not have OPFS support.")
     );
   }
-  const options = (asyncProxyUri && 'object'===asyncProxyUri) ? asyncProxyUri : {
-    proxyUri: asyncProxyUri
-  };
+  if(!options || 'object'!==typeof options){
+    options = Object.create(null);
+  }
   const urlParams = new URL(self.location.href).searchParams;
   if(undefined===options.verbose){
     options.verbose = urlParams.has('opfs-verbose') ? 3 : 2;
@@ -113,7 +116,6 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
     const log =    (...args)=>logImpl(2, ...args);
     const warn =   (...args)=>logImpl(1, ...args);
     const error =  (...args)=>logImpl(0, ...args);
-    //warn("The OPFS VFS feature is very much experimental and under construction.");
     const toss = function(...args){throw new Error(args.join(' '))};
     const capi = sqlite3.capi;
     const wasm = capi.wasm;
@@ -158,9 +160,6 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
         s.count = s.time = 0;
         s = metrics.s11n.deserialize = Object.create(null);
         s.count = s.time = 0;
-        //[ // timed routines which are not in state.opIds
-        //  'xFileControl'
-        //].forEach((k)=>r(metrics[k] = Object.create(null)));
       }
     }/*metrics*/;      
     const promiseReject = function(err){
@@ -223,32 +222,36 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
        cases. We should probably have one SAB here with a single slot
        for locking a per-file initialization step and then allocate a
        separate SAB like the above one for each file. That will
-       require a bit of acrobatics but should be feasible.
+       require a bit of acrobatics but should be feasible. The most
+       problematic part is that xOpen() would have to use
+       postMessage() to communicate its SharedArrayBuffer, and mixing
+       that approach with Atomics.wait/notify() gets a bit messy.
     */
     const state = Object.create(null);
     state.verbose = options.verbose;
     state.littleEndian = (()=>{
       const buffer = new ArrayBuffer(2);
-      new DataView(buffer).setInt16(0, 256, true /* littleEndian */);
+      new DataView(buffer).setInt16(0, 256, true /* ==>littleEndian */);
       // Int16Array uses the platform's endianness.
       return new Int16Array(buffer)[0] === 256;
     })();
-    /** Whether the async counterpart should log exceptions to
-        the serialization channel. That produces a great deal of
-        noise for seemingly innocuous things like xAccess() checks
-        for missing files, so this option may have one of 3 values:
+    /**
+       Whether the async counterpart should log exceptions to
+       the serialization channel. That produces a great deal of
+       noise for seemingly innocuous things like xAccess() checks
+       for missing files, so this option may have one of 3 values:
 
-        0 = no exception logging
+       0 = no exception logging
 
-        1 = only log exceptions for "significant" ops like xOpen(),
-        xRead(), and xWrite().
+       1 = only log exceptions for "significant" ops like xOpen(),
+       xRead(), and xWrite().
 
-        2 = log all exceptions.
+       2 = log all exceptions.
     */
     state.asyncS11nExceptions = 1;
-    /* Size of file I/O buffer block. 64k = max sqlite3 page size. */
-    state.fileBufferSize =
-      1024 * 64;
+    /* Size of file I/O buffer block. 64k = max sqlite3 page size, and
+       xRead/xWrite() will never deal in blocks larger than that. */
+    state.fileBufferSize = 1024 * 64;
     state.sabS11nOffset = state.fileBufferSize;
     /**
        The size of the block in our SAB for serializing arguments and
@@ -258,7 +261,8 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
     */
     state.sabS11nSize = opfsVfs.$mxPathname * 2;
     /**
-       The SAB used for all data I/O (files and arg/result s11n).
+       The SAB used for all data I/O between the synchronous and
+       async halves (file i/o and arg/result s11n).
     */
     state.sabIO = new SharedArrayBuffer(
       state.fileBufferSize/* file i/o block */
@@ -297,7 +301,13 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
       state.opIds.mkdir = i++;
       state.opIds['opfs-async-metrics'] = i++;
       state.opIds['opfs-async-shutdown'] = i++;
-      state.sabOP = new SharedArrayBuffer(i * 4/*sizeof int32*/);
+      /* The retry slot is used by the async part for wait-and-retry
+         semantics. Though we could hypothetically use the xSleep slot
+         for that, doing so might lead to undesired side effects. */
+      state.opIds.retry = i++;
+      state.sabOP = new SharedArrayBuffer(
+        i * 4/* ==sizeof int32, noting that Atomics.wait() and friends
+                can only function on Int32Array views of an SAB. */);
       opfsUtil.metrics.reset();
     }
     /**
@@ -338,9 +348,12 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
       state.s11n.serialize(...args);
       Atomics.store(state.sabOPView, state.opIds.rc, -1);
       Atomics.store(state.sabOPView, state.opIds.whichOp, opNdx);
-      Atomics.notify(state.sabOPView, state.opIds.whichOp) /* async thread will take over here */;
+      Atomics.notify(state.sabOPView, state.opIds.whichOp)
+      /* async thread will take over here */;
       const t = performance.now();
-      Atomics.wait(state.sabOPView, state.opIds.rc, -1);
+      Atomics.wait(state.sabOPView, state.opIds.rc, -1)
+      /* When this wait() call returns, the async half will have
+         completed the operation and reported its results. */;
       const rc = Atomics.load(state.sabOPView, state.opIds.rc);
       metrics[op].wait += performance.now() - t;
       if(rc && state.asyncS11nExceptions){
@@ -352,17 +365,22 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
 
     const initS11n = ()=>{
       /**
-         ACHTUNG: this code is 100% duplicated in the other half of this
-         proxy! The documentation is maintained in the "synchronous half".
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+         ACHTUNG: this code is 100% duplicated in the other half of
+         this proxy! The documentation is maintained in the
+         "synchronous half".
+         !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
          This proxy de/serializes cross-thread function arguments and
          output-pointer values via the state.sabIO SharedArrayBuffer,
          using the region defined by (state.sabS11nOffset,
          state.sabS11nOffset]. Only one dataset is recorded at a time.
 
-         This is not a general-purpose format. It only supports the range
-         of operations, and data sizes, needed by the sqlite3_vfs and
-         sqlite3_io_methods operations.
+         This is not a general-purpose format. It only supports the
+         range of operations, and data sizes, needed by the
+         sqlite3_vfs and sqlite3_io_methods operations. Serialized
+         data are transient and this serialization algorithm may
+         change at any time.
 
          The data format can be succinctly summarized as:
 
@@ -386,7 +404,8 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
          using their TextEncoder/TextDecoder representations. It would
          arguably make more sense to store them as Int16Arrays of
          their JS character values, but how best/fastest to get that
-         in and out of string form us an open point.
+         in and out of string form is an open point. Initial
+         experimentation with that approach did not gain us any speed.
 
          Historical note: this impl was initially about 1% this size by
          using using JSON.stringify/parse(), but using fit-to-purpose
@@ -583,9 +602,11 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
         toss("Member",name," is not a function pointer. Signature =",sigN);
       }
       const memKey = tgt.memberKey(name);
-      //log("installMethod",tgt, name, sigN);
       const fProxy = 0
-      // We can remove this proxy middle-man once the VFS is working
+      /** This middle-man proxy is only for use during development, to
+          confirm that we always pass the proper number of
+          arguments. We know that the C-level code will always use the
+          correct argument count. */
             ? callee.argcProxy(func, sigN)
             : func;
       const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name, true));
@@ -606,7 +627,6 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
     const mTimeStart = (op)=>{
       opTimer.start = performance.now();
       opTimer.op = op;
-      //metrics[op] || toss("Maintenance required: missing metrics for",op);
       ++metrics[op].count;
     };
     const mTimeEnd = ()=>(
@@ -619,8 +639,15 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
     */
     const ioSyncWrappers = {
       xCheckReservedLock: function(pFile,pOut){
-        // Exclusive lock is automatically acquired when opened
-        //warn("xCheckReservedLock(",arguments,") is a no-op");
+        /**
+           As of late 2022, only a single lock can be held on an OPFS
+           file. We have no way of checking whether any _other_ db
+           connection has a lock except by trying to obtain and (on
+           success) release a sync-handle for it, but doing so would
+           involve an inherent race condition. For the time being,
+           pending a better solution, we simply report whether the
+           given pFile instance has a lock.
+        */
         const f = __openFiles[pFile];
         wasm.setMemValue(pOut, f.lockMode ? 1 : 0, 'i32');
         return 0;
@@ -673,14 +700,17 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
         return rc;
       },
       xRead: function(pFile,pDest,n,offset64){
-        /* int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst) */
         mTimeStart('xRead');
         const f = __openFiles[pFile];
         let rc;
         try {
           rc = opRun('xRead',pFile, n, Number(offset64));
-          if(0===rc || capi.SQLITE_IOERR_SHORT_READ===rc){
-            // set() seems to be the fastest way to copy this...
+          if(0===rc || capi.SQLITE_IOERR_SHORT_READ===rc){ 
+            /**
+               Results get written to the SharedArrayBuffer f.sabView.
+               Because the heap is _not_ a SharedArrayBuffer, we have
+               to copy the results. TypedArray.set() seems to be the
+               fastest way to copy this. */
             wasm.heap8u().set(f.sabView.subarray(0, n), pDest);
           }
         }catch(e){
@@ -713,7 +743,6 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
         return rc;
       },
       xWrite: function(pFile,pSrc,n,offset64){
-        /* int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst) */
         mTimeStart('xWrite');
         const f = __openFiles[pFile];
         let rc;
@@ -779,28 +808,6 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
       //xSleep is optionally defined below
       xOpen: function f(pVfs, zName, pFile, flags, pOutFlags){
         mTimeStart('xOpen');
-        if(!f._){
-          f._ = {
-            fileTypes: {
-              SQLITE_OPEN_MAIN_DB: 'mainDb',
-              SQLITE_OPEN_MAIN_JOURNAL: 'mainJournal',
-              SQLITE_OPEN_TEMP_DB: 'tempDb',
-              SQLITE_OPEN_TEMP_JOURNAL: 'tempJournal',
-              SQLITE_OPEN_TRANSIENT_DB: 'transientDb',
-              SQLITE_OPEN_SUBJOURNAL: 'subjournal',
-              SQLITE_OPEN_SUPER_JOURNAL: 'superJournal',
-              SQLITE_OPEN_WAL: 'wal'
-            },
-            getFileType: function(filename,oflags){
-              const ft = f._.fileTypes;
-              for(let k of Object.keys(ft)){
-                if(oflags & capi[k]) return ft[k];
-              }
-              warn("Cannot determine fileType based on xOpen() flags for file",filename);
-              return '???';
-            }
-          };
-        }
         if(0===zName){
           zName = randomFilename();
         }else if('number'===typeof zName){
@@ -1084,16 +1091,13 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
             promiseReject(e);
             error("Unexpected message from the async worker:",data);
             break;
-      }
-    };
-
+      }/*switch(data.type)*/
+    }/*W.onmessage()*/;
   })/*thePromise*/;
   return thePromise;
 }/*installOpfsVfs()*/;
 installOpfsVfs.defaultProxyUri =
-    //self.location.pathname.replace(/[^/]*$/, "sqlite3-opfs-async-proxy.js");
   "sqlite3-opfs-async-proxy.js";
-//console.warn("sqlite3.installOpfsVfs.defaultProxyUri =",sqlite3.installOpfsVfs.defaultProxyUri);
 self.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
   if(sqlite3.scriptInfo && !sqlite3.scriptInfo.isWorker){
     return;
index 5b29aa3ea50979eccd004ac7e8663d2169c23e3d..254da7ee5d4bc0a2eba7540b9142beca6bf7d91b 100644 (file)
@@ -10,7 +10,7 @@
 
   ***********************************************************************
 
-  An Worker which manages asynchronous OPFS handles on behalf of a
+  A Worker which manages asynchronous OPFS handles on behalf of a
   synchronous API which controls it via a combination of Worker
   messages, SharedArrayBuffer, and Atomics. It is the asynchronous
   counterpart of the API defined in sqlite3-api-opfs.js.
   access to the sqlite3 JS/WASM bits, so any bits which it needs (most
   notably SQLITE_xxx integer codes) have to be imported into it via an
   initialization process.
+
+  This file represents an implementation detail of a larger piece of
+  code, and not a public interface. Its details may change at any time
+  and are not intended to be used by any client-level code.
 */
-'use strict';
+"use strict";
 const toss = function(...args){throw new Error(args.join(' '))};
 if(self.window === self){
   toss("This code cannot run from the main thread.",
@@ -133,8 +137,8 @@ const getDirForFilename = async function f(absFilename, createDirs = false){
 
 /**
    Returns the sync access handle associated with the given file
-   handle object (which must be a valid handle object), lazily opening
-   it if needed.
+   handle object (which must be a valid handle object, as created by
+   xOpen()), lazily opening it if needed.
 
    In order to help alleviate cross-tab contention for a dabase,
    if an exception is thrown while acquiring the handle, this routine
@@ -150,7 +154,7 @@ const getSyncHandle = async (fh)=>{
     let i = 1, ms = 300;
     for(; true; ms *= ++i){
       try {
-        //if(1===i) toss("Just testing.");
+        //if(i<3) toss("Just testing.");
         //TODO? A config option which tells it to throw here
         //randomly every now and then, for testing purposes.
         fh.syncHandle = await fh.fileHandle.createSyncAccessHandle();
@@ -163,7 +167,7 @@ const getSyncHandle = async (fh)=>{
         }
         warn("Error getting sync handle. Waiting",ms,
               "ms and trying again.",fh.filenameAbs,e);
-        Atomics.wait(state.sabOPView, state.opIds.xSleep, 0, ms);
+        Atomics.wait(state.sabOPView, state.opIds.retry, 0, ms);
       }
     }
     log("Got sync handle for",fh.filenameAbs,'in',performance.now() - t,'ms');
@@ -305,7 +309,7 @@ const vfsAsyncImpls = {
     storeAndNotify('xAccess', rc);
     mTimeEnd();
   },
-  xClose: async function(fid){
+  xClose: async function(fid/*sqlite3_file pointer*/){
     const opName = 'xClose';
     mTimeStart(opName);
     const fh = __openFiles[fid];
@@ -364,7 +368,7 @@ const vfsAsyncImpls = {
     wTimeEnd();
     return rc;
   },
-  xFileSize: async function(fid){
+  xFileSize: async function(fid/*sqlite3_file pointer*/){
     mTimeStart('xFileSize');
     const fh = __openFiles[fid];
     let sz;
@@ -381,7 +385,8 @@ const vfsAsyncImpls = {
     storeAndNotify('xFileSize', sz);
     mTimeEnd();
   },
-  xLock: async function(fid,lockType){
+  xLock: async function(fid/*sqlite3_file pointer*/,
+                        lockType/*SQLITE_LOCK_...*/){
     mTimeStart('xLock');
     const fh = __openFiles[fid];
     let rc = 0;
@@ -397,7 +402,8 @@ const vfsAsyncImpls = {
     storeAndNotify('xLock',rc);
     mTimeEnd();
   },
-  xOpen: async function(fid/*sqlite3_file pointer*/, filename, flags){
+  xOpen: async function(fid/*sqlite3_file pointer*/, filename,
+                        flags/*SQLITE_OPEN_...*/){
     const opName = 'xOpen';
     mTimeStart(opName);
     const deleteOnClose = (state.sq3Codes.SQLITE_OPEN_DELETEONCLOSE & flags);
@@ -440,7 +446,7 @@ const vfsAsyncImpls = {
     }
     mTimeEnd();
   },
-  xRead: async function(fid,n,offset){
+  xRead: async function(fid/*sqlite3_file pointer*/,n,offset64){
     mTimeStart('xRead');
     let rc = 0, nRead;
     const fh = __openFiles[fid];
@@ -448,7 +454,7 @@ const vfsAsyncImpls = {
       wTimeStart('xRead');
       nRead = (await getSyncHandle(fh)).read(
         fh.sabView.subarray(0, n),
-        {at: Number(offset)}
+        {at: Number(offset64)}
       );
       wTimeEnd();
       if(nRead < n){/* Zero-fill remaining bytes */
@@ -464,7 +470,7 @@ const vfsAsyncImpls = {
     storeAndNotify('xRead',rc);
     mTimeEnd();
   },
-  xSync: async function(fid,flags/*ignored*/){
+  xSync: async function(fid/*sqlite3_file pointer*/,flags/*ignored*/){
     mTimeStart('xSync');
     const fh = __openFiles[fid];
     let rc = 0;
@@ -480,7 +486,7 @@ const vfsAsyncImpls = {
     storeAndNotify('xSync',rc);
     mTimeEnd();
   },
-  xTruncate: async function(fid,size){
+  xTruncate: async function(fid/*sqlite3_file pointer*/,size){
     mTimeStart('xTruncate');
     let rc = 0;
     const fh = __openFiles[fid];
@@ -497,7 +503,8 @@ const vfsAsyncImpls = {
     storeAndNotify('xTruncate',rc);
     mTimeEnd();
   },
-  xUnlock: async function(fid,lockType){
+  xUnlock: async function(fid/*sqlite3_file pointer*/,
+                          lockType/*SQLITE_LOCK_...*/){
     mTimeStart('xUnlock');
     let rc = 0;
     const fh = __openFiles[fid];
@@ -514,7 +521,7 @@ const vfsAsyncImpls = {
     storeAndNotify('xUnlock',rc);
     mTimeEnd();
   },
-  xWrite: async function(fid,n,offset){
+  xWrite: async function(fid/*sqlite3_file pointer*/,n,offset64){
     mTimeStart('xWrite');
     let rc;
     wTimeStart('xWrite');
@@ -524,7 +531,7 @@ const vfsAsyncImpls = {
       rc = (
         n === (await getSyncHandle(fh))
           .write(fh.sabView.subarray(0, n),
-                 {at: Number(offset)})
+                 {at: Number(offset64)})
       ) ? 0 : state.sq3Codes.SQLITE_IOERR_WRITE;
     }catch(e){
       error("xWrite():",e,fh);
index bf748e6b596ab4ad1c791c023055b0354d130194..a762413d2d35f894d218b9f1f6f7a3517058bd5f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\stypo\sin\scomment.
-D 2022-10-24T18:42:45.118
+C Minor\scleanups\sand\sdoc\simprovements\sin\sthe\sOPFS\ssqlite3_vfs\sproxy.
+D 2022-10-25T08:06:17.330
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -478,7 +478,7 @@ F ext/wasm/README.md 1e5b28158b74ab3ffc9d54fcbc020f0bbeb82c2ff8bbd904214c86c70e8
 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/extern-post-js.js 926d192b72fa808378e5e7843721dc7ba3908c163a0260e06d8aa501c12f5469
 F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
 F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1
 F ext/wasm/api/post-js-header.js 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b
@@ -486,11 +486,11 @@ F ext/wasm/api/pre-js.js 151e0616614a49f3db19ed544fa13b38c87c108959fbcd4029ea839
 F ext/wasm/api/sqlite3-api-cleanup.js 4d07a7524dc9b7b050acfde57163e839243ad2383bd7ee0de0178b1b3e988588
 F ext/wasm/api/sqlite3-api-glue.js 6e4e472eb5afc732a695cd7c5ded6dee6ef8b480e61aa0d648a3fc9033c84745
 F ext/wasm/api/sqlite3-api-oo1.js ca41ffe58bfbbefc98181081fba0b7af58afcc2770e963558f4f6a408c583fc0
-F ext/wasm/api/sqlite3-api-opfs.js 22d60ba956e873b65e2e0591e239178082bd53a6d563c3c58db7dc03e562e8f7
+F ext/wasm/api/sqlite3-api-opfs.js 62da8b7cac30d4e7bb940762d2ac948b0aeb89704a5a290b74eb268ecbd1a64e
 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/api/sqlite3-opfs-async-proxy.js f04cb1eb483c92bc61fe02749f7afcf17ec803968171aedd7d96faf428c26bcb
 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
 F ext/wasm/api/sqlite3-wasm.c 940d576bda7068ba60492e206d06a3567b8a89a3770700aa88690a6e246a0c78
 F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b
@@ -2037,8 +2037,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 69d704224e9ed022fcec591beff2ffcc4daf3e7fc586debfdcf00b25c1fddd87
-R e2a88fcf6a9d4446fa629ea861bc8ca4
-U drh
-Z ea85a8ca90f8837e6e02f1969966b7f9
+P f65c95658fe4d30817da8de7eb88e823ea1cd8be40e347d626870bad3cc13359
+R 18bf727aa37df31466f2ea66a532842e
+U stephan
+Z 9cf62ee935cac4cb5c613433da7a1983
 # Remove this line to create a well-formed Fossil manifest.
index c85389d8a26709724bd01b28c2773e143e15bbc8..125f873da6b062a6cb243a4e46bfb93dfadb6a38 100644 (file)
@@ -1 +1 @@
-f65c95658fe4d30817da8de7eb88e823ea1cd8be40e347d626870bad3cc13359
\ No newline at end of file
+48645f7bcacf81c4149f26d20ee1752fbe93a02f96b85bd7e28bfa49322137e5
\ No newline at end of file