@johngw/stream
Version:
Reactive programming tools using the WHATWG Streams API.
72 lines (67 loc) • 1.67 kB
text/typescript
import { Predicate } from '@johngw/stream-common/Function'
import { Flushable, pipeFlushes } from '@johngw/stream-common/Stream'
/**
* Runs every chunk through a predicate. If anything suceeds the
* predicate, `true` is queued and the stream terminated.
* Otherwise this will wait for the entire stream to finish
* before queuing `false`.
*
* @group Transformers
* @see {@link every:function}
* @example
* When every chunk failes the predicate.
* ```
* --1--2--3--4--5--6--7--8--9-|
*
* every((x) => x > 10)
*
* ----------------------------F-|
* ```
*
* When something passes the predicate.
* ```
* --1--2--3--4--5--6--X
*
* every((x) => x > 5)
*
* -----------------T--|
* ```
*
* A `flushes` stream can be used to force the transformer to queue
* it's current state downstream.
*
* ```
* --1--2--3--4--5--6--7--8--9-|
*
* some((x) => x > 10, { flushes:
* -----------N-----------------
* })
*
* -----------F----------------F-|
*/
export function some<T>(predicate: Predicate<T>, options?: Flushable) {
const abortController = new AbortController()
return new TransformStream<T, boolean>({
start(controller) {
pipeFlushes(
() => controller.enqueue(false),
(error) => controller.error(error),
{ ...options, signal: abortController.signal }
)
},
async transform(chunk, controller) {
try {
if (await predicate(chunk)) {
controller.enqueue(true)
controller.terminate()
}
} catch (error) {
controller.error(error)
}
},
flush(controller) {
controller.enqueue(false)
abortController.abort()
},
})
}