UNPKG

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,497 lines (1,401 loc) 74.3 kB
import type * as Cause from "../Cause.js" import * as Chunk from "../Chunk.js" import * as Clock from "../Clock.js" import * as Context from "../Context.js" import * as Duration from "../Duration.js" import type * as Effect from "../Effect.js" import type * as Fiber from "../Fiber.js" import type * as FiberId from "../FiberId.js" import type * as FiberRef from "../FiberRef.js" import * as FiberRefs from "../FiberRefs.js" import type * as FiberRefsPatch from "../FiberRefsPatch.js" import type { LazyArg } from "../Function.js" import { constFalse, constTrue, constVoid, dual, identity, pipe } from "../Function.js" import * as HashMap from "../HashMap.js" import * as HashSet from "../HashSet.js" import * as List from "../List.js" import * as LogLevel from "../LogLevel.js" import * as LogSpan from "../LogSpan.js" import type * as Metric from "../Metric.js" import type * as MetricLabel from "../MetricLabel.js" import * as Option from "../Option.js" import * as Predicate from "../Predicate.js" import type * as Random from "../Random.js" import * as ReadonlyArray from "../ReadonlyArray.js" import * as Ref from "../Ref.js" import type * as runtimeFlagsPatch from "../RuntimeFlagsPatch.js" import * as Tracer from "../Tracer.js" import type { MergeRecord, NoInfer } from "../Types.js" import * as internalCause from "./cause.js" import { clockTag } from "./clock.js" import * as core from "./core.js" import * as defaultServices from "./defaultServices.js" import * as fiberRefsPatch from "./fiberRefs/patch.js" import type { FiberRuntime } from "./fiberRuntime.js" import * as metricLabel from "./metric/label.js" import * as runtimeFlags from "./runtimeFlags.js" import * as SingleShotGen from "./singleShotGen.js" import * as internalTracer from "./tracer.js" /* @internal */ export const annotateLogs = dual< { (key: string, value: unknown): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> ( values: Record<string, unknown> ): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> }, { <A, E, R>(effect: Effect.Effect<A, E, R>, key: string, value: unknown): Effect.Effect<A, E, R> <A, E, R>(effect: Effect.Effect<A, E, R>, values: Record<string, unknown>): Effect.Effect<A, E, R> } >( (args) => core.isEffect(args[0]), function<A, E, R>() { const args = arguments return core.fiberRefLocallyWith( args[0] as Effect.Effect<A, E, R>, core.currentLogAnnotations, typeof args[1] === "string" ? HashMap.set(args[1], args[2]) : (annotations) => Object.entries(args[1] as Record<string, unknown>).reduce( (acc, [key, value]) => HashMap.set(acc, key, value), annotations ) ) } ) /* @internal */ export const asSome = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<Option.Option<A>, E, R> => core.map(self, Option.some) /* @internal */ export const asSomeError = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, Option.Option<E>, R> => core.mapError(self, Option.some) /* @internal */ export const try_: { <A, E>(options: { readonly try: LazyArg<A> readonly catch: (error: unknown) => E }): Effect.Effect<A, E> <A>(evaluate: LazyArg<A>): Effect.Effect<A, Cause.UnknownException> } = <A, E>( arg: LazyArg<A> | { readonly try: LazyArg<A> readonly catch: (error: unknown) => E } ) => { let evaluate: LazyArg<A> let onFailure: ((error: unknown) => E) | undefined = undefined if (typeof arg === "function") { evaluate = arg } else { evaluate = arg.try onFailure = arg.catch } return core.sync(() => { try { return evaluate() } catch (error) { throw core.makeEffectError(internalCause.fail( onFailure ? onFailure(error) : new core.UnknownException(error) )) } }) } /* @internal */ export const _catch: { <N extends keyof E, K extends E[N] & string, E, A1, E1, R1>( discriminator: N, options: { readonly failure: K readonly onFailure: (error: Extract<E, { [n in N]: K }>) => Effect.Effect<A1, E1, R1> } ): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect< A | A1, Exclude<E, { [n in N]: K }> | E1, R | R1 > <A, E, R, N extends keyof E, K extends E[N] & string, A1, E1, R1>( self: Effect.Effect<A, E, R>, discriminator: N, options: { readonly failure: K readonly onFailure: (error: Extract<E, { [n in N]: K }>) => Effect.Effect<A1, E1, R1> } ): Effect.Effect<A | A1, Exclude<E, { [n in N]: K }> | E1, R | R1> } = dual( 3, (self, tag, options) => core.catchAll(self, (e) => { if (Predicate.hasProperty(e, tag) && e[tag] === options.failure) { return options.onFailure(e) } return core.fail(e) }) ) /* @internal */ export const catchAllDefect = dual< <A2, E2, R2>( f: (defect: unknown) => 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>, f: (defect: unknown) => 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>, f: (defect: unknown) => Effect.Effect<A2, E2, R2> ): Effect.Effect<A | A2, E | E2, R | R2> => core.catchAllCause( self, (cause): Effect.Effect<A | A2, E | E2, R | R2> => { const option = internalCause.find(cause, (_) => internalCause.isDieType(_) ? Option.some(_) : Option.none()) switch (option._tag) { case "None": { return core.failCause(cause) } case "Some": { return f(option.value.defect) } } } )) /* @internal */ export const catchSomeCause: { <E, A2, E2, R2>( f: (cause: Cause.Cause<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>, f: (cause: Cause.Cause<NoInfer<E>>) => Option.Option<Effect.Effect<A2, E2, R2>> ): Effect.Effect<A2 | A, E | E2, R2 | R> } = dual( 2, <A, E, R, A2, E2, R2>( self: Effect.Effect<A, E, R>, f: (cause: Cause.Cause<NoInfer<E>>) => Option.Option<Effect.Effect<A2, E2, R2>> ): Effect.Effect<A2 | A, E | E2, R2 | R> => core.matchCauseEffect(self, { onFailure: (cause): Effect.Effect<A2, E | E2, R2> => { const option = f(cause) switch (option._tag) { case "None": { return core.failCause(cause) } case "Some": { return option.value } } }, onSuccess: core.succeed }) ) /* @internal */ export const catchSomeDefect = dual< <A2, E2, R2>( pf: (defect: unknown) => Option.Option<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>, pf: (defect: unknown) => Option.Option<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>, pf: (defect: unknown) => Option.Option<Effect.Effect<A2, E2, R2>> ): Effect.Effect<A | A2, E | E2, R | R2> => core.catchAllCause( self, (cause): Effect.Effect<A | A2, E | E2, R | R2> => { const option = internalCause.find(cause, (_) => internalCause.isDieType(_) ? Option.some(_) : Option.none()) switch (option._tag) { case "None": { return core.failCause(cause) } case "Some": { const optionEffect = pf(option.value.defect) return optionEffect._tag === "Some" ? optionEffect.value : core.failCause(cause) } } } ) ) /* @internal */ export const catchTag = dual< <K extends (E extends { _tag: string } ? E["_tag"] : never), E, A1, E1, R1>( k: K, f: (e: Extract<E, { _tag: K }>) => Effect.Effect<A1, E1, R1> ) => <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | A1, Exclude<E, { _tag: K }> | E1, R | R1>, <A, E, R, K extends (E extends { _tag: string } ? E["_tag"] : never), R1, E1, A1>( self: Effect.Effect<A, E, R>, k: K, f: (e: Extract<E, { _tag: K }>) => Effect.Effect<A1, E1, R1> ) => Effect.Effect<A | A1, Exclude<E, { _tag: K }> | E1, R | R1> >(3, <A, E, R, K extends (E extends { _tag: string } ? E["_tag"] : never), R1, E1, A1>( self: Effect.Effect<A, E, R>, k: K, f: (e: Extract<E, { _tag: K }>) => Effect.Effect<A1, E1, R1> ): Effect.Effect<A | A1, Exclude<E, { _tag: K }> | E1, R | R1> => core.catchIf(self, Predicate.isTagged(k) as Predicate.Refinement<E, Extract<E, { _tag: K }>>, f) as any) /** @internal */ export const catchTags: { < E, Cases extends (E extends { _tag: string } ? { [K in E["_tag"]]+?: (error: Extract<E, { _tag: K }>) => Effect.Effect<any, any, any> } : {}) >( cases: Cases ): <A, R>(self: Effect.Effect<A, E, R>) => Effect.Effect< | A | { [K in keyof Cases]: Cases[K] extends ((...args: Array<any>) => Effect.Effect<infer A, any, any>) ? A : never }[keyof Cases], | Exclude<E, { _tag: keyof Cases }> | { [K in keyof Cases]: Cases[K] extends ((...args: Array<any>) => Effect.Effect<any, infer E, any>) ? E : never }[keyof Cases], | R | { [K in keyof Cases]: Cases[K] extends ((...args: Array<any>) => Effect.Effect<any, any, infer R>) ? R : never }[keyof Cases] > < R, E, A, Cases extends (E extends { _tag: string } ? { [K in E["_tag"]]+?: (error: Extract<E, { _tag: K }>) => Effect.Effect<any, any, any> } : {}) >( self: Effect.Effect<A, E, R>, cases: Cases ): Effect.Effect< | A | { [K in keyof Cases]: Cases[K] extends ((...args: Array<any>) => Effect.Effect<infer A, any, any>) ? A : never }[keyof Cases], | Exclude<E, { _tag: keyof Cases }> | { [K in keyof Cases]: Cases[K] extends ((...args: Array<any>) => Effect.Effect<any, infer E, any>) ? E : never }[keyof Cases], | R | { [K in keyof Cases]: Cases[K] extends ((...args: Array<any>) => Effect.Effect<any, any, infer R>) ? R : never }[keyof Cases] > } = dual(2, (self, cases) => { let keys: Array<string> return core.catchIf( self, (e): e is { readonly _tag: string } => { keys ??= Object.keys(cases) return Predicate.hasProperty(e, "_tag") && Predicate.isString(e["_tag"]) && keys.includes(e["_tag"]) }, (e) => cases[e["_tag"]](e) ) }) /* @internal */ export const cause = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<Cause.Cause<E>, never, R> => core.matchCause(self, { onFailure: identity, onSuccess: () => internalCause.empty }) /* @internal */ export const clockWith: <A, E, R>(f: (clock: Clock.Clock) => Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> = Clock.clockWith /* @internal */ export const clock: Effect.Effect<Clock.Clock> = clockWith(core.succeed) /* @internal */ export const delay = dual< (duration: Duration.DurationInput) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>, <A, E, R>(self: Effect.Effect<A, E, R>, duration: Duration.DurationInput) => Effect.Effect<A, E, R> >(2, (self, duration) => core.zipRight(Clock.sleep(duration), self)) /* @internal */ export const descriptorWith = <A, E, R>( f: (descriptor: Fiber.Fiber.Descriptor) => Effect.Effect<A, E, R> ): Effect.Effect<A, E, R> => core.withFiberRuntime((state, status) => f({ id: state.id(), status, interruptors: internalCause.interruptors(state.getFiberRef(core.currentInterruptedCause)) }) ) as Effect.Effect<A, E, R> /* @internal */ export const allowInterrupt: Effect.Effect<void> = descriptorWith( (descriptor) => HashSet.size(descriptor.interruptors) > 0 ? core.interrupt : core.unit ) /* @internal */ export const descriptor: Effect.Effect<Fiber.Fiber.Descriptor> = descriptorWith(core.succeed) /* @internal */ export const diffFiberRefs = <A, E, R>( self: Effect.Effect<A, E, R> ): Effect.Effect<[FiberRefsPatch.FiberRefsPatch, A], E, R> => summarized(self, fiberRefs, fiberRefsPatch.diff) /* @internal */ export const diffFiberRefsAndRuntimeFlags = <A, E, R>( self: Effect.Effect<A, E, R> ): Effect.Effect<[[FiberRefsPatch.FiberRefsPatch, runtimeFlagsPatch.RuntimeFlagsPatch], A], E, R> => summarized( self, core.zip(fiberRefs, core.runtimeFlags), ([refs, flags], [refsNew, flagsNew]) => [fiberRefsPatch.diff(refs, refsNew), runtimeFlags.diff(flags, flagsNew)] ) /* @internal */ export const Do: Effect.Effect<{}> = core.succeed({}) /* @internal */ export const bind: { <N extends string, K, A, E2, R2>( tag: Exclude<N, keyof K>, f: (_: K) => Effect.Effect<A, E2, R2> ): <E, R>(self: Effect.Effect<K, E, R>) => Effect.Effect<MergeRecord<K, { [k in N]: A }>, E2 | E, R2 | R> <K, E, R, N extends string, A, E2, R2>( self: Effect.Effect<K, E, R>, tag: Exclude<N, keyof K>, f: (_: K) => Effect.Effect<A, E2, R2> ): Effect.Effect<MergeRecord<K, { [k in N]: A }>, E2 | E, R2 | R> } = dual(3, <K, E, R, N extends string, A, E2, R2>( self: Effect.Effect<K, E, R>, tag: Exclude<N, keyof K>, f: (_: K) => Effect.Effect<A, E2, R2> ): Effect.Effect<MergeRecord<K, { [k in N]: A }>, E2 | E, R2 | R> => core.flatMap(self, (k) => core.map( f(k), (a): MergeRecord<K, { [k in N]: A }> => ({ ...k, [tag]: a } as any) ))) /* @internal */ export const bindTo: { <N extends string>(tag: N): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<Record<N, A>, E, R> <A, E, R, N extends string>(self: Effect.Effect<A, E, R>, tag: N): Effect.Effect<Record<N, A>, E, R> } = dual( 2, <A, E, R, N extends string>(self: Effect.Effect<A, E, R>, tag: N): Effect.Effect<Record<N, A>, E, R> => core.map(self, (a) => ({ [tag]: a } as Record<N, A>)) ) /* @internal */ export const let_: { <N extends string, K, A>( tag: Exclude<N, keyof K>, f: (_: K) => A ): <E, R>(self: Effect.Effect<K, E, R>) => Effect.Effect<MergeRecord<K, { [k in N]: A }>, E, R> <K, E, R, N extends string, A>( self: Effect.Effect<K, E, R>, tag: Exclude<N, keyof K>, f: (_: K) => A ): Effect.Effect<MergeRecord<K, { [k in N]: A }>, E, R> } = dual(3, <K, E, R, N extends string, A>( self: Effect.Effect<K, E, R>, tag: Exclude<N, keyof K>, f: (_: K) => A ): Effect.Effect<MergeRecord<K, { [k in N]: A }>, E, R> => core.map( self, (k): MergeRecord<K, { [k in N]: A }> => ({ ...k, [tag]: f(k) } as any) )) /* @internal */ export const dropUntil: { <A, E, R>( predicate: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R> ): (elements: Iterable<A>) => Effect.Effect<Array<A>, E, R> <A, E, R>( elements: Iterable<A>, predicate: (a: A, i: number) => Effect.Effect<boolean, E, R> ): Effect.Effect<Array<A>, E, R> } = dual( 2, <A, E, R>( elements: Iterable<A>, predicate: (a: A, i: number) => Effect.Effect<boolean, E, R> ): Effect.Effect<Array<A>, E, R> => core.suspend(() => { const iterator = elements[Symbol.iterator]() const builder: Array<A> = [] let next: IteratorResult<A, any> let dropping: Effect.Effect<boolean, E, R> = core.succeed(false) let i = 0 while ((next = iterator.next()) && !next.done) { const a = next.value const index = i++ dropping = core.flatMap(dropping, (bool) => { if (bool) { builder.push(a) return core.succeed(true) } return predicate(a, index) }) } return core.map(dropping, () => builder) }) ) /* @internal */ export const dropWhile: { <A, E, R>( predicate: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R> ): (elements: Iterable<A>) => Effect.Effect<Array<A>, E, R> <A, E, R>( elements: Iterable<A>, predicate: (a: A, i: number) => Effect.Effect<boolean, E, R> ): Effect.Effect<Array<A>, E, R> } = dual( 2, <A, E, R>( elements: Iterable<A>, predicate: (a: A, i: number) => Effect.Effect<boolean, E, R> ): Effect.Effect<Array<A>, E, R> => core.suspend(() => { const iterator = elements[Symbol.iterator]() const builder: Array<A> = [] let next let dropping: Effect.Effect<boolean, E, R> = core.succeed(true) let i = 0 while ((next = iterator.next()) && !next.done) { const a = next.value const index = i++ dropping = core.flatMap(dropping, (d) => core.map(d ? predicate(a, index) : core.succeed(false), (b) => { if (!b) { builder.push(a) } return b })) } return core.map(dropping, () => builder) }) ) /* @internal */ export const contextWith = <R, A>(f: (context: Context.Context<R>) => A): Effect.Effect<A, never, R> => core.map(core.context<R>(), f) /* @internal */ export const eventually = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, never, R> => core.orElse(self, () => core.flatMap(core.yieldNow(), () => eventually(self))) /* @internal */ export const filterMap = dual< <Eff extends Effect.Effect<any, any, any>, B>( pf: (a: Effect.Effect.Success<Eff>) => Option.Option<B> ) => (elements: Iterable<Eff>) => Effect.Effect<Array<B>, Effect.Effect.Error<Eff>, Effect.Effect.Context<Eff>>, <Eff extends Effect.Effect<any, any, any>, B>( elements: Iterable<Eff>, pf: (a: Effect.Effect.Success<Eff>) => Option.Option<B> ) => Effect.Effect<Array<B>, Effect.Effect.Error<Eff>, Effect.Effect.Context<Eff>> >(2, (elements, pf) => core.map( core.forEachSequential(elements, identity), ReadonlyArray.filterMap(pf) )) /* @internal */ export const filterOrDie: { <A, B extends A>( refinement: Predicate.Refinement<NoInfer<A>, B>, orDieWith: (a: NoInfer<A>) => unknown ): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<B, E, R> <A>( predicate: Predicate.Predicate<NoInfer<A>>, orDieWith: (a: NoInfer<A>) => unknown ): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> <A, E, R, B extends A>( self: Effect.Effect<A, E, R>, refinement: Predicate.Refinement<A, B>, orDieWith: (a: A) => unknown ): Effect.Effect<B, E, R> <A, E, R>( self: Effect.Effect<A, E, R>, predicate: Predicate.Predicate<A>, orDieWith: (a: A) => unknown ): Effect.Effect<A, E, R> } = dual( 3, <A, E, R>( self: Effect.Effect<A, E, R>, predicate: Predicate.Predicate<A>, orDieWith: (a: A) => unknown ): Effect.Effect<A, E, R> => filterOrElse(self, predicate, (a) => core.dieSync(() => orDieWith(a))) ) /* @internal */ export const filterOrDieMessage: { <A, B extends A>( refinement: Predicate.Refinement<NoInfer<A>, B>, message: string ): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<B, E, R> <A>( predicate: Predicate.Predicate<NoInfer<A>>, message: string ): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> <A, E, R, B extends A>( self: Effect.Effect<A, E, R>, refinement: Predicate.Refinement<A, B>, message: string ): Effect.Effect<B, E, R> <A, E, R>(self: Effect.Effect<A, E, R>, predicate: Predicate.Predicate<A>, message: string): Effect.Effect<A, E, R> } = dual( 3, <A, E, R>(self: Effect.Effect<A, E, R>, predicate: Predicate.Predicate<A>, message: string): Effect.Effect<A, E, R> => filterOrElse(self, predicate, () => core.dieMessage(message)) ) /* @internal */ export const filterOrElse: { <A, B extends A, C, E2, R2>( refinement: Predicate.Refinement<NoInfer<A>, B>, orElse: (a: NoInfer<A>) => Effect.Effect<C, E2, R2> ): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<B | C, E2 | E, R2 | R> <A, B, E2, R2>( predicate: Predicate.Predicate<NoInfer<A>>, orElse: (a: NoInfer<A>) => Effect.Effect<B, E2, R2> ): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | B, E2 | E, R2 | R> <A, E, R, B extends A, C, E2, R2>( self: Effect.Effect<A, E, R>, refinement: Predicate.Refinement<A, B>, orElse: (a: A) => Effect.Effect<C, E2, R2> ): Effect.Effect<B | C, E | E2, R | R2> <A, E, R, B, E2, R2>( self: Effect.Effect<A, E, R>, predicate: Predicate.Predicate<A>, orElse: (a: A) => Effect.Effect<B, E2, R2> ): Effect.Effect<A | B, E | E2, R | R2> } = dual(3, <A, E, R, B, E2, R2>( self: Effect.Effect<A, E, R>, predicate: Predicate.Predicate<A>, orElse: (a: A) => Effect.Effect<B, E2, R2> ): Effect.Effect<A | B, E | E2, R | R2> => core.flatMap( self, (a) => predicate(a) ? core.succeed<A | B>(a) : orElse(a) )) /* @internal */ export const filterOrFail: { <A, B extends A, E2>( refinement: Predicate.Refinement<NoInfer<A>, B>, orFailWith: (a: NoInfer<A>) => E2 ): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<B, E2 | E, R> <A, E2>( predicate: Predicate.Predicate<NoInfer<A>>, orFailWith: (a: NoInfer<A>) => E2 ): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E2 | E, R> <A, B extends A>( refinement: Predicate.Refinement<NoInfer<A>, B> ): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<B, Cause.NoSuchElementException | E, R> <A>( predicate: Predicate.Predicate<NoInfer<A>> ): <E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, Cause.NoSuchElementException | E, R> <A, E, R, B extends A, E2>( self: Effect.Effect<A, E, R>, refinement: Predicate.Refinement<A, B>, orFailWith: (a: A) => E2 ): Effect.Effect<B, E | E2, R> <A, E, R, E2>( self: Effect.Effect<A, E, R>, predicate: Predicate.Predicate<A>, orFailWith: (a: A) => E2 ): Effect.Effect<A, E | E2, R> <A, E, R, B extends A>( self: Effect.Effect<A, E, R>, refinement: Predicate.Refinement<A, B> ): Effect.Effect<B, E | Cause.NoSuchElementException, R> <A, E, R>( self: Effect.Effect<A, E, R>, predicate: Predicate.Predicate<A> ): Effect.Effect<A, E | Cause.NoSuchElementException, R> } = dual((args) => core.isEffect(args[0]), <A, E, R, E2>( self: Effect.Effect<A, E, R>, predicate: Predicate.Predicate<A>, orFailWith?: (a: A) => E2 ): Effect.Effect<A, E | E2 | Cause.NoSuchElementException, R> => filterOrElse( self, predicate, (a): Effect.Effect<never, E2 | Cause.NoSuchElementException, never> => orFailWith === undefined ? core.fail(new core.NoSuchElementException()) : core.failSync(() => orFailWith(a)) )) /* @internal */ export const findFirst: { <A, E, R>( f: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R> ): (elements: Iterable<A>) => Effect.Effect<Option.Option<A>, E, R> <A, E, R>( elements: Iterable<A>, f: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R> ): Effect.Effect<Option.Option<A>, E, R> } = dual( 2, <A, E, R>( elements: Iterable<A>, f: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R> ): Effect.Effect<Option.Option<A>, E, R> => core.suspend(() => { const iterator = elements[Symbol.iterator]() const next = iterator.next() if (!next.done) { return findLoop(iterator, 0, f, next.value) } return core.succeed(Option.none()) }) ) const findLoop = <A, E, R>( iterator: Iterator<A>, index: number, f: (a: A, i: number) => Effect.Effect<boolean, E, R>, value: A ): Effect.Effect<Option.Option<A>, E, R> => core.flatMap(f(value, index), (result) => { if (result) { return core.succeed(Option.some(value)) } const next = iterator.next() if (!next.done) { return findLoop(iterator, index + 1, f, next.value) } return core.succeed(Option.none()) }) /* @internal */ export const firstSuccessOf = <Eff extends Effect.Effect<any, any, any>>( effects: Iterable<Eff> ): Effect.Effect<Effect.Effect.Success<Eff>, Effect.Effect.Error<Eff>, Effect.Effect.Context<Eff>> => core.suspend(() => { const list = Chunk.fromIterable(effects) if (!Chunk.isNonEmpty(list)) { return core.dieSync(() => new core.IllegalArgumentException(`Received an empty collection of effects`)) } return pipe( Chunk.tailNonEmpty(list), ReadonlyArray.reduce(Chunk.headNonEmpty(list), (left, right) => core.orElse(left, () => right) as Eff) ) }) /* @internal */ export const flipWith: { <E, A, R, E2, A2, R2>( f: (effect: Effect.Effect<E, A, R>) => Effect.Effect<E2, A2, R2> ): (self: Effect.Effect<A, E, R>) => Effect.Effect<A2, E2, R2> <A, E, R, E2, A2, R2>( self: Effect.Effect<A, E, R>, f: (effect: Effect.Effect<E, A, R>) => Effect.Effect<E2, A2, R2> ): Effect.Effect<A2, E2, R2> } = dual(2, <A, E, R, E2, A2, R2>( self: Effect.Effect<A, E, R>, f: (effect: Effect.Effect<E, A, R>) => Effect.Effect<E2, A2, R2> ): Effect.Effect<A2, E2, R2> => core.flip(f(core.flip(self)))) /* @internal */ export const match: { <E, A2, A, A3>( options: { readonly onFailure: (error: E) => A2 readonly onSuccess: (value: 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: (error: E) => A2 readonly onSuccess: (value: A) => A3 } ): Effect.Effect<A2 | A3, never, R> } = dual(2, <A, E, R, A2, A3>( self: Effect.Effect<A, E, R>, options: { readonly onFailure: (error: E) => A2 readonly onSuccess: (value: A) => A3 } ): Effect.Effect<A2 | A3, never, R> => core.matchEffect(self, { onFailure: (e) => core.succeed(options.onFailure(e)), onSuccess: (a) => core.succeed(options.onSuccess(a)) })) /* @internal */ export const every: { <A, E, R>( f: (a: A, i: number) => Effect.Effect<boolean, E, R> ): (elements: Iterable<A>) => Effect.Effect<boolean, E, R> <A, E, R>(elements: Iterable<A>, f: (a: A, i: number) => Effect.Effect<boolean, E, R>): Effect.Effect<boolean, E, R> } = dual( 2, <A, E, R>( elements: Iterable<A>, f: (a: A, i: number) => Effect.Effect<boolean, E, R> ): Effect.Effect<boolean, E, R> => core.suspend(() => forAllLoop(elements[Symbol.iterator](), 0, f)) ) const forAllLoop = <A, E, R>( iterator: Iterator<A>, index: number, f: (a: A, i: number) => Effect.Effect<boolean, E, R> ): Effect.Effect<boolean, E, R> => { const next = iterator.next() return next.done ? core.succeed(true) : core.flatMap( f(next.value, index), (b) => b ? forAllLoop(iterator, index + 1, f) : core.succeed(b) ) } /* @internal */ export const forever = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<never, E, R> => { const loop: Effect.Effect<never, E, R> = core.flatMap(core.flatMap(self, () => core.yieldNow()), () => loop) return loop } /** @internal */ class EffectGen { constructor(readonly value: Effect.Effect<any, any, any>) { } [Symbol.iterator]() { return new SingleShotGen.SingleShotGen(this) } } const adapter = function() { let x = arguments[0] for (let i = 1; i < arguments.length; i++) { x = arguments[i](x) } return new EffectGen(x) as any } /** * Inspired by https://github.com/tusharmath/qio/pull/22 (revised) @internal */ export const gen: typeof Effect.gen = function() { let f: any if (arguments.length === 1) { f = arguments[0] } else { f = arguments[1].bind(arguments[0]) } return core.suspend(() => { const iterator = f(adapter) const state = iterator.next() const run = ( state: IteratorYieldResult<any> | IteratorReturnResult<any> ): Effect.Effect<any, any, any> => (state.done ? core.succeed(state.value) : pipe( state.value.value as unknown as Effect.Effect<any, any, any>, core.flatMap((val: any) => run(iterator.next(val))) )) return run(state) }) } /* @internal */ export const fiberRefs: Effect.Effect<FiberRefs.FiberRefs> = core.withFiberRuntime((state) => core.succeed(state.getFiberRefs()) ) /* @internal */ export const head = <A, E, R>( self: Effect.Effect<Iterable<A>, E, R> ): Effect.Effect<A, E | Cause.NoSuchElementException, R> => core.flatMap(self, (as) => { const iterator = as[Symbol.iterator]() const next = iterator.next() if (next.done) { return core.fail(new core.NoSuchElementException()) } return core.succeed(next.value) }) /* @internal */ export const ignore = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<void, never, R> => match(self, { onFailure: constVoid, onSuccess: constVoid }) /* @internal */ export const ignoreLogged = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<void, never, R> => core.matchCauseEffect(self, { onFailure: (cause) => logDebug(cause, "An error was silently ignored because it is not anticipated to be useful"), onSuccess: () => core.unit }) /* @internal */ export const inheritFiberRefs = (childFiberRefs: FiberRefs.FiberRefs) => updateFiberRefs((parentFiberId, parentFiberRefs) => FiberRefs.joinAs(parentFiberRefs, parentFiberId, childFiberRefs)) /* @internal */ export const isFailure = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<boolean, never, R> => match(self, { onFailure: constTrue, onSuccess: constFalse }) /* @internal */ export const isSuccess = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<boolean, never, R> => match(self, { onFailure: constFalse, onSuccess: constTrue }) /* @internal */ export const iterate: { <A, B extends A, R, E>( initial: A, options: { readonly while: Predicate.Refinement<A, B> readonly body: (b: B) => Effect.Effect<A, E, R> } ): Effect.Effect<A, E, R> <A, R, E>( initial: A, options: { readonly while: Predicate.Predicate<A> readonly body: (a: A) => Effect.Effect<A, E, R> } ): Effect.Effect<A, E, R> } = <A, E, R>( initial: A, options: { readonly while: Predicate.Predicate<A> readonly body: (z: A) => Effect.Effect<A, E, R> } ): Effect.Effect<A, E, R> => core.suspend<A, E, R>(() => { if (options.while(initial)) { return core.flatMap(options.body(initial), (z2) => iterate(z2, options)) } return core.succeed(initial) }) const logWithLevel = (level?: LogLevel.LogLevel) => <A>( messageOrCause: A, supplementary?: A extends Cause.Cause<any> ? unknown : Cause.Cause<unknown> ): Effect.Effect<void> => { const levelOption = Option.fromNullable(level) let message: unknown let cause: Cause.Cause<unknown> if (internalCause.isCause(messageOrCause)) { cause = messageOrCause message = (supplementary as unknown) ?? "" } else { message = messageOrCause cause = (supplementary as Cause.Cause<unknown>) ?? internalCause.empty } return core.withFiberRuntime((fiberState) => { fiberState.log(message, cause, levelOption) return core.unit }) } /** @internal */ export const log: <A>( messageOrCause: A, supplementary?: A extends Cause.Cause<any> ? unknown : Cause.Cause<unknown> ) => Effect.Effect<void> = logWithLevel() /** @internal */ export const logTrace: <A>( messageOrCause: A, supplementary?: A extends Cause.Cause<any> ? unknown : Cause.Cause<unknown> ) => Effect.Effect<void> = logWithLevel(LogLevel.Trace) /** @internal */ export const logDebug: <A>( messageOrCause: A, supplementary?: A extends Cause.Cause<any> ? unknown : Cause.Cause<unknown> ) => Effect.Effect<void> = logWithLevel(LogLevel.Debug) /** @internal */ export const logInfo: <A>( messageOrCause: A, supplementary?: A extends Cause.Cause<any> ? unknown : Cause.Cause<unknown> ) => Effect.Effect<void> = logWithLevel(LogLevel.Info) /** @internal */ export const logWarning: <A>( messageOrCause: A, supplementary?: A extends Cause.Cause<any> ? unknown : Cause.Cause<unknown> ) => Effect.Effect<void> = logWithLevel(LogLevel.Warning) /** @internal */ export const logError: <A>( messageOrCause: A, supplementary?: A extends Cause.Cause<any> ? unknown : Cause.Cause<unknown> ) => Effect.Effect<void> = logWithLevel(LogLevel.Error) /** @internal */ export const logFatal: <A>( messageOrCause: A, supplementary?: A extends Cause.Cause<any> ? unknown : Cause.Cause<unknown> ) => Effect.Effect<void> = logWithLevel(LogLevel.Fatal) /* @internal */ export const withLogSpan = dual< (label: string) => <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>, <A, E, R>(effect: Effect.Effect<A, E, R>, label: string) => Effect.Effect<A, E, R> >(2, (effect, label) => core.flatMap(Clock.currentTimeMillis, (now) => core.fiberRefLocallyWith( effect, core.currentLogSpan, List.prepend(LogSpan.make(label, now)) ))) /* @internal */ export const logAnnotations: Effect.Effect<HashMap.HashMap<string, unknown>> = core .fiberRefGet( core.currentLogAnnotations ) /* @internal */ export const loop: { <A, B extends A, C, E, R>( initial: A, options: { readonly while: Predicate.Refinement<A, B> readonly step: (b: B) => A readonly body: (b: B) => Effect.Effect<C, E, R> readonly discard?: false | undefined } ): Effect.Effect<Array<C>, E, R> <A, C, E, R>( initial: A, options: { readonly while: (a: A) => boolean readonly step: (a: A) => A readonly body: (a: A) => Effect.Effect<C, E, R> readonly discard?: false | undefined } ): Effect.Effect<Array<C>, E, R> <A, B extends A, C, E, R>( initial: A, options: { readonly while: Predicate.Refinement<A, B> readonly step: (b: B) => A readonly body: (b: B) => Effect.Effect<R, E, C> readonly discard: true } ): Effect.Effect<void, E, R> <A, C, E, R>( initial: A, options: { readonly while: (a: A) => boolean readonly step: (a: A) => A readonly body: (a: A) => Effect.Effect<C, E, R> readonly discard: true } ): Effect.Effect<void, E, R> } = <A, C, E, R>( initial: A, options: { readonly while: Predicate.Predicate<A> readonly step: (a: A) => A readonly body: (a: A) => Effect.Effect<C, E, R> readonly discard?: boolean | undefined } ): any => options.discard ? loopDiscard(initial, options.while, options.step, options.body) : core.map(loopInternal(initial, options.while, options.step, options.body), Array.from) const loopInternal = <Z, A, E, R>( initial: Z, cont: Predicate.Predicate<Z>, inc: (z: Z) => Z, body: (z: Z) => Effect.Effect<A, E, R> ): Effect.Effect<List.List<A>, E, R> => core.suspend(() => cont(initial) ? core.flatMap(body(initial), (a) => core.map( loopInternal(inc(initial), cont, inc, body), List.prepend(a) )) : core.sync(() => List.empty()) ) const loopDiscard = <S, X, E, R>( initial: S, cont: Predicate.Predicate<S>, inc: (s: S) => S, body: (s: S) => Effect.Effect<X, E, R> ): Effect.Effect<void, E, R> => core.suspend(() => cont(initial) ? core.flatMap( body(initial), () => loopDiscard(inc(initial), cont, inc, body) ) : core.unit ) /* @internal */ export const mapAccum: { <S, A, B, E, R>( zero: S, f: (s: S, a: A, i: number) => Effect.Effect<readonly [S, B], E, R> ): (elements: Iterable<A>) => Effect.Effect<[S, Array<B>], E, R> <A, S, B, E, R>( elements: Iterable<A>, zero: S, f: (s: S, a: A, i: number) => Effect.Effect<readonly [S, B], E, R> ): Effect.Effect<[S, Array<B>], E, R> } = dual(3, <A, S, B, E, R>( elements: Iterable<A>, zero: S, f: (s: S, a: A, i: number) => Effect.Effect<readonly [S, B], E, R> ): Effect.Effect<[S, Array<B>], E, R> => core.suspend(() => { const iterator = elements[Symbol.iterator]() const builder: Array<B> = [] let result: Effect.Effect<S, E, R> = core.succeed(zero) let next: IteratorResult<A, any> let i = 0 while (!(next = iterator.next()).done) { const index = i++ const value = next.value result = core.flatMap(result, (state) => core.map(f(state, value, index), ([z, b]) => { builder.push(b) return z })) } return core.map(result, (z) => [z, builder]) })) /* @internal */ export const mapErrorCause: { <E, E2>( f: (cause: Cause.Cause<E>) => Cause.Cause<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: (cause: Cause.Cause<E>) => Cause.Cause<E2>): Effect.Effect<A, E2, R> } = dual( 2, <A, E, R, E2>(self: Effect.Effect<A, E, R>, f: (cause: Cause.Cause<E>) => Cause.Cause<E2>): Effect.Effect<A, E2, R> => core.matchCauseEffect(self, { onFailure: (c) => core.failCauseSync(() => f(c)), onSuccess: core.succeed }) ) /* @internal */ export const memoize = <A, E, R>( self: Effect.Effect<A, E, R> ): Effect.Effect<Effect.Effect<A, E, R>> => pipe( core.deferredMake<[[FiberRefsPatch.FiberRefsPatch, runtimeFlagsPatch.RuntimeFlagsPatch], A], E>(), core.flatMap((deferred) => pipe( diffFiberRefsAndRuntimeFlags(self), core.intoDeferred(deferred), once, core.map((complete) => core.zipRight( complete, pipe( core.deferredAwait(deferred), core.flatMap(([patch, a]) => core.as(core.zip(patchFiberRefs(patch[0]), core.updateRuntimeFlags(patch[1])), a) ) ) ) ) ) ) ) /* @internal */ export const merge = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<E | A, never, R> => core.matchEffect(self, { onFailure: (e) => core.succeed(e), onSuccess: core.succeed }) /* @internal */ export const negate = <E, R>(self: Effect.Effect<boolean, E, R>): Effect.Effect<boolean, E, R> => core.map(self, (b) => !b) /* @internal */ export const none = <A, E, R>( self: Effect.Effect<Option.Option<A>, E, R> ): Effect.Effect<void, E | Cause.NoSuchElementException, R> => core.flatMap(self, (option) => { switch (option._tag) { case "None": return core.unit case "Some": return core.fail(new core.NoSuchElementException()) } }) /* @internal */ export const once = <A, E, R>( self: Effect.Effect<A, E, R> ): Effect.Effect<Effect.Effect<void, E, R>> => core.map( Ref.make(true), (ref) => core.asUnit(core.whenEffect(self, Ref.getAndSet(ref, false))) ) /* @internal */ export const option = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<Option.Option<A>, never, R> => core.matchEffect(self, { onFailure: () => core.succeed(Option.none()), onSuccess: (a) => core.succeed(Option.some(a)) }) /* @internal */ export const orElseFail = dual< <E2>(evaluate: LazyArg<E2>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E2, R>, <A, E, R, E2>(self: Effect.Effect<A, E, R>, evaluate: LazyArg<E2>) => Effect.Effect<A, E2, R> >(2, (self, evaluate) => core.orElse(self, () => core.failSync(evaluate))) /* @internal */ export const orElseSucceed = dual< <A2>(evaluate: LazyArg<A2>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A | A2, never, R>, <A, E, R, A2>(self: Effect.Effect<A, E, R>, evaluate: LazyArg<A2>) => Effect.Effect<A | A2, never, R> >(2, (self, evaluate) => core.orElse(self, () => core.sync(evaluate))) /* @internal */ export const parallelErrors = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, Array<E>, R> => core.matchCauseEffect(self, { onFailure: (cause) => { const errors = Array.from(internalCause.failures(cause)) return errors.length === 0 ? core.failCause(cause as Cause.Cause<never>) : core.fail(errors) }, onSuccess: core.succeed }) /* @internal */ export const patchFiberRefs = (patch: FiberRefsPatch.FiberRefsPatch): Effect.Effect<void> => updateFiberRefs((fiberId, fiberRefs) => pipe(patch, fiberRefsPatch.patch(fiberId, fiberRefs))) /* @internal */ export const promise = <A>(evaluate: (signal: AbortSignal) => PromiseLike<A>): Effect.Effect<A> => evaluate.length >= 1 ? core.async((resolve, signal) => { evaluate(signal) .then((a) => resolve(core.exitSucceed(a)), (e) => resolve(core.exitDie(e))) }) : core.async((resolve) => { ;(evaluate as LazyArg<PromiseLike<A>>)() .then((a) => resolve(core.exitSucceed(a)), (e) => resolve(core.exitDie(e))) }) /* @internal */ export const provideService = dual< <T extends Context.Tag<any, any>>( tag: T, service: Context.Tag.Service<T> ) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, Exclude<R, Context.Tag.Identifier<T>>>, <A, E, R, T extends Context.Tag<any, any>>( self: Effect.Effect<A, E, R>, tag: T, service: Context.Tag.Service<T> ) => Effect.Effect<A, E, Exclude<R, Context.Tag.Identifier<T>>> >( 3, <A, E, R, T extends Context.Tag<any, any>>( self: Effect.Effect<A, E, R>, tag: T, service: Context.Tag.Service<T> ): Effect.Effect<A, E, Exclude<R, Context.Tag.Identifier<T>>> => core.contextWithEffect((env) => core.provideContext( self as Effect.Effect<A, E, Context.Tag.Identifier<T> | Exclude<R, Context.Tag.Identifier<T>>>, Context.add(env, tag, service) ) ) ) /* @internal */ export const provideServiceEffect = dual< <T extends Context.Tag<any, any>, E1, R1>( tag: T, effect: Effect.Effect<Context.Tag.Service<T>, E1, R1> ) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E | E1, R1 | Exclude<R, Context.Tag.Identifier<T>>>, <A, E, R, T extends Context.Tag<any, any>, E1, R1>( self: Effect.Effect<A, E, R>, tag: T, effect: Effect.Effect<Context.Tag.Service<T>, E1, R1> ) => Effect.Effect<A, E | E1, R1 | Exclude<R, Context.Tag.Identifier<T>>> >(3, <A, E, R, T extends Context.Tag<any, any>, E1, R1>( self: Effect.Effect<A, E, R>, tag: T, effect: Effect.Effect<Context.Tag.Service<T>, E1, R1> ) => core.contextWithEffect((env: Context.Context<R1 | Exclude<R, Context.Tag.Identifier<T>>>) => core.flatMap( effect, (service) => core.provideContext(self, pipe(env, Context.add(tag, service)) as Context.Context<R | R1>) ) )) /* @internal */ export const random: Effect.Effect<Random.Random> = defaultServices.randomWith(core.succeed) /* @internal */ export const reduce = dual< <Z, A, E, R>( zero: Z, f: (z: Z, a: A, i: number) => Effect.Effect<Z, E, R> ) => (elements: Iterable<A>) => Effect.Effect<Z, E, R>, <A, Z, E, R>( elements: Iterable<A>, zero: Z, f: (z: Z, a: A, i: number) => Effect.Effect<Z, E, R> ) => Effect.Effect<Z, E, R> >( 3, <A, Z, E, R>( elements: Iterable<A>, zero: Z, f: (z: Z, a: A, i: number) => Effect.Effect<Z, E, R> ) => ReadonlyArray.fromIterable(elements).reduce( (acc, el, i) => core.flatMap(acc, (a) => f(a, el, i)), core.succeed(zero) as Effect.Effect<Z, E, R> ) ) /* @internal */ export const reduceRight = dual< <A, Z, R, E>( zero: Z, f: (a: A, z: Z, i: number) => Effect.Effect<Z, E, R> ) => (elements: Iterable<A>) => Effect.Effect<Z, E, R>, <A, Z, R, E>( elements: Iterable<A>, zero: Z, f: (a: A, z: Z, i: number) => Effect.Effect<Z, E, R> ) => Effect.Effect<Z, E, R> >( 3, <A, Z, R, E>(elements: Iterable<A>, zero: Z, f: (a: A, z: Z, i: number) => Effect.Effect<Z, E, R>) => ReadonlyArray.fromIterable(elements).reduceRight( (acc, el, i) => core.flatMap(acc, (a) => f(el, a, i)), core.succeed(zero) as Effect.Effect<Z, E, R> ) ) /* @internal */ export const reduceWhile = dual< <Z, A, E, R>( zero: Z, options: { readonly while: Predicate.Predicate<Z> readonly body: (s: Z, a: A, i: number) => Effect.Effect<Z, E, R> } ) => (elements: Iterable<A>) => Effect.Effect<Z, E, R>, <A, Z, E, R>( elements: Iterable<A>, zero: Z, options: { readonly while: Predicate.Predicate<Z> readonly body: (s: Z, a: A, i: number) => Effect.Effect<Z, E, R> } ) => Effect.Effect<Z, E, R> >(3, <A, Z, E, R>( elements: Iterable<A>, zero: Z, options: { readonly while: Predicate.Predicate<Z> readonly body: (s: Z, a: A, i: number) => Effect.Effect<Z, E, R> } ) => core.flatMap( core.sync(() => elements[Symbol.iterator]()), (iterator) => reduceWhileLoop(iterator, 0, zero, options.while, options.body) )) const reduceWhileLoop = <A, R, E, Z>( iterator: Iterator<A>, index: number, state: Z, predicate: Predicate.Predicate<Z>, f: (s: Z, a: A, i: number) => Effect.Effect<Z, E, R> ): Effect.Effect<Z, E, R> => { const next = iterator.next() if (!next.done && predicate(state)) { return core.flatMap( f(state, next.value, index), (nextState) => reduceWhileLoop(iterator, index + 1, nextState, predicate, f) ) } return core.succeed(state) } /* @internal */ export const repeatN = dual< (n: number) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>, <A, E, R>(self: Effect.Effect<A, E, R>, n: number) => Effect.Effect<A, E, R> >(2, (self, n) => core.suspend(() => repeatNLoop(self, n))) /* @internal */ const repeatNLoop = <A, E, R>(self: Effect.Effect<A, E, R>, n: number): Effect.Effect<A, E, R> => core.flatMap(self, (a) => n <= 0 ? core.succeed(a) : core.zipRight(core.yieldNow(), repeatNLoop(self, n - 1))) /* @internal */ export const sandbox = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, Cause.Cause<E>, R> => core.matchCauseEffect(self, { onFailure: core.fail, onSuccess: core.succeed }) /* @internal */ export const setFiberRefs = (fiberRefs: FiberRefs.FiberRefs): Effect.Effect<void> => core.suspend(() => FiberRefs.setAll(fiberRefs)) /* @internal */ export const sleep: (duration: Duration.DurationInput) => Effect.Effect<void> = Clock.sleep /* @internal */ export const succeedNone: Effect.Effect<Option.Option<never>> = core.succeed(Option.none()) /* @internal */ export const succeedSome = <A>(value: A): Effect.Effect<Option.Option<A>> => core.succeed(Option.some(value)) /* @internal */ export const summarized: { <B, E2, R2, C>( summary: Effect.Effect<B, E2, R2>, f: (start: B, end: B) => C ): <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<[C, A], E2 | E, R2 | R> <A, E, R, B, E2, R2, C>( self: Effect.Effect<A, E, R>, summary: Effect.Effect<B, E2, R2>, f: (start: B, end: B) => C ): Effect.Effect<[C, A], E2 | E, R2 | R> } = dual( 3, <A, E, R, B, E2, R2, C>( self: Effect.Effect<A, E, R>, summary: Effect.Effect<B, E2, R2>, f: (start: B, end: B) => C ): Effect.Effect<[C, A], E2 | E, R2 | R> => core.flatMap( summary, (start) => core.flatMap(self, (value) => core.map(summary, (end) => [f(start, end), value])) ) ) /* @internal */ export const tagMetrics = dual< { (key: string, value: string): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> ( values: Record<string, string> ): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> }, { <A, E, R>(effect: Effect.Effect<A, E, R>, key: string, value: string): Effect.Effect<A, E, R> <A, E, R>(effect: Effect.Effect<A, E, R>, values: Record<string, string>): Effect.Effect<A, E, R> } >((args) => core.isEffect(args[0]), function() { return labelMetrics( arguments[0], typeof arguments[1] === "string" ? [metricLabel.make(arguments[1], arguments[2])] : Object.entries<string>(arguments[1]).map(([k, v]) => metricLabel.make(k, v)) ) }) /* @internal */ export const labelMetrics = dual< (labels: Iterable<MetricLabel.MetricLabel>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>, <A, E, R>(self: Effect.Effect<A, E, R>, labels: Iterable<MetricLabel.MetricLabel>) => Effect.Effect<A, E, R> >( 2, (self, labels) => core.fiberRefLocallyWith(self, core.currentMetricLabels, (old) => ReadonlyArray.union(old, labels)) ) /* @internal */ export const takeUntil: { <A, R, E>( predicate: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R> ): (elements: Iterable<A>) => Effect.Effect<Array<A>, E, R> <A, E, R>( elements: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R> ): Effect.Effect<Array<A>, E, R> } = dual( 2, <A, E, R>( elements: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R> ): Effect.Effect<Array<A>, E, R> => core.suspend(() => { const iterator = elements[Symbol.iterator]() const builder: Array<A> = [] let next: IteratorResult<A, any> let effect: Effect.Effect<boolean, E, R> = core.succeed(false) let i = 0 while ((next = iterator.next()) && !next.done) { const a = next.value const index = i++ effect = core.flatMap(effect, (bool) => { if (bool) { return core.succeed(true) } builder.push(a) return predicate(a, index) }) } return core.map(effect, () => builder) }) ) /* @internal */ export const takeWhile = dual< <A, E, R>( predicate: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R> ) => (elements: Iterable<A>) => Effect.Effect<Array<A>, E, R>, <A, E, R>( elements: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R> ) => Effect.Effect<Array<A>, E, R> >( 2, <A, E, R>(elements: Iterable<A>, predicate: (a: NoInfer<A>, i: number) => Effect.Effect<boolean, E, R>) => core.suspend(() => { const iterator = elements[Symbol.iterator]() const builder: Array<A> = [] let next: IteratorResult<A, any> let taking: Effect.Effect<boolean, E, R> = core.succeed(true) let i = 0 while ((next = iterator.next()) && !next.done) { const a = next.value const index = i++ taking = core.flatMap(taking, (taking) => pipe( ta