Computed<T> constructor

Computed<T>(
  1. List<Reactive> _sources,
  2. T _compute(
    1. List<Reactive>
    ), {
  3. List<FluxivityMiddleware<T>>? middlewares,
})

Constructs a new Computed instance.

_sources is a list of Reactive instances whose values are used to compute the new value. _compute is a function that takes the list of Reactive instances and computes the new value. _middlewares is a list of FluxivityMiddleware instances that can be used to add hooks or intercept the update process.

Implementation

Computed(this._sources, this._compute,
    {List<FluxivityMiddleware<T>>? middlewares})
    : _middlewares = middlewares ?? [] {
  _value = _compute(_sources);
  _controller.add(Snapshot(_value, _value));

  _subscription =
      StreamGroup.merge(_sources.map((source) => source.stream)).listen((_) {
    final T newValue;
    try {
      newValue = _compute(_sources);
    } catch (e, st) {
      for (var middleware in _middlewares) {
        middleware.onError(e, st);
      }
      return;
    }
    final oldValue = _value;
    if (newValue != _value) {
      for (var middleware in _middlewares) {
        middleware.beforeUpdate(oldValue, newValue);
      }
      _value = newValue;
      for (var middleware in _middlewares) {
        middleware.afterUpdate(oldValue, newValue);
      }
      bool shouldPublish = _middlewares
          .map((e) => e.shouldEmit(oldValue, newValue))
          .fold(true, (value, element) => value && element);

      if (shouldPublish) {
        Snapshot<T> snapshot = Snapshot(oldValue, newValue);
        if (_isBatchUpdate) {
          _bufferedEvents.add(snapshot);
        } else {
          _controller.add(snapshot);
        }
      }
    }
  });
}