diff --git a/package-lock.json b/package-lock.json index e5a785e..f700f51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@sqlite.org/sqlite-wasm", - "version": "3.51.2-build2", + "version": "3.51.2-build3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@sqlite.org/sqlite-wasm", - "version": "3.51.2-build2", + "version": "3.51.2-build3", "license": "Apache-2.0", "devDependencies": { "@types/node": "^25.0.9", @@ -1388,7 +1388,6 @@ "integrity": "sha512-CE9nlzslHX6Qz//MVrjpulTC9IgtXTbJ+q7Rx1HD+IeSOWv4NHIRNHPA6dB4x01d9paEqt+TvoqZfmgq40DxEQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/browser": "4.0.17", "@vitest/mocker": "4.0.17", @@ -2079,7 +2078,6 @@ "integrity": "sha512-rfbiwB6OKxZFIFQ7SRnCPB2WL9WhyXsFoTfecYgeCeFSOBxvkWLaXsdv5ehzJrfqwXQmDephAKWLRQoFoJwrew==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", @@ -3206,7 +3204,6 @@ "integrity": "sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -3241,7 +3238,6 @@ "integrity": "sha512-MFqyfRLAExPVZdTQFwkAQELzA8idyXzROVOytg6nEJ/GEypXBUmMGrVaID8cTuzRS1U5L8yTOdOJtMXgFUJAeA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@publint/pack": "^0.1.2", "package-manager-detector": "^1.6.0", @@ -3313,7 +3309,6 @@ "integrity": "sha512-YYgpv7MiTp9LdLj1fzGzCtij8Yi2OKEc3HQtfbIxW4yuSgpQz9518I69U72T5ErPA/ATOXqlcisiLrWy+5V9YA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@oxc-project/types": "=0.108.0", "@rolldown/pluginutils": "1.0.0-beta.60" @@ -3746,7 +3741,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3841,7 +3835,6 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -3917,7 +3910,6 @@ "integrity": "sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/expect": "4.0.17", "@vitest/mocker": "4.0.17", diff --git a/package.json b/package.json index ec8eaee..f8a3bb6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sqlite.org/sqlite-wasm", - "version": "3.51.2-build2", + "version": "3.51.2-build3", "description": "SQLite Wasm conveniently wrapped as an ES Module.", "type": "module", "repository": { diff --git a/src/__tests__/bundler-compatibility.test.js b/src/__tests__/bundler-compatibility.test.js new file mode 100644 index 0000000..ac951d9 --- /dev/null +++ b/src/__tests__/bundler-compatibility.test.js @@ -0,0 +1,53 @@ +import { describe, test, expect } from 'vitest'; +import { execSync } from 'node:child_process'; +import path from 'node:path'; +import fs from 'node:fs'; + +describe('Vite bundler compatibility', () => { + test('should rename sqlite3.wasm with a hash and update the import URL', () => { + const testDir = path.resolve(__dirname, 'vite-repro'); + const distDir = path.resolve(testDir, 'dist'); + + // Clean up previous build + if (fs.existsSync(distDir)) { + fs.rmSync(distDir, { recursive: true, force: true }); + } + + // Run vite build + execSync('npx vite build --logLevel error', { + cwd: testDir, + stdio: 'inherit', + }); + + // 1. Check if hashed WASM file exists in dist/assets + const assetsDir = path.resolve(distDir, 'assets'); + const files = fs.readdirSync(assetsDir); + const wasmFile = files.find( + (f) => f.startsWith('sqlite3-') && f.endsWith('.wasm'), + ); + + expect(wasmFile).toBeDefined(); + + // 2. Check if the JS bundle contains the hashed WASM filename + const assetsDirJs = path.resolve(distDir, 'assets'); + const jsFiles = fs + .readdirSync(assetsDirJs) + .filter((f) => f.endsWith('.js')); + const mainBundle = jsFiles.find((f) => f.startsWith('index-')); + expect(mainBundle).toBeDefined(); + + const bundleContent = fs.readFileSync( + path.resolve(assetsDirJs, mainBundle), + 'utf8', + ); + + // It should contain something like: new URL("/assets/sqlite3-hash.wasm", import.meta.url) + expect(bundleContent).toContain(wasmFile); + + // Specifically check that it's part of a new URL call or at least correctly referenced + const urlPattern = new RegExp( + `new URL\\(".*${wasmFile}",\\s*import\\.meta\\.url\\)`, + ); + expect(bundleContent).toMatch(urlPattern); + }); +}); diff --git a/src/__tests__/sqlite3-node.test.js b/src/__tests__/sqlite3-node.test.js index 43fcefe..88f50d3 100644 --- a/src/__tests__/sqlite3-node.test.js +++ b/src/__tests__/sqlite3-node.test.js @@ -135,6 +135,30 @@ test('Node.js build sanity check', async () => { expect( typeof db.selectValue('SELECT sqlite_offset(id) FROM off_test'), ).toBe('number'); + + // 13. Blobs + const blobData = new Uint8Array([0x00, 0xff, 0xaa, 0x55]); + db.exec({ + sql: 'CREATE TABLE blobs (data BLOB)', + }); + db.exec({ + sql: 'INSERT INTO blobs (data) VALUES (?)', + bind: [blobData], + }); + const retrievedBlob = db.selectValue('SELECT data FROM blobs'); + expect(retrievedBlob).toBeInstanceOf(Uint8Array); + expect(retrievedBlob).toEqual(blobData); + + // 14. Error handling + expect(() => { + db.exec('INVALID SQL'); + }).toThrow(); + + db.exec('CREATE TABLE unique_test (id INTEGER PRIMARY KEY)'); + db.exec('INSERT INTO unique_test VALUES (1)'); + expect(() => { + db.exec('INSERT INTO unique_test VALUES (1)'); + }).toThrow(/UNIQUE constraint failed/); } finally { // 11. Close the database db.close(); diff --git a/src/__tests__/sqlite3-oo1.browser.test.js b/src/__tests__/sqlite3-oo1.browser.test.js index 1dc77c7..c636bb3 100644 --- a/src/__tests__/sqlite3-oo1.browser.test.js +++ b/src/__tests__/sqlite3-oo1.browser.test.js @@ -135,6 +135,30 @@ test('Bundler-friendly OO1 API sanity check (browser)', async () => { expect( typeof db.selectValue('SELECT sqlite_offset(id) FROM off_test'), ).toBe('number'); + + // 13. Blobs + const blobData = new Uint8Array([0x00, 0xff, 0xaa, 0x55]); + db.exec({ + sql: 'CREATE TABLE blobs (data BLOB)', + }); + db.exec({ + sql: 'INSERT INTO blobs (data) VALUES (?)', + bind: [blobData], + }); + const retrievedBlob = db.selectValue('SELECT data FROM blobs'); + expect(retrievedBlob).toBeInstanceOf(Uint8Array); + expect(retrievedBlob).toEqual(blobData); + + // 14. Error handling + expect(() => { + db.exec('INVALID SQL'); + }).toThrow(); + + db.exec('CREATE TABLE unique_test (id INTEGER PRIMARY KEY)'); + db.exec('INSERT INTO unique_test VALUES (1)'); + expect(() => { + db.exec('INSERT INTO unique_test VALUES (1)'); + }).toThrow(/UNIQUE constraint failed/); } finally { db.close(); expect(db.isOpen()).toBe(false); diff --git a/src/__tests__/vite-repro/index.html b/src/__tests__/vite-repro/index.html new file mode 100644 index 0000000..906966c --- /dev/null +++ b/src/__tests__/vite-repro/index.html @@ -0,0 +1,6 @@ + + +
+ + + diff --git a/src/__tests__/vite-repro/main.js b/src/__tests__/vite-repro/main.js new file mode 100644 index 0000000..1a0fd14 --- /dev/null +++ b/src/__tests__/vite-repro/main.js @@ -0,0 +1,3 @@ +import sqlite3InitModule from '../../../src/index.js'; + +await sqlite3InitModule(); diff --git a/src/__tests__/workers/sqlite3-sahpool.worker.js b/src/__tests__/workers/sqlite3-sahpool.worker.js index 8b13e6c..251f919 100644 --- a/src/__tests__/workers/sqlite3-sahpool.worker.js +++ b/src/__tests__/workers/sqlite3-sahpool.worker.js @@ -1,10 +1,10 @@ import sqlite3InitModule from '../../bin/sqlite3-bundler-friendly.mjs'; -self.onmessage = async (e) => { +self.onmessage = async () => { try { const sqlite3 = await sqlite3InitModule(); const opfsSahPool = await sqlite3.installOpfsSAHPoolVfs(); - const db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3'); + let db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3'); try { // 1. Basic CRUD @@ -29,6 +29,15 @@ self.onmessage = async (e) => { throw new Error('CRUD check failed'); } + db.close(); + + // Reopen to check persistence + db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3'); + const count = db.selectValue('SELECT count(*) FROM test'); + if (count !== 2) { + throw new Error('Persistence check failed'); + } + // 2. Joins db.exec( 'CREATE TABLE orders (id INTEGER PRIMARY KEY, user_id INTEGER, product TEXT)', @@ -42,13 +51,17 @@ self.onmessage = async (e) => { rowMode: 'object', callback: (row) => joinedRows.push(row), }); - if (joinedRows.length !== 2) throw new Error('Join check failed'); + if (joinedRows.length !== 2) { + throw new Error('Join check failed'); + } // 3. CTE const cteCount = db.selectValue( 'WITH RECURSIVE cnt(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM cnt LIMIT 5) SELECT count(*) FROM cnt', ); - if (cteCount !== 5) throw new Error('CTE check failed'); + if (cteCount !== 5) { + throw new Error('CTE check failed'); + } // 4. FTS5 db.exec('CREATE VIRTUAL TABLE docs USING fts5(content)'); @@ -56,16 +69,71 @@ self.onmessage = async (e) => { const ftsResult = db.selectValue( "SELECT content FROM docs WHERE docs MATCH 'sqlite'", ); - if (ftsResult !== 'sqlite is great') throw new Error('FTS5 check failed'); + if (ftsResult !== 'sqlite is great') { + throw new Error('FTS5 check failed'); + } // 5. Math Functions const cosResult = db.selectValue('SELECT cos(0)'); - if (cosResult !== 1) throw new Error('Math functions check failed'); + if (cosResult !== 1) { + throw new Error('Math functions check failed'); + } // 6. Percentile db.exec('CREATE TABLE p(x); INSERT INTO p VALUES (1),(2),(3),(4),(5);'); const perc = db.selectValue('SELECT percentile(x, 50) FROM p'); - if (perc !== 3) throw new Error('Percentile check failed'); + if (perc !== 3) { + throw new Error('Percentile check failed'); + } + + // 7. pauseVfs and unpauseVfs + // Ensure it's not paused initially + if (opfsSahPool.isPaused()) { + throw new Error('VFS should not be paused initially'); + } + + db.close(); // Must close DB before pausing if it's the only one using it, + // or at least ensures no open file handles. + // Actually, pauseVfs throws if there are open file handles. + + opfsSahPool.pauseVfs(); + if (!opfsSahPool.isPaused()) { + throw new Error('VFS should be paused after pauseVfs()'); + } + + // Attempting to open a DB with a paused VFS should fail + try { + new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3'); + throw new Error('Opening DB should have failed while VFS is paused'); + } catch (e) { + // Expected error + } + + await opfsSahPool.unpauseVfs(); + if (opfsSahPool.isPaused()) { + throw new Error('VFS should not be paused after unpauseVfs()'); + } + + // Test that pauseVfs() throws if there are open file handles + db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3'); + try { + opfsSahPool.pauseVfs(); + throw new Error('pauseVfs should have failed with open DB handles'); + } catch (e) { + if (!e.message.includes('Cannot pause VFS')) { + throw new Error( + 'pauseVfs failed with unexpected error: ' + e.message, + ); + } + } + db.close(); + + // Now it should work again + db = new opfsSahPool.OpfsSAHPoolDb('/test-sahpool-worker.sqlite3'); + const count2 = db.selectValue('SELECT count(*) FROM test'); + if (count2 !== 2) { + throw new Error('Persistence check after unpause failed'); + } self.postMessage({ type: 'success' }); } finally { diff --git a/src/bin/sqlite3-bundler-friendly.mjs b/src/bin/sqlite3-bundler-friendly.mjs index aecc550..d70b37b 100644 --- a/src/bin/sqlite3-bundler-friendly.mjs +++ b/src/bin/sqlite3-bundler-friendly.mjs @@ -29,7 +29,7 @@ ** ** SQLITE_VERSION "3.52.0" ** SQLITE_VERSION_NUMBER 3052000 -** SQLITE_SOURCE_ID "2026-01-20 10:57:44 346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca" +** SQLITE_SOURCE_ID "2026-01-20 18:30:48 2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552" ** ** Emscripten SDK: 4.0.23 */ @@ -94,85 +94,6 @@ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIR ./c-pp-lite -o ./bld/pre-js.bundler.js -Dtarget:es6-module -Dtarget:es6-bundler-friendly -DModule.instantiateWasm api/pre-js.c-pp.js */ -(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) { - return new URL(path, import.meta.url).href; - }.bind(sIMS); - - /** - 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){ - const sims = this; - 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 finalThen = (arg)=>{ - arg.imports = imports; - sims.instantiateWasm = arg /* used by sqlite3-api-prologue.c-pp.js */; - onSuccess(arg.instance, arg.module); - }; - 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(); - }.bind(sIMS); -})(Module); /* END FILE: api/pre-js.js. */ // end include: ./bld/pre-js.bundler.js @@ -4824,7 +4745,7 @@ Module.runSQLite3PostLoadInit = async function( ** ** SQLITE_VERSION "3.52.0" ** SQLITE_VERSION_NUMBER 3052000 -** SQLITE_SOURCE_ID "2026-01-20 10:57:44 346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca" +** SQLITE_SOURCE_ID "2026-01-20 18:30:48 2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552" ** ** Emscripten SDK: 4.0.23 */ @@ -6999,7 +6920,7 @@ globalThis.sqlite3ApiBootstrap.defaultConfig = Object.create(null); */ globalThis.sqlite3ApiBootstrap.sqlite3 = undefined; globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - sqlite3.version = {"libVersion": "3.52.0", "libVersionNumber": 3052000, "sourceId": "2026-01-20 10:57:44 346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca","downloadVersion": 3520000,"scm":{ "sha3-256": "346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca","branch": "trunk","tags": "","datetime": "2026-01-20T10:57:44.925Z"}}; + sqlite3.version = {"libVersion": "3.52.0", "libVersionNumber": 3052000, "sourceId": "2026-01-20 18:30:48 2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552","downloadVersion": 3520000,"scm":{ "sha3-256": "2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552","branch": "trunk","tags": "","datetime": "2026-01-20T18:30:48.704Z"}}; }); /** 2022-07-08 @@ -21047,6 +20968,8 @@ const toExportForESM = const sIM = globalThis.sqlite3InitModule = function ff(...args){ //console.warn("Using replaced sqlite3InitModule()",globalThis.location); + sIMS.emscriptenLocateFile = args[0]?.locateFile /* see pre-js.c-pp.js [tag:locateFile] */; + sIMS.emscriptenInstantiateWasm = args[0]?.instantiateWasm /* see pre-js.c-pp.js [tag:locateFile] */; return originalInit(...args).then((EmscriptenModule)=>{ sIMS.debugModule("sqlite3InitModule() sIMS =",sIMS); sIMS.debugModule("sqlite3InitModule() EmscriptenModule =",EmscriptenModule); diff --git a/src/bin/sqlite3-node.mjs b/src/bin/sqlite3-node.mjs index 407f45a..5981029 100644 --- a/src/bin/sqlite3-node.mjs +++ b/src/bin/sqlite3-node.mjs @@ -29,7 +29,7 @@ ** ** SQLITE_VERSION "3.52.0" ** SQLITE_VERSION_NUMBER 3052000 -** SQLITE_SOURCE_ID "2026-01-20 10:57:44 346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca" +** SQLITE_SOURCE_ID "2026-01-20 18:30:48 2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552" ** ** Emscripten SDK: 4.0.23 */ @@ -105,50 +105,11 @@ if (ENVIRONMENT_IS_NODE) { 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 targeting browser - environments are supported and tested. + 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) are not supported deliverables. */ -(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) { - return new URL(path, import.meta.url).href; - }.bind(sIMS); - -})(Module); /* END FILE: api/pre-js.js. */ // end include: ./bld/pre-js.node.js @@ -4842,7 +4803,7 @@ Module.runSQLite3PostLoadInit = async function( ** ** SQLITE_VERSION "3.52.0" ** SQLITE_VERSION_NUMBER 3052000 -** SQLITE_SOURCE_ID "2026-01-20 10:57:44 346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca" +** SQLITE_SOURCE_ID "2026-01-20 18:30:48 2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552" ** ** Emscripten SDK: 4.0.23 */ @@ -7017,7 +6978,7 @@ globalThis.sqlite3ApiBootstrap.defaultConfig = Object.create(null); */ globalThis.sqlite3ApiBootstrap.sqlite3 = undefined; globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - sqlite3.version = {"libVersion": "3.52.0", "libVersionNumber": 3052000, "sourceId": "2026-01-20 10:57:44 346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca","downloadVersion": 3520000,"scm":{ "sha3-256": "346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca","branch": "trunk","tags": "","datetime": "2026-01-20T10:57:44.925Z"}}; + sqlite3.version = {"libVersion": "3.52.0", "libVersionNumber": 3052000, "sourceId": "2026-01-20 18:30:48 2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552","downloadVersion": 3520000,"scm":{ "sha3-256": "2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552","branch": "trunk","tags": "","datetime": "2026-01-20T18:30:48.704Z"}}; }); /** 2022-07-08 @@ -18157,6 +18118,8 @@ const toExportForESM = const sIM = globalThis.sqlite3InitModule = function ff(...args){ //console.warn("Using replaced sqlite3InitModule()",globalThis.location); + sIMS.emscriptenLocateFile = args[0]?.locateFile /* see pre-js.c-pp.js [tag:locateFile] */; + sIMS.emscriptenInstantiateWasm = args[0]?.instantiateWasm /* see pre-js.c-pp.js [tag:locateFile] */; return originalInit(...args).then((EmscriptenModule)=>{ sIMS.debugModule("sqlite3InitModule() sIMS =",sIMS); sIMS.debugModule("sqlite3InitModule() EmscriptenModule =",EmscriptenModule); diff --git a/src/bin/sqlite3.mjs b/src/bin/sqlite3.mjs index 3a1dc11..d73d496 100644 --- a/src/bin/sqlite3.mjs +++ b/src/bin/sqlite3.mjs @@ -29,7 +29,7 @@ ** ** SQLITE_VERSION "3.52.0" ** SQLITE_VERSION_NUMBER 3052000 -** SQLITE_SOURCE_ID "2026-01-20 10:57:44 346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca" +** SQLITE_SOURCE_ID "2026-01-20 18:30:48 2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552" ** ** Emscripten SDK: 4.0.23 */ @@ -131,6 +131,14 @@ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIR 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); + } return new URL(path, import.meta.url).href; }.bind(sIMS); @@ -147,6 +155,10 @@ var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIR 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 uri = Module.locateFile( sims.wasmFilename, ( @@ -4824,7 +4836,7 @@ Module.runSQLite3PostLoadInit = async function( ** ** SQLITE_VERSION "3.52.0" ** SQLITE_VERSION_NUMBER 3052000 -** SQLITE_SOURCE_ID "2026-01-20 10:57:44 346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca" +** SQLITE_SOURCE_ID "2026-01-20 18:30:48 2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552" ** ** Emscripten SDK: 4.0.23 */ @@ -6999,7 +7011,7 @@ globalThis.sqlite3ApiBootstrap.defaultConfig = Object.create(null); */ globalThis.sqlite3ApiBootstrap.sqlite3 = undefined; globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - sqlite3.version = {"libVersion": "3.52.0", "libVersionNumber": 3052000, "sourceId": "2026-01-20 10:57:44 346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca","downloadVersion": 3520000,"scm":{ "sha3-256": "346ad366a8ebed1e7936c59f8a40e9c8e7e31d0153bc4f654a47b2ddc39b18ca","branch": "trunk","tags": "","datetime": "2026-01-20T10:57:44.925Z"}}; + sqlite3.version = {"libVersion": "3.52.0", "libVersionNumber": 3052000, "sourceId": "2026-01-20 18:30:48 2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552","downloadVersion": 3520000,"scm":{ "sha3-256": "2b3b36da9d60c265dceec5964ea51c752d81f41459fb6849c8faea658b253552","branch": "trunk","tags": "","datetime": "2026-01-20T18:30:48.704Z"}}; }); /** 2022-07-08 @@ -21047,6 +21059,8 @@ const toExportForESM = const sIM = globalThis.sqlite3InitModule = function ff(...args){ //console.warn("Using replaced sqlite3InitModule()",globalThis.location); + sIMS.emscriptenLocateFile = args[0]?.locateFile /* see pre-js.c-pp.js [tag:locateFile] */; + sIMS.emscriptenInstantiateWasm = args[0]?.instantiateWasm /* see pre-js.c-pp.js [tag:locateFile] */; return originalInit(...args).then((EmscriptenModule)=>{ sIMS.debugModule("sqlite3InitModule() sIMS =",sIMS); sIMS.debugModule("sqlite3InitModule() EmscriptenModule =",EmscriptenModule); diff --git a/src/bin/sqlite3.wasm b/src/bin/sqlite3.wasm index 84c0df8..d9c2cb9 100644 Binary files a/src/bin/sqlite3.wasm and b/src/bin/sqlite3.wasm differ diff --git a/vitest.config.ts b/vitest.config.ts index a9c413a..b6d6f87 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -26,7 +26,10 @@ const vitestConfig: ViteUserConfig = defineConfig({ test: { name: 'node', environment: 'node', - include: ['src/__tests__/sqlite3-node.test.js'], + include: [ + 'src/__tests__/sqlite3-node.test.js', + 'src/__tests__/bundler-compatibility.test.js', + ], }, }, {