@tempest/flatten
Version:
flatten operator for tempest
98 lines • 2.63 kB
JavaScript
import { Stream } from '@tempest/core';
export function flatten(stream) {
return new Stream(new Flatten(stream.source));
}
const emptyDisposable = { dispose: () => { return void 0; } };
export class Flatten {
constructor(source) {
this.source = source;
}
run(sink, scheduler) {
const flattenSink = new FlattenSink(sink, scheduler);
const disposable = this.source.run(flattenSink, scheduler);
return {
dispose() {
flattenSink.dispose();
disposable.dispose();
}
};
}
}
class FlattenSink {
constructor(sink, scheduler) {
this.sink = sink;
this.scheduler = scheduler;
this.current = null;
this.ended = false;
}
event(time, value) {
this._disposeCurrent(time);
this.current = new Segment(time, Infinity, this, this.sink);
this.current.disposable = value.source.run(this.current, this.scheduler);
}
error(time, err) {
this.ended = true;
this.sink.error(time, err);
}
end(time) {
this.ended = true;
this._checkEnd(time, void 0);
}
dispose() {
return this._disposeCurrent(0);
}
_disposeCurrent(time) {
if (this.current !== null) {
return this.current._dispose(time);
}
}
_disposeInner(time, inner) {
inner._dispose(time);
if (inner === this.current) {
this.current = null;
}
}
_checkEnd(time, value) {
if (this.ended && this.current === null) {
this.sink.end(time, value);
}
}
_endInner(time, value, inner) {
this._disposeInner(time, inner);
this._checkEnd(time, value);
}
_errorInner(time, err, inner) {
this._disposeInner(time, inner);
this.sink.error(time, err);
}
}
class Segment {
constructor(min, max, outer, sink) {
this.min = min;
this.max = max;
this.outer = outer;
this.sink = sink;
this.disposable = emptyDisposable;
}
event(time, value) {
if (time < this.max) {
this.sink.event(Math.max(time, this.min), value);
}
}
error(time, err) {
this.outer._errorInner(Math.max(time, this.min), err, this);
}
end(time, value) {
this.outer._endInner(Math.max(time, this.min), value, this);
}
_dispose(time) {
this.max = time;
try {
this.disposable.dispose();
}
catch (e) {
this.sink.error(time, e);
}
}
}
//# sourceMappingURL=index.js.map