Index: ext/wasm/GNUmakefile ================================================================== --- ext/wasm/GNUmakefile +++ ext/wasm/GNUmakefile @@ -435,11 +435,11 @@ emcc.jsflags += -sIMPORTED_MEMORY emcc.jsflags += -sSTRICT_JS=0 # STRICT_JS disabled due to: # https://github.com/emscripten-core/emscripten/issues/18610 # TL;DR: does not work with MODULARIZE or EXPORT_ES6 as of version 3.1.31. -emcc.environment := -sENVIRONMENT=web,worker +emcc.environment := -sENVIRONMENT=web,worker,node ######################################################################## # -sINITIAL_MEMORY: How much memory we need to start with is governed # at least in part by whether -sALLOW_MEMORY_GROWTH is enabled. If so, # we can start with less. If not, we need as much as we'll ever # possibly use (which, of course, we can't know for sure). Note, @@ -448,13 +448,13 @@ # at runtime. e.g. OPFS-backed (speedtest1 --size 75) take MAY take X # time with 16mb+ memory and 3X time when starting with 8MB. However, # such test results are inconsistent due to browser internals which # are opaque to us. emcc.jsflags += -sALLOW_MEMORY_GROWTH -emcc.INITIAL_MEMORY.128 := 13107200 +emcc.INITIAL_MEMORY.128 := 134217728 emcc.INITIAL_MEMORY.96 := 100663296 -emcc.INITIAL_MEMORY.64 := 64225280 +emcc.INITIAL_MEMORY.64 := 67108864 emcc.INITIAL_MEMORY.32 := 33554432 emcc.INITIAL_MEMORY.16 := 16777216 emcc.INITIAL_MEMORY.8 := 8388608 emcc.INITIAL_MEMORY ?= 16 ifeq (,$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY))) @@ -467,10 +467,12 @@ emcc.jsflags += $(emcc.environment) emcc.jsflags += -sSTACK_SIZE=512KB # ^^^ ACHTUNG: emsdk 3.1.27 reduced the default stack size from 5MB to # a mere 64KB, which leads to silent memory corruption via the kvvfs # VFS, which requires twice that for its xRead() and xWrite() methods. +# 2023-03: those methods have since been adapted to use a malloc()'d +# buffer. ######################################################################## # $(sqlite3.js.init-func) is the name Emscripten assigns our exported # module init/load function. This symbol name is hard-coded in # $(extern-post-js.js) as well as in numerous docs. # @@ -535,11 +537,11 @@ ######################################################################## $(sqlite3-api-build-version.js): $(bin.version-info) $(MAKEFILE) @echo "Making $@..." @{ \ - echo 'self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){'; \ + echo 'globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){'; \ echo -n ' sqlite3.version = '; \ $(bin.version-info) --json; \ echo ';'; \ echo '});'; \ } > $@ @@ -664,11 +666,11 @@ # $5 = -D... flags for $(bin.c-pp) # $6 = emcc -sXYZ flags define SETUP_LIB_BUILD_MODE $(info Setting up build [$(1)]: $(4)) c-pp.D.$(1) := $(5) -pre-js.js.$(1) := $$(dir.api)/pre-js.$(1).js +pre-js.js.$(1) := $$(dir.tmp)/pre-js.$(1).js $$(eval $$(call C-PP.FILTER,$$(pre-js.js.in),$$(pre-js.js.$(1)),$$(c-pp.D.$(1)))) post-js.js.$(1) := $$(dir.tmp)/post-js.$(1).js $$(eval $$(call C-PP.FILTER,$$(post-js.js.in),$$(post-js.js.$(1)),$$(c-pp.D.$(1)))) extern-post-js.js.$(1) := $$(dir.tmp)/extern-post-js.$(1).js $$(eval $$(call C-PP.FILTER,$$(extern-post-js.js.in),$$(extern-post-js.js.$(1)),$$(c-pp.D.$(1)))) Index: ext/wasm/api/extern-post-js.c-pp.js ================================================================== --- ext/wasm/api/extern-post-js.c-pp.js +++ ext/wasm/api/extern-post-js.c-pp.js @@ -26,11 +26,11 @@ const originalInit = /* Maintenance reminder: DO NOT use `self.` here. It's correct for non-ES6 Module cases but wrong for ES6 modules because those resolve this symbol differently. */ sqlite3InitModule; if(!originalInit){ - throw new Error("Expecting self.sqlite3InitModule to be defined by the Emscripten build."); + throw new Error("Expecting globalThis.sqlite3InitModule to be defined by the Emscripten build."); } /** We need to add some state which our custom Module.locateFile() can see, but an Emscripten limitation currently prevents us from attaching it to the sqlite3InitModule function object: @@ -39,15 +39,17 @@ The only(?) current workaround is to temporarily stash this state into the global scope and delete it when sqlite3InitModule() is called. */ - const initModuleState = self.sqlite3InitModuleState = Object.assign(Object.create(null),{ + const initModuleState = globalThis.sqlite3InitModuleState = Object.assign(Object.create(null),{ moduleScript: self?.document?.currentScript, isWorker: ('undefined' !== typeof WorkerGlobalScope), - location: self.location, - urlParams: new URL(self.location.href).searchParams + location: globalThis.location, + urlParams: globalThis?.location?.href + ? new URL(globalThis.location.href).searchParams + : new URLSearchParams() }); initModuleState.debugModule = initModuleState.urlParams.has('sqlite3.debugModule') ? (...args)=>console.warn('sqlite3.debugModule:',...args) : ()=>{}; @@ -58,18 +60,18 @@ const li = initModuleState.moduleScript.src.split('/'); li.pop(); initModuleState.sqlite3Dir = li.join('/') + '/'; } - self.sqlite3InitModule = function ff(...args){ + globalThis.sqlite3InitModule = function ff(...args){ //console.warn("Using replaced sqlite3InitModule()",self.location); return originalInit(...args).then((EmscriptenModule)=>{ - if(self.window!==self && + if('undefined'!==typeof WorkerGlobalScope && (EmscriptenModule['ENVIRONMENT_IS_PTHREAD'] || EmscriptenModule['_pthread_self'] || 'function'===typeof threadAlert - || self.location.pathname.endsWith('.worker.js') + || globalThis?.location?.pathname?.endsWith?.('.worker.js') )){ /** Workaround for wasmfs-generated worker, which calls this routine from each individual thread and requires that its argument be returned. All of the criteria above are fragile, based solely on inspection of the offending code, not public @@ -86,22 +88,22 @@ }).catch((e)=>{ console.error("Exception loading sqlite3 module:",e); throw e; }); }; - self.sqlite3InitModule.ready = originalInit.ready; + globalThis.sqlite3InitModule.ready = originalInit.ready; - if(self.sqlite3InitModuleState.moduleScript){ - const sim = self.sqlite3InitModuleState; + if(globalThis.sqlite3InitModuleState.moduleScript){ + const sim = globalThis.sqlite3InitModuleState; let src = sim.moduleScript.src.split('/'); src.pop(); sim.scriptDir = src.join('/') + '/'; } initModuleState.debugModule('sqlite3InitModuleState =',initModuleState); if(0){ console.warn("Replaced sqlite3InitModule()"); - console.warn("self.location.href =",self.location.href); + console.warn("globalThis.location.href =",globalThis.location.href); if('undefined' !== typeof document){ console.warn("document.currentScript.src =", document?.currentScript?.src); } } @@ -117,10 +119,10 @@ exports["sqlite3InitModule"] = sqlite3InitModule; } /* AMD modules get injected in a way we cannot override, so we can't handle those here. */ //#endif // !target=es6-module - return self.sqlite3InitModule /* required for ESM */; + return globalThis.sqlite3InitModule /* required for ESM */; })(); //#if target=es6-module export default toExportForESM; //#endif Index: ext/wasm/api/pre-js.c-pp.js ================================================================== --- ext/wasm/api/pre-js.c-pp.js +++ ext/wasm/api/pre-js.c-pp.js @@ -4,16 +4,16 @@ This file is intended to be prepended to the sqlite3.js build using Emscripten's --pre-js=THIS_FILE flag (or equivalent). */ // See notes in extern-post-js.js -const sqlite3InitModuleState = self.sqlite3InitModuleState +const sqlite3InitModuleState = globalThis.sqlite3InitModuleState || Object.assign(Object.create(null),{ debugModule: ()=>{} }); -delete self.sqlite3InitModuleState; -sqlite3InitModuleState.debugModule('self.location =',self.location); +delete globalThis.sqlite3InitModuleState; +sqlite3InitModuleState.debugModule('globalThis.location =',globalThis.location); //#ifnot target=es6-bundler-friendly /** 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 Index: ext/wasm/api/sqlite3-api-cleanup.js ================================================================== --- ext/wasm/api/sqlite3-api-cleanup.js +++ ext/wasm/api/sqlite3-api-cleanup.js @@ -23,39 +23,39 @@ const SABC = Object.assign( Object.create(null), { exports: Module['asm'], memory: Module.wasmMemory /* gets set if built with -sIMPORT_MEMORY */ }, - self.sqlite3ApiConfig || {} + globalThis.sqlite3ApiConfig || {} ); /** For current (2022-08-22) purposes, automatically call sqlite3ApiBootstrap(). That decision will be revisited at some point, as we really want client code to be able to call this to configure certain parts. Clients may modify - self.sqlite3ApiBootstrap.defaultConfig to tweak the default + globalThis.sqlite3ApiBootstrap.defaultConfig to tweak the default configuration used by a no-args call to sqlite3ApiBootstrap(), but must have first loaded their WASM module in order to be able to provide the necessary configuration state. */ - //console.warn("self.sqlite3ApiConfig = ",self.sqlite3ApiConfig); - self.sqlite3ApiConfig = SABC; + //console.warn("globalThis.sqlite3ApiConfig = ",globalThis.sqlite3ApiConfig); + globalThis.sqlite3ApiConfig = SABC; let sqlite3; try{ - sqlite3 = self.sqlite3ApiBootstrap(); + sqlite3 = globalThis.sqlite3ApiBootstrap(); }catch(e){ console.error("sqlite3ApiBootstrap() error:",e); throw e; }finally{ - delete self.sqlite3ApiBootstrap; - delete self.sqlite3ApiConfig; + delete globalThis.sqlite3ApiBootstrap; + delete globalThis.sqlite3ApiConfig; } Module.sqlite3 = sqlite3 /* Needed for customized sqlite3InitModule() to be able to pass the sqlite3 object off to the client. */; }else{ console.warn("This is not running in an Emscripten module context, so", - "self.sqlite3ApiBootstrap() is _not_ being called due to lack", + "globalThis.sqlite3ApiBootstrap() is _not_ being called due to lack", "of config info for the WASM environment.", "It must be called manually."); } Index: ext/wasm/api/sqlite3-api-glue.js ================================================================== --- ext/wasm/api/sqlite3-api-glue.js +++ ext/wasm/api/sqlite3-api-glue.js @@ -14,17 +14,17 @@ previous steps of the sqlite3-api.js bootstrapping process: sqlite3-api-prologue.js, whwasmutil.js, and jaccwabyt.js. It initializes the main API pieces so that the downstream components (e.g. sqlite3-api-oo1.js) have all that they need. */ -self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ +globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ 'use strict'; const toss = (...args)=>{throw new Error(args.join(' '))}; const toss3 = sqlite3.SQLite3Error.toss; const capi = sqlite3.capi, wasm = sqlite3.wasm, util = sqlite3.util; - self.WhWasmUtilInstaller(wasm); - delete self.WhWasmUtilInstaller; + globalThis.WhWasmUtilInstaller(wasm); + delete globalThis.WhWasmUtilInstaller; if(0){ /** Please keep this block around as a maintenance reminder that we cannot rely on this type of check. @@ -603,19 +603,19 @@ ]; /** Install JS<->C struct bindings for the non-opaque struct types we need... */ - sqlite3.StructBinder = self.Jaccwabyt({ + sqlite3.StructBinder = globalThis.Jaccwabyt({ heap: 0 ? wasm.memory : wasm.heap8u, alloc: wasm.alloc, dealloc: wasm.dealloc, bigIntEnabled: wasm.bigIntEnabled, memberPrefix: /* Never change this: this prefix is baked into any amount of code and client-facing docs. */ '$' }); - delete self.Jaccwabyt; + delete globalThis.Jaccwabyt; {// wasm.xWrap() bindings... /* Convert Arrays and certain TypedArrays to strings for 'string:flexible'-type arguments */ Index: ext/wasm/api/sqlite3-api-oo1.js ================================================================== --- ext/wasm/api/sqlite3-api-oo1.js +++ ext/wasm/api/sqlite3-api-oo1.js @@ -10,13 +10,13 @@ *********************************************************************** This file contains the so-called OO #1 API wrapper for the sqlite3 WASM build. It requires that sqlite3-api-glue.js has already run - and it installs its deliverable as self.sqlite3.oo1. + and it installs its deliverable as globalThis.sqlite3.oo1. */ -self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ +globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const toss = (...args)=>{throw new Error(args.join(' '))}; const toss3 = (...args)=>{throw new sqlite3.SQLite3Error(...args)}; const capi = sqlite3.capi, wasm = sqlite3.wasm, util = sqlite3.util; /* What follows is colloquially known as "OO API #1". It is a Index: ext/wasm/api/sqlite3-api-prologue.js ================================================================== --- ext/wasm/api/sqlite3-api-prologue.js +++ ext/wasm/api/sqlite3-api-prologue.js @@ -27,11 +27,11 @@ /** sqlite3ApiBootstrap() is the only global symbol persistently exposed by this API. It is intended to be called one time at the end of the API amalgamation process, passed configuration details for the current environment, and then optionally be removed from - the global object using `delete self.sqlite3ApiBootstrap`. + the global object using `delete globalThis.sqlite3ApiBootstrap`. This function is not intended for client-level use. It is intended for use in creating bundles configured for specific WASM environments. @@ -56,11 +56,11 @@ to `Module.wasmMemory` if the build uses `-sIMPORT_MEMORY`, or be left undefined/falsy to default to `exports.memory` when using WASM-exported memory. - `bigIntEnabled`: true if BigInt support is enabled. Defaults to - true if `self.BigInt64Array` is available, else false. Some APIs + true if `globalThis.BigInt64Array` is available, else false. Some APIs will throw exceptions if called without BigInt support, as BigInt is required for marshalling C-side int64 into and out of JS. (Sidebar: it is technically possible to add int64 support via marshalling of int32 pairs, but doing so is unduly invasive.) @@ -98,12 +98,12 @@ The returned object is the top-level sqlite3 namespace object. */ 'use strict'; -self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( - apiConfig = (self.sqlite3ApiConfig || sqlite3ApiBootstrap.defaultConfig) +globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( + apiConfig = (globalThis.sqlite3ApiConfig || sqlite3ApiBootstrap.defaultConfig) ){ if(sqlite3ApiBootstrap.sqlite3){ /* already initalized */ console.warn("sqlite3ApiBootstrap() called multiple times.", "Config and external initializers are ignored on calls after the first."); return sqlite3ApiBootstrap.sqlite3; @@ -115,11 +115,11 @@ if('undefined'!==typeof Module){ /* Emscripten module will contain HEAPU64 when built with -sWASM_BIGINT=1, else it will not. */ return !!Module.HEAPU64; } - return !!self.BigInt64Array; + return !!globalThis.BigInt64Array; })(), debug: console.debug.bind(console), warn: console.warn.bind(console), error: console.error.bind(console), log: console.log.bind(console), @@ -770,11 +770,11 @@ affirmBindableTypedArray, flexibleString, bigIntFits32, bigIntFits64, bigIntFitsDouble, isBindableTypedArray, isInt32, isSQLableTypedArray, isTypedArray, typedArrayToString, - isUIThread: ()=>(self.window===self && !!self.document), + isUIThread: ()=>(globalThis.window===globalThis && !!globalThis.document), // is this true for ESM?: 'undefined'===typeof WorkerGlobalScope isSharedTypedArray, toss: function(...args){throw new Error(args.join(' '))}, toss3, typedArrayPart @@ -1201,13 +1201,13 @@ // If we have no OPFS, there is no persistent dir const pdir = config.wasmfsOpfsDir; console.error("sqlite3_wasmfs_opfs_dir() can no longer work due "+ "to incompatible WASMFS changes. It will be removed."); if(!pdir - || !self.FileSystemHandle - || !self.FileSystemDirectoryHandle - || !self.FileSystemFileHandle){ + || !globalThis.FileSystemHandle + || !globalThis.FileSystemDirectoryHandle + || !globalThis.FileSystemFileHandle){ return __wasmfsOpfsDir = ""; } try{ if(pdir && 0===wasm.xCallWrapped( 'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir @@ -1459,12 +1459,12 @@ */ const __kvvfsInfo = function(which){ const rc = Object.create(null); rc.prefix = 'kvvfs-'+which; rc.stores = []; - if('session'===which || ""===which) rc.stores.push(self.sessionStorage); - if('local'===which || ""===which) rc.stores.push(self.localStorage); + if('session'===which || ""===which) rc.stores.push(globalThis.sessionStorage); + if('local'===which || ""===which) rc.stores.push(globalThis.localStorage); return rc; }; /** Clears all storage used by the kvvfs DB backend, deleting any @@ -1960,11 +1960,11 @@ delete sqlite3ApiBootstrap.initializers; sqlite3ApiBootstrap.sqlite3 = sqlite3; return sqlite3; }/*sqlite3ApiBootstrap()*/; /** - self.sqlite3ApiBootstrap.initializers is an internal detail used by + globalThis.sqlite3ApiBootstrap.initializers is an internal detail used by the various pieces of the sqlite3 API's amalgamation process. It must not be modified by client code except when plugging such code into the amalgamation process. Each component of the amalgamation is expected to append a function @@ -1978,18 +1978,18 @@ Note that the order of insertion into this array is significant for some pieces. e.g. sqlite3.capi and sqlite3.wasm cannot be fully utilized until the whwasmutil.js part is plugged in via sqlite3-api-glue.js. */ -self.sqlite3ApiBootstrap.initializers = []; +globalThis.sqlite3ApiBootstrap.initializers = []; /** - self.sqlite3ApiBootstrap.initializersAsync is an internal detail + globalThis.sqlite3ApiBootstrap.initializersAsync is an internal detail used by the sqlite3 API's amalgamation process. It must not be modified by client code except when plugging such code into the amalgamation process. - The counterpart of self.sqlite3ApiBootstrap.initializers, + The counterpart of globalThis.sqlite3ApiBootstrap.initializers, specifically for initializers which are asynchronous. All entries in this list must be either async functions, non-async functions which return a Promise, or a Promise. Each function in the list is called with the sqlite3 ojbect as its only argument. @@ -1997,28 +1997,27 @@ the asyncPostInit() process (at an indeterminate point because all of them are run asynchronously in parallel). This list is not processed until the client calls sqlite3.asyncPostInit(). This means, for example, that intializers - added to self.sqlite3ApiBootstrap.initializers may push entries to + added to globalThis.sqlite3ApiBootstrap.initializers may push entries to this list. */ -self.sqlite3ApiBootstrap.initializersAsync = []; +globalThis.sqlite3ApiBootstrap.initializersAsync = []; /** Client code may assign sqlite3ApiBootstrap.defaultConfig an object-type value before calling sqlite3ApiBootstrap() (without arguments) in order to tell that call to use this object as its default config value. The intention of this is to provide downstream clients with a reasonably flexible approach for plugging in an environment-suitable configuration without having to define a new global-scope symbol. */ -self.sqlite3ApiBootstrap.defaultConfig = Object.create(null); +globalThis.sqlite3ApiBootstrap.defaultConfig = Object.create(null); /** Placeholder: gets installed by the first call to - self.sqlite3ApiBootstrap(). However, it is recommended that the + globalThis.sqlite3ApiBootstrap(). However, it is recommended that the caller of sqlite3ApiBootstrap() capture its return value and delete - self.sqlite3ApiBootstrap after calling it. It returns the same + globalThis.sqlite3ApiBootstrap after calling it. It returns the same value which will be stored here. */ -self.sqlite3ApiBootstrap.sqlite3 = undefined; - +globalThis.sqlite3ApiBootstrap.sqlite3 = undefined; Index: ext/wasm/api/sqlite3-api-worker1.js ================================================================== --- ext/wasm/api/sqlite3-api-worker1.js +++ ext/wasm/api/sqlite3-api-worker1.js @@ -311,15 +311,15 @@ The response is the input options object (or a synthesized one if passed only a string), noting that options.resultRows and options.columnNames may be populated by the call to db.exec(). */ -self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ +globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ sqlite3.initWorker1API = function(){ 'use strict'; const toss = (...args)=>{throw new Error(args.join(' '))}; - if('function' !== typeof importScripts){ + if(!(globalThis.WorkerGlobalScope instanceof Function)){ toss("initWorker1API() must be run from a Worker thread."); } const self = this.self; const sqlite3 = this.sqlite3 || toss("Missing this.sqlite3 object."); const DB = sqlite3.oo1.DB; @@ -380,14 +380,14 @@ postMessage()'s second argument and xferList.length is set to 0. */ post: function(msg,xferList){ if(xferList && xferList.length){ - self.postMessage( msg, Array.from(xferList) ); + globalThis.postMessage( msg, Array.from(xferList) ); xferList.length = 0; }else{ - self.postMessage(msg); + globalThis.postMessage(msg); } }, /** Map of DB IDs to DBs. */ dbs: Object.create(null), /** Fetch the DB for the given id. Throw if require=true and the @@ -587,11 +587,11 @@ const response = await sqlite3.opfs.treeList(); return response; } }/*wMsgHandler*/; - self.onmessage = async function(ev){ + globalThis.onmessage = async function(ev){ ev = ev.data; let result, dbId = ev.dbId, evType = ev.type; const arrivalTime = performance.now(); try { if(wMsgHandler.hasOwnProperty(evType) && @@ -635,8 +635,8 @@ // workerResponse: performance.now(); //}, result: result }, wState.xfer); }; - self.postMessage({type:'sqlite3-api',result:'worker1-ready'}); + globalThis.postMessage({type:'sqlite3-api',result:'worker1-ready'}); }.bind({self, sqlite3}); }); Index: ext/wasm/api/sqlite3-opfs-async-proxy.js ================================================================== --- ext/wasm/api/sqlite3-opfs-async-proxy.js +++ ext/wasm/api/sqlite3-opfs-async-proxy.js @@ -48,14 +48,14 @@ */ "use strict"; const wPost = (type,...args)=>postMessage({type, payload:args}); const installAsyncProxy = function(self){ const toss = function(...args){throw new Error(args.join(' '))}; - if(self.window === self){ + if(globalThis.window === globalThis){ toss("This code cannot run from the main thread.", "Load it as a Worker from a separate Worker."); - }else if(!navigator.storage.getDirectory){ + }else if(!navigator?.storage?.getDirectory){ toss("This API requires navigator.storage.getDirectory."); } /** Will hold state copied to this object from the syncronous side of @@ -104,12 +104,12 @@ n += m.count; t += m.time; w += m.wait; m.avgTime = (m.count && m.time) ? (m.time / m.count) : 0; } - console.log(self.location.href, - "metrics for",self.location.href,":\n", + console.log(globalThis?.location?.href, + "metrics for",globalThis?.location?.href,":\n", metrics, "\nTotal of",n,"op(s) for",t,"ms", "approx",w,"ms spent waiting on OPFS APIs."); console.log("Serialization metrics:",metrics.s11n); }; @@ -841,11 +841,11 @@ } }; navigator.storage.getDirectory().then(function(d){ state.rootDir = d; - self.onmessage = function({data}){ + globalThis.onmessage = function({data}){ switch(data.type){ case 'opfs-async-init':{ /* Receive shared state from synchronous partner */ const opt = data.args; for(const k in opt) state[k] = opt[k]; @@ -878,20 +878,20 @@ } }; wPost('opfs-async-loaded'); }).catch((e)=>error("error initializing OPFS asyncer:",e)); }/*installAsyncProxy()*/; -if(!self.SharedArrayBuffer){ +if(!globalThis.SharedArrayBuffer){ wPost('opfs-unavailable', "Missing SharedArrayBuffer API.", "The server must emit the COOP/COEP response headers to enable that."); -}else if(!self.Atomics){ +}else if(!globalThis.Atomics){ wPost('opfs-unavailable', "Missing Atomics API.", "The server must emit the COOP/COEP response headers to enable that."); -}else if(!self.FileSystemHandle || - !self.FileSystemDirectoryHandle || - !self.FileSystemFileHandle || - !self.FileSystemFileHandle.prototype.createSyncAccessHandle || - !navigator.storage.getDirectory){ +}else if(!globalThis.FileSystemHandle || + !globalThis.FileSystemDirectoryHandle || + !globalThis.FileSystemFileHandle || + !globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle || + !navigator?.storage?.getDirectory){ wPost('opfs-unavailable',"Missing required OPFS APIs."); }else{ installAsyncProxy(self); } Index: ext/wasm/api/sqlite3-v-helper.js ================================================================== --- ext/wasm/api/sqlite3-v-helper.js +++ ext/wasm/api/sqlite3-v-helper.js @@ -13,14 +13,17 @@ This file installs sqlite3.vfs, and object which exists to assist in the creation of JavaScript implementations of sqlite3_vfs, along with its virtual table counterpart, sqlite3.vtab. */ 'use strict'; -self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ +globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const wasm = sqlite3.wasm, capi = sqlite3.capi, toss = sqlite3.util.toss3; const vfs = Object.create(null), vtab = Object.create(null); + const StructBinder = sqlite3.StructBinder + /* we require a local alias b/c StructBinder is removed from the sqlite3 + object during the final steps of the API cleanup. */; sqlite3.vfs = vfs; sqlite3.vtab = vtab; const sii = capi.sqlite3_index_info; /** @@ -110,11 +113,11 @@ environment in an undefined state. */ const installMethod = function callee( tgt, name, func, applyArgcCheck = callee.installMethodArgcCheck ){ - if(!(tgt instanceof sqlite3.StructBinder.StructType)){ + if(!(tgt instanceof StructBinder.StructType)){ toss("Usage error: target object is-not-a StructType."); }else if(!(func instanceof Function) && !wasm.isPtr(func)){ toss("Usage errror: expecting a Function or WASM pointer to one."); } if(1===arguments.length){ @@ -130,11 +133,11 @@ } return func.apply(this, args); } }; /* An ondispose() callback for use with - sqlite3.StructBinder-created types. */ + StructBinder-created types. */ callee.removeFuncList = function(){ if(this.ondispose.__removeFuncList){ this.ondispose.__removeFuncList.forEach( (v,ndx)=>{ if('number'===typeof v){ @@ -219,11 +222,11 @@ Equivalent to calling installMethod(this,...arguments) with a first argument of this object. If called with 1 or 2 arguments and the first is an object, it's instead equivalent to calling installMethods(this,...arguments). */ - sqlite3.StructBinder.StructType.prototype.installMethod = function callee( + StructBinder.StructType.prototype.installMethod = function callee( name, func, applyArgcCheck = installMethod.installMethodArgcCheck ){ return (arguments.length < 3 && name && 'object'===typeof name) ? installMethods(this, ...arguments) : installMethod(this, ...arguments); @@ -231,11 +234,11 @@ /** Equivalent to calling installMethods() with a first argument of this object. */ - sqlite3.StructBinder.StructType.prototype.installMethods = function( + StructBinder.StructType.prototype.installMethods = function( methods, applyArgcCheck = installMethod.installMethodArgcCheck ){ return installMethods(this, methods, applyArgcCheck); }; Index: ext/wasm/api/sqlite3-vfs-opfs.c-pp.js ================================================================== --- ext/wasm/api/sqlite3-vfs-opfs.c-pp.js +++ ext/wasm/api/sqlite3-vfs-opfs.c-pp.js @@ -16,11 +16,11 @@ Worker, implemented in sqlite3-opfs-async-proxy.js. This file is intended to be appended to the main sqlite3 JS deliverable somewhere after sqlite3-api-oo1.js and before sqlite3-api-cleanup.js. */ 'use strict'; -self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ +globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** installOpfsVfs() returns a Promise which, on success, installs an sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs which accept a VFS. It is intended to be called via sqlite3ApiBootstrap.initializersAsync or an equivalent mechanism. @@ -74,35 +74,35 @@ On success, the Promise resolves to the top-most sqlite3 namespace object and that object gets a new object installed in its `opfs` property, containing several OPFS-specific utilities. */ const installOpfsVfs = function callee(options){ - if(!self.SharedArrayBuffer - || !self.Atomics){ + if(!globalThis.SharedArrayBuffer + || !globalThis.Atomics){ return Promise.reject( new Error("Cannot install OPFS: Missing SharedArrayBuffer and/or Atomics. "+ "The server must emit the COOP/COEP response headers to enable those. "+ "See https://sqlite.org/wasm/doc/trunk/persistence.md#coop-coep") ); - }else if(self.window===self && self.document){ + }else if('undefined'===typeof WorkerGlobalScope){ return Promise.reject( new Error("The OPFS sqlite3_vfs cannot run in the main thread "+ "because it requires Atomics.wait().") ); - }else if(!self.FileSystemHandle || - !self.FileSystemDirectoryHandle || - !self.FileSystemFileHandle || - !self.FileSystemFileHandle.prototype.createSyncAccessHandle || - !navigator.storage.getDirectory){ + }else if(!globalThis.FileSystemHandle || + !globalThis.FileSystemDirectoryHandle || + !globalThis.FileSystemFileHandle || + !globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle || + !navigator?.storage?.getDirectory){ return Promise.reject( new Error("Missing required OPFS APIs.") ); } if(!options || 'object'!==typeof options){ options = Object.create(null); } - const urlParams = new URL(self.location.href).searchParams; + const urlParams = new URL(globalThis.location.href).searchParams; if(undefined===options.verbose){ options.verbose = urlParams.has('opfs-verbose') ? (+urlParams.get('opfs-verbose') || 2) : 1; } if(undefined===options.sanityChecks){ @@ -110,11 +110,11 @@ } if(undefined===options.proxyUri){ options.proxyUri = callee.defaultProxyUri; } - //sqlite3.config.warn("OPFS options =",options,self.location); + //sqlite3.config.warn("OPFS options =",options,globalThis.location); if('function' === typeof options.proxyUri){ options.proxyUri = options.proxyUri(); } const thePromise = new Promise(function(promiseResolve, promiseReject_){ @@ -147,15 +147,15 @@ /** Returns true if _this_ thread has access to the OPFS APIs. */ const thisThreadHasOPFS = ()=>{ - return self.FileSystemHandle && - self.FileSystemDirectoryHandle && - self.FileSystemFileHandle && - self.FileSystemFileHandle.prototype.createSyncAccessHandle && - navigator.storage.getDirectory; + return globalThis.FileSystemHandle && + globalThis.FileSystemDirectoryHandle && + globalThis.FileSystemFileHandle && + globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle && + navigator?.storage?.getDirectory; }; /** Not part of the public API. Solely for internal/development use. @@ -169,12 +169,12 @@ t += m.time; w += m.wait; m.avgTime = (m.count && m.time) ? (m.time / m.count) : 0; m.avgWait = (m.count && m.wait) ? (m.wait / m.count) : 0; } - sqlite3.config.log(self.location.href, - "metrics for",self.location.href,":",metrics, + sqlite3.config.log(globalThis.location.href, + "metrics for",globalThis.location.href,":",metrics, "\nTotal of",n,"op(s) for",t, "ms (incl. "+w+" ms of waiting on the async side)"); sqlite3.config.log("Serialization metrics:",metrics.s11n); W.postMessage({type:'opfs-async-metrics'}); }, @@ -1309,11 +1309,11 @@ })/*thePromise*/; return thePromise; }/*installOpfsVfs()*/; installOpfsVfs.defaultProxyUri = "sqlite3-opfs-async-proxy.js"; -self.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{ +globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{ try{ let proxyJs = installOpfsVfs.defaultProxyUri; if(sqlite3.scriptInfo.sqlite3Dir){ installOpfsVfs.defaultProxyUri = sqlite3.scriptInfo.sqlite3Dir + proxyJs; Index: ext/wasm/api/sqlite3-worker1-promiser.c-pp.js ================================================================== --- ext/wasm/api/sqlite3-worker1-promiser.c-pp.js +++ ext/wasm/api/sqlite3-worker1-promiser.c-pp.js @@ -130,11 +130,11 @@ Worker constructor, so that particular usage is not something we're going to target for the time being: https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker */ -self.sqlite3Worker1Promiser = function callee(config = callee.defaultConfig){ +globalThis.sqlite3Worker1Promiser = function callee(config = callee.defaultConfig){ // Inspired by: https://stackoverflow.com/a/52439530 if(1===arguments.length && 'function'===typeof arguments[0]){ const f = config; config = Object.assign(Object.create(null), callee.defaultConfig); config.onready = f; @@ -243,11 +243,11 @@ }); if(rowCallbackId) p = p.finally(()=>delete handlerMap[rowCallbackId]); return p; }; }/*sqlite3Worker1Promiser()*/; -self.sqlite3Worker1Promiser.defaultConfig = { +globalThis.sqlite3Worker1Promiser.defaultConfig = { worker: function(){ //#if target=es6-bundler-friendly return new Worker("sqlite3-worker1-bundler-friendly.mjs",{ type: 'module' /* Noting that neither Firefox nor Safari suppor this, as of this writing. */ @@ -257,19 +257,19 @@ if(this.currentScript){ const src = this.currentScript.src.split('/'); src.pop(); theJs = src.join('/')+'/' + theJs; //sqlite3.config.warn("promiser currentScript, theJs =",this.currentScript,theJs); - }else{ - //sqlite3.config.warn("promiser self.location =",self.location); - const urlParams = new URL(self.location.href).searchParams; + }else if(globalThis.location){ + //sqlite3.config.warn("promiser globalThis.location =",globalThis.location); + const urlParams = new URL(globalThis.location.href).searchParams; if(urlParams.has('sqlite3.dir')){ theJs = urlParams.get('sqlite3.dir') + '/' + theJs; } } - return new Worker(theJs + self.location.search); + return new Worker(theJs + globalThis.location.search); //#endif }.bind({ - currentScript: self?.document?.currentScript + currentScript: globalThis?.document?.currentScript }), onerror: (...args)=>console.error('worker1 promiser error',...args) }; Index: ext/wasm/api/sqlite3-worker1.c-pp.js ================================================================== --- ext/wasm/api/sqlite3-worker1.c-pp.js +++ ext/wasm/api/sqlite3-worker1.c-pp.js @@ -34,11 +34,13 @@ //#if target=es6-bundler-friendly import {default as sqlite3InitModule} from './sqlite3-bundler-friendly.mjs'; //#else "use strict"; { - const urlParams = new URL(self.location.href).searchParams; + const urlParams = globalThis.location + ? new URL(self.location.href).searchParams + : new URLSearchParams(); let theJs = 'sqlite3.js'; if(urlParams.has('sqlite3.dir')){ theJs = urlParams.get('sqlite3.dir') + '/' + theJs; } //console.warn("worker1 theJs =",theJs); Index: ext/wasm/common/whwasmutil.js ================================================================== --- ext/wasm/common/whwasmutil.js +++ ext/wasm/common/whwasmutil.js @@ -43,12 +43,12 @@ for their sub-optimally-documented Emscripten counterparts. Intended usage: ``` - self.WhWasmUtilInstaller(appObject); - delete self.WhWasmUtilInstaller; + globalThis.WhWasmUtilInstaller(appObject); + delete globalThis.WhWasmUtilInstaller; ``` Its global-scope symbol is intended only to provide an easy way to make it available to 3rd-party scripts and "should" be deleted after calling it. That symbols is _not_ used within the library. @@ -169,11 +169,11 @@ More specifically: https://fossil.wanderinghorse.net/r/jaccwabbyt/file/common/whwasmutil.js */ -self.WhWasmUtilInstaller = function(target){ +globalThis.WhWasmUtilInstaller = function(target){ 'use strict'; if(undefined===target.bigIntEnabled){ target.bigIntEnabled = !!self['BigInt64Array']; } @@ -2192,11 +2192,11 @@ that object, and not the `config` one.) Error handling is up to the caller, who may attach a `catch()` call to the promise. */ -self.WhWasmUtilInstaller.yawl = function(config){ +globalThis.WhWasmUtilInstaller.yawl = function(config){ const wfetch = ()=>fetch(config.uri, {credentials: 'same-origin'}); const wui = this; const finalThen = function(arg){ //log("finalThen()",arg); if(config.wasmUtilTarget){ @@ -2238,6 +2238,6 @@ .then(response => response.arrayBuffer()) .then(bytes => WebAssembly.instantiate(bytes, config.imports||{})) .then(finalThen); }; return loadWasm; -}.bind(self.WhWasmUtilInstaller)/*yawl()*/; +}.bind(globalThis.WhWasmUtilInstaller)/*yawl()*/; Index: ext/wasm/jaccwabyt/jaccwabyt.js ================================================================== --- ext/wasm/jaccwabyt/jaccwabyt.js +++ ext/wasm/jaccwabyt/jaccwabyt.js @@ -17,11 +17,11 @@ - https://fossil.wanderinghorse.net/r/jaccwabyt - https://sqlite.org/src/dir/ext/wasm/jaccwabyt */ 'use strict'; -self.Jaccwabyt = function StructBinderFactory(config){ +globalThis.Jaccwabyt = function StructBinderFactory(config){ /* ^^^^ it is recommended that clients move that object into wherever they'd like to have it and delete the self-held copy ("self" being the global window or worker object). This API does not require the global reference - it is simply installed as a convenience for connecting these bits to other co-developed code before it gets