onSnapshot method
Reads the data and set a listener to redo the query on changes, including changes made in other browser tabs.
Implementation
Stream<SdbRecordSnapshot<K, V>?> onSnapshot(SdbDatabase db) {
late StreamController<SdbRecordSnapshot<K, V>?> controller;
StreamSubscription<List<String>>? externalSub;
void addSnapshot() {
get(db).then((snapshot) {
if (!controller.isClosed) {
controller.add(snapshot);
}
});
}
FutureOr<void> onChange(
SdbTransaction transaction,
List<SdbRecordChange<K, V>> changes,
) {
for (var change in changes) {
if (change.ref.key == key) {
addSnapshot();
}
}
}
controller = StreamController<SdbRecordSnapshot<K, V>?>(
onListen: () {
addSnapshot();
store.addOnChangesListener(db, onChange);
// Cross-tab: re-fetch the record when any change in this store arrives
// from another tab. We cannot filter by key at this level.
externalSub = db.impl.externalStoreChanges
.where((storeNames) => storeNames.contains(store.name))
.listen((_) => addSnapshot());
controller.onCancel = () {
externalSub?.cancel();
externalSub = null;
store.removeOnChangesListener(db, onChange);
};
},
);
return controller.stream;
}