move helper enumerators; add build script

This commit is contained in:
Rowan 2025-04-30 23:35:31 -05:00
parent def4351179
commit ab6c644a87
9 changed files with 537 additions and 639 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
dist/
node_modules/

41
build.js Normal file
View file

@ -0,0 +1,41 @@
import * as esbuild from 'esbuild'
import cc from '@apeleghq/esbuild-plugin-closure-compiler'
const closure = cc({ language_in: 'UNSTABLE', compilation_level: 'SIMPLE' })
const cjs = esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
format: 'cjs',
sourcemap: 'linked',
outfile: './dist/index.js',
})
const cjsmin = esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
outfile: './dist/index.min.js',
format: 'cjs',
sourcemap: 'linked',
plugins: [closure]
})
const esm = esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
format: 'esm',
sourcemap: 'linked',
outfile: './dist/index.esm.js'
})
const esmmin = esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
format: 'esm',
sourcemap: 'linked',
outfile: './dist/index.esm.min.js',
plugins: [closure]
})
await Promise.all([cjs, cjsmin, esm, esmmin])

550
dist/index.js vendored
View file

@ -1,550 +0,0 @@
// 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
};

369
package-lock.json generated
View file

@ -9,10 +9,22 @@
"version": "1.0.0",
"license": "ISC",
"devDependencies": {
"@apeleghq/esbuild-plugin-closure-compiler": "^1.0.8",
"esbuild": "^0.25.3",
"folktest": "git+https://git.kitsu.cafe/rowan/folktest.git"
}
},
"node_modules/@apeleghq/esbuild-plugin-closure-compiler": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@apeleghq/esbuild-plugin-closure-compiler/-/esbuild-plugin-closure-compiler-1.0.8.tgz",
"integrity": "sha512-2J1hEXsH5FoQ1thKZW4gQrXvSP9FSNf7a4QoM2VaiuOX9zlP5IqAOHkpS20JOlHLvCp7XBjDlaOVe9YkX0t5fA==",
"dev": true,
"license": "Apache-2.0 WITH LLVM-exception",
"peerDependencies": {
"esbuild": "^0.17.0 || ^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0|| ^0.23.0 || ^0.24.0 || ^0.25.0",
"google-closure-compiler": "*"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.3",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz",
@ -438,6 +450,114 @@
"node": ">=18"
}
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/clone": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.8"
}
},
"node_modules/clone-buffer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
"integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 0.10"
}
},
"node_modules/clone-stats": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
"integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/cloneable-readable": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
"integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"inherits": "^2.0.1",
"process-nextick-args": "^2.0.0",
"readable-stream": "^2.3.5"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/esbuild": {
"version": "0.25.3",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.3.tgz",
@ -481,9 +601,256 @@
},
"node_modules/folktest": {
"version": "1.0.0",
"resolved": "git+https://git.kitsu.cafe/rowan/folktest.git#cbf48ff3b1334eb883f202a77a5bc89d24534520",
"resolved": "git+https://git.kitsu.cafe/rowan/folktest.git#3faea728ab7bb02614e2fb8237ce9c3f7142847e",
"dev": true,
"license": "GPL-3.0-or-later"
},
"node_modules/google-closure-compiler": {
"version": "20240317.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20240317.0.0.tgz",
"integrity": "sha512-PlC5aU2vwsypKbxyFNXOW4psDZfhDoOr2dCwuo8VcgQji+HVIgRi2lviO66x2SfTi0ilm3kI6rq/RSdOMFczcQ==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"chalk": "4.x",
"google-closure-compiler-java": "^20240317.0.0",
"minimist": "1.x",
"vinyl": "2.x",
"vinyl-sourcemaps-apply": "^0.2.0"
},
"bin": {
"google-closure-compiler": "cli.js"
},
"engines": {
"node": ">=10"
},
"optionalDependencies": {
"google-closure-compiler-linux": "^20240317.0.0",
"google-closure-compiler-osx": "^20240317.0.0",
"google-closure-compiler-windows": "^20240317.0.0"
}
},
"node_modules/google-closure-compiler-java": {
"version": "20240317.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-java/-/google-closure-compiler-java-20240317.0.0.tgz",
"integrity": "sha512-oWURPChjcCrVfiQOuVtpSoUJVvtOYo41JGEQ2qtArsTGmk/DpWh40vS6hitwKRM/0YzJX/jYUuyt9ibuXXJKmg==",
"dev": true,
"license": "Apache-2.0",
"peer": true
},
"node_modules/google-closure-compiler-linux": {
"version": "20240317.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-linux/-/google-closure-compiler-linux-20240317.0.0.tgz",
"integrity": "sha512-dYLtcbbJdbbBS0lTy9SzySdVv/aGkpyTekQiW4ADhT/i1p1b4r0wQTKj6kpVVmFvbZ6t9tW/jbXc9EXXNUahZw==",
"cpu": [
"x32",
"x64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"peer": true
},
"node_modules/google-closure-compiler-osx": {
"version": "20240317.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-osx/-/google-closure-compiler-osx-20240317.0.0.tgz",
"integrity": "sha512-0mABwjD4HP11rikFd8JRIb9OgPqn9h3o3wS0otufMfmbwS7zRpnnoJkunifhORl3VoR1gFm6vcTC9YziTEFdOw==",
"cpu": [
"x32",
"x64",
"arm64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"peer": true
},
"node_modules/google-closure-compiler-windows": {
"version": "20240317.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-windows/-/google-closure-compiler-windows-20240317.0.0.tgz",
"integrity": "sha512-fTueVFzNOWURFlXZmrFkAB7yA+jzpA2TeDOYeBEFwVlVGHwi8PV3Q9vCIWlbkE8wLpukKEg5wfRHYrLwVPINCA==",
"cpu": [
"x32",
"x64"
],
"dev": true,
"license": "Apache-2.0",
"optional": true,
"os": [
"win32"
],
"peer": true
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true,
"license": "ISC",
"peer": true
},
"node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true,
"license": "MIT",
"peer": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
"integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
"dev": true,
"license": "ISC",
"peer": true
},
"node_modules/replace-ext": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz",
"integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 0.10"
}
},
"node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
"dev": true,
"license": "BSD-3-Clause",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/vinyl": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz",
"integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"clone": "^2.1.1",
"clone-buffer": "^1.0.0",
"clone-stats": "^1.0.0",
"cloneable-readable": "^1.0.0",
"remove-trailing-separator": "^1.0.1",
"replace-ext": "^1.0.0"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/vinyl-sourcemaps-apply": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
"integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==",
"dev": true,
"license": "ISC",
"peer": true,
"dependencies": {
"source-map": "^0.5.1"
}
}
}
}

View file

@ -4,7 +4,7 @@
"description": "",
"main": "index.js",
"scripts": {
"build": "esbuild src/index.ts --bundle --platform=node --format=esm --outfile=./dist/index.js",
"build": "node build.js",
"test": "./test/index.js"
},
"keywords": [],
@ -12,6 +12,7 @@
"license": "ISC",
"type": "module",
"devDependencies": {
"@apeleghq/esbuild-plugin-closure-compiler": "^1.0.8",
"esbuild": "^0.25.3",
"folktest": "git+https://git.kitsu.cafe/rowan/folktest.git"
}

36
test/unit/common.js Normal file
View file

@ -0,0 +1,36 @@
import { Enumerable } from '../../dist/index.esm.min.js'
export const createIterator = (arr = []) => {
let index = 0
return {
next() {
return index < arr.length ? {
value: arr[index++],
done: false
} : { done: true }
}
}
}
export const createIterable = arr => ({
[Symbol.iterator]() {
return createIterator(arr)
}
})
export const createEnumerator = (arr = []) => {
let index = -1
return {
get current() { return arr[index] },
moveNext() {
index += 1
return index < arr.length
},
reset() {
index = -1
}
}
}
export const createEnumerable = arr => new Enumerable(createEnumerator(arr))

View file

@ -1,27 +1,7 @@
import { it, assert, assertEq, assertErr } from 'folktest'
import { ArrayEnumerator, CachedIteratorEnumerator, DropEnumerator, Enumerable, Enumerator, FilterEnumerator, FlatMapEnumerator, FusedEnumerator, IterableEnumerator, IteratorEnumerator, MapEnumerator, TakeEnumerator } from '../../dist/index.js'
import { createIterator, createIterable, createEnumerator, createEnumerable } from './common.js'
import { ArrayEnumerator, CachedIteratorEnumerator, DropEnumerator, Enumerable, Enumerator, FilterEnumerator, FlatMapEnumerator, FusedEnumerator, IterableEnumerator, IteratorEnumerator, MapEnumerator, TakeEnumerator } from '../../dist/index.esm.min.js'
const createIterator = (arr = []) => {
let index = 0
return {
next() {
return index < arr.length ? {
value: arr[index++],
done: false
} : { done: true }
}
}
}
const createIterable = arr => ({
[Symbol.iterator]() {
return createIterator(arr)
}
})
const createEnumerator = arr => Enumerator.fromIterable(createIterable(arr))
const createEnumerable = arr => Enumerable.from(createIterator(arr))
const helpers = {
concat: {
@ -190,68 +170,3 @@ export const EnumerableMethod = [
})
]
export const EnumerableHelpers = [
it('FusedEnumerator', () => {
const expected = [1, 2, 3, 10, 20, 30]
const e1 = createEnumerator([1, 2, 3])
const e2 = createEnumerator([10, 20, 30])
const fe = new FusedEnumerator([e1, e2])
expected.forEach(n => {
fe.moveNext()
assertEq(fe.current, n)
})
}),
it('DropEnumerator', () => {
const expected = [4, 5, 6]
const e = new DropEnumerator(createEnumerator([1, 2, 3, 4, 5, 6]), 3)
expected.forEach(n => {
e.moveNext()
assertEq(e.current, n)
})
}),
it('FilterEnumerator', () => {
const expected = [1, 3, 5]
const e = new FilterEnumerator(createEnumerator([1, 2, 3, 4, 5, 6]), x => x % 2 !== 0)
expected.forEach(n => {
e.moveNext()
assertEq(e.current, n)
})
}),
it('FlatMapEnumerator', () => {
const expected = [1, 2, 2, 3, 3, 3]
const e = new FlatMapEnumerator(
createEnumerator([1, 2, 3]),
n => {
const arr = Array.from({ length: n }).fill(n)
return createEnumerator(arr)
}
)
expected.forEach(n => {
e.moveNext()
assertEq(e.current, n)
})
}),
it('MapEnumerator', () => {
const expected = [1, 4, 9]
const e = new MapEnumerator(createEnumerator([1, 2, 3]), n => n * n)
expected.forEach(n => {
e.moveNext()
assertEq(e.current, n)
})
}),
it('TakeEnumerator', () => {
const expected = [1, 2, 3]
const e = new TakeEnumerator(createEnumerator([1, 2, 3, 4, 5, 6]), 3)
expected.forEach(n => {
e.moveNext()
assertEq(e.current, n)
})
})
]

86
test/unit/enumerator.js Normal file
View file

@ -0,0 +1,86 @@
import { assert, assertEq, it } from 'folktest'
import { createIterator, createIterable, createEnumerator, createEnumerable } from './common.js'
import { CachedIteratorEnumerator, DropEnumerator, Enumerator, FilterEnumerator, FlatMapEnumerator, FusedEnumerator, IterableEnumerator, IteratorEnumerator, MapEnumerator, TakeEnumerator } from '../../dist/index.esm.min.js'
export const EnumeratorFrom = [
it('from iterator', () => {
const iterator = createIterator()
const enumerator1 = Enumerator.fromIterator(iterator)
assert(enumerator1 instanceof CachedIteratorEnumerator)
const enumerator2 = Enumerator.fromIterator(iterator, false)
assert(enumerator2 instanceof IteratorEnumerator)
}),
it('from iterable', () => {
const iterable = createIterable()
const enumerator = Enumerator.fromIterable(iterable)._enumerator
assert(enumerator instanceof IterableEnumerator, `${enumerator.constructor.name} is not instance of 'IterableEnumerator'`)
})
]
export const HelperEnumerator = [
it('FusedEnumerator', () => {
const expected = [1, 2, 3, 10, 20, 30]
const e1 = createEnumerator([1, 2, 3])
const e2 = createEnumerator([10, 20, 30])
const fe = new FusedEnumerator([e1, e2])
expected.forEach(n => {
fe.moveNext()
assertEq(fe.current, n)
})
}),
it('DropEnumerator', () => {
const expected = [4, 5, 6]
const e = new DropEnumerator(createEnumerator([1, 2, 3, 4, 5, 6]), 3)
expected.forEach(n => {
e.moveNext()
assertEq(e.current, n)
})
}),
it('FilterEnumerator', () => {
const expected = [1, 3, 5]
const e = new FilterEnumerator(createEnumerator([1, 2, 3, 4, 5, 6]), x => x % 2 !== 0)
expected.forEach(n => {
e.moveNext()
assertEq(e.current, n)
})
}),
it('FlatMapEnumerator', () => {
const expected = [1, 2, 2, 3, 3, 3]
const e = new FlatMapEnumerator(
createEnumerator([1, 2, 3]),
n => {
const arr = Array.from({ length: n }).fill(n)
return createEnumerator(arr)
}
)
expected.forEach(n => {
e.moveNext()
assertEq(e.current, n)
})
}),
it('MapEnumerator', () => {
const expected = [1, 4, 9]
const e = new MapEnumerator(createEnumerator([1, 2, 3]), n => n * n)
expected.forEach(n => {
e.moveNext()
assertEq(e.current, n)
})
}),
it('TakeEnumerator', () => {
const expected = [1, 2, 3]
const e = new TakeEnumerator(createEnumerator([1, 2, 3, 4, 5, 6]), 3)
expected.forEach(n => {
e.moveNext()
assertEq(e.current, n)
})
})
]

View file

@ -1,2 +1,3 @@
export * from './enumerable.js'
export * from './enumerator.js'