-
-
Notifications
You must be signed in to change notification settings - Fork 641
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Official event Dexie.on('storagemutated') (#1384)
Official event Dexie.on('storagemutated'). This change is a step to making dexie@3.2.0 an officially supported stable release where the observability communication channel can be official and documented. The event was previously undocumented and had the name Dexie.on('txcommitted'). The event is the channel that communicates changes on indexeddb databases to enable `liveQuery()` to detect changes across service worker, windows and tabs. Event is propagated across peers using BroadcastChannel on browsers supporting it, and "storage" event on IE and Safari. The commit does not break any officially documented Dexie API but as the rename of the "txcommitted" event to "storagemutated" and its corresponding event names in BroadcastChannel land localStorage ("x-storagemutated-1") are changed, code that would have been using those undocumented event names will need to be updated. This commit also improves observability in a rare use case when "dexie" module is imported multiple times (possibly with different versions of the package) as it also propagates on window/self event target and not just Dexie static.
- Loading branch information
1 parent
b6a1236
commit 0f2c780
Showing
6 changed files
with
73 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,19 @@ | ||
import Events from '../helpers/Events'; | ||
import { GlobalDexieEvents } from '../public/types/db-events'; | ||
|
||
export const globalEvents = Events(null, "txcommitted") as GlobalDexieEvents; | ||
export const DEXIE_STORAGE_MUTATED_EVENT_NAME = 'storagemutated' as 'storagemutated'; | ||
|
||
// Name of the global event fired using DOM dispatchEvent (if not in node). | ||
// Reason for propagating this as a DOM event is for getting reactivity across | ||
// multiple versions of Dexie within the same app (as long as they are | ||
// compatible with regards to the event data). | ||
// If the ObservabilitySet protocol change in a way that would not be backward | ||
// compatible, make sure also update the event name to a new number at the end | ||
// so that two Dexie instances of different versions continue to work together | ||
// - maybe not able to communicate but won't fail due to unexpected data in | ||
// the detail property of the CustomEvent. If so, also make sure to udpate | ||
// docs and explain at which Dexie version the new name and format of the event | ||
// is being used. | ||
export const STORAGE_MUTATED_DOM_EVENT_NAME = 'x-storagemutated-1'; | ||
|
||
export const globalEvents = Events(null, DEXIE_STORAGE_MUTATED_EVENT_NAME) as GlobalDexieEvents; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,39 @@ | ||
import { globalEvents } from '../globals/global-events'; | ||
import { isIEOrEdge } from '../globals/constants'; | ||
import { globalEvents, DEXIE_STORAGE_MUTATED_EVENT_NAME, STORAGE_MUTATED_DOM_EVENT_NAME } from '../globals/global-events'; | ||
import { ObservabilitySet } from "../public/types/db-events"; | ||
import { extendObservabilitySet } from './extend-observability-set'; | ||
|
||
function fireLocally(updateParts: ObservabilitySet) { | ||
if (typeof dispatchEvent !== 'undefined' && typeof addEventListener !== 'undefined') { | ||
globalEvents(DEXIE_STORAGE_MUTATED_EVENT_NAME, updatedParts => { | ||
if (!propagatingLocally) { | ||
let event: CustomEvent<ObservabilitySet>; | ||
if (isIEOrEdge) { | ||
event = document.createEvent('CustomEvent'); | ||
event.initCustomEvent(STORAGE_MUTATED_DOM_EVENT_NAME, true, true, updatedParts); | ||
} else { | ||
event = new CustomEvent(STORAGE_MUTATED_DOM_EVENT_NAME, { | ||
detail: updatedParts | ||
}); | ||
} | ||
propagatingLocally = true; | ||
dispatchEvent(event); | ||
propagatingLocally = false; | ||
} | ||
}); | ||
addEventListener(STORAGE_MUTATED_DOM_EVENT_NAME, ({detail}: CustomEvent<ObservabilitySet>) => { | ||
if (!propagatingLocally) { | ||
propagateLocally(detail); | ||
} | ||
}); | ||
} | ||
|
||
export function propagateLocally(updateParts: ObservabilitySet) { | ||
let wasMe = propagatingLocally; | ||
try { | ||
propagatingLocally = true; | ||
globalEvents.txcommitted.fire(updateParts); | ||
globalEvents.storagemutated.fire(updateParts); | ||
} finally { | ||
propagatingLocally = wasMe; | ||
} | ||
} | ||
|
||
export let propagateLocally = fireLocally; | ||
export let propagatingLocally = false; | ||
let accumulatedParts: ObservabilitySet = {}; | ||
|
||
if (typeof document !== 'undefined' && document.addEventListener) { | ||
// If our tab becomes open, trigger all the collected changes | ||
const fireIfVisible = () => { | ||
// Only trigger the event if our tab is open: | ||
if (document.visibilityState === "visible") { | ||
if (Object.keys(accumulatedParts).length > 0) { | ||
fireLocally(accumulatedParts); | ||
} | ||
accumulatedParts = {}; | ||
} | ||
}; | ||
|
||
document.addEventListener("visibilitychange", fireIfVisible); | ||
|
||
propagateLocally = (changedParts: ObservabilitySet) => { | ||
extendObservabilitySet(accumulatedParts, changedParts); | ||
fireIfVisible(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters