RxJS Signal cycle
Test of "Signal" implementation tested with a cycle.
by Santiago J
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.lite.min.js"></script>
<h4>A = B + 1</h4>
<input id="a">
<h4>B = A + 1</h4>
<input id="b">
JavaScript
class Value {
constructor(value, valid) {
this.value = value;
this.valid = valid;
}
map(f) {
if (this.valid) return Value.Valid(f(this.value));
else return Value.Invalid();
}
toString() {
if (this.valid) return 'Valid ' + this.value;
else return 'Invalid';
}
isValid() { return this.valid; }
isInvalid() { return !this.valid; }
static Valid(val) {
return new Value(val, true);
}
static Invalid() {
return new Value(null, false);
}
}
class Signal extends Rx.BehaviorSubject {
constructor() {
super(Value.Invalid());
}
isValid() {
return this.getValue().isValid();
}
setValue(val) {
this.onNext(Value.Invalid());
this.onNext(val);
}
set(val) {
this.setValue(Value.Valid(val));
}
}
Signal.Value = Value;
var observableProto = Rx.Observable.prototype;
observableProto.subscribeSignal = function(signal) {
return this
.filter(v => v.isValid() !== signal.isValid())
.subscribe(signal);
};
observableProto.mapSignal = function(f) {
return this.map(val => val.map(f));
};
// -------------------------------------------------
//*
var a = document.querySelector('#a');
var b = document.querySelector('#b');
var aSignal = new Signal();
var bSignal = new Signal();
bSignal.mapSignal(x => x + 1).subscribeSignal(aSignal);
aSignal.mapSignal(x => x + 1).subscribeSignal(bSignal);
aSignal.subscribe(value => { a.value = value.value; });
bSignal.subscribe(value => { b.value = value.value; });
Rx.Observable.fromEvent(a, 'input').subscribe(e => e.target.value && aSignal.set(+e.target.value));
Rx.Observable.fromEvent(b, 'input').subscribe(e => e.target.value && bSignal.set(+e.target.value));
//*/