| 3777 | * @since 3.3.0 |
| 3778 | */ |
| 3779 | export const zipLatestAll = <T extends ReadonlyArray<Stream<any, any, any>>>( |
| 3780 | ...streams: T |
| 3781 | ): Stream< |
| 3782 | [T[number]] extends [never] ? never |
| 3783 | : { [K in keyof T]: T[K] extends Stream<infer A, infer _E, infer _R> ? A : never }, |
| 3784 | [T[number]] extends [never] ? never : T[number] extends Stream<infer _A, infer _E, infer _R> ? _E : never, |
| 3785 | [T[number]] extends [never] ? never : T[number] extends Stream<infer _A, infer _E, infer _R> ? _R : never |
| 3786 | > => |
| 3787 | fromChannel(Channel.suspend(() => { |
| 3788 | const latest: Array<any> = [] |
| 3789 | const emitted = new Set<number>() |
| 3790 | const readyLatch = Latch.makeUnsafe() |
| 3791 | return Channel.mergeAll( |
| 3792 | Channel.fromArray( |
| 3793 | streams.map((s, i) => |
| 3794 | s.channel.pipe( |
| 3795 | Channel.flattenArray, |
| 3796 | Channel.mapEffect((a) => { |
| 3797 | latest[i] = a |
| 3798 | if (!emitted.has(i)) { |
| 3799 | emitted.add(i) |
| 3800 | if (emitted.size < streams.length) { |
| 3801 | return readyLatch.await as Effect.Effect<undefined> |
| 3802 | } |
| 3803 | return Effect.as(readyLatch.open, Arr.of(latest.slice())) |
| 3804 | } |
| 3805 | return Effect.succeed(Arr.of(latest.slice())) |
| 3806 | }), |
| 3807 | Channel.filter(isNotUndefined) |
| 3808 | ) |
| 3809 | ) |
| 3810 | ), |
| 3811 | { |
| 3812 | concurrency: "unbounded", |
| 3813 | bufferSize: 0 |
| 3814 | } |
| 3815 | ) |
| 3816 | })) as any |
| 3817 | |
| 3818 | /** |
| 3819 | * Combines two streams by emitting each new element with the latest value from the other stream. |