import * as Effect from "../../Effect.js" import type * as Exit from "../../Exit.js" import { hasProperty } from "../../Predicate.js" import type * as Types from "../../Types.js" import * as OpCodes from "../opCodes/channelState.js" import type { ErasedExecutor } from "./channelExecutor.js" /** @internal */ export const ChannelStateTypeId = Symbol.for("effect/ChannelState") /** @internal */ export type ChannelStateTypeId = typeof ChannelStateTypeId /** @internal */ export interface ChannelState extends ChannelState.Variance {} /** @internal */ export declare namespace ChannelState { export interface Variance { readonly [ChannelStateTypeId]: { readonly _E: Types.Covariant readonly _R: Types.Covariant } } } const channelStateVariance = { /* c8 ignore next */ _E: (_: never) => _, /* c8 ignore next */ _R: (_: never) => _ } /** @internal */ const proto = { [ChannelStateTypeId]: channelStateVariance } /** @internal */ export type Primitive = | Done | Emit | FromEffect | Read /** @internal */ export type Op = ChannelState & Body & { readonly _tag: Tag } /** @internal */ export interface Done extends Op {} /** @internal */ export interface Emit extends Op {} /** @internal */ export interface FromEffect extends Op }> {} /** @internal */ export interface Read extends Op onEffect(effect: Effect.Effect): Effect.Effect onEmit(value: unknown): Effect.Effect onDone(exit: Exit.Exit): Effect.Effect }> {} /** @internal */ export const Done = (): ChannelState => { const op = Object.create(proto) op._tag = OpCodes.OP_DONE return op } /** @internal */ export const Emit = (): ChannelState => { const op = Object.create(proto) op._tag = OpCodes.OP_EMIT return op } /** @internal */ export const fromEffect = (effect: Effect.Effect): ChannelState => { const op = Object.create(proto) op._tag = OpCodes.OP_FROM_EFFECT op.effect = effect return op } /** @internal */ export const Read = ( upstream: ErasedExecutor, onEffect: (effect: Effect.Effect) => Effect.Effect, onEmit: (value: unknown) => Effect.Effect | undefined, onDone: (exit: Exit.Exit) => Effect.Effect | undefined ): ChannelState => { const op = Object.create(proto) op._tag = OpCodes.OP_READ op.upstream = upstream op.onEffect = onEffect op.onEmit = onEmit op.onDone = onDone return op } /** @internal */ export const isChannelState = (u: unknown): u is ChannelState => hasProperty(u, ChannelStateTypeId) /** @internal */ export const isDone = (self: ChannelState): self is Done => (self as Primitive)._tag === OpCodes.OP_DONE /** @internal */ export const isEmit = (self: ChannelState): self is Emit => (self as Primitive)._tag === OpCodes.OP_EMIT /** @internal */ export const isFromEffect = (self: ChannelState): self is FromEffect => (self as Primitive)._tag === OpCodes.OP_FROM_EFFECT /** @internal */ export const isRead = (self: ChannelState): self is Read => (self as Primitive)._tag === OpCodes.OP_READ /** @internal */ export const effect = (self: ChannelState): Effect.Effect => isFromEffect(self) ? self.effect as Effect.Effect : Effect.void /** @internal */ export const effectOrUndefinedIgnored = (self: ChannelState): Effect.Effect | undefined => isFromEffect(self) ? Effect.ignore(self.effect as Effect.Effect) : undefined