rsocket-rpc-core
Version:
RSocket JavaScript RPC Core
181 lines (153 loc) • 4.16 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var MAX_REQUEST_N = 0x7fffffff; // uint31
var QueuingFlowableProcessor = function () {
function QueuingFlowableProcessor(capacity) {
_classCallCheck(this, QueuingFlowableProcessor);
this._once = false;
this._requested = 0;
this._actual = null;
this._error = null;
this._done = false;
this._wip = 0;
this._cancelled = false;
this._capacity = capacity;
this._queue = [];
this._transformers = [];
}
QueuingFlowableProcessor.prototype.subscribe = function subscribe(s) {
if (!this._once) {
this._once = true;
this._actual = s;
s.onSubscribe(this);
} else {
throw new Error('Only one Subscriber allowed');
}
};
QueuingFlowableProcessor.prototype.onSubscribe = function onSubscribe(s) {
if (this._done) {
s.cancel();
} else {
s.request(this._capacity || MAX_REQUEST_N);
}
};
QueuingFlowableProcessor.prototype.onNext = function onNext(t) {
if (t === null) {
throw new Error('t is null');
}
if (!this._capacity || this._queue.length < this._capacity) {
this._queue.push(t);
}
this.drain();
};
QueuingFlowableProcessor.prototype.onError = function onError(t) {
if (t === null) {
throw new Error('t is null');
}
this._error = t;
this._done = true;
this.drain();
};
QueuingFlowableProcessor.prototype.onComplete = function onComplete() {
this._done = true;
this.drain();
};
QueuingFlowableProcessor.prototype.request = function request(n) {
if (n > 0) {
this._requested += n;
this.drain();
} else {
throw new Error('Invalid N for request, must be > 0: ' + n);
}
};
QueuingFlowableProcessor.prototype.cancel = function cancel() {
this._cancelled = true;
if (this._wip++ === 0) {
this._actual = null;
this._queue = [];
}
};
QueuingFlowableProcessor.prototype.map = function map(transformer) {
this._transformers.push(transformer);
return this;
};
QueuingFlowableProcessor.prototype.drain = function drain() {
if (this._actual == null) {
return;
}
if (this._wip++ !== 0) {
return;
}
var missed = 1;
for (;;) {
var r = this._requested;
var e = 0;
while (e !== r) {
if (this._cancelled) {
this._actual = null;
this._queue = [];
return;
}
var d = this._done;
var v = this._queue.shift();
var empty = v == null;
if (d && empty) {
if (this._actual != null) {
var ex = this._error;
if (ex != null) {
this._actual.onError(ex);
} else {
this._actual.onComplete();
}
this._actual = null;
}
return;
}
if (empty) {
break;
}
if (this._actual != null) {
var transformedV = this._transformers.reduce(function (interim, xform) {
return xform(interim);
}, v);
this._actual.onNext(transformedV);
}
e++;
}
if (e == r) {
if (this._cancelled) {
this._actual = null;
this._queue = [];
return;
}
var _d = this._done;
var _empty = this._queue.length === 0;
if (_d && _empty) {
if (this._actual != null) {
var _ex = this._error;
if (_ex != null) {
this._actual.onError(_ex);
} else {
this._actual.onComplete();
}
this._actual = null;
}
return;
}
}
if (e != 0) {
this._requested -= e;
}
var m = this._wip - missed;
this._wip = m;
if (m == 0) {
break;
}
}
};
return QueuingFlowableProcessor;
}();
exports.default = QueuingFlowableProcessor;