This repository has been archived by the owner on Feb 2, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
createIterableIterator.ts
49 lines (47 loc) · 1.66 KB
/
createIterableIterator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { isIterable } from "@vangware/predicates";
import type { Function } from "@vangware/types";
import type { IsomorphicGeneratorFunction } from "./types/IsomorphicGeneratorFunction.js";
import type { ReadOnlyAsyncIterableIterator } from "./types/ReadOnlyAsyncIterableIterator.js";
import type { ReadOnlyAsyncIterator } from "./types/ReadOnlyAsyncIterator.js";
import type { ReadOnlyIterableIterator } from "./types/ReadOnlyIterableIterator.js";
/**
* Takes a generator function and returns an iterable iterator or asynchronous
* iterable iterator object.
*
* @category Common
* @example
* ```typescript
* const identityGenerator = function* (value) { yield value; };
* const iterableIterator = createIterableIterator(identityGenerator);
*
* const fooIdentity = iterableIterator("foo");
*
* for (const value of fooIdentity) {
* console.log(value); // "foo"
* }
*
* // Same IterableIterator as above, return values again:
*
* for (const value of fooIdentity) {
* console.log(value); // "foo"
* }
* ```
* @param generatorFunction Generator to be used every time `[Symbol.iterator]` is called.
* @returns Iterable iterator object.
*/
export const createIterableIterator = <
GeneratorFunction extends IsomorphicGeneratorFunction,
>(
generatorFunction: GeneratorFunction,
) => {
const generator = generatorFunction();
return {
...generator,
[Symbol[isIterable(generator) ? "iterator" : "asyncIterator"]]:
generatorFunction,
} as GeneratorFunction extends IsomorphicGeneratorFunction<infer Item>
? GeneratorFunction extends Function<never, ReadOnlyAsyncIterator<Item>>
? ReadOnlyAsyncIterableIterator<Item>
: ReadOnlyIterableIterator<Item>
: never;
};