@anion155/proposal-iterator-helpers 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/lib/base.js +10 -0
  2. package/lib/global-iterator.js +5 -0
  3. package/lib/global.js +2 -0
  4. package/lib/index.js +14 -0
  5. package/lib/iterator-constructor.js +15 -0
  6. package/lib/iterator-from.js +45 -0
  7. package/lib/iterator-prototype-drop.js +15 -0
  8. package/lib/iterator-prototype-every.js +17 -0
  9. package/lib/iterator-prototype-filter.js +16 -0
  10. package/lib/iterator-prototype-find.js +17 -0
  11. package/lib/iterator-prototype-flat-map.js +15 -0
  12. package/lib/iterator-prototype-for-each.js +14 -0
  13. package/lib/iterator-prototype-map.js +14 -0
  14. package/lib/iterator-prototype-reduce.js +21 -0
  15. package/lib/iterator-prototype-some.js +17 -0
  16. package/lib/iterator-prototype-take.js +17 -0
  17. package/lib/iterator-prototype-to-array.js +13 -0
  18. package/lib/iterator-prototype.js +12 -0
  19. package/lib/utils.js +7 -0
  20. package/package.json +45 -0
  21. package/src/base.ts +10 -0
  22. package/src/global-iterator.ts +8 -0
  23. package/src/global.ts +2 -0
  24. package/src/index.ts +15 -0
  25. package/src/iterator-constructor.ts +20 -0
  26. package/src/iterator-from.ts +50 -0
  27. package/src/iterator-prototype-drop.ts +16 -0
  28. package/src/iterator-prototype-every.ts +19 -0
  29. package/src/iterator-prototype-filter.ts +21 -0
  30. package/src/iterator-prototype-find.ts +19 -0
  31. package/src/iterator-prototype-flat-map.ts +20 -0
  32. package/src/iterator-prototype-for-each.ts +16 -0
  33. package/src/iterator-prototype-map.ts +19 -0
  34. package/src/iterator-prototype-reduce.ts +27 -0
  35. package/src/iterator-prototype-some.ts +19 -0
  36. package/src/iterator-prototype-take.ts +19 -0
  37. package/src/iterator-prototype-to-array.ts +15 -0
  38. package/src/iterator-prototype.ts +14 -0
  39. package/src/utils.ts +9 -0
package/lib/base.js ADDED
@@ -0,0 +1,10 @@
1
+ export function polyfill(condition, polyfill) {
2
+ if (!condition)
3
+ polyfill();
4
+ }
5
+ export function polyfillProperty(value, key, descriptor) {
6
+ if (!(key in value)) {
7
+ const { writable = true, enumerable = true, configurable = true } = descriptor;
8
+ Object.defineProperty(value, key, { ...descriptor, writable, enumerable, configurable });
9
+ }
10
+ }
@@ -0,0 +1,5 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorConstructor } from "./iterator-constructor";
3
+ polyfillProperty(globalThis, "Iterator", {
4
+ value: IteratorConstructor,
5
+ });
package/lib/global.js ADDED
@@ -0,0 +1,2 @@
1
+ import "./global-iterator";
2
+ import "./index";
package/lib/index.js ADDED
@@ -0,0 +1,14 @@
1
+ import "./iterator-from";
2
+ import "./iterator-prototype-drop";
3
+ import "./iterator-prototype-every";
4
+ import "./iterator-prototype-filter";
5
+ import "./iterator-prototype-find";
6
+ import "./iterator-prototype-flat-map";
7
+ import "./iterator-prototype-for-each";
8
+ import "./iterator-prototype-map";
9
+ import "./iterator-prototype-reduce";
10
+ import "./iterator-prototype-some";
11
+ import "./iterator-prototype-take";
12
+ import "./iterator-prototype-to-array";
13
+ export * from "./iterator-constructor";
14
+ export * from "./iterator-prototype";
@@ -0,0 +1,15 @@
1
+ import { polyfill, polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ import { isIteratorInstance } from "./utils";
4
+ polyfill("constructor" in IteratorPrototype, () => {
5
+ const IteratorConstructor = function Iterator() {
6
+ if (!isIteratorInstance(this))
7
+ throw new TypeError("Constructor Iterator requires 'new'");
8
+ if (Object.getPrototypeOf(this) === IteratorPrototype)
9
+ throw new TypeError("Abstract class Iterator not directly constructable");
10
+ return this;
11
+ };
12
+ IteratorConstructor.prototype = IteratorPrototype;
13
+ polyfillProperty(IteratorPrototype, "constructor", { value: IteratorConstructor, enumerable: false });
14
+ });
15
+ export const IteratorConstructor = IteratorPrototype.constructor;
@@ -0,0 +1,45 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorConstructor } from "./iterator-constructor";
3
+ import { IteratorPrototype } from "./iterator-prototype";
4
+ import { isIterable, isIteratorInstance } from "./utils";
5
+ const doneKey = Symbol.for("proxy-iterator-done");
6
+ const targetKey = Symbol.for("proxy-iterator-target");
7
+ function ProxyIterator(target) {
8
+ this[doneKey] = false;
9
+ polyfillProperty(this, targetKey, { value: target, writable: false });
10
+ }
11
+ ProxyIterator.prototype = Object.create(IteratorPrototype, {
12
+ next: {
13
+ value: function proxyNext(value) {
14
+ if (this[doneKey])
15
+ return { done: true, value: undefined };
16
+ return this[targetKey].next(value);
17
+ },
18
+ },
19
+ return: {
20
+ value: function proxyReturn(value) {
21
+ this[doneKey] = true;
22
+ if (!this[targetKey].return)
23
+ return { value, done: true };
24
+ return this[targetKey].return?.(value);
25
+ },
26
+ },
27
+ throw: {
28
+ value: function proxyThrow(error) {
29
+ this[doneKey] = true;
30
+ if (!this[targetKey].throw)
31
+ throw error;
32
+ return this[targetKey].throw(error);
33
+ },
34
+ },
35
+ });
36
+ polyfillProperty(IteratorConstructor, "from", {
37
+ value: function from(it) {
38
+ if (isIteratorInstance(it))
39
+ return it;
40
+ const iterator = isIterable(it) ? it[Symbol.iterator]() : it;
41
+ if (isIteratorInstance(iterator))
42
+ return iterator;
43
+ return Reflect.construct(ProxyIterator, [iterator]);
44
+ },
45
+ });
@@ -0,0 +1,15 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ polyfillProperty(IteratorPrototype, "drop", {
4
+ value: function* drop(limit) {
5
+ let index = 0;
6
+ while (true) {
7
+ const result = this.next();
8
+ if (result.done)
9
+ return result.value;
10
+ if (index >= limit)
11
+ yield result.value;
12
+ index += 1;
13
+ }
14
+ },
15
+ });
@@ -0,0 +1,17 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ polyfillProperty(IteratorPrototype, "every", {
4
+ value: function every(predicate) {
5
+ let index = 0;
6
+ while (true) {
7
+ const result = this.next();
8
+ if (result.done)
9
+ return true;
10
+ if (!predicate(result.value, index)) {
11
+ this.return?.(undefined);
12
+ return false;
13
+ }
14
+ index += 1;
15
+ }
16
+ },
17
+ });
@@ -0,0 +1,16 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ polyfillProperty(IteratorPrototype, "filter", {
4
+ value: function* filter(predicate) {
5
+ let index = 0;
6
+ while (true) {
7
+ const result = this.next();
8
+ if (result.done)
9
+ return result.value;
10
+ if (predicate(result.value, index)) {
11
+ yield result.value;
12
+ }
13
+ index += 1;
14
+ }
15
+ },
16
+ });
@@ -0,0 +1,17 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ polyfillProperty(IteratorPrototype, "find", {
4
+ value: function find(predicate) {
5
+ let index = 0;
6
+ while (true) {
7
+ const result = this.next();
8
+ if (result.done)
9
+ return undefined;
10
+ if (predicate(result.value, index)) {
11
+ this.return?.(undefined);
12
+ return result.value;
13
+ }
14
+ index += 1;
15
+ }
16
+ },
17
+ });
@@ -0,0 +1,15 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorConstructor } from "./iterator-constructor";
3
+ import { IteratorPrototype } from "./iterator-prototype";
4
+ polyfillProperty(IteratorPrototype, "flatMap", {
5
+ value: function* flatMap(project) {
6
+ let index = 0;
7
+ while (true) {
8
+ const result = this.next();
9
+ if (result.done)
10
+ return result.value;
11
+ yield* IteratorConstructor.from(project(result.value, index));
12
+ index += 1;
13
+ }
14
+ },
15
+ });
@@ -0,0 +1,14 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ polyfillProperty(IteratorPrototype, "forEach", {
4
+ value: function forEach(callback) {
5
+ let index = 0;
6
+ while (true) {
7
+ const result = this.next();
8
+ if (result.done)
9
+ return;
10
+ callback(result.value, index);
11
+ index += 1;
12
+ }
13
+ },
14
+ });
@@ -0,0 +1,14 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ polyfillProperty(IteratorPrototype, "map", {
4
+ value: function* map(project) {
5
+ let index = 0;
6
+ while (true) {
7
+ const result = this.next();
8
+ if (result.done)
9
+ return result.value;
10
+ yield project(result.value, index);
11
+ index += 1;
12
+ }
13
+ },
14
+ });
@@ -0,0 +1,21 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ polyfillProperty(IteratorPrototype, "reduce", {
4
+ value: function reduce(reducer, ...args) {
5
+ let index = 0;
6
+ let aggregation = args[0];
7
+ let initiated = args.length > 0;
8
+ while (true) {
9
+ const result = this.next();
10
+ if (result.done)
11
+ return aggregation;
12
+ if (!initiated && args.length === 0) {
13
+ aggregation = result.value;
14
+ initiated = true;
15
+ continue;
16
+ }
17
+ aggregation = reducer(aggregation, result.value, index);
18
+ index += 1;
19
+ }
20
+ },
21
+ });
@@ -0,0 +1,17 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ polyfillProperty(IteratorPrototype, "some", {
4
+ value: function some(predicate) {
5
+ let index = 0;
6
+ while (true) {
7
+ const result = this.next();
8
+ if (result.done)
9
+ return false;
10
+ if (predicate(result.value, index)) {
11
+ this.return?.(undefined);
12
+ return true;
13
+ }
14
+ index += 1;
15
+ }
16
+ },
17
+ });
@@ -0,0 +1,17 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ polyfillProperty(IteratorPrototype, "take", {
4
+ value: function* take(limit) {
5
+ let index = 0;
6
+ while (true) {
7
+ if (index >= limit) {
8
+ return this.return?.(undefined).value;
9
+ }
10
+ const result = this.next();
11
+ if (result.done)
12
+ return result.value;
13
+ yield result.value;
14
+ index += 1;
15
+ }
16
+ },
17
+ });
@@ -0,0 +1,13 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ polyfillProperty(IteratorPrototype, "toArray", {
4
+ value: function toArray() {
5
+ const items = [];
6
+ while (true) {
7
+ const result = this.next();
8
+ if (result.done)
9
+ return items;
10
+ items.push(result.value);
11
+ }
12
+ },
13
+ });
@@ -0,0 +1,12 @@
1
+ import { polyfillProperty } from "./base";
2
+ export const IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()));
3
+ polyfillProperty(IteratorPrototype, Symbol.toStringTag, {
4
+ value: "Iterator",
5
+ writable: false,
6
+ enumerable: false,
7
+ });
8
+ polyfillProperty(IteratorPrototype, Symbol.iterator, {
9
+ value: function iterator() {
10
+ return this;
11
+ },
12
+ });
package/lib/utils.js ADDED
@@ -0,0 +1,7 @@
1
+ import { IteratorPrototype } from "./iterator-prototype";
2
+ export function isIteratorInstance(value) {
3
+ return Object.prototype.isPrototypeOf.call(IteratorPrototype, value);
4
+ }
5
+ export function isIterable(value) {
6
+ return Symbol.iterator in value && typeof value[Symbol.iterator] === "function";
7
+ }
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@anion155/proposal-iterator-helpers",
3
+ "version": "0.1.0",
4
+ "description": "Polyfills implementing the Iterator Helpers proposal for ECMAScript.",
5
+ "keywords": [
6
+ "iterator",
7
+ "iterable",
8
+ "helpers",
9
+ "ecmascript",
10
+ "proposal",
11
+ "polyfill"
12
+ ],
13
+ "author": {
14
+ "name": "anion155",
15
+ "url": "https://github.com/anion155"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/anion155/monorepo.git",
20
+ "directory": "packages/proposal-iterator-helpers"
21
+ },
22
+ "license": "MIT",
23
+ "type": "module",
24
+ "exports": {
25
+ "./global-iterator": "./src/global-iterator.ts",
26
+ "./global": "./src/global.ts",
27
+ ".": "./src/index.ts",
28
+ "./iterator-constructor": "./src/iterator-constructor.ts",
29
+ "./iterator-from": "./src/iterator-from.ts",
30
+ "./iterator-prototype-drop": "./src/iterator-prototype-drop.ts",
31
+ "./iterator-prototype-every": "./src/iterator-prototype-every.ts",
32
+ "./iterator-prototype-filter": "./src/iterator-prototype-filter.ts",
33
+ "./iterator-prototype-find": "./src/iterator-prototype-find.ts",
34
+ "./iterator-prototype-flat-map": "./src/iterator-prototype-flat-map.ts",
35
+ "./iterator-prototype-for-each": "./src/iterator-prototype-for-each.ts",
36
+ "./iterator-prototype-map": "./src/iterator-prototype-map.ts",
37
+ "./iterator-prototype-reduce": "./src/iterator-prototype-reduce.ts",
38
+ "./iterator-prototype-some": "./src/iterator-prototype-some.ts",
39
+ "./iterator-prototype-take": "./src/iterator-prototype-take.ts",
40
+ "./iterator-prototype-to-array": "./src/iterator-prototype-to-array.ts",
41
+ "./iterator-prototype": "./src/iterator-prototype.ts",
42
+ "./utils": "./src/utils.ts"
43
+ },
44
+ "dependencies": {}
45
+ }
package/src/base.ts ADDED
@@ -0,0 +1,10 @@
1
+ export function polyfill(condition: unknown, polyfill: () => void) {
2
+ if (!condition) polyfill();
3
+ }
4
+
5
+ export function polyfillProperty<Value extends object>(value: Value, key: keyof Value | (PropertyKey & {}), descriptor: PropertyDescriptor) {
6
+ if (!(key in value)) {
7
+ const { writable = true, enumerable = true, configurable = true } = descriptor;
8
+ Object.defineProperty(value, key, { ...descriptor, writable, enumerable, configurable });
9
+ }
10
+ }
@@ -0,0 +1,8 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorConstructor } from "./iterator-constructor";
3
+
4
+ polyfillProperty(globalThis, "Iterator", {
5
+ value: IteratorConstructor,
6
+ });
7
+
8
+ export {};
package/src/global.ts ADDED
@@ -0,0 +1,2 @@
1
+ import "./global-iterator";
2
+ import "./index";
package/src/index.ts ADDED
@@ -0,0 +1,15 @@
1
+ import "./iterator-from";
2
+ import "./iterator-prototype-drop";
3
+ import "./iterator-prototype-every";
4
+ import "./iterator-prototype-filter";
5
+ import "./iterator-prototype-find";
6
+ import "./iterator-prototype-flat-map";
7
+ import "./iterator-prototype-for-each";
8
+ import "./iterator-prototype-map";
9
+ import "./iterator-prototype-reduce";
10
+ import "./iterator-prototype-some";
11
+ import "./iterator-prototype-take";
12
+ import "./iterator-prototype-to-array";
13
+
14
+ export * from "./iterator-constructor";
15
+ export * from "./iterator-prototype";
@@ -0,0 +1,20 @@
1
+ import { polyfill, polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+ import { isIteratorInstance } from "./utils";
4
+
5
+ polyfill("constructor" in IteratorPrototype, () => {
6
+ const IteratorConstructor = function Iterator(this: Iterator<unknown>): Iterator<unknown> {
7
+ if (!isIteratorInstance(this)) throw new TypeError("Constructor Iterator requires 'new'");
8
+ if (Object.getPrototypeOf(this) === IteratorPrototype) throw new TypeError("Abstract class Iterator not directly constructable");
9
+ return this;
10
+ };
11
+ IteratorConstructor.prototype = IteratorPrototype;
12
+ polyfillProperty(IteratorPrototype, "constructor", { value: IteratorConstructor, enumerable: false });
13
+ });
14
+ export const IteratorConstructor = IteratorPrototype.constructor as never as (abstract new <T, TReturn = unknown, TNext = unknown>() => Iterator<
15
+ T,
16
+ TReturn,
17
+ TNext
18
+ >) & {
19
+ from<T, TReturn = unknown, TNext = unknown>(it: Iterator<T, TReturn, TNext> | Iterable<T, TReturn, TNext>): IteratorObject<T, TReturn, TNext>;
20
+ };
@@ -0,0 +1,50 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorConstructor } from "./iterator-constructor";
3
+ import { IteratorPrototype } from "./iterator-prototype";
4
+ import { isIterable, isIteratorInstance } from "./utils";
5
+
6
+ const doneKey = Symbol.for("proxy-iterator-done");
7
+ const targetKey = Symbol.for("proxy-iterator-target");
8
+
9
+ type ProxyIterator<T, TReturn = unknown, TNext = unknown> = Iterator<T, TReturn, TNext> & {
10
+ [doneKey]: boolean;
11
+ readonly [targetKey]: Iterator<T, TReturn, TNext>;
12
+ };
13
+
14
+ function ProxyIterator<T, TReturn = unknown, TNext = unknown>(this: ProxyIterator<T, TReturn, TNext>, target: Iterator<T, TReturn, TNext>) {
15
+ this[doneKey] = false;
16
+ polyfillProperty(this, targetKey, { value: target, writable: false });
17
+ }
18
+ ProxyIterator.prototype = Object.create(IteratorPrototype, {
19
+ next: {
20
+ value: function proxyNext(this: ProxyIterator<unknown, unknown, unknown>, value: unknown) {
21
+ if (this[doneKey]) return { done: true, value: undefined };
22
+ return this[targetKey].next(value);
23
+ },
24
+ },
25
+ return: {
26
+ value: function proxyReturn(this: ProxyIterator<unknown, unknown, unknown>, value?: unknown) {
27
+ this[doneKey] = true;
28
+ if (!this[targetKey].return) return { value, done: true };
29
+ return this[targetKey].return?.(value);
30
+ },
31
+ },
32
+ throw: {
33
+ value: function proxyThrow(this: ProxyIterator<unknown, unknown, unknown>, error?: unknown) {
34
+ this[doneKey] = true;
35
+ if (!this[targetKey].throw) throw error;
36
+ return this[targetKey].throw(error);
37
+ },
38
+ },
39
+ }) as ProxyIterator<unknown, unknown, unknown>;
40
+
41
+ polyfillProperty(IteratorConstructor, "from", {
42
+ value: function from<T, TReturn = unknown, TNext = unknown>(it: Iterator<T, TReturn, TNext> | Iterable<T>): IteratorObject<T, TReturn, TNext> {
43
+ if (isIteratorInstance<T, TReturn, TNext>(it)) return it;
44
+ const iterator = isIterable(it) ? it[Symbol.iterator]() : it;
45
+ if (isIteratorInstance<T, TReturn, TNext>(iterator)) return iterator;
46
+ return Reflect.construct(ProxyIterator, [iterator]) as never;
47
+ },
48
+ });
49
+
50
+ export {};
@@ -0,0 +1,16 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+
4
+ polyfillProperty(IteratorPrototype, "drop", {
5
+ value: function* drop<T, TReturn, TNext>(this: Iterator<T, TReturn, TNext>, limit: number): Generator<T, TReturn, TNext> {
6
+ let index = 0;
7
+ while (true) {
8
+ const result = this.next();
9
+ if (result.done) return result.value;
10
+ if (index >= limit) yield result.value;
11
+ index += 1;
12
+ }
13
+ },
14
+ });
15
+
16
+ export {};
@@ -0,0 +1,19 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+
4
+ polyfillProperty(IteratorPrototype, "every", {
5
+ value: function every<T, TReturn, TNext>(this: Iterator<T, TReturn, TNext>, predicate: (value: T, index: number) => boolean): boolean {
6
+ let index = 0;
7
+ while (true) {
8
+ const result = this.next();
9
+ if (result.done) return true;
10
+ if (!predicate(result.value, index)) {
11
+ this.return?.(undefined);
12
+ return false;
13
+ }
14
+ index += 1;
15
+ }
16
+ },
17
+ });
18
+
19
+ export {};
@@ -0,0 +1,21 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+
4
+ polyfillProperty(IteratorPrototype, "filter", {
5
+ value: function* filter<T, TReturn, TNext>(
6
+ this: Iterator<T, TReturn, TNext>,
7
+ predicate: (value: T, index: number) => boolean,
8
+ ): Generator<T, TReturn, TNext> {
9
+ let index = 0;
10
+ while (true) {
11
+ const result = this.next();
12
+ if (result.done) return result.value;
13
+ if (predicate(result.value, index)) {
14
+ yield result.value;
15
+ }
16
+ index += 1;
17
+ }
18
+ },
19
+ });
20
+
21
+ export {};
@@ -0,0 +1,19 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+
4
+ polyfillProperty(IteratorPrototype, "find", {
5
+ value: function find<T, TReturn, TNext>(this: Iterator<T, TReturn, TNext>, predicate: (value: T, index: number) => boolean): T | undefined {
6
+ let index = 0;
7
+ while (true) {
8
+ const result = this.next();
9
+ if (result.done) return undefined;
10
+ if (predicate(result.value, index)) {
11
+ this.return?.(undefined);
12
+ return result.value;
13
+ }
14
+ index += 1;
15
+ }
16
+ },
17
+ });
18
+
19
+ export {};
@@ -0,0 +1,20 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorConstructor } from "./iterator-constructor";
3
+ import { IteratorPrototype } from "./iterator-prototype";
4
+
5
+ polyfillProperty(IteratorPrototype, "flatMap", {
6
+ value: function* flatMap<T, TReturn, TNext, U>(
7
+ this: Iterator<T, TReturn, TNext>,
8
+ project: (value: T, index: number) => Iterator<U> | Iterable<U>,
9
+ ): Generator<U, TReturn, undefined> {
10
+ let index = 0;
11
+ while (true) {
12
+ const result = this.next();
13
+ if (result.done) return result.value;
14
+ yield* IteratorConstructor.from(project(result.value, index));
15
+ index += 1;
16
+ }
17
+ },
18
+ });
19
+
20
+ export {};
@@ -0,0 +1,16 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+
4
+ polyfillProperty(IteratorPrototype, "forEach", {
5
+ value: function forEach<T, TReturn, TNext>(this: Iterator<T, TReturn, TNext>, callback: (value: T, index: number) => void): void {
6
+ let index = 0;
7
+ while (true) {
8
+ const result = this.next();
9
+ if (result.done) return;
10
+ callback(result.value, index);
11
+ index += 1;
12
+ }
13
+ },
14
+ });
15
+
16
+ export {};
@@ -0,0 +1,19 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+
4
+ polyfillProperty(IteratorPrototype, "map", {
5
+ value: function* map<T, TReturn, TNext, U>(
6
+ this: Iterator<T, TReturn, TNext>,
7
+ project: (value: T, index: number) => U,
8
+ ): Generator<U, TReturn, TNext> {
9
+ let index = 0;
10
+ while (true) {
11
+ const result = this.next();
12
+ if (result.done) return result.value;
13
+ yield project(result.value, index);
14
+ index += 1;
15
+ }
16
+ },
17
+ });
18
+
19
+ export {};
@@ -0,0 +1,27 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+
4
+ polyfillProperty(IteratorPrototype, "reduce", {
5
+ value: function reduce<T, TReturn, TNext, U>(
6
+ this: Iterator<T, TReturn, TNext>,
7
+ reducer: (aggregation: U, value: T, index: number) => U,
8
+ ...args: [initialValue?: U]
9
+ ): U {
10
+ let index = 0;
11
+ let aggregation: U = args[0] as never;
12
+ let initiated = args.length > 0;
13
+ while (true) {
14
+ const result = this.next();
15
+ if (result.done) return aggregation;
16
+ if (!initiated && args.length === 0) {
17
+ aggregation = result.value as never;
18
+ initiated = true;
19
+ continue;
20
+ }
21
+ aggregation = reducer(aggregation, result.value, index);
22
+ index += 1;
23
+ }
24
+ },
25
+ });
26
+
27
+ export {};
@@ -0,0 +1,19 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+
4
+ polyfillProperty(IteratorPrototype, "some", {
5
+ value: function some<T, TReturn, TNext>(this: Iterator<T, TReturn, TNext>, predicate: (value: T, index: number) => boolean): boolean {
6
+ let index = 0;
7
+ while (true) {
8
+ const result = this.next();
9
+ if (result.done) return false;
10
+ if (predicate(result.value, index)) {
11
+ this.return?.(undefined);
12
+ return true;
13
+ }
14
+ index += 1;
15
+ }
16
+ },
17
+ });
18
+
19
+ export {};
@@ -0,0 +1,19 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+
4
+ polyfillProperty(IteratorPrototype, "take", {
5
+ value: function* take<T, TReturn, TNext>(this: Iterator<T, TReturn, TNext>, limit: number): Generator<T, T | TReturn | undefined, TNext> {
6
+ let index = 0;
7
+ while (true) {
8
+ if (index >= limit) {
9
+ return this.return?.(undefined).value;
10
+ }
11
+ const result = this.next();
12
+ if (result.done) return result.value;
13
+ yield result.value;
14
+ index += 1;
15
+ }
16
+ },
17
+ });
18
+
19
+ export {};
@@ -0,0 +1,15 @@
1
+ import { polyfillProperty } from "./base";
2
+ import { IteratorPrototype } from "./iterator-prototype";
3
+
4
+ polyfillProperty(IteratorPrototype, "toArray", {
5
+ value: function toArray<T, TReturn, TNext>(this: Iterator<T, TReturn, TNext>): T[] {
6
+ const items: T[] = [];
7
+ while (true) {
8
+ const result = this.next();
9
+ if (result.done) return items;
10
+ items.push(result.value);
11
+ }
12
+ },
13
+ });
14
+
15
+ export {};
@@ -0,0 +1,14 @@
1
+ import { polyfillProperty } from "./base";
2
+
3
+ export const IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]())) as Iterator<unknown>;
4
+
5
+ polyfillProperty(IteratorPrototype, Symbol.toStringTag, {
6
+ value: "Iterator",
7
+ writable: false,
8
+ enumerable: false,
9
+ });
10
+ polyfillProperty(IteratorPrototype, Symbol.iterator, {
11
+ value: function iterator() {
12
+ return this;
13
+ },
14
+ });
package/src/utils.ts ADDED
@@ -0,0 +1,9 @@
1
+ import { IteratorPrototype } from "./iterator-prototype";
2
+
3
+ export function isIteratorInstance<T, TReturn = unknown, TNext = unknown>(value: object): value is IteratorObject<T, TReturn, TNext> {
4
+ return Object.prototype.isPrototypeOf.call(IteratorPrototype, value);
5
+ }
6
+
7
+ export function isIterable<T>(value: object): value is Iterable<T> {
8
+ return Symbol.iterator in value && typeof value[Symbol.iterator] === "function";
9
+ }