UNPKG

@connectv/core

Version:

agent-based reactive programming library for typescript/javascript

117 lines 3.69 kB
import isequal from 'lodash.isequal'; import { BehaviorSubject } from 'rxjs'; import { emission } from '../shared/emission'; import group from '../pin/group'; import source from '../pin/source'; import filter from '../pin/filter'; import { Agent } from './agent'; const _Unset = {}; /** * * Represents [state](https://connective.dev/docs/state) agents. * */ export class State extends Agent { /** * * @param initialOrCompare either initial value or equality function * @param compare the equality function, if provided the first parameter must be the initial value. */ constructor(initialOrCompare = _Unset, compare) { super({ inputs: ['value'], outputs: ['value'] }); /** * * The initial value of the agent * */ this.initial = _Unset; if (initialOrCompare == _Unset && !compare) { this.initial = _Unset; this.compare = isequal; } else if (compare) { this.initial = initialOrCompare; this.compare = compare; } else { if (typeof initialOrCompare === 'function') this.compare = initialOrCompare; else { this.initial = initialOrCompare; this.compare = isequal; } } this._subject = new BehaviorSubject(emission(this.initial)); this._injector = source(); } /** * * Shortcut for `.in('value')`, on which the state receives new values. * [Read this](https://connective.dev/docs/state#signature) for more details. * */ get input() { return this.in('value'); } /** * * Shortcut for `.out('value')`, on which the state emits new values. * [Read this](https://connective.dev/docs/state#signature) for more details. * */ get output() { return this.out('value'); } /** * * Allows reading or updating `State`'s value directly. It will be equal * to the latest value emitted by the `State`, and setting it, if the value * has changed truly, will cause the `State` to emit the new value. * */ get value() { return (this._subject.value.value !== _Unset) ? (this._subject.value.value) : undefined; } set value(v) { this._injector.send(v); } /** * * Causes the agent to start receiving values even * without any subscribers. * */ bind() { this.track(this.output.observable.subscribe()); return this; } /** * * @note `State`'s `.clear()` also causes a complete * notification to be sent to observers. * */ clear() { this._subject.complete(); return super.clear(); } createOutput(_) { this.checkOutput(_); return group(this.input, this._injector) .to(filter((v) => !this.compare(v, this.value))) .to(source(this._subject)) .to(filter((v) => v !== _Unset)); } createEntries() { return [this.input]; } createExits() { return [this.output]; } } /** * * Creates a [state](https://connective.dev/docs/state) agent. * State agents can hold state in a reactive flow. * [Checkout the docs](https://connective.dev/docs/state) for examples and further information. * * @param initialOrCompare the initial value or compare function * @param compare the equality function to be used to determine state change, in case initial value is provided * */ export function state(initialOrCompare, compare) { return new State(initialOrCompare, compare); } export default state; //# sourceMappingURL=state.js.map