UNPKG

@effect-ts/system

Version:

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

551 lines (508 loc) 12.7 kB
// ets_tracing: off import "../../../../Operator/index.js" import type * as Cause from "../../../../Cause/index.js" import type * as T from "../../../../Effect/index.js" import type * as Exit from "../../../../Exit/index.js" import type { AsyncInputProducer } from "./producer.js" import { _Env, _InDone, _InElem, _InErr, _OutDone, _OutDone2, _OutElem, _OutErr, _OutErr2 } from "./symbols.js" /** * A `Channel` is a nexus of I/O operations, which supports both reading and writing. * A channel may read values of type `InElem` and write values of type `OutElem`. * When the channel finishes, it yields a value of type `OutDone`. A channel may fail with * a value of type `OutErr`. * * Channels are the foundation of Streams: both streams and sinks are built on channels. * Most users shouldn't have to use channels directly, as streams and sinks are much more convenient * and cover all common use cases. However, when adding new stream and sink operators, or doing * something highly specialized, it may be useful to use channels directly. * * Channels compose in a variety of ways: * * - Piping. One channel can be piped to another channel, assuming the input type of the second * is the same as the output type of the first. * - Sequencing. The terminal value of one channel can be used to create another channel, and * both the first channel and the function that makes the second channel can be composed into a * channel. * - Concating. The output of one channel can be used to create other channels, which are all * concatenated together. The first channel and the function that makes the other channels can * be composed into a channel. */ export abstract class Channel<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone> { readonly [_Env]!: (_: Env) => void; readonly [_InErr]!: (_: InErr) => void; readonly [_InElem]!: (_: InElem) => void; readonly [_InDone]!: (_: InDone) => void; readonly [_OutErr]!: () => OutErr; readonly [_OutElem]!: () => OutElem; readonly [_OutDone]!: () => OutDone; readonly [">>>"] = <Env2, OutErr2, OutElem2, OutDone2>( that: Channel<Env2, OutErr, OutElem, OutDone, OutErr2, OutElem2, OutDone2> ): Channel<Env & Env2, InErr, InElem, InDone, OutErr2, OutElem2, OutDone2> => new PipeTo< Env & Env2, InErr, InElem, InDone, OutErr2, OutElem2, OutDone2, OutErr, OutElem, OutDone >( () => this, () => that ) } export abstract class Continuation< Env, InErr, InElem, InDone, OutErr, OutErr2, OutElem, OutDone, OutDone2 > { readonly [_Env]!: (_: Env) => void; readonly [_InErr]!: (_: InErr) => void; readonly [_InElem]!: (_: InElem) => void; readonly [_InDone]!: (_: InDone) => void; readonly [_OutErr]!: (_: OutErr) => OutErr; readonly [_OutDone]!: (_: OutDone) => OutDone; readonly [_OutErr2]!: () => OutErr2; readonly [_OutElem]!: () => OutElem; readonly [_OutDone2]!: () => OutDone2 } /** * @ets_optimize remove */ export function concreteContinuation< Env, InErr, InElem, InDone, OutErr, OutErr2, OutElem, OutDone, OutDone2 >( _: Continuation< Env, InErr, InElem, InDone, OutErr, OutErr2, OutElem, OutDone, OutDone2 > ): asserts _ is | ContinuationK< Env, InErr, InElem, InDone, OutErr, OutErr2, OutElem, OutDone, OutDone2 > | ContinuationFinalizer<Env, OutErr, OutDone> { // } export const ContinuationKTypeId = Symbol() export type ContinuationKTypeId = typeof ContinuationKTypeId export class ContinuationK< Env, InErr, InElem, InDone, OutErr, OutErr2, OutElem, OutDone, OutDone2 > extends Continuation< Env, InErr, InElem, InDone, OutErr, OutErr2, OutElem, OutDone, OutDone2 > { readonly _typeId: ContinuationKTypeId = ContinuationKTypeId constructor( readonly onSuccess: ( o: OutDone ) => Channel<Env, InErr, InElem, InDone, OutErr2, OutElem, OutDone2>, readonly onHalt: ( c: Cause.Cause<OutErr> ) => Channel<Env, InErr, InElem, InDone, OutErr2, OutElem, OutDone2> ) { super() } onExit(exit: Exit.Exit<OutErr, OutDone>) { switch (exit._tag) { case "Failure": { return this.onHalt(exit.cause) } case "Success": { return this.onSuccess(exit.value) } } } } export const ContinuationFinalizerTypeId = Symbol() export type ContinuationFinalizerTypeId = typeof ContinuationFinalizerTypeId export class ContinuationFinalizer<Env, OutErr, OutDone> extends Continuation< Env, unknown, unknown, unknown, OutErr, never, never, OutDone, never > { readonly _typeId: ContinuationFinalizerTypeId = ContinuationFinalizerTypeId constructor( readonly finalizer: (e: Exit.Exit<OutErr, OutDone>) => T.RIO<Env, unknown> ) { super() } } /** * @ets_optimize remove */ export function concrete<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone>( _: Channel<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone> ): asserts _ is | PipeTo<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone, any, any, any> | Read<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone, any, any> | Done<OutDone> | Halt<OutErr> | Effect<Env, OutErr, OutDone> | Emit<OutElem, OutDone> | ConcatAll<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone, any, any, any> | Bridge<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone> | Fold<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone, any, any> | Provide<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone> | BracketOut<Env, OutErr, OutElem, OutDone> | Ensuring<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone> | EffectTotal<OutDone> | EffectSuspendTotal<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone> { // } export const PipeToTypeId: unique symbol = Symbol() export type PipeToTypeId = typeof PipeToTypeId export class PipeTo< Env, InErr, InElem, InDone, OutErr2, OutElem2, OutDone2, OutErr, OutElem, OutDone > extends Channel<Env, InErr, InElem, InDone, OutErr2, OutElem2, OutDone2> { readonly _typeId: PipeToTypeId = PipeToTypeId constructor( readonly left: () => Channel<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone>, readonly right: () => Channel< Env, OutErr, OutElem, OutDone, OutErr2, OutElem2, OutDone2 > ) { super() } } export const ReadTypeId: unique symbol = Symbol() export type ReadTypeId = typeof ReadTypeId export class Read< Env, InErr, InElem, InDone, OutErr2, OutElem, OutDone2, OutErr, OutDone > extends Channel<Env, InErr, InElem, InDone, OutErr2, OutElem, OutDone2> { readonly _typeId: ReadTypeId = ReadTypeId constructor( readonly more: ( i: InElem ) => Channel<Env, InErr, InElem, InDone, OutErr2, OutElem, OutDone2>, readonly done: ContinuationK< Env, InErr, InElem, InDone, OutErr, OutErr2, OutElem, OutDone, OutDone2 > ) { super() } } export const DoneTypeId: unique symbol = Symbol() export type DoneTypeId = typeof DoneTypeId export class Done<OutDone> extends Channel< unknown, unknown, unknown, unknown, never, never, OutDone > { readonly _typeId: DoneTypeId = DoneTypeId constructor(readonly terminal: () => OutDone) { super() } } export const HaltTypeId: unique symbol = Symbol() export type HaltTypeId = typeof HaltTypeId export class Halt<OutErr> extends Channel< unknown, unknown, unknown, unknown, OutErr, never, never > { readonly _typeId: HaltTypeId = HaltTypeId constructor(readonly error: () => Cause.Cause<OutErr>) { super() } } export const EffectTypeId: unique symbol = Symbol() export type EffectTypeId = typeof EffectTypeId export class Effect<Env, OutErr, OutDone> extends Channel< Env, unknown, unknown, unknown, OutErr, never, OutDone > { readonly _typeId: EffectTypeId = EffectTypeId constructor(readonly effect: T.Effect<Env, OutErr, OutDone>) { super() } } export const EmitTypeId: unique symbol = Symbol() export type EmitTypeId = typeof EmitTypeId export class Emit<OutElem, OutDone> extends Channel< unknown, unknown, unknown, unknown, never, OutElem, OutDone > { readonly _typeId: EmitTypeId = EmitTypeId constructor(readonly out: () => OutElem) { super() } } export const EnsuringTypeId: unique symbol = Symbol() export type EnsuringTypeId = typeof EnsuringTypeId export class Ensuring< Env, InErr, InElem, InDone, OutErr, OutElem, OutDone > extends Channel<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone> { readonly _typeId: EnsuringTypeId = EnsuringTypeId constructor( readonly channel: Channel<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone>, readonly finalizer: (e: Exit.Exit<OutErr, OutDone>) => T.Effect<Env, never, unknown> ) { super() } } export const ConcatAllTypeId: unique symbol = Symbol() export type ConcatAllTypeId = typeof ConcatAllTypeId export class ConcatAll< Env, InErr, InElem, InDone, OutErr, OutElem2, OutDone3, OutElem, OutDone, OutDone2 > extends Channel<Env, InErr, InElem, InDone, OutErr, OutElem2, OutDone3> { readonly _typeId: ConcatAllTypeId = ConcatAllTypeId constructor( readonly combineInners: (o: OutDone, o1: OutDone) => OutDone, readonly combineAll: (o: OutDone, o2: OutDone2) => OutDone3, readonly value: Channel<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone2>, readonly k: ( o: OutElem ) => Channel<Env, InErr, InElem, InDone, OutErr, OutElem2, OutDone> ) { super() } } export const FoldTypeId: unique symbol = Symbol() export type FoldTypeId = typeof FoldTypeId export class Fold< Env, InErr, InElem, InDone, OutErr2, OutElem, OutDone2, OutErr, OutDone > extends Channel<Env, InErr, InElem, InDone, OutErr2, OutElem, OutDone2> { readonly _typeId: FoldTypeId = FoldTypeId constructor( readonly value: Channel<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone>, readonly k: ContinuationK< Env, InErr, InElem, InDone, OutErr, OutErr2, OutElem, OutDone, OutDone2 > ) { super() } } export const BridgeTypeId: unique symbol = Symbol() export type BridgeTypeId = typeof BridgeTypeId export class Bridge< Env, InErr, InElem, InDone, OutErr, OutElem, OutDone > extends Channel<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone> { readonly _typeId: BridgeTypeId = BridgeTypeId constructor( readonly input: AsyncInputProducer<InErr, InElem, InDone>, readonly channel: Channel<Env, unknown, unknown, unknown, OutErr, OutElem, OutDone> ) { super() } } export const BracketOutTypeId: unique symbol = Symbol() export type BracketOutTypeId = typeof BracketOutTypeId export class BracketOut<R, E, Z, OutDone> extends Channel< R, unknown, unknown, unknown, E, Z, OutDone > { readonly _typeId: BracketOutTypeId = BracketOutTypeId constructor( readonly acquire: T.Effect<R, E, Z>, readonly finalizer: (z: Z, e: Exit.Exit<unknown, unknown>) => T.RIO<R, unknown> ) { super() } } export const ProvideTypeId: unique symbol = Symbol() export type ProvideTypeId = typeof ProvideTypeId export class Provide< Env, InErr, InElem, InDone, OutErr, OutElem, OutDone > extends Channel<unknown, InErr, InElem, InDone, OutErr, OutElem, OutDone> { readonly _typeId: ProvideTypeId = ProvideTypeId constructor( readonly env: Env, readonly channel: Channel<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone> ) { super() } } export const EffectTotalTypeId: unique symbol = Symbol() export type EffectTotalTypeId = typeof EffectTotalTypeId export class EffectTotal<OutDone> extends Channel< unknown, unknown, unknown, unknown, never, never, OutDone > { readonly _typeId: EffectTotalTypeId = EffectTotalTypeId constructor(readonly effect: () => OutDone) { super() } } export const EffectSuspendTotalTypeId: unique symbol = Symbol() export type EffectSuspendTotalTypeId = typeof EffectSuspendTotalTypeId export class EffectSuspendTotal< Env, InErr, InElem, InDone, OutErr, OutElem, OutDone > extends Channel<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone> { readonly _typeId: EffectSuspendTotalTypeId = EffectSuspendTotalTypeId constructor( readonly effect: () => Channel<Env, InErr, InElem, InDone, OutErr, OutElem, OutDone> ) { super() } }