@connectv/core
Version:
agent-based reactive programming library for typescript/javascript
117 lines • 3.69 kB
JavaScript
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