const signals = {
completed: Symbol.for("Completed"),
failed: Symbol.for("Failed"),
error: e => Symbol.for(e)
};
class Stream {
constructor() { }
next() { return signals.completed; }
hasNext() { return false; }
}
class Iterator extends Stream {
constructor(l) {
super();
this.list = l;
this.index = 0;
}
next() {
try {
let ret = this.index < this.list.length ? this.list[this.index] : signals.completed;
this.index += 1;
return ret;
} catch (e) {
return signals.error(e);
}
}
hasNext() {
return this.index < this.list.length;
}
}
class Itoa extends Stream {
constructor(i, val = 0) {
super();
this.val = val;
this.step = i;
}
next() {
let ret = this.val;
this.val += this.step;
return ret;
}
hasNext() {
return true;
}
}
function Transform(f) {
class Wrapper extends Stream {
constructor(stream) {
this.stream = stream;
}
next() {
if (!stream.hasNext()) return signals.completed;
return f(stream.next());
}
hasNext() {
return stream.hasNext();
}
}
return Wrapper;
}
function Filter(f) {
class Wrapper extends Stream {
constructor(stream) {
this.stream = stream;
}
next() {
while (stream.hasNext()) {
let val = stream.next();
if (f(val)) return val;
}
return signals.completed;
}
hasNext() {
return stream.hasNext()
}
}
}