// ets_tracing: off import * as CK from "../../../Collections/Immutable/Chunk/index.js" import * as AR from "../../../Support/AtomicReference/index.js" import * as CH from "../Channel/index.js" import * as C from "./core.js" export function foldSink_< R, R1, R2, InErr, InErr1, InErr2, In, In1 extends In, In2 extends In, OutErr, OutErr2, OutErr3, L, L1 extends L, L2 extends L, Z, Z1, Z2 >( self: C.Sink, failure: (err: OutErr) => C.Sink, success: (z: Z) => C.Sink ): C.Sink< R & R1 & R2, InErr & InErr1 & InErr2, In1 & In2, OutErr2 | OutErr3, L1 | L2, Z1 | Z2 > { return new C.Sink( CH.foldChannel_( CH.doneCollect(self.channel), (_) => failure(_).channel, ({ tuple: [leftovers, z] }) => CH.suspend(() => { const leftoversRef = new AR.AtomicReference( CK.filter_(leftovers, (a): a is CK.Chunk => !CK.isEmpty(a)) ) const refReader = CH.chain_( CH.succeedWith(() => leftoversRef.getAndSet(CK.empty())), (chunk) => CH.writeChunk(chunk as unknown as CK.Chunk>) ) const passthrough = CH.identity, unknown>() const continationSink = CH.zipRight_(refReader, passthrough)[">>>"]( success(z).channel ) return CH.chain_( CH.doneCollect(continationSink), ({ tuple: [newLeftovers, z1] }) => CH.zipRight_( CH.chain_( CH.succeedWith(() => leftoversRef.get), (_) => CH.writeChunk(_) ), CH.as_(CH.writeChunk(newLeftovers), z1) ) ) }) ) ) } /** * * @ets_data_first foldSink_ */ export function foldSink< R1, R2, InErr1, InErr2, In, In1 extends In, In2 extends In, OutErr, OutErr2, OutErr3, L, L1 extends L, L2 extends L, Z, Z1, Z2 >( failure: (err: OutErr) => C.Sink, success: (z: Z) => C.Sink ) { return (self: C.Sink) => foldSink_(self, failure, success) }