StatefulEvt<T>
A StatefulEvt is an Evt stat keep a reference to the last value posted.
You can think of it as way to observe when a value is changed.
.state
.stateProperty type: T
reading the property gives the last event data posted. Setting the property (evt.state = data) is equivalent to calling .post(data).
In v2 evt.state = data will only trigger the call of .post(data) if data !== evt.state
Consult v2 roadmap here
import { Evt } from "evt";
const evtCount = Evt.create(0); // Equivalent wit new StatefulEvt<number>(0)
evtCount.attach(console.log);
console.log(evtCount.state); //Pints "state: 0"
evtIsConnected.post(1); //Pints "1"
console.log(evtCount.state); //Prints "1";
evtCount.state++; //Prints "2"
console.log(evtCount.state); //Pints "2";.evtChange
.evtChangeProperty type: ReadonlyStatefulEvt<T>
The .evtChange property is an Evt that post only when the .state has changed. ( or when post is made via .postForceChange() )
import { Evt } from "evt";
const evtIsConnected = Evt.create(false);
evtIsConnected.attach(console.log);
evtIsConnected.state = false; //Prints nothing .state was already false.
evtIsConnected.state = true; //Prints "true";.evtDiff
.evtDiffProperty type: NonPostableEvt<{prevState:T; newState: T}>
Posted every time the Evt is posted. Used to compare the previous state with the new state.
import { Evt } from "evt";
const evtColor = Evt.create<"BLUE"|"RED"|"WHITE">("BLUE");
evtColor.evtDiff.attach(
({ prevState, newState})=> console.log(`${prevState}=>${newState}`)
);
evtColor.state= "BLUE"; //Prints "BLUE=>BLUE"
evtColor.state= "WHITE"; //Prints "BLUE=>WHITE".evtChangeDiff
.evtChangeDiffProperty type: NonPostableEvt<{prevState:T; newState: T}>
Same than .evtDiff but post only when .evtChang post.
import { Evt } from "evt";
const evtColor = Evt.create<"BLUE"|"RED"|"WHITE">("BLUE");
evtColor.evtChangeDiff.attach(
({ prevState, newState})=> console.log(`${prevState}=>${newState}`)
);
evtColor.state= "BLUE"; //Prints nothing
evtColor.state= "WHITE"; //Prints "BLUE=>WHITE".pipe(...)
.pipe(...)Same as evt.pipe(...) but return a StatefulEvt. Be aware that the current state of the StatefulEvt must be matched by the operator ( if any ) when invoking .pipe(), elst an exception will be thrown.
import { Evt } from "evt";
type Circle = {
color: "WHITE" | "RED";
radius: number;
};
const evtSelectedCircle = Evt.create<Circle>({ "color": "RED", "radius": 3 });
const evtSelectedCricleColor =
evtSelectedCircle.pipe(circle=> [ cicle.color ]);
evtSelectedCircleColor.attach(console.log);Converting an Evt into a StatefulEvt
Evt into a StatefulEvtUse the method method .toStateful(initialState) of Evt. Example:
import { Evt } from "evt";
const evtClickCount= Evt.from(document,"click")
.pipe([(...[,count])=>[count+1],0])
.toStateful(0);
//...user click 3 times on the page
console.log(evtClickCount.state); //Prints "3"You do not need to pass an initialization value to .toStateful(), if you don't the state will be initialized with undefined and the returned StatefulEvt will be of type<T | undefined>. This is usefull when using .toStateful after Evt.merge(). See next example.
Merging multiple StatefulEvts
StatefulEvtsimport { Evt } from "evt";
const evtIsBlue= Evt.create(false);
const evtIsBig= Evt.create(false);
const evtIsBigAndBlue = Evt.merge([
evtIsBlue.evtChange,
evtIsBig.evtChange
])
.toStateful()
.pipe(()=> [ evtIsBlue.state && evtIsBig.state ])
;
console.log(evtIsBigAndBlue.state); // Prints "false"
evtIsBlue.state= true;
console.log(evtIsBigAndBlue.state); // Prints "false"
evtIsBig.state= true;
console.log(evtIsBigAndBlue.state); // Prints "true"****Run the example****
Make a StatefulEvt readonly
StatefulEvt readonlyTo prevent a StatefulEvt to be posted by parts of the code that is not supposed to StatefulEvt can be exposed as StatefulReadonlyEvt.
import { StatefulEvt, StatefulReadonlyEvt } from "evt";
//Return an event that post every second.
function generateEvtTick(delay: number): StatefulReadonlyEvt<number> {
const evtTick= new StatefulEvt(0);
setInterval(()=> evtTick.state++, delay);
retrun evtTick;
}
const evtTick= generateTick(1000);
evtTick.state++; // TS ERROR
evtTick.post(2); // TS ERROR.postFoceChange()
.postFoceChange() /**
* Post and enforce that .evtChange and .evtChangeDiff
* be posted even if the state has not changed.
*
* If no argument is passed the post is performed with the current state.
*
* Returns post count
**/
postForceChange(wData?: readonly [T]): number;.toStateless([ctx])
.toStateless([ctx])Return a stateless copy of the Evt.
import { Evt } from "evt";
const evtText= Evt.create("foo");
//x is Evt<string>
const x= evtText.toStateless();evt.toStateless() is equivalent to Evt.prototype.pipe.call(evt)
Last updated