import * as Arr from "../Array.js"
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 * as Duration from "../Duration.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, type Predicate, type Refinement } from "../Predicate.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 { internalCall, YieldWrap } from "../Utils.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 { CommitPrototype, 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 { SingleShotGen } from "./singleShotGen.js"
// -----------------------------------------------------------------------------
// Effect
// -----------------------------------------------------------------------------
/**
* @internal
*/
export const blocked = (
blockedRequests: BlockedRequests.RequestBlock,
_continue: Effect.Effect
): Effect.Blocked => {
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 => {
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
| FromIterator
| WithRuntime
| Yield
| OpTag
| Blocked
| RunBlocked
| Either.Either
| Option.Option
/** @internal */
export type Continuation =
| OnSuccess
| OnStep
| OnSuccessAndFailure
| OnFailure
| While
| FromIterator
| 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 }
) {
}
}
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()
}
[Symbol.iterator]() {
return new SingleShotGen(new YieldWrap(this))
}
}
/** @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 exitIsExit(that) && that._op === "Failure" &&
// @ts-expect-error
Equal.equals(this.effect_instruction_i0, that.effect_instruction_i0)
}
[Hash.symbol](this: {}) {
return pipe(
// @ts-expect-error
Hash.string(this._tag),
// @ts-expect-error
Hash.combine(Hash.hash(this.effect_instruction_i0)),
Hash.cached(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()
}
[Symbol.iterator]() {
return new SingleShotGen(new YieldWrap(this))
}
}
/** @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 exitIsExit(that) && that._op === "Success" &&
// @ts-expect-error
Equal.equals(this.effect_instruction_i0, that.effect_instruction_i0)
}
[Hash.symbol](this: {}) {
return pipe(
// @ts-expect-error
Hash.string(this._tag),
// @ts-expect-error
Hash.combine(Hash.hash(this.effect_instruction_i0)),
Hash.cached(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()
}
[Symbol.iterator]() {
return new SingleShotGen(new YieldWrap(this))
}
}
/** @internal */
export type Op = Effect.Effect & Body & {
readonly _op: Tag
}
/** @internal */
export interface Async extends
Op void): void
readonly effect_instruction_i1: FiberId.FiberId
}>
{}
/** @internal */
export interface Blocked extends
Op<"Blocked", {
readonly effect_instruction_i0: BlockedRequests.RequestBlock
readonly effect_instruction_i1: Effect.Effect
}>
{}
/** @internal */
export interface RunBlocked extends
Op<"RunBlocked", {
readonly effect_instruction_i0: BlockedRequests.RequestBlock
}>
{}
/** @internal */
export interface Failure extends
Op
}>
{}
/** @internal */
export interface OpTag extends Op {}
/** @internal */
export interface Commit extends
Op
}>
{}
/** @internal */
export interface OnFailure extends
Op): Primitive
}>
{}
/** @internal */
export interface OnSuccess extends
Op
{}
/** @internal */
export interface OnStep extends Op<"OnStep", { readonly effect_instruction_i0: Primitive }> {}
/** @internal */
export interface OnSuccessAndFailure extends
Op): Primitive
effect_instruction_i2(a: unknown): Primitive
}>
{}
/** @internal */
export interface Success extends
Op
{}
/** @internal */
export interface Sync extends
Op
{}
/** @internal */
export interface UpdateRuntimeFlags extends
Op Primitive
}>
{}
/** @internal */
export interface While extends
Op
{}
/** @internal */
export interface FromIterator extends
Op, any>
}>
{}
/** @internal */
export interface WithRuntime extends
Op, status: FiberStatus.Running): Primitive
}>
{}
/** @internal */
export interface Yield extends Op {}
/** @internal */
export const isEffect = (u: unknown): u is Effect.Effect => hasProperty(u, EffectTypeId)
/* @internal */
export const withFiberRuntime = (
withRuntime: (fiber: FiberRuntime.FiberRuntime, status: FiberStatus.Running) => Effect.Effect
): Effect.Effect => {
const effect = new EffectPrimitive(OpCodes.OP_WITH_RUNTIME) as any
effect.effect_instruction_i0 = withRuntime
return effect
}
/* @internal */
export const acquireUseRelease: {
(
use: (a: A) => Effect.Effect,
release: (a: A, exit: Exit.Exit) => Effect.Effect
): (acquire: Effect.Effect) => Effect.Effect
(
acquire: Effect.Effect,
use: (a: A) => Effect.Effect,
release: (a: A, exit: Exit.Exit) => Effect.Effect
): Effect.Effect
} = dual(3, (
acquire: Effect.Effect,
use: (a: A) => Effect.Effect,
release: (a: A, exit: Exit.Exit) => Effect.Effect
): Effect.Effect =>
uninterruptibleMask((restore) =>
flatMap(
acquire,
(a) =>
flatMap(exit(suspend(() => restore(use(a)))), (exit): Effect.Effect => {
return suspend(() => release(a, exit)).pipe(
matchCauseEffect({
onFailure: (cause) => {
switch (exit._tag) {
case OpCodes.OP_FAILURE:
return failCause(internalCause.sequential(exit.effect_instruction_i0, cause))
case OpCodes.OP_SUCCESS:
return failCause(cause)
}
},
onSuccess: () => exit
})
)
})
)
))
/* @internal */
export const as: {
(value: B): (self: Effect.Effect) => Effect.Effect
(self: Effect.Effect, value: B): Effect.Effect
} = dual(
2,
(self: Effect.Effect, value: B): Effect.Effect => flatMap(self, () => succeed(value))
)
/* @internal */
export const asVoid = (self: Effect.Effect): Effect.Effect => as(self, void 0)
/* @internal */
export const custom: {
(i0: X, body: (this: { effect_instruction_i0: X }) => Effect.Effect): Effect.Effect
(
i0: X,
i1: Y,
body: (this: { effect_instruction_i0: X; effect_instruction_i1: Y }) => Effect.Effect
): Effect.Effect
(
i0: X,
i1: Y,
i2: Z,
body: (
this: { effect_instruction_i0: X; effect_instruction_i1: Y; effect_instruction_i2: Z }
) => Effect.Effect
): Effect.Effect
} = 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 unsafeAsync = (
register: (
callback: (_: Effect.Effect) => void
) => void | Effect.Effect,
blockingOn: FiberId.FiberId = FiberId.none
): Effect.Effect => {
const effect = new EffectPrimitive(OpCodes.OP_ASYNC) as any
let cancelerRef: Effect.Effect | void = undefined
effect.effect_instruction_i0 = (resume: (_: Effect.Effect) => void) => {
cancelerRef = register(resume)
}
effect.effect_instruction_i1 = blockingOn
return onInterrupt(effect, (_) => isEffect(cancelerRef) ? cancelerRef : void_)
}
/* @internal */
export const asyncInterrupt = (
register: (
callback: (_: Effect.Effect) => void
) => void | Effect.Effect,
blockingOn: FiberId.FiberId = FiberId.none
): Effect.Effect => suspend(() => unsafeAsync(register, blockingOn))
const async_ = (
resume: (
callback: (_: Effect.Effect) => void,
signal: AbortSignal
) => void | Effect.Effect,
blockingOn: FiberId.FiberId = FiberId.none
): Effect.Effect => {
return custom(resume, function() {
let backingResume: ((_: Effect.Effect) => void) | undefined = undefined
let pendingEffect: Effect.Effect | undefined = undefined
function proxyResume(effect: Effect.Effect) {
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) => void) => {
backingResume = resume
if (pendingEffect) {
resume(pendingEffect)
}
}
effect.effect_instruction_i1 = blockingOn
let cancelerRef: Effect.Effect | void = undefined
let controllerRef: AbortController | void = undefined
if (this.effect_instruction_i0.length !== 1) {
controllerRef = new AbortController()
cancelerRef = internalCall(() => this.effect_instruction_i0(proxyResume, controllerRef!.signal))
} else {
cancelerRef = internalCall(() => (this.effect_instruction_i0 as any)(proxyResume))
}
return (cancelerRef || controllerRef) ?
onInterrupt(effect, (_) => {
if (controllerRef) {
controllerRef.abort()
}
return cancelerRef ?? void_
}) :
effect
})
}
export {
/** @internal */
async_ as async
}
/* @internal */
export const catchAllCause = dual<
(
f: (cause: Cause.Cause) => Effect.Effect
) => (self: Effect.Effect) => Effect.Effect,
(
self: Effect.Effect,
f: (cause: Cause.Cause) => Effect.Effect
) => Effect.Effect
>(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: {
(
f: (e: E) => Effect.Effect
): (self: Effect.Effect) => Effect.Effect
(
self: Effect.Effect,
f: (e: E) => Effect.Effect
): Effect.Effect
} = dual(
2,
(
self: Effect.Effect,
f: (e: E) => Effect.Effect
): Effect.Effect => matchEffect(self, { onFailure: f, onSuccess: succeed })
)
/* @internal */
export const catchIf: {
(
refinement: Refinement, EB>,
f: (e: EB) => Effect.Effect
): (self: Effect.Effect) => Effect.Effect, R2 | R>
(
predicate: Predicate>,
f: (e: NoInfer) => Effect.Effect
): (self: Effect.Effect) => Effect.Effect
(
self: Effect.Effect,
refinement: Refinement,
f: (e: EB) => Effect.Effect
): Effect.Effect, R2 | R>
(
self: Effect.Effect,
predicate: Predicate,
f: (e: E) => Effect.Effect
): Effect.Effect
} = dual(3, (
self: Effect.Effect,
predicate: Predicate,
f: (e: E) => Effect.Effect
): Effect.Effect =>
catchAllCause(self, (cause): Effect.Effect => {
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<
(
pf: (e: NoInfer) => Option.Option>
) => (self: Effect.Effect) => Effect.Effect,
(
self: Effect.Effect,
pf: (e: NoInfer) => Option.Option>
) => Effect.Effect
>(2, (
self: Effect.Effect,
pf: (e: NoInfer) => Option.Option>
) =>
catchAllCause(self, (cause): Effect.Effect => {
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 = (
f: (isInterruptible: boolean) => Effect.Effect
): Effect.Effect => withFiberRuntime((_, status) => f(runtimeFlags_.interruption(status.runtimeFlags)))
const originalSymbol = Symbol.for("effect/OriginalAnnotation")
/* @internal */
export const originalInstance = (obj: E): E => {
if (hasProperty(obj, originalSymbol)) {
// @ts-expect-error
return obj[originalSymbol]
}
return obj
}
/* @internal */
export const capture = (obj: E & object, span: Option.Option): E => {
if (Option.isSome(span)) {
return new Proxy(obj, {
has(target, p) {
return p === internalCause.spanSymbol || p === originalSymbol || p in target
},
get(target, p) {
if (p === internalCause.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 =>
isObject(defect) && !(internalCause.spanSymbol in defect) ?
withFiberRuntime((fiber) => failCause(internalCause.die(capture(defect, currentSpanFromFiber(fiber)))))
: failCause(internalCause.die(defect))
/* @internal */
export const dieMessage = (message: string): Effect.Effect =>
failCauseSync(() => internalCause.die(new RuntimeException(message)))
/* @internal */
export const dieSync = (evaluate: LazyArg): Effect.Effect => flatMap(sync(evaluate), die)
/* @internal */
export const either = (self: Effect.Effect): Effect.Effect, never, R> =>
matchEffect(self, {
onFailure: (e) => succeed(Either.left(e)),
onSuccess: (a) => succeed(Either.right(a))
})
/* @internal */
export const exit = (self: Effect.Effect): Effect.Effect, never, R> =>
matchCause(self, {
onFailure: exitFailCause,
onSuccess: exitSucceed
})
/* @internal */
export const fail = (error: E): Effect.Effect =>
isObject(error) && !(internalCause.spanSymbol in error) ?
withFiberRuntime((fiber) => failCause(internalCause.fail(capture(error, currentSpanFromFiber(fiber)))))
: failCause(internalCause.fail(error))
/* @internal */
export const failSync = (evaluate: LazyArg): Effect.Effect => flatMap(sync(evaluate), fail)
/* @internal */
export const failCause = (cause: Cause.Cause): Effect.Effect => {
const effect = new EffectPrimitiveFailure(OpCodes.OP_FAILURE) as any
effect.effect_instruction_i0 = cause
return effect
}
/* @internal */
export const failCauseSync = (
evaluate: LazyArg>
): Effect.Effect => flatMap(sync(evaluate), failCause)
/* @internal */
export const fiberId: Effect.Effect = withFiberRuntime((state) => succeed(state.id()))
/* @internal */
export const fiberIdWith = (
f: (descriptor: FiberId.Runtime) => Effect.Effect
): Effect.Effect => withFiberRuntime((state) => f(state.id()))
/* @internal */
export const flatMap = dual<
(
f: (a: A) => Effect.Effect
) => (self: Effect.Effect) => Effect.Effect,
(
self: Effect.Effect,
f: (a: A) => Effect.Effect
) => Effect.Effect
>(
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: {
(
f: (a: NoInfer) => X
): (
self: Effect.Effect
) => [X] extends [Effect.Effect] ? Effect.Effect
: [X] extends [PromiseLike] ? Effect.Effect
: Effect.Effect
(
f: NotFunction
): (
self: Effect.Effect
) => [X] extends [Effect.Effect] ? Effect.Effect
: [X] extends [PromiseLike] ? Effect.Effect
: Effect.Effect
(
self: Effect.Effect,
f: (a: NoInfer) => X
): [X] extends [Effect.Effect] ? Effect.Effect
: [X] extends [PromiseLike] ? Effect.Effect
: Effect.Effect
(
self: Effect.Effect,
f: NotFunction
): [X] extends [Effect.Effect] ? Effect.Effect
: [X] extends [PromiseLike] ? Effect.Effect
: Effect.Effect
} = 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 unsafeAsync((resume) => {
b.then((a) => resume(succeed(a)), (e) =>
resume(fail(new UnknownException(e, "An unknown error occurred in Effect.andThen"))))
})
}
return succeed(b)
}))
/* @internal */
export const step = (
self: Effect.Effect
): Effect.Effect | Effect.Blocked, never, R> => {
const effect = new EffectPrimitive("OnStep") as any
effect.effect_instruction_i0 = self
return effect
}
/* @internal */
export const flatten = (
self: Effect.Effect, E, R>
): Effect.Effect => flatMap(self, identity)
/* @internal */
export const flip = (self: Effect.Effect): Effect.Effect =>
matchEffect(self, { onFailure: succeed, onSuccess: fail })
/* @internal */
export const matchCause: {
(
options: {
readonly onFailure: (cause: Cause.Cause) => A2
readonly onSuccess: (a: A) => A3
}
): (self: Effect.Effect) => Effect.Effect
(
self: Effect.Effect,
options: {
readonly onFailure: (cause: Cause.Cause) => A2
readonly onSuccess: (a: A) => A3
}
): Effect.Effect
} = dual(2, (
self: Effect.Effect,
options: {
readonly onFailure: (cause: Cause.Cause) => A2
readonly onSuccess: (a: A) => A3
}
): Effect.Effect =>
matchCauseEffect(self, {
onFailure: (cause) => succeed(options.onFailure(cause)),
onSuccess: (a) => succeed(options.onSuccess(a))
}))
/* @internal */
export const matchCauseEffect: {
(
options: {
readonly onFailure: (cause: Cause.Cause) => Effect.Effect
readonly onSuccess: (a: A) => Effect.Effect
}
): (self: Effect.Effect) => Effect.Effect
(
self: Effect.Effect,
options: {
readonly onFailure: (cause: Cause.Cause) => Effect.Effect
readonly onSuccess: (a: A) => Effect.Effect
}
): Effect.Effect
} = dual(2, (
self: Effect.Effect,
options: {
readonly onFailure: (cause: Cause.Cause) => Effect.Effect
readonly onSuccess: (a: A) => Effect.Effect
}
): Effect.Effect => {
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: {
(
options: {
readonly onFailure: (e: E) => Effect.Effect
readonly onSuccess: (a: A) => Effect.Effect
}
): (self: Effect.Effect) => Effect.Effect
(
self: Effect.Effect,
options: {
readonly onFailure: (e: E) => Effect.Effect
readonly onSuccess: (a: A) => Effect.Effect
}
): Effect.Effect
} = dual(2, (
self: Effect.Effect,
options: {
readonly onFailure: (e: E) => Effect.Effect
readonly onSuccess: (a: A) => Effect.Effect
}
): Effect.Effect =>
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)
},
onSuccess: options.onSuccess
}))
/* @internal */
export const forEachSequential: {
(f: (a: A, i: number) => Effect.Effect): (self: Iterable) => Effect.Effect, E, R>
(self: Iterable, f: (a: A, i: number) => Effect.Effect): Effect.Effect, E, R>
} = dual(
2,
(self: Iterable, f: (a: A, i: number) => Effect.Effect): Effect.Effect, E, R> =>
suspend(() => {
const arr = Arr.fromIterable(self)
const ret = Arr.allocate(arr.length)
let i = 0
return as(
whileLoop({
while: () => i < arr.length,
body: () => f(arr[i], i),
step: (b) => {
ret[i++] = b
}
}),
ret as Array
)
})
)
/* @internal */
export const forEachSequentialDiscard: {
(f: (a: A, i: number) => Effect.Effect): (self: Iterable) => Effect.Effect
(self: Iterable, f: (a: A, i: number) => Effect.Effect): Effect.Effect
} = dual(
2,
(self: Iterable, f: (a: A, i: number) => Effect.Effect): Effect.Effect =>
suspend(() => {
const arr = Arr.fromIterable(self)
let i = 0
return whileLoop({
while: () => i < arr.length,
body: () => f(arr[i], i),
step: () => {
i++
}
})
})
)
/* @internal */
export const if_ = dual<
(
options: {
readonly onTrue: LazyArg