Repository navigation
Conversation
…ored SQL
* [LokiJS] Web migrations: destroyTable, unsafeExecuteLoki, warn on ignored SQL
- New destroyTable({ table }) migration step. SQLite runs DROP TABLE IF
EXISTS. LokiJS removes the collection and deletes its chunks from
IndexedDB in the same transaction that saves the updated metadata, so
dropped tables are no longer loaded and parsed on every launch.
- New unsafeExecuteLoki(fn) step, the LokiJS counterpart of
unsafeExecuteSql. It's ignored on SQLite.
- LokiJS logs a warning for each ignored unsafeExecuteSql step.
- Migration syncs skip tables and columns destroyed later in the range.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Reject reserved table names case-insensitively, and unsafeExecuteLoki on web workers
destroyTable() now rejects local_storage in any letter case, since SQLite
table names are case-insensitive. LokiJSAdapter throws a clear error in
development when unsafeExecuteLoki() steps are used with
useWebWorker: true, instead of failing with DataCloneError.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Reject unsafeExecuteLoki with web workers in production too, test failed-save retry
The useWebWorker check now runs in production as well, so setup fails
with a clear error instead of DataCloneError. A new test aborts the
saves of a destroy + recreate migration, checks the old chunks are
intact, then lets the retry succeed and checks only the new data
remains after reopening.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Don't save changes made by a LokiJS migration that fails
If a migration step throws, Loki is stopped from saving before the
error is propagated, so the persisted database stays at the old version
and steps aren't applied twice when the migration runs again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Warn when a destroyed table's persisted data can't be deleted
destroyCollection() relies on IncrementalIndexedDBAdapter internals of
the pinned lokijs version. If the persistence adapter is incremental but
doesn't have them, it now logs a warning instead of silently keeping the
chunks.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
Hi @joker-777, thank you for this! I maintain NitromelonDB, a maintained fork of WatermelonDB (New Architecture, Nitro Modules). Something that might interest you: on the web, our A If you don't have the time or would rather not, no worries at all, I'm happy to port it myself. Just let me know. Thanks a lot! |
Migrations on the web (LokiJS) had no way to drop a table or change data:
unsafeExecuteSql()steps are silently ignored there. A table dropped with SQL stays in IndexedDB and is loaded and parsed on every launch.Changes
destroyTable({ table })migration step for both adapters. SQLite runsDROP TABLE IF EXISTS, so it's a no-op for a table that was already dropped withunsafeExecuteSql(). LokiJS removes the collection and deletes its chunks from IndexedDB, including leftover chunks of a collection that's no longer in LokiunsafeExecuteLoki(loki => {})step, the LokiJS counterpart ofunsafeExecuteSql(). It runs against the Loki instance during the migration and is ignored on SQLite. It can't be sent to a web worker, soLokiJSAdapterthrows a clear error when it's used withuseWebWorker: trueunsafeExecuteSql()step, with the first 200 characters of the SQLgetSyncChanges) accept the new steps, and skip tables and columns destroyed later in the rangedestroyTable()rejectslocal_storagein any letter caseLoki's own
removeCollection()throws for collections thatIncrementalIndexedDBAdapterloaded lazily, so the driver removes the collection fromloki.collectionsdirectly. Deleting the chunks relies on internals of theIncrementalIndexedDBAdapterin the lokijs version this repo pins. If they're missing, a warning is logged and the chunks are kept.Tests
src/adapters/lokijs/migrations.test.js, usingfake-indexeddband the realIncrementalIndexedDBAdapter. It checks the persisted IndexedDB keys after each migration: the destroyed table's chunks are gone; leftover chunks of a collection already missing from Loki are deleted; destroy plus create in one migration keeps the new data across later saves; and a failed save is retried with the old chunks intact until it succeeds. It also covers the SQL warning andunsafeExecuteLoki()destroys tables in migrations, which runs on LokiJS and SQLiteencodeMigrationSteps,getSyncChangesand the step constructorsfake-indexeddb@^6.2.5as a dev dependencyVerification
flow checkis clean, and ESLint is clean on the changed files. Thesqlite-nodesuite was run separately in a Node 22 container, because better-sqlite3 doesn't build on the host's Node; all 122 tests pass therelokiExtensions.js, where both add a function at the same place🤖 Generated with Claude Code