mirror of
https://github.com/sqlite/sqlite.git
synced 2026-10-25 09:59:22 +03:00
179 lines
6.4 KiB
JavaScript
179 lines
6.4 KiB
JavaScript
/**
|
|
BEGIN FILE: api/pre-js.js
|
|
|
|
This file is intended to be prepended to the sqlite3.js build using
|
|
Emscripten's --pre-js=THIS_FILE flag (or equivalent). It is run
|
|
from inside of sqlite3InitModule(), after Emscripten's Module is
|
|
defined, but early enough that we can ammend, or even outright
|
|
replace, Module from here.
|
|
|
|
Because this runs in-between Emscripten's own bootstrapping and
|
|
Emscripten's main work, we must be careful with file-local symbol
|
|
names. e.g. don't overwrite anything Emscripten defines and do not
|
|
use 'const' for local symbols which Emscripten might try to use for
|
|
itself. i.e. try to keep file-local symbol names obnoxiously
|
|
collision-resistant.
|
|
*/
|
|
/**
|
|
This file was preprocessed using:
|
|
|
|
//#@ policy error <<
|
|
@c-pp::argv@
|
|
//#/@
|
|
*/
|
|
//#if unsupported-build
|
|
/**
|
|
UNSUPPORTED BUILD:
|
|
|
|
This SQLite JS build configuration is entirely unsupported! It has
|
|
not been tested beyond the ability to compile it. It may not
|
|
load. It may not work properly. Only builds _directly_ targeting
|
|
browser environments ("vanilla" JS and ESM modules) are supported
|
|
and tested. Builds which _indirectly_ target browsers (namely
|
|
bundler-friendly builds and any node builds) are not supported
|
|
deliverables.
|
|
*/
|
|
//#/if
|
|
//#if not target:es6-bundler-friendly and not target:node
|
|
(function(Module){
|
|
const sIMS =
|
|
globalThis.sqlite3InitModuleState/*from extern-post-js.c-pp.js*/
|
|
|| Object.assign(Object.create(null),{
|
|
/* In WASMFS builds this file gets loaded once per thread,
|
|
but sqlite3InitModuleState is not getting set for the
|
|
worker threads? That those workers seem to function fine
|
|
despite that is curious. */
|
|
debugModule: function(){
|
|
console.warn("globalThis.sqlite3InitModuleState is missing",arguments);
|
|
}
|
|
});
|
|
delete globalThis.sqlite3InitModuleState;
|
|
sIMS.debugModule('pre-js.js sqlite3InitModuleState =',sIMS);
|
|
|
|
/**
|
|
This custom locateFile() tries to figure out where to load `path`
|
|
from. The intent is to provide a way for foo/bar/X.js loaded from a
|
|
Worker constructor or importScripts() to be able to resolve
|
|
foo/bar/X.wasm (in the latter case, with some help):
|
|
|
|
1) If URL param named the same as `path` is set, it is returned.
|
|
|
|
2) If sqlite3InitModuleState.sqlite3Dir is set, then (thatName + path)
|
|
is returned (it's assumed to end with '/').
|
|
|
|
3) If this code is running in the main UI thread AND it was loaded
|
|
from a SCRIPT tag, the directory part of that URL is used
|
|
as the prefix. (This form of resolution unfortunately does not
|
|
function for scripts loaded via importScripts().)
|
|
|
|
4) If none of the above apply, (prefix+path) is returned.
|
|
|
|
None of the above apply in ES6 builds, which uses a much simpler
|
|
approach.
|
|
*/
|
|
Module['locateFile'] = function(path, prefix) {
|
|
if( this.emscriptenLocateFile instanceof Function ){
|
|
/* [tag:locateFile] Client-overridden impl. We do not support
|
|
this but offer it as a back-door which will go away the
|
|
moment either Emscripten changes that interface or we manage
|
|
to get non-Emscripten builds working.
|
|
https://sqlite.org/forum/forumpost/1eec339854c935bd */
|
|
return this.emscriptenLocateFile(path, prefix);
|
|
}
|
|
//#if target:es6-module
|
|
return new URL(path, import.meta.url).href;
|
|
//#else
|
|
'use strict';
|
|
let theFile;
|
|
const up = this.urlParams;
|
|
if(up?.has(path)){
|
|
theFile = up.get(path);
|
|
}else if(this.sqlite3Dir){
|
|
theFile = this.sqlite3Dir + path;
|
|
}else if(this.scriptDir){
|
|
theFile = this.scriptDir + path;
|
|
}else{
|
|
theFile = prefix + path;
|
|
}
|
|
this.debugModule(
|
|
"locateFile(",arguments[0], ',', arguments[1],")",
|
|
'sqlite3InitModuleState.scriptDir =',this.scriptDir,
|
|
'up.entries() =',Array.from(up.entries()),
|
|
"result =", theFile
|
|
);
|
|
return theFile;
|
|
//#/if target:es6-module
|
|
}.bind(sIMS);
|
|
|
|
//#if Module.instantiateWasm and not wasmfs and not target:node
|
|
/**
|
|
Override Module.instantiateWasm().
|
|
|
|
A custom Module.instantiateWasm() does not work in WASMFS builds:
|
|
|
|
https://github.com/emscripten-core/emscripten/issues/17951
|
|
|
|
In such builds we must disable this.
|
|
|
|
It's disabled in the (unsupported/untested) node builds because
|
|
node does not do fetch().
|
|
*/
|
|
Module['instantiateWasm'] = function callee(imports, onSuccess){
|
|
if( this.emscriptenInstantiateWasm instanceof Function ){
|
|
/* See [tag:locateFile]. Same story here */
|
|
return this.emscriptenInstantiateWasm(imports, onSuccess);
|
|
}
|
|
const sims = this;
|
|
const finalThen = (arg)=>{
|
|
arg.imports = imports;
|
|
sims.instantiateWasm = arg; /* used by sqlite3-api-prologue.c-pp.js */
|
|
onSuccess(arg.instance, arg.module);
|
|
};
|
|
//#// \
|
|
{/*
|
|
The following block uses //% as a directive delimiter and is
|
|
replaced in a second pass after compilation of sqlite3.js.
|
|
*/}
|
|
//%define ? base64.wasm 0
|
|
//%if base64.wasm and defined sqlite3.wasm.base64
|
|
//%@ push policy error delimiter '<<<' '>>>'
|
|
let b64Wasm = `<<<[base64 -file sqlite3.wasm.base64]>>>`;
|
|
//%@ pop policy delimiter
|
|
const bytes = Uint8Array.fromBase64(b64Wasm);
|
|
b64Wasm = null;
|
|
|
|
WebAssembly.instantiate(bytes.buffer, imports)
|
|
.then(finalThen)
|
|
.catch((err)=>{
|
|
console.error("Failed to instantiate embedded sqlite3.wasm", err);
|
|
throw err;
|
|
});
|
|
|
|
return {}/* Emscripten interprets this to wait on async instantiation
|
|
via onSuccess(). */;
|
|
//%else
|
|
const uri = Module.locateFile(
|
|
sims.wasmFilename, (
|
|
('undefined'===typeof scriptDirectory/*var defined by Emscripten glue*/)
|
|
? "" : scriptDirectory)
|
|
);
|
|
sims.debugModule("instantiateWasm() uri =", uri, "sIMS =",this);
|
|
const wfetch = ()=>fetch(uri, {credentials: 'same-origin'});
|
|
const loadWasm = WebAssembly.instantiateStreaming
|
|
? async ()=>
|
|
WebAssembly
|
|
.instantiateStreaming(wfetch(), imports)
|
|
.then(finalThen)
|
|
: async ()=>// Safari < v15
|
|
wfetch()
|
|
.then(response => response.arrayBuffer())
|
|
.then(bytes => WebAssembly.instantiate(bytes, imports))
|
|
.then(finalThen)
|
|
return loadWasm();
|
|
//%/if sqlite3.wasm.base64 pass 2
|
|
}.bind(sIMS);
|
|
//#/if Module.instantiateWasm and not wasmfs
|
|
})(Module);
|
|
//#/if not target:es6-bundler-friendly
|
|
/* END FILE: api/pre-js.js. */
|