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

Refactor JS API amalgamation such that the bootstrapping/configuration is deferred until the whole amalgamation is available, to facilitate providing clients with a way to initialize the API with their own config (noting that we're still one small level of refactoring away from being able to actually do that).

FossilOrigin-Name: 9dbe9a6aecec43b51057375ef1d2d632db0d17eac8b7552c20cc91fc2f1a55d1
This commit is contained in:
stephan
2022-08-22 13:34:13 +00:00
parent 64d04a8d9f
commit e3cd67603d
9 changed files with 206 additions and 107 deletions

View File

@ -16,29 +16,45 @@
various subsystems. various subsystems.
*/ */
'use strict'; 'use strict';
self.sqlite3.postInit.forEach( (function(){
self.importScripts/*global is a Worker*/ /**
? function(f){ Replace sqlite3ApiBootstrap() with a variant which plugs in the
/** We try/catch/report for the sake of failures which happen in Emscripten-based config for all config options which the client
a Worker, as those exceptions can otherwise get completely does not provide.
swallowed, leading to confusing downstream errors which have */
nothing to do with this failure. */ const SAB = self.sqlite3ApiBootstrap;
try{ f(self, self.sqlite3) } self.sqlite3ApiBootstrap = function(apiConfig){
catch(e){ apiConfig = apiConfig||{};
console.error("Error in postInit() function:",e); const configDefaults = {
throw e; Module: Module /* ==> Emscripten-style Module object. Currently
} needs to be exposed here for test code. NOT part
} of the public API. */,
: (f)=>f(self, self.sqlite3) exports: Module['asm'],
); memory: Module.wasmMemory /* gets set if built with -sIMPORT_MEMORY */
delete self.sqlite3.postInit; };
if(self.location && +self.location.port > 1024){ const config = {};
Object.keys(configDefaults).forEach(function(k){
config[k] = Object.prototype.hasOwnProperty.call(apiConfig, k)
? apiConfig[k] : configDefaults[k];
});
return SAB(config);
};
/**
For current (2022-08-22) purposes, automatically call sqlite3ApiBootstrap().
That decision will be revisited at some point, as we really want client code
to be able to call this to configure certain parts.
*/
const sqlite3 = self.sqlite3ApiBootstrap();
if(self.location && +self.location.port > 1024){
console.warn("Installing sqlite3 bits as global S for dev-testing purposes."); console.warn("Installing sqlite3 bits as global S for dev-testing purposes.");
self.S = self.sqlite3; self.S = sqlite3;
} }
/* Clean up temporary global-scope references to our APIs... */
self.sqlite3.config.Module.sqlite3 = self.sqlite3 /* Clean up temporary references to our APIs... */
/* ^^^^ Currently needed by test code and Worker API setup */; delete self.sqlite3ApiBootstrap;
delete self.sqlite3.capi.util /* arguable, but these are (currently) internal-use APIs */; Module.sqlite3 = sqlite3 /* Currently needed by test code */;
delete self.sqlite3 /* clean up our global-scope reference */; delete sqlite3.capi.util /* arguable, but these are (currently) internal-use APIs */;
//console.warn("Module.sqlite3 =",Module.sqlite3); //console.warn("Module.sqlite3 =",Module.sqlite3);
})();

View File

@ -16,23 +16,9 @@
initializes the main API pieces so that the downstream components initializes the main API pieces so that the downstream components
(e.g. sqlite3-api-oo1.js) have all that they need. (e.g. sqlite3-api-oo1.js) have all that they need.
*/ */
(function(self){ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
'use strict'; 'use strict';
const toss = (...args)=>{throw new Error(args.join(' '))}; const toss = (...args)=>{throw new Error(args.join(' '))};
self.sqlite3 = self.sqlite3ApiBootstrap({
Module: Module /* ==> Emscripten-style Module object. Currently
needs to be exposed here for test code. NOT part
of the public API. */,
exports: Module['asm'],
memory: Module.wasmMemory /* gets set if built with -sIMPORT_MEMORY */,
bigIntEnabled: !!self.BigInt64Array,
allocExportName: 'malloc',
deallocExportName: 'free'
});
delete self.sqlite3ApiBootstrap;
const sqlite3 = self.sqlite3;
const capi = sqlite3.capi, wasm = capi.wasm, util = capi.util; const capi = sqlite3.capi, wasm = capi.wasm, util = capi.util;
self.WhWasmUtilInstaller(capi.wasm); self.WhWasmUtilInstaller(capi.wasm);
delete self.WhWasmUtilInstaller; delete self.WhWasmUtilInstaller;
@ -57,7 +43,7 @@
return oldP(v); return oldP(v);
}; };
wasm.xWrap.argAdapter('.pointer', adapter); wasm.xWrap.argAdapter('.pointer', adapter);
} } /* ".pointer" xWrap() argument adapter */
// WhWasmUtil.xWrap() bindings... // WhWasmUtil.xWrap() bindings...
{ {
@ -78,7 +64,7 @@
capi[e[0]] = wasm.xWrap.apply(null, e); capi[e[0]] = wasm.xWrap.apply(null, e);
} }
/* For functions which cannot work properly unless /* For C API functions which cannot work properly unless
wasm.bigIntEnabled is true, install a bogus impl which wasm.bigIntEnabled is true, install a bogus impl which
throws if called when bigIntEnabled is false. */ throws if called when bigIntEnabled is false. */
const fI64Disabled = function(fname){ const fI64Disabled = function(fname){
@ -198,5 +184,4 @@
capi[s.name] = sqlite3.StructBinder(s); capi[s.name] = sqlite3.StructBinder(s);
} }
} }
});
})(self);

View File

@ -14,10 +14,9 @@
WASM build. It requires that sqlite3-api-glue.js has already run WASM build. It requires that sqlite3-api-glue.js has already run
and it installs its deliverable as self.sqlite3.oo1. and it installs its deliverable as self.sqlite3.oo1.
*/ */
(function(self){ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
const toss = (...args)=>{throw new Error(args.join(' '))}; const toss = (...args)=>{throw new Error(args.join(' '))};
const sqlite3 = self.sqlite3 || toss("Missing main sqlite3 object.");
const capi = sqlite3.capi, util = capi.util; const capi = sqlite3.capi, util = capi.util;
/* What follows is colloquially known as "OO API #1". It is a /* What follows is colloquially known as "OO API #1". It is a
binding of the sqlite3 API which is designed to be run within binding of the sqlite3 API which is designed to be run within
@ -1547,5 +1546,6 @@
}, },
DB, DB,
Stmt Stmt
}/*SQLite3 object*/; }/*oo1 object*/;
})(self); });

View File

@ -31,12 +31,13 @@
// FileSystemDirectoryHandle // FileSystemDirectoryHandle
// FileSystemFileHandle // FileSystemFileHandle
// FileSystemFileHandle.prototype.createSyncAccessHandle // FileSystemFileHandle.prototype.createSyncAccessHandle
self.sqlite3.postInit.push(function(self, sqlite3){ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
const warn = console.warn.bind(console), const warn = console.warn.bind(console),
error = console.error.bind(console); error = console.error.bind(console);
if(!self.importScripts || !self.FileSystemFileHandle if(!self.importScripts || !self.FileSystemFileHandle){
|| !self.FileSystemFileHandle.prototype.createSyncAccessHandle){ //|| !self.FileSystemFileHandle.prototype.createSyncAccessHandle){
warn("OPFS not found or its sync API is not available in this environment."); // ^^^ sync API is not required with WASMFS/OPFS backend.
warn("OPFS is not available in this environment.");
return; return;
}else if(!sqlite3.capi.wasm.bigIntEnabled){ }else if(!sqlite3.capi.wasm.bigIntEnabled){
error("OPFS requires BigInt support but sqlite3.capi.wasm.bigIntEnabled is false."); error("OPFS requires BigInt support but sqlite3.capi.wasm.bigIntEnabled is false.");

View File

@ -78,25 +78,88 @@
*/ */
/** /**
This global symbol is is only a temporary measure: the JS-side sqlite3ApiBootstrap() is the only global symbol exposed by this
post-processing will remove that object from the global scope when API. It is intended to be called one time at the end of the API
setup is complete. We require it there temporarily in order to glue amalgamation process, passed configuration details for the current
disparate parts together during the loading of the API (which spans environment, and then optionally be removed from the global object
several components). using `delete self.sqlite3ApiBootstrap`.
This function requires a configuration object intended to abstract This function expects a configuration object, intended to abstract
away details specific to any given WASM environment, primarily so away details specific to any given WASM environment, primarily so
that it can be used without any _direct_ dependency on Emscripten. that it can be used without any _direct_ dependency on
(That said, OO API #1 requires, as of this writing, Emscripten's Emscripten. The config object is only honored the first time this
virtual filesystem API. Baby steps.) is called. Subsequent calls ignore the argument and return the same
(configured) object which gets initialized by the first call.
The config object properties include:
- `Module`: Emscripten-style module object. Currently only required
by certain test code and is _not_ part of the public interface.
(TODO: rename this to EmscriptenModule to be more explicit.)
- `exports`: the "exports" object for the current WASM
environment. In an Emscripten build, this should be set to
`Module['asm']`.
- `memory`: optional WebAssembly.Memory object, defaulting to
`exports.memory`. In Emscripten environments this should be set
to `Module.wasmMemory` if the build uses `-sIMPORT_MEMORY`, or be
left undefined/falsy to default to `exports.memory` when using
WASM-exported memory.
- `bigIntEnabled`: true if BigInt support is enabled. Defaults to
true if self.BigInt64Array is available, else false. Some APIs
will throw exceptions if called without BigInt support, as BigInt
is required for marshalling C-side int64 into and out of JS.
- `allocExportName`: the name of the function, in `exports`, of the
`malloc(3)`-compatible routine for the WASM environment. Defaults
to `"malloc"`.
- `deallocExportName`: the name of the function, in `exports`, of
the `free(3)`-compatible routine for the WASM
environment. Defaults to `"free"`.
- `persistentDirName`: if the environment supports persistent storage, this
directory names the "mount point" for that directory. It must be prefixed
by `/` and may currently contain only a single directory-name part. Using
the root directory name is not supported by any current persistent backend.
*/ */
self.sqlite3ApiBootstrap = function(config){ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(apiConfig){
'use strict'; 'use strict';
if(sqlite3ApiBootstrap.sqlite3){ /* already initalized */
console.warn("sqlite3ApiBootstrap() called multiple times.",
"Config and external initializers are ignored on calls after the first.");
return sqlite3ApiBootstrap.sqlite3;
}
apiConfig = apiConfig||{};
const config = Object.create(null);
{
const configDefaults = {
Module: undefined/*needed for some test code, not part of the public API*/,
exports: undefined,
memory: undefined,
bigIntEnabled: !!self.BigInt64Array,
allocExportName: 'malloc',
deallocExportName: 'free',
persistentDirName: '/persistent'
};
Object.keys(configDefaults).forEach(function(k){
config[k] = Object.prototype.hasOwnProperty.call(apiConfig, k)
? apiConfig[k] : configDefaults[k];
});
}
/** Throws a new Error, the message of which is the concatenation /** Throws a new Error, the message of which is the concatenation
all args with a space between each. */ all args with a space between each. */
const toss = (...args)=>{throw new Error(args.join(' '))}; const toss = (...args)=>{throw new Error(args.join(' '))};
if(config.persistentDirName && !/^\/[^/]+$/.test(config.persistentDirName)){
toss("config.persistentDirName must be falsy or in the form '/dir-name'.");
}
/** /**
Returns true if n is a 32-bit (signed) integer, else Returns true if n is a 32-bit (signed) integer, else
false. This is used for determining when we need to switch to false. This is used for determining when we need to switch to
@ -143,7 +206,18 @@ self.sqlite3ApiBootstrap = function(config){
}; };
const utf8Decoder = new TextDecoder('utf-8'); const utf8Decoder = new TextDecoder('utf-8');
const typedArrayToString = (str)=>utf8Decoder.decode(str);
/** Internal helper to use in operations which need to distinguish
between SharedArrayBuffer heap memory and non-shared heap. */
const __SAB = ('undefined'===typeof SharedArrayBuffer)
? function(){} : SharedArrayBuffer;
const typedArrayToString = function(arrayBuffer, begin, end){
return utf8Decoder.decode(
(arrayBuffer.buffer instanceof __SAB)
? arrayBuffer.slice(begin, end)
: arrayBuffer.subarray(begin, end)
);
};
/** /**
An Error subclass specifically for reporting Wasm-level malloc() An Error subclass specifically for reporting Wasm-level malloc()
@ -591,9 +665,6 @@ self.sqlite3ApiBootstrap = function(config){
TODOs and caveats: TODOs and caveats:
- The directory name (mount point) for persistent storage is
currently hard-coded. It needs to be configurable.
- If persistent storage is available at the root of the virtual - If persistent storage is available at the root of the virtual
filesystem, this interface cannot currently distinguish that filesystem, this interface cannot currently distinguish that
from the lack of persistence. That case cannot currently (with from the lack of persistence. That case cannot currently (with
@ -604,12 +675,17 @@ self.sqlite3ApiBootstrap = function(config){
capi.sqlite3_web_persistent_dir = function(){ capi.sqlite3_web_persistent_dir = function(){
if(undefined !== __persistentDir) return __persistentDir; if(undefined !== __persistentDir) return __persistentDir;
// If we have no OPFS, there is no persistent dir // If we have no OPFS, there is no persistent dir
if(!self.FileSystemHandle || !self.FileSystemDirectoryHandle const pdir = config.persistentDirName;
if(!pdir
|| !self.FileSystemHandle
|| !self.FileSystemDirectoryHandle
|| !self.FileSystemFileHandle){ || !self.FileSystemFileHandle){
return __persistentDir = ""; return __persistentDir = "";
} }
try{ try{
if(0===this.wasm.xCall('sqlite3_wasm_init_opfs')){ if(pdir && 0===this.wasm.xCallWrapped(
'sqlite3_wasm_init_opfs', 'i32', ['string'], pdir
)){
/** OPFS does not support locking and will trigger errors if /** OPFS does not support locking and will trigger errors if
we try to lock. We don't _really_ want to we try to lock. We don't _really_ want to
_unconditionally_ install a non-locking sqlite3 VFS as the _unconditionally_ install a non-locking sqlite3 VFS as the
@ -617,13 +693,12 @@ self.sqlite3ApiBootstrap = function(config){
time being. That said: locking is a no-op on all of the time being. That said: locking is a no-op on all of the
current WASM storage, so this isn't (currently) as bad as current WASM storage, so this isn't (currently) as bad as
it may initially seem. */ it may initially seem. */
const pVfs = this.sqlite3_vfs_find("unix-none"); const pVfs = sqlite3.capi.sqlite3_vfs_find("unix-none");
if(pVfs){ if(pVfs){
this.sqlite3_vfs_register(pVfs,1); capi.sqlite3_vfs_register(pVfs,1);
//warn("Installed 'unix-none' as the default sqlite3 VFS."); console.warn("Installed 'unix-none' as the default sqlite3 VFS.");
} }
return __persistentDir = return __persistentDir = pdir;
"/persistent" /* name is hard-coded in sqlite3_wasm_init_opfs()!*/;
}else{ }else{
return __persistentDir = ""; return __persistentDir = "";
} }
@ -644,19 +719,29 @@ self.sqlite3ApiBootstrap = function(config){
}.bind(capi); }.bind(capi);
/* The remainder of the API will be set up in later steps. */ /* The remainder of the API will be set up in later steps. */
return { const sqlite3 = {
/**
An Error subclass which is thrown by this.wasm.alloc() on OOM.
*/
WasmAllocError: WasmAllocError, WasmAllocError: WasmAllocError,
capi, capi,
postInit: [
/* some pieces of the API may install functions into this array,
and each such function will be called, passed (self,sqlite3),
at the very end of the API load/init process, where self is
the current global object and sqlite3 is the object returned
from sqlite3ApiBootstrap(). This array will be removed at the
end of the API setup process. */],
config config
}; };
sqlite3ApiBootstrap.initializers.forEach((f)=>f(sqlite3));
delete sqlite3ApiBootstrap.initializers;
sqlite3ApiBootstrap.sqlite3 = sqlite3;
return sqlite3;
}/*sqlite3ApiBootstrap()*/; }/*sqlite3ApiBootstrap()*/;
/**
self.sqlite3ApiBootstrap.initializers is an internal detail used by
the various pieces of the sqlite3 API's amalgamation process. It
must not be modified by client code except when plugging such code
into the amalgamation process.
Each component of the amalgamation is expected to append a function
to this array. When sqlite3ApiBootstrap() is called for the first
time, each such function will be called (in their appended order)
and passed the sqlite3 namespace object, into which they can install
their features (noting that most will also require that certain
features alread have been installed). At the end of that process,
this array is deleted.
*/
self.sqlite3ApiBootstrap.initializers = [];
self.sqlite3ApiBootstrap.sqlite3 = undefined /* installed at first call */;

View File

@ -43,7 +43,8 @@
In some contexts, however, listening for the above message is In some contexts, however, listening for the above message is
a better fit. a better fit.
*/ */
self.sqlite3.initWorker1API = function(){ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
sqlite3.initWorker1API = function(){
'use strict'; 'use strict';
/** /**
UNDER CONSTRUCTION UNDER CONSTRUCTION
@ -418,4 +419,6 @@ self.sqlite3.initWorker1API = function(){
wState.post(evType, response, wMsgHandler.xfer); wState.post(evType, response, wMsgHandler.xfer);
}; };
setTimeout(()=>self.postMessage({type:'sqlite3-api',data:'worker1-ready'}), 0); setTimeout(()=>self.postMessage({type:'sqlite3-api',data:'worker1-ready'}), 0);
}.bind({self, sqlite3: self.sqlite3}); }.bind({self, sqlite3});
});

View File

@ -435,7 +435,8 @@ int sqlite3_wasm_vfs_unlink(const char * zName){
#include <emscripten/console.h> #include <emscripten/console.h>
/* /*
** This function is NOT part of the sqlite3 public API. It is strictly ** This function is NOT part of the sqlite3 public API. It is strictly
** for use by the sqlite project's own JS/WASM bindings. ** for use by the sqlite project's own JS/WASM bindings, specifically
** only when building with Emscripten's WASMFS support.
** **
** This function should only be called if the JS side detects the ** This function should only be called if the JS side detects the
** existence of the Origin-Private FileSystem (OPFS) APIs in the ** existence of the Origin-Private FileSystem (OPFS) APIs in the
@ -443,14 +444,19 @@ int sqlite3_wasm_vfs_unlink(const char * zName){
** WASMFS backend impl for OPFS. On success, subsequent calls are ** WASMFS backend impl for OPFS. On success, subsequent calls are
** no-ops. ** no-ops.
** **
** This function may be passed a "mount point" name, which must have a
** leading "/" and is currently restricted to a single path component,
** e.g. "/foo" is legal but "/foo/" and "/foo/bar" are not. If it is
** NULL or empty, it defaults to "/persistent".
**
** Returns 0 on success, SQLITE_NOMEM if instantiation of the backend ** Returns 0 on success, SQLITE_NOMEM if instantiation of the backend
** object fails, SQLITE_IOERR if mkdir() of the "/persistent" dir in ** object fails, SQLITE_IOERR if mkdir() of the zMountPoint dir in
** the virtual FS fails. In builds compiled without SQLITE_WASM_OPFS ** the virtual FS fails. In builds compiled without SQLITE_WASM_OPFS
** defined, SQLITE_NOTFOUND is returned without side effects. ** defined, SQLITE_NOTFOUND is returned without side effects.
*/ */
int sqlite3_wasm_init_opfs(void){ int sqlite3_wasm_init_opfs(const char *zMountPoint){
static backend_t pOpfs = 0; static backend_t pOpfs = 0;
static const char * zDir = "/persistent"; if( !zMountPoint || !*zMountPoint ) zMountPoint = "/persistent";
if( !pOpfs ){ if( !pOpfs ){
pOpfs = wasmfs_create_opfs_backend(); pOpfs = wasmfs_create_opfs_backend();
if( pOpfs ){ if( pOpfs ){
@ -459,12 +465,15 @@ int sqlite3_wasm_init_opfs(void){
} }
/** It's not enough to instantiate the backend. We have to create a /** It's not enough to instantiate the backend. We have to create a
mountpoint in the VFS and attach the backend to it. */ mountpoint in the VFS and attach the backend to it. */
if( pOpfs && 0!=access(zDir, F_OK) ){ if( pOpfs && 0!=access(zMountPoint, F_OK) ){
/* mkdir() simply hangs when called from fiddle app. Cause is /* mkdir() simply hangs when called from fiddle app. Cause is
not yet determined but the hypothesis is an init-order not yet determined but the hypothesis is an init-order
issue. */ issue. */
const int rc = wasmfs_create_directory(zDir, 0777, pOpfs); /* Note that this check and is not robust but it will
emscripten_console_log(rc ? "OPFS mkdir failed." : "OPFS mkdir ok."); hypothetically suffice for the transient wasm-based virtual
filesystem we're currently running in. */
const int rc = wasmfs_create_directory(zMountPoint, 0777, pOpfs);
emscripten_console_logf("OPFS mkdir rc=%d", rc);
if(rc) return SQLITE_IOERR; if(rc) return SQLITE_IOERR;
} }
return pOpfs ? 0 : SQLITE_NOMEM; return pOpfs ? 0 : SQLITE_NOMEM;

View File

@ -1,5 +1,5 @@
C wasm:\saccommodated\sa\sJS\sAPI\srename. C Refactor\sJS\sAPI\samalgamation\ssuch\sthat\sthe\sbootstrapping/configuration\sis\sdeferred\suntil\sthe\swhole\samalgamation\sis\savailable,\sto\sfacilitate\sproviding\sclients\swith\sa\sway\sto\sinitialize\sthe\sAPI\swith\stheir\sown\sconfig\s(noting\sthat\swe're\sstill\sone\ssmall\slevel\sof\srefactoring\saway\sfrom\sbeing\sable\sto\sactually\sdo\sthat).
D 2022-08-22T08:55:10.642 D 2022-08-22T13:34:13.519
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
@ -481,14 +481,14 @@ F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de
F ext/wasm/api/README.md d876597edd2b9542b6ea031adaaff1c042076fde7b670b1dc6d8a87b28a6631b F ext/wasm/api/README.md d876597edd2b9542b6ea031adaaff1c042076fde7b670b1dc6d8a87b28a6631b
F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba81456260a713ed04900c F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba81456260a713ed04900c
F ext/wasm/api/post-js-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a4a06cb776c003880b F ext/wasm/api/post-js-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a4a06cb776c003880b
F ext/wasm/api/sqlite3-api-cleanup.js 149fd63a0400cd1d69548887ffde2ed89c13283384a63c2e9fcfc695e38a9e11 F ext/wasm/api/sqlite3-api-cleanup.js eee5ac931fa0aee2cace52a0dff0cf22ae56a1993a88d911bd0dd384fb380c9a
F ext/wasm/api/sqlite3-api-glue.js 4a09dd1153874f7a716cf953329bc1e78bf24e0870a9aad15214ffd51ac913bc F ext/wasm/api/sqlite3-api-glue.js 67ca83974410961953eeaa1dfed3518530d68381729ed1d27f95122f5baeabd3
F ext/wasm/api/sqlite3-api-oo1.js 6c14e97987fafdd5f63ffa8a086e5316d49c115743add4dabfacb302a7c76b45 F ext/wasm/api/sqlite3-api-oo1.js f6dcaac3270182471f97efcfda25bd4a4ac1777b8ec52ebd1c6846721160e54c
F ext/wasm/api/sqlite3-api-opfs.js c93cdd14f81a26b3a64990515ee05c7e29827fbc8fba4e4c2fef3a37a984db89 F ext/wasm/api/sqlite3-api-opfs.js 011799db398157cbd254264b6ebae00d7234b93d0e9e810345f213a5774993c0
F ext/wasm/api/sqlite3-api-prologue.js 96997e411b41ff3d4024c2ad625c5cdb7b6a619ba8beece4662ad190191b1119 F ext/wasm/api/sqlite3-api-prologue.js 5d1b13b23af48ce952e30a0f2d6dff4bc4b33f2dc36fdcaf69c164fd9a72b60f
F ext/wasm/api/sqlite3-api-worker1.js 74130ec4979baeaf3e909c7619b99e9f466e2d816cd07370987ff639d168ef45 F ext/wasm/api/sqlite3-api-worker1.js ceb1fc88d8a3742c069632e88fd05c14d5a79eb86bdb9e12969ec37f64fbf42b
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
F ext/wasm/api/sqlite3-wasm.c 0e78035045e3328fb050ec9580c6bfb714c756a1d3b917259e58baf9b0332c98 F ext/wasm/api/sqlite3-wasm.c 0d81282eaeff2a6e9fc5c28a388c5c5b45cf25a9393992fa511ac009b27df982
F ext/wasm/common/SqliteTestUtil.js e41a1406f18da9224523fad0c48885caf995b56956a5b9852909c0989e687e90 F ext/wasm/common/SqliteTestUtil.js e41a1406f18da9224523fad0c48885caf995b56956a5b9852909c0989e687e90
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
F ext/wasm/common/testing.css 572cf1ffae0b6eb7ca63684d3392bf350217a07b90e7a896e4fa850700c989b0 F ext/wasm/common/testing.css 572cf1ffae0b6eb7ca63684d3392bf350217a07b90e7a896e4fa850700c989b0
@ -2006,8 +2006,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 7a3c444fb515413254b426908e4d3528ccc664a629628c23b7b85bd21c060d0e P 00991335c4dae56232e999398e5e82d8161903ba7d084b16a73a150e83f1f782
R 763c38437f86fddfab452c17546273d5 R d8e7cfc53479bc2a5e5d34dd2cc26aa3
U stephan U stephan
Z 9e445c1e5e3ac9504605b874a5870c61 Z dd954bd42edcc1a06b3b31bdffb215a4
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
00991335c4dae56232e999398e5e82d8161903ba7d084b16a73a150e83f1f782 9dbe9a6aecec43b51057375ef1d2d632db0d17eac8b7552c20cc91fc2f1a55d1