Skip to content

Commit

Permalink
Version 3.0.0
Browse files Browse the repository at this point in the history
Improves typing & spec compliance
fixes: [Bug] Typing issue causes AsyncIterator.from(...) to fail against plain ES iterator-like things #21
fixes: [Bug] counter/index argument is not provided to callback functions #22
  • Loading branch information
MadProbe committed Apr 14, 2024
1 parent f262d3d commit 7c25ac2
Show file tree
Hide file tree
Showing 57 changed files with 1,609 additions and 1,394 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,11 @@ Example:
// inclusive
Iterator.range(1, 3, 1, true).toArray(); // [1, 2, 3]
// exclusive
Iterator.range(1, 3, 1, true).toArray(); // [1, 2]
Iterator.range(1, 3, 1).toArray(); // [1, 2]
// inclusive reverse
Iterator.range(-1, -3, -1, true).toArray(); // [-1, -2, -3]
// exclusive
Iterator.range(-1, -3, -1, true).toArray(); // [-1, -2]
Iterator.range(-1, -3, -1).toArray(); // [-1, -2]
// edge cases
Iterator.range(1, 1, 0, false).toArray(); // []
Iterator.range(0, 1, 0, true).toArray(); // []
Expand All @@ -185,7 +185,6 @@ Iterator.range(0, 0, 0, true).take(2).toArray(); // [0, 0], .range() itetates in
* It takes globalThis by a polyfill written by Mathias Bynens from [his awensome article](https://mathiasbynens.be/notes/globalthis) (Lingers on fact that `__0x_6642_5d0e_72c2_4e09` preperty is writable and extensible in Object.prototype and Object.defineProperty isn't changed before the script is run).
* UMD bundle is exposed into global as `__IteratorHelpersPolyfill`.
* All bundles are **minified**.
* Typings mutate `AsyncIterator` interface so its `T` type variable is optional and defaults to `unknown` (just to be consistent with `Iterator` interface).
* Additional helpers can be removed by the `config` variable from exports.
* This polyfill's size is less than 5 kb (4.62 kb atm) when compressed by Brotli compression algorithm.
* Typings are made to accurately reflect behaviour of methods as much as possible.
Expand Down
224 changes: 112 additions & 112 deletions declarations/index.d.ts

Large diffs are not rendered by default.

2,429 changes: 1,330 additions & 1,099 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"author": "MadProbe#7435",
"name": "iterator-helpers-polyfill",
"description": "A polyfill for Iterator helpers proposal",
"version": "2.3.3",
"version": "3.0.0",
"license": "MIT",
"type": "module",
"main": "./build/bundle.min.js",
Expand Down Expand Up @@ -60,9 +60,9 @@
"@typescript-eslint/eslint-plugin": "^6.8.0",
"eslint": "^8.51.0",
"eslint-plugin-import": "^2.28.1",
"rollup": "^4.1.4",
"rollup": "^4.14.2",
"rollup-plugin-copy": "^3.5.0",
"rollup-plugin-typescript2": "^0.36.0",
"typescript": "^5.2.2"
"typescript": "^5.4.5"
}
}
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import * as async_methods from "@async/all.js";
import * as sync_methods from "@sync/all.js";
import * as additional_async from "@async/additionals/all.js";
import * as additional_sync from "@sync/additionals/all.js";
import * as additional_async_statics from "@async/statics/additionals/all.js";
import * as async_statics from "@async/statics/all.js";
import * as additional_sync_statics from "@sync/statics/additionals/all.js";
import * as sync_statics from "@sync/statics/all.js";
import * as additional_async_statics from "@async/statics/additionals/all.js";
import * as additional_sync_statics from "@sync/statics/additionals/all.js";


type Methods = Record<string, AnyFunction>;
Expand Down
1 change: 1 addition & 0 deletions src/methods/async/additionals/all.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { default as symmetricDifference } from "./symmetricDifference.js";
export { default as asIndexedPairs } from "../indexed.js";
export { default as uniqueJustseen } from "./uniqueJustseen.js";
export { default as groupByToMap } from "./groupByToMap.js";
export { default as intersection } from "./intersection.js";
Expand Down
6 changes: 3 additions & 3 deletions src/methods/async/additionals/cycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { assertIterator, assertReplace, isPositiveInteger, mimic } from "@utils/

export default mimic(0, "cycle", assertReplace((x = 1 / 0) => isPositiveInteger(x), assertIterator(
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], times: number) {
var results: unknown[] = [], length = 0, done: boolean | void, value: unknown, lastValue: unknown, index: number;
var results: unknown[] = [], length = 0, done: boolean | void, value: unknown, index: number;

while ({ done, value } = await _next(lastValue), !done) {
lastValue = yield results[length++] = value;
while ({ done, value } = await _next(), !done) {
yield results[length++] = value;
}

while (times--) {
Expand Down
8 changes: 4 additions & 4 deletions src/methods/async/additionals/dropWhile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { assert, assertIterator, closeAsyncIterator, isFunction, mimic } from "@


export default mimic(undefined, "dropWhile", assert(isFunction, O => O + " is not a function", assertIterator(
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown) => Promise<boolean>) {
var lastValue: unknown, done: boolean | undefined, value: unknown;
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown, index: number) => Promise<boolean>) {
var done: boolean | undefined, value: unknown, index = 0;

while ({ done, value } = await _next(), !done) try {
if (!await fn(value)) break;
if (!await fn(value, index++)) break;
} catch (error) {
await closeAsyncIterator(this);
throw error;
}

while ({ done, value } = await _next(lastValue), !done) lastValue = yield value;
while ({ done, value } = await _next(), !done) yield value;
}
)));
10 changes: 5 additions & 5 deletions src/methods/async/additionals/each.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { assert, assertIterator, closeAsyncIterator, isFunction, mimic } from "@


export default mimic(undefined, "each", assert(isFunction, O => `${ O } is not a function`, assertIterator(
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown) => Promise<unknown>) {
var done: boolean | undefined, value: unknown, lastValue: unknown;
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown, index: number) => Promise<unknown>) {
var done: boolean | undefined, value: unknown, index = 0;

while ({ done, value } = await _next(lastValue), !done) try {
await fn(value);
lastValue = yield value;
while ({ done, value } = await _next(), !done) try {
await fn(value, index++);
yield value;
} catch (error) {
await closeAsyncIterator(this);
throw error;
Expand Down
6 changes: 3 additions & 3 deletions src/methods/async/additionals/filterMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { SameValueZero } from "tslib";


export default mimic(1, "filterMap", assert(isFunction, O => `${ O } is not a function`, assertIterator(
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<Iterator, never, unknown>["next"], fn: (...args: readonly unknown[]) => Promise<unknown>, ignoreValue?: unknown) {
var done: boolean | undefined, value: Iterator;
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, never, unknown>["next"], fn: (...args: readonly unknown[]) => Promise<unknown>, ignoreValue?: unknown) {
var done: boolean | undefined, value: unknown, index = 0;

while ({ done, value } = await _next(), !done) try {
const val = await fn(...value);
const val = await fn(value, index++);

if (SameValueZero(val, ignoreValue)) {
yield val;
Expand Down
2 changes: 1 addition & 1 deletion src/methods/async/additionals/flatten.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default mimic(0, "flatten", assertReplace((x = 1) => isPositiveInteger(x)

while ({ done, value } = await _next(), !done) {
if (depth > 0 && (typeof value !== "string" || !keepStringsAsIs && value.length > 1)) {
yield* call(recurse, iterator = from(value as AsyncIterator), (next = iterator.next, ((...args: readonly unknown[]) => apply<typeof _next>(next, iterator, args))), depth - 1);
yield* call(recurse, iterator = from(value as AsyncIterator<unknown>), (next = iterator.next, ((...args: readonly unknown[]) => apply<typeof _next>(next, iterator, args))), depth - 1);
} else yield value;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/methods/async/additionals/groupBy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { assert, assertIterator, closeAsyncIterator, isFunction, mimic, pushValu


export default mimic(undefined, "groupBy", assert(isFunction, O => `${ O } is not a function`, assertIterator(
async function (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown) => Promise<unknown>) {
var done: boolean | undefined, value: unknown, map: Record<PropertyKey, unknown[]> = {};
async function (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown, index: number) => Promise<unknown>) {
var done: boolean | undefined, value: unknown, index = 0, map: Record<PropertyKey, unknown[]> = {};

while ({ done, value } = await _next(), !done) try {
pushValue(map[toPropertyKey(await fn(value))] ??= [], value);
pushValue(map[toPropertyKey(await fn(value, index++))] ??= [], value);
} catch (error) {
await closeAsyncIterator(this);
throw error;
Expand Down
6 changes: 3 additions & 3 deletions src/methods/async/additionals/groupByToMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { assert, assertIterator, closeAsyncIterator, isFunction, mimic, pushValu


export default mimic(undefined, "groupByToMap", assert(isFunction, O => `${ O } is not a function`, assertIterator(
async function (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown) => Promise<unknown>) {
var done: boolean | undefined, value: unknown, map: SafeMap<unknown, unknown[]> = new SafeMap;
async function (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown, index: number) => Promise<unknown>) {
var done: boolean | undefined, value: unknown, index = 0, map: SafeMap<unknown, unknown[]> = new SafeMap;

while ({ done, value } = await _next(), !done) try {
pushValue(map.getSet(await fn(value), Array), value);
pushValue(map.getSet(await fn(value, index++), Array), value);
} catch (error) {
await closeAsyncIterator(this);
throw error;
Expand Down
8 changes: 4 additions & 4 deletions src/methods/async/additionals/partition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { assert, assertIterator, closeAsyncIterator, isFunction, mimic, pushValu
class PartitionateAsyncIterator {
private _done?: readonly [unknown];
private rejected?: readonly [unknown];
private lastValue?: unknown;
private index: number = 0;
public constructor(private readonly _next: AsyncIterator<unknown, unknown, unknown>["next"],
private readonly fn: (...args: readonly unknown[]) => Promise<boolean>, private readonly _iterator: AsyncIterator<unknown>) { }
private async *start(direction: boolean, items: unknown[], opposite: unknown[]) {
Expand All @@ -15,7 +15,7 @@ class PartitionateAsyncIterator {
while (items.length > 0) yield shift(items);
if (this._done) break;
while (1) {
var { value, done } = await this._next(this.lastValue), result: boolean;
var { value, done } = await this._next(), result: boolean;

if (done) {
this._done = [value];
Expand All @@ -24,14 +24,14 @@ class PartitionateAsyncIterator {
return value;
}
try {
result = await call(this.fn, undefined!, value); // fn would be otherwise called with `this` set with current `this` value (of PartitionateAsyncIterator class);
result = await call(this.fn, undefined!, value, this.index++); // fn would be otherwise called with `this` set with current `this` value (of PartitionateAsyncIterator class);
} catch (error) {
await closeAsyncIterator(this._iterator);
throw error;
}
if (!!result === direction) {
while (items.length > 0) yield shift(items);
this.lastValue = yield value;
yield value;
break;
} else {
pushValue(opposite, value);
Expand Down
8 changes: 4 additions & 4 deletions src/methods/async/additionals/roundrobin.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { assertIterator, assertReplaceStar, mimic } from "@utils/utils.js";
import { type AnyFunction, Array, bind, undefined, unshift } from "tslib";
import { type AnyFunction, bind, undefined, unshift } from "tslib";
import from from "@async/statics/from.js";


Expand All @@ -9,15 +9,15 @@ export default mimic(undefined, "roundrobin", assertReplaceStar(args => {
}
}, assertIterator(
async function* (this: AsyncIterator<unknown>, next: AsyncIterator<unknown, unknown, unknown>["next"], ...nexts: AsyncIterator<unknown, unknown, unknown>["next"][]) {
var index, length = unshift(nexts, next), doneCount = 0, lastValues: unknown[] = Array(length);
var index, length = unshift(nexts, next), doneCount = 0;

while (doneCount < length) {
for (index = 0; index < length; index++) {
if (nexts[index]) {
const { done, value } = await nexts[index]!(lastValues[index]);
const { done, value } = await nexts[index]();

if (done && ++doneCount) { delete nexts[index]; continue; }
lastValues[index] = yield value;
yield value;
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/methods/async/additionals/starMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { assert, assertIterator, closeAsyncIterator, isFunction, mimic } from "@


export default mimic(undefined, "starMap", assert(isFunction, O => `${ O } is not a function`, assertIterator(
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<Iterator, never, unknown>["next"], fn: (...args: readonly unknown[]) => Promise<unknown>) {
var lastValue: unknown, done: boolean | undefined, value: Iterator;
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<Iterator<unknown>, never, unknown>["next"], fn: (...args: readonly unknown[]) => Promise<unknown>) {
var done: boolean | undefined, value: Iterator<unknown>;

while ({ done, value } = await _next(lastValue), !done) try {
lastValue = yield await fn(...value);
while ({ done, value } = await _next(), !done) try {
yield await fn(...value);
} catch (error) {
await closeAsyncIterator(this);
throw error;
Expand Down
8 changes: 4 additions & 4 deletions src/methods/async/additionals/takeWhile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { assert, assertIterator, closeAsyncIterator, isFunction, mimic } from "@


export default mimic(undefined, "takeWhile", assert(isFunction, O => O + " is not a function", assertIterator(
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown) => Promise<boolean>) {
var lastValue: unknown, done: boolean | undefined, value: unknown;
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown, index: number) => Promise<boolean>) {
var done: boolean | undefined, value: unknown, index = 0;

while ({ done, value } = await _next(), !done) try {
if (!await fn(value)) break;
if (!await fn(value, index++)) break;
} catch (error) {
await closeAsyncIterator(this);
throw error;
}

while ({ done, value } = await _next(lastValue), !done) lastValue = yield value;
while ({ done, value } = await _next(), !done) yield value;
}
)));
5 changes: 2 additions & 3 deletions src/methods/async/additionals/tee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { assertIterator, assertReplace, isPositiveInteger, mimic } from "@utils/
/** A clever implementation of tee method which is garbage-collection friendly */
class ClonedAsyncIterator {
private _done?: readonly [number, unknown];
private lastValue!: unknown;
public constructor(private readonly _next: AsyncIterator<unknown, unknown, unknown>["next"]) { }
public _create(count: number): readonly AsyncGenerator[] {
const a = Array<AsyncGenerator>(count), results: unknown[] = [], positions = Array<number>(count);
Expand All @@ -23,14 +22,14 @@ class ClonedAsyncIterator {

while ((this._done && this._done[0]) !== position) {
if (position >= results.length) {
const { done, value } = await this._next(this.lastValue);
const { done, value } = await this._next();

if (done) {
this._done = [position, value];

return value;
}
this.lastValue = yield results[position++] = value;
yield results[position++] = value;
positions[index] = position;
continue;
}
Expand Down
1 change: 0 additions & 1 deletion src/methods/async/all.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export { default as asIndexedPairs } from "./indexed.js";
export { default as flatMap } from "./flatMap.js";
export { default as forEach } from "./forEach.js";
export { default as indexed } from "./indexed.js";
Expand Down
4 changes: 2 additions & 2 deletions src/methods/async/drop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export default mimic(undefined, "drop", assertReplace(isPositiveInteger, assertI
if ((await _next()).done) return;
}

for (var lastValue: unknown, done: boolean | undefined, value: unknown; { done, value } = await _next(lastValue), !done;) {
lastValue = yield value;
for (var done: boolean | undefined, value: unknown; { done, value } = await _next(), !done;) {
yield value;
}
}
)));
6 changes: 3 additions & 3 deletions src/methods/async/every.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { assert, assertIterator, closeAsyncIterator, isFunction, mimic } from "@


export default mimic(undefined, "every", assert(isFunction, O => `${ O } is not a function`, assertIterator(
async function (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown) => Promise<boolean>) {
var done: boolean | undefined, value: unknown;
async function (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown, index: number) => Promise<boolean>) {
var done: boolean | undefined, value: unknown, index = 0;

while ({ done, value } = await _next(), !done) try {
if (!await fn(value)) return closeAsyncIterator(this, false);
if (!await fn(value, index++)) return closeAsyncIterator(this, false);
} catch (error) {
await closeAsyncIterator(this);
throw error;
Expand Down
6 changes: 3 additions & 3 deletions src/methods/async/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { assert, assertIterator, closeAsyncIterator, isFunction, mimic } from "@


export default mimic(undefined, "filter", assert(isFunction, O => `${ O } is not a function`, assertIterator(
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown) => Promise<boolean>) {
for (var lastValue: unknown, done: boolean | undefined, value: unknown; { done, value } = await _next(lastValue), !done;) {
async function* (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown, index: number) => Promise<boolean>) {
for (var done: boolean | undefined, value: unknown, index = 0; { done, value } = await _next(), !done;) {
try {
if (await fn(value)) lastValue = yield value;
if (await fn(value, index++)) yield value;
} catch (error) {
await closeAsyncIterator(this);
throw error;
Expand Down
6 changes: 3 additions & 3 deletions src/methods/async/find.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { assert, assertIterator, closeAsyncIterator, isFunction, mimic } from "@


export default mimic(undefined, "find", assert(isFunction, O => `${ O } is not a function`, assertIterator(
async function (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown) => Promise<boolean>) {
var value: unknown, done: boolean | undefined;
async function (this: AsyncIterator<unknown>, _next: AsyncIterator<unknown, unknown, unknown>["next"], fn: (item: unknown, index: number) => Promise<boolean>) {
var value: unknown, done: boolean | undefined, index = 0;

while ({ value, done } = await _next(), !done) try {
if (await fn(value)) return closeAsyncIterator(this, value);
if (await fn(value, index++)) return closeAsyncIterator(this, value);
} catch (error) {
await closeAsyncIterator(this);
throw error;
Expand Down
Loading

0 comments on commit 7c25ac2

Please sign in to comment.