Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG-Unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- New `destroyTable({ table })` migration step. On SQLite, it's `DROP TABLE IF EXISTS`. On LokiJS, the collection is removed and its data is deleted from IndexedDB, so it's no longer loaded and parsed on every launch (also if it was already removed from Loki)
- [LokiJS] New `unsafeExecuteLoki(loki => {})` migration step, the LokiJS counterpart of `unsafeExecuteSql()`. It's ignored on SQLite
- [LokiJS] `unsafeExecuteSql()` migration steps, which are ignored on LokiJS, now log a warning
- [LokiJS] New opt-in `exclusiveLock` option: only one browser tab at a time has the database open (using the Web Locks API), so tabs no longer overwrite each other's changes or undo a reset done in another tab. Other tabs wait until it's closed, and `onDatabaseLockedElsewhere` is called. Without the Web Locks API, the database is opened without a lock

### Fixes

Expand All @@ -22,6 +23,7 @@
- [LokiJS] When IndexedDB database is deleted in another tab (`onversionchange`), the database is no longer re-created from this tab's memory on next autosave. Instead, the adapter stops saving, rejects further changes, and calls `onPersistenceError`
- [LokiJS] Failures to save the database to IndexedDB are now always logged
- [LokiJS] When a migration fails, changes made by the steps that ran before the failure are no longer autosaved under the old schema version
- [LokiJS] After the database stops being saved (e.g. it was deleted in another tab), callbacks waiting for a save that was in progress (from `close()` or `unsafeResetDatabase()`) are now called with an error instead of never being called
- [LokiJS] When accessing or opening IndexedDB throws synchronously (e.g. `SecurityError` when storage access is denied), the adapter now falls back to an in-memory database like for other IndexedDB open failures (or fails setup with `allowInMemoryFallback: false`), instead of always failing setup
- [Android] Added linker flag for building with 16kB page alignment
- [TS] make catchError visible to typescript
Expand Down
10 changes: 8 additions & 2 deletions docs-website/docs/docs/Setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ const adapter = new LokiJSAdapter({
onInMemoryFallback: (reason) => {
// IndexedDB is unavailable, so data will be lost when the page is closed -- warn the user
},
// (Opt-in) Only one browser tab at a time has the database open (uses the Web Locks API)
exclusiveLock: true,
onDatabaseLockedElsewhere: () => {
// The database is open in another tab. Setup waits until that tab is closed -- tell the user
},
extraIncrementalIDBOptions: {
onDidOverwrite: () => {
// Called when this adapter is forced to overwrite contents of IndexedDB.
Expand Down Expand Up @@ -127,8 +132,9 @@ On the web, `database.write()` resolves once changes are applied in memory. Loki
Multiple tabs of the same app share one IndexedDB database, but each tab keeps its own in-memory copy:

- When another tab deletes the database (e.g. on logout), this tab stops saving to IndexedDB, rejects further changes (including `unsafeExecute`), and calls `onPersistenceError` and `onversionchange`. Reload the page to continue.
- When two tabs make changes concurrently, the last tab to save overwrites changes saved by the other one (`onDidOverwrite` is called). WatermelonDB does not coordinate writers across tabs.
- `onPersistenceError`, `onInMemoryFallback`, `onQuotaExceededError` and `extraIncrementalIDBOptions` callbacks only work with `useWebWorker: false`.
- When two tabs make changes concurrently, the last tab to save overwrites changes saved by the other one (`onDidOverwrite` is called). By default, WatermelonDB does not coordinate writers across tabs.
- With `exclusiveLock: true`, only one tab at a time has the database open, using the [Web Locks API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Locks_API). In other tabs, setup (and all database operations) wait until that tab is closed, and `onDatabaseLockedElsewhere` is called. If the lock is lost (e.g. stolen using DevTools), the tab stops saving and rejects further changes. Where the Web Locks API is unavailable (old browsers, insecure contexts), the database is opened without a lock and a warning is logged.
- `onPersistenceError`, `onInMemoryFallback`, `onQuotaExceededError`, `onDatabaseLockedElsewhere` and `extraIncrementalIDBOptions` callbacks only work with `useWebWorker: false`.
:::

* * *
Expand Down
Loading
Loading