1/*
2  2022-05-22
3
4  The author disclaims copyright to this source code.  In place of a
5  legal notice, here is a blessing:
6
7  *   May you do good and not evil.
8  *   May you find forgiveness for yourself and forgive others.
9  *   May you share freely, never taking more than you give.
10
11  ***********************************************************************
12
13  This file is intended to be combined at build-time with other
14  related code, most notably a header and footer which wraps this whole
15  file into an Emscripten Module.postRun() handler which has a parameter
16  named "Module" (the Emscripten Module object). The exact requirements,
17  conventions, and build process are very much under construction and
18  will be (re)documented once they've stopped fluctuating so much.
19
20  Specific goals of this project:
21
22  - Except where noted in the non-goals, provide a more-or-less
23    feature-complete wrapper to the sqlite3 C API, insofar as WASM
24    feature parity with C allows for. In fact, provide at least 3
25    APIs...
26
27    1) Bind a low-level sqlite3 API which is as close to the native
28       one as feasible in terms of usage.
29
30    2) A higher-level API, more akin to sql.js and node.js-style
31       implementations. This one speaks directly to the low-level
32       API. This API must be used from the same thread as the
33       low-level API.
34
35    3) A second higher-level API which speaks to the previous APIs via
36       worker messages. This one is intended for use in the main
37       thread, with the lower-level APIs installed in a Worker thread,
38       and talking to them via Worker messages. Because Workers are
39       asynchronouns and have only a single message channel, some
40       acrobatics are needed here to feed async work results back to
41       the client (as we cannot simply pass around callbacks between
42       the main and Worker threads).
43
44  - Insofar as possible, support client-side storage using JS
45    filesystem APIs. As of this writing, such things are still very
46    much under development.
47
48  Specific non-goals of this project:
49
50  - As WASM is a web-centric technology and UTF-8 is the King of
51    Encodings in that realm, there are no currently plans to support
52    the UTF16-related sqlite3 APIs. They would add a complication to
53    the bindings for no appreciable benefit. Though web-related
54    implementation details take priority, and the JavaScript
55    components of the API specifically focus on browser clients, the
56    lower-level WASM module "should" work in non-web WASM
57    environments.
58
59  - Supporting old or niche-market platforms. WASM is built for a
60    modern web and requires modern platforms.
61
62  - Though scalar User-Defined Functions (UDFs) may be created in
63    JavaScript, there are currently no plans to add support for
64    aggregate and window functions.
65
66  Attribution:
67
68  This project is endebted to the work of sql.js:
69
70  https://github.com/sql-js/sql.js
71
72  sql.js was an essential stepping stone in this code's development as
73  it demonstrated how to handle some of the WASM-related voodoo (like
74  handling pointers-to-pointers and adding JS implementations of
75  C-bound callback functions). These APIs have a considerably
76  different shape than sql.js's, however.
77*/
78
79/**
80   sqlite3ApiBootstrap() is the only global symbol persistently
81   exposed by this API. It is intended to be called one time at the
82   end of the API amalgamation process, passed configuration details
83   for the current environment, and then optionally be removed from
84   the global object using `delete self.sqlite3ApiBootstrap`.
85
86   This function expects a configuration object, intended to abstract
87   away details specific to any given WASM environment, primarily so
88   that it can be used without any _direct_ dependency on
89   Emscripten. (Note the default values for the config object!) The
90   config object is only honored the first time this is
91   called. Subsequent calls ignore the argument and return the same
92   (configured) object which gets initialized by the first call.
93
94   The config object properties include:
95
96   - `exports`[^1]: the "exports" object for the current WASM
97     environment. In an Emscripten build, this should be set to
98     `Module['asm']`.
99
100   - `memory`[^1]: optional WebAssembly.Memory object, defaulting to
101     `exports.memory`. In Emscripten environments this should be set
102     to `Module.wasmMemory` if the build uses `-sIMPORT_MEMORY`, or be
103     left undefined/falsy to default to `exports.memory` when using
104     WASM-exported memory.
105
106   - `bigIntEnabled`: true if BigInt support is enabled. Defaults to
107     true if self.BigInt64Array is available, else false. Some APIs
108     will throw exceptions if called without BigInt support, as BigInt
109     is required for marshalling C-side int64 into and out of JS.
110
111   - `allocExportName`: the name of the function, in `exports`, of the
112     `malloc(3)`-compatible routine for the WASM environment. Defaults
113     to `"malloc"`.
114
115   - `deallocExportName`: the name of the function, in `exports`, of
116     the `free(3)`-compatible routine for the WASM
117     environment. Defaults to `"free"`.
118
119   - `wasmfsOpfsDir`[^1]: if the environment supports persistent storage, this
120     directory names the "mount point" for that directory. It must be prefixed
121     by `/` and may currently contain only a single directory-name part. Using
122     the root directory name is not supported by any current persistent backend.
123
124
125   [^1] = This property may optionally be a function, in which case this
126          function re-assigns it to the value returned from that function,
127          enabling delayed evaluation.
128
129*/
130'use strict';
131self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
132  apiConfig = (self.sqlite3ApiConfig || sqlite3ApiBootstrap.defaultConfig)
133){
134  if(sqlite3ApiBootstrap.sqlite3){ /* already initalized */
135    console.warn("sqlite3ApiBootstrap() called multiple times.",
136                 "Config and external initializers are ignored on calls after the first.");
137    return sqlite3ApiBootstrap.sqlite3;
138  }
139  const config = Object.assign(Object.create(null),{
140    exports: undefined,
141    memory: undefined,
142    bigIntEnabled: (()=>{
143      if('undefined'!==typeof Module){
144        /* Emscripten module will contain HEAPU64 when built with
145           -sWASM_BIGINT=1, else it will not. */
146        return !!Module.HEAPU64;
147      }
148      return !!self.BigInt64Array;
149    })(),
150    allocExportName: 'malloc',
151    deallocExportName: 'free',
152    wasmfsOpfsDir: '/opfs'
153  }, apiConfig || {});
154
155  [
156    // If any of these config options are functions, replace them with
157    // the result of calling that function...
158    'exports', 'memory', 'wasmfsOpfsDir'
159  ].forEach((k)=>{
160    if('function' === typeof config[k]){
161      config[k] = config[k]();
162    }
163  });
164
165  /** Throws a new Error, the message of which is the concatenation
166      all args with a space between each. */
167  const toss = (...args)=>{throw new Error(args.join(' '))};
168
169  if(config.wasmfsOpfsDir && !/^\/[^/]+$/.test(config.wasmfsOpfsDir)){
170    toss("config.wasmfsOpfsDir must be falsy or in the form '/dir-name'.");
171  }
172
173  /**
174     Returns true if n is a 32-bit (signed) integer, else
175     false. This is used for determining when we need to switch to
176     double-type DB operations for integer values in order to keep
177     more precision.
178  */
179  const isInt32 = (n)=>{
180    return ('bigint'!==typeof n /*TypeError: can't convert BigInt to number*/)
181      && !!(n===(n|0) && n<=2147483647 && n>=-2147483648);
182  };
183  /**
184     Returns true if the given BigInt value is small enough to fit
185     into an int64 value, else false.
186  */
187  const bigIntFits64 = function f(b){
188    if(!f._max){
189      f._max = BigInt("0x7fffffffffffffff");
190      f._min = ~f._max;
191    }
192    return b >= f._min && b <= f._max;
193  };
194
195  /**
196     Returns true if the given BigInt value is small enough to fit
197     into an int32, else false.
198  */
199  const bigIntFits32 = (b)=>(b >= (-0x7fffffffn - 1n) && b <= 0x7fffffffn);
200
201  /**
202     Returns true if the given BigInt value is small enough to fit
203     into a double value without loss of precision, else false.
204  */
205  const bigIntFitsDouble = function f(b){
206    if(!f._min){
207      f._min = Number.MIN_SAFE_INTEGER;
208      f._max = Number.MAX_SAFE_INTEGER;
209    }
210    return b >= f._min && b <= f._max;
211  };
212
213  /** Returns v if v appears to be a TypedArray, else false. */
214  const isTypedArray = (v)=>{
215    return (v && v.constructor && isInt32(v.constructor.BYTES_PER_ELEMENT)) ? v : false;
216  };
217
218  /**
219     Returns true if v appears to be one of our bind()-able
220     TypedArray types: Uint8Array or Int8Array. Support for
221     TypedArrays with element sizes >1 is TODO.
222  */
223  const isBindableTypedArray = (v)=>{
224    return v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
225  };
226
227  /**
228     Returns true if v appears to be one of the TypedArray types
229     which is legal for holding SQL code (as opposed to binary blobs).
230
231     Currently this is the same as isBindableTypedArray() but it
232     seems likely that we'll eventually want to add Uint32Array
233     and friends to the isBindableTypedArray() list but not to the
234     isSQLableTypedArray() list.
235  */
236  const isSQLableTypedArray = (v)=>{
237    return v && v.constructor && (1===v.constructor.BYTES_PER_ELEMENT);
238  };
239
240  /** Returns true if isBindableTypedArray(v) does, else throws with a message
241      that v is not a supported TypedArray value. */
242  const affirmBindableTypedArray = (v)=>{
243    return isBindableTypedArray(v)
244      || toss("Value is not of a supported TypedArray type.");
245  };
246
247  const utf8Decoder = new TextDecoder('utf-8');
248
249  /** Internal helper to use in operations which need to distinguish
250      between SharedArrayBuffer heap memory and non-shared heap. */
251  const __SAB = ('undefined'===typeof SharedArrayBuffer)
252        ? function(){} : SharedArrayBuffer;
253  const typedArrayToString = function(arrayBuffer, begin, end){
254    return utf8Decoder.decode(
255      (arrayBuffer.buffer instanceof __SAB)
256        ? arrayBuffer.slice(begin, end)
257        : arrayBuffer.subarray(begin, end)
258    );
259  };
260
261  /**
262     If v is-a Array, its join('') result is returned.  If
263     isSQLableTypedArray(v) is true then typedArrayToString(v) is
264     returned. Else v is returned as-is.
265  */
266  const flexibleString = function(v){
267    if(isSQLableTypedArray(v)) return typedArrayToString(v);
268    else if(Array.isArray(v)) return v.join('');
269    return v;
270  };
271
272  /**
273     An Error subclass specifically for reporting Wasm-level malloc()
274     failure and enabling clients to unambiguously identify such
275     exceptions.
276  */
277  class WasmAllocError extends Error {
278    constructor(...args){
279      super(...args);
280      this.name = 'WasmAllocError';
281    }
282  };
283  WasmAllocError.toss = (...args)=>{
284    throw new WasmAllocError(args.join(' '));
285  };
286
287  /**
288      The main sqlite3 binding API gets installed into this object,
289      mimicking the C API as closely as we can. The numerous members
290      names with prefixes 'sqlite3_' and 'SQLITE_' behave, insofar as
291      possible, identically to the C-native counterparts, as documented at:
292
293      https://www.sqlite.org/c3ref/intro.html
294
295      A very few exceptions require an additional level of proxy
296      function or may otherwise require special attention in the WASM
297      environment, and all such cases are document here. Those not
298      documented here are installed as 1-to-1 proxies for their C-side
299      counterparts.
300  */
301  const capi = {
302    /**
303       sqlite3_create_function_v2() differs from its native
304       counterpart only in the following ways:
305
306       1) The fourth argument (`eTextRep`) argument must not specify
307       any encoding other than sqlite3.SQLITE_UTF8. The JS API does not
308       currently support any other encoding and likely never
309       will. This function does not replace that argument on its own
310       because it may contain other flags.
311
312       2) Any of the four final arguments may be either WASM pointers
313       (assumed to be function pointers) or JS Functions. In the
314       latter case, each gets bound to WASM using
315       sqlite3.capi.wasm.installFunction() and that wrapper is passed
316       on to the native implementation.
317
318       The semantics of JS functions are:
319
320       xFunc: is passed `(pCtx, ...values)`. Its return value becomes
321       the new SQL function's result.
322
323       xStep: is passed `(pCtx, ...values)`. Its return value is
324       ignored.
325
326       xFinal: is passed `(pCtx)`. Its return value becomes the new
327       aggregate SQL function's result.
328
329       xDestroy: is passed `(void*)`. Its return value is ignored. The
330       pointer passed to it is the one from the 5th argument to
331       sqlite3_create_function_v2().
332
333       Note that:
334
335       - `pCtx` in the above descriptions is a `sqlite3_context*`. At
336         least 99 times out of a hundred, that initial argument will
337         be irrelevant for JS UDF bindings, but it needs to be there
338         so that the cases where it _is_ relevant, in particular with
339         window and aggregate functions, have full access to the
340         lower-level sqlite3 APIs.
341
342       - When wrapping JS functions, the remaining arguments are passd
343         to them as positional arguments, not as an array of
344         arguments, because that allows callback definitions to be
345         more JS-idiomatic than C-like. For example `(pCtx,a,b)=>a+b`
346         is more intuitive and legible than
347         `(pCtx,args)=>args[0]+args[1]`. For cases where an array of
348         arguments would be more convenient, the callbacks simply need
349         to be declared like `(pCtx,...args)=>{...}`, in which case
350         `args` will be an array.
351
352       - If a JS wrapper throws, it gets translated to
353         sqlite3_result_error() or sqlite3_result_error_nomem(),
354         depending on whether the exception is an
355         sqlite3.WasmAllocError object or not.
356
357       - When passing on WASM function pointers, arguments are _not_
358         converted or reformulated. They are passed on as-is in raw
359         pointer form using their native C signatures. Only JS
360         functions passed in to this routine, and thus wrapped by this
361         routine, get automatic conversions of arguments and result
362         values. The routines which perform those conversions are
363         exposed for client-side use as
364         sqlite3_create_function_v2.convertUdfArgs() and
365         sqlite3_create_function_v2.setUdfResult(). sqlite3_create_function()
366         and sqlite3_create_window_function() have those same methods.
367
368       For xFunc(), xStep(), and xFinal():
369
370       - When called from SQL, arguments to the UDF, and its result,
371         will be converted between JS and SQL with as much fidelity as
372         is feasible, triggering an exception if a type conversion
373         cannot be determined. Some freedom is afforded to numeric
374         conversions due to friction between the JS and C worlds:
375         integers which are larger than 32 bits may be treated as
376         doubles or BigInts.
377
378       If any JS-side bound functions throw, those exceptions are
379       intercepted and converted to database-side errors with the
380       exception of xDestroy(): any exception from it is ignored,
381       possibly generating a console.error() message.  Destructors
382       must not throw.
383
384       Once installed, there is currently no way to uninstall the
385       automatically-converted WASM-bound JS functions from WASM. They
386       can be uninstalled from the database as documented in the C
387       API, but this wrapper currently has no infrastructure in place
388       to also free the WASM-bound JS wrappers, effectively resulting
389       in a memory leak if the client uninstalls the UDF. Improving that
390       is a potential TODO, but removing client-installed UDFs is rare
391       in practice. If this factor is relevant for a given client,
392       they can create WASM-bound JS functions themselves, hold on to their
393       pointers, and pass the pointers in to here. Later on, they can
394       free those pointers (using `wasm.uninstallFunction()` or
395       equivalent).
396
397       C reference: https://www.sqlite.org/c3ref/create_function.html
398
399       Maintenance reminder: the ability to add new
400       WASM-accessible functions to the runtime requires that the
401       WASM build is compiled with emcc's `-sALLOW_TABLE_GROWTH`
402       flag.
403    */
404    sqlite3_create_function_v2: function(
405      pDb, funcName, nArg, eTextRep, pApp,
406      xFunc, xStep, xFinal, xDestroy
407    ){/*installed later*/},
408    /**
409       Equivalent to passing the same arguments to
410       sqlite3_create_function_v2(), with 0 as the final argument.
411    */
412    sqlite3_create_function:function(
413      pDb, funcName, nArg, eTextRep, pApp,
414      xFunc, xStep, xFinal
415    ){/*installed later*/},
416    /**
417       The sqlite3_create_window_function() JS wrapper differs from
418       its native implementation in the exact same way that
419       sqlite3_create_function_v2() does. The additional function,
420       xInverse(), is treated identically to xStep() by the wrapping
421       layer.
422    */
423    sqlite3_create_window_function: function(
424      pDb, funcName, nArg, eTextRep, pApp,
425      xStep, xFinal, xValue, xInverse, xDestroy
426    ){/*installed later*/},
427    /**
428       The sqlite3_prepare_v3() binding handles two different uses
429       with differing JS/WASM semantics:
430
431       1) sqlite3_prepare_v3(pDb, sqlString, -1, prepFlags, ppStmt , null)
432
433       2) sqlite3_prepare_v3(pDb, sqlPointer, sqlByteLen, prepFlags, ppStmt, sqlPointerToPointer)
434
435       Note that the SQL length argument (the 3rd argument) must, for
436       usage (1), always be negative because it must be a byte length
437       and that value is expensive to calculate from JS (where only
438       the character length of strings is readily available). It is
439       retained in this API's interface for code/documentation
440       compatibility reasons but is currently _always_ ignored. With
441       usage (2), the 3rd argument is used as-is but is is still
442       critical that the C-style input string (2nd argument) be
443       terminated with a 0 byte.
444
445       In usage (1), the 2nd argument must be of type string,
446       Uint8Array, or Int8Array (either of which is assumed to
447       hold SQL). If it is, this function assumes case (1) and
448       calls the underyling C function with the equivalent of:
449
450       (pDb, sqlAsString, -1, prepFlags, ppStmt, null)
451
452       The `pzTail` argument is ignored in this case because its
453       result is meaningless when a string-type value is passed
454       through: the string goes through another level of internal
455       conversion for WASM's sake and the result pointer would refer
456       to that transient conversion's memory, not the passed-in
457       string.
458
459       If the sql argument is not a string, it must be a _pointer_ to
460       a NUL-terminated string which was allocated in the WASM memory
461       (e.g. using capi.wasm.alloc() or equivalent). In that case,
462       the final argument may be 0/null/undefined or must be a pointer
463       to which the "tail" of the compiled SQL is written, as
464       documented for the C-side sqlite3_prepare_v3(). In case (2),
465       the underlying C function is called with the equivalent of:
466
467       (pDb, sqlAsPointer, sqlByteLen, prepFlags, ppStmt, pzTail)
468
469       It returns its result and compiled statement as documented in
470       the C API. Fetching the output pointers (5th and 6th
471       parameters) requires using `capi.wasm.getMemValue()` (or
472       equivalent) and the `pzTail` will point to an address relative to
473       the `sqlAsPointer` value.
474
475       If passed an invalid 2nd argument type, this function will
476       return SQLITE_MISUSE and sqlite3_errmsg() will contain a string
477       describing the problem.
478
479       Side-note: if given an empty string, or one which contains only
480       comments or an empty SQL expression, 0 is returned but the result
481       output pointer will be NULL.
482    */
483    sqlite3_prepare_v3: (dbPtr, sql, sqlByteLen, prepFlags,
484                         stmtPtrPtr, strPtrPtr)=>{}/*installed later*/,
485
486    /**
487       Equivalent to calling sqlite3_prapare_v3() with 0 as its 4th argument.
488    */
489    sqlite3_prepare_v2: (dbPtr, sql, sqlByteLen,
490                         stmtPtrPtr,strPtrPtr)=>{}/*installed later*/,
491
492    /**
493       This binding enables the callback argument to be a JavaScript.
494
495       If the callback is a function, then for the duration of the
496       sqlite3_exec() call, it installs a WASM-bound function which
497       acts as a proxy for the given callback. That proxy will
498       also perform a conversion of the callback's arguments from
499       `(char**)` to JS arrays of strings. However, for API
500       consistency's sake it will still honor the C-level
501       callback parameter order and will call it like:
502
503       `callback(pVoid, colCount, listOfValues, listOfColNames)`
504
505       If the callback is not a JS function then this binding performs
506       no translation of the callback, but the sql argument is still
507       converted to a WASM string for the call using the
508       "flexible-string" argument converter.
509    */
510    sqlite3_exec: (pDb, sql, callback, pVoid, pErrMsg)=>{}/*installed later*/,
511    /**
512       Various internal-use utilities are added here as needed. They
513       are bound to an object only so that we have access to them in
514       the differently-scoped steps of the API bootstrapping
515       process. At the end of the API setup process, this object gets
516       removed.
517    */
518    util:{
519      affirmBindableTypedArray, flexibleString,
520      bigIntFits32, bigIntFits64, bigIntFitsDouble,
521      isBindableTypedArray,
522      isInt32, isSQLableTypedArray, isTypedArray,
523      typedArrayToString,
524      isMainWindow: ()=>{
525        return 'undefined' === typeof WorkerGlobalScope
526      }
527    },
528
529    /**
530       Holds state which are specific to the WASM-related
531       infrastructure and glue code. It is not expected that client
532       code will normally need these, but they're exposed here in case
533       it does. These APIs are _not_ to be considered an
534       official/stable part of the sqlite3 WASM API. They may change
535       as the developers' experience suggests appropriate changes.
536
537       Note that a number of members of this object are injected
538       dynamically after the api object is fully constructed, so
539       not all are documented inline here.
540    */
541    wasm: {
542    //^^^ TODO?: move wasm from sqlite3.capi.wasm to sqlite3.wasm
543      /**
544         Emscripten APIs have a deep-seated assumption that all pointers
545         are 32 bits. We'll remain optimistic that that won't always be
546         the case and will use this constant in places where we might
547         otherwise use a hard-coded 4.
548      */
549      ptrSizeof: config.wasmPtrSizeof || 4,
550      /**
551         The WASM IR (Intermediate Representation) value for
552         pointer-type values. It MUST refer to a value type of the
553         size described by this.ptrSizeof _or_ it may be any value
554         which ends in '*', which Emscripten's glue code internally
555         translates to i32.
556      */
557      ptrIR: config.wasmPtrIR || "i32",
558      /**
559         True if BigInt support was enabled via (e.g.) the
560         Emscripten -sWASM_BIGINT flag, else false. When
561         enabled, certain 64-bit sqlite3 APIs are enabled which
562         are not otherwise enabled due to JS/WASM int64
563         impedence mismatches.
564      */
565      bigIntEnabled: !!config.bigIntEnabled,
566      /**
567         The symbols exported by the WASM environment.
568      */
569      exports: config.exports
570        || toss("Missing API config.exports (WASM module exports)."),
571
572      /**
573         When Emscripten compiles with `-sIMPORT_MEMORY`, it
574         initalizes the heap and imports it into wasm, as opposed to
575         the other way around. In this case, the memory is not
576         available via this.exports.memory.
577      */
578      memory: config.memory || config.exports['memory']
579        || toss("API config object requires a WebAssembly.Memory object",
580                "in either config.exports.memory (exported)",
581                "or config.memory (imported)."),
582
583      /**
584         The API's one single point of access to the WASM-side memory
585         allocator. Works like malloc(3) (and is likely bound to
586         malloc()) but throws an WasmAllocError if allocation fails. It is
587         important that any code which might pass through the sqlite3 C
588         API NOT throw and must instead return SQLITE_NOMEM (or
589         equivalent, depending on the context).
590
591         That said, very few cases in the API can result in
592         client-defined functions propagating exceptions via the C-style
593         API. Most notably, this applies ot User-defined SQL Functions
594         (UDFs) registered via sqlite3_create_function_v2(). For that
595         specific case it is recommended that all UDF creation be
596         funneled through a utility function and that a wrapper function
597         be added around the UDF which catches any exception and sets
598         the error state to OOM. (The overall complexity of registering
599         UDFs essentially requires a helper for doing so!)
600      */
601      alloc: undefined/*installed later*/,
602      /**
603         The API's one single point of access to the WASM-side memory
604         deallocator. Works like free(3) (and is likely bound to
605         free()).
606      */
607      dealloc: undefined/*installed later*/
608
609      /* Many more wasm-related APIs get installed later on. */
610    }/*wasm*/
611  }/*capi*/;
612
613  const wasm = capi.wasm;
614
615  /**
616     wasm.alloc()'s srcTypedArray.byteLength bytes,
617     populates them with the values from the source
618     TypedArray, and returns the pointer to that memory. The
619     returned pointer must eventually be passed to
620     wasm.dealloc() to clean it up.
621
622     As a special case, to avoid further special cases where
623     this is used, if srcTypedArray.byteLength is 0, it
624     allocates a single byte and sets it to the value
625     0. Even in such cases, calls must behave as if the
626     allocated memory has exactly srcTypedArray.byteLength
627     bytes.
628
629     ACHTUNG: this currently only works for Uint8Array and
630     Int8Array types and will throw if srcTypedArray is of
631     any other type.
632  */
633  wasm.allocFromTypedArray = function(srcTypedArray){
634    affirmBindableTypedArray(srcTypedArray);
635    const pRet = wasm.alloc(srcTypedArray.byteLength || 1);
636    wasm.heapForSize(srcTypedArray.constructor).set(srcTypedArray.byteLength ? srcTypedArray : [0], pRet);
637    return pRet;
638  };
639
640  const keyAlloc = config.allocExportName || 'malloc',
641        keyDealloc =  config.deallocExportName || 'free';
642  for(const key of [keyAlloc, keyDealloc]){
643    const f = wasm.exports[key];
644    if(!(f instanceof Function)) toss("Missing required exports[",key,"] function.");
645  }
646
647  wasm.alloc = function(n){
648    const m = wasm.exports[keyAlloc](n);
649    if(!m) throw new WasmAllocError("Failed to allocate "+n+" bytes.");
650    return m;
651  };
652
653  wasm.dealloc = (m)=>wasm.exports[keyDealloc](m);
654
655  /**
656     Reports info about compile-time options using
657     sqlite_compileoption_get() and sqlite3_compileoption_used(). It
658     has several distinct uses:
659
660     If optName is an array then it is expected to be a list of
661     compilation options and this function returns an object
662     which maps each such option to true or false, indicating
663     whether or not the given option was included in this
664     build. That object is returned.
665
666     If optName is an object, its keys are expected to be compilation
667     options and this function sets each entry to true or false,
668     indicating whether the compilation option was used or not. That
669     object is returned.
670
671     If passed no arguments then it returns an object mapping
672     all known compilation options to their compile-time values,
673     or boolean true if they are defined with no value. This
674     result, which is relatively expensive to compute, is cached
675     and returned for future no-argument calls.
676
677     In all other cases it returns true if the given option was
678     active when when compiling the sqlite3 module, else false.
679
680     Compile-time option names may optionally include their
681     "SQLITE_" prefix. When it returns an object of all options,
682     the prefix is elided.
683  */
684  wasm.compileOptionUsed = function f(optName){
685    if(!arguments.length){
686      if(f._result) return f._result;
687      else if(!f._opt){
688        f._rx = /^([^=]+)=(.+)/;
689        f._rxInt = /^-?\d+$/;
690        f._opt = function(opt, rv){
691          const m = f._rx.exec(opt);
692          rv[0] = (m ? m[1] : opt);
693          rv[1] = m ? (f._rxInt.test(m[2]) ? +m[2] : m[2]) : true;
694        };
695      }
696      const rc = {}, ov = [0,0];
697      let i = 0, k;
698      while((k = capi.sqlite3_compileoption_get(i++))){
699        f._opt(k,ov);
700        rc[ov[0]] = ov[1];
701      }
702      return f._result = rc;
703    }else if(Array.isArray(optName)){
704      const rc = {};
705      optName.forEach((v)=>{
706        rc[v] = capi.sqlite3_compileoption_used(v);
707      });
708      return rc;
709    }else if('object' === typeof optName){
710      Object.keys(optName).forEach((k)=> {
711        optName[k] = capi.sqlite3_compileoption_used(k);
712      });
713      return optName;
714    }
715    return (
716      'string'===typeof optName
717    ) ? !!capi.sqlite3_compileoption_used(optName) : false;
718  }/*compileOptionUsed()*/;
719
720  /**
721     Signatures for the WASM-exported C-side functions. Each entry
722     is an array with 2+ elements:
723
724     [ "c-side name",
725       "result type" (wasm.xWrap() syntax),
726       [arg types in xWrap() syntax]
727       // ^^^ this needn't strictly be an array: it can be subsequent
728       // elements instead: [x,y,z] is equivalent to x,y,z
729     ]
730
731     Note that support for the API-specific data types in the
732     result/argument type strings gets plugged in at a later phase in
733     the API initialization process.
734  */
735  wasm.bindingSignatures = [
736    // Please keep these sorted by function name!
737    ["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"],
738    ["sqlite3_bind_blob","int", "sqlite3_stmt*", "int", "*", "int", "*"
739     /* We should arguably write a custom wrapper which knows how
740        to handle Blob, TypedArrays, and JS strings. */
741    ],
742    ["sqlite3_bind_double","int", "sqlite3_stmt*", "int", "f64"],
743    ["sqlite3_bind_int","int", "sqlite3_stmt*", "int", "int"],
744    ["sqlite3_bind_null",undefined, "sqlite3_stmt*", "int"],
745    ["sqlite3_bind_parameter_count", "int", "sqlite3_stmt*"],
746    ["sqlite3_bind_parameter_index","int", "sqlite3_stmt*", "string"],
747    ["sqlite3_bind_text","int", "sqlite3_stmt*", "int", "string", "int", "int"
748     /* We should arguably create a hand-written binding
749        which does more flexible text conversion, along the lines of
750        sqlite3_prepare_v3(). The slightly problematic part is the
751        final argument (text destructor). */
752    ],
753    ["sqlite3_close_v2", "int", "sqlite3*"],
754    ["sqlite3_changes", "int", "sqlite3*"],
755    ["sqlite3_clear_bindings","int", "sqlite3_stmt*"],
756    ["sqlite3_column_blob","*", "sqlite3_stmt*", "int"],
757    ["sqlite3_column_bytes","int", "sqlite3_stmt*", "int"],
758    ["sqlite3_column_count", "int", "sqlite3_stmt*"],
759    ["sqlite3_column_double","f64", "sqlite3_stmt*", "int"],
760    ["sqlite3_column_int","int", "sqlite3_stmt*", "int"],
761    ["sqlite3_column_name","string", "sqlite3_stmt*", "int"],
762    ["sqlite3_column_text","string", "sqlite3_stmt*", "int"],
763    ["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
764    ["sqlite3_compileoption_get", "string", "int"],
765    ["sqlite3_compileoption_used", "int", "string"],
766    /* sqlite3_create_function_v2() is handled separate to simplify conversion
767       of its callback argument */
768    ["sqlite3_data_count", "int", "sqlite3_stmt*"],
769    ["sqlite3_db_filename", "string", "sqlite3*", "string"],
770    ["sqlite3_db_handle", "sqlite3*", "sqlite3_stmt*"],
771    ["sqlite3_db_name", "string", "sqlite3*", "int"],
772    ["sqlite3_deserialize", "int", "sqlite3*", "string", "*", "i64", "i64", "int"]
773    /* Careful! Short version: de/serialize() are problematic because they
774       might use a different allocator that the user for managing the
775       deserialized block. de/serialize() are ONLY safe to use with
776       sqlite3_malloc(), sqlite3_free(), and its 64-bit variants. */,
777    ["sqlite3_errmsg", "string", "sqlite3*"],
778    ["sqlite3_error_offset", "int", "sqlite3*"],
779    ["sqlite3_errstr", "string", "int"],
780    /*["sqlite3_exec", "int", "sqlite3*", "string", "*", "*", "**"
781      Handled seperately to perform translation of the callback
782      into a WASM-usable one. ],*/
783    ["sqlite3_expanded_sql", "string", "sqlite3_stmt*"],
784    ["sqlite3_extended_errcode", "int", "sqlite3*"],
785    ["sqlite3_extended_result_codes", "int", "sqlite3*", "int"],
786    ["sqlite3_file_control", "int", "sqlite3*", "string", "int", "*"],
787    ["sqlite3_finalize", "int", "sqlite3_stmt*"],
788    ["sqlite3_free", undefined,"*"],
789    ["sqlite3_initialize", undefined],
790    ["sqlite3_interrupt", undefined, "sqlite3*"
791     /* ^^^ we cannot actually currently support this because JS is
792        single-threaded and we don't have a portable way to access a DB
793        from 2 SharedWorkers concurrently. */],
794    ["sqlite3_libversion", "string"],
795    ["sqlite3_libversion_number", "int"],
796    ["sqlite3_malloc", "*","int"],
797    ["sqlite3_open", "int", "string", "*"],
798    ["sqlite3_open_v2", "int", "string", "*", "int", "string"],
799    /* sqlite3_prepare_v2() and sqlite3_prepare_v3() are handled
800       separately due to us requiring two different sets of semantics
801       for those, depending on how their SQL argument is provided. */
802    ["sqlite3_realloc", "*","*","int"],
803    ["sqlite3_reset", "int", "sqlite3_stmt*"],
804    ["sqlite3_result_blob",undefined, "*", "*", "int", "*"],
805    ["sqlite3_result_double",undefined, "*", "f64"],
806    ["sqlite3_result_error",undefined, "*", "string", "int"],
807    ["sqlite3_result_error_code", undefined, "*", "int"],
808    ["sqlite3_result_error_nomem", undefined, "*"],
809    ["sqlite3_result_error_toobig", undefined, "*"],
810    ["sqlite3_result_int",undefined, "*", "int"],
811    ["sqlite3_result_null",undefined, "*"],
812    ["sqlite3_result_text",undefined, "*", "string", "int", "*"],
813    ["sqlite3_serialize","*", "sqlite3*", "string", "*", "int"],
814    ["sqlite3_shutdown", undefined],
815    ["sqlite3_sourceid", "string"],
816    ["sqlite3_sql", "string", "sqlite3_stmt*"],
817    ["sqlite3_step", "int", "sqlite3_stmt*"],
818    ["sqlite3_strglob", "int", "string","string"],
819    ["sqlite3_strlike", "int", "string","string","int"],
820    ["sqlite3_trace_v2", "int", "sqlite3*", "int", "*", "*"],
821    ["sqlite3_total_changes", "int", "sqlite3*"],
822    ["sqlite3_uri_boolean", "int", "string", "string", "int"],
823    ["sqlite3_uri_key", "string", "string", "int"],
824    ["sqlite3_uri_parameter", "string", "string", "string"],
825    ["sqlite3_user_data","void*", "sqlite3_context*"],
826    ["sqlite3_value_blob", "*", "sqlite3_value*"],
827    ["sqlite3_value_bytes","int", "sqlite3_value*"],
828    ["sqlite3_value_double","f64", "sqlite3_value*"],
829    ["sqlite3_value_int","int", "sqlite3_value*"],
830    ["sqlite3_value_text", "string", "sqlite3_value*"],
831    ["sqlite3_value_type", "int", "sqlite3_value*"],
832    ["sqlite3_vfs_find", "*", "string"],
833    ["sqlite3_vfs_register", "int", "*", "int"]
834  ]/*wasm.bindingSignatures*/;
835
836  if(false && wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){
837    /* ^^^ "the problem" is that this is an option feature and the
838       build-time function-export list does not currently take
839       optional features into account. */
840    wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]);
841  }
842
843  /**
844     Functions which require BigInt (int64) support are separated from
845     the others because we need to conditionally bind them or apply
846     dummy impls, depending on the capabilities of the environment.
847  */
848  wasm.bindingSignatures.int64 = [
849    ["sqlite3_bind_int64","int", ["sqlite3_stmt*", "int", "i64"]],
850    ["sqlite3_changes64","i64", ["sqlite3*"]],
851    ["sqlite3_column_int64","i64", ["sqlite3_stmt*", "int"]],
852    ["sqlite3_malloc64", "*","i64"],
853    ["sqlite3_msize", "i64", "*"],
854    ["sqlite3_realloc64", "*","*", "i64"],
855    ["sqlite3_result_int64",undefined, "*", "i64"],
856    ["sqlite3_total_changes64", "i64", ["sqlite3*"]],
857    ["sqlite3_uri_int64", "i64", ["string", "string", "i64"]],
858    ["sqlite3_value_int64","i64", "sqlite3_value*"],
859  ];
860
861  /**
862     Functions which are intended solely for API-internal use by the
863     WASM components, not client code. These get installed into
864     capi.wasm.
865  */
866  wasm.bindingSignatures.wasm = [
867    ["sqlite3_wasm_db_reset", "int", "sqlite3*"],
868    ["sqlite3_wasm_db_vfs", "sqlite3_vfs*", "sqlite3*","string"],
869    ["sqlite3_wasm_vfs_unlink", "int", "sqlite3_vfs*","string"]
870  ];
871
872
873  /**
874     sqlite3.wasm.pstack (pseudo-stack) holds a special-case
875     stack-style allocator intended only for use with _small_ data of
876     not more than (in total) a few kb in size, managed as if it were
877     stack-based.
878
879     It has only a single intended usage:
880
881     ```
882     const stackPos = pstack.pointer;
883     try{
884       const ptr = pstack.alloc(8);
885       // ==> pstack.pointer === ptr
886       const otherPtr = pstack.alloc(8);
887       // ==> pstack.pointer === otherPtr
888       ...
889     }finally{
890       pstack.restore(stackPos);
891       // ==> pstack.pointer === stackPos
892     }
893     ```
894
895     This allocator is much faster than a general-purpose one but is
896     limited to usage patterns like the one shown above.
897
898     It operates from a static range of memory which lives outside of
899     space managed by Emscripten's stack-management, so does not
900     collide with Emscripten-provided stack allocation APIs. The
901     memory lives in the WASM heap and can be used with routines such
902     as wasm.setMemValue() and any wasm.heap8u().slice().
903  */
904  wasm.pstack = Object.assign(Object.create(null),{
905    /**
906       Sets the current pstack position to the given pointer. Results
907       are undefined if the passed-in value did not come from
908       this.pointer.
909    */
910    restore: wasm.exports.sqlite3_wasm_pstack_restore,
911    /**
912       Attempts to allocate the given number of bytes from the
913       pstack. On success, it zeroes out a block of memory of the
914       given size, adjusts the pstack pointer, and returns a pointer
915       to the memory. On error, returns throws a WasmAllocError. The
916       memory must eventually be released using restore().
917
918       This method always adjusts the given value to be a multiple
919       of 8 bytes because failing to do so can lead to incorrect
920       results when reading and writing 64-bit values from/to the WASM
921       heap. Similarly, the returned address is always 8-byte aligned.
922    */
923    alloc: (n)=>{
924      return wasm.exports.sqlite3_wasm_pstack_alloc(n)
925        || WasmAllocError.toss("Could not allocate",n,
926                               "bytes from the pstack.");
927    },
928    /**
929       alloc()'s n chunks, each sz bytes, as a single memory block and
930       returns the addresses as an array of n element, each holding
931       the address of one chunk.
932
933       Throws a WasmAllocError if allocation fails.
934
935       Example:
936
937       ```
938       const [p1, p2, p3] = wasm.pstack.allocChunks(3,4);
939       ```
940    */
941    allocChunks: (n,sz)=>{
942      const mem = wasm.pstack.alloc(n * sz);
943      const rc = [];
944      let i = 0, offset = 0;
945      for(; i < n; offset = (sz * ++i)){
946        rc.push(mem + offset);
947      }
948      return rc;
949    },
950    /**
951       A convenience wrapper for allocChunks() which sizes each chunk
952       as either 8 bytes (safePtrSize is truthy) or wasm.ptrSizeof (if
953       safePtrSize is falsy).
954
955       How it returns its result differs depending on its first
956       argument: if it's 1, it returns a single pointer value. If it's
957       more than 1, it returns the same as allocChunks().
958
959       When a returned pointers will refer to a 64-bit value, e.g. a
960       double or int64, and that value must be written or fetched,
961       e.g. using wasm.setMemValue() or wasm.getMemValue(), it is
962       important that the pointer in question be aligned to an 8-byte
963       boundary or else it will not be fetched or written properly and
964       will corrupt or read neighboring memory.
965
966       However, when all pointers involved point to "small" data, it
967       is safe to pass a falsy value to save a tiny bit of memory.
968    */
969    allocPtr: (n=1,safePtrSize=true)=>{
970      return 1===n
971        ? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof)
972        : wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof);
973    }
974  })/*wasm.pstack*/;
975  Object.defineProperties(wasm.pstack, {
976    /**
977       sqlite3.wasm.pstack.pointer resolves to the current pstack
978       position pointer. This value is intended _only_ to be saved
979       for passing to restore(). Writing to this memory, without
980       first reserving it via wasm.pstack.alloc() and friends, leads
981       to undefined results.
982    */
983    pointer: {
984      configurable: false, iterable: true, writeable: false,
985      get: wasm.exports.sqlite3_wasm_pstack_ptr
986      //Whether or not a setter as an alternative to restore() is
987      //clearer or would just lead to confusion is unclear.
988      //set: wasm.exports.sqlite3_wasm_pstack_restore
989    },
990    /**
991      Resolves to the total number of bytes available in the pstack,
992      including any space which is currently allocated. This value is
993      a compile-time constant.
994    */
995    quota: {
996      configurable: false, iterable: true, writeable: false,
997      get: wasm.exports.sqlite3_wasm_pstack_quota
998    }
999  })/*wasm.pstack properties*/;
1000
1001  /**
1002     sqlite3.wasm.pstack.remaining resolves to the amount of
1003     space remaining in the pstack.
1004  */
1005  Object.defineProperty(wasm.pstack, 'remaining', {
1006    configurable: false, iterable: true, writeable: false,
1007    get: wasm.exports.sqlite3_wasm_pstack_remaining
1008  });
1009
1010  /**
1011     An Error subclass specifically for reporting DB-level errors and
1012     enabling clients to unambiguously identify such exceptions.
1013     The C-level APIs never throw, but some of the higher-level
1014     C-style APIs do and the object-oriented APIs use exceptions
1015     exclusively to report errors.
1016  */
1017  class SQLite3Error extends Error {
1018    /**
1019       Constructs this object with a message equal to all arguments
1020       concatenated with a space between each one.
1021    */
1022    constructor(...args){
1023      super(args.join(' '));
1024      this.name = 'SQLite3Error';
1025    }
1026  };
1027  SQLite3Error.toss = (...args)=>{
1028    throw new SQLite3Error(args.join(' '));
1029  };
1030
1031  /** State for sqlite3_wasmfs_opfs_dir(). */
1032  let __persistentDir = undefined;
1033  /**
1034     If the wasm environment has a WASMFS/OPFS-backed persistent
1035     storage directory, its path is returned by this function. If it
1036     does not then it returns "" (noting that "" is a falsy value).
1037
1038     The first time this is called, this function inspects the current
1039     environment to determine whether persistence support is available
1040     and, if it is, enables it (if needed).
1041
1042     This function currently only recognizes the WASMFS/OPFS storage
1043     combination and its path refers to storage rooted in the
1044     Emscripten-managed virtual filesystem.
1045  */
1046  capi.sqlite3_wasmfs_opfs_dir = function(){
1047    if(undefined !== __persistentDir) return __persistentDir;
1048    // If we have no OPFS, there is no persistent dir
1049    const pdir = config.wasmfsOpfsDir;
1050    if(!pdir
1051       || !self.FileSystemHandle
1052       || !self.FileSystemDirectoryHandle
1053       || !self.FileSystemFileHandle){
1054      return __persistentDir = "";
1055    }
1056    try{
1057      if(pdir && 0===wasm.xCallWrapped(
1058        'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir
1059      )){
1060        return __persistentDir = pdir;
1061      }else{
1062        return __persistentDir = "";
1063      }
1064    }catch(e){
1065      // sqlite3_wasm_init_wasmfs() is not available
1066      return __persistentDir = "";
1067    }
1068  };
1069
1070  /**
1071     Experimental and subject to change or removal.
1072
1073     Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a
1074     non-empty string and the given name starts with (that string +
1075     '/'), else returns false.
1076  */
1077  capi.sqlite3_wasmfs_filename_is_persistent = function(name){
1078    const p = capi.sqlite3_wasmfs_opfs_dir();
1079    return (p && name) ? name.startsWith(p+'/') : false;
1080  };
1081
1082  // This bit is highly arguable and is incompatible with the fiddle shell.
1083  if(false && 0===wasm.exports.sqlite3_vfs_find(0)){
1084    /* Assume that sqlite3_initialize() has not yet been called.
1085       This will be the case in an SQLITE_OS_KV build. */
1086    wasm.exports.sqlite3_initialize();
1087  }
1088
1089  /**
1090     Given an `sqlite3*`, an sqlite3_vfs name, and an optional db
1091     name, returns a truthy value (see below) if that db handle uses
1092     that VFS, else returns false. If pDb is falsy then the 3rd
1093     argument is ignored and this function returns a truthy value if
1094     the default VFS name matches that of the 2nd argument. Results
1095     are undefined if pDb is truthy but refers to an invalid
1096     pointer. The 3rd argument specifies the database name of the
1097     given database connection to check, defaulting to the main db.
1098
1099     The 2nd and 3rd arguments may either be a JS string or a C-string
1100     allocated from the wasm environment.
1101
1102     The truthy value it returns is a pointer to the `sqlite3_vfs`
1103     object.
1104
1105     To permit safe use of this function from APIs which may be called
1106     via the C stack (like SQL UDFs), this function does not throw: if
1107     bad arguments cause a conversion error when passing into
1108     wasm-space, false is returned.
1109  */
1110  capi.sqlite3_web_db_uses_vfs = function(pDb,vfsName,dbName="main"){
1111    try{
1112      const pK = capi.sqlite3_vfs_find(vfsName);
1113      if(!pK) return false;
1114      else if(!pDb){
1115        return capi.sqlite3_vfs_find(0)===pK ? pK : false;
1116      }
1117      const ppVfs = wasm.allocPtr();
1118      try{
1119        return (
1120          (0===capi.sqlite3_file_control(
1121            pDb, dbName, capi.SQLITE_FCNTL_VFS_POINTER, ppVfs
1122          )) && (wasm.getPtrValue(ppVfs) === pK)
1123        ) ? pK : false;
1124      }finally{
1125        wasm.dealloc(ppVfs);
1126      }
1127    }catch(e){
1128      /* Ignore - probably bad args to a wasm-bound function. */
1129      return false;
1130    }
1131  };
1132
1133  /**
1134     Returns an array of the names of all currently-registered sqlite3
1135     VFSes.
1136  */
1137  capi.sqlite3_web_vfs_list = function(){
1138    const rc = [];
1139    let pVfs = capi.sqlite3_vfs_find(0);
1140    while(pVfs){
1141      const oVfs = new capi.sqlite3_vfs(pVfs);
1142      rc.push(wasm.cstringToJs(oVfs.$zName));
1143      pVfs = oVfs.$pNext;
1144      oVfs.dispose();
1145    }
1146    return rc;
1147  };
1148
1149  /**
1150     Serializes the given `sqlite3*` pointer to a Uint8Array, as per
1151     sqlite3_serialize(). On success it returns a Uint8Array. On
1152     error it throws with a description of the problem.
1153  */
1154  capi.sqlite3_web_db_export = function(pDb){
1155    if(!pDb) toss('Invalid sqlite3* argument.');
1156    if(!wasm.bigIntEnabled) toss('BigInt64 support is not enabled.');
1157    const stack = wasm.pstack.pointer;
1158    let pOut;
1159    try{
1160      const pSize = wasm.pstack.alloc(8/*i64*/ + wasm.ptrSizeof);
1161      const ppOut = pSize + 8;
1162      /**
1163         Maintenance reminder, since this cost a full hour of grief
1164         and confusion: if the order of pSize/ppOut are reversed in
1165         that memory block, fetching the value of pSize after the
1166         export reads a garbage size because it's not on an 8-byte
1167         memory boundary!
1168      */
1169      let rc = wasm.exports.sqlite3_wasm_db_serialize(
1170        pDb, ppOut, pSize, 0
1171      );
1172      if(rc){
1173        toss("Database serialization failed with code",
1174             sqlite3.capi.sqlite3_web_rc_str(rc));
1175      }
1176      pOut = wasm.getPtrValue(ppOut);
1177      const nOut = wasm.getMemValue(pSize, 'i64');
1178      rc = nOut
1179        ? wasm.heap8u().slice(pOut, pOut + Number(nOut))
1180        : new Uint8Array();
1181      return rc;
1182    }catch(e){
1183      console.error('internal error?',e);
1184      throw w;
1185    }finally{
1186      if(pOut) wasm.exports.sqlite3_free(pOut);
1187      wasm.pstack.restore(stack);
1188    }
1189  };
1190
1191  if( capi.util.isMainWindow() ){
1192    /* Features specific to the main window thread... */
1193
1194    /**
1195       Internal helper for sqlite3_web_kvvfs_clear() and friends.
1196       Its argument should be one of ('local','session','').
1197    */
1198    const __kvvfsInfo = function(which){
1199      const rc = Object.create(null);
1200      rc.prefix = 'kvvfs-'+which;
1201      rc.stores = [];
1202      if('session'===which || ''===which) rc.stores.push(self.sessionStorage);
1203      if('local'===which || ''===which) rc.stores.push(self.localStorage);
1204      return rc;
1205    };
1206
1207    /**
1208       Clears all storage used by the kvvfs DB backend, deleting any
1209       DB(s) stored there. Its argument must be either 'session',
1210       'local', or ''. In the first two cases, only sessionStorage
1211       resp. localStorage is cleared. If it's an empty string (the
1212       default) then both are cleared. Only storage keys which match
1213       the pattern used by kvvfs are cleared: any other client-side
1214       data are retained.
1215
1216       This function is only available in the main window thread.
1217
1218       Returns the number of entries cleared.
1219    */
1220    capi.sqlite3_web_kvvfs_clear = function(which=''){
1221      let rc = 0;
1222      const kvinfo = __kvvfsInfo(which);
1223      kvinfo.stores.forEach((s)=>{
1224        const toRm = [] /* keys to remove */;
1225        let i;
1226        for( i = 0; i < s.length; ++i ){
1227          const k = s.key(i);
1228          if(k.startsWith(kvinfo.prefix)) toRm.push(k);
1229        }
1230        toRm.forEach((kk)=>s.removeItem(kk));
1231        rc += toRm.length;
1232      });
1233      return rc;
1234    };
1235
1236    /**
1237       This routine guesses the approximate amount of
1238       window.localStorage and/or window.sessionStorage in use by the
1239       kvvfs database backend. Its argument must be one of
1240       ('session', 'local', ''). In the first two cases, only
1241       sessionStorage resp. localStorage is counted. If it's an empty
1242       string (the default) then both are counted. Only storage keys
1243       which match the pattern used by kvvfs are counted. The returned
1244       value is the "length" value of every matching key and value,
1245       noting that JavaScript stores each character in 2 bytes.
1246
1247       Note that the returned size is not authoritative from the
1248       perspective of how much data can fit into localStorage and
1249       sessionStorage, as the precise algorithms for determining
1250       those limits are unspecified and may include per-entry
1251       overhead invisible to clients.
1252    */
1253    capi.sqlite3_web_kvvfs_size = function(which=''){
1254      let sz = 0;
1255      const kvinfo = __kvvfsInfo(which);
1256      kvinfo.stores.forEach((s)=>{
1257        let i;
1258        for(i = 0; i < s.length; ++i){
1259          const k = s.key(i);
1260          if(k.startsWith(kvinfo.prefix)){
1261            sz += k.length;
1262            sz += s.getItem(k).length;
1263          }
1264        }
1265      });
1266      return sz * 2 /* because JS uses 2-byte char encoding */;
1267    };
1268
1269  }/* main-window-only bits */
1270
1271
1272  /* The remainder of the API will be set up in later steps. */
1273  const sqlite3 = {
1274    WasmAllocError: WasmAllocError,
1275    SQLite3Error: SQLite3Error,
1276    capi,
1277    config,
1278    /**
1279       Holds the version info of the sqlite3 source tree from which
1280       the generated sqlite3-api.js gets built. Note that its version
1281       may well differ from that reported by sqlite3_libversion(), but
1282       that should be considered a source file mismatch, as the JS and
1283       WASM files are intended to be built and distributed together.
1284
1285       This object is initially a placeholder which gets replaced by a
1286       build-generated object.
1287    */
1288    version: Object.create(null),
1289    /**
1290       Performs any optional asynchronous library-level initialization
1291       which might be required. This function returns a Promise which
1292       resolves to the sqlite3 namespace object. Any error in the
1293       async init will be fatal to the init as a whole, but init
1294       routines are themselves welcome to install dummy catch()
1295       handlers which are not fatal if their failure should be
1296       considered non-fatal. If called more than once, the second and
1297       subsequent calls are no-ops which return a pre-resolved
1298       Promise.
1299
1300       Ideally this function is called as part of the Promise chain
1301       which handles the loading and bootstrapping of the API.  If not
1302       then it must be called by client-level code, which must not use
1303       the library until the returned promise resolves.
1304
1305       Bug: if called while a prior call is still resolving, the 2nd
1306       call will resolve prematurely, before the 1st call has finished
1307       resolving. The current build setup precludes that possibility,
1308       so it's only a hypothetical problem if/when this function
1309       ever needs to be invoked by clients.
1310
1311       In Emscripten-based builds, this function is called
1312       automatically and deleted from this object.
1313    */
1314    asyncPostInit: async function(){
1315      let lip = sqlite3ApiBootstrap.initializersAsync;
1316      delete sqlite3ApiBootstrap.initializersAsync;
1317      if(!lip || !lip.length) return Promise.resolve(sqlite3);
1318      // Is it okay to resolve these in parallel or do we need them
1319      // to resolve in order? We currently only have 1, so it
1320      // makes no difference.
1321      lip = lip.map((f)=>{
1322        const p = (f instanceof Promise) ? f : f(sqlite3);
1323        return p.catch((e)=>{
1324          console.error("an async sqlite3 initializer failed:",e);
1325          throw e;
1326        });
1327      });
1328      //let p = lip.shift();
1329      //while(lip.length) p = p.then(lip.shift());
1330      //return p.then(()=>sqlite3);
1331      return Promise.all(lip).then(()=>sqlite3);
1332    },
1333    /**
1334       scriptInfo ideally gets injected into this object by the
1335       infrastructure which assembles the JS/WASM module. It contains
1336       state which must be collected before sqlite3ApiBootstrap() can
1337       be declared. It is not necessarily available to any
1338       sqlite3ApiBootstrap.initializers but "should" be in place (if
1339       it's added at all) by the time that
1340       sqlite3ApiBootstrap.initializersAsync is processed.
1341
1342       This state is not part of the public API, only intended for use
1343       with the sqlite3 API bootstrapping and wasm-loading process.
1344    */
1345    scriptInfo: undefined
1346  };
1347  try{
1348    sqlite3ApiBootstrap.initializers.forEach((f)=>{
1349      f(sqlite3);
1350    });
1351  }catch(e){
1352    /* If we don't report this here, it can get completely swallowed
1353       up and disappear into the abyss of Promises and Workers. */
1354    console.error("sqlite3 bootstrap initializer threw:",e);
1355    throw e;
1356  }
1357  delete sqlite3ApiBootstrap.initializers;
1358  sqlite3ApiBootstrap.sqlite3 = sqlite3;
1359  return sqlite3;
1360}/*sqlite3ApiBootstrap()*/;
1361/**
1362  self.sqlite3ApiBootstrap.initializers is an internal detail used by
1363  the various pieces of the sqlite3 API's amalgamation process. It
1364  must not be modified by client code except when plugging such code
1365  into the amalgamation process.
1366
1367  Each component of the amalgamation is expected to append a function
1368  to this array. When sqlite3ApiBootstrap() is called for the first
1369  time, each such function will be called (in their appended order)
1370  and passed the sqlite3 namespace object, into which they can install
1371  their features (noting that most will also require that certain
1372  features alread have been installed).  At the end of that process,
1373  this array is deleted.
1374
1375  Note that the order of insertion into this array is significant for
1376  some pieces. e.g. sqlite3.capi and sqlite3.capi.wasm cannot be fully
1377  utilized until the whwasmutil.js part is plugged in via
1378  sqlite3-api-glue.js.
1379*/
1380self.sqlite3ApiBootstrap.initializers = [];
1381/**
1382  self.sqlite3ApiBootstrap.initializersAsync is an internal detail
1383  used by the sqlite3 API's amalgamation process. It must not be
1384  modified by client code except when plugging such code into the
1385  amalgamation process.
1386
1387  The counterpart of self.sqlite3ApiBootstrap.initializers,
1388  specifically for initializers which are asynchronous. All entries in
1389  this list must be either async functions, non-async functions which
1390  return a Promise, or a Promise. Each function in the list is called
1391  with the sqlite3 ojbect as its only argument.
1392
1393  The resolved value of any Promise is ignored and rejection will kill
1394  the asyncPostInit() process (at an indeterminate point because all
1395  of them are run asynchronously in parallel).
1396
1397  This list is not processed until the client calls
1398  sqlite3.asyncPostInit(). This means, for example, that intializers
1399  added to self.sqlite3ApiBootstrap.initializers may push entries to
1400  this list.
1401*/
1402self.sqlite3ApiBootstrap.initializersAsync = [];
1403/**
1404   Client code may assign sqlite3ApiBootstrap.defaultConfig an
1405   object-type value before calling sqlite3ApiBootstrap() (without
1406   arguments) in order to tell that call to use this object as its
1407   default config value. The intention of this is to provide
1408   downstream clients with a reasonably flexible approach for plugging in
1409   an environment-suitable configuration without having to define a new
1410   global-scope symbol.
1411*/
1412self.sqlite3ApiBootstrap.defaultConfig = Object.create(null);
1413/**
1414   Placeholder: gets installed by the first call to
1415   self.sqlite3ApiBootstrap(). However, it is recommended that the
1416   caller of sqlite3ApiBootstrap() capture its return value and delete
1417   self.sqlite3ApiBootstrap after calling it. It returns the same
1418   value which will be stored here.
1419*/
1420self.sqlite3ApiBootstrap.sqlite3 = undefined;
1421
1422