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));
//*/