4 The author disclaims copyright to this source code. In place of a
5 legal notice, here is a blessing:
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.
11 ***********************************************************************
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
15 whole file into an Emscripten Module.postRun() handler. The sqlite3
16 JS API has no hard requirements on Emscripten and does not expose
17 any Emscripten APIs to clients. It is structured such that its build
18 can be tweaked to include it in arbitrary WASM environments which
19 can supply the necessary underlying features (e.g. a POSIX file I/O
22 Main project home page: https://sqlite.org
24 Documentation home page: https://sqlite.org/wasm
28 sqlite3ApiBootstrap() is the only global symbol persistently
29 exposed by this API. It is intended to be called one time at the
30 end of the API amalgamation process, passed configuration details
31 for the current environment, and then optionally be removed from
32 the global object using `delete globalThis.sqlite3ApiBootstrap`.
34 This function is not intended for client-level use. It is intended
35 for use in creating bundles configured for specific WASM
38 This function expects a configuration object, intended to abstract
39 away details specific to any given WASM environment, primarily so
40 that it can be used without any direct dependency on
41 Emscripten. (Note the default values for the config object!) The
42 config object is only honored the first time this is
43 called. Subsequent calls ignore the argument and return the same
44 (configured) object which gets initialized by the first call. This
45 function will throw if any of the required config options are
48 The config object properties include:
50 - `exports`[^1]: the "exports" object for the current WASM
51 environment. In an Emscripten-based build, this should be set to
54 - `memory`[^1]: optional WebAssembly.Memory object, defaulting to
55 `exports.memory`. In Emscripten environments this should be set
56 to `Module.wasmMemory` if the build uses `-sIMPORTED_MEMORY`, or be
57 left undefined/falsy to default to `exports.memory` when using
60 - `bigIntEnabled`: true if BigInt support is enabled. Defaults to
61 true if `globalThis.BigInt64Array` is available, else false. Some APIs
62 will throw exceptions if called without BigInt support, as BigInt
63 is required for marshalling C-side int64 into and out of JS.
64 (Sidebar: it is technically possible to add int64 support via
65 marshalling of int32 pairs, but doing so is unduly invasive.)
67 - `allocExportName`: the name of the function, in `exports`, of the
68 `malloc(3)`-compatible routine for the WASM environment. Defaults
69 to `"sqlite3_malloc"`. Beware that using any allocator other than
70 sqlite3_malloc() may require care in certain client-side code
71 regarding which allocator is uses. Notably, sqlite3_deserialize()
72 and sqlite3_serialize() can only safely use memory from different
73 allocators under very specific conditions. The canonical builds
74 of this API guaranty that `sqlite3_malloc()` is the JS-side
75 allocator implementation.
77 - `deallocExportName`: the name of the function, in `exports`, of
78 the `free(3)`-compatible routine for the WASM
79 environment. Defaults to `"sqlite3_free"`.
81 - `reallocExportName`: the name of the function, in `exports`, of
82 the `realloc(3)`-compatible routine for the WASM
83 environment. Defaults to `"sqlite3_realloc"`.
85 - `debug`, `log`, `warn`, and `error` may be functions equivalent
86 to the like-named methods of the global `console` object. By
87 default, these map directly to their `console` counterparts, but
88 can be replaced with (e.g.) empty functions to squelch all such
91 - `wasmfsOpfsDir`[^1]: Specifies the "mount point" of the OPFS-backed
92 filesystem in WASMFS-capable builds.
95 [^1] = This property may optionally be a function, in which case
96 this function calls that function to fetch the value,
97 enabling delayed evaluation.
99 The returned object is the top-level sqlite3 namespace object.
102 Client code may optionally assign sqlite3ApiBootstrap.defaultConfig
103 an object-type value before calling sqlite3ApiBootstrap() (without
104 arguments) in order to tell that call to use this object as its
105 default config value. The intention of this is to provide
106 downstream clients with a reasonably flexible approach for plugging
107 in an environment-suitable configuration without having to define a
108 new global-scope symbol.
110 However, because clients who access this library via an
111 Emscripten-hosted module will not have an opportunity to call
112 sqlite3ApiBootstrap() themselves, nor to access it before it is
113 called, an alternative option for setting the configuration is to
114 define globalThis.sqlite3ApiConfig to an object. If it is set, it
115 is used instead of sqlite3ApiBootstrap.defaultConfig if
116 sqlite3ApiBootstrap() is called without arguments.
118 Both sqlite3ApiBootstrap.defaultConfig and
119 globalThis.sqlite3ApiConfig get deleted by sqlite3ApiBootstrap()
120 because any changes to them made after that point would have no
124 globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
125 apiConfig = (globalThis.sqlite3ApiConfig || sqlite3ApiBootstrap.defaultConfig)
127 if(sqlite3ApiBootstrap.sqlite3){ /* already initalized */
128 (sqlite3ApiBootstrap.sqlite3.config || console).warn(
129 "sqlite3ApiBootstrap() called multiple times.",
130 "Config and external initializers are ignored on calls after the first."
132 return sqlite3ApiBootstrap.sqlite3;
134 const config = Object.assign(Object.create(null),{
137 bigIntEnabled: (()=>{
138 if('undefined'!==typeof Module){
139 /* Emscripten module will contain HEAPU64 when built with
140 -sWASM_BIGINT=1, else it will not.
142 As of emsdk 3.1.55, when building in strict mode, HEAPxyz
143 are only available if _explicitly_ included in the exports,
144 else they are not. We do not (as of 2024-03-04) use -sSTRICT
145 for the canonical builds.
147 if( !!Module.HEAPU64 ) return true;
148 /* Else fall through and hope for the best. Nobody _really_
149 builds this without BigInt support, do they? */
151 return !!globalThis.BigInt64Array;
153 debug: console.debug.bind(console),
154 warn: console.warn.bind(console),
155 error: console.error.bind(console),
156 log: console.log.bind(console),
157 wasmfsOpfsDir: '/opfs',
159 useStdAlloc is just for testing allocator discrepancies. The
160 docs guarantee that this is false in the canonical builds. For
161 99% of purposes it doesn't matter which allocators we use, but
162 it becomes significant with, e.g., sqlite3_deserialize() and
163 certain wasm.xWrap.resultAdapter()s.
168 Object.assign(config, {
169 allocExportName: config.useStdAlloc ? 'malloc' : 'sqlite3_malloc',
170 deallocExportName: config.useStdAlloc ? 'free' : 'sqlite3_free',
171 reallocExportName: config.useStdAlloc ? 'realloc' : 'sqlite3_realloc'
175 // If any of these config options are functions, replace them with
176 // the result of calling that function...
177 'exports', 'memory', 'wasmfsOpfsDir'
179 if('function' === typeof config[k]){
180 config[k] = config[k]();
185 Eliminate any confusion about whether these config objects may
186 be used after library initialization by eliminating the outward-facing
189 delete globalThis.sqlite3ApiConfig;
190 delete sqlite3ApiBootstrap.defaultConfig;
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:
198 https://www.sqlite.org/c3ref/intro.html
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 documented somewhere below
203 in this file or in sqlite3-api-glue.js. capi members which are
204 not documented are installed as 1-to-1 proxies for their
207 const capi = Object.create(null);
209 Holds state which are specific to the WASM-related
210 infrastructure and glue code.
212 Note that a number of members of this object are injected
213 dynamically after the api object is fully constructed, so
214 not all are documented in this file.
216 const wasm = Object.create(null);
218 /** Internal helper for SQLite3Error ctor. */
219 const __rcStr = (rc)=>{
220 return (capi.sqlite3_js_rc_str && capi.sqlite3_js_rc_str(rc))
221 || ("Unknown result code #"+rc);
224 /** Internal helper for SQLite3Error ctor. */
225 const __isInt = (n)=>'number'===typeof n && n===(n | 0);
228 An Error subclass specifically for reporting DB-level errors and
229 enabling clients to unambiguously identify such exceptions.
230 The C-level APIs never throw, but some of the higher-level
231 C-style APIs do and the object-oriented APIs use exceptions
232 exclusively to report errors.
234 class SQLite3Error extends Error {
236 Constructs this object with a message depending on its arguments:
238 If its first argument is an integer, it is assumed to be
239 an SQLITE_... result code and it is passed to
240 sqlite3.capi.sqlite3_js_rc_str() to stringify it.
242 If called with exactly 2 arguments and the 2nd is an object,
243 that object is treated as the 2nd argument to the parent
246 The exception's message is created by concatenating its
247 arguments with a space between each, except for the
248 two-args-with-an-object form and that the first argument will
249 get coerced to a string, as described above, if it's an
252 If passed an integer first argument, the error object's
253 `resultCode` member will be set to the given integer value,
254 else it will be set to capi.SQLITE_ERROR.
256 constructor(...args){
259 if(__isInt(args[0])){
262 super(__rcStr(args[0]));
264 const rcStr = __rcStr(rc);
265 if('object'===typeof args[1]){
266 super(rcStr,args[1]);
269 super(args.join(' '));
273 if(2===args.length && 'object'===typeof args[1]){
276 super(args.join(' '));
280 this.resultCode = rc || capi.SQLITE_ERROR;
281 this.name = 'SQLite3Error';
286 Functionally equivalent to the SQLite3Error constructor but may
287 be used as part of an expression, e.g.:
290 return someFunction(x) || SQLite3Error.toss(...);
293 SQLite3Error.toss = (...args)=>{
294 throw new SQLite3Error(...args);
296 const toss3 = SQLite3Error.toss;
298 if(config.wasmfsOpfsDir && !/^\/[^/]+$/.test(config.wasmfsOpfsDir)){
299 toss3("config.wasmfsOpfsDir must be falsy or in the form '/dir-name'.");
303 Returns true if n is a 32-bit (signed) integer, else
304 false. This is used for determining when we need to switch to
305 double-type DB operations for integer values in order to keep
308 const isInt32 = (n)=>{
309 return ('bigint'!==typeof n /*TypeError: can't convert BigInt to number*/)
310 && !!(n===(n|0) && n<=2147483647 && n>=-2147483648);
313 Returns true if the given BigInt value is small enough to fit
314 into an int64 value, else false.
316 const bigIntFits64 = function f(b){
318 f._max = BigInt("0x7fffffffffffffff");
321 return b >= f._min && b <= f._max;
325 Returns true if the given BigInt value is small enough to fit
326 into an int32, else false.
328 const bigIntFits32 = (b)=>(b >= (-0x7fffffffn - 1n) && b <= 0x7fffffffn);
331 Returns true if the given BigInt value is small enough to fit
332 into a double value without loss of precision, else false.
334 const bigIntFitsDouble = function f(b){
336 f._min = Number.MIN_SAFE_INTEGER;
337 f._max = Number.MAX_SAFE_INTEGER;
339 return b >= f._min && b <= f._max;
342 /** Returns v if v appears to be a TypedArray, else false. */
343 const isTypedArray = (v)=>{
344 return (v && v.constructor && isInt32(v.constructor.BYTES_PER_ELEMENT)) ? v : false;
348 /** Internal helper to use in operations which need to distinguish
349 between TypedArrays which are backed by a SharedArrayBuffer
350 from those which are not. */
351 const __SAB = ('undefined'===typeof SharedArrayBuffer)
352 ? function(){} : SharedArrayBuffer;
353 /** Returns true if the given TypedArray object is backed by a
354 SharedArrayBuffer, else false. */
355 const isSharedTypedArray = (aTypedArray)=>(aTypedArray.buffer instanceof __SAB);
358 Returns either aTypedArray.slice(begin,end) (if
359 aTypedArray.buffer is a SharedArrayBuffer) or
360 aTypedArray.subarray(begin,end) (if it's not).
362 This distinction is important for APIs which don't like to
363 work on SABs, e.g. TextDecoder, and possibly for our
364 own APIs which work on memory ranges which "might" be
365 modified by other threads while they're working.
367 const typedArrayPart = (aTypedArray, begin, end)=>{
368 return isSharedTypedArray(aTypedArray)
369 ? aTypedArray.slice(begin, end)
370 : aTypedArray.subarray(begin, end);
374 Returns true if v appears to be one of our bind()-able TypedArray
375 types: Uint8Array or Int8Array or ArrayBuffer. Support for
376 TypedArrays with element sizes >1 is a potential TODO just
377 waiting on a use case to justify them. Until then, their `buffer`
378 property can be used to pass them as an ArrayBuffer. If it's not
379 a bindable array type, a falsy value is returned.
381 const isBindableTypedArray = (v)=>{
382 return v && (v instanceof Uint8Array
383 || v instanceof Int8Array
384 || v instanceof ArrayBuffer);
388 Returns true if v appears to be one of the TypedArray types
389 which is legal for holding SQL code (as opposed to binary blobs).
391 Currently this is the same as isBindableTypedArray() but it
392 seems likely that we'll eventually want to add Uint32Array
393 and friends to the isBindableTypedArray() list but not to the
394 isSQLableTypedArray() list.
396 const isSQLableTypedArray = (v)=>{
397 return v && (v instanceof Uint8Array
398 || v instanceof Int8Array
399 || v instanceof ArrayBuffer);
402 /** Returns true if isBindableTypedArray(v) does, else throws with a message
403 that v is not a supported TypedArray value. */
404 const affirmBindableTypedArray = (v)=>{
405 return isBindableTypedArray(v)
406 || toss3("Value is not of a supported TypedArray type.");
409 const utf8Decoder = new TextDecoder('utf-8');
412 Uses TextDecoder to decode the given half-open range of the
413 given TypedArray to a string. This differs from a simple
414 call to TextDecoder in that it accounts for whether the
415 first argument is backed by a SharedArrayBuffer or not,
416 and can work more efficiently if it's not (TextDecoder
417 refuses to act upon an SAB).
419 const typedArrayToString = function(typedArray, begin, end){
420 return utf8Decoder.decode(typedArrayPart(typedArray, begin,end));
424 If v is-a Array, its join("") result is returned. If
425 isSQLableTypedArray(v) is true then typedArrayToString(v) is
426 returned. If it looks like a WASM pointer, wasm.cstrToJs(v) is
427 returned. Else v is returned as-is.
429 const flexibleString = function(v){
430 if(isSQLableTypedArray(v)){
431 return typedArrayToString(
432 (v instanceof ArrayBuffer) ? new Uint8Array(v) : v
435 else if(Array.isArray(v)) return v.join("");
436 else if(wasm.isPtr(v)) v = wasm.cstrToJs(v);
441 An Error subclass specifically for reporting Wasm-level malloc()
442 failure and enabling clients to unambiguously identify such
445 class WasmAllocError extends Error {
447 If called with 2 arguments and the 2nd one is an object, it
448 behaves like the Error constructor, else it concatenates all
449 arguments together with a single space between each to
450 construct an error message string. As a special case, if
451 called with no arguments then it uses a default error
454 constructor(...args){
455 if(2===args.length && 'object'===typeof args[1]){
457 }else if(args.length){
458 super(args.join(' '));
460 super("Allocation failed.");
462 this.resultCode = capi.SQLITE_NOMEM;
463 this.name = 'WasmAllocError';
467 Functionally equivalent to the WasmAllocError constructor but may
468 be used as part of an expression, e.g.:
471 return someAllocatingFunction(x) || WasmAllocError.toss(...);
474 WasmAllocError.toss = (...args)=>{
475 throw new WasmAllocError(...args);
478 Object.assign(capi, {
480 sqlite3_bind_blob() works exactly like its C counterpart unless
481 its 3rd argument is one of:
483 - JS string: the 3rd argument is converted to a C string, the
484 4th argument is ignored, and the C-string's length is used
487 - Array: converted to a string as defined for "flexible
488 strings" and then it's treated as a JS string.
490 - Int8Array or Uint8Array: wasm.allocFromTypedArray() is used to
491 conver the memory to the WASM heap. If the 4th argument is
492 0 or greater, it is used as-is, otherwise the array's byteLength
493 value is used. This is an exception to the C API's undefined
494 behavior for a negative 4th argument, but results are undefined
495 if the given 4th argument value is greater than the byteLength
498 - If it's an ArrayBuffer, it gets wrapped in a Uint8Array and
499 treated as that type.
501 In all of those cases, the final argument (destructor) is
502 ignored and capi.SQLITE_WASM_DEALLOC is assumed.
504 A 3rd argument of `null` is treated as if it were a WASM pointer
507 If the 3rd argument is neither a WASM pointer nor one of the
508 above-described types, capi.SQLITE_MISUSE is returned.
510 The first argument may be either an `sqlite3_stmt*` WASM
511 pointer or an sqlite3.oo1.Stmt instance.
513 For consistency with the C API, it requires the same number of
514 arguments. It returns capi.SQLITE_MISUSE if passed any other
517 sqlite3_bind_blob: undefined/*installed later*/,
520 sqlite3_bind_text() works exactly like its C counterpart unless
521 its 3rd argument is one of:
523 - JS string: the 3rd argument is converted to a C string, the
524 4th argument is ignored, and the C-string's length is used
527 - Array: converted to a string as defined for "flexible
528 strings". The 4th argument is ignored and a value of -1
531 - Int8Array or Uint8Array: is assumed to contain UTF-8 text, is
532 converted to a string. The 4th argument is ignored, replaced
533 by the array's byteLength value.
535 - If it's an ArrayBuffer, it gets wrapped in a Uint8Array and
536 treated as that type.
538 In each of those cases, the final argument (text destructor) is
539 ignored and capi.SQLITE_WASM_DEALLOC is assumed.
541 A 3rd argument of `null` is treated as if it were a WASM pointer
544 If the 3rd argument is neither a WASM pointer nor one of the
545 above-described types, capi.SQLITE_MISUSE is returned.
547 The first argument may be either an `sqlite3_stmt*` WASM
548 pointer or an sqlite3.oo1.Stmt instance.
550 For consistency with the C API, it requires the same number of
551 arguments. It returns capi.SQLITE_MISUSE if passed any other
554 If client code needs to bind partial strings, it needs to
555 either parcel the string up before passing it in here or it
556 must pass in a WASM pointer for the 3rd argument and a valid
557 4th-argument value, taking care not to pass a value which
558 truncates a multi-byte UTF-8 character. When passing
559 WASM-format strings, it is important that the final argument be
560 valid or unexpected content can result can result, or even a
561 crash if the application reads past the WASM heap bounds.
563 sqlite3_bind_text: undefined/*installed later*/,
566 sqlite3_create_function_v2() differs from its native
567 counterpart only in the following ways:
569 1) The fourth argument (`eTextRep`) argument must not specify
570 any encoding other than sqlite3.SQLITE_UTF8. The JS API does not
571 currently support any other encoding and likely never
572 will. This function does not replace that argument on its own
573 because it may contain other flags. As a special case, if
574 the bottom 4 bits of that argument are 0, SQLITE_UTF8 is
577 2) Any of the four final arguments may be either WASM pointers
578 (assumed to be function pointers) or JS Functions. In the
579 latter case, each gets bound to WASM using
580 sqlite3.capi.wasm.installFunction() and that wrapper is passed
581 on to the native implementation.
583 For consistency with the C API, it requires the same number of
584 arguments. It returns capi.SQLITE_MISUSE if passed any other
587 The semantics of JS functions are:
589 xFunc: is passed `(pCtx, ...values)`. Its return value becomes
590 the new SQL function's result.
592 xStep: is passed `(pCtx, ...values)`. Its return value is
595 xFinal: is passed `(pCtx)`. Its return value becomes the new
596 aggregate SQL function's result.
598 xDestroy: is passed `(void*)`. Its return value is ignored. The
599 pointer passed to it is the one from the 5th argument to
600 sqlite3_create_function_v2().
604 - `pCtx` in the above descriptions is a `sqlite3_context*`. At
605 least 99 times out of a hundred, that initial argument will
606 be irrelevant for JS UDF bindings, but it needs to be there
607 so that the cases where it _is_ relevant, in particular with
608 window and aggregate functions, have full access to the
609 lower-level sqlite3 APIs.
611 - When wrapping JS functions, the remaining arguments are passd
612 to them as positional arguments, not as an array of
613 arguments, because that allows callback definitions to be
614 more JS-idiomatic than C-like. For example `(pCtx,a,b)=>a+b`
615 is more intuitive and legible than
616 `(pCtx,args)=>args[0]+args[1]`. For cases where an array of
617 arguments would be more convenient, the callbacks simply need
618 to be declared like `(pCtx,...args)=>{...}`, in which case
619 `args` will be an array.
621 - If a JS wrapper throws, it gets translated to
622 sqlite3_result_error() or sqlite3_result_error_nomem(),
623 depending on whether the exception is an
624 sqlite3.WasmAllocError object or not.
626 - When passing on WASM function pointers, arguments are _not_
627 converted or reformulated. They are passed on as-is in raw
628 pointer form using their native C signatures. Only JS
629 functions passed in to this routine, and thus wrapped by this
630 routine, get automatic conversions of arguments and result
631 values. The routines which perform those conversions are
632 exposed for client-side use as
633 sqlite3_create_function_v2.convertUdfArgs() and
634 sqlite3_create_function_v2.setUdfResult(). sqlite3_create_function()
635 and sqlite3_create_window_function() have those same methods.
637 For xFunc(), xStep(), and xFinal():
639 - When called from SQL, arguments to the UDF, and its result,
640 will be converted between JS and SQL with as much fidelity as
641 is feasible, triggering an exception if a type conversion
642 cannot be determined. Some freedom is afforded to numeric
643 conversions due to friction between the JS and C worlds:
644 integers which are larger than 32 bits may be treated as
647 If any JS-side bound functions throw, those exceptions are
648 intercepted and converted to database-side errors with the
649 exception of xDestroy(): any exception from it is ignored,
650 possibly generating a console.error() message. Destructors
653 Once installed, there is currently no way to uninstall the
654 automatically-converted WASM-bound JS functions from WASM. They
655 can be uninstalled from the database as documented in the C
656 API, but this wrapper currently has no infrastructure in place
657 to also free the WASM-bound JS wrappers, effectively resulting
658 in a memory leak if the client uninstalls the UDF. Improving that
659 is a potential TODO, but removing client-installed UDFs is rare
660 in practice. If this factor is relevant for a given client,
661 they can create WASM-bound JS functions themselves, hold on to their
662 pointers, and pass the pointers in to here. Later on, they can
663 free those pointers (using `wasm.uninstallFunction()` or
666 C reference: https://www.sqlite.org/c3ref/create_function.html
668 Maintenance reminder: the ability to add new
669 WASM-accessible functions to the runtime requires that the
670 WASM build is compiled with emcc's `-sALLOW_TABLE_GROWTH`
673 sqlite3_create_function_v2: (
674 pDb, funcName, nArg, eTextRep, pApp,
675 xFunc, xStep, xFinal, xDestroy
676 )=>{/*installed later*/},
678 Equivalent to passing the same arguments to
679 sqlite3_create_function_v2(), with 0 as the final argument.
681 sqlite3_create_function: (
682 pDb, funcName, nArg, eTextRep, pApp,
684 )=>{/*installed later*/},
686 The sqlite3_create_window_function() JS wrapper differs from
687 its native implementation in the exact same way that
688 sqlite3_create_function_v2() does. The additional function,
689 xInverse(), is treated identically to xStep() by the wrapping
692 sqlite3_create_window_function: (
693 pDb, funcName, nArg, eTextRep, pApp,
694 xStep, xFinal, xValue, xInverse, xDestroy
695 )=>{/*installed later*/},
697 The sqlite3_prepare_v3() binding handles two different uses
698 with differing JS/WASM semantics:
700 1) sqlite3_prepare_v3(pDb, sqlString, -1, prepFlags, ppStmt , null)
702 2) sqlite3_prepare_v3(pDb, sqlPointer, sqlByteLen, prepFlags, ppStmt, sqlPointerToPointer)
704 Note that the SQL length argument (the 3rd argument) must, for
705 usage (1), always be negative because it must be a byte length
706 and that value is expensive to calculate from JS (where only
707 the character length of strings is readily available). It is
708 retained in this API's interface for code/documentation
709 compatibility reasons but is currently _always_ ignored. With
710 usage (2), the 3rd argument is used as-is but is is still
711 critical that the C-style input string (2nd argument) be
712 terminated with a 0 byte.
714 In usage (1), the 2nd argument must be of type string,
715 Uint8Array, Int8Array, or ArrayBuffer (all of which are assumed
716 to hold SQL). If it is, this function assumes case (1) and
717 calls the underyling C function with the equivalent of:
719 (pDb, sqlAsString, -1, prepFlags, ppStmt, null)
721 The `pzTail` argument is ignored in this case because its
722 result is meaningless when a string-type value is passed
723 through: the string goes through another level of internal
724 conversion for WASM's sake and the result pointer would refer
725 to that transient conversion's memory, not the passed-in
728 If the sql argument is not a string, it must be a _pointer_ to
729 a NUL-terminated string which was allocated in the WASM memory
730 (e.g. using capi.wasm.alloc() or equivalent). In that case,
731 the final argument may be 0/null/undefined or must be a pointer
732 to which the "tail" of the compiled SQL is written, as
733 documented for the C-side sqlite3_prepare_v3(). In case (2),
734 the underlying C function is called with the equivalent of:
736 (pDb, sqlAsPointer, sqlByteLen, prepFlags, ppStmt, pzTail)
738 It returns its result and compiled statement as documented in
739 the C API. Fetching the output pointers (5th and 6th
740 parameters) requires using `capi.wasm.peek()` (or
741 equivalent) and the `pzTail` will point to an address relative to
742 the `sqlAsPointer` value.
744 If passed an invalid 2nd argument type, this function will
745 return SQLITE_MISUSE and sqlite3_errmsg() will contain a string
746 describing the problem.
748 Side-note: if given an empty string, or one which contains only
749 comments or an empty SQL expression, 0 is returned but the result
750 output pointer will be NULL.
752 sqlite3_prepare_v3: (dbPtr, sql, sqlByteLen, prepFlags,
753 stmtPtrPtr, strPtrPtr)=>{}/*installed later*/,
756 Equivalent to calling sqlite3_prapare_v3() with 0 as its 4th argument.
758 sqlite3_prepare_v2: (dbPtr, sql, sqlByteLen,
759 stmtPtrPtr,strPtrPtr)=>{}/*installed later*/,
762 This binding enables the callback argument to be a JavaScript.
764 If the callback is a function, then for the duration of the
765 sqlite3_exec() call, it installs a WASM-bound function which
766 acts as a proxy for the given callback. That proxy will also
767 perform a conversion of the callback's arguments from
768 `(char**)` to JS arrays of strings. However, for API
769 consistency's sake it will still honor the C-level callback
770 parameter order and will call it like:
772 `callback(pVoid, colCount, listOfValues, listOfColNames)`
774 If the callback is not a JS function then this binding performs
775 no translation of the callback, but the sql argument is still
776 converted to a WASM string for the call using the
777 "string:flexible" argument converter.
779 sqlite3_exec: (pDb, sql, callback, pVoid, pErrMsg)=>{}/*installed later*/,
782 If passed a single argument which appears to be a byte-oriented
783 TypedArray (Int8Array or Uint8Array), this function treats that
784 TypedArray as an output target, fetches `theArray.byteLength`
785 bytes of randomness, and populates the whole array with it. As
786 a special case, if the array's length is 0, this function
787 behaves as if it were passed (0,0). When called this way, it
788 returns its argument, else it returns the `undefined` value.
790 If called with any other arguments, they are passed on as-is
791 to the C API. Results are undefined if passed any incompatible
794 sqlite3_randomness: (n, outPtr)=>{/*installed later*/},
798 Various internal-use utilities are added here as needed. They
799 are bound to an object only so that we have access to them in
800 the differently-scoped steps of the API bootstrapping
801 process. At the end of the API setup process, this object gets
802 removed. These are NOT part of the public API.
805 affirmBindableTypedArray, flexibleString,
806 bigIntFits32, bigIntFits64, bigIntFitsDouble,
807 isBindableTypedArray,
808 isInt32, isSQLableTypedArray, isTypedArray,
810 isUIThread: ()=>(globalThis.window===globalThis && !!globalThis.document),
811 // is this true for ESM?: 'undefined'===typeof WorkerGlobalScope
813 toss: function(...args){throw new Error(args.join(' '))},
817 Given a byte array or ArrayBuffer, this function throws if the
818 lead bytes of that buffer do not hold a SQLite3 database header,
819 else it returns without side effects.
823 affirmDbHeader: function(bytes){
824 if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes);
825 const header = "SQLite format 3";
826 if( header.length > bytes.byteLength ){
827 toss3("Input does not contain an SQLite3 database header.");
829 for(let i = 0; i < header.length; ++i){
830 if( header.charCodeAt(i) !== bytes[i] ){
831 toss3("Input does not contain an SQLite3 database header.");
836 Given a byte array or ArrayBuffer, this function throws if the
837 database does not, at a cursory glance, appear to be an SQLite3
838 database. It only examines the size and header, but further
839 checks may be added in the future.
843 affirmIsDb: function(bytes){
844 if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes);
845 const n = bytes.byteLength;
846 if(n<512 || n%512!==0) {
847 toss3("Byte array size",n,"is invalid for an SQLite3 db.");
849 util.affirmDbHeader(bytes);
853 Object.assign(wasm, {
855 Emscripten APIs have a deep-seated assumption that all pointers
856 are 32 bits. We'll remain optimistic that that won't always be
857 the case and will use this constant in places where we might
858 otherwise use a hard-coded 4.
860 ptrSizeof: config.wasmPtrSizeof || 4,
862 The WASM IR (Intermediate Representation) value for
863 pointer-type values. It MUST refer to a value type of the
864 size described by this.ptrSizeof.
866 ptrIR: config.wasmPtrIR || "i32",
868 True if BigInt support was enabled via (e.g.) the
869 Emscripten -sWASM_BIGINT flag, else false. When
870 enabled, certain 64-bit sqlite3 APIs are enabled which
871 are not otherwise enabled due to JS/WASM int64
872 impedence mismatches.
874 bigIntEnabled: !!config.bigIntEnabled,
876 The symbols exported by the WASM environment.
878 exports: config.exports
879 || toss3("Missing API config.exports (WASM module exports)."),
882 When Emscripten compiles with `-sIMPORTED_MEMORY`, it
883 initalizes the heap and imports it into wasm, as opposed to
884 the other way around. In this case, the memory is not
885 available via this.exports.memory.
887 memory: config.memory || config.exports['memory']
888 || toss3("API config object requires a WebAssembly.Memory object",
889 "in either config.exports.memory (exported)",
890 "or config.memory (imported)."),
893 The API's primary point of access to the WASM-side memory
894 allocator. Works like sqlite3_malloc() but throws a
895 WasmAllocError if allocation fails. It is important that any
896 code which might pass through the sqlite3 C API NOT throw and
897 must instead return SQLITE_NOMEM (or equivalent, depending on
900 Very few cases in the sqlite3 JS APIs can result in
901 client-defined functions propagating exceptions via the C-style
902 API. Most notably, this applies to WASM-bound JS functions
903 which are created directly by clients and passed on _as WASM
904 function pointers_ to functions such as
905 sqlite3_create_function_v2(). Such bindings created
906 transparently by this API will automatically use wrappers which
907 catch exceptions and convert them to appropriate error codes.
909 For cases where non-throwing allocation is required, use
910 this.alloc.impl(), which is direct binding of the
911 underlying C-level allocator.
913 Design note: this function is not named "malloc" primarily
914 because Emscripten uses that name and we wanted to avoid any
915 confusion early on in this code's development, when it still
916 had close ties to Emscripten's glue code.
918 alloc: undefined/*installed later*/,
921 Rarely necessary in JS code, this routine works like
922 sqlite3_realloc(M,N), where M is either NULL or a pointer
923 obtained from this function or this.alloc() and N is the number
924 of bytes to reallocate the block to. Returns a pointer to the
925 reallocated block or 0 if allocation fails.
927 If M is NULL and N is positive, this behaves like
928 this.alloc(N). If N is 0, it behaves like this.dealloc().
929 Results are undefined if N is negative (sqlite3_realloc()
930 treats that as 0, but if this code is built with a different
931 allocator it may misbehave with negative values).
933 Like this.alloc.impl(), this.realloc.impl() is a direct binding
934 to the underlying realloc() implementation which does not throw
935 exceptions, instead returning 0 on allocation error.
937 realloc: undefined/*installed later*/,
940 The API's primary point of access to the WASM-side memory
941 deallocator. Works like sqlite3_free().
943 Design note: this function is not named "free" for the same
944 reason that this.alloc() is not called this.malloc().
946 dealloc: undefined/*installed later*/
948 /* Many more wasm-related APIs get installed later on. */
952 wasm.alloc()'s srcTypedArray.byteLength bytes,
953 populates them with the values from the source
954 TypedArray, and returns the pointer to that memory. The
955 returned pointer must eventually be passed to
956 wasm.dealloc() to clean it up.
958 The argument may be a Uint8Array, Int8Array, or ArrayBuffer,
959 and it throws if passed any other type.
961 As a special case, to avoid further special cases where
962 this is used, if srcTypedArray.byteLength is 0, it
963 allocates a single byte and sets it to the value
964 0. Even in such cases, calls must behave as if the
965 allocated memory has exactly srcTypedArray.byteLength
968 wasm.allocFromTypedArray = function(srcTypedArray){
969 if(srcTypedArray instanceof ArrayBuffer){
970 srcTypedArray = new Uint8Array(srcTypedArray);
972 affirmBindableTypedArray(srcTypedArray);
973 const pRet = wasm.alloc(srcTypedArray.byteLength || 1);
974 wasm.heapForSize(srcTypedArray.constructor).set(
975 srcTypedArray.byteLength ? srcTypedArray : [0], pRet
981 // Set up allocators...
982 const keyAlloc = config.allocExportName,
983 keyDealloc = config.deallocExportName,
984 keyRealloc = config.reallocExportName;
985 for(const key of [keyAlloc, keyDealloc, keyRealloc]){
986 const f = wasm.exports[key];
987 if(!(f instanceof Function)) toss3("Missing required exports[",key,"] function.");
990 wasm.alloc = function f(n){
991 return f.impl(n) || WasmAllocError.toss("Failed to allocate",n," bytes.");
993 wasm.alloc.impl = wasm.exports[keyAlloc];
994 wasm.realloc = function f(m,n){
995 const m2 = f.impl(m,n);
996 return n ? (m2 || WasmAllocError.toss("Failed to reallocate",n," bytes.")) : 0;
998 wasm.realloc.impl = wasm.exports[keyRealloc];
999 wasm.dealloc = wasm.exports[keyDealloc];
1003 Reports info about compile-time options using
1004 sqlite3_compileoption_get() and sqlite3_compileoption_used(). It
1005 has several distinct uses:
1007 If optName is an array then it is expected to be a list of
1008 compilation options and this function returns an object
1009 which maps each such option to true or false, indicating
1010 whether or not the given option was included in this
1011 build. That object is returned.
1013 If optName is an object, its keys are expected to be compilation
1014 options and this function sets each entry to true or false,
1015 indicating whether the compilation option was used or not. That
1018 If passed no arguments then it returns an object mapping
1019 all known compilation options to their compile-time values,
1020 or boolean true if they are defined with no value. This
1021 result, which is relatively expensive to compute, is cached
1022 and returned for future no-argument calls.
1024 In all other cases it returns true if the given option was
1025 active when when compiling the sqlite3 module, else false.
1027 Compile-time option names may optionally include their
1028 "SQLITE_" prefix. When it returns an object of all options,
1029 the prefix is elided.
1031 wasm.compileOptionUsed = function f(optName){
1032 if(!arguments.length){
1033 if(f._result) return f._result;
1035 f._rx = /^([^=]+)=(.+)/;
1036 f._rxInt = /^-?\d+$/;
1037 f._opt = function(opt, rv){
1038 const m = f._rx.exec(opt);
1039 rv[0] = (m ? m[1] : opt);
1040 rv[1] = m ? (f._rxInt.test(m[2]) ? +m[2] : m[2]) : true;
1043 const rc = {}, ov = [0,0];
1045 while((k = capi.sqlite3_compileoption_get(i++))){
1049 return f._result = rc;
1050 }else if(Array.isArray(optName)){
1052 optName.forEach((v)=>{
1053 rc[v] = capi.sqlite3_compileoption_used(v);
1056 }else if('object' === typeof optName){
1057 Object.keys(optName).forEach((k)=> {
1058 optName[k] = capi.sqlite3_compileoption_used(k);
1063 'string'===typeof optName
1064 ) ? !!capi.sqlite3_compileoption_used(optName) : false;
1065 }/*compileOptionUsed()*/;
1068 sqlite3.wasm.pstack (pseudo-stack) holds a special-case
1069 stack-style allocator intended only for use with _small_ data of
1070 not more than (in total) a few kb in size, managed as if it were
1073 It has only a single intended usage:
1076 const stackPos = pstack.pointer;
1078 const ptr = pstack.alloc(8);
1079 // ==> pstack.pointer === ptr
1080 const otherPtr = pstack.alloc(8);
1081 // ==> pstack.pointer === otherPtr
1084 pstack.restore(stackPos);
1085 // ==> pstack.pointer === stackPos
1089 This allocator is much faster than a general-purpose one but is
1090 limited to usage patterns like the one shown above.
1092 It operates from a static range of memory which lives outside of
1093 space managed by Emscripten's stack-management, so does not
1094 collide with Emscripten-provided stack allocation APIs. The
1095 memory lives in the WASM heap and can be used with routines such
1096 as wasm.poke() and wasm.heap8u().slice().
1098 wasm.pstack = Object.assign(Object.create(null),{
1100 Sets the current pstack position to the given pointer. Results
1101 are undefined if the passed-in value did not come from
1104 restore: wasm.exports.sqlite3__wasm_pstack_restore,
1106 Attempts to allocate the given number of bytes from the
1107 pstack. On success, it zeroes out a block of memory of the
1108 given size, adjusts the pstack pointer, and returns a pointer
1109 to the memory. On error, throws a WasmAllocError. The
1110 memory must eventually be released using restore().
1112 If n is a string, it must be a WASM "IR" value in the set
1113 accepted by wasm.sizeofIR(), which is mapped to the size of
1114 that data type. If passed a string not in that set, it throws a
1117 This method always adjusts the given value to be a multiple
1118 of 8 bytes because failing to do so can lead to incorrect
1119 results when reading and writing 64-bit values from/to the WASM
1120 heap. Similarly, the returned address is always 8-byte aligned.
1123 if('string'===typeof n && !(n = wasm.sizeofIR(n))){
1124 WasmAllocError.toss("Invalid value for pstack.alloc(",arguments[0],")");
1126 return wasm.exports.sqlite3__wasm_pstack_alloc(n)
1127 || WasmAllocError.toss("Could not allocate",n,
1128 "bytes from the pstack.");
1131 alloc()'s n chunks, each sz bytes, as a single memory block and
1132 returns the addresses as an array of n element, each holding
1133 the address of one chunk.
1135 sz may optionally be an IR string accepted by wasm.sizeofIR().
1137 Throws a WasmAllocError if allocation fails.
1142 const [p1, p2, p3] = wasm.pstack.allocChunks(3,4);
1145 allocChunks: function(n,sz){
1146 if('string'===typeof sz && !(sz = wasm.sizeofIR(sz))){
1147 WasmAllocError.toss("Invalid size value for allocChunks(",arguments[1],")");
1149 const mem = wasm.pstack.alloc(n * sz);
1151 let i = 0, offset = 0;
1152 for(; i < n; ++i, offset += sz) rc.push(mem + offset);
1156 A convenience wrapper for allocChunks() which sizes each chunk
1157 as either 8 bytes (safePtrSize is truthy) or wasm.ptrSizeof (if
1158 safePtrSize is falsy).
1160 How it returns its result differs depending on its first
1161 argument: if it's 1, it returns a single pointer value. If it's
1162 more than 1, it returns the same as allocChunks().
1164 When a returned pointers will refer to a 64-bit value, e.g. a
1165 double or int64, and that value must be written or fetched,
1166 e.g. using wasm.poke() or wasm.peek(), it is
1167 important that the pointer in question be aligned to an 8-byte
1168 boundary or else it will not be fetched or written properly and
1169 will corrupt or read neighboring memory.
1171 However, when all pointers involved point to "small" data, it
1172 is safe to pass a falsy value to save a tiny bit of memory.
1174 allocPtr: (n=1,safePtrSize=true)=>{
1176 ? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof)
1177 : wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof);
1181 Records the current pstack position, calls the given function,
1182 passing it the sqlite3 object, then restores the pstack
1183 regardless of whether the function throws. Returns the result
1184 of the call or propagates an exception on error.
1189 const stackPos = wasm.pstack.pointer;
1190 try{ return f(sqlite3) } finally{
1191 wasm.pstack.restore(stackPos);
1196 Object.defineProperties(wasm.pstack, {
1198 sqlite3.wasm.pstack.pointer resolves to the current pstack
1199 position pointer. This value is intended _only_ to be saved
1200 for passing to restore(). Writing to this memory, without
1201 first reserving it via wasm.pstack.alloc() and friends, leads
1202 to undefined results.
1205 configurable: false, iterable: true, writeable: false,
1206 get: wasm.exports.sqlite3__wasm_pstack_ptr
1207 //Whether or not a setter as an alternative to restore() is
1208 //clearer or would just lead to confusion is unclear.
1209 //set: wasm.exports.sqlite3__wasm_pstack_restore
1212 sqlite3.wasm.pstack.quota to the total number of bytes
1213 available in the pstack, including any space which is currently
1214 allocated. This value is a compile-time constant.
1217 configurable: false, iterable: true, writeable: false,
1218 get: wasm.exports.sqlite3__wasm_pstack_quota
1221 sqlite3.wasm.pstack.remaining resolves to the amount of space
1222 remaining in the pstack.
1225 configurable: false, iterable: true, writeable: false,
1226 get: wasm.exports.sqlite3__wasm_pstack_remaining
1228 })/*wasm.pstack properties*/;
1230 capi.sqlite3_randomness = (...args)=>{
1231 if(1===args.length && util.isTypedArray(args[0])
1232 && 1===args[0].BYTES_PER_ELEMENT){
1234 if(0===ta.byteLength){
1235 wasm.exports.sqlite3_randomness(0,0);
1238 const stack = wasm.pstack.pointer;
1240 let n = ta.byteLength, offset = 0;
1241 const r = wasm.exports.sqlite3_randomness;
1242 const heap = wasm.heap8u();
1243 const nAlloc = n < 512 ? n : 512;
1244 const ptr = wasm.pstack.alloc(nAlloc);
1246 const j = (n>nAlloc ? nAlloc : n);
1248 ta.set(typedArrayPart(heap, ptr, ptr+j), offset);
1253 console.error("Highly unexpected (and ignored!) "+
1254 "exception in sqlite3_randomness():",e);
1256 wasm.pstack.restore(stack);
1260 wasm.exports.sqlite3_randomness(...args);
1263 /** State for sqlite3_wasmfs_opfs_dir(). */
1264 let __wasmfsOpfsDir = undefined;
1266 If the wasm environment has a WASMFS/OPFS-backed persistent
1267 storage directory, its path is returned by this function. If it
1268 does not then it returns "" (noting that "" is a falsy value).
1270 The first time this is called, this function inspects the current
1271 environment to determine whether persistence support is available
1272 and, if it is, enables it (if needed). After the first call it
1273 always returns the cached result.
1275 If the returned string is not empty, any files stored under the
1276 given path (recursively) are housed in OPFS storage. If the
1277 returned string is empty, this particular persistent storage
1278 option is not available on the client.
1280 Though the mount point name returned by this function is intended
1281 to remain stable, clients should not hard-coded it anywhere. Always call this function to get the path.
1283 Note that this function is a no-op in must builds of this
1284 library, as the WASMFS capability requires a custom
1287 capi.sqlite3_wasmfs_opfs_dir = function(){
1288 if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir;
1289 // If we have no OPFS, there is no persistent dir
1290 const pdir = config.wasmfsOpfsDir;
1292 || !globalThis.FileSystemHandle
1293 || !globalThis.FileSystemDirectoryHandle
1294 || !globalThis.FileSystemFileHandle){
1295 return __wasmfsOpfsDir = "";
1298 if(pdir && 0===wasm.xCallWrapped(
1299 'sqlite3__wasm_init_wasmfs', 'i32', ['string'], pdir
1301 return __wasmfsOpfsDir = pdir;
1303 return __wasmfsOpfsDir = "";
1306 // sqlite3__wasm_init_wasmfs() is not available
1307 return __wasmfsOpfsDir = "";
1312 Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a
1313 non-empty string and the given name starts with (that string +
1314 '/'), else returns false.
1316 capi.sqlite3_wasmfs_filename_is_persistent = function(name){
1317 const p = capi.sqlite3_wasmfs_opfs_dir();
1318 return (p && name) ? name.startsWith(p+'/') : false;
1322 Given an `sqlite3*`, an sqlite3_vfs name, and an optional db name
1323 (defaulting to "main"), returns a truthy value (see below) if
1324 that db uses that VFS, else returns false. If pDb is falsy then
1325 the 3rd argument is ignored and this function returns a truthy
1326 value if the default VFS name matches that of the 2nd
1327 argument. Results are undefined if pDb is truthy but refers to an
1328 invalid pointer. The 3rd argument specifies the database name of
1329 the given database connection to check, defaulting to the main
1332 The 2nd and 3rd arguments may either be a JS string or a WASM
1333 C-string. If the 2nd argument is a NULL WASM pointer, the default
1334 VFS is assumed. If the 3rd is a NULL WASM pointer, "main" is
1337 The truthy value it returns is a pointer to the `sqlite3_vfs`
1340 To permit safe use of this function from APIs which may be called
1341 via the C stack (like SQL UDFs), this function does not throw: if
1342 bad arguments cause a conversion error when passing into
1343 wasm-space, false is returned.
1345 capi.sqlite3_js_db_uses_vfs = function(pDb,vfsName,dbName=0){
1347 const pK = capi.sqlite3_vfs_find(vfsName);
1348 if(!pK) return false;
1350 return pK===capi.sqlite3_vfs_find(0) ? pK : false;
1352 return pK===capi.sqlite3_js_db_vfs(pDb,dbName) ? pK : false;
1355 /* Ignore - probably bad args to a wasm-bound function. */
1361 Returns an array of the names of all currently-registered sqlite3
1364 capi.sqlite3_js_vfs_list = function(){
1366 let pVfs = capi.sqlite3_vfs_find(0);
1368 const oVfs = new capi.sqlite3_vfs(pVfs);
1369 rc.push(wasm.cstrToJs(oVfs.$zName));
1377 A convenience wrapper around sqlite3_serialize() which serializes
1378 the given `sqlite3*` pointer to a Uint8Array. The first argument
1379 may be either an `sqlite3*` or an sqlite3.oo1.DB instance.
1381 On success it returns a Uint8Array. If the schema is empty, an
1382 empty array is returned.
1384 `schema` is the schema to serialize. It may be a WASM C-string
1385 pointer or a JS string. If it is falsy, it defaults to `"main"`.
1387 On error it throws with a description of the problem.
1389 capi.sqlite3_js_db_export = function(pDb, schema=0){
1390 pDb = wasm.xWrap.testConvertArg('sqlite3*', pDb);
1391 if(!pDb) toss3('Invalid sqlite3* argument.');
1392 if(!wasm.bigIntEnabled) toss3('BigInt64 support is not enabled.');
1393 const scope = wasm.scopedAllocPush();
1396 const pSize = wasm.scopedAlloc(8/*i64*/ + wasm.ptrSizeof);
1397 const ppOut = pSize + 8;
1399 Maintenance reminder, since this cost a full hour of grief
1400 and confusion: if the order of pSize/ppOut are reversed in
1401 that memory block, fetching the value of pSize after the
1402 export reads a garbage size because it's not on an 8-byte
1405 const zSchema = schema
1406 ? (wasm.isPtr(schema) ? schema : wasm.scopedAllocCString(''+schema))
1408 let rc = wasm.exports.sqlite3__wasm_db_serialize(
1409 pDb, zSchema, ppOut, pSize, 0
1412 toss3("Database serialization failed with code",
1413 sqlite3.capi.sqlite3_js_rc_str(rc));
1415 pOut = wasm.peekPtr(ppOut);
1416 const nOut = wasm.peek(pSize, 'i64');
1418 ? wasm.heap8u().slice(pOut, pOut + Number(nOut))
1422 if(pOut) wasm.exports.sqlite3_free(pOut);
1423 wasm.scopedAllocPop(scope);
1428 Given a `sqlite3*` and a database name (JS string or WASM
1429 C-string pointer, which may be 0), returns a pointer to the
1430 sqlite3_vfs responsible for it. If the given db name is null/0,
1431 or not provided, then "main" is assumed.
1433 capi.sqlite3_js_db_vfs =
1434 (dbPointer, dbName=0)=>util.sqlite3__wasm_db_vfs(dbPointer, dbName);
1437 A thin wrapper around capi.sqlite3_aggregate_context() which
1438 behaves the same except that it throws a WasmAllocError if that
1439 function returns 0. As a special case, if n is falsy it does
1440 _not_ throw if that function returns 0. That special case is
1441 intended for use with xFinal() implementations.
1443 capi.sqlite3_js_aggregate_context = (pCtx, n)=>{
1444 return capi.sqlite3_aggregate_context(pCtx, n)
1445 || (n ? WasmAllocError.toss("Cannot allocate",n,
1446 "bytes for sqlite3_aggregate_context()")
1451 If the current environment supports the POSIX file APIs, this routine
1452 creates (or overwrites) the given file using those APIs. This is
1453 primarily intended for use in Emscripten-based builds where the POSIX
1454 APIs are transparently proxied by an in-memory virtual filesystem.
1455 It may behave diffrently in other environments.
1457 The first argument must be either a JS string or WASM C-string
1458 holding the filename. Note that this routine does _not_ create
1459 intermediary directories if the filename has a directory part.
1461 The 2nd argument may either a valid WASM memory pointer, an
1462 ArrayBuffer, or a Uint8Array. The 3rd must be the length, in
1463 bytes, of the data array to copy. If the 2nd argument is an
1464 ArrayBuffer or Uint8Array and the 3rd is not a positive integer
1465 then the 3rd defaults to the array's byteLength value.
1467 Results are undefined if data is a WASM pointer and dataLen is
1468 exceeds data's bounds.
1470 Throws if any arguments are invalid or if creating or writing to
1473 Added in 3.43 as an alternative for the deprecated
1474 sqlite3_js_vfs_create_file().
1476 capi.sqlite3_js_posix_create_file = function(filename, data, dataLen){
1478 if(data && wasm.isPtr(data)){
1480 }else if(data instanceof ArrayBuffer || data instanceof Uint8Array){
1481 pData = wasm.allocFromTypedArray(data);
1482 if(arguments.length<3 || !util.isInt32(dataLen) || dataLen<0){
1483 dataLen = data.byteLength;
1486 SQLite3Error.toss("Invalid 2nd argument for sqlite3_js_posix_create_file().");
1489 if(!util.isInt32(dataLen) || dataLen<0){
1490 SQLite3Error.toss("Invalid 3rd argument for sqlite3_js_posix_create_file().");
1492 const rc = util.sqlite3__wasm_posix_create_file(filename, pData, dataLen);
1493 if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code",
1494 capi.sqlite3_js_rc_str(rc));
1496 wasm.dealloc(pData);
1501 Deprecation warning: this function does not work properly in
1502 debug builds of sqlite3 because its out-of-scope use of the
1503 sqlite3_vfs API triggers assertions in the core library. That
1504 was unfortunately not discovered until 2023-08-11. This function
1505 is now deprecated and should not be used in new code.
1507 Alternative options:
1509 - "unix" VFS and its variants can get equivalent functionality
1510 with sqlite3_js_posix_create_file().
1512 - OPFS: use either sqlite3.oo1.OpfsDb.importDb(), for the "opfs"
1513 VFS, or the importDb() method of the PoolUtil object provided
1514 by the "opfs-sahpool" OPFS (noting that its VFS name may differ
1515 depending on client-side configuration). We cannot proxy those
1516 from here because the former is necessarily asynchronous and
1517 the latter requires information not available to this function.
1519 Creates a file using the storage appropriate for the given
1520 sqlite3_vfs. The first argument may be a VFS name (JS string
1521 only, NOT a WASM C-string), WASM-managed `sqlite3_vfs*`, or
1522 a capi.sqlite3_vfs instance. Pass 0 (a NULL pointer) to use the
1523 default VFS. If passed a string which does not resolve using
1524 sqlite3_vfs_find(), an exception is thrown. (Note that a WASM
1525 C-string is not accepted because it is impossible to
1526 distinguish from a C-level `sqlite3_vfs*`.)
1528 The second argument, the filename, must be a JS or WASM C-string.
1530 The 3rd may either be falsy, a valid WASM memory pointer, an
1531 ArrayBuffer, or a Uint8Array. The 4th must be the length, in
1532 bytes, of the data array to copy. If the 3rd argument is an
1533 ArrayBuffer or Uint8Array and the 4th is not a positive integer
1534 then the 4th defaults to the array's byteLength value.
1536 If data is falsy then a file is created with dataLen bytes filled
1537 with uninitialized data (whatever truncate() leaves there). If
1538 data is not falsy then a file is created or truncated and it is
1539 filled with the first dataLen bytes of the data source.
1541 Throws if any arguments are invalid or if creating or writing to
1544 Note that most VFSes do _not_ automatically create directory
1545 parts of filenames, nor do all VFSes have a concept of
1546 directories. If the given filename is not valid for the given
1547 VFS, an exception will be thrown. This function exists primarily
1548 to assist in implementing file-upload capability, with the caveat
1549 that clients must have some idea of the VFS into which they want
1550 to upload and that VFS must support the operation.
1554 - "memdb": results are undefined.
1556 - "kvvfs": will fail with an I/O error due to strict internal
1557 requirments of that VFS's xTruncate().
1559 - "unix" and related: will use the WASM build's equivalent of the
1560 POSIX I/O APIs. This will work so long as neither a specific
1561 VFS nor the WASM environment imposes requirements which break it.
1563 - "opfs": uses OPFS storage and creates directory parts of the
1564 filename. It can only be used to import an SQLite3 database
1565 file and will fail if given anything else.
1567 capi.sqlite3_js_vfs_create_file = function(vfs, filename, data, dataLen){
1568 config.warn("sqlite3_js_vfs_create_file() is deprecated and",
1569 "should be avoided because it can lead to C-level crashes.",
1570 "See its documentation for alternative options.");
1573 if(wasm.isPtr(data)){
1575 }else if(data instanceof ArrayBuffer){
1576 data = new Uint8Array(data);
1578 if(data instanceof Uint8Array){
1579 pData = wasm.allocFromTypedArray(data);
1580 if(arguments.length<4 || !util.isInt32(dataLen) || dataLen<0){
1581 dataLen = data.byteLength;
1584 SQLite3Error.toss("Invalid 3rd argument type for sqlite3_js_vfs_create_file().");
1589 if(!util.isInt32(dataLen) || dataLen<0){
1590 wasm.dealloc(pData);
1591 SQLite3Error.toss("Invalid 4th argument for sqlite3_js_vfs_create_file().");
1594 const rc = util.sqlite3__wasm_vfs_create_file(vfs, filename, pData, dataLen);
1595 if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code",
1596 capi.sqlite3_js_rc_str(rc));
1598 wasm.dealloc(pData);
1603 Converts SQL input from a variety of convenient formats
1606 If v is a string, it is returned as-is. If it is-a Array, its
1607 join("") result is returned. If is is a Uint8Array, Int8Array,
1608 or ArrayBuffer, it is assumed to hold UTF-8-encoded text and is
1609 decoded to a string. If it looks like a WASM pointer,
1610 wasm.cstrToJs(sql) is returned. Else undefined is returned.
1614 capi.sqlite3_js_sql_to_string = (sql)=>{
1615 if('string' === typeof sql){
1618 const x = flexibleString(v);
1619 return x===v ? undefined : x;
1622 if( util.isUIThread() ){
1623 /* Features specific to the main window thread... */
1626 Internal helper for sqlite3_js_kvvfs_clear() and friends.
1627 Its argument should be one of ('local','session',"").
1629 const __kvvfsInfo = function(which){
1630 const rc = Object.create(null);
1631 rc.prefix = 'kvvfs-'+which;
1633 if('session'===which || ""===which) rc.stores.push(globalThis.sessionStorage);
1634 if('local'===which || ""===which) rc.stores.push(globalThis.localStorage);
1639 Clears all storage used by the kvvfs DB backend, deleting any
1640 DB(s) stored there. Its argument must be either 'session',
1641 'local', or "". In the first two cases, only sessionStorage
1642 resp. localStorage is cleared. If it's an empty string (the
1643 default) then both are cleared. Only storage keys which match
1644 the pattern used by kvvfs are cleared: any other client-side
1647 This function is only available in the main window thread.
1649 Returns the number of entries cleared.
1651 capi.sqlite3_js_kvvfs_clear = function(which=""){
1653 const kvinfo = __kvvfsInfo(which);
1654 kvinfo.stores.forEach((s)=>{
1655 const toRm = [] /* keys to remove */;
1657 for( i = 0; i < s.length; ++i ){
1659 if(k.startsWith(kvinfo.prefix)) toRm.push(k);
1661 toRm.forEach((kk)=>s.removeItem(kk));
1668 This routine guesses the approximate amount of
1669 window.localStorage and/or window.sessionStorage in use by the
1670 kvvfs database backend. Its argument must be one of
1671 ('session', 'local', ""). In the first two cases, only
1672 sessionStorage resp. localStorage is counted. If it's an empty
1673 string (the default) then both are counted. Only storage keys
1674 which match the pattern used by kvvfs are counted. The returned
1675 value is the "length" value of every matching key and value,
1676 noting that JavaScript stores each character in 2 bytes.
1678 Note that the returned size is not authoritative from the
1679 perspective of how much data can fit into localStorage and
1680 sessionStorage, as the precise algorithms for determining
1681 those limits are unspecified and may include per-entry
1682 overhead invisible to clients.
1684 capi.sqlite3_js_kvvfs_size = function(which=""){
1686 const kvinfo = __kvvfsInfo(which);
1687 kvinfo.stores.forEach((s)=>{
1689 for(i = 0; i < s.length; ++i){
1691 if(k.startsWith(kvinfo.prefix)){
1693 sz += s.getItem(k).length;
1697 return sz * 2 /* because JS uses 2-byte char encoding */;
1700 }/* main-window-only bits */
1703 Wraps all known variants of the C-side variadic
1704 sqlite3_db_config().
1706 Full docs: https://sqlite.org/c3ref/db_config.html
1708 Returns capi.SQLITE_MISUSE if op is not a valid operation ID.
1710 The variants which take `(int, int*)` arguments treat a
1711 missing or falsy pointer argument as 0.
1713 capi.sqlite3_db_config = function(pDb, op, ...args){
1715 this.s = wasm.xWrap('sqlite3__wasm_db_config_s','int',
1716 ['sqlite3*', 'int', 'string:static']
1717 /* MAINDBNAME requires a static string */);
1718 this.pii = wasm.xWrap('sqlite3__wasm_db_config_pii', 'int',
1719 ['sqlite3*', 'int', '*','int', 'int']);
1720 this.ip = wasm.xWrap('sqlite3__wasm_db_config_ip','int',
1721 ['sqlite3*', 'int', 'int','*']);
1724 case capi.SQLITE_DBCONFIG_ENABLE_FKEY:
1725 case capi.SQLITE_DBCONFIG_ENABLE_TRIGGER:
1726 case capi.SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER:
1727 case capi.SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION:
1728 case capi.SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE:
1729 case capi.SQLITE_DBCONFIG_ENABLE_QPSG:
1730 case capi.SQLITE_DBCONFIG_TRIGGER_EQP:
1731 case capi.SQLITE_DBCONFIG_RESET_DATABASE:
1732 case capi.SQLITE_DBCONFIG_DEFENSIVE:
1733 case capi.SQLITE_DBCONFIG_WRITABLE_SCHEMA:
1734 case capi.SQLITE_DBCONFIG_LEGACY_ALTER_TABLE:
1735 case capi.SQLITE_DBCONFIG_DQS_DML:
1736 case capi.SQLITE_DBCONFIG_DQS_DDL:
1737 case capi.SQLITE_DBCONFIG_ENABLE_VIEW:
1738 case capi.SQLITE_DBCONFIG_LEGACY_FILE_FORMAT:
1739 case capi.SQLITE_DBCONFIG_TRUSTED_SCHEMA:
1740 case capi.SQLITE_DBCONFIG_STMT_SCANSTATUS:
1741 case capi.SQLITE_DBCONFIG_REVERSE_SCANORDER:
1742 return this.ip(pDb, op, args[0], args[1] || 0);
1743 case capi.SQLITE_DBCONFIG_LOOKASIDE:
1744 return this.pii(pDb, op, args[0], args[1], args[2]);
1745 case capi.SQLITE_DBCONFIG_MAINDBNAME:
1746 return this.s(pDb, op, args[0]);
1748 return capi.SQLITE_MISUSE;
1750 }.bind(Object.create(null));
1753 Given a (sqlite3_value*), this function attempts to convert it
1754 to an equivalent JS value with as much fidelity as feasible and
1757 By default it throws if it cannot determine any sensible
1758 conversion. If passed a falsy second argument, it instead returns
1759 `undefined` if no suitable conversion is found. Note that there
1760 is no conversion from SQL to JS which results in the `undefined`
1761 value, so `undefined` has an unambiguous meaning here. It will
1762 always throw a WasmAllocError if allocating memory for a
1767 - It does not support sqlite3_value_to_pointer() conversions
1768 because those require a type name string which this function
1769 does not have and cannot sensibly be given at the level of the
1770 API where this is used (e.g. automatically converting UDF
1771 arguments). Clients using sqlite3_value_to_pointer(), and its
1772 related APIs, will need to manage those themselves.
1774 capi.sqlite3_value_to_js = function(pVal,throwIfCannotConvert=true){
1776 const valType = capi.sqlite3_value_type(pVal);
1778 case capi.SQLITE_INTEGER:
1779 if(wasm.bigIntEnabled){
1780 arg = capi.sqlite3_value_int64(pVal);
1781 if(util.bigIntFitsDouble(arg)) arg = Number(arg);
1783 else arg = capi.sqlite3_value_double(pVal)/*yes, double, for larger integers*/;
1785 case capi.SQLITE_FLOAT:
1786 arg = capi.sqlite3_value_double(pVal);
1788 case capi.SQLITE_TEXT:
1789 arg = capi.sqlite3_value_text(pVal);
1791 case capi.SQLITE_BLOB:{
1792 const n = capi.sqlite3_value_bytes(pVal);
1793 const pBlob = capi.sqlite3_value_blob(pVal);
1794 if(n && !pBlob) sqlite3.WasmAllocError.toss(
1795 "Cannot allocate memory for blob argument of",n,"byte(s)"
1797 arg = n ? wasm.heap8u().slice(pBlob, pBlob + Number(n)) : null;
1800 case capi.SQLITE_NULL:
1803 if(throwIfCannotConvert){
1804 toss3(capi.SQLITE_MISMATCH,
1805 "Unhandled sqlite3_value_type():",valType);
1813 Requires a C-style array of `sqlite3_value*` objects and the
1814 number of entries in that array. Returns a JS array containing
1815 the results of passing each C array entry to
1816 sqlite3_value_to_js(). The 3rd argument to this function is
1817 passed on as the 2nd argument to that one.
1819 capi.sqlite3_values_to_js = function(argc,pArgv,throwIfCannotConvert=true){
1822 for(i = 0; i < argc; ++i){
1824 Curiously: despite ostensibly requiring 8-byte
1825 alignment, the pArgv array is parcelled into chunks of
1826 4 bytes (1 pointer each). The values those point to
1827 have 8-byte alignment but the individual argv entries
1830 tgt.push(capi.sqlite3_value_to_js(
1831 wasm.peekPtr(pArgv + (wasm.ptrSizeof * i)),
1832 throwIfCannotConvert
1839 Calls either sqlite3_result_error_nomem(), if e is-a
1840 WasmAllocError, or sqlite3_result_error(). In the latter case,
1841 the second argument is coerced to a string to create the error
1844 The first argument is a (sqlite3_context*). Returns void.
1847 capi.sqlite3_result_error_js = function(pCtx,e){
1848 if(e instanceof WasmAllocError){
1849 capi.sqlite3_result_error_nomem(pCtx);
1851 /* Maintenance reminder: ''+e, rather than e.message,
1852 will prefix e.message with e.name, so it includes
1853 the exception's type name in the result. */;
1854 capi.sqlite3_result_error(pCtx, ''+e, -1);
1859 This function passes its 2nd argument to one of the
1860 sqlite3_result_xyz() routines, depending on the type of that
1863 - If (val instanceof Error), this function passes it to
1864 sqlite3_result_error_js().
1865 - `null`: `sqlite3_result_null()`
1866 - `boolean`: `sqlite3_result_int()` with a value of 0 or 1.
1867 - `number`: `sqlite3_result_int()`, `sqlite3_result_int64()`, or
1868 `sqlite3_result_double()`, depending on the range of the number
1869 and whether or not int64 support is enabled.
1870 - `bigint`: similar to `number` but will trigger an error if the
1871 value is too big to store in an int64.
1872 - `string`: `sqlite3_result_text()`
1873 - Uint8Array or Int8Array or ArrayBuffer: `sqlite3_result_blob()`
1874 - `undefined`: is a no-op provided to simplify certain use cases.
1876 Anything else triggers `sqlite3_result_error()` with a
1877 description of the problem.
1879 The first argument to this function is a `(sqlite3_context*)`.
1880 Returns void. Does not throw.
1882 capi.sqlite3_result_js = function(pCtx,val){
1883 if(val instanceof Error){
1884 capi.sqlite3_result_error_js(pCtx, val);
1888 switch(typeof val) {
1890 /* This is a no-op. This routine originated in the create_function()
1891 family of APIs and in that context, passing in undefined indicated
1892 that the caller was responsible for calling sqlite3_result_xxx()
1896 capi.sqlite3_result_int(pCtx, val ? 1 : 0);
1899 if(util.bigIntFits32(val)){
1900 capi.sqlite3_result_int(pCtx, Number(val));
1901 }else if(util.bigIntFitsDouble(val)){
1902 capi.sqlite3_result_double(pCtx, Number(val));
1903 }else if(wasm.bigIntEnabled){
1904 if(util.bigIntFits64(val)) capi.sqlite3_result_int64(pCtx, val);
1905 else toss3("BigInt value",val.toString(),"is too BigInt for int64.");
1907 toss3("BigInt value",val.toString(),"is too BigInt.");
1912 if(util.isInt32(val)){
1913 f = capi.sqlite3_result_int;
1914 }else if(wasm.bigIntEnabled
1915 && Number.isInteger(val)
1916 && util.bigIntFits64(BigInt(val))){
1917 f = capi.sqlite3_result_int64;
1919 f = capi.sqlite3_result_double;
1925 const [p, n] = wasm.allocCString(val,true);
1926 capi.sqlite3_result_text(pCtx, p, n, capi.SQLITE_WASM_DEALLOC);
1930 if(null===val/*yes, typeof null === 'object'*/) {
1931 capi.sqlite3_result_null(pCtx);
1933 }else if(util.isBindableTypedArray(val)){
1934 const pBlob = wasm.allocFromTypedArray(val);
1935 capi.sqlite3_result_blob(
1936 pCtx, pBlob, val.byteLength,
1937 capi.SQLITE_WASM_DEALLOC
1941 // else fall through
1943 toss3("Don't not how to handle this UDF result value:",(typeof val), val);
1946 capi.sqlite3_result_error_js(pCtx, e);
1951 Returns the result sqlite3_column_value(pStmt,iCol) passed to
1952 sqlite3_value_to_js(). The 3rd argument of this function is
1953 ignored by this function except to pass it on as the second
1954 argument of sqlite3_value_to_js(). If the sqlite3_column_value()
1955 returns NULL (e.g. because the column index is out of range),
1956 this function returns `undefined`, regardless of the 3rd
1957 argument. If the 3rd argument is falsy and conversion fails,
1958 `undefined` will be returned.
1960 Note that sqlite3_column_value() returns an "unprotected" value
1961 object, but in a single-threaded environment (like this one)
1962 there is no distinction between protected and unprotected values.
1964 capi.sqlite3_column_js = function(pStmt, iCol, throwIfCannotConvert=true){
1965 const v = capi.sqlite3_column_value(pStmt, iCol);
1966 return (0===v) ? undefined : capi.sqlite3_value_to_js(v, throwIfCannotConvert);
1970 Internal impl of sqlite3_preupdate_new/old_js() and
1971 sqlite3changeset_new/old_js().
1973 const __newOldValue = function(pObj, iCol, impl){
1975 if(!this.ptr) this.ptr = wasm.allocPtr();
1976 else wasm.pokePtr(this.ptr, 0);
1977 const rc = impl(pObj, iCol, this.ptr);
1978 if(rc) return SQLite3Error.toss(rc,arguments[2]+"() failed with code "+rc);
1979 const pv = wasm.peekPtr(this.ptr);
1980 return pv ? capi.sqlite3_value_to_js( pv, true ) : undefined;
1981 }.bind(Object.create(null));
1984 A wrapper around sqlite3_preupdate_new() which fetches the
1985 sqlite3_value at the given index and returns the result of
1986 passing it to sqlite3_value_to_js(). Throws on error.
1988 capi.sqlite3_preupdate_new_js =
1989 (pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_new');
1992 The sqlite3_preupdate_old() counterpart of
1993 sqlite3_preupdate_new_js(), with an identical interface.
1995 capi.sqlite3_preupdate_old_js =
1996 (pDb, iCol)=>__newOldValue(pDb, iCol, 'sqlite3_preupdate_old');
1999 A wrapper around sqlite3changeset_new() which fetches the
2000 sqlite3_value at the given index and returns the result of
2001 passing it to sqlite3_value_to_js(). Throws on error.
2003 If sqlite3changeset_new() succeeds but has no value to report,
2004 this function returns the undefined value, noting that undefined
2005 is a valid conversion from an `sqlite3_value`, so is unambiguous.
2007 capi.sqlite3changeset_new_js =
2008 (pChangesetIter, iCol) => __newOldValue(pChangesetIter, iCol,
2009 'sqlite3changeset_new');
2012 The sqlite3changeset_old() counterpart of
2013 sqlite3changeset_new_js(), with an identical interface.
2015 capi.sqlite3changeset_old_js =
2016 (pChangesetIter, iCol)=>__newOldValue(pChangesetIter, iCol,
2017 'sqlite3changeset_old');
2019 /* The remainder of the API will be set up in later steps. */
2021 WasmAllocError: WasmAllocError,
2022 SQLite3Error: SQLite3Error,
2028 Holds the version info of the sqlite3 source tree from which
2029 the generated sqlite3-api.js gets built. Note that its version
2030 may well differ from that reported by sqlite3_libversion(), but
2031 that should be considered a source file mismatch, as the JS and
2032 WASM files are intended to be built and distributed together.
2034 This object is initially a placeholder which gets replaced by a
2035 build-generated object.
2037 version: Object.create(null),
2040 The library reserves the 'client' property for client-side use
2041 and promises to never define a property with this name nor to
2042 ever rely on specific contents of it. It makes no such guarantees
2043 for other properties.
2048 This function is not part of the public interface, but a
2049 piece of internal bootstrapping infrastructure.
2051 Performs any optional asynchronous library-level initialization
2052 which might be required. This function returns a Promise which
2053 resolves to the sqlite3 namespace object. Any error in the
2054 async init will be fatal to the init as a whole, but init
2055 routines are themselves welcome to install dummy catch()
2056 handlers which are not fatal if their failure should be
2057 considered non-fatal. If called more than once, the second and
2058 subsequent calls are no-ops which return a pre-resolved
2061 Ideally this function is called as part of the Promise chain
2062 which handles the loading and bootstrapping of the API. If not
2063 then it must be called by client-level code, which must not use
2064 the library until the returned promise resolves.
2066 If called multiple times it will return the same promise on
2067 subsequent calls. The current build setup precludes that
2068 possibility, so it's only a hypothetical problem if/when this
2069 function ever needs to be invoked by clients.
2071 In Emscripten-based builds, this function is called
2072 automatically and deleted from this object.
2074 asyncPostInit: async function ff(){
2075 if(ff.isReady instanceof Promise) return ff.isReady;
2076 let lia = sqlite3ApiBootstrap.initializersAsync;
2077 delete sqlite3ApiBootstrap.initializersAsync;
2078 const postInit = async ()=>{
2079 if(!sqlite3.__isUnderTest){
2080 /* Delete references to internal-only APIs which are used by
2081 some initializers. Retain them when running in test mode
2082 so that we can add tests for them. */
2083 delete sqlite3.util;
2084 /* It's conceivable that we might want to expose
2085 StructBinder to client-side code, but it's only useful if
2086 clients build their own sqlite3.wasm which contains their
2087 own C struct types. */
2088 delete sqlite3.StructBinder;
2092 const catcher = (e)=>{
2093 config.error("an async sqlite3 initializer failed:",e);
2096 if(!lia || !lia.length){
2097 return ff.isReady = postInit().catch(catcher);
2099 lia = lia.map((f)=>{
2100 return (f instanceof Function) ? async x=>f(sqlite3) : f;
2103 let p = Promise.resolve(sqlite3);
2104 while(lia.length) p = p.then(lia.shift());
2105 return ff.isReady = p.catch(catcher);
2108 scriptInfo ideally gets injected into this object by the
2109 infrastructure which assembles the JS/WASM module. It contains
2110 state which must be collected before sqlite3ApiBootstrap() can
2111 be declared. It is not necessarily available to any
2112 sqlite3ApiBootstrap.initializers but "should" be in place (if
2113 it's added at all) by the time that
2114 sqlite3ApiBootstrap.initializersAsync is processed.
2116 This state is not part of the public API, only intended for use
2117 with the sqlite3 API bootstrapping and wasm-loading process.
2119 scriptInfo: undefined
2122 sqlite3ApiBootstrap.initializers.forEach((f)=>{
2126 /* If we don't report this here, it can get completely swallowed
2127 up and disappear into the abyss of Promises and Workers. */
2128 console.error("sqlite3 bootstrap initializer threw:",e);
2131 delete sqlite3ApiBootstrap.initializers;
2132 sqlite3ApiBootstrap.sqlite3 = sqlite3;
2134 }/*sqlite3ApiBootstrap()*/;
2136 globalThis.sqlite3ApiBootstrap.initializers is an internal detail used by
2137 the various pieces of the sqlite3 API's amalgamation process. It
2138 must not be modified by client code except when plugging such code
2139 into the amalgamation process.
2141 Each component of the amalgamation is expected to append a function
2142 to this array. When sqlite3ApiBootstrap() is called for the first
2143 time, each such function will be called (in their appended order)
2144 and passed the sqlite3 namespace object, into which they can install
2145 their features (noting that most will also require that certain
2146 features alread have been installed). At the end of that process,
2147 this array is deleted.
2149 Note that the order of insertion into this array is significant for
2150 some pieces. e.g. sqlite3.capi and sqlite3.wasm cannot be fully
2151 utilized until the whwasmutil.js part is plugged in via
2152 sqlite3-api-glue.js.
2154 globalThis.sqlite3ApiBootstrap.initializers = [];
2156 globalThis.sqlite3ApiBootstrap.initializersAsync is an internal detail
2157 used by the sqlite3 API's amalgamation process. It must not be
2158 modified by client code except when plugging such code into the
2159 amalgamation process.
2161 The counterpart of globalThis.sqlite3ApiBootstrap.initializers,
2162 specifically for initializers which are asynchronous. All entries in
2163 this list must be either async functions, non-async functions which
2164 return a Promise, or a Promise. Each function in the list is called
2165 with the sqlite3 object as its only argument.
2167 The resolved value of any Promise is ignored and rejection will kill
2168 the asyncPostInit() process (at an indeterminate point because all
2169 of them are run asynchronously in parallel).
2171 This list is not processed until the client calls
2172 sqlite3.asyncPostInit(). This means, for example, that intializers
2173 added to globalThis.sqlite3ApiBootstrap.initializers may push entries to
2176 globalThis.sqlite3ApiBootstrap.initializersAsync = [];
2178 Client code may assign sqlite3ApiBootstrap.defaultConfig an
2179 object-type value before calling sqlite3ApiBootstrap() (without
2180 arguments) in order to tell that call to use this object as its
2181 default config value. The intention of this is to provide
2182 downstream clients with a reasonably flexible approach for plugging in
2183 an environment-suitable configuration without having to define a new
2184 global-scope symbol.
2186 globalThis.sqlite3ApiBootstrap.defaultConfig = Object.create(null);
2188 Placeholder: gets installed by the first call to
2189 globalThis.sqlite3ApiBootstrap(). However, it is recommended that the
2190 caller of sqlite3ApiBootstrap() capture its return value and delete
2191 globalThis.sqlite3ApiBootstrap after calling it. It returns the same
2192 value which will be stored here.
2194 globalThis.sqlite3ApiBootstrap.sqlite3 = undefined;