iter-fest 0.1.1-main.1dec735 → 0.1.1-main.2a21293

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 (2) hide show
  1. package/README.md +42 -29
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -16,23 +16,6 @@ Iterables can contains infinite number of items, please use this package respons
16
16
  npm install iter-fest
17
17
  ```
18
18
 
19
- ### `Array.prototype` ports
20
-
21
- We ported majority of functions from `Array.prototype.*` to `iterable*`.
22
-
23
- ```ts
24
- import { iterableIncludes, iterableReduce } from 'iter-fest'; // Via default exports.
25
- import { iterableSome } from 'iter-fest/iterableSome'; // Via named exports.
26
-
27
- const iterable: Iterable<number> = [1, 2, 3, 4, 5].values();
28
-
29
- console.log(iterableIncludes(iterable, 3)); // Prints "true".
30
- console.log(iterableReduce(iterable, (sum, value) => sum + value, 0)); // Prints "15".
31
- console.log(iterableSome(iterable, value => value % 2)); // Prints "true".
32
- ```
33
-
34
- List of ported functions: [`at`](https://tc39.es/ecma262/#sec-array.prototype.at), [`concat`](https://tc39.es/ecma262/#sec-array.prototype.concat), [`entries`](https://tc39.es/ecma262/#sec-array.prototype.entries), [`every`](https://tc39.es/ecma262/#sec-array.prototype.every), [`filter`](https://tc39.es/ecma262/#sec-array.prototype.filter), [`find`](https://tc39.es/ecma262/#sec-array.prototype.find), [`findIndex`](https://tc39.es/ecma262/#sec-array.prototype.findindex), [`findLast`](https://tc39.es/ecma262/#sec-array.prototype.findlast), [`findLastIndex`](https://tc39.es/ecma262/#sec-array.prototype.findlastindex), [`forEach`](https://tc39.es/ecma262/#sec-array.prototype.foreach), [`includes`](https://tc39.es/ecma262/#sec-array.prototype.includes), [`indexOf`](https://tc39.es/ecma262/#sec-array.prototype.indexof), [`join`](https://tc39.es/ecma262/#sec-array.prototype.join), [`keys`](https://tc39.es/ecma262/#sec-array.prototype.keys), [`map`](https://tc39.es/ecma262/#sec-array.prototype.map), [`reduce`](https://tc39.es/ecma262/#sec-array.prototype.reduce), [`slice`](https://tc39.es/ecma262/#sec-array.prototype.slice), [`some`](https://tc39.es/ecma262/#sec-array.prototype.some), [`toSpliced`](https://tc39.es/ecma262/#sec-array.prototype.tospliced), and [`toString`](https://tc39.es/ecma262/#sec-array.prototype.tostring).
35
-
36
19
  ## Conversions
37
20
 
38
21
  | From | To | Function signature |
@@ -70,28 +53,31 @@ for (const value of iteratorToIterable(iterate())) {
70
53
  }
71
54
  ```
72
55
 
73
- Note: calling `[Symbol.iterator]` will not refresh the iteration.
56
+ Note: calling `[Symbol.iterator]()` or `[Symbol.asyncIterator]()` will not restart the iteration. This is because iterator is an instance of iteration and is not restartable.
74
57
 
75
58
  ### Converting an `Observable` to `AsyncIterableIterator`
76
59
 
77
- `ReadableStream` can be used to when converting an `Observable` to `AsyncIterableIterator`.
60
+ `ReadableStream` can be used as an intermediate format when converting an `Observable` to `AsyncIterableIterator`.
78
61
 
79
62
  Note: `Observable` is push-based and it does not support flow control. When converting to `AsyncIterableIteratorrr`, the internal buffer of `ReadableStream` could build up quickly.
80
63
 
81
64
  ```ts
82
65
  const observable = Observable.from([1, 2, 3]);
83
66
  const readable = observableSubscribeAsReadable(observable);
67
+ const iterable = readerValues(readable.getReader());
84
68
 
85
- for await (const value of readerValues(readable.getReader())) {
69
+ for await (const value of iterable) {
86
70
  console.log(value); // Prints "1", "2", "3".
87
71
  }
88
72
  ```
89
73
 
74
+ Note: calling `[Symbol.asyncIterator]()` will not resubscribe and read from the start of the observable. This is because the intermediate format does not support restart.
75
+
90
76
  ### Converting an `AsyncIterable` to `Observable`
91
77
 
92
78
  `Observable.from` converts `Iterable` into `Observable`. However, it does not convert `AsyncIterable`.
93
79
 
94
- `observableFromAsync` will convert `AsyncIterable` into `Observable`.
80
+ `observableFromAsync` will convert `AsyncIterable` into `Observable`. It will try to restart the iteration by calling `[Symbol.asyncIterator]()`.
95
81
 
96
82
  ```ts
97
83
  async function* generate() {
@@ -106,7 +92,9 @@ const next = value => console.log(value);
106
92
  observable.subscribe({ next }); // Prints "1", "2", "3".
107
93
  ```
108
94
 
109
- ## Converting an `Observable` to `ReadableStream`
95
+ Note: `observableFromAsync` will call `[Symbol.asyncIterator]()` initially to restart the iteration where possible.
96
+
97
+ ### Converting an `Observable` to `ReadableStream`
110
98
 
111
99
  `ReadableStream` is powerful for transforming and piping stream of data. It can be formed using data from both push-based and pull-based source with backpressuree.
112
100
 
@@ -115,7 +103,6 @@ Note: `Observable` is push-based and it does not support flow control. When conv
115
103
  ```ts
116
104
  const observable = Observable.from([1, 2, 3]);
117
105
  const readable = observableSubscribeAsReadable(observable);
118
- const reader = readable.getReader();
119
106
 
120
107
  readable.pipeTo(stream.writable); // Will write 1, 2, 3.
121
108
  ```
@@ -136,12 +123,16 @@ const readableStream = new ReadableStream({
136
123
  }
137
124
  });
138
125
 
139
- for await (const value of readerValues(readableStream.getReader())) {
126
+ const iterable = readerValues(readableStream.getReader());
127
+
128
+ for await (const value of iterable) {
140
129
  console.log(value); // Prints "1", "2", "3".
141
130
  }
142
131
  ```
143
132
 
144
- ## Converting an `AsyncIterable`/`Iterable` to `ReadableStream`
133
+ Note: `[Symbol.asyncIterator]()` will not restart the reader and read from start of the stream. Reader is not restartable and streams are not seekable.
134
+
135
+ ### Converting an `AsyncIterable`/`Iterable` to `ReadableStream`
145
136
 
146
137
  ```ts
147
138
  const iterable = [1, 2, 3].values();
@@ -150,6 +141,8 @@ const readable = iterableGetReadable(iterable);
150
141
  readable.pipeTo(stream.writable); // Will write 1, 2, 3.
151
142
  ```
152
143
 
144
+ Note: `iterableGetReadable()` will call `[Symbol.iterator]()` initially to restart the iteration where possible.
145
+
153
146
  ## Others
154
147
 
155
148
  ### Typed `Observable`
@@ -158,9 +151,9 @@ readable.pipeTo(stream.writable); // Will write 1, 2, 3.
158
151
 
159
152
  ### Producer-consumer queue
160
153
 
161
- `PushAsyncIterableIterator` is a simple push-based producer-consumer queue and designed to decouple the flow between a producer and consumer. The producer can push a new job at anytime. The consumer can pull a job at its own convenience.
154
+ `PushAsyncIterableIterator` is a simple push-based producer-consumer queue and designed to decouple the flow between a producer and consumer. The producer can push a new job at anytime. The consumer can pull a job at its own convenience via for-loop.
162
155
 
163
- Compare to pull-based queue, a push-based queue is easier to use. However, pull-based queue offers better flow control as it will produce a job only if there is a consumer ready to consume.
156
+ Compare to pull-based queue, a push-based queue is very easy to use. However, pull-based queue offers better flow control as it will produce a job only if there is a consumer ready to consume.
164
157
 
165
158
  For a full-featured producer-consumer queue that supports flow control, use `ReadableStream` instead.
166
159
 
@@ -223,6 +216,23 @@ const generator = generatorWithLastValue(
223
216
  );
224
217
  ```
225
218
 
219
+ ## `Array.prototype` ports
220
+
221
+ We ported majority of functions from `Array.prototype.*` to `iterable*`.
222
+
223
+ ```ts
224
+ import { iterableIncludes, iterableReduce } from 'iter-fest'; // Via default exports.
225
+ import { iterableSome } from 'iter-fest/iterableSome'; // Via named exports.
226
+
227
+ const iterable: Iterable<number> = [1, 2, 3, 4, 5].values();
228
+
229
+ console.log(iterableIncludes(iterable, 3)); // Prints "true".
230
+ console.log(iterableReduce(iterable, (sum, value) => sum + value, 0)); // Prints "15".
231
+ console.log(iterableSome(iterable, value => value % 2)); // Prints "true".
232
+ ```
233
+
234
+ List of ported functions: [`at`](https://tc39.es/ecma262/#sec-array.prototype.at), [`concat`](https://tc39.es/ecma262/#sec-array.prototype.concat), [`entries`](https://tc39.es/ecma262/#sec-array.prototype.entries), [`every`](https://tc39.es/ecma262/#sec-array.prototype.every), [`filter`](https://tc39.es/ecma262/#sec-array.prototype.filter), [`find`](https://tc39.es/ecma262/#sec-array.prototype.find), [`findIndex`](https://tc39.es/ecma262/#sec-array.prototype.findindex), [`findLast`](https://tc39.es/ecma262/#sec-array.prototype.findlast), [`findLastIndex`](https://tc39.es/ecma262/#sec-array.prototype.findlastindex), [`forEach`](https://tc39.es/ecma262/#sec-array.prototype.foreach), [`includes`](https://tc39.es/ecma262/#sec-array.prototype.includes), [`indexOf`](https://tc39.es/ecma262/#sec-array.prototype.indexof), [`join`](https://tc39.es/ecma262/#sec-array.prototype.join), [`keys`](https://tc39.es/ecma262/#sec-array.prototype.keys), [`map`](https://tc39.es/ecma262/#sec-array.prototype.map), [`reduce`](https://tc39.es/ecma262/#sec-array.prototype.reduce), [`slice`](https://tc39.es/ecma262/#sec-array.prototype.slice), [`some`](https://tc39.es/ecma262/#sec-array.prototype.some), [`toSpliced`](https://tc39.es/ecma262/#sec-array.prototype.tospliced), and [`toString`](https://tc39.es/ecma262/#sec-array.prototype.tostring).
235
+
226
236
  ## Behaviors
227
237
 
228
238
  ### How this compares to the TC39 proposals?
@@ -271,18 +281,21 @@ Generator has more functionalities than iterator and array. It is not recommende
271
281
  - Generator can define the return value
272
282
  - `return { done: true, value: 'the very last value' }`
273
283
  - Iterating generator using for-loop will not get any values from `{ done: true }`
284
+ - The `generatorWithLastValue()` will help capturing and retrieving the last return value
274
285
  - Generator can receive feedback values from its iterator
275
286
  - `generator.next('something')`, the feedback can be assigned to variable via `const feedback = yield;`
276
287
  - For-loop cannot send feedbacks to generator
277
288
 
278
289
  ### When should I use `Iterable`, `IterableIterator` and `Iterator`?
279
290
 
280
- For best compatibility, you should generally follow this API signature: use `Iterable` for inputs, and use `IterableIterator` for outputs. You should avoid exporting pure `Iterator`.
291
+ For best compatibility, you should generally follow this API signature: use `Iterable` for inputs, and use `IterableIterator` for outputs. You should avoid exporting pure `Iterator`. Sample function signature should looks below.
281
292
 
282
293
  ```ts
283
- function transform<T>(iterable: Iterable<T>): IterableIterator<T>;
294
+ function myFunction<T>(input: Iterable<T>): IterableIterator<T>;
284
295
  ```
285
296
 
297
+ `IterableIterator` may opt to support restarting the iteration through `[Symbol.iterator]()`. When consuming an `IterableIterator`, you should call `[Symbol.iterator]()` to obtain a fresh iteration or use for-loop statement if possible. However, `[Symbol.iterator]()` is an opt-in feature and does not always guarantee a fresh iteration.
298
+
286
299
  ### What is on the roadmap?
287
300
 
288
301
  We are planning to bring iterables and its siblings together, including:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iter-fest",
3
- "version": "0.1.1-main.1dec735",
3
+ "version": "0.1.1-main.2a21293",
4
4
  "description": "A collection of utilities for iterations.",
5
5
  "files": [
6
6
  "./dist/"
@@ -378,6 +378,6 @@
378
378
  "typescript": "^5.4.5"
379
379
  },
380
380
  "dependencies": {
381
- "iter-fest": "^0.1.1-main.1dec735"
381
+ "iter-fest": "^0.1.1-main.2a21293"
382
382
  }
383
383
  }