550 lines
12 KiB
JavaScript
550 lines
12 KiB
JavaScript
// src/index.ts
|
|
var DoneIteratorResult = Object.freeze({ value: void 0, done: true });
|
|
function hasMethods(methods, obj) {
|
|
return methods.every((method) => typeof obj[method] === "function");
|
|
}
|
|
function isIterable(value) {
|
|
return typeof value[Symbol.iterator] === "function";
|
|
}
|
|
function isIterator(value) {
|
|
return typeof value.next === "function";
|
|
}
|
|
function isBuffer(value) {
|
|
return ArrayBuffer.isView(value);
|
|
}
|
|
function isArrayLike(value) {
|
|
return Array.isArray(value) || value instanceof Array;
|
|
}
|
|
var IteratorEnumerator = class _IteratorEnumerator {
|
|
_iterator;
|
|
_consumed = false;
|
|
_current;
|
|
get current() {
|
|
return this._current;
|
|
}
|
|
constructor(iterator) {
|
|
this._iterator = iterator;
|
|
}
|
|
static from(iterator) {
|
|
return new _IteratorEnumerator(iterator);
|
|
}
|
|
moveNext() {
|
|
if (!this._consumed) {
|
|
const { value, done } = this._iterator.next();
|
|
this._current = value;
|
|
if (done) {
|
|
this._consumed = true;
|
|
}
|
|
return !done;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
reset() {
|
|
}
|
|
toIterator() {
|
|
return this;
|
|
}
|
|
next(...[_value]) {
|
|
const done = this.moveNext();
|
|
return { value: this.current, done };
|
|
}
|
|
return(value) {
|
|
return this._iterator.return?.(value) ?? DoneIteratorResult;
|
|
}
|
|
throw(e) {
|
|
return this._iterator.throw?.(e) ?? DoneIteratorResult;
|
|
}
|
|
};
|
|
var CachedIteratorEnumerator = class _CachedIteratorEnumerator {
|
|
_iterator;
|
|
_cache = [];
|
|
_index = -1;
|
|
get current() {
|
|
return this._cache[this._index];
|
|
}
|
|
constructor(iterator) {
|
|
this._iterator = new IteratorEnumerator(iterator);
|
|
}
|
|
static from(iterator) {
|
|
return new _CachedIteratorEnumerator(iterator);
|
|
}
|
|
moveNext() {
|
|
this._index += 1;
|
|
if (this._cache.length > this._index) {
|
|
return true;
|
|
} else if (this._iterator.moveNext()) {
|
|
this._cache.push(this._iterator.current);
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
reset() {
|
|
this._index = -1;
|
|
}
|
|
toIterator() {
|
|
return this;
|
|
}
|
|
next(...[_value]) {
|
|
const done = this.moveNext();
|
|
return { value: this.current, done };
|
|
}
|
|
return(value) {
|
|
return this._iterator.return(value);
|
|
}
|
|
throw(e) {
|
|
return this._iterator.throw(e);
|
|
}
|
|
};
|
|
var IterableEnumerator = class {
|
|
_iterable;
|
|
_factory;
|
|
_enumerator;
|
|
get current() {
|
|
return this._enumerator?.current;
|
|
}
|
|
constructor(iterable, factory = IteratorEnumerator.from) {
|
|
this._iterable = iterable;
|
|
this._factory = factory;
|
|
this._enumerator = this._createEnumerator();
|
|
}
|
|
static fromIterable(iterable, factory) {
|
|
return new this(iterable, factory);
|
|
}
|
|
moveNext() {
|
|
return this._enumerator?.moveNext() ?? false;
|
|
}
|
|
_createIterator() {
|
|
return this._iterable[Symbol.iterator]();
|
|
}
|
|
_createEnumerator() {
|
|
return this._factory(this._createIterator());
|
|
}
|
|
reset() {
|
|
this._enumerator = this._createEnumerator();
|
|
}
|
|
toIterator() {
|
|
return this._createIterator();
|
|
}
|
|
next(...[_value]) {
|
|
const done = !this.moveNext();
|
|
return { value: this.current, done };
|
|
}
|
|
return(value) {
|
|
if (isIterator(this._enumerator)) {
|
|
return this._enumerator?.return?.(value) || DoneIteratorResult;
|
|
} else {
|
|
return DoneIteratorResult;
|
|
}
|
|
}
|
|
throw(e) {
|
|
if (isIterator(this._enumerator)) {
|
|
return this._enumerator?.throw?.(e) || DoneIteratorResult;
|
|
} else {
|
|
return DoneIteratorResult;
|
|
}
|
|
}
|
|
};
|
|
function toArrayLikeBuffer(buffer) {
|
|
return Object.defineProperty(buffer, "length", {
|
|
get: function() {
|
|
return buffer.byteLength;
|
|
}
|
|
});
|
|
}
|
|
var ArrayEnumerator = class _ArrayEnumerator {
|
|
_array;
|
|
_index = -1;
|
|
get current() {
|
|
return this._array[this._index];
|
|
}
|
|
constructor(array) {
|
|
this._array = array;
|
|
}
|
|
static from(array) {
|
|
if (ArrayBuffer.isView(array)) {
|
|
return new _ArrayEnumerator(toArrayLikeBuffer(array));
|
|
} else {
|
|
return new _ArrayEnumerator(array);
|
|
}
|
|
}
|
|
[Symbol.iterator]() {
|
|
return this._array[Symbol.iterator]();
|
|
}
|
|
setIndex(index) {
|
|
this._index = index;
|
|
}
|
|
moveNext() {
|
|
this._index += 1;
|
|
return this._index < this._array.length;
|
|
}
|
|
reset() {
|
|
this._index = -1;
|
|
}
|
|
toIterator() {
|
|
return this._array[Symbol.iterator]();
|
|
}
|
|
next(...[_value]) {
|
|
const done = this.moveNext();
|
|
return { value: this.current, done };
|
|
}
|
|
return(_value) {
|
|
return DoneIteratorResult;
|
|
}
|
|
throw(_e) {
|
|
return DoneIteratorResult;
|
|
}
|
|
};
|
|
var Enumerator = class _Enumerator {
|
|
_enumerator;
|
|
_index = 0;
|
|
get current() {
|
|
return this._enumerator.current;
|
|
}
|
|
constructor(enumerator) {
|
|
this._enumerator = enumerator;
|
|
}
|
|
static fromIterable(iterable) {
|
|
if (isArrayLike(iterable) || ArrayBuffer.isView(iterable)) {
|
|
return ArrayEnumerator.from(iterable);
|
|
} else {
|
|
return new this(new IterableEnumerator(iterable));
|
|
}
|
|
}
|
|
static fromIterator(iterator, cache = true) {
|
|
if (cache) {
|
|
return new CachedIteratorEnumerator(iterator);
|
|
} else {
|
|
return new IteratorEnumerator(iterator);
|
|
}
|
|
}
|
|
static toIterator(enumerator) {
|
|
return new this(enumerator);
|
|
}
|
|
[Symbol.iterator]() {
|
|
return this.toIterator();
|
|
}
|
|
toIterator() {
|
|
return _Enumerator.toIterator(this);
|
|
}
|
|
moveNext() {
|
|
this._index += 1;
|
|
return this._enumerator.moveNext();
|
|
}
|
|
reset() {
|
|
this._enumerator.reset();
|
|
}
|
|
next(...[_value]) {
|
|
const done = this.moveNext();
|
|
return { value: this.current, done };
|
|
}
|
|
return(_value) {
|
|
return DoneIteratorResult;
|
|
}
|
|
throw(_e) {
|
|
return DoneIteratorResult;
|
|
}
|
|
};
|
|
var HelperEnumerator = class _HelperEnumerator {
|
|
_enumerator;
|
|
_index = 0;
|
|
get current() {
|
|
return this._enumerator.current;
|
|
}
|
|
constructor(enumerator) {
|
|
this._enumerator = enumerator;
|
|
}
|
|
static toIterator(enumerator) {
|
|
return new this(enumerator);
|
|
}
|
|
[Symbol.iterator]() {
|
|
return this.toIterator();
|
|
}
|
|
toIterator() {
|
|
return _HelperEnumerator.toIterator(this);
|
|
}
|
|
moveNext() {
|
|
this._index += 1;
|
|
return this._enumerator.moveNext();
|
|
}
|
|
reset() {
|
|
this._enumerator.reset();
|
|
}
|
|
next(...[_value]) {
|
|
const done = this.moveNext();
|
|
return { value: this.current, done };
|
|
}
|
|
return(_value) {
|
|
return DoneIteratorResult;
|
|
}
|
|
throw(_e) {
|
|
return DoneIteratorResult;
|
|
}
|
|
};
|
|
var DropEnumerator = class extends HelperEnumerator {
|
|
_limit;
|
|
constructor(enumerator, limit) {
|
|
super(enumerator);
|
|
this._limit = limit;
|
|
}
|
|
moveNext() {
|
|
let next = super.moveNext();
|
|
while (this._limit > 0 && next) {
|
|
next = super.moveNext();
|
|
this._limit -= 1;
|
|
}
|
|
return next;
|
|
}
|
|
};
|
|
var FilterEnumerator = class extends HelperEnumerator {
|
|
_filter;
|
|
constructor(enumerator, filter) {
|
|
super(enumerator);
|
|
this._filter = filter;
|
|
}
|
|
moveNext() {
|
|
let next = super.moveNext();
|
|
while (next && !this._filter(this.current, this._index)) {
|
|
next = super.moveNext();
|
|
}
|
|
return next;
|
|
}
|
|
};
|
|
var FlatMapEnumerator = class {
|
|
_enumerator;
|
|
_flatMap;
|
|
_inner;
|
|
_index = -1;
|
|
constructor(enumerator, flatMap) {
|
|
this._enumerator = enumerator;
|
|
this._flatMap = flatMap;
|
|
}
|
|
get current() {
|
|
return this._inner?.current;
|
|
}
|
|
moveNext() {
|
|
if (this._inner && this._inner.moveNext()) {
|
|
return true;
|
|
}
|
|
const next = this._enumerator.moveNext();
|
|
if (!next) {
|
|
return false;
|
|
}
|
|
this._index += 1;
|
|
this._inner = this._flatMap(this._enumerator.current, this._index);
|
|
return this._inner.moveNext();
|
|
}
|
|
reset() {
|
|
this._index = -1;
|
|
this._inner = void 0;
|
|
this._enumerator.reset();
|
|
}
|
|
toIterator() {
|
|
return HelperEnumerator.toIterator(this);
|
|
}
|
|
};
|
|
var MapEnumerator = class {
|
|
_enumerator;
|
|
_map;
|
|
_current;
|
|
_index = -1;
|
|
get current() {
|
|
return this._current;
|
|
}
|
|
constructor(enumerator, map) {
|
|
this._enumerator = enumerator;
|
|
this._map = map;
|
|
}
|
|
toIterator() {
|
|
return HelperEnumerator.toIterator(this);
|
|
}
|
|
moveNext() {
|
|
this._index += 1;
|
|
const next = this._enumerator.moveNext();
|
|
if (next) {
|
|
this._current = this._map(this._enumerator.current, this._index);
|
|
}
|
|
return next;
|
|
}
|
|
reset() {
|
|
this._index = -1;
|
|
this._enumerator.reset();
|
|
}
|
|
};
|
|
var TakeEnumerator = class extends HelperEnumerator {
|
|
_limit;
|
|
constructor(enumerator, limit) {
|
|
super(enumerator);
|
|
this._limit = limit;
|
|
}
|
|
moveNext() {
|
|
if (this._limit < 0) {
|
|
return false;
|
|
} else {
|
|
super.moveNext();
|
|
this._limit -= 1;
|
|
return true;
|
|
}
|
|
}
|
|
};
|
|
var FusedEnumerator = class {
|
|
_enumerators;
|
|
_index = 0;
|
|
get current() {
|
|
return this._cur()?.current;
|
|
}
|
|
constructor(enumerators) {
|
|
this._enumerators = enumerators;
|
|
}
|
|
_cur() {
|
|
return this._enumerators[this._index];
|
|
}
|
|
_done() {
|
|
return this._index >= this._enumerators.length;
|
|
}
|
|
toIterator() {
|
|
return HelperEnumerator.toIterator(this);
|
|
}
|
|
moveNext() {
|
|
while (!this._done() && !this._cur().moveNext()) {
|
|
this._index += 1;
|
|
}
|
|
return this._done();
|
|
}
|
|
reset() {
|
|
const len = this._enumerators.length;
|
|
for (let i = 0; i < len; i++) {
|
|
this._enumerators[i].reset();
|
|
}
|
|
this._index = 0;
|
|
}
|
|
};
|
|
var Enumerable = class _Enumerable {
|
|
_enumerator;
|
|
constructor(enumerator) {
|
|
this._enumerator = enumerator;
|
|
}
|
|
static from(value) {
|
|
if (this.isEnumerable(value)) {
|
|
return value;
|
|
} else if (this.isEnumerator(value)) {
|
|
return new _Enumerable(value);
|
|
} else if (isIterable(value)) {
|
|
const enumerator = Enumerator.fromIterable(value);
|
|
if (isArrayLike(value)) {
|
|
return new ArrayEnumerble(enumerator);
|
|
} else {
|
|
return new _Enumerable(enumerator);
|
|
}
|
|
} else if (isIterator(value)) {
|
|
return new _Enumerable(
|
|
Enumerator.fromIterator(value)
|
|
);
|
|
} else {
|
|
throw new TypeError("value is not enumerable");
|
|
}
|
|
}
|
|
static isEnumerable(value) {
|
|
return typeof value["enumerator"] === "function";
|
|
}
|
|
static isEnumerator(value) {
|
|
return hasMethods(["moveNext", "reset", "toIterator"], value);
|
|
}
|
|
[Symbol.iterator]() {
|
|
return this._enumerator.toIterator();
|
|
}
|
|
at(index) {
|
|
while (index >= 0 && this._enumerator.moveNext()) {
|
|
index -= 1;
|
|
}
|
|
const value = this._enumerator.current;
|
|
this._enumerator.reset();
|
|
return value;
|
|
}
|
|
atOrDefault(index, defaultValue) {
|
|
const value = this.at(index);
|
|
return value || defaultValue;
|
|
}
|
|
atOrElse(index, defaultValue) {
|
|
const value = this.at(index);
|
|
return value || defaultValue();
|
|
}
|
|
concat(other) {
|
|
return new _Enumerable(
|
|
new FusedEnumerator([this._enumerator, other.enumerator()])
|
|
);
|
|
}
|
|
drop(limit) {
|
|
return new _Enumerable(new DropEnumerator(this._enumerator, limit));
|
|
}
|
|
enumerator() {
|
|
return this._enumerator;
|
|
}
|
|
//entries(): IEnumerator<T> {
|
|
//}
|
|
every(predicate) {
|
|
let index = 0;
|
|
while (this._enumerator.moveNext()) {
|
|
if (!predicate(this._enumerator.current, index)) {
|
|
return false;
|
|
}
|
|
index += 1;
|
|
}
|
|
this._enumerator.reset();
|
|
return true;
|
|
}
|
|
filter(predicate) {
|
|
return new _Enumerable(new FilterEnumerator(this._enumerator, predicate));
|
|
}
|
|
flatMap(fn) {
|
|
return new _Enumerable(new FlatMapEnumerator(this._enumerator, fn));
|
|
}
|
|
map(fn) {
|
|
return new _Enumerable(new MapEnumerator(this._enumerator, fn));
|
|
}
|
|
some(predicate) {
|
|
let index = 0;
|
|
while (this._enumerator.moveNext()) {
|
|
if (predicate(this._enumerator.current, index)) {
|
|
return true;
|
|
}
|
|
index += 1;
|
|
}
|
|
this._enumerator.reset();
|
|
return false;
|
|
}
|
|
take(limit) {
|
|
return new _Enumerable(new TakeEnumerator(this._enumerator, limit));
|
|
}
|
|
};
|
|
var ArrayEnumerble = class extends Enumerable {
|
|
at(index) {
|
|
if (this._enumerator instanceof ArrayEnumerator) {
|
|
this._enumerator.setIndex(index);
|
|
return this._enumerator.current;
|
|
} else {
|
|
return super.at(index);
|
|
}
|
|
}
|
|
};
|
|
export {
|
|
ArrayEnumerator,
|
|
ArrayEnumerble,
|
|
CachedIteratorEnumerator,
|
|
DropEnumerator,
|
|
Enumerable,
|
|
Enumerator,
|
|
FilterEnumerator,
|
|
FlatMapEnumerator,
|
|
FusedEnumerator,
|
|
HelperEnumerator,
|
|
IterableEnumerator,
|
|
IteratorEnumerator,
|
|
MapEnumerator,
|
|
TakeEnumerator,
|
|
isArrayLike,
|
|
isBuffer,
|
|
isIterable,
|
|
isIterator
|
|
};
|