Observability broadcasted between tabs and workers
This version broadcasts txcommitted events between tabs and workers within same origin. It does so using BroadcastChannel so that not only tabs/windows are involved but also workers. This makes the built-in observability in Dexie a nice replacement for dexie-observable addon - and better, as that addon doesnt support workers, you will probably not need the dexie-observable addon anymore unless you use it as a base for dexie-syncable. Note also that dexie-observable slows down write performance a lot while the new built-in liveQuery feature does not.
Any part of an origin (a tab, a frame, a window, a web worker, shared worker or service worker) can observe the database no matter where the database was modified. Any thread can be either producer or consumer. If one peer writes to a Dexie instance, the other part can subscribe and get notified when something change.
Sparing DOM resources
Hidden tabs and minimized windows are not being bothered. Instead they get notified when they are visible again - with an accumulated result so nothing that had happened while being asleep will get lost.
Fallback to storage-event
The implementation falls back to using storage event and localStorage if browser doesnt support BroadcastChannel (Safari). The fallback implementation does only propagate changes across windows/tabs - not workers. It would however possible to make a standalone polyfill for BroadcastChannel that would support this for workers also. I currently don't know of any such polyfill except broadcastchannel-polyfill that currently not supports workers either. If I will have time I may complement it to support all kinds of workers as well as the structuring cloning.
Example
Worker
importScripts("https://unpkg.com/dexie@3.1.0-alpha.4");
const db = new Dexie('mydb');
db.version(1).stores({
logItems: '++id'
});
// Write to DB now and then...
setInterval (()=>{
db.logItems.add({foo: "bar", time: new Date()});
}, 1000);
Browser
import React from "react";
import Dexie from "dexie";
import { useLiveQuery } from "dexie-react-hooks";
const db = new Dexie('mydb');
db.version(1).stores({
logItems: '++id'
});
function LogWatcherComponent({limit = 50}) {
// Observe the last {limit} items in log:
const logItems = useLiveQuery(
() => db.logItems.reverse().limit(limit).toArray()
);
return <div>
<h1>Log viewer</h1>
<ul>
{logItems.map(logItem => <li key={logItem.id}>
{logItem.time.toLocaleTimeString()} {logItem.foo}
</li>)}
</ul>
</div>;
}
Read more?
Awesome React integration coming (Blog post)