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