UNPKG

@effect-ts/system

Version:

Effect-TS is a zero dependency set of libraries to write highly productive, purely functional TypeScript at scale.

96 lines (91 loc) 3.29 kB
// ets_tracing: off import * as CK from "../../../../Collections/Immutable/Chunk/index.js" import * as HM from "../../../../Collections/Immutable/HashMap/index.js" import * as L from "../../../../Collections/Immutable/List/index.js" import * as Tp from "../../../../Collections/Immutable/Tuple/index.js" import * as T from "../../../../Effect/index.js" import type * as Ex from "../../../../Exit/index.js" import type { Predicate } from "../../../../Function/index.js" import { pipe } from "../../../../Function/index.js" import * as M from "../../../../Managed/index.js" import type * as O from "../../../../Option/index.js" import * as P from "../../../../Promise/index.js" import type * as Q from "../../../../Queue/index.js" import type * as C from "../core.js" import * as DistributedWithDynamic from "./distributedWithDynamic.js" /** * More powerful version of `Stream#broadcast`. Allows to provide a function that determines what * queues should receive which elements. The decide function will receive the indices of the queues * in the resulting list. */ export function distributedWith_<R, E, A>( self: C.Stream<R, E, A>, n: number, maximumLag: number, decide: (a: A) => T.UIO<Predicate<number>> ): M.RIO<R, L.List<Q.Dequeue<Ex.Exit<O.Option<E>, A>>>> { return M.chain_( T.toManaged(P.make<never, (a: A) => T.UIO<Predicate<number>>>()), (prom) => { return M.chain_( DistributedWithDynamic.distributedWithDynamic_( self, maximumLag, (a: A) => T.chain_(P.await(prom), (_) => _(a)), (_) => T.unit ), (next) => pipe( T.collectAll( CK.map_(CK.range(0, n - 1), (id) => T.map_(next, ({ tuple: [key, queue] }) => Tp.tuple(Tp.tuple(key, id), queue) ) ) ), T.chain((entries) => { const { tuple: [mappings, queues] } = CK.reduceRight_( entries, Tp.tuple( HM.make<number, number>(), L.empty<Q.Dequeue<Ex.Exit<O.Option<E>, A>>>() ), ({ tuple: [mapping, queue] }, { tuple: [mappings, queues] }) => Tp.tuple( HM.set_(mappings, Tp.get_(mapping, 0), Tp.get_(mapping, 1)), L.prepend_(queues, queue) ) ) return T.as_( P.succeed_(prom, (a: A) => T.map_( decide(a), (f) => (key: number) => f(HM.unsafeGet_(mappings, key)) ) ), queues ) }), T.toManaged ) ) } ) } /** * More powerful version of `Stream#broadcast`. Allows to provide a function that determines what * queues should receive which elements. The decide function will receive the indices of the queues * in the resulting list. * * @ets_data_first distributedWith_ */ export function distributedWith<A>( n: number, maximumLag: number, decide: (a: A) => T.UIO<Predicate<number>> ) { return <R, E>(self: C.Stream<R, E, A>) => distributedWith_(self, n, maximumLag, decide) }