1f71c954cSstephan/* extern-post-js.js must be appended to the resulting sqlite3.js 2f861b36bSstephan file. It gets its name from being used as the value for the 3f861b36bSstephan --extern-post-js=... Emscripten flag. Note that this code, unlike 4f861b36bSstephan most of the associated JS code, runs outside of the 5f861b36bSstephan Emscripten-generated module init scope, in the current 6f861b36bSstephan global scope. */ 7b94a9860Sstephan(function(){ 8b94a9860Sstephan /** 9b94a9860Sstephan In order to hide the sqlite3InitModule()'s resulting Emscripten 10b94a9860Sstephan module from downstream clients (and simplify our documentation by 11b94a9860Sstephan being able to elide those details), we rewrite 12b94a9860Sstephan sqlite3InitModule() to return the sqlite3 object. 13b94a9860Sstephan 14b94a9860Sstephan Unfortunately, we cannot modify the module-loader/exporter-based 15b94a9860Sstephan impls which Emscripten installs at some point in the file above 16b94a9860Sstephan this. 17b94a9860Sstephan */ 18b94a9860Sstephan const originalInit = self.sqlite3InitModule; 19b94a9860Sstephan if(!originalInit){ 20b94a9860Sstephan throw new Error("Expecting self.sqlite3InitModule to be defined by the Emscripten build."); 21b94a9860Sstephan } 22cd0df83cSstephan /** 23cd0df83cSstephan We need to add some state which our custom Module.locateFile() 24cd0df83cSstephan can see, but an Emscripten limitation currently prevents us from 25cd0df83cSstephan attaching it to the sqlite3InitModule function object: 26cd0df83cSstephan 27cd0df83cSstephan https://github.com/emscripten-core/emscripten/issues/18071 28cd0df83cSstephan 29d89a66ecSstephan The only(?) current workaround is to temporarily stash this state 30cd0df83cSstephan into the global scope and delete it when sqlite3InitModule() 31cd0df83cSstephan is called. 32cd0df83cSstephan */ 33cd0df83cSstephan const initModuleState = self.sqlite3InitModuleState = Object.assign(Object.create(null),{ 34cd0df83cSstephan moduleScript: self?.document?.currentScript, 35d89a66ecSstephan isWorker: ('undefined' !== typeof WorkerGlobalScope), 36cd0df83cSstephan location: self.location, 37cd0df83cSstephan urlParams: new URL(self.location.href).searchParams 38cd0df83cSstephan }); 39*1fc6ffccSstephan initModuleState.debugModule = 40*1fc6ffccSstephan (new URL(self.location.href).searchParams).has('sqlite3.debugModule') 41*1fc6ffccSstephan ? (...args)=>console.warn('sqlite3.debugModule:',...args) 42*1fc6ffccSstephan : ()=>{}; 43*1fc6ffccSstephan 44cd0df83cSstephan if(initModuleState.urlParams.has('sqlite3.dir')){ 45cd0df83cSstephan initModuleState.sqlite3Dir = initModuleState.urlParams.get('sqlite3.dir') +'/'; 46d89a66ecSstephan }else if(initModuleState.moduleScript){ 47d89a66ecSstephan const li = initModuleState.moduleScript.src.split('/'); 48d89a66ecSstephan li.pop(); 49d89a66ecSstephan initModuleState.sqlite3Dir = li.join('/') + '/'; 50d89a66ecSstephan } 51cd0df83cSstephan 52b94a9860Sstephan self.sqlite3InitModule = (...args)=>{ 53b94a9860Sstephan //console.warn("Using replaced sqlite3InitModule()",self.location); 54b94a9860Sstephan return originalInit(...args).then((EmscriptenModule)=>{ 55b94a9860Sstephan if(self.window!==self && 56b94a9860Sstephan (EmscriptenModule['ENVIRONMENT_IS_PTHREAD'] 57b94a9860Sstephan || EmscriptenModule['_pthread_self'] 58b94a9860Sstephan || 'function'===typeof threadAlert 59b94a9860Sstephan || self.location.pathname.endsWith('.worker.js') 60b94a9860Sstephan )){ 61b94a9860Sstephan /** Workaround for wasmfs-generated worker, which calls this 62b94a9860Sstephan routine from each individual thread and requires that its 63b94a9860Sstephan argument be returned. All of the criteria above are fragile, 64b94a9860Sstephan based solely on inspection of the offending code, not public 65b94a9860Sstephan Emscripten details. */ 66b94a9860Sstephan return EmscriptenModule; 67b94a9860Sstephan } 68cd0df83cSstephan EmscriptenModule.sqlite3.scriptInfo = initModuleState; 69cd0df83cSstephan //console.warn("sqlite3.scriptInfo =",EmscriptenModule.sqlite3.scriptInfo); 70b94a9860Sstephan const f = EmscriptenModule.sqlite3.asyncPostInit; 71b94a9860Sstephan delete EmscriptenModule.sqlite3.asyncPostInit; 72b94a9860Sstephan return f(); 73e67a0f40Sstephan }).catch((e)=>{ 74e67a0f40Sstephan console.error("Exception loading sqlite3 module:",e); 75e67a0f40Sstephan throw e; 76b94a9860Sstephan }); 77b94a9860Sstephan }; 78e67a0f40Sstephan self.sqlite3InitModule.ready = originalInit.ready; 7971de8e02Sstephan 80cd0df83cSstephan if(self.sqlite3InitModuleState.moduleScript){ 81cd0df83cSstephan const sim = self.sqlite3InitModuleState; 82cd0df83cSstephan let src = sim.moduleScript.src.split('/'); 83cd0df83cSstephan src.pop(); 84cd0df83cSstephan sim.scriptDir = src.join('/') + '/'; 85cd0df83cSstephan } 86*1fc6ffccSstephan initModuleState.debugModule('sqlite3InitModuleState =',initModuleState); 8771de8e02Sstephan if(0){ 88cd0df83cSstephan console.warn("Replaced sqlite3InitModule()"); 8971de8e02Sstephan console.warn("self.location.href =",self.location.href); 9071de8e02Sstephan if('undefined' !== typeof document){ 9171de8e02Sstephan console.warn("document.currentScript.src =", 9271de8e02Sstephan document?.currentScript?.src); 9371de8e02Sstephan } 9471de8e02Sstephan } 95d89a66ecSstephan /* Replace the various module exports performed by the Emscripten 96d89a66ecSstephan glue... */ 97d89a66ecSstephan if (typeof exports === 'object' && typeof module === 'object') 98d89a66ecSstephan module.exports = sqlite3InitModule; 99d89a66ecSstephan else if (typeof exports === 'object') 100d89a66ecSstephan exports["sqlite3InitModule"] = sqlite3InitModule; 101d89a66ecSstephan /* AMD modules get injected in a way we cannot override, 102d89a66ecSstephan so we can't handle those here. */ 103cd0df83cSstephan})(); 104