@effectionx/stream-helpers 0.6.1 → 0.7.2
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.
- package/README.md +87 -0
- package/batch.test.ts +2 -2
- package/dist/drain.d.ts +24 -0
- package/dist/drain.d.ts.map +1 -0
- package/dist/drain.js +33 -0
- package/dist/first.d.ts +28 -0
- package/dist/first.d.ts.map +1 -0
- package/dist/first.js +67 -0
- package/dist/for-each.d.ts.map +1 -1
- package/dist/for-each.js +12 -8
- package/dist/last.d.ts +29 -0
- package/dist/last.d.ts.map +1 -0
- package/dist/last.js +81 -0
- package/dist/mod.d.ts +5 -0
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +5 -0
- package/dist/reduce.d.ts +23 -0
- package/dist/reduce.d.ts.map +1 -0
- package/dist/reduce.js +42 -0
- package/dist/stream-of.d.ts +9 -0
- package/dist/stream-of.d.ts.map +1 -0
- package/dist/stream-of.js +18 -0
- package/dist/test-helpers/faucet.d.ts.map +1 -1
- package/dist/test-helpers/faucet.js +28 -24
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/drain.test.ts +52 -0
- package/drain.ts +35 -0
- package/first.test.ts +53 -0
- package/first.ts +74 -0
- package/for-each.ts +12 -8
- package/last.test.ts +65 -0
- package/last.ts +96 -0
- package/mod.ts +5 -0
- package/package.json +5 -4
- package/reduce.test.ts +67 -0
- package/reduce.ts +49 -0
- package/stream-of.ts +22 -0
- package/test-helpers/faucet.test.ts +3 -3
- package/test-helpers/faucet.ts +28 -24
- package/tracker.test.ts +4 -4
- package/valve.test.ts +2 -2
package/README.md
CHANGED
|
@@ -63,6 +63,27 @@ function* example(stream: Stream<number, unknown>) {
|
|
|
63
63
|
}
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
### Reduce
|
|
67
|
+
|
|
68
|
+
The `reduce` helper transforms each item in a stream by applying it to
|
|
69
|
+
an accumulated value.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { reduce } from "@effectionx/stream-helpers";
|
|
73
|
+
import { each } from "effection";
|
|
74
|
+
|
|
75
|
+
function* example(stream: Stream<number, unknown>) {
|
|
76
|
+
let sum = reduce(function* (total: number, current: number) {
|
|
77
|
+
return total + current;
|
|
78
|
+
}, 0);
|
|
79
|
+
|
|
80
|
+
for (let value of yield* each(sum(streamOf([1,2,3]))) {
|
|
81
|
+
console.log(value) // logs 1 -> 3 -> 6
|
|
82
|
+
yield* each.next();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
66
87
|
### Batch
|
|
67
88
|
|
|
68
89
|
The `batch` helper is useful when you want to convert individual items passing
|
|
@@ -144,6 +165,72 @@ function* example() {
|
|
|
144
165
|
}
|
|
145
166
|
```
|
|
146
167
|
|
|
168
|
+
### Drain
|
|
169
|
+
|
|
170
|
+
The `drain` helper exhausts a stream, discarding all yielded values, and returns
|
|
171
|
+
the close value. This is useful when you only care about the final result of a
|
|
172
|
+
stream, not the intermediate values.
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { drain } from "@effectionx/stream-helpers";
|
|
176
|
+
|
|
177
|
+
function* example() {
|
|
178
|
+
// Get the response from a request channel (ignoring any progress)
|
|
179
|
+
const channel = yield* transport.send(request);
|
|
180
|
+
const response = yield* drain(channel);
|
|
181
|
+
console.log(response); // The close value
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### First
|
|
186
|
+
|
|
187
|
+
The `first` helper returns the first value yielded by a stream, or `undefined`
|
|
188
|
+
if the stream closes without yielding any values. Use `first.expect()` to throw
|
|
189
|
+
an error instead of returning `undefined`.
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import { first } from "@effectionx/stream-helpers";
|
|
193
|
+
import { streamOf } from "@effectionx/stream-helpers";
|
|
194
|
+
|
|
195
|
+
function* example() {
|
|
196
|
+
const stream = streamOf([1, 2, 3]);
|
|
197
|
+
const value = yield* first(stream);
|
|
198
|
+
console.log(value); // 1
|
|
199
|
+
|
|
200
|
+
const empty = streamOf([]);
|
|
201
|
+
const none = yield* first(empty);
|
|
202
|
+
console.log(none); // undefined
|
|
203
|
+
|
|
204
|
+
// Use first.expect() to throw if stream is empty
|
|
205
|
+
const required = yield* first.expect(stream); // throws if empty
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Last
|
|
210
|
+
|
|
211
|
+
The `last` helper returns the last value yielded by a stream, or `undefined`
|
|
212
|
+
if the stream closes without yielding any values. It exhausts the entire stream
|
|
213
|
+
to find the last value. Use `last.expect()` to throw an error instead of
|
|
214
|
+
returning `undefined`.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
import { last } from "@effectionx/stream-helpers";
|
|
218
|
+
import { streamOf } from "@effectionx/stream-helpers";
|
|
219
|
+
|
|
220
|
+
function* example() {
|
|
221
|
+
const stream = streamOf([1, 2, 3]);
|
|
222
|
+
const value = yield* last(stream);
|
|
223
|
+
console.log(value); // 3
|
|
224
|
+
|
|
225
|
+
const empty = streamOf([]);
|
|
226
|
+
const none = yield* last(empty);
|
|
227
|
+
console.log(none); // undefined
|
|
228
|
+
|
|
229
|
+
// Use last.expect() to throw if stream is empty
|
|
230
|
+
const required = yield* last.expect(stream); // throws if empty
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
147
234
|
### ForEach
|
|
148
235
|
|
|
149
236
|
The `forEach` helper invokes a function for each item passing through a stream.
|
package/batch.test.ts
CHANGED
|
@@ -57,7 +57,7 @@ describe("batch", () => {
|
|
|
57
57
|
}, stream),
|
|
58
58
|
);
|
|
59
59
|
|
|
60
|
-
yield* sleep(
|
|
60
|
+
yield* sleep(0);
|
|
61
61
|
|
|
62
62
|
yield* faucet.pour(function* (send) {
|
|
63
63
|
for (let i = 1; i <= 10; i++) {
|
|
@@ -89,7 +89,7 @@ describe("batch", () => {
|
|
|
89
89
|
}, stream),
|
|
90
90
|
);
|
|
91
91
|
|
|
92
|
-
yield* sleep(
|
|
92
|
+
yield* sleep(0);
|
|
93
93
|
|
|
94
94
|
yield* faucet.pour([1, 2, 3, 4, 5, 6]);
|
|
95
95
|
|
package/dist/drain.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Operation, Stream } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* Exhausts a stream, discarding all yielded values, and returns the close value.
|
|
4
|
+
*
|
|
5
|
+
* Use this when you only care about the final result of a stream, not the
|
|
6
|
+
* intermediate values. This is common for request/response patterns where
|
|
7
|
+
* the response is the close value and there may be no progress events.
|
|
8
|
+
*
|
|
9
|
+
* @template T - The type of items in the stream (discarded)
|
|
10
|
+
* @template TClose - The type of the close value returned when the stream ends
|
|
11
|
+
* @param stream - The stream to drain
|
|
12
|
+
* @returns The close value of the stream
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { drain } from "./drain.ts";
|
|
17
|
+
*
|
|
18
|
+
* // Get the response from a request channel (ignoring any progress)
|
|
19
|
+
* const channel = yield* transport.send(request);
|
|
20
|
+
* const response = yield* drain(channel);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function drain<T, TClose>(stream: Stream<T, TClose>): Operation<TClose>;
|
|
24
|
+
//# sourceMappingURL=drain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drain.d.ts","sourceRoot":"","sources":["../drain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,CAW7E"}
|
package/dist/drain.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exhausts a stream, discarding all yielded values, and returns the close value.
|
|
3
|
+
*
|
|
4
|
+
* Use this when you only care about the final result of a stream, not the
|
|
5
|
+
* intermediate values. This is common for request/response patterns where
|
|
6
|
+
* the response is the close value and there may be no progress events.
|
|
7
|
+
*
|
|
8
|
+
* @template T - The type of items in the stream (discarded)
|
|
9
|
+
* @template TClose - The type of the close value returned when the stream ends
|
|
10
|
+
* @param stream - The stream to drain
|
|
11
|
+
* @returns The close value of the stream
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { drain } from "./drain.ts";
|
|
16
|
+
*
|
|
17
|
+
* // Get the response from a request channel (ignoring any progress)
|
|
18
|
+
* const channel = yield* transport.send(request);
|
|
19
|
+
* const response = yield* drain(channel);
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function drain(stream) {
|
|
23
|
+
return {
|
|
24
|
+
*[Symbol.iterator]() {
|
|
25
|
+
const subscription = yield* stream;
|
|
26
|
+
let result = yield* subscription.next();
|
|
27
|
+
while (!result.done) {
|
|
28
|
+
result = yield* subscription.next();
|
|
29
|
+
}
|
|
30
|
+
return result.value;
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
package/dist/first.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Operation, Stream } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the first value yielded by a stream, or `undefined` if the stream
|
|
4
|
+
* closes without yielding any values.
|
|
5
|
+
*
|
|
6
|
+
* Use `first.expect()` if you want to throw an error when the stream is empty.
|
|
7
|
+
*
|
|
8
|
+
* @template T - The type of items in the stream
|
|
9
|
+
* @template TClose - The type of the close value (unused)
|
|
10
|
+
* @param stream - The stream to get the first value from
|
|
11
|
+
* @returns The first value yielded by the stream, or `undefined` if empty
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { first } from "./first.ts";
|
|
16
|
+
*
|
|
17
|
+
* const stream = streamOf([1, 2, 3]);
|
|
18
|
+
* const value = yield* first(stream); // returns 1
|
|
19
|
+
*
|
|
20
|
+
* const empty = streamOf([]);
|
|
21
|
+
* const value = yield* first(empty); // returns undefined
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function first<T, TClose>(stream: Stream<T, TClose>): Operation<T | undefined>;
|
|
25
|
+
export declare namespace first {
|
|
26
|
+
var expect: <T, TClose>(stream: Stream<T, TClose>) => Operation<T>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=first.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"first.d.ts","sourceRoot":"","sources":["../first.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAC7B,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,GACxB,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,CAW1B;yBAbe,KAAK;iBAoCe,CAAC,EAAE,MAAM,UACnC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,KACxB,SAAS,CAAC,CAAC,CAAC"}
|
package/dist/first.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the first value yielded by a stream, or `undefined` if the stream
|
|
3
|
+
* closes without yielding any values.
|
|
4
|
+
*
|
|
5
|
+
* Use `first.expect()` if you want to throw an error when the stream is empty.
|
|
6
|
+
*
|
|
7
|
+
* @template T - The type of items in the stream
|
|
8
|
+
* @template TClose - The type of the close value (unused)
|
|
9
|
+
* @param stream - The stream to get the first value from
|
|
10
|
+
* @returns The first value yielded by the stream, or `undefined` if empty
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { first } from "./first.ts";
|
|
15
|
+
*
|
|
16
|
+
* const stream = streamOf([1, 2, 3]);
|
|
17
|
+
* const value = yield* first(stream); // returns 1
|
|
18
|
+
*
|
|
19
|
+
* const empty = streamOf([]);
|
|
20
|
+
* const value = yield* first(empty); // returns undefined
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function first(stream) {
|
|
24
|
+
return {
|
|
25
|
+
*[Symbol.iterator]() {
|
|
26
|
+
const subscription = yield* stream;
|
|
27
|
+
const result = yield* subscription.next();
|
|
28
|
+
if (result.done) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return result.value;
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Returns the first value yielded by a stream.
|
|
37
|
+
* Throws an error if the stream closes without yielding any values.
|
|
38
|
+
*
|
|
39
|
+
* @template T - The type of items in the stream
|
|
40
|
+
* @template TClose - The type of the close value (unused)
|
|
41
|
+
* @param stream - The stream to get the first value from
|
|
42
|
+
* @returns The first value yielded by the stream
|
|
43
|
+
* @throws Error if the stream closes without yielding any values
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* import { first } from "./first.ts";
|
|
48
|
+
*
|
|
49
|
+
* const stream = streamOf([1, 2, 3]);
|
|
50
|
+
* const value = yield* first.expect(stream); // returns 1
|
|
51
|
+
*
|
|
52
|
+
* const empty = streamOf([]);
|
|
53
|
+
* const value = yield* first.expect(empty); // throws Error
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
first.expect = function expectFirst(stream) {
|
|
57
|
+
return {
|
|
58
|
+
*[Symbol.iterator]() {
|
|
59
|
+
const subscription = yield* stream;
|
|
60
|
+
const result = yield* subscription.next();
|
|
61
|
+
if (result.done) {
|
|
62
|
+
throw new Error("Stream closed without yielding any values");
|
|
63
|
+
}
|
|
64
|
+
return result.value;
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
};
|
package/dist/for-each.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"for-each.d.ts","sourceRoot":"","sources":["../for-each.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,
|
|
1
|
+
{"version":3,"file":"for-each.d.ts","sourceRoot":"","sources":["../for-each.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAC/B,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC,IAAI,CAAC,EAChC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,GACxB,SAAS,CAAC,MAAM,CAAC,CAYnB"}
|
package/dist/for-each.js
CHANGED
|
@@ -22,12 +22,16 @@
|
|
|
22
22
|
* yield* stream.send(2);
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
export function
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
export function forEach(fn, stream) {
|
|
26
|
+
return {
|
|
27
|
+
*[Symbol.iterator]() {
|
|
28
|
+
let subscription = yield* stream;
|
|
29
|
+
let next = yield* subscription.next();
|
|
30
|
+
while (!next.done) {
|
|
31
|
+
yield* fn(next.value);
|
|
32
|
+
next = yield* subscription.next();
|
|
33
|
+
}
|
|
34
|
+
return next.value;
|
|
35
|
+
},
|
|
36
|
+
};
|
|
33
37
|
}
|
package/dist/last.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Operation, Stream } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the last value yielded by a stream, or `undefined` if the stream
|
|
4
|
+
* closes without yielding any values.
|
|
5
|
+
*
|
|
6
|
+
* Exhausts the entire stream to find the last value.
|
|
7
|
+
* Use `last.expect()` if you want to throw an error when the stream is empty.
|
|
8
|
+
*
|
|
9
|
+
* @template T - The type of items in the stream
|
|
10
|
+
* @template TClose - The type of the close value (unused)
|
|
11
|
+
* @param stream - The stream to get the last value from
|
|
12
|
+
* @returns The last value yielded by the stream, or `undefined` if empty
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { last } from "./last.ts";
|
|
17
|
+
*
|
|
18
|
+
* const stream = streamOf([1, 2, 3]);
|
|
19
|
+
* const value = yield* last(stream); // returns 3
|
|
20
|
+
*
|
|
21
|
+
* const empty = streamOf([]);
|
|
22
|
+
* const value = yield* last(empty); // returns undefined
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function last<T, TClose>(stream: Stream<T, TClose>): Operation<T | undefined>;
|
|
26
|
+
export declare namespace last {
|
|
27
|
+
var expect: <T, TClose>(stream: Stream<T, TClose>) => Operation<T>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=last.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"last.d.ts","sourceRoot":"","sources":["../last.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAC5B,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,GACxB,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC,CAqB1B;yBAvBe,IAAI;iBA+Cc,CAAC,EAAE,MAAM,UACjC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,KACxB,SAAS,CAAC,CAAC,CAAC"}
|
package/dist/last.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the last value yielded by a stream, or `undefined` if the stream
|
|
3
|
+
* closes without yielding any values.
|
|
4
|
+
*
|
|
5
|
+
* Exhausts the entire stream to find the last value.
|
|
6
|
+
* Use `last.expect()` if you want to throw an error when the stream is empty.
|
|
7
|
+
*
|
|
8
|
+
* @template T - The type of items in the stream
|
|
9
|
+
* @template TClose - The type of the close value (unused)
|
|
10
|
+
* @param stream - The stream to get the last value from
|
|
11
|
+
* @returns The last value yielded by the stream, or `undefined` if empty
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { last } from "./last.ts";
|
|
16
|
+
*
|
|
17
|
+
* const stream = streamOf([1, 2, 3]);
|
|
18
|
+
* const value = yield* last(stream); // returns 3
|
|
19
|
+
*
|
|
20
|
+
* const empty = streamOf([]);
|
|
21
|
+
* const value = yield* last(empty); // returns undefined
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function last(stream) {
|
|
25
|
+
return {
|
|
26
|
+
*[Symbol.iterator]() {
|
|
27
|
+
const subscription = yield* stream;
|
|
28
|
+
const first = yield* subscription.next();
|
|
29
|
+
if (first.done) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
let lastValue = first.value;
|
|
33
|
+
let result = yield* subscription.next();
|
|
34
|
+
while (!result.done) {
|
|
35
|
+
lastValue = result.value;
|
|
36
|
+
result = yield* subscription.next();
|
|
37
|
+
}
|
|
38
|
+
return lastValue;
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns the last value yielded by a stream.
|
|
44
|
+
* Exhausts the entire stream to find the last value.
|
|
45
|
+
* Throws an error if the stream closes without yielding any values.
|
|
46
|
+
*
|
|
47
|
+
* @template T - The type of items in the stream
|
|
48
|
+
* @template TClose - The type of the close value (unused)
|
|
49
|
+
* @param stream - The stream to get the last value from
|
|
50
|
+
* @returns The last value yielded by the stream
|
|
51
|
+
* @throws Error if the stream closes without yielding any values
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* import { last } from "./last.ts";
|
|
56
|
+
*
|
|
57
|
+
* const stream = streamOf([1, 2, 3]);
|
|
58
|
+
* const value = yield* last.expect(stream); // returns 3
|
|
59
|
+
*
|
|
60
|
+
* const empty = streamOf([]);
|
|
61
|
+
* const value = yield* last.expect(empty); // throws Error
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
last.expect = function expectLast(stream) {
|
|
65
|
+
return {
|
|
66
|
+
*[Symbol.iterator]() {
|
|
67
|
+
const subscription = yield* stream;
|
|
68
|
+
const first = yield* subscription.next();
|
|
69
|
+
if (first.done) {
|
|
70
|
+
throw new Error("Stream closed without yielding any values");
|
|
71
|
+
}
|
|
72
|
+
let lastValue = first.value;
|
|
73
|
+
let result = yield* subscription.next();
|
|
74
|
+
while (!result.done) {
|
|
75
|
+
lastValue = result.value;
|
|
76
|
+
result = yield* subscription.next();
|
|
77
|
+
}
|
|
78
|
+
return lastValue;
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
};
|
package/dist/mod.d.ts
CHANGED
|
@@ -6,4 +6,9 @@ export * from "./tracker.ts";
|
|
|
6
6
|
export * from "./for-each.ts";
|
|
7
7
|
export * from "./subject.ts";
|
|
8
8
|
export * from "./lines.ts";
|
|
9
|
+
export * from "./stream-of.ts";
|
|
10
|
+
export * from "./reduce.ts";
|
|
11
|
+
export * from "./drain.ts";
|
|
12
|
+
export * from "./first.ts";
|
|
13
|
+
export * from "./last.ts";
|
|
9
14
|
//# sourceMappingURL=mod.d.ts.map
|
package/dist/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../mod.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../mod.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC"}
|
package/dist/mod.js
CHANGED
|
@@ -6,3 +6,8 @@ export * from "./tracker.js";
|
|
|
6
6
|
export * from "./for-each.js";
|
|
7
7
|
export * from "./subject.js";
|
|
8
8
|
export * from "./lines.js";
|
|
9
|
+
export * from "./stream-of.js";
|
|
10
|
+
export * from "./reduce.js";
|
|
11
|
+
export * from "./drain.js";
|
|
12
|
+
export * from "./first.js";
|
|
13
|
+
export * from "./last.js";
|
package/dist/reduce.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Operation, Stream } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* Transforms a stream by taking each item and applying it to an
|
|
4
|
+
* accumulated value to produce a new accumulated value which is then
|
|
5
|
+
* passed downstream.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { reduce, streamOf } from "@effectionx/stream-helpers";
|
|
10
|
+
*
|
|
11
|
+
* const sum = reduce(function*(total: number, item: number) {
|
|
12
|
+
* return sum + number;
|
|
13
|
+
* }, 0);
|
|
14
|
+
*
|
|
15
|
+
* sum(streamOf([1,2,3])) //=> yields 1, 3, 6
|
|
16
|
+
* ```
|
|
17
|
+
*
|
|
18
|
+
* @param fn - The operation to apply a single item to the accumulated value
|
|
19
|
+
* @param initial - The first accumulated value from which all others will descend
|
|
20
|
+
* @returns A stream transformer that applies the reduction over the lifetime of the stream
|
|
21
|
+
*/
|
|
22
|
+
export declare function reduce<T, TSum>(fn: (current: TSum, item: T) => Operation<TSum>, initial: TSum): <TClose>(stream: Stream<T, TClose>) => Stream<TSum, TClose>;
|
|
23
|
+
//# sourceMappingURL=reduce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reduce.d.ts","sourceRoot":"","sources":["../reduce.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAC5B,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC,IAAI,CAAC,EAC/C,OAAO,EAAE,IAAI,GACZ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAuB7D"}
|
package/dist/reduce.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transforms a stream by taking each item and applying it to an
|
|
3
|
+
* accumulated value to produce a new accumulated value which is then
|
|
4
|
+
* passed downstream.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { reduce, streamOf } from "@effectionx/stream-helpers";
|
|
9
|
+
*
|
|
10
|
+
* const sum = reduce(function*(total: number, item: number) {
|
|
11
|
+
* return sum + number;
|
|
12
|
+
* }, 0);
|
|
13
|
+
*
|
|
14
|
+
* sum(streamOf([1,2,3])) //=> yields 1, 3, 6
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @param fn - The operation to apply a single item to the accumulated value
|
|
18
|
+
* @param initial - The first accumulated value from which all others will descend
|
|
19
|
+
* @returns A stream transformer that applies the reduction over the lifetime of the stream
|
|
20
|
+
*/
|
|
21
|
+
export function reduce(fn, initial) {
|
|
22
|
+
return (upstream) => ({
|
|
23
|
+
*[Symbol.iterator]() {
|
|
24
|
+
let current = initial;
|
|
25
|
+
let subscription = yield* upstream;
|
|
26
|
+
return {
|
|
27
|
+
*next() {
|
|
28
|
+
let next = yield* subscription.next();
|
|
29
|
+
while (!next.done) {
|
|
30
|
+
let reduction = yield* fn(current, next.value);
|
|
31
|
+
if (reduction !== current) {
|
|
32
|
+
current = reduction;
|
|
33
|
+
return { done: false, value: current };
|
|
34
|
+
}
|
|
35
|
+
next = yield* subscription.next();
|
|
36
|
+
}
|
|
37
|
+
return next;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Stream } from "effection";
|
|
2
|
+
/**
|
|
3
|
+
* Lift a synchronous iterable into a stream context.
|
|
4
|
+
*
|
|
5
|
+
* @param iterable - synchronous iterable to present as an Effection `Stream`
|
|
6
|
+
* @returns a stream that yields the members of the iterable.
|
|
7
|
+
*/
|
|
8
|
+
export declare function streamOf<T, TDone>(iterable: Iterable<T, TDone>): Stream<T, TDone>;
|
|
9
|
+
//# sourceMappingURL=stream-of.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-of.d.ts","sourceRoot":"","sources":["../stream-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAC/B,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,GAC3B,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAWlB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lift a synchronous iterable into a stream context.
|
|
3
|
+
*
|
|
4
|
+
* @param iterable - synchronous iterable to present as an Effection `Stream`
|
|
5
|
+
* @returns a stream that yields the members of the iterable.
|
|
6
|
+
*/
|
|
7
|
+
export function streamOf(iterable) {
|
|
8
|
+
return {
|
|
9
|
+
*[Symbol.iterator]() {
|
|
10
|
+
let iterator = iterable[Symbol.iterator]();
|
|
11
|
+
return {
|
|
12
|
+
*next() {
|
|
13
|
+
return iterator.next();
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"faucet.d.ts","sourceRoot":"","sources":["../../test-helpers/faucet.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"faucet.d.ts","sourceRoot":"","sources":["../../test-helpers/faucet.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,MAAM,EAAiB,MAAM,WAAW,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC,CAAE,SAAQ,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC;IACjD;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAClC;;;OAGG;IACH,IAAI,CACF,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,IAAI,CAAC,GAC1D,SAAS,CAAC,IAAI,CAAC,CAAC;IACnB;;OAEG;IACH,IAAI,IAAI,IAAI,CAAC;IACb;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CA8BzE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createChannel } from "effection";
|
|
2
1
|
import { createBooleanSignal, is } from "@effectionx/signals";
|
|
2
|
+
import { createChannel } from "effection";
|
|
3
3
|
/**
|
|
4
4
|
* Creates a stream that can be used to test the behavior of streams that use backpressure.
|
|
5
5
|
* It's useful in tests where it can be used as a source stream. This function is used to create
|
|
@@ -43,30 +43,34 @@ import { createBooleanSignal, is } from "@effectionx/signals";
|
|
|
43
43
|
* @param options.open - Whether the faucet is open.
|
|
44
44
|
* @returns stream of items coming from the faucet
|
|
45
45
|
*/
|
|
46
|
-
export function
|
|
47
|
-
let signal = createChannel();
|
|
48
|
-
let open = yield* createBooleanSignal(options.open);
|
|
46
|
+
export function useFaucet(options) {
|
|
49
47
|
return {
|
|
50
|
-
[Symbol.iterator]
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
48
|
+
*[Symbol.iterator]() {
|
|
49
|
+
let signal = createChannel();
|
|
50
|
+
let open = yield* createBooleanSignal(options.open);
|
|
51
|
+
return {
|
|
52
|
+
[Symbol.iterator]: signal[Symbol.iterator],
|
|
53
|
+
*pour(items) {
|
|
54
|
+
if (Array.isArray(items)) {
|
|
55
|
+
for (let i of items) {
|
|
56
|
+
yield* is(open, (open) => open);
|
|
57
|
+
yield* signal.send(i);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
yield* items(function* (item) {
|
|
62
|
+
yield* is(open, (open) => open);
|
|
63
|
+
yield* signal.send(item);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
close() {
|
|
68
|
+
open.set(false);
|
|
69
|
+
},
|
|
70
|
+
open() {
|
|
71
|
+
open.set(true);
|
|
72
|
+
},
|
|
73
|
+
};
|
|
70
74
|
},
|
|
71
75
|
};
|
|
72
76
|
}
|