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
1,503 lines (1,390 loc) • 99.7 kB
text/typescript
import type * as Cause from "../Cause.js"
import * as Chunk from "../Chunk.js"
import * as Context from "../Context.js"
import type * as Deferred from "../Deferred.js"
import type * as Differ from "../Differ.js"
import type * as Effect from "../Effect.js"
import * as Either from "../Either.js"
import * as Equal from "../Equal.js"
import type * as ExecutionStrategy from "../ExecutionStrategy.js"
import type * as Exit from "../Exit.js"
import type * as Fiber from "../Fiber.js"
import * as FiberId from "../FiberId.js"
import type * as FiberRef from "../FiberRef.js"
import type * as FiberStatus from "../FiberStatus.js"
import type { LazyArg } from "../Function.js"
import { dual, identity, pipe } from "../Function.js"
import { globalValue } from "../GlobalValue.js"
import * as Hash from "../Hash.js"
import * as HashMap from "../HashMap.js"
import type * as HashSet from "../HashSet.js"
import { format, NodeInspectSymbol, toJSON } from "../Inspectable.js"
import * as List from "../List.js"
import type * as LogLevel from "../LogLevel.js"
import type * as LogSpan from "../LogSpan.js"
import type * as MetricLabel from "../MetricLabel.js"
import * as MutableRef from "../MutableRef.js"
import * as Option from "../Option.js"
import { pipeArguments } from "../Pipeable.js"
import { hasProperty, isObject, isPromiseLike, isString, type Predicate, type Refinement } from "../Predicate.js"
import * as ReadonlyArray from "../ReadonlyArray.js"
import type * as Request from "../Request.js"
import type * as BlockedRequests from "../RequestBlock.js"
import type * as RequestResolver from "../RequestResolver.js"
import type * as RuntimeFlags from "../RuntimeFlags.js"
import * as RuntimeFlagsPatch from "../RuntimeFlagsPatch.js"
import type * as Scope from "../Scope.js"
import type * as Tracer from "../Tracer.js"
import type { NoInfer, NotFunction } from "../Types.js"
import * as _blockedRequests from "./blockedRequests.js"
import * as internalCause from "./cause.js"
import * as deferred from "./deferred.js"
import * as internalDiffer from "./differ.js"
import { effectVariance, StructuralCommitPrototype } from "./effectable.js"
import { getBugErrorMessage } from "./errors.js"
import type * as FiberRuntime from "./fiberRuntime.js"
import type * as fiberScope from "./fiberScope.js"
import * as DeferredOpCodes from "./opCodes/deferred.js"
import * as OpCodes from "./opCodes/effect.js"
import * as _runtimeFlags from "./runtimeFlags.js"
import * as internalTracer from "./tracer.js"
// -----------------------------------------------------------------------------
// Effect
// -----------------------------------------------------------------------------
/** @internal */
const EffectErrorSymbolKey = "effect/EffectError"
/** @internal */
export const EffectErrorTypeId = Symbol.for(EffectErrorSymbolKey)
/** @internal */
export type EffectErrorTypeId = typeof EffectErrorTypeId
/** @internal */
export interface EffectError<out E> {
readonly [EffectErrorTypeId]: EffectErrorTypeId
readonly _tag: "EffectError"
readonly cause: Cause.Cause<E>
}
/** @internal */
export const isEffectError = (u: unknown): u is EffectError<unknown> => hasProperty(u, EffectErrorTypeId)
/** @internal */
export const makeEffectError = <E>(cause: Cause.Cause<E>): EffectError<E> => ({
[EffectErrorTypeId]: EffectErrorTypeId,
_tag: "EffectError",
cause
})
/**
* @internal
*/
export const blocked = <A, E>(
blockedRequests: BlockedRequests.RequestBlock,
_continue: Effect.Effect<A, E>
): Effect.Blocked<A, E> => {
const effect = new EffectPrimitive("Blocked") as any
effect.effect_instruction_i0 = blockedRequests
effect.effect_instruction_i1 = _continue
return effect
}
/**
* @internal
*/
export const runRequestBlock = (
blockedRequests: BlockedRequests.RequestBlock
): Effect.Effect<void> => {
const effect = new EffectPrimitive("RunBlocked") as any
effect.effect_instruction_i0 = blockedRequests
return effect
}
/** @internal */
export const EffectTypeId: Effect.EffectTypeId = Symbol.for("effect/Effect") as Effect.EffectTypeId
/** @internal */
export type Primitive =
| Async
| Commit
| Failure
| OnFailure
| OnSuccess
| OnStep
| OnSuccessAndFailure
| Success
| Sync
| UpdateRuntimeFlags
| While
| WithRuntime
| Yield
| OpTag
| Blocked
| RunBlocked
| Either.Either<any, any>
| Option.Option<any>
/** @internal */
export type Continuation =
| OnSuccess
| OnStep
| OnSuccessAndFailure
| OnFailure
| While
| RevertFlags
/** @internal */
export class RevertFlags {
readonly _op = OpCodes.OP_REVERT_FLAGS
constructor(
readonly patch: RuntimeFlagsPatch.RuntimeFlagsPatch,
readonly op: Primitive & { _op: OpCodes.OP_UPDATE_RUNTIME_FLAGS }
) {
}
}
/** @internal */
class EffectPrimitive {
public effect_instruction_i0 = undefined
public effect_instruction_i1 = undefined
public effect_instruction_i2 = undefined
public trace = undefined;
[EffectTypeId] = effectVariance
constructor(readonly _op: Primitive["_op"]) {}
[Equal.symbol](this: {}, that: unknown) {
return this === that
}
[Hash.symbol](this: {}) {
return Hash.cached(this, Hash.random(this))
}
pipe() {
return pipeArguments(this, arguments)
}
toJSON() {
return {
_id: "Effect",
_op: this._op,
effect_instruction_i0: toJSON(this.effect_instruction_i0),
effect_instruction_i1: toJSON(this.effect_instruction_i1),
effect_instruction_i2: toJSON(this.effect_instruction_i2)
}
}
toString() {
return format(this.toJSON())
}
[NodeInspectSymbol]() {
return this.toJSON()
}
}
/** @internal */
class EffectPrimitiveFailure {
public effect_instruction_i0 = undefined
public effect_instruction_i1 = undefined
public effect_instruction_i2 = undefined
public trace = undefined;
[EffectTypeId] = effectVariance
constructor(readonly _op: Primitive["_op"]) {
// @ts-expect-error
this._tag = _op
}
[Equal.symbol](this: {}, that: unknown) {
return this === that
}
[Hash.symbol](this: {}) {
return Hash.cached(this, Hash.random(this))
}
get cause() {
return this.effect_instruction_i0
}
pipe() {
return pipeArguments(this, arguments)
}
toJSON() {
return {
_id: "Exit",
_tag: this._op,
cause: (this.cause as any).toJSON()
}
}
toString() {
return format(this.toJSON())
}
[NodeInspectSymbol]() {
return this.toJSON()
}
}
/** @internal */
class EffectPrimitiveSuccess {
public effect_instruction_i0 = undefined
public effect_instruction_i1 = undefined
public effect_instruction_i2 = undefined
public trace = undefined;
[EffectTypeId] = effectVariance
constructor(readonly _op: Primitive["_op"]) {
// @ts-expect-error
this._tag = _op
}
[Equal.symbol](this: {}, that: unknown) {
return this === that
}
[Hash.symbol](this: {}) {
return Hash.cached(this, Hash.random(this))
}
get value() {
return this.effect_instruction_i0
}
pipe() {
return pipeArguments(this, arguments)
}
toJSON() {
return {
_id: "Exit",
_tag: this._op,
value: toJSON(this.value)
}
}
toString() {
return format(this.toJSON())
}
[NodeInspectSymbol]() {
return this.toJSON()
}
}
/** @internal */
export type Op<Tag extends string, Body = {}> = Effect.Effect<never> & Body & {
readonly _op: Tag
}
/** @internal */
export interface Async extends
Op<OpCodes.OP_ASYNC, {
effect_instruction_i0(resume: (effect: Primitive) => void): void
readonly effect_instruction_i1: FiberId.FiberId
}>
{}
/** @internal */
export interface Blocked<out E = any, out A = any> extends
Op<"Blocked", {
readonly effect_instruction_i0: BlockedRequests.RequestBlock
readonly effect_instruction_i1: Effect.Effect<A, E>
}>
{}
/** @internal */
export interface RunBlocked extends
Op<"RunBlocked", {
readonly effect_instruction_i0: BlockedRequests.RequestBlock
}>
{}
/** @internal */
export interface Failure extends
Op<OpCodes.OP_FAILURE, {
readonly effect_instruction_i0: Cause.Cause<unknown>
}>
{}
/** @internal */
export interface OpTag extends Op<OpCodes.OP_TAG, {}> {}
/** @internal */
export interface Commit extends
Op<OpCodes.OP_COMMIT, {
commit(): Effect.Effect<unknown, unknown, unknown>
}>
{}
/** @internal */
export interface OnFailure extends
Op<OpCodes.OP_ON_FAILURE, {
readonly effect_instruction_i0: Primitive
effect_instruction_i1(a: Cause.Cause<unknown>): Primitive
}>
{}
/** @internal */
export interface OnSuccess extends
Op<OpCodes.OP_ON_SUCCESS, {
readonly effect_instruction_i0: Primitive
effect_instruction_i1(a: unknown): Primitive
}>
{}
/** @internal */
export interface OnStep extends Op<"OnStep", { readonly effect_instruction_i0: Primitive }> {}
/** @internal */
export interface OnSuccessAndFailure extends
Op<OpCodes.OP_ON_SUCCESS_AND_FAILURE, {
readonly effect_instruction_i0: Primitive
effect_instruction_i1(a: Cause.Cause<unknown>): Primitive
effect_instruction_i2(a: unknown): Primitive
}>
{}
/** @internal */
export interface Success extends
Op<OpCodes.OP_SUCCESS, {
readonly effect_instruction_i0: unknown
}>
{}
/** @internal */
export interface Sync extends
Op<OpCodes.OP_SYNC, {
effect_instruction_i0(): unknown
}>
{}
/** @internal */
export interface UpdateRuntimeFlags extends
Op<OpCodes.OP_UPDATE_RUNTIME_FLAGS, {
readonly effect_instruction_i0: RuntimeFlagsPatch.RuntimeFlagsPatch
readonly effect_instruction_i1?: (oldRuntimeFlags: RuntimeFlags.RuntimeFlags) => Primitive
}>
{}
/** @internal */
export interface While extends
Op<OpCodes.OP_WHILE, {
effect_instruction_i0(): boolean
effect_instruction_i1(): Primitive
effect_instruction_i2(a: unknown): void
}>
{}
/** @internal */
export interface WithRuntime extends
Op<OpCodes.OP_WITH_RUNTIME, {
effect_instruction_i0(fiber: FiberRuntime.FiberRuntime<unknown, unknown>, status: FiberStatus.Running): Primitive
}>
{}
/** @internal */
export interface Yield extends Op<OpCodes.OP_YIELD> {}
/** @internal */
export const isEffect = (u: unknown): u is Effect.Effect<unknown, unknown, unknown> => hasProperty(u, EffectTypeId)
/* @internal */
export const withFiberRuntime = <A, E = never, R = never>(
withRuntime: (fiber: FiberRuntime.FiberRuntime<A, E>, status: FiberStatus.Running) => Effect.Effect<A, E, R>
): Effect.Effect<A, E, R> => {
const effect = new EffectPrimitive(OpCodes.OP_WITH_RUNTIME) as any
effect.effect_instruction_i0 = withRuntime
return effect
}
/* @internal */
export const acquireUseRelease: {
<A2, E2, R2, A, X, R3>(
use: (a: A) => Effect.Effect<A2, E2, R2>,
release: (a: A, exit: Exit.Exit<A2, E2>) => Effect.Effect<X, never, R3>
): <E, R>(acquire: Effect.Effect<A, E, R>) => Effect.Effect<A2, E2 | E, R2 | R3 | R>
<A, E, R, A2, E2, R2, X, R3>(
acquire: Effect.Effect<A, E, R>,
use: (a: A) => Effect.Effect<A2, E2, R2>,
release: (a: A, exit: Exit.Exit<A2, E2>) => Effect.Effect<X, never, R3>
): Effect.Effect<A2, E | E2, R | R2 | R3>
} = dual(3, <A, E, R, A2, E2, R2, X, R3>(
acquire: Effect.Effect<A, E, R>,
use: (a: A) => Effect.Effect<A2, E2, R2>,
release: (a: A, exit: Exit.Exit<A2, E2>) => Effect.Effect<X, never, R3>
): Effect.Effect<A2, E | E2, R | R2 | R3> =>
uninterruptibleMask((restore) =>
flatMap(
acquire,
(a) =>
flatMap(exit(suspend(() => restore(use(a)))), (exit): Effect.Effect<A2, E | E2, R | R2 | R3> => {
return suspend(() => release(a, exit)).pipe(
matchCauseEffect({
onFailure: (cause) => {
switch (exit._tag) {
case OpCodes.OP_FAILURE:
return failCause(internalCause.parallel(exit.effect_instruction_i0, cause))
case OpCodes.OP_SUCCESS:
return failCause(cause)
}
},
onSuccess: () => exit
})
)
})
)
))
/* @internal */
export const as: {
<B>(value: B): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<B, E, R>
<A, E, R, B>(self: Effect.Effect<A, E, R>, value: B): Effect.Effect<B, E, R>
} = dual(
2,
<A, E, R, B>(self: Effect.Effect<A, E, R>, value: B): Effect.Effect<B, E, R> => flatMap(self, () => succeed(value))
)
/* @internal */
export const asUnit = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<void, E, R> => as(self, void 0)
/* @internal */
export const custom: {
<X, A, E, R>(i0: X, body: (this: { effect_instruction_i0: X }) => Effect.Effect<A, E, R>): Effect.Effect<A, E, R>
<X, Y, A, E, R>(
i0: X,
i1: Y,
body: (this: { effect_instruction_i0: X; effect_instruction_i1: Y }) => Effect.Effect<A, E, R>
): Effect.Effect<A, E, R>
<X, Y, Z, A, E, R>(
i0: X,
i1: Y,
i2: Z,
body: (
this: { effect_instruction_i0: X; effect_instruction_i1: Y; effect_instruction_i2: Z }
) => Effect.Effect<A, E, R>
): Effect.Effect<A, E, R>
} = function() {
const wrapper = new EffectPrimitive(OpCodes.OP_COMMIT) as any
switch (arguments.length) {
case 2: {
wrapper.effect_instruction_i0 = arguments[0]
wrapper.commit = arguments[1]
break
}
case 3: {
wrapper.effect_instruction_i0 = arguments[0]
wrapper.effect_instruction_i1 = arguments[1]
wrapper.commit = arguments[2]
break
}
case 4: {
wrapper.effect_instruction_i0 = arguments[0]
wrapper.effect_instruction_i1 = arguments[1]
wrapper.effect_instruction_i2 = arguments[2]
wrapper.commit = arguments[3]
break
}
default: {
throw new Error(getBugErrorMessage("you're not supposed to end up here"))
}
}
return wrapper
}
/* @internal */
export const async = <A, E = never, R = never>(
register: (
callback: (_: Effect.Effect<A, E, R>) => void,
signal: AbortSignal
) => void | Effect.Effect<void, never, R>,
blockingOn: FiberId.FiberId = FiberId.none
): Effect.Effect<A, E, R> => {
return custom(register, function() {
let backingResume: ((_: Effect.Effect<A, E, R>) => void) | undefined = undefined
let pendingEffect: Effect.Effect<A, E, R> | undefined = undefined
function proxyResume(effect: Effect.Effect<A, E, R>) {
if (backingResume) {
backingResume(effect)
} else if (pendingEffect === undefined) {
pendingEffect = effect
}
}
const effect = new EffectPrimitive(OpCodes.OP_ASYNC) as any
effect.effect_instruction_i0 = (resume: (_: Effect.Effect<A, E, R>) => void) => {
backingResume = resume
if (pendingEffect) {
resume(pendingEffect)
}
}
effect.effect_instruction_i1 = blockingOn
let cancelerRef: Effect.Effect<void, never, R> | void = undefined
let controllerRef: AbortController | void = undefined
if (this.effect_instruction_i0.length !== 1) {
controllerRef = new AbortController()
cancelerRef = this.effect_instruction_i0(proxyResume, controllerRef.signal)
} else {
cancelerRef = (this.effect_instruction_i0 as any)(proxyResume)
}
return (cancelerRef || controllerRef) ?
onInterrupt(effect, (_) => {
if (controllerRef) {
controllerRef.abort()
}
return cancelerRef ?? unit
}) :
effect
})
}
/* @internal */
export const catchAllCause = dual<
<E, A2, E2, R2>(
f: (cause: Cause.Cause<E>) => Effect.Effect<A2, E2, R2>
) => <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A, E2, R2 | R>,
<A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
f: (cause: Cause.Cause<E>) => Effect.Effect<A2, E2, R2>
) => Effect.Effect<A2 | A, E2, R2 | R>
>(2, (self, f) => {
const effect = new EffectPrimitive(OpCodes.OP_ON_FAILURE) as any
effect.effect_instruction_i0 = self
effect.effect_instruction_i1 = f
return effect
})
/* @internal */
export const catchAll: {
<E, A2, E2, R2>(
f: (e: E) => Effect.Effect<A2, E2, R2>
): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A, E2, R2 | R>
<A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
f: (e: E) => Effect.Effect<A2, E2, R2>
): Effect.Effect<A2 | A, E2, R2 | R>
} = dual(
2,
<A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
f: (e: E) => Effect.Effect<A2, E2, R2>
): Effect.Effect<A2 | A, E2, R2 | R> => matchEffect(self, { onFailure: f, onSuccess: succeed })
)
/* @internal */
export const catchIf: {
<E, EB extends E, A2, E2, R2>(
refinement: Refinement<NoInfer<E>, EB>,
f: (e: EB) => Effect.Effect<A2, E2, R2>
): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A, E2 | Exclude<E, EB>, R2 | R>
<E, A2, E2, R2>(
predicate: Predicate<NoInfer<E>>,
f: (e: NoInfer<E>) => Effect.Effect<A2, E2, R2>
): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A, E | E2, R2 | R>
<A, E, R, EB extends E, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
refinement: Refinement<E, EB>,
f: (e: EB) => Effect.Effect<A2, E2, R2>
): Effect.Effect<A2 | A, E2 | Exclude<E, EB>, R2 | R>
<A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
predicate: Predicate<E>,
f: (e: E) => Effect.Effect<A2, E2, R2>
): Effect.Effect<A | A2, E | E2, R | R2>
} = dual(3, <A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
predicate: Predicate<E>,
f: (e: E) => Effect.Effect<A2, E2, R2>
): Effect.Effect<A | A2, E | E2, R | R2> =>
catchAllCause(self, (cause): Effect.Effect<A | A2, E | E2, R | R2> => {
const either = internalCause.failureOrCause(cause)
switch (either._tag) {
case "Left":
return predicate(either.left) ? f(either.left) : failCause(cause)
case "Right":
return failCause(either.right)
}
}))
/* @internal */
export const catchSome = dual<
<E, A2, E2, R2>(
pf: (e: NoInfer<E>) => Option.Option<Effect.Effect<A2, E2, R2>>
) => <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A, E | E2, R2 | R>,
<A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
pf: (e: NoInfer<E>) => Option.Option<Effect.Effect<A2, E2, R2>>
) => Effect.Effect<A2 | A, E | E2, R2 | R>
>(2, <A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
pf: (e: NoInfer<E>) => Option.Option<Effect.Effect<A2, E2, R2>>
) =>
catchAllCause(self, (cause): Effect.Effect<A2 | A, E | E2, R2 | R> => {
const either = internalCause.failureOrCause(cause)
switch (either._tag) {
case "Left":
return pipe(pf(either.left), Option.getOrElse(() => failCause(cause)))
case "Right":
return failCause(either.right)
}
}))
/* @internal */
export const checkInterruptible = <A, E, R>(
f: (isInterruptible: boolean) => Effect.Effect<A, E, R>
): Effect.Effect<A, E, R> => withFiberRuntime((_, status) => f(_runtimeFlags.interruption(status.runtimeFlags)))
const spanSymbol = Symbol.for("effect/SpanAnnotation")
const originalSymbol = Symbol.for("effect/OriginalAnnotation")
/* @internal */
export const originalInstance = <E>(obj: E): E => {
if (hasProperty(obj, originalSymbol)) {
// @ts-expect-error
return obj[originalSymbol]
}
return obj
}
/* @internal */
const capture = <E>(obj: E & object, span: Option.Option<Tracer.Span>): E => {
if (Option.isSome(span)) {
return new Proxy(obj, {
has(target, p) {
return p === spanSymbol || p === originalSymbol || p in target
},
get(target, p) {
if (p === spanSymbol) {
return span.value
}
if (p === originalSymbol) {
return obj
}
// @ts-expect-error
return target[p]
}
})
}
return obj
}
/* @internal */
export const die = (defect: unknown): Effect.Effect<never> =>
isObject(defect) && !(spanSymbol in defect) ?
withFiberRuntime((fiber) => failCause(internalCause.die(capture(defect, currentSpanFromFiber(fiber)))))
: failCause(internalCause.die(defect))
/* @internal */
export const dieMessage = (message: string): Effect.Effect<never> =>
failCauseSync(() => internalCause.die(new RuntimeException(message)))
/* @internal */
export const dieSync = (evaluate: LazyArg<unknown>): Effect.Effect<never> => flatMap(sync(evaluate), die)
/* @internal */
export const either = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<Either.Either<A, E>, never, R> =>
matchEffect(self, {
onFailure: (e) => succeed(Either.left(e)),
onSuccess: (a) => succeed(Either.right(a))
})
/* @internal */
export const exit = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<Exit.Exit<A, E>, never, R> =>
matchCause(self, {
onFailure: exitFailCause,
onSuccess: exitSucceed
})
/* @internal */
export const fail = <E>(error: E): Effect.Effect<never, E> =>
isObject(error) && !(spanSymbol in error) ?
withFiberRuntime((fiber) => failCause(internalCause.fail(capture(error, currentSpanFromFiber(fiber)))))
: failCause(internalCause.fail(error))
/* @internal */
export const failSync = <E>(evaluate: LazyArg<E>): Effect.Effect<never, E> => flatMap(sync(evaluate), fail)
/* @internal */
export const failCause = <E>(cause: Cause.Cause<E>): Effect.Effect<never, E> => {
const effect = new EffectPrimitiveFailure(OpCodes.OP_FAILURE) as any
effect.effect_instruction_i0 = cause
return effect
}
/* @internal */
export const failCauseSync = <E>(
evaluate: LazyArg<Cause.Cause<E>>
): Effect.Effect<never, E> => flatMap(sync(evaluate), failCause)
/* @internal */
export const fiberId: Effect.Effect<FiberId.FiberId> = withFiberRuntime((state) => succeed(state.id()))
/* @internal */
export const fiberIdWith = <A, E, R>(
f: (descriptor: FiberId.Runtime) => Effect.Effect<A, E, R>
): Effect.Effect<A, E, R> => withFiberRuntime((state) => f(state.id()))
/* @internal */
export const flatMap = dual<
<A, B, E1, R1>(
f: (a: A) => Effect.Effect<B, E1, R1>
) => <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<B, E1 | E, R1 | R>,
<A, E, R, B, E1, R1>(
self: Effect.Effect<A, E, R>,
f: (a: A) => Effect.Effect<B, E1, R1>
) => Effect.Effect<B, E | E1, R | R1>
>(
2,
(self, f) => {
const effect = new EffectPrimitive(OpCodes.OP_ON_SUCCESS) as any
effect.effect_instruction_i0 = self
effect.effect_instruction_i1 = f
return effect
}
)
/* @internal */
export const andThen: {
<A, X>(
f: (a: NoInfer<A>) => X
): <E, R>(
self: Effect.Effect<A, E, R>
) => [X] extends [Effect.Effect<infer A1, infer E1, infer R1>] ? Effect.Effect<A1, E | E1, R | R1>
: [X] extends [PromiseLike<infer A1>] ? Effect.Effect<A1, E | Cause.UnknownException, R>
: Effect.Effect<X, E, R>
<X>(
f: NotFunction<X>
): <A, E, R>(
self: Effect.Effect<A, E, R>
) => [X] extends [Effect.Effect<infer A1, infer E1, infer R1>] ? Effect.Effect<A1, E | E1, R | R1>
: [X] extends [PromiseLike<infer A1>] ? Effect.Effect<A1, E | Cause.UnknownException, R>
: Effect.Effect<X, E, R>
<A, E, R, X>(
self: Effect.Effect<A, E, R>,
f: (a: NoInfer<A>) => X
): [X] extends [Effect.Effect<infer A1, infer E1, infer R1>] ? Effect.Effect<A1, E | E1, R | R1>
: [X] extends [PromiseLike<infer A1>] ? Effect.Effect<A1, E | Cause.UnknownException, R>
: Effect.Effect<X, E, R>
<A, E, R, X>(
self: Effect.Effect<A, E, R>,
f: NotFunction<X>
): [X] extends [Effect.Effect<infer A1, infer E1, infer R1>] ? Effect.Effect<A1, E | E1, R | R1>
: [X] extends [PromiseLike<infer A1>] ? Effect.Effect<A1, E | Cause.UnknownException, R>
: Effect.Effect<X, E, R>
} = dual(2, (self, f) =>
flatMap(self, (a) => {
const b = typeof f === "function" ? (f as any)(a) : f
if (isEffect(b)) {
return b
} else if (isPromiseLike(b)) {
return async<any, Cause.UnknownException>((resume) => {
b.then((a) => resume(succeed(a)), (e) => resume(fail(new UnknownException(e))))
})
}
return succeed(b)
}))
/* @internal */
export const step = <A, E, R>(
self: Effect.Effect<A, E, R>
): Effect.Effect<Exit.Exit<A, E> | Effect.Blocked<A, E>, never, R> => {
const effect = new EffectPrimitive("OnStep") as any
effect.effect_instruction_i0 = self
return effect
}
/* @internal */
export const flatten = <A, E1, R1, E, R>(
self: Effect.Effect<Effect.Effect<A, E1, R1>, E, R>
): Effect.Effect<A, E | E1, R | R1> => flatMap(self, identity)
/* @internal */
export const flip = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<E, A, R> =>
matchEffect(self, { onFailure: succeed, onSuccess: fail })
/* @internal */
export const matchCause: {
<E, A2, A, A3>(
options: {
readonly onFailure: (cause: Cause.Cause<E>) => A2
readonly onSuccess: (a: A) => A3
}
): <R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A3, never, R>
<A, E, R, A2, A3>(
self: Effect.Effect<A, E, R>,
options: {
readonly onFailure: (cause: Cause.Cause<E>) => A2
readonly onSuccess: (a: A) => A3
}
): Effect.Effect<A2 | A3, never, R>
} = dual(2, <A, E, R, A2, A3>(
self: Effect.Effect<A, E, R>,
options: {
readonly onFailure: (cause: Cause.Cause<E>) => A2
readonly onSuccess: (a: A) => A3
}
): Effect.Effect<A2 | A3, never, R> =>
matchCauseEffect(self, {
onFailure: (cause) => succeed(options.onFailure(cause)),
onSuccess: (a) => succeed(options.onSuccess(a))
}))
/* @internal */
export const matchCauseEffect: {
<E, A2, E2, R2, A, A3, E3, R3>(
options: {
readonly onFailure: (cause: Cause.Cause<E>) => Effect.Effect<A2, E2, R2>
readonly onSuccess: (a: A) => Effect.Effect<A3, E3, R3>
}
): <R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A3, E2 | E3, R2 | R3 | R>
<A, E, R, A2, E2, R2, A3, E3, R3>(
self: Effect.Effect<A, E, R>,
options: {
readonly onFailure: (cause: Cause.Cause<E>) => Effect.Effect<A2, E2, R2>
readonly onSuccess: (a: A) => Effect.Effect<A3, E3, R3>
}
): Effect.Effect<A2 | A3, E2 | E3, R2 | R3 | R>
} = dual(2, <A, E, R, A2, E2, R2, A3, E3, R3>(
self: Effect.Effect<A, E, R>,
options: {
readonly onFailure: (cause: Cause.Cause<E>) => Effect.Effect<A2, E2, R2>
readonly onSuccess: (a: A) => Effect.Effect<A3, E3, R3>
}
): Effect.Effect<A2 | A3, E2 | E3, R2 | R3 | R> => {
const effect = new EffectPrimitive(OpCodes.OP_ON_SUCCESS_AND_FAILURE) as any
effect.effect_instruction_i0 = self
effect.effect_instruction_i1 = options.onFailure
effect.effect_instruction_i2 = options.onSuccess
return effect
})
/* @internal */
export const matchEffect: {
<E, A2, E2, R2, A, A3, E3, R3>(
options: {
readonly onFailure: (e: E) => Effect.Effect<A2, E2, R2>
readonly onSuccess: (a: A) => Effect.Effect<A3, E3, R3>
}
): <R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A3, E2 | E3, R2 | R3 | R>
<A, E, R, A2, E2, R2, A3, E3, R3>(
self: Effect.Effect<A, E, R>,
options: {
readonly onFailure: (e: E) => Effect.Effect<A2, E2, R2>
readonly onSuccess: (a: A) => Effect.Effect<A3, E3, R3>
}
): Effect.Effect<A2 | A3, E2 | E3, R2 | R3 | R>
} = dual(2, <A, E, R, A2, E2, R2, A3, E3, R3>(
self: Effect.Effect<A, E, R>,
options: {
readonly onFailure: (e: E) => Effect.Effect<A2, E2, R2>
readonly onSuccess: (a: A) => Effect.Effect<A3, E3, R3>
}
): Effect.Effect<A2 | A3, E2 | E3, R2 | R3 | R> =>
matchCauseEffect(self, {
onFailure: (cause) => {
const defects = internalCause.defects(cause)
if (defects.length > 0) {
return failCause(internalCause.electFailures(cause))
}
const failures = internalCause.failures(cause)
if (failures.length > 0) {
return options.onFailure(Chunk.unsafeHead(failures))
}
return failCause(cause as Cause.Cause<never>)
},
onSuccess: options.onSuccess
}))
/* @internal */
export const forEachSequential: {
<A, B, E, R>(f: (a: A, i: number) => Effect.Effect<B, E, R>): (self: Iterable<A>) => Effect.Effect<Array<B>, E, R>
<A, B, E, R>(self: Iterable<A>, f: (a: A, i: number) => Effect.Effect<B, E, R>): Effect.Effect<Array<B>, E, R>
} = dual(
2,
<A, B, E, R>(self: Iterable<A>, f: (a: A, i: number) => Effect.Effect<B, E, R>): Effect.Effect<Array<B>, E, R> =>
suspend(() => {
const arr = ReadonlyArray.fromIterable(self)
const ret = new Array(arr.length)
let i = 0
return as(
whileLoop({
while: () => i < arr.length,
body: () => f(arr[i], i),
step: (b) => {
ret[i++] = b
}
}),
ret
)
})
)
/* @internal */
export const forEachSequentialDiscard: {
<A, B, E, R>(f: (a: A, i: number) => Effect.Effect<B, E, R>): (self: Iterable<A>) => Effect.Effect<void, E, R>
<A, B, E, R>(self: Iterable<A>, f: (a: A, i: number) => Effect.Effect<B, E, R>): Effect.Effect<void, E, R>
} = dual(
2,
<A, B, E, R>(self: Iterable<A>, f: (a: A, i: number) => Effect.Effect<B, E, R>): Effect.Effect<void, E, R> =>
suspend(() => {
const arr = ReadonlyArray.fromIterable(self)
let i = 0
return whileLoop({
while: () => i < arr.length,
body: () => f(arr[i], i),
step: () => {
i++
}
})
})
)
/* @internal */
export const if_ = dual<
<A1, E1, R1, A2, E2, R2>(
options: {
readonly onTrue: Effect.Effect<A1, E1, R1>
readonly onFalse: Effect.Effect<A2, E2, R2>
}
) => <E = never, R = never>(
self: Effect.Effect<boolean, E, R> | boolean
) => Effect.Effect<A1 | A2, E | E1 | E2, R | R1 | R2>,
{
<A1, E1, R1, A2, E2, R2>(
self: boolean,
options: {
readonly onTrue: Effect.Effect<A1, E1, R1>
readonly onFalse: Effect.Effect<A2, E2, R2>
}
): Effect.Effect<A1 | A2, E1 | E2, R1 | R2>
<E, R, A1, E1, R1, A2, E2, R2>(
self: Effect.Effect<boolean, E, R>,
options: {
readonly onTrue: Effect.Effect<A1, E1, R1>
readonly onFalse: Effect.Effect<A2, E2, R2>
}
): Effect.Effect<A1 | A2, E1 | E2 | E, R1 | R2 | R>
}
>(
(args) => typeof args[0] === "boolean" || isEffect(args[0]),
(self: boolean | Effect.Effect<unknown, unknown, unknown>, { onFalse, onTrue }: {
readonly onTrue: Effect.Effect<unknown, unknown, unknown>
readonly onFalse: Effect.Effect<unknown, unknown, unknown>
// eslint-disable-next-line no-extra-boolean-cast
}) => isEffect(self) ? flatMap(self, (b) => (b ? onTrue : onFalse)) : Boolean(self) ? onTrue : onFalse
)
/* @internal */
export const interrupt: Effect.Effect<never> = flatMap(fiberId, (fiberId) => interruptWith(fiberId))
/* @internal */
export const interruptWith = (fiberId: FiberId.FiberId): Effect.Effect<never> =>
failCause(internalCause.interrupt(fiberId))
/* @internal */
export const interruptible = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> => {
const effect = new EffectPrimitive(OpCodes.OP_UPDATE_RUNTIME_FLAGS) as any
effect.effect_instruction_i0 = RuntimeFlagsPatch.enable(_runtimeFlags.Interruption)
effect.effect_instruction_i1 = () => self
return effect
}
/* @internal */
export const interruptibleMask = <A, E, R>(
f: (restore: <AX, EX, RX>(effect: Effect.Effect<AX, EX, RX>) => Effect.Effect<AX, EX, RX>) => Effect.Effect<A, E, R>
): Effect.Effect<A, E, R> =>
custom(f, function() {
const effect = new EffectPrimitive(OpCodes.OP_UPDATE_RUNTIME_FLAGS) as any
effect.effect_instruction_i0 = RuntimeFlagsPatch.enable(_runtimeFlags.Interruption)
effect.effect_instruction_i1 = (oldFlags: RuntimeFlags.RuntimeFlags) =>
_runtimeFlags.interruption(oldFlags)
? this.effect_instruction_i0(interruptible)
: this.effect_instruction_i0(uninterruptible)
return effect
})
/* @internal */
export const intoDeferred: {
<A, E>(deferred: Deferred.Deferred<A, E>): <R>(self: Effect.Effect<A, E, R>) => Effect.Effect<boolean, never, R>
<A, E, R>(self: Effect.Effect<A, E, R>, deferred: Deferred.Deferred<A, E>): Effect.Effect<boolean, never, R>
} = dual(
2,
<A, E, R>(self: Effect.Effect<A, E, R>, deferred: Deferred.Deferred<A, E>): Effect.Effect<boolean, never, R> =>
uninterruptibleMask((restore) =>
flatMap(
exit(restore(self)),
(exit) => deferredDone(deferred, exit)
)
)
)
/* @internal */
export const map: {
<A, B>(f: (a: A) => B): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<B, E, R>
<A, E, R, B>(self: Effect.Effect<A, E, R>, f: (a: A) => B): Effect.Effect<B, E, R>
} = dual(
2,
<A, E, R, B>(self: Effect.Effect<A, E, R>, f: (a: A) => B): Effect.Effect<B, E, R> =>
flatMap(self, (a) => sync(() => f(a)))
)
/* @internal */
export const mapBoth: {
<E, E2, A, A2>(
options: { readonly onFailure: (e: E) => E2; readonly onSuccess: (a: A) => A2 }
): <R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2, E2, R>
<A, E, R, E2, A2>(
self: Effect.Effect<A, E, R>,
options: { readonly onFailure: (e: E) => E2; readonly onSuccess: (a: A) => A2 }
): Effect.Effect<A2, E2, R>
} = dual(2, <A, E, R, E2, A2>(
self: Effect.Effect<A, E, R>,
options: { readonly onFailure: (e: E) => E2; readonly onSuccess: (a: A) => A2 }
): Effect.Effect<A2, E2, R> =>
matchEffect(self, {
onFailure: (e) => failSync(() => options.onFailure(e)),
onSuccess: (a) => sync(() => options.onSuccess(a))
}))
/* @internal */
export const mapError: {
<E, E2>(f: (e: E) => E2): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E2, R>
<A, E, R, E2>(self: Effect.Effect<A, E, R>, f: (e: E) => E2): Effect.Effect<A, E2, R>
} = dual(
2,
<A, E, R, E2>(self: Effect.Effect<A, E, R>, f: (e: E) => E2): Effect.Effect<A, E2, R> =>
matchCauseEffect(self, {
onFailure: (cause) => {
const either = internalCause.failureOrCause(cause)
switch (either._tag) {
case "Left": {
return failSync(() => f(either.left))
}
case "Right": {
return failCause(either.right)
}
}
},
onSuccess: succeed
})
)
/* @internal */
export const onError: {
<E, X, R2>(
cleanup: (cause: Cause.Cause<E>) => Effect.Effect<X, never, R2>
): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R2 | R>
<A, E, R, X, R2>(
self: Effect.Effect<A, E, R>,
cleanup: (cause: Cause.Cause<E>) => Effect.Effect<X, never, R2>
): Effect.Effect<A, E, R2 | R>
} = dual(2, <A, E, R, X, R2>(
self: Effect.Effect<A, E, R>,
cleanup: (cause: Cause.Cause<E>) => Effect.Effect<X, never, R2>
): Effect.Effect<A, E, R2 | R> =>
onExit(self, (exit) => exitIsSuccess(exit) ? unit : cleanup(exit.effect_instruction_i0)))
/* @internal */
export const onExit: {
<A, E, X, R2>(
cleanup: (exit: Exit.Exit<A, E>) => Effect.Effect<X, never, R2>
): <R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R2 | R>
<A, E, R, X, R2>(
self: Effect.Effect<A, E, R>,
cleanup: (exit: Exit.Exit<A, E>) => Effect.Effect<X, never, R2>
): Effect.Effect<A, E, R2 | R>
} = dual(2, <A, E, R, X, R2>(
self: Effect.Effect<A, E, R>,
cleanup: (exit: Exit.Exit<A, E>) => Effect.Effect<X, never, R2>
): Effect.Effect<A, E, R2 | R> =>
uninterruptibleMask((restore) =>
matchCauseEffect(restore(self), {
onFailure: (cause1) => {
const result = exitFailCause(cause1)
return matchCauseEffect(cleanup(result), {
onFailure: (cause2) => exitFailCause(internalCause.sequential(cause1, cause2)),
onSuccess: () => result
})
},
onSuccess: (success) => {
const result = exitSucceed(success)
return zipRight(cleanup(result), result)
}
})
))
/* @internal */
export const onInterrupt: {
<X, R2>(
cleanup: (interruptors: HashSet.HashSet<FiberId.FiberId>) => Effect.Effect<X, never, R2>
): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R2 | R>
<A, E, R, X, R2>(
self: Effect.Effect<A, E, R>,
cleanup: (interruptors: HashSet.HashSet<FiberId.FiberId>) => Effect.Effect<X, never, R2>
): Effect.Effect<A, E, R2 | R>
} = dual(2, <A, E, R, X, R2>(
self: Effect.Effect<A, E, R>,
cleanup: (interruptors: HashSet.HashSet<FiberId.FiberId>) => Effect.Effect<X, never, R2>
): Effect.Effect<A, E, R2 | R> =>
onExit(
self,
exitMatch({
onFailure: (cause) =>
internalCause.isInterruptedOnly(cause)
? asUnit(cleanup(internalCause.interruptors(cause)))
: unit,
onSuccess: () => unit
})
))
/* @internal */
export const orElse: {
<A2, E2, R2>(
that: LazyArg<Effect.Effect<A2, E2, R2>>
): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A, E2, R2 | R>
<A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
that: LazyArg<Effect.Effect<A2, E2, R2>>
): Effect.Effect<A2 | A, E2, R2 | R>
} = dual(
2,
<A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
that: LazyArg<Effect.Effect<A2, E2, R2>>
): Effect.Effect<A2 | A, E2, R2 | R> => attemptOrElse(self, that, succeed)
)
/* @internal */
export const orDie = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, never, R> => orDieWith(self, identity)
/* @internal */
export const orDieWith: {
<E>(f: (error: E) => unknown): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, never, R>
<A, E, R>(self: Effect.Effect<A, E, R>, f: (error: E) => unknown): Effect.Effect<A, never, R>
} = dual(
2,
<A, E, R>(self: Effect.Effect<A, E, R>, f: (error: E) => unknown): Effect.Effect<A, never, R> =>
matchEffect(self, {
onFailure: (e) => die(f(e)),
onSuccess: succeed
})
)
/* @internal */
export const partitionMap = <A, A1, A2>(
elements: Iterable<A>,
f: (a: A) => Either.Either<A2, A1>
): [left: Array<A1>, right: Array<A2>] =>
ReadonlyArray.fromIterable(elements).reduceRight(
([lefts, rights], current) => {
const either = f(current)
switch (either._tag) {
case "Left": {
return [[either.left, ...lefts], rights]
}
case "Right": {
return [lefts, [either.right, ...rights]]
}
}
},
[new Array<A1>(), new Array<A2>()]
)
/* @internal */
export const runtimeFlags: Effect.Effect<RuntimeFlags.RuntimeFlags> = withFiberRuntime((_, status) =>
succeed(status.runtimeFlags)
)
/* @internal */
export const succeed = <A>(value: A): Effect.Effect<A> => {
const effect = new EffectPrimitiveSuccess(OpCodes.OP_SUCCESS) as any
effect.effect_instruction_i0 = value
return effect
}
/* @internal */
export const suspend = <A, E, R>(effect: LazyArg<Effect.Effect<A, E, R>>): Effect.Effect<A, E, R> =>
flatMap(sync(effect), identity)
/* @internal */
export const sync = <A>(evaluate: LazyArg<A>): Effect.Effect<A> => {
const effect = new EffectPrimitive(OpCodes.OP_SYNC) as any
effect.effect_instruction_i0 = evaluate
return effect
}
/* @internal */
export const tap = dual<
{
<A, X>(
f: (a: NoInfer<A>) => X
): <E, R>(
self: Effect.Effect<A, E, R>
) => [X] extends [Effect.Effect<infer _A1, infer E1, infer R1>] ? Effect.Effect<A, E | E1, R | R1>
: [X] extends [PromiseLike<infer _A1>] ? Effect.Effect<A, E | Cause.UnknownException, R>
: Effect.Effect<A, E, R>
<X>(
f: NotFunction<X>
): <A, E, R>(
self: Effect.Effect<A, E, R>
) => [X] extends [Effect.Effect<infer _A1, infer E1, infer R1>] ? Effect.Effect<A, E | E1, R | R1>
: [X] extends [PromiseLike<infer _A1>] ? Effect.Effect<A, E | Cause.UnknownException, R>
: Effect.Effect<A, E, R>
},
{
<A, E, R, X>(
self: Effect.Effect<A, E, R>,
f: (a: NoInfer<A>) => X
): [X] extends [Effect.Effect<infer _A1, infer E1, infer R1>] ? Effect.Effect<A, E | E1, R | R1>
: [X] extends [PromiseLike<infer _A1>] ? Effect.Effect<A, E | Cause.UnknownException, R>
: Effect.Effect<A, E, R>
<A, E, R, X>(
self: Effect.Effect<A, E, R>,
f: NotFunction<X>
): [X] extends [Effect.Effect<infer _A1, infer E1, infer R1>] ? Effect.Effect<A, E | E1, R | R1>
: [X] extends [PromiseLike<infer _A1>] ? Effect.Effect<A, E | Cause.UnknownException, R>
: Effect.Effect<A, E, R>
}
>(2, (self, f) =>
flatMap(self, (a) => {
const b = typeof f === "function" ? (f as any)(a) : f
if (isEffect(b)) {
return as(b, a)
} else if (isPromiseLike(b)) {
return async<any, Cause.UnknownException>((resume) => {
b.then((_) => resume(succeed(a)), (e) => resume(fail(new UnknownException(e))))
})
}
return succeed(a)
}))
/* @internal */
export const transplant = <A, E, R>(
f: (grafter: <A2, E2, R2>(effect: Effect.Effect<A2, E2, R2>) => Effect.Effect<A2, E2, R2>) => Effect.Effect<A, E, R>
): Effect.Effect<A, E, R> =>
withFiberRuntime<A, E, R>((state) => {
const scopeOverride = state.getFiberRef(currentForkScopeOverride)
const scope = pipe(scopeOverride, Option.getOrElse(() => state.scope()))
return f(fiberRefLocally(currentForkScopeOverride, Option.some(scope)))
})
/* @internal */
export const attemptOrElse: {
<A2, E2, R2, A, A3, E3, R3>(
that: LazyArg<Effect.Effect<A2, E2, R2>>,
onSuccess: (a: A) => Effect.Effect<A3, E3, R3>
): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2 | A3, E2 | E3, R | R2 | R3>
<A, E, R, A2, E2, R2, A3, E3, R3>(
self: Effect.Effect<A, E, R>,
that: LazyArg<Effect.Effect<A2, E2, R2>>,
onSuccess: (a: A) => Effect.Effect<A3, E3, R3>
): Effect.Effect<A2 | A3, E2 | E3, R | R2 | R3>
} = dual(3, <A, E, R, A2, E2, R2, A3, E3, R3>(
self: Effect.Effect<A, E, R>,
that: LazyArg<Effect.Effect<A2, E2, R2>>,
onSuccess: (a: A) => Effect.Effect<A3, E3, R3>
): Effect.Effect<A2 | A3, E2 | E3, R | R2 | R3> =>
matchCauseEffect(self, {
onFailure: (cause) => {
const defects = internalCause.defects(cause)
if (defects.length > 0) {
return failCause(Option.getOrThrow(internalCause.keepDefectsAndElectFailures(cause)))
}
return that()
},
onSuccess
}))
/* @internal */
export const uninterruptible: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> = <A, E, R>(
self: Effect.Effect<A, E, R>
): Effect.Effect<A, E, R> => {
const effect = new EffectPrimitive(OpCodes.OP_UPDATE_RUNTIME_FLAGS) as any
effect.effect_instruction_i0 = RuntimeFlagsPatch.disable(_runtimeFlags.Interruption)
effect.effect_instruction_i1 = () => self
return effect
}
/* @internal */
export const uninterruptibleMask = <A, E, R>(
f: (restore: <AX, EX, RX>(effect: Effect.Effect<AX, EX, RX>) => Effect.Effect<AX, EX, RX>) => Effect.Effect<A, E, R>
): Effect.Effect<A, E, R> =>
custom(f, function() {
const effect = new EffectPrimitive(OpCodes.OP_UPDATE_RUNTIME_FLAGS) as any
effect.effect_instruction_i0 = RuntimeFlagsPatch.disable(_runtimeFlags.Interruption)
effect.effect_instruction_i1 = (oldFlags: RuntimeFlags.RuntimeFlags) =>
_runtimeFlags.interruption(oldFlags)
? this.effect_instruction_i0(interruptible)
: this.effect_instruction_i0(uninterruptible)
return effect
})
/* @internal */
export const unit: Effect.Effect<void> = succeed(void 0)
/* @internal */
export const updateRuntimeFlags = (patch: RuntimeFlagsPatch.RuntimeFlagsPatch): Effect.Effect<void> => {
const effect = new EffectPrimitive(OpCodes.OP_UPDATE_RUNTIME_FLAGS) as any
effect.effect_instruction_i0 = patch
effect.effect_instruction_i1 = void 0
return effect
}
/* @internal */
export const whenEffect: {
<E, R>(
condition: Effect.Effect<boolean, E, R>
): <A, E2, R2>(
effect: Effect.Effect<A, E2, R2>
) => Effect.Effect<Option.Option<A>, E | E2, R | R2>
<A, E2, R2, E, R>(
self: Effect.Effect<A, E2, R2>,
condition: Effect.Effect<boolean, E, R>
): Effect.Effect<Option.Option<A>, E | E2, R | R2>
} = dual(2, <A, E2, R2, E, R>(
self: Effect.Effect<A, E2, R2>,
condition: Effect.Effect<boolean, E, R>
): Effect.Effect<Option.Option<A>, E | E2, R | R2> =>
flatMap(condition, (b) => {
if (b) {
return pipe(self, map(Option.some))
}
return succeed(Option.none())
}))
/* @internal */
export const whileLoop = <A, E, R>(
options: {
readonly while: LazyArg<boolean>
readonly body: LazyArg<Effect.Effect<A, E, R>>
readonly step: (a: A) => void
}
): Effect.Effect<void, E, R> => {
const effect = new EffectPrimitive(OpCodes.OP_WHILE) as any
effect.effect_instruction_i0 = options.while
effect.effect_instruction_i1 = options.body
effect.effect_instruction_i2 = options.step
return effect
}
/* @internal */
export const withConcurrency = dual<
(concurrency: number | "unbounded") => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
<A, E, R>(self: Effect.Effect<A, E, R>, concurrency: number | "unbounded") => Effect.Effect<A, E, R>
>(2, (self, concurrency) => fiberRefLocally(self, currentConcurrency, concurrency))
/* @internal */
export const withRequestBatching = dual<
(requestBatching: boolean) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
<A, E, R>(self: Effect.Effect<A, E, R>, requestBatching: boolean) => Effect.Effect<A, E, R>
>(2, (self, requestBatching) => fiberRefLocally(self, currentRequestBatching, requestBatching))
/* @internal */
export const withRuntimeFlags = dual<
(update: RuntimeFlagsPatch.RuntimeFlagsPatch) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
<A, E, R>(self: Effect.Effect<A, E, R>, update: RuntimeFlagsPatch.RuntimeFlagsPatch) => Effect.Effect<A, E, R>
>(2, (self, update) => {
const effect = new EffectPrimitive(OpCodes.OP_UPDATE_RUNTIME_FLAGS) as any
effect.effect_instruction_i0 = update
effect.effect_instruction_i1 = () => self
return effect
})
/** @internal */
export const withTracerEnabled = dual<
(enabled: boolean) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
<A, E, R>(effect: Effect.Effect<A, E, R>, enabled: boolean) => Effect.Effect<A, E, R>
>(2, (effect, enabled) =>
fiberRefLocally(
effect,
currentTracerEnabled,
enabled
))
/** @internal */
export const withTracerTiming = dual<
(enabled: boolean) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>,
<A, E, R>(effect: Effect.Effect<A, E, R>, enabled: boolean) => Effect.Effect<A, E, R>
>(2, (effect, enabled) =>
fiberRefLocally(
effect,
currentTracerTimingEnabled,
enabled
))
/* @internal */
export const yieldNow = (options?: {
readonly priority?: number | undefined
}): Effect.Effect<void> => {
const effect = new EffectPrimitive(OpCodes.OP_YIELD) as any
return typeof options?.priority !== "undefined" ?
withSchedulingPriority(effect, options.priority) :
effect
}
/* @internal */
export const zip = dual<
<A2, E2, R2>(
that: Effect.Effect<A2, E2, R2>
) => <A, E, R>(
self: Effect.Effect<A, E, R>
) => Effect.Effect<[A, A2], E | E2, R | R2>,
<A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
that: Effect.Effect<A2, E2, R2>
) => Effect.Effect<[A, A2], E | E2, R | R2>
>(2, <A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
that: Effect.Effect<A2, E2, R2>
): Effect.Effect<[A, A2], E | E2, R | R2> => flatMap(self, (a) => map(that, (b) => [a, b])))
/* @internal */
export const zipFlatten: {
<A2, E2, R2>(
that: Effect.Effect<A2, E2, R2>
): <A extends ReadonlyArray<any>, E, R>(
self: Effect.Effect<A, E, R>
) => Effect.Effect<[...A, A2], E | E2, R | R2>
<A extends ReadonlyArray<any>, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
that: Effect.Effect<A2, E2, R2>
): Effect.Effect<[...A, A2], E | E2, R | R2>
} = dual(2, <A extends ReadonlyArray<any>, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
that: Effect.Effect<A2, E2, R2>
): Effect.Effect<[...A, A2], E | E2, R | R2> => flatMap(self, (a) => map(that, (b) => [...a, b])))
/* @internal */
export const zipLeft: {
<A2, E2, R2>(
that: Effect.Effect<A2, E2, R2>
): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E | E2, R | R2>
<A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
that: Effect.Effect<A2, E2, R2>
): Effect.Effect<A, E | E2, R | R2>
} = dual(2, <A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
that: Effect.Effect<A2, E2, R2>
): Effect.Effect<A, E | E2, R | R2> => flatMap(self, (a) => as(that, a)))
/* @internal */
export const zipRight: {
<A2, E2, R2>(
that: Effect.Effect<A2, E2, R2>
): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A2, E | E2, R | R2>
<A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
that: Effect.Effect<A2, E2, R2>
): Effect.Effect<A2, E | E2, R | R2>
} = dual(2, <A, E, R, A2, E2, R2>(
self: Effect.Effect<A, E, R>,
that: Effect.Effect<A2, E2, R2>
): Effect.Effect<A2, E | E2, R | R2> => flatMap(self, () => that))
/* @internal */
export const zipWith: {
<A2, E2, R2, A, B>(
that: Effect.Effect<A2, E2, R2>,
f: (a: A, b: A2) => B
): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<B, E | E2, R | R2>
<A, E, R, A2, E2, R2, B>(
self: Effect.Effect<A, E, R>,
that: Effect.Effect<A2, E2, R2>,
f: (a: A, b: A2) => B
): Effect.Effect<B, E | E2, R | R2>
} = dual(3, <A, E, R, A2, E2, R2, B>(
self: Effect.Effect<A, E, R>,
that: Effect.Effect<A2, E2, R2>,
f: (a: A, b: A2) => B
): Effect.Effect<B, E | E2, R | R2> => flatMap(self, (a) => map(that, (b) => f(a, b))))
/* @internal */
export const never: Effect.Effect<never> = async<never>(() => {
const interval = setInterval(() => {
//
}, 2 ** 31 - 1)
return sync(() => clearInterval(interval))
})
// -----------------------------------------------------------------------------
// Fiber
// -----------------------------------------------------------------------------
/* @internal */
export const interruptFiber = <A, E>(self: Fiber.Fiber<A, E>): Effect.Effect<Exit.Exit<A, E>> =>
flatMap(fiberId, (fiberId) => pipe(self, interruptAsFiber(fiberId)))
/* @internal */
export const interruptAsFiber = dual<
(fiberId: FiberId.FiberId) => <A, E>(self: Fiber.Fiber<A, E