Typesafe custom wa-sqlite wrapper, run in memory or persist data to IndexedDB or OPFS, support FTS5 and update / delete limit
Low-level layer for kysely-wasqlite-worker-dialect
Store data in memory, use MemoryVFS
with wa-sqlite.wasm
, no data persistence
import { initSQLite, isOpfsSupported, useMemoryStorage } from '@subframe7536/sqlite-wasm' // optional url const url = 'https://cdn.jsdelivr.net/npm/@subframe7536/sqlite-wasm@0.5.0/wa-sqlite.wasm' const url1 = 'https://cdn.jsdelivr.net/gh/subframe7536/sqlite-wasm@v0.5.0/wa-sqlite-fts5/wa-sqlite.wasm' const { run, changes, lastInsertRowId, close } = await initSQLite( useMemoryStorage({ url }) )
Store data in IndexedDB
, use IDBBatchAtomicVFS
with wa-sqlite-async.wasm
, larger than sync version, better compatibility
minimal IndexedDB backend browser version
import { initSQLite } from '@subframe7536/sqlite-wasm' import { useIdbStorage } from '@subframe7536/sqlite-wasm/idb' // optional url const url = 'https://cdn.jsdelivr.net/npm/@subframe7536/sqlite-wasm@0.5.0/wa-sqlite-async.wasm' const url1 = 'https://cdn.jsdelivr.net/gh/subframe7536/sqlite-wasm@v0.5.0/wa-sqlite-fts5/wa-sqlite-async.wasm' const { run, changes, lastInsertRowId, close } = await initSQLite( useIdbStorage('test.db', { url }) )
Store data in memory and sync to IndexedDB
, use IDBMirrorVFS
with wa-sqlite-async.wasm
(larger than sync version), better performance compare to useIdbStorage
.
import { initSQLite } from '@subframe7536/sqlite-wasm' import { useIdbMemoryStorage } from '@subframe7536/sqlite-wasm/idb-memory' // before 0.5.0 // import { useIdbMemoryStorage } from '@subframe7536/sqlite-wasm/idb' // optional url const url = 'https://cdn.jsdelivr.net/npm/@subframe7536/sqlite-wasm@0.5.0/dist/wa-sqlite-async.wasm' const { run, changes, lastInsertRowId, close } = await initSQLite( useIdbMemoryStorage('test.db', { url }) )
Store data in OPFS through FileSystemSyncAccessHandle, use OPFSCoopSyncVFS
with wa-sqlite.wasm
, smaller and faster all other persist storages.
Important
MUST RUN IN WEB WORKER!
minimal OPFS backend browser version
import { initSQLite, isOpfsSupported } from '@subframe7536/sqlite-wasm' import { useOpfsStorage } from '@subframe7536/sqlite-wasm/opfs' // optional url const url = 'https://cdn.jsdelivr.net/npm/@subframe7536/sqlite-wasm@0.5.0/dist/wa-sqlite.wasm' onmessage = async () => { if (!await isOpfsSupported()) { // this can be called in main thread return } const { run, changes, lastInsertRowId, close } = await initSQLite( useOpfsStorage('test.db', url) ) }
Store data through FileSystemFileHandle
, use modified OPFSAnyContextVFS
with wa-sqlite-async.wasm
, allow to directly read and write to device's local file or OPFS file entry in main or worker thread, but a little slower than useOpfsStorage
minimal File System Access backend browser version
Warning
import { initSQLite, isOpfsSupported } from '@subframe7536/sqlite-wasm' import { useFsHandleStorage } from '@subframe7536/sqlite-wasm/fs-handle' // optional url const url = 'https://cdn.jsdelivr.net/npm/@subframe7536/sqlite-wasm@0.5.0/dist/wa-sqlite-async.wasm' // device's local file const root = await window.showDirectoryPicker() // OPFS const root1 = await navigator.storage.getDirectory() const { run, changes, lastInsertRowId, close } = await initSQLite( useFsHandleStorage('test.db', root, url) )
From v0.5.0
Existing database can be File
or ReadableStream
async function selectFile(): Promise<File> { return await new Promise((resolve, reject) => { const input = document.createElement('input') input.type = 'file' input.onchange = () => { const file = input.files?.[0] if (file) { resolve(file) } else { reject(new Error('No file selected')) } input.remove() } input.oncancel = () => { reject(new Error('File selection cancelled')) input.remove() } input.click() }) } const FileOrReadableStream = remote ? (await fetch(remoteSqliteURL)).body! : await selectFile()
Import while initiaizing
import { initSQLite, withExistDB } from '@subframe7536/sqlite-wasm' import { useIdbStorage } from '@subframe7536/sqlite-wasm/idb' const db = initSQLite( useIdbStorage('test.db', withExistDB(FileOrReadableStream, { url })) )
or load it later
import { importDatabase } from '@subframe7536/sqlite-wasm' import { useIdbStorage } from '@subframe7536/sqlite-wasm/idb' const db = initSQLite('test.db', { url }) await db.sync(FileOrReadableStream) // or use independent function await importDatabase(db.vfs, db.path, FileOrReadableStream)
Currently import with useIdbMemoryStorage
will emit error (upstream)
From v0.5.0
If you are using useOpfsStorage
, you can directly download it from OPFS, since its db file has same structure as native filesystem.
Example for useIdbStorage
import { exportDatabase } from '@subframe7536/sqlite-wasm' import { useIdbStorage } from '@subframe7536/sqlite-wasm/idb' const db = initSQLite('test.db', { url }) const buffer = await db.dump() // or use independent function const buffer1 = exportDatabase(db.vfs, db.path)
import { customFunction, initSQLite, isOpfsSupported } from '@subframe7536/sqlite-wasm' import { useOpfsStorage } from '@subframe7536/sqlite-wasm/opfs' import { uuidv7 } from 'uuidv7' const { run, sqlite, db } = await initSQLite( useOpfsStorage('test') ) customFunction(sqlite, db, 'uuidv7', () => uuidv7()) console.log(await run('select uuidv7() as a')) // [{ "a": "01932f1b-b663-7714-af4d-17a3d9efc7b3" }]
import { close, customFunctionCore, exportDatabase, importDatabase, initSQLiteCore, run, } from '@subframe7536/sqlite-wasm' const core = await initSQLiteCore(/* options */) await importDatabase(core.vfs, core.path, stream) customFunctionCore(core, 'test', num => num) await run(core, 'select test(?)', [1]) const buf = await exportDatabase(core.vfs, core.path) await close(core)
MIT