veffect
Version:
powerful TypeScript validation library built on the robust foundation of Effect combining exceptional type safety, high performance, and developer experience. Taking inspiration from Effect's functional principles, VEffect delivers a balanced approach tha
996 lines (945 loc) • 27.7 kB
text/typescript
import * as Cause from "../Cause.js"
import type * as Channel from "../Channel.js"
import type * as ChildExecutorDecision from "../ChildExecutorDecision.js"
import * as Chunk from "../Chunk.js"
import type * as Context from "../Context.js"
import * as Effect from "../Effect.js"
import * as Either from "../Either.js"
import type * as Exit from "../Exit.js"
import { constVoid, dual, identity } from "../Function.js"
import type { LazyArg } from "../Function.js"
import * as Option from "../Option.js"
import { pipeArguments } from "../Pipeable.js"
import { hasProperty } from "../Predicate.js"
import type * as SingleProducerAsyncInput from "../SingleProducerAsyncInput.js"
import type * as UpstreamPullRequest from "../UpstreamPullRequest.js"
import type * as UpstreamPullStrategy from "../UpstreamPullStrategy.js"
import * as childExecutorDecision from "./channel/childExecutorDecision.js"
import type { ErasedContinuationK } from "./channel/continuation.js"
import { ContinuationKImpl } from "./channel/continuation.js"
import * as upstreamPullStrategy from "./channel/upstreamPullStrategy.js"
import * as OpCodes from "./opCodes/channel.js"
/** @internal */
const ChannelSymbolKey = "effect/Channel"
/** @internal */
export const ChannelTypeId: Channel.ChannelTypeId = Symbol.for(
ChannelSymbolKey
) as Channel.ChannelTypeId
const channelVariance = {
/* c8 ignore next */
_Env: (_: never) => _,
/* c8 ignore next */
_InErr: (_: unknown) => _,
/* c8 ignore next */
_InElem: (_: unknown) => _,
/* c8 ignore next */
_InDone: (_: unknown) => _,
/* c8 ignore next */
_OutErr: (_: never) => _,
/* c8 ignore next */
_OutElem: (_: never) => _,
/* c8 ignore next */
_OutDone: (_: never) => _
}
/** @internal */
const proto = {
[ChannelTypeId]: channelVariance,
pipe() {
return pipeArguments(this, arguments)
}
}
/** @internal */
type ErasedChannel = Channel.Channel<never, unknown, never, unknown, never, unknown>
/** @internal */
export type Op<Tag extends string, Body = {}> =
& ErasedChannel
& Body
& { readonly _tag: Tag }
export type Primitive =
| BracketOut
| Bridge
| ConcatAll
| Emit
| Ensuring
| Fail
| Fold
| FromEffect
| PipeTo
| Provide
| Read
| Succeed
| SucceedNow
| Suspend
/** @internal */
export interface BracketOut extends
Op<OpCodes.OP_BRACKET_OUT, {
acquire(): Effect.Effect<unknown, unknown, unknown>
finalizer(resource: unknown, exit: Exit.Exit<unknown, unknown>): Effect.Effect<unknown, unknown, unknown>
}>
{}
/** @internal */
export interface Bridge extends
Op<OpCodes.OP_BRIDGE, {
readonly input: SingleProducerAsyncInput.AsyncInputProducer<unknown, unknown, unknown>
readonly channel: ErasedChannel
}>
{}
/** @internal */
export interface ConcatAll extends
Op<OpCodes.OP_CONCAT_ALL, {
combineInners(outDone: unknown, outDone2: unknown): unknown
combineAll(outDone: unknown, outDone2: unknown): unknown
onPull(
request: UpstreamPullRequest.UpstreamPullRequest<unknown>
): UpstreamPullStrategy.UpstreamPullStrategy<unknown>
onEmit(outElem: unknown): ChildExecutorDecision.ChildExecutorDecision
value(): ErasedChannel
k(outElem: unknown): ErasedChannel
}>
{}
/** @internal */
export interface Emit extends
Op<OpCodes.OP_EMIT, {
readonly out: unknown
}>
{}
/** @internal */
export interface Ensuring extends
Op<OpCodes.OP_ENSURING, {
readonly channel: ErasedChannel
finalizer(exit: Exit.Exit<unknown, unknown>): Effect.Effect<unknown, unknown, unknown>
}>
{}
/** @internal */
export interface Fail extends
Op<OpCodes.OP_FAIL, {
error(): Cause.Cause<unknown>
}>
{}
/** @internal */
export interface Fold extends
Op<OpCodes.OP_FOLD, {
readonly channel: ErasedChannel
readonly k: ErasedContinuationK
}>
{}
/** @internal */
export interface FromEffect extends
Op<OpCodes.OP_FROM_EFFECT, {
effect(): Effect.Effect<unknown, unknown, unknown>
}>
{}
/** @internal */
export interface PipeTo extends
Op<OpCodes.OP_PIPE_TO, {
left(): ErasedChannel
right(): ErasedChannel
}>
{}
/** @internal */
export interface Provide extends
Op<OpCodes.OP_PROVIDE, {
context(): Context.Context<unknown>
readonly inner: ErasedChannel
}>
{}
/** @internal */
export interface Read extends
Op<OpCodes.OP_READ, {
more(input: unknown): ErasedChannel
readonly done: ErasedContinuationK
}>
{}
/** @internal */
export interface Succeed extends
Op<OpCodes.OP_SUCCEED, {
evaluate(): unknown
}>
{}
/** @internal */
export interface SucceedNow extends
Op<OpCodes.OP_SUCCEED_NOW, {
readonly terminal: unknown
}>
{}
/** @internal */
export interface Suspend extends
Op<OpCodes.OP_SUSPEND, {
channel(): ErasedChannel
}>
{}
/** @internal */
export const isChannel = (u: unknown): u is Channel.Channel<
unknown,
unknown,
unknown,
unknown,
unknown,
unknown,
unknown
> => hasProperty(u, ChannelTypeId) || Effect.isEffect(u)
/** @internal */
export const acquireReleaseOut = dual<
<Z, R2>(
release: (z: Z, e: Exit.Exit<unknown, unknown>) => Effect.Effect<unknown, never, R2>
) => <E, R>(self: Effect.Effect<Z, E, R>) => Channel.Channel<Z, unknown, E, unknown, void, unknown, R | R2>,
<Z, E, R, R2>(
self: Effect.Effect<Z, E, R>,
release: (z: Z, e: Exit.Exit<unknown, unknown>) => Effect.Effect<unknown, never, R2>
) => Channel.Channel<Z, unknown, E, unknown, void, unknown, R | R2>
>(2, (self, release) => {
const op = Object.create(proto)
op._tag = OpCodes.OP_BRACKET_OUT
op.acquire = () => self
op.finalizer = release
return op
})
/** @internal */
export const catchAllCause = dual<
<OutErr, OutElem1, InElem1, OutErr1, InErr1, OutDone1, InDone1, Env1>(
f: (cause: Cause.Cause<OutErr>) => Channel.Channel<OutElem1, InElem1, OutErr1, InErr1, OutDone1, InDone1, Env1>
) => <OutElem, InElem, InErr, OutDone, InDone, Env>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
) => Channel.Channel<
OutElem1 | OutElem,
InElem & InElem1,
OutErr1,
InErr & InErr1,
OutDone1 | OutDone,
InDone & InDone1,
Env1 | Env
>,
<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env, OutElem1, InElem1, OutErr1, InErr1, OutDone1, InDone1, Env1>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
f: (cause: Cause.Cause<OutErr>) => Channel.Channel<OutElem1, InElem1, OutErr1, InErr1, OutDone1, InDone1, Env1>
) => Channel.Channel<
OutElem1 | OutElem,
InElem & InElem1,
OutErr1,
InErr & InErr1,
OutDone1 | OutDone,
InDone & InDone1,
Env1 | Env
>
>(
2,
<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env, OutElem1, InElem1, OutErr1, InErr1, OutDone1, InDone1, Env1>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
f: (cause: Cause.Cause<OutErr>) => Channel.Channel<OutElem1, InElem1, OutErr1, InErr1, OutDone1, InDone1, Env1>
): Channel.Channel<
OutElem | OutElem1,
InElem & InElem1,
OutErr1,
InErr & InErr1,
OutDone | OutDone1,
InDone & InDone1,
Env | Env1
> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_FOLD
op.channel = self
op.k = new ContinuationKImpl(succeed, f)
return op
}
)
/** @internal */
export const collectElements = <Env, InErr, InElem, InDone, OutErr, OutElem, OutDone>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
): Channel.Channel<never, InElem, OutErr, InErr, [Chunk.Chunk<OutElem>, OutDone], InDone, Env> => {
return suspend(() => {
const builder: Array<OutElem> = []
return flatMap(
pipeTo(self, collectElementsReader(builder)),
(value) => sync(() => [Chunk.fromIterable(builder), value])
)
})
}
/** @internal */
const collectElementsReader = <OutErr, OutElem, OutDone>(
builder: Array<OutElem>
): Channel.Channel<never, OutElem, OutErr, OutErr, OutDone, OutDone> =>
readWith({
onInput: (outElem) =>
flatMap(
sync(() => {
builder.push(outElem)
}),
() => collectElementsReader<OutErr, OutElem, OutDone>(builder)
),
onFailure: fail,
onDone: succeedNow
})
/** @internal */
export const concatAll = <OutElem, InElem, OutErr, InErr, InDone, Env>(
channels: Channel.Channel<
Channel.Channel<OutElem, InElem, OutErr, InErr, any, InDone, Env>,
InElem,
OutErr,
InErr,
any,
InDone,
Env
>
): Channel.Channel<OutElem, InElem, OutErr, InErr, any, InDone, Env> => concatAllWith(channels, constVoid, constVoid)
/** @internal */
export const concatAllWith = <
OutElem,
InElem2,
OutErr2,
InErr2,
OutDone,
InDone2,
Env2,
InElem,
OutErr,
InErr,
OutDone2,
InDone,
Env,
OutDone3
>(
channels: Channel.Channel<
Channel.Channel<OutElem, InElem2, OutErr2, InErr2, OutDone, InDone2, Env2>,
InElem,
OutErr,
InErr,
OutDone2,
InDone,
Env
>,
f: (o: OutDone, o1: OutDone) => OutDone,
g: (o: OutDone, o2: OutDone2) => OutDone3
): Channel.Channel<
OutElem,
InElem & InElem2,
OutErr | OutErr2,
InErr & InErr2,
OutDone3,
InDone & InDone2,
Env | Env2
> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_CONCAT_ALL
op.combineInners = f
op.combineAll = g
op.onPull = () => upstreamPullStrategy.PullAfterNext(Option.none())
op.onEmit = () => childExecutorDecision.Continue
op.value = () => channels
op.k = identity
return op
}
/** @internal */
export const concatMapWith = dual<
<OutElem, OutElem2, InElem2, OutErr2, InErr2, OutDone, InDone2, Env2, OutDone2, OutDone3>(
f: (o: OutElem) => Channel.Channel<OutElem2, InElem2, OutErr2, InErr2, OutDone, InDone2, Env2>,
g: (o: OutDone, o1: OutDone) => OutDone,
h: (o: OutDone, o2: OutDone2) => OutDone3
) => <Env, InErr, InElem, InDone, OutErr>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone2, InDone, Env>
) => Channel.Channel<
OutElem2,
InElem & InElem2,
OutErr2 | OutErr,
InErr & InErr2,
OutDone3,
InDone & InDone2,
Env2 | Env
>,
<
OutElem,
InElem,
OutErr,
InErr,
OutDone2,
InDone,
Env,
OutElem2,
InElem2,
OutErr2,
InErr2,
OutDone,
InDone2,
Env2,
OutDone3
>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone2, InDone, Env>,
f: (o: OutElem) => Channel.Channel<OutElem2, InElem2, OutErr2, InErr2, OutDone, InDone2, Env2>,
g: (o: OutDone, o1: OutDone) => OutDone,
h: (o: OutDone, o2: OutDone2) => OutDone3
) => Channel.Channel<
OutElem2,
InElem & InElem2,
OutErr2 | OutErr,
InErr & InErr2,
OutDone3,
InDone & InDone2,
Env2 | Env
>
>(4, <
Env,
InErr,
InElem,
InDone,
OutErr,
OutElem,
OutElem2,
OutDone,
OutDone2,
OutDone3,
Env2,
InErr2,
InElem2,
InDone2,
OutErr2
>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone2, InDone, Env>,
f: (
o: OutElem
) => Channel.Channel<OutElem2, InElem2, OutErr2, InErr2, OutDone, InDone2, Env2>,
g: (o: OutDone, o1: OutDone) => OutDone,
h: (o: OutDone, o2: OutDone2) => OutDone3
): Channel.Channel<
OutElem2,
InElem & InElem2,
OutErr | OutErr2,
InErr & InErr2,
OutDone3,
InDone & InDone2,
Env | Env2
> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_CONCAT_ALL
op.combineInners = g
op.combineAll = h
op.onPull = () => upstreamPullStrategy.PullAfterNext(Option.none())
op.onEmit = () => childExecutorDecision.Continue
op.value = () => self
op.k = f
return op
})
/** @internal */
export const concatMapWithCustom = dual<
<OutElem, OutElem2, InElem2, OutErr2, InErr2, OutDone, InDone2, Env2, OutDone2, OutDone3>(
f: (o: OutElem) => Channel.Channel<OutElem2, InElem2, OutErr2, InErr2, OutDone, InDone2, Env2>,
g: (o: OutDone, o1: OutDone) => OutDone,
h: (o: OutDone, o2: OutDone2) => OutDone3,
onPull: (
upstreamPullRequest: UpstreamPullRequest.UpstreamPullRequest<OutElem>
) => UpstreamPullStrategy.UpstreamPullStrategy<OutElem2>,
onEmit: (elem: OutElem2) => ChildExecutorDecision.ChildExecutorDecision
) => <Env, InErr, InElem, InDone, OutErr>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone2, InDone, Env>
) => Channel.Channel<
OutElem2,
InElem & InElem2,
OutErr2 | OutErr,
InErr & InErr2,
OutDone3,
InDone & InDone2,
Env2 | Env
>,
<
OutElem,
InElem,
OutErr,
InErr,
OutDone2,
InDone,
Env,
OutElem2,
InElem2,
OutErr2,
InErr2,
OutDone,
InDone2,
Env2,
OutDone3
>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone2, InDone, Env>,
f: (o: OutElem) => Channel.Channel<OutElem2, InElem2, OutErr2, InErr2, OutDone, InDone2, Env2>,
g: (o: OutDone, o1: OutDone) => OutDone,
h: (o: OutDone, o2: OutDone2) => OutDone3,
onPull: (
upstreamPullRequest: UpstreamPullRequest.UpstreamPullRequest<OutElem>
) => UpstreamPullStrategy.UpstreamPullStrategy<OutElem2>,
onEmit: (elem: OutElem2) => ChildExecutorDecision.ChildExecutorDecision
) => Channel.Channel<
OutElem2,
InElem & InElem2,
OutErr2 | OutErr,
InErr & InErr2,
OutDone3,
InDone & InDone2,
Env2 | Env
>
>(6, <
Env,
InErr,
InElem,
InDone,
OutErr,
OutElem,
OutElem2,
OutDone,
OutDone2,
OutDone3,
Env2,
InErr2,
InElem2,
InDone2,
OutErr2
>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone2, InDone, Env>,
f: (
o: OutElem
) => Channel.Channel<OutElem2, InElem2, OutErr2, InErr2, OutDone, InDone2, Env2>,
g: (o: OutDone, o1: OutDone) => OutDone,
h: (o: OutDone, o2: OutDone2) => OutDone3,
onPull: (
upstreamPullRequest: UpstreamPullRequest.UpstreamPullRequest<OutElem>
) => UpstreamPullStrategy.UpstreamPullStrategy<OutElem2>,
onEmit: (elem: OutElem2) => ChildExecutorDecision.ChildExecutorDecision
): Channel.Channel<
OutElem2,
InElem & InElem2,
OutErr | OutErr2,
InErr & InErr2,
OutDone3,
InDone & InDone2,
Env | Env2
> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_CONCAT_ALL
op.combineInners = g
op.combineAll = h
op.onPull = onPull
op.onEmit = onEmit
op.value = () => self
op.k = f
return op
})
/** @internal */
export const embedInput = dual<
<InErr, InElem, InDone>(
input: SingleProducerAsyncInput.AsyncInputProducer<InErr, InElem, InDone>
) => <OutElem, OutErr, OutDone, Env>(
self: Channel.Channel<OutElem, unknown, OutErr, unknown, OutDone, unknown, Env>
) => Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
<OutElem, OutErr, OutDone, Env, InErr, InElem, InDone>(
self: Channel.Channel<OutElem, unknown, OutErr, unknown, OutDone, unknown, Env>,
input: SingleProducerAsyncInput.AsyncInputProducer<InErr, InElem, InDone>
) => Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
>(
2,
<OutElem, OutErr, OutDone, Env, InErr, InElem, InDone>(
self: Channel.Channel<OutElem, unknown, OutErr, unknown, OutDone, unknown, Env>,
input: SingleProducerAsyncInput.AsyncInputProducer<InErr, InElem, InDone>
): Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_BRIDGE
op.input = input
op.channel = self
return op
}
)
/** @internal */
export const ensuringWith = dual<
<OutDone, OutErr, Env2>(
finalizer: (e: Exit.Exit<OutDone, OutErr>) => Effect.Effect<unknown, never, Env2>
) => <OutElem, InElem, InErr, InDone, Env>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
) => Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env2 | Env>,
<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env, Env2>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
finalizer: (e: Exit.Exit<OutDone, OutErr>) => Effect.Effect<unknown, never, Env2>
) => Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env2 | Env>
>(
2,
<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env, Env2>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
finalizer: (e: Exit.Exit<OutDone, OutErr>) => Effect.Effect<unknown, never, Env2>
): Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env | Env2> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_ENSURING
op.channel = self
op.finalizer = finalizer
return op
}
)
/** @internal */
export const fail = <E>(error: E): Channel.Channel<never, unknown, E, unknown, never, unknown> =>
failCause(Cause.fail(error))
/** @internal */
export const failSync = <E>(
evaluate: LazyArg<E>
): Channel.Channel<never, unknown, E, unknown, never, unknown> => failCauseSync(() => Cause.fail(evaluate()))
/** @internal */
export const failCause = <E>(
cause: Cause.Cause<E>
): Channel.Channel<never, unknown, E, unknown, never, unknown> => failCauseSync(() => cause)
/** @internal */
export const failCauseSync = <E>(
evaluate: LazyArg<Cause.Cause<E>>
): Channel.Channel<never, unknown, E, unknown, never, unknown> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_FAIL
op.error = evaluate
return op
}
/** @internal */
export const flatMap = dual<
<OutDone, OutElem1, InElem1, OutErr1, InErr1, OutDone2, InDone1, Env1>(
f: (d: OutDone) => Channel.Channel<OutElem1, InElem1, OutErr1, InErr1, OutDone2, InDone1, Env1>
) => <OutElem, InElem, OutErr, InErr, InDone, Env>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
) => Channel.Channel<
OutElem1 | OutElem,
InElem & InElem1,
OutErr1 | OutErr,
InErr & InErr1,
OutDone2,
InDone & InDone1,
Env1 | Env
>,
<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env, OutElem1, InElem1, OutErr1, InErr1, OutDone2, InDone1, Env1>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
f: (d: OutDone) => Channel.Channel<OutElem1, InElem1, OutErr1, InErr1, OutDone2, InDone1, Env1>
) => Channel.Channel<
OutElem1 | OutElem,
InElem & InElem1,
OutErr1 | OutErr,
InErr & InErr1,
OutDone2,
InDone & InDone1,
Env1 | Env
>
>(
2,
<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env, OutElem1, InElem1, OutErr1, InErr1, OutDone2, InDone1, Env1>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
f: (d: OutDone) => Channel.Channel<OutElem1, InElem1, OutErr1, InErr1, OutDone2, InDone1, Env1>
): Channel.Channel<
OutElem | OutElem1,
InElem & InElem1,
OutErr | OutErr1,
InErr & InErr1,
OutDone2,
InDone & InDone1,
Env | Env1
> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_FOLD
op.channel = self
op.k = new ContinuationKImpl(f, failCause)
return op
}
)
/** @internal */
export const foldCauseChannel = dual<
<
OutErr,
OutElem1,
InElem1,
OutErr2,
InErr1,
OutDone2,
InDone1,
Env1,
OutDone,
OutElem2,
InElem2,
OutErr3,
InErr2,
OutDone3,
InDone2,
Env2
>(
options: {
readonly onFailure: (
c: Cause.Cause<OutErr>
) => Channel.Channel<OutElem1, InElem1, OutErr2, InErr1, OutDone2, InDone1, Env1>
readonly onSuccess: (o: OutDone) => Channel.Channel<OutElem2, InElem2, OutErr3, InErr2, OutDone3, InDone2, Env2>
}
) => <Env, InErr, InElem, InDone, OutElem>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
) => Channel.Channel<
OutElem1 | OutElem2 | OutElem,
InElem & InElem1 & InElem2,
OutErr2 | OutErr3,
InErr & InErr1 & InErr2,
OutDone2 | OutDone3,
InDone & InDone1 & InDone2,
Env1 | Env2 | Env
>,
<
OutElem,
InElem,
OutErr,
InErr,
OutDone,
InDone,
Env,
OutElem1,
InElem1,
OutErr2,
InErr1,
OutDone2,
InDone1,
Env1,
OutElem2,
InElem2,
OutErr3,
InErr2,
OutDone3,
InDone2,
Env2
>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
options: {
readonly onFailure: (
c: Cause.Cause<OutErr>
) => Channel.Channel<OutElem1, InElem1, OutErr2, InErr1, OutDone2, InDone1, Env1>
readonly onSuccess: (o: OutDone) => Channel.Channel<OutElem2, InElem2, OutErr3, InErr2, OutDone3, InDone2, Env2>
}
) => Channel.Channel<
OutElem1 | OutElem2 | OutElem,
InElem & InElem1 & InElem2,
OutErr2 | OutErr3,
InErr & InErr1 & InErr2,
OutDone2 | OutDone3,
InDone & InDone1 & InDone2,
Env1 | Env2 | Env
>
>(
2,
<
OutElem,
InElem,
OutErr,
InErr,
OutDone,
InDone,
Env,
OutElem1,
InElem1,
OutErr2,
InErr1,
OutDone2,
InDone1,
Env1,
OutElem2,
InElem2,
OutErr3,
InErr2,
OutDone3,
InDone2,
Env2
>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
options: {
readonly onFailure: (
c: Cause.Cause<OutErr>
) => Channel.Channel<OutElem1, InElem1, OutErr2, InErr1, OutDone2, InDone1, Env1>
readonly onSuccess: (o: OutDone) => Channel.Channel<OutElem2, InElem2, OutErr3, InErr2, OutDone3, InDone2, Env2>
}
): Channel.Channel<
OutElem | OutElem1 | OutElem2,
InElem & InElem1 & InElem2,
OutErr2 | OutErr3,
InErr & InErr1 & InErr2,
OutDone2 | OutDone3,
InDone & InDone1 & InDone2,
Env | Env1 | Env2
> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_FOLD
op.channel = self
op.k = new ContinuationKImpl(options.onSuccess, options.onFailure as any)
return op
}
)
/** @internal */
export const fromEffect = <A, E, R>(
effect: Effect.Effect<A, E, R>
): Channel.Channel<never, unknown, E, unknown, A, unknown, R> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_FROM_EFFECT
op.effect = () => effect
return op
}
/** @internal */
export const pipeTo = dual<
<OutElem2, OutElem, OutErr2, OutErr, OutDone2, OutDone, Env2>(
that: Channel.Channel<OutElem2, OutElem, OutErr2, OutErr, OutDone2, OutDone, Env2>
) => <InElem, InErr, InDone, Env>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
) => Channel.Channel<OutElem2, InElem, OutErr2, InErr, OutDone2, InDone, Env2 | Env>,
<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env, OutElem2, OutErr2, OutDone2, Env2>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
that: Channel.Channel<OutElem2, OutElem, OutErr2, OutErr, OutDone2, OutDone, Env2>
) => Channel.Channel<OutElem2, InElem, OutErr2, InErr, OutDone2, InDone, Env2 | Env>
>(
2,
<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env, OutElem2, OutErr2, OutDone2, Env2>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
that: Channel.Channel<OutElem2, OutElem, OutErr2, OutErr, OutDone2, OutDone, Env2>
): Channel.Channel<OutElem2, InElem, OutErr2, InErr, OutDone2, InDone, Env | Env2> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_PIPE_TO
op.left = () => self
op.right = () => that
return op
}
)
/** @internal */
export const provideContext = dual<
<Env>(
env: Context.Context<Env>
) => <OutElem, InElem, OutErr, InErr, OutDone, InDone>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
) => Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone>,
<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
env: Context.Context<Env>
) => Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone>
>(
2,
<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
self: Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>,
env: Context.Context<Env>
): Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_PROVIDE
op.context = () => env
op.inner = self
return op
}
)
/** @internal */
export const readOrFail = <E, In = unknown>(
error: E
): Channel.Channel<never, In, E, unknown, In, unknown> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_READ
op.more = succeed
op.done = new ContinuationKImpl(() => fail(error), () => fail(error))
return op
}
/** @internal */
export const readWith = <
InElem,
OutElem,
OutErr,
InErr,
OutDone,
InDone,
Env,
OutElem2,
OutErr2,
OutDone2,
Env2,
OutElem3,
OutErr3,
OutDone3,
Env3
>(
options: {
readonly onInput: (input: InElem) => Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
readonly onFailure: (error: InErr) => Channel.Channel<OutElem2, InElem, OutErr2, InErr, OutDone2, InDone, Env2>
readonly onDone: (done: InDone) => Channel.Channel<OutElem3, InElem, OutErr3, InErr, OutDone3, InDone, Env3>
}
): Channel.Channel<
OutElem | OutElem2 | OutElem3,
InElem,
OutErr | OutErr2 | OutErr3,
InErr,
OutDone | OutDone2 | OutDone3,
InDone,
Env | Env2 | Env3
> =>
readWithCause({
onInput: options.onInput,
onFailure: (cause) => Either.match(Cause.failureOrCause(cause), { onLeft: options.onFailure, onRight: failCause }),
onDone: options.onDone
})
/** @internal */
export const readWithCause = <
InElem,
OutElem,
OutErr,
InErr,
OutDone,
InDone,
Env,
OutElem2,
OutErr2,
OutDone2,
Env2,
OutElem3,
OutErr3,
OutDone3,
Env3
>(
options: {
readonly onInput: (input: InElem) => Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>
readonly onFailure: (
cause: Cause.Cause<InErr>
) => Channel.Channel<OutElem2, InElem, OutErr2, InErr, OutDone2, InDone, Env2>
readonly onDone: (done: InDone) => Channel.Channel<OutElem3, InElem, OutErr3, InErr, OutDone3, InDone, Env3>
}
): Channel.Channel<
OutElem | OutElem2 | OutElem3,
InElem,
OutErr | OutErr2 | OutErr3,
InErr,
OutDone | OutDone2 | OutDone3,
InDone,
Env | Env2 | Env3
> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_READ
op.more = options.onInput
op.done = new ContinuationKImpl(options.onDone, options.onFailure as any)
return op
}
/** @internal */
export const succeed = <A>(
value: A
): Channel.Channel<never, unknown, never, unknown, A, unknown> => sync(() => value)
/** @internal */
export const succeedNow = <OutDone>(
result: OutDone
): Channel.Channel<never, unknown, never, unknown, OutDone, unknown> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_SUCCEED_NOW
op.terminal = result
return op
}
/** @internal */
export const suspend = <OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>(
evaluate: LazyArg<Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env>>
): Channel.Channel<OutElem, InElem, OutErr, InErr, OutDone, InDone, Env> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_SUSPEND
op.channel = evaluate
return op
}
export const sync = <OutDone>(
evaluate: LazyArg<OutDone>
): Channel.Channel<never, unknown, never, unknown, OutDone, unknown> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_SUCCEED
op.evaluate = evaluate
return op
}
/** @internal */
export const unit: Channel.Channel<never> = succeedNow(void 0)
/** @internal */
export const write = <OutElem>(
out: OutElem
): Channel.Channel<OutElem, unknown, never, unknown, void, unknown> => {
const op = Object.create(proto)
op._tag = OpCodes.OP_EMIT
op.out = out
return op
}