@johnhenry/iteration 0.0.0 → 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.
- package/dist/async-channel.d.ts +24 -4
- package/dist/async-channel.d.ts.map +1 -1
- package/dist/async-channel.js +41 -38
- package/dist/async-channel.js.map +1 -1
- package/dist/combine.d.ts +146 -0
- package/dist/combine.d.ts.map +1 -0
- package/dist/combine.js +353 -0
- package/dist/combine.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/internal.d.ts +66 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +134 -0
- package/dist/internal.js.map +1 -0
- package/dist/iterator-tools.d.ts +13 -0
- package/dist/iterator-tools.d.ts.map +1 -1
- package/dist/iterator-tools.js +38 -18
- package/dist/iterator-tools.js.map +1 -1
- package/dist/itertools.d.ts.map +1 -1
- package/dist/itertools.js +42 -24
- package/dist/itertools.js.map +1 -1
- package/dist/tee.d.ts +24 -2
- package/dist/tee.d.ts.map +1 -1
- package/dist/tee.js +175 -2
- package/dist/tee.js.map +1 -1
- package/dist/time.d.ts +69 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/time.js +234 -0
- package/dist/time.js.map +1 -0
- package/dist/transduce.d.ts +65 -0
- package/dist/transduce.d.ts.map +1 -1
- package/dist/transduce.js +33 -1
- package/dist/transduce.js.map +1 -1
- package/dist/transducers.d.ts.map +1 -1
- package/dist/transducers.js +86 -16
- package/dist/transducers.js.map +1 -1
- package/package.json +10 -2
- package/readme.md +338 -14
- package/src/async-channel.ts +63 -47
- package/src/combine.ts +441 -0
- package/src/index.ts +2 -0
- package/src/internal.ts +164 -0
- package/src/iterator-tools.ts +48 -20
- package/src/itertools.ts +36 -23
- package/src/tee.ts +202 -2
- package/src/time.ts +262 -0
- package/src/transduce.ts +113 -1
- package/src/transducers.ts +121 -30
package/dist/async-channel.d.ts
CHANGED
|
@@ -14,6 +14,14 @@ export interface AsyncChannelOptions<T> {
|
|
|
14
14
|
limit?: number;
|
|
15
15
|
transform?: (item: T) => T | Promise<T>;
|
|
16
16
|
debug?: (...args: unknown[]) => unknown;
|
|
17
|
+
/**
|
|
18
|
+
* How an error queued by `throw()` reaches a `take()` that arrives after
|
|
19
|
+
* it (a `take()` already waiting when `throw()` is called always rejects).
|
|
20
|
+
* - `"value"` (default, the pre-0.0.1 behaviour): `take()` resolves with
|
|
21
|
+
* the `Error` object, and async iteration yields it as an item.
|
|
22
|
+
* - `"throw"`: `take()` rejects with it, so async iteration throws.
|
|
23
|
+
*/
|
|
24
|
+
errors?: "value" | "throw";
|
|
17
25
|
}
|
|
18
26
|
/**
|
|
19
27
|
* Asynchronous Channel class
|
|
@@ -25,9 +33,15 @@ export declare class AsyncChannel<T = unknown> {
|
|
|
25
33
|
cache: Array<T | typeof CHANNEL_END | Error>;
|
|
26
34
|
transform: (item: T) => T | Promise<T>;
|
|
27
35
|
debug?: (...args: unknown[]) => unknown;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
errors: "value" | "throw";
|
|
37
|
+
/**
|
|
38
|
+
* Consumers waiting in take(), served FIFO. Before 0.0.1 this was a
|
|
39
|
+
* single slot, so a second concurrent take() replaced the first, which
|
|
40
|
+
* then never resolved.
|
|
41
|
+
*/
|
|
42
|
+
private takers;
|
|
43
|
+
/** Errors queued by throw() (as opposed to Error objects put() as values). */
|
|
44
|
+
private thrown;
|
|
31
45
|
/** Producers awaiting capacity, FIFO (backpressure -- see put()). */
|
|
32
46
|
private putters;
|
|
33
47
|
/**
|
|
@@ -43,7 +57,13 @@ export declare class AsyncChannel<T = unknown> {
|
|
|
43
57
|
* @kind function
|
|
44
58
|
* @name constructor
|
|
45
59
|
*/
|
|
46
|
-
constructor({ cache, limit, transform, debug }?: AsyncChannelOptions<T>);
|
|
60
|
+
constructor({ cache, limit, transform, debug, errors, }?: AsyncChannelOptions<T>);
|
|
61
|
+
/**
|
|
62
|
+
* Hand an item that came off the cache or a producer to a take() caller:
|
|
63
|
+
* with `errors: "throw"`, an error queued by throw() rejects.
|
|
64
|
+
* @ignore
|
|
65
|
+
*/
|
|
66
|
+
private deliver;
|
|
47
67
|
/**
|
|
48
68
|
* Move waiting producers' items into the cache while there is capacity,
|
|
49
69
|
* releasing their pending put() promises (FIFO).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-channel.d.ts","sourceRoot":"","sources":["../src/async-channel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,OAAO,MAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"async-channel.d.ts","sourceRoot":"","sources":["../src/async-channel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,OAAO,MAA8B,CAAC;AAEhE,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,OAAO,WAAW,GAAG,KAAK,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACxC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IACxC;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC5B;AAQD;;;;GAIG;AACH,qBAAa,YAAY,CAAC,CAAC,GAAG,OAAO;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,CAAC,GAAG,OAAO,WAAW,GAAG,KAAK,CAAC,CAAC;IAC7C,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACvC,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IACxC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAuB;IACrC,8EAA8E;IAC9E,OAAO,CAAC,MAAM,CAAwB;IACtC,qEAAqE;IACrE,OAAO,CAAC,OAAO,CAGP;IACR;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAoC;IAEpD;;;;OAIG;gBACS,EACV,KAAU,EACV,KAAgB,EAChB,SAAuB,EACvB,KAAK,EACL,MAAgB,GACjB,GAAE,mBAAmB,CAAC,CAAC,CAAM;IAO9B;;;;OAIG;IACH,OAAO,CAAC,OAAO;IAMf;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAUpB;;;;;;;;OAQG;IACG,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BtD;;;;OAIG;IACG,IAAI,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,OAAO,WAAW,CAAC;IAqBhE;;;;OAIG;IACG,KAAK,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAa/C;;;;OAIG;IACG,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjE;;;;;OAKG;IACH,OAAO,IAAI,OAAO;IAGlB;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IAGlB;;;;OAIG;IACI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,KAAK,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC;CAStE"}
|
package/dist/async-channel.js
CHANGED
|
@@ -9,20 +9,6 @@
|
|
|
9
9
|
* @name CHANNEL_END
|
|
10
10
|
*/
|
|
11
11
|
export const CHANNEL_END = Symbol("CHANNEL_END");
|
|
12
|
-
/**
|
|
13
|
-
* Creates a promise that can be resolved/rejected outside of initial closure
|
|
14
|
-
* @kind function
|
|
15
|
-
* @name InvertedPromise
|
|
16
|
-
* @ignore
|
|
17
|
-
*/
|
|
18
|
-
const InvertedPromise = () => {
|
|
19
|
-
const out = {};
|
|
20
|
-
out.promise = new Promise((resolve, reject) => {
|
|
21
|
-
out.resolve = resolve;
|
|
22
|
-
out.reject = reject;
|
|
23
|
-
});
|
|
24
|
-
return out;
|
|
25
|
-
};
|
|
26
12
|
/**
|
|
27
13
|
* Asynchronous Channel class
|
|
28
14
|
* @kind class
|
|
@@ -33,9 +19,15 @@ export class AsyncChannel {
|
|
|
33
19
|
cache;
|
|
34
20
|
transform;
|
|
35
21
|
debug;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
22
|
+
errors;
|
|
23
|
+
/**
|
|
24
|
+
* Consumers waiting in take(), served FIFO. Before 0.0.1 this was a
|
|
25
|
+
* single slot, so a second concurrent take() replaced the first, which
|
|
26
|
+
* then never resolved.
|
|
27
|
+
*/
|
|
28
|
+
takers = [];
|
|
29
|
+
/** Errors queued by throw() (as opposed to Error objects put() as values). */
|
|
30
|
+
thrown = new WeakSet();
|
|
39
31
|
/** Producers awaiting capacity, FIFO (backpressure -- see put()). */
|
|
40
32
|
putters = [];
|
|
41
33
|
/**
|
|
@@ -51,11 +43,23 @@ export class AsyncChannel {
|
|
|
51
43
|
* @kind function
|
|
52
44
|
* @name constructor
|
|
53
45
|
*/
|
|
54
|
-
constructor({ cache = [], limit = Infinity, transform = ($) => $, debug } = {}) {
|
|
46
|
+
constructor({ cache = [], limit = Infinity, transform = ($) => $, debug, errors = "value", } = {}) {
|
|
55
47
|
this.limit = limit;
|
|
56
48
|
this.cache = cache.slice(0, limit);
|
|
57
49
|
this.transform = transform;
|
|
58
50
|
this.debug = debug;
|
|
51
|
+
this.errors = errors;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Hand an item that came off the cache or a producer to a take() caller:
|
|
55
|
+
* with `errors: "throw"`, an error queued by throw() rejects.
|
|
56
|
+
* @ignore
|
|
57
|
+
*/
|
|
58
|
+
deliver(value) {
|
|
59
|
+
if (this.errors === "throw" && value instanceof Error && this.thrown.has(value)) {
|
|
60
|
+
throw value;
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
59
63
|
}
|
|
60
64
|
/**
|
|
61
65
|
* Move waiting producers' items into the cache while there is capacity,
|
|
@@ -91,8 +95,9 @@ export class AsyncChannel {
|
|
|
91
95
|
try {
|
|
92
96
|
const value = await this.transform(item);
|
|
93
97
|
await myTurn;
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
const taker = this.takers.shift();
|
|
99
|
+
if (taker) {
|
|
100
|
+
taker.resolve(value);
|
|
96
101
|
return;
|
|
97
102
|
}
|
|
98
103
|
if (this.cache.length < this.limit) {
|
|
@@ -117,24 +122,18 @@ export class AsyncChannel {
|
|
|
117
122
|
if (this.cache.length) {
|
|
118
123
|
const value = this.cache.shift();
|
|
119
124
|
this.drainPutters();
|
|
120
|
-
return value;
|
|
125
|
+
return this.deliver(value);
|
|
121
126
|
}
|
|
122
127
|
if (this.putters.length) {
|
|
123
128
|
// limit of 0 (rendezvous) or drained cache with waiting producers:
|
|
124
129
|
// hand off directly.
|
|
125
130
|
const { value, release } = this.putters.shift();
|
|
126
131
|
release();
|
|
127
|
-
return value;
|
|
132
|
+
return this.deliver(value);
|
|
128
133
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
this.reject = reject;
|
|
133
|
-
const value = await this.promise;
|
|
134
|
-
delete this.promise;
|
|
135
|
-
delete this.resolve;
|
|
136
|
-
delete this.reject;
|
|
137
|
-
return value;
|
|
134
|
+
return new Promise((resolve, reject) => {
|
|
135
|
+
this.takers.push({ resolve, reject });
|
|
136
|
+
});
|
|
138
137
|
}
|
|
139
138
|
/**
|
|
140
139
|
* Pause Asynchronous Channel
|
|
@@ -143,8 +142,9 @@ export class AsyncChannel {
|
|
|
143
142
|
*/
|
|
144
143
|
async break(...debug) {
|
|
145
144
|
this.debug?.("break", ...debug);
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
const taker = this.takers.shift();
|
|
146
|
+
if (taker) {
|
|
147
|
+
taker.resolve(CHANNEL_END);
|
|
148
148
|
}
|
|
149
149
|
else if (this.putters.length > 0) {
|
|
150
150
|
// Keep FIFO order: the end marker must not overtake producers
|
|
@@ -162,15 +162,18 @@ export class AsyncChannel {
|
|
|
162
162
|
*/
|
|
163
163
|
async throw(message, ...debug) {
|
|
164
164
|
this.debug?.("throw", ...debug);
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
const error = new Error(message);
|
|
166
|
+
this.thrown.add(error);
|
|
167
|
+
const taker = this.takers.shift();
|
|
168
|
+
if (taker) {
|
|
169
|
+
taker.reject(error);
|
|
167
170
|
}
|
|
168
171
|
else if (this.putters.length > 0) {
|
|
169
172
|
// Keep FIFO order behind producers already waiting for capacity.
|
|
170
|
-
this.putters.push({ value:
|
|
173
|
+
this.putters.push({ value: error, release: () => { } });
|
|
171
174
|
}
|
|
172
175
|
else {
|
|
173
|
-
this.cache.push(
|
|
176
|
+
this.cache.push(error);
|
|
174
177
|
}
|
|
175
178
|
}
|
|
176
179
|
/**
|
|
@@ -180,7 +183,7 @@ export class AsyncChannel {
|
|
|
180
183
|
* Note: should this be a getter?
|
|
181
184
|
*/
|
|
182
185
|
pending() {
|
|
183
|
-
return
|
|
186
|
+
return this.takers.length > 0;
|
|
184
187
|
}
|
|
185
188
|
/**
|
|
186
189
|
* Return string representation of Asynchronous Channel
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-channel.js","sourceRoot":"","sources":["../src/async-channel.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAkB,MAAM,CAAC,aAAa,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"async-channel.js","sourceRoot":"","sources":["../src/async-channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combinators for live values and events: merge several async sources,
|
|
3
|
+
* combine their latest values, sample one by another, and conflate a fast
|
|
4
|
+
* source down to its newest value.
|
|
5
|
+
*
|
|
6
|
+
* Every combinator here:
|
|
7
|
+
* - accepts async or sync iterables as inputs;
|
|
8
|
+
* - takes an optional `{ signal }`; on abort it rejects with the signal's
|
|
9
|
+
* reason (an "AbortError" DOMException by default);
|
|
10
|
+
* - closes (`return()`) every input that has not ended when it finishes,
|
|
11
|
+
* when an input errors, when the signal aborts, and when the consumer
|
|
12
|
+
* exits early (`break`, or calling `return()` on it). An input with a
|
|
13
|
+
* `next()` still pending is closed without waiting for that `next()`.
|
|
14
|
+
*
|
|
15
|
+
* The "latest value" combinators (combineLatestAsync, withLatestFromAsync,
|
|
16
|
+
* latestAsync, sampleAsync) drain some inputs eagerly: they keep pulling
|
|
17
|
+
* from them whether or not the consumer is reading, and keep only the
|
|
18
|
+
* newest value. Like every generator in this library they start when the
|
|
19
|
+
* consumer first calls `next()`.
|
|
20
|
+
*/
|
|
21
|
+
import { type SignalOptions } from "./abort.ts";
|
|
22
|
+
import { type AnyIterable } from "./internal.ts";
|
|
23
|
+
/** The value type of an async or sync iterable. */
|
|
24
|
+
export type IteratedValue<I> = I extends AsyncIterable<infer V> ? V : I extends Iterable<infer V> ? V : never;
|
|
25
|
+
/** Inputs for combineLatestAsync / withLatestFromAsync: an array or a record of iterables. */
|
|
26
|
+
export type IterableShape = readonly AnyIterable<unknown>[] | {
|
|
27
|
+
readonly [key: string]: AnyIterable<unknown>;
|
|
28
|
+
};
|
|
29
|
+
/** A snapshot with the same shape as its inputs: each iterable replaced by its latest value. */
|
|
30
|
+
export type LatestOf<I> = {
|
|
31
|
+
-readonly [K in keyof I]: IteratedValue<I[K]>;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Merge several (async or sync) iterables into one, yielding each value as
|
|
35
|
+
* it arrives from any input. Ends when every input has ended.
|
|
36
|
+
*
|
|
37
|
+
* - Lazy: each input has at most one `next()` outstanding, and the next
|
|
38
|
+
* value is requested from an input only after its previous value has
|
|
39
|
+
* been consumed. Inputs that are ready at the same time are served in
|
|
40
|
+
* rotation, so a fast or synchronous input cannot starve the others.
|
|
41
|
+
* - An error from any input closes the others and is rethrown.
|
|
42
|
+
* - Consumer exit or abort closes every input.
|
|
43
|
+
*
|
|
44
|
+
* Pass `{ signal }` as the last argument.
|
|
45
|
+
* @kind function
|
|
46
|
+
* @name mergeAsync
|
|
47
|
+
* @example
|
|
48
|
+
* ```javascript
|
|
49
|
+
* for await (const event of mergeAsync(clicks, keys, { signal })) { ... }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function mergeAsync<T>(...inputs: Array<AnyIterable<T>>): AsyncGenerator<T>;
|
|
53
|
+
export declare function mergeAsync<T>(...args: [...inputs: Array<AnyIterable<T>>, options: SignalOptions]): AsyncGenerator<T>;
|
|
54
|
+
export interface CombineLatestOptions<I> extends SignalOptions {
|
|
55
|
+
/**
|
|
56
|
+
* Starting values for some or all inputs (same shape as the inputs), so a
|
|
57
|
+
* snapshot can be emitted before those inputs have yielded. They are not
|
|
58
|
+
* emitted on their own: the first snapshot still waits for an input to
|
|
59
|
+
* yield.
|
|
60
|
+
*/
|
|
61
|
+
initial?: Partial<LatestOf<I>>;
|
|
62
|
+
/**
|
|
63
|
+
* `"all"` (default): end once every input has ended. `"any"`: end as
|
|
64
|
+
* soon as any input ends. Either way, an input that ends without ever
|
|
65
|
+
* having a value (and no `initial` for it) ends the output at once,
|
|
66
|
+
* since no complete snapshot can ever be made.
|
|
67
|
+
*/
|
|
68
|
+
endOn?: "all" | "any";
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Combine the latest values of several inputs. `inputs` is an array or a
|
|
72
|
+
* record of (async or sync) iterables; each output is a snapshot of the
|
|
73
|
+
* same shape holding every input's latest value. A snapshot is emitted
|
|
74
|
+
* whenever an input yields, once every input has a value (from the input
|
|
75
|
+
* itself or from `initial`).
|
|
76
|
+
*
|
|
77
|
+
* Latest-wins: inputs are drained eagerly, and while the consumer is busy
|
|
78
|
+
* the snapshots that would have been emitted coalesce into one, holding
|
|
79
|
+
* the newest values. Every snapshot is a fresh object.
|
|
80
|
+
*
|
|
81
|
+
* An input error closes the others and is rethrown (a pending snapshot is
|
|
82
|
+
* dropped). Consumer exit or abort closes every input.
|
|
83
|
+
* @kind function
|
|
84
|
+
* @name combineLatestAsync
|
|
85
|
+
* @example
|
|
86
|
+
* ```javascript
|
|
87
|
+
* for await (const { x, y } of combineLatestAsync({ x: xs, y: ys })) { ... }
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export declare const combineLatestAsync: <const I extends IterableShape>(inputs: I, { signal, initial, endOn }?: CombineLatestOptions<I>) => AsyncGenerator<LatestOf<I>>;
|
|
91
|
+
/**
|
|
92
|
+
* Pair each value of `source` with the latest value of each of `others`
|
|
93
|
+
* (an array or a record of iterables): yields `[value, snapshot]`, where
|
|
94
|
+
* `snapshot` has the same shape as `others`. This is the "an event samples
|
|
95
|
+
* values" pattern.
|
|
96
|
+
*
|
|
97
|
+
* `source` is pulled lazily, as the consumer reads; `others` are drained
|
|
98
|
+
* eagerly. Source values that arrive before every one of `others` has a
|
|
99
|
+
* value are dropped. An input in `others` that ends keeps its last value.
|
|
100
|
+
* Ends when `source` ends. An error from any input closes the rest and is
|
|
101
|
+
* rethrown; consumer exit or abort closes every input.
|
|
102
|
+
* @kind function
|
|
103
|
+
* @name withLatestFromAsync
|
|
104
|
+
* @example
|
|
105
|
+
* ```javascript
|
|
106
|
+
* for await (const [click, { price }] of withLatestFromAsync(clicks, { price: prices })) { ... }
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export declare const withLatestFromAsync: <T, const I extends IterableShape>(source: AnyIterable<T>, others: I, { signal }?: SignalOptions) => AsyncGenerator<[T, LatestOf<I>]>;
|
|
110
|
+
/**
|
|
111
|
+
* Conflate a source down to its newest value. The source is drained
|
|
112
|
+
* eagerly; only the newest value not yet read is kept. Each `next()`
|
|
113
|
+
* returns that value, or waits for the next one. A value is returned at
|
|
114
|
+
* most once.
|
|
115
|
+
*
|
|
116
|
+
* Ends once the source has ended and its last value has been read. A source
|
|
117
|
+
* error is rethrown on the next read (an unread value is dropped). Closing
|
|
118
|
+
* the result, or aborting, closes the source.
|
|
119
|
+
* @kind function
|
|
120
|
+
* @name latestAsync
|
|
121
|
+
* @example
|
|
122
|
+
* ```javascript
|
|
123
|
+
* for await (const position of latestAsync(pointerMoves)) {
|
|
124
|
+
* await render(position); // never falls behind: stale positions are skipped
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export declare const latestAsync: <T>(iterable: AnyIterable<T>, { signal }?: SignalOptions) => AsyncGenerator<T>;
|
|
129
|
+
/**
|
|
130
|
+
* On each value from `trigger`, yield the latest value of `source`, if it
|
|
131
|
+
* has produced one yet. The same source value is yielded again on every
|
|
132
|
+
* trigger until the source produces a new one.
|
|
133
|
+
*
|
|
134
|
+
* `source` is drained eagerly; `trigger` is pulled lazily, as the consumer
|
|
135
|
+
* reads. Ends when `trigger` ends (a source that ends keeps its last
|
|
136
|
+
* value). An error from either closes the other and is rethrown; consumer
|
|
137
|
+
* exit or abort closes both.
|
|
138
|
+
* @kind function
|
|
139
|
+
* @name sampleAsync
|
|
140
|
+
* @example
|
|
141
|
+
* ```javascript
|
|
142
|
+
* for await (const position of sampleAsync(pointerMoves, animationFrames)) { ... }
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
export declare const sampleAsync: <T>(source: AnyIterable<T>, trigger: AnyIterable<unknown>, { signal }?: SignalOptions) => AsyncGenerator<T>;
|
|
146
|
+
//# sourceMappingURL=combine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"combine.d.ts","sourceRoot":"","sources":["../src/combine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,YAAY,CAAC;AAChE,OAAO,EACL,KAAK,WAAW,EASjB,MAAM,eAAe,CAAC;AAEvB,mDAAmD;AACnD,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,SAAS,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAE9G,8FAA8F;AAC9F,MAAM,MAAM,aAAa,GAAG,SAAS,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC;AAE/G,gGAAgG;AAChG,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IAAE,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAyD5E;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;AACnF,wBAAgB,UAAU,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;AA4CtH,MAAM,WAAW,oBAAoB,CAAC,CAAC,CAAE,SAAQ,aAAa;IAC5D;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,kBAAkB,GAAoB,KAAK,CAAC,CAAC,SAAS,aAAa,EAC9E,QAAQ,CAAC,EACT,6BAAoC,oBAAoB,CAAC,CAAC,CAAM,KAC/D,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAyD5B,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,mBAAmB,GAAoB,CAAC,EAAE,KAAK,CAAC,CAAC,SAAS,aAAa,EAClF,QAAQ,WAAW,CAAC,CAAC,CAAC,EACtB,QAAQ,CAAC,EACT,aAAY,aAAkB,KAC7B,cAAc,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAmCjC,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,WAAW,GAAoB,CAAC,EAC3C,UAAU,WAAW,CAAC,CAAC,CAAC,EACxB,aAAY,aAAkB,KAC7B,cAAc,CAAC,CAAC,CA6ClB,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,WAAW,GAAoB,CAAC,EAC3C,QAAQ,WAAW,CAAC,CAAC,CAAC,EACtB,SAAS,WAAW,CAAC,OAAO,CAAC,EAC7B,aAAY,aAAkB,KAC7B,cAAc,CAAC,CAAC,CAgClB,CAAC"}
|