onSnapshot method

Stream<SdbRecordSnapshot<K, V>?> onSnapshot(
  1. SdbDatabase db
)

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;
}