Skip to content

Conversation

@ikusteu
Copy link

@ikusteu ikusteu commented Oct 12, 2025

Follows #54 (includes the patch)
Fixes #33

Following the aforementioned PR, the updated wa-sqlite implementation allows for usage of multiple VFS implementations. In order to support this in the JS stack, this PR provides some minor extensions to the API allowing for specifying of custom wasm initializer.

Public API

The changes are done in such a way that they don't break the existing public API:

The existing public API usage:

import initWasm from "@vlcn.io/crsqlite-wasm"
import wasmUrl from "@vlcn.io/wa-sqlite/dist/crsqlite.wasm?url"

const sqlite = await initWasm(() => wasmUrl)

The update (allowing for more modular usage of VFS adapters):

// The default, consistent with the existing impl
import initWasm from "@vlcn.io/crsqlite-wasm"
import wasmUrl from "@vlcn.io/wa-sqlite/dist/crsqlite.wasm?url"

const sqlite = await initWasm(() => wasmUrl)

// Custom initializer (e.g. sync build + 'opfs-coop-sync')
import { createWasmInitializer } from "@vlcn.io/crsqlite-wasm";

import wasmSyncUrl from "@vlcn.io/wa-sqlite/dist/crsqlite-sync.wasm?url";
import ModuleFactory from "@vlcn.io/wa-sqlite/dist/crsqlite-sync.mjs";
import { OPFSCoopSyncVFS } from "@vlcn.io/wa-sqlite/src/examples/OPFSCoopSyncVFS.js"

const vfsFactory = (module: any) => OPFSCoopSyncVFS.create("opfs-coop-sync", module)
const initWasm = createWasmInitializer({ ModuleFactory, vfsFactory })

const sqlite = await initWasm(() => wasmSyncUrl)

Other consumers of initWasm (e.g. createDbProvider in browserdb package) accepts the custom initializer (defaulting to the default initWasm):

// before
export function createDbProvider(wasmUri?: string): (dbname: string) => PromiseLike<DB>

// after
export function createDbProvider(wasmUri?: string, initializer = initWasm): (dbname: string) => PromiseLike<DB>

Caching

Finally, the caching is changed a bit. The existing impl uses a single JS glue code (asyncify build), corresponding WASM binary and IDBBatchAtomicVFS. To that end, crsqlite-wasm (initWasm) caches the initialised and wrapped sqlite API.

In this case, however, we can't cache every result of createWasmInitializer(config)(() => wasmUrl) all the same as different consumers might initialise with different builds (or different VFS adapters), so the caching is extended like so:

  • use const apiCache = new Map<string, SQLite3>() instead of let api: SQLite3 | null
  • cache only if cache key specified (otherwise no caching - every call to initWasm will create a new WASM <-> JS instance)
  • the cache key is provided when creating the initialiser (e.g.):
const ModuleFactory // e.g. sync build: crsqlite-sync.mjs
const vfsFactory // e.g. OPFSCoopSyncVFS
const cacheKey = "sync-opfs-coop-sync"

const initWasm = createWasmInitializer({ ModuleFactory, vfsFactory, cacheKey })

const a = initWasm(() => wasmUrl)
const b = initWasm(() => wasmUrl)
a === b // true
  • default initWasm is cached using "default" as cache key

TODO

In the React package, the init() function accepts the custom initializer, but that bit in unreachable from the end caller, this could be updated, but I didn't jump through React hoops there at this moment

* includes commit: 'debug' make target fix
* includes commit: bump requested IDB 5 -> 6
* point 'wa-sqlite' submodule to reconciliation checkpoint 2
* bump emcc used in 'build-wasm.sh' (and 'build-wasm-dbg.sh') to 3.1.45 -> 3.1.47
* update crsqlite-wasm's 'initWasm' VFS initialisation (in line with changes to 'wa-sqlite' API)
* point 'wa-sqlite' submodule to the latest (in-sync-with-original) commit
* bump emscripten version in the build script to 3.1.61
* add 'createWasmInitializer' function - creating a function akin to 'initWasm' with custom setup (WASM ModuleFactory, vfsFactory)
* keep the default 'initWasm' (Asyncify build, IDBBatchAtomic) for API consistency
* add (optional) parameter for 'initializer' in browserdb, react and direct-connect-browser packages
@ikusteu ikusteu force-pushed the modular-vfs-support branch from 46d47e3 to 89d89de Compare October 17, 2025 11:54
* don't ALWAYS cache the SQLiteAPI in 'crsqlite-wasm' (initWasm)
* cache only if 'cacheKey' provided (based on cache key)
* use "default" as cache key for default 'initWasm'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose different VFS options

1 participant