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