From 85281f6d29ad6cb39accc4206397728d82905455 Mon Sep 17 00:00:00 2001 From: Felipe Lalanne <1822826+pipex@users.noreply.github.com> Date: Tue, 26 Sep 2023 10:24:00 -0300 Subject: [PATCH] Additional API improvements and fixes Renames some effect helpers and makes condition usable with tasks defined with an effect. This allows to have fewer levels of callbacks when defining the effect for a task Change-type: minor --- lib/agent.spec.ts | 15 +- lib/effects.spec.ts | 112 ---- lib/effects/do.ts | 1100 +++++++++++++++++++++------------------- lib/effects/effect.ts | 11 +- lib/effects/helpers.ts | 56 +- lib/effects/pipe.ts | 760 +++++++++++++-------------- lib/task/tasks.ts | 31 +- 7 files changed, 1007 insertions(+), 1078 deletions(-) diff --git a/lib/agent.spec.ts b/lib/agent.spec.ts index a841bc8..6cd5d74 100644 --- a/lib/agent.spec.ts +++ b/lib/agent.spec.ts @@ -76,12 +76,15 @@ describe('Agent', () => { // side, to produce multiple values while the computation is performed // The sync side just tells us that the effect of the computation is that // the counter reaches the target - IO(async function* () { - while (s < target) { - yield ++s; - await setTimeout(10); - } - }, target), + IO( + async function* () { + while (s < target) { + yield ++s; + await setTimeout(10); + } + }, + () => target, + ), ), ), }); diff --git a/lib/effects.spec.ts b/lib/effects.spec.ts index a6f185c..e69de29 100644 --- a/lib/effects.spec.ts +++ b/lib/effects.spec.ts @@ -1,112 +0,0 @@ -import { expect } from '~/test-utils'; -import { Effect, doPipe, map, when, of, bindIO } from './effects'; - -import { stub } from 'sinon'; - -describe('Effects API', () => { - describe('Effect', () => { - it('allows chaining calculations', () => { - const effect = Effect.of(0).map((x) => x + 1); - expect(effect()).to.equal(1); - }); - - it('allows a sync and async executions', async () => { - const effect = Effect.of(0) - .map((x) => x + 1) - .flatMap((x) => - Effect.from( - async () => x + 2, - () => x + 1, - ), - ) - .flatMap((x) => - Effect.from( - async () => x + 1, - () => x + 1, - ), - ); - expect(effect()).to.equal(3); - expect(await effect).to.equal(4); - }); - - it('propagates errors in a promise', async () => { - const effect = Effect.of(0) - .map((x) => x + 1) - .flatMap((x) => - Effect.from( - async () => { - if (x < 2) { - throw new Error('x is too small'); - } - // This will never be reached - return x + 2; - }, - () => x + 1, - ), - ) - .flatMap((x) => - Effect.from( - async () => x + 1, - () => x + 1, - ), - ); - expect(effect()).to.equal(3); - await expect(effect).to.be.rejected; - }); - }); - - describe('pipe', () => { - it('allows piping effects', async () => { - const effectFn = () => - doPipe( - 0, - map((x) => x + 1), - bindIO( - async (x) => x + 2, - (x) => x + 1, - ), - map((x) => x + 1), - when((x) => x < 2, of), - ); - expect(effectFn()()).to.equal(3); - expect(await effectFn()).to.equal(4); - }); - }); - - describe('Observables', () => { - it('allows using an async generator as IO', async () => { - const effect = doPipe( - 0, - map((x) => x + 1), - bindIO( - async function* (x) { - yield x + 1; - yield x + 2; - }, - (x) => x + 1, - ), - map((x) => x + 1), - ); - const next = stub(); - - // Create a new promise to wait for the effect to - // finish - const promise = new Promise((resolve, reject) => { - const subscriber = effect.subscribe({ - next, - error: reject, - complete: () => { - resolve(); - subscriber.unsubscribe(); - }, - }); - }); - await promise; - expect(effect()).to.equal(3); - expect(next).to.have.been.calledTwice; - expect(next).to.have.been.calledWith(3); - expect(next).to.have.been.calledWith(4); - expect(await effect).to.equal(4); - }); - }); -}); diff --git a/lib/effects/do.ts b/lib/effects/do.ts index fb0728b..cd2085f 100644 --- a/lib/effects/do.ts +++ b/lib/effects/do.ts @@ -1,7 +1,7 @@ import { Effect } from './effect'; import { pipe, Fn } from './pipe'; -type EfectFn = Fn, Effect>; +type EffectFn = Fn, Effect>; /** * Chain functions from left to right, returning an Effect @@ -9,232 +9,252 @@ type EfectFn = Fn, Effect>; * Returns a new function that receives the same arguments as first * function and returns the result of the last function. */ -export function doPipe(a: A): Effect; -export function doPipe(a: A, fa: EfectFn): Effect; +export function fromPipe(a: A): Effect; +export function fromPipe(a: A, fa: EffectFn): Effect; // This repetition is necessary unfortunately to ensure that typescript can // infer the correct types for the arguments -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, + fa: EffectFn, + fb: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, ): Effect

; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, ): Effect; -export function doPipe( +export function fromPipe( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, - fr: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, + fr: EffectFn, ): Effect; -export function doPipe( +export function fromPipe< + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, +>( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, - fr: EfectFn, - fs: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, + fr: EffectFn, + fs: EffectFn, ): Effect; -export function doPipe< +export function fromPipe< A, B, C, @@ -257,27 +277,27 @@ export function doPipe< T, >( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, - fr: EfectFn, - fs: EfectFn, - ft: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, + fr: EffectFn, + fs: EffectFn, + ft: EffectFn, ): Effect; -export function doPipe< +export function fromPipe< A, B, C, @@ -301,28 +321,28 @@ export function doPipe< U, >( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, - fr: EfectFn, - fs: EfectFn, - ft: EfectFn, - fu: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, + fr: EffectFn, + fs: EffectFn, + ft: EffectFn, + fu: EffectFn, ): Effect; -export function doPipe< +export function fromPipe< A, B, C, @@ -347,251 +367,266 @@ export function doPipe< V, >( a: A, - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, - fr: EfectFn, - fs: EfectFn, - ft: EfectFn, - fu: EfectFn, - fv: EfectFn, + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, + fr: EffectFn, + fs: EffectFn, + ft: EffectFn, + fu: EffectFn, + fv: EffectFn, ): Effect; -export function doPipe(a: any, ...fns: Array>) { +export function fromPipe(a: any, ...fns: Array>) { return (pipe as any)(a, Effect.of, ...fns); } -/** - * Alias of doPipe for more declarative definitions - */ -export const fromPipe = doPipe; - /** * Chain functions from left to right * * Returns a new function that receives the same arguments as first * function and returns the result of the last function. */ -export function doFlow(fa: EfectFn): Fn>; +export function fromFlow(fa: EffectFn): Effect; // This repetition is necessary unfortunately to ensure that typescript can // infer the correct types for the arguments -export function doFlow( - fa: EfectFn, - fb: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, - fr: EfectFn, -): Fn>; -export function doFlow( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, - fr: EfectFn, - fs: EfectFn, -): Fn>; -export function doFlow< +export function fromFlow( + fa: EffectFn, + fb: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, +): Effect

; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, +): Effect; +export function fromFlow( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, + fr: EffectFn, +): Effect; +export function fromFlow< + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, +>( + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, + fr: EffectFn, + fs: EffectFn, +): Effect; +export function fromFlow< A, B, C, @@ -613,27 +648,27 @@ export function doFlow< S, T, >( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, - fr: EfectFn, - fs: EfectFn, - ft: EfectFn, -): Fn>; -export function doFlow< + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, + fr: EffectFn, + fs: EffectFn, + ft: EffectFn, +): Effect; +export function fromFlow< A, B, C, @@ -656,28 +691,28 @@ export function doFlow< T, U, >( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, - fr: EfectFn, - fs: EfectFn, - ft: EfectFn, - fu: EfectFn, -): Fn>; -export function doFlow< + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, + fr: EffectFn, + fs: EffectFn, + ft: EffectFn, + fu: EffectFn, +): Effect; +export function fromFlow< A, B, C, @@ -701,29 +736,29 @@ export function doFlow< U, V, >( - fa: EfectFn, - fb: EfectFn, - fc: EfectFn, - fd: EfectFn, - fe: EfectFn, - fg: EfectFn, - fh: EfectFn, - fi: EfectFn, - fj: EfectFn, - fk: EfectFn, - fl: EfectFn, - fm: EfectFn, - fn: EfectFn, - fo: EfectFn, - fp: EfectFn, - fq: EfectFn, - fr: EfectFn, - fs: EfectFn, - ft: EfectFn, - fu: EfectFn, - fv: EfectFn, -): Fn>; -export function doFlow(...fns: Array>) { + fa: EffectFn, + fb: EffectFn, + fc: EffectFn, + fd: EffectFn, + fe: EffectFn, + fg: EffectFn, + fh: EffectFn, + fi: EffectFn, + fj: EffectFn, + fk: EffectFn, + fl: EffectFn, + fm: EffectFn, + fn: EffectFn, + fo: EffectFn, + fp: EffectFn, + fq: EffectFn, + fr: EffectFn, + fs: EffectFn, + ft: EffectFn, + fu: EffectFn, + fv: EffectFn, +): Effect; +export function fromFlow(...fns: Array>) { return (a: any) => (pipe as any)(a, Effect.of, ...fns); } @@ -731,4 +766,5 @@ export function doFlow(...fns: Array>) { * Alias of doFlow for more declarative * definitions */ -export const then = doFlow; +export const then = fromFlow; +export const fromSequence = fromFlow; diff --git a/lib/effects/effect.ts b/lib/effects/effect.ts index 547870a..13789b4 100644 --- a/lib/effects/effect.ts +++ b/lib/effects/effect.ts @@ -151,17 +151,10 @@ function of(t: T): Effect { } /** - * Create a side effect from an async function and a fallback + * Create a side effect from an async and sync sides * value. - * - * This is equivalent to calling `Effect.from(async, () => t)` but it provides - * a shorter syntax. */ -export function IO(async: Async): Effect; -export function IO(async: Async, t: T): Effect; -export function IO(async: Async, t?: T): Effect { - return from(async, of(t!)); -} +export const IO = from; /** * Type guard to check if a given value is an effect diff --git a/lib/effects/helpers.ts b/lib/effects/helpers.ts index 59a3194..00cf47f 100644 --- a/lib/effects/helpers.ts +++ b/lib/effects/helpers.ts @@ -23,16 +23,6 @@ export function flatMap( return (et: Effect) => et.flatMap(ef); } -/** - * Chains two effects together. - * - * This returns a function on effects that can be used as - * part of a pipe - * - * This is an alias of flatMap - */ -export const bind = flatMap; - /** * Creates a new IO effect from a async and sync * functions. @@ -40,7 +30,7 @@ export const bind = flatMap; * If no sync function is used, then the identity function * will be used as the sync part. */ -export function bindIO( +export function mapIO( fa: (t: T) => AsyncReturn, // TODO: the `as U` cast is a potential source for bugs // as the async side could return a value not in the sync side @@ -48,7 +38,12 @@ export function bindIO( // values match fs: (t: T) => U = (t: T) => t as U, ): (et: Effect) => Effect { - return bind((t) => IO(() => fa(t), fs(t))); + return flatMap((t) => + IO( + () => fa(t), + () => fs(t), + ), + ); } /** @@ -62,7 +57,7 @@ export function when( doIf: (t: T) => Effect, doElse: (t: T) => Effect = (t) => Effect.of(t as U), ): (et: Effect) => Effect { - return bind((t) => (condition(t) ? doIf(t) : doElse(t))); + return flatMap((t) => (condition(t) ? doIf(t) : doElse(t))); } /** @@ -114,19 +109,30 @@ export function tapIO( ): (et: Effect) => Effect { return (et: Effect) => et.flatMap((t) => - IO(async () => { - await f(t); - return t; - }, t), + IO( + async () => { + await f(t); + return t; + }, + () => t, + ), ); } -/** - * Set a property of an object in an effect. - */ -export function set( - key: K, - eu: Effect, -): (et: Effect) => Effect { - return bind((t) => eu.map((u) => ({ ...t, [key]: u }))); +export function bind( + key: Exclude, + fn: (t: T) => Effect, +): ( + et: Effect, +) => Effect<{ readonly [K in N | keyof T]: K extends keyof T ? T[K] : U }> { + return flatMap((t) => fn(t).map((u) => ({ ...t, [key]: u }) as any)); +} + +export function set( + key: Exclude, + fn: (t: T) => U, +): ( + et: Effect, +) => Effect<{ readonly [K in N | keyof T]: K extends keyof T ? T[K] : U }> { + return map((t) => ({ ...t, [key]: fn(t) }) as any); } diff --git a/lib/effects/pipe.ts b/lib/effects/pipe.ts index 78701a9..7efe937 100644 --- a/lib/effects/pipe.ts +++ b/lib/effects/pipe.ts @@ -24,122 +24,122 @@ export function flow( fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, + fd: Fn, ): (...a: A) => E; export function flow( fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, + fd: Fn, + fe: Fn, ): (...a: A) => F; export function flow( fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, + fd: Fn, + fe: Fn, + fg: Fn, ): (...a: A) => G; export function flow( fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, ): (...a: A) => H; export function flow( fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, ): (...a: A) => I; export function flow( fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, ): (...a: A) => J; export function flow( fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, ): (...a: A) => K; export function flow( fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, ): (...a: A) => L; export function flow( fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, ): (...a: A) => M; export function flow( fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, ): (...a: A) => N; export function flow( fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, ): (...a: A) => O; export function flow< A extends any[], @@ -162,18 +162,18 @@ export function flow< fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, ): (...a: A) => P; export function flow< A extends any[], @@ -197,19 +197,19 @@ export function flow< fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, ): (...a: A) => Q; export function flow< A extends any[], @@ -234,20 +234,20 @@ export function flow< fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, ): (...a: A) => R; export function flow< A extends any[], @@ -273,21 +273,21 @@ export function flow< fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, - fs: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, + fs: Fn, ): (...a: A) => S; export function flow< A extends any[], @@ -314,22 +314,22 @@ export function flow< fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, - fs: Fn, - ft: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, + fs: Fn, + ft: Fn, ): (...a: A) => T; export function flow< A extends any[], @@ -357,23 +357,23 @@ export function flow< fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, - fs: Fn, - ft: Fn, - fu: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, + fs: Fn, + ft: Fn, + fu: Fn, ): (...a: A) => U; export function flow< A extends any[], @@ -402,24 +402,24 @@ export function flow< fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, - fs: Fn, - ft: Fn, - fu: Fn, - fv: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, + fs: Fn, + ft: Fn, + fu: Fn, + fv: Fn, ): (...a: A) => V; export function flow< A extends any[], @@ -449,25 +449,25 @@ export function flow< fa: (...a: A) => B, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, - fs: Fn, - ft: Fn, - fu: Fn, - fv: Fn, - fw: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, + fs: Fn, + ft: Fn, + fu: Fn, + fv: Fn, + fw: Fn, ): (...a: A) => W; export function flow(fa: (...a: any[]) => any, ...fns: Array>) { return fns.reduce( @@ -498,210 +498,210 @@ export function pipe( fa: Fn, fb: Fn, fc: Fn, - fd: Fn, + fd: Fn, ): E; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, + fd: Fn, + fe: Fn, ): F; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, + fd: Fn, + fe: Fn, + fg: Fn, ): G; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, ): H; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, ): I; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, ): J; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, ): K; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, ): L; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, ): M; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, ): N; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, ): O; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, ): P; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, ): Q; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, ): R; export function pipe( a: A, fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, - fs: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, + fs: Fn, ): S; export function pipe< A, @@ -729,22 +729,22 @@ export function pipe< fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, - fs: Fn, - ft: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, + fs: Fn, + ft: Fn, ): T; export function pipe< A, @@ -773,23 +773,23 @@ export function pipe< fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, - fs: Fn, - ft: Fn, - fu: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, + fs: Fn, + ft: Fn, + fu: Fn, ): U; export function pipe< A, @@ -819,24 +819,24 @@ export function pipe< fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, - fs: Fn, - ft: Fn, - fu: Fn, - fv: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, + fs: Fn, + ft: Fn, + fu: Fn, + fv: Fn, ): V; export function pipe< A, @@ -867,25 +867,25 @@ export function pipe< fa: Fn, fb: Fn, fc: Fn, - fd: Fn, - fe: Fn, - fg: Fn, - fh: Fn, - fi: Fn, - fj: Fn, - fk: Fn, - fl: Fn, - fm: Fn, - fn: Fn, - fo: Fn, - fp: Fn, - fq: Fn, - fr: Fn, - fs: Fn, - ft: Fn, - fu: Fn, - fv: Fn, - fw: Fn, + fd: Fn, + fe: Fn, + fg: Fn, + fh: Fn, + fi: Fn, + fj: Fn, + fk: Fn, + fl: Fn, + fm: Fn, + fn: Fn, + fo: Fn, + fp: Fn, + fq: Fn, + fr: Fn, + fs: Fn, + ft: Fn, + fu: Fn, + fv: Fn, + fw: Fn, ): W; export function pipe(a: any, ...fns: Array>) { return fns.reduce((acc, f) => f(acc), a); diff --git a/lib/task/tasks.ts b/lib/task/tasks.ts index c83b314..a729fe6 100644 --- a/lib/task/tasks.ts +++ b/lib/task/tasks.ts @@ -2,7 +2,7 @@ import { createHash } from 'crypto'; import assert from '../assert'; import { Context, ContextAsArgs, TaskOp } from '../context'; -import { Effect, IO, when, pipe } from '../effects'; +import { Effect, IO, flatMap, pipe } from '../effects'; import { Path } from '../path'; import { Action, Instruction, Method } from './instructions'; @@ -58,7 +58,10 @@ export interface ActionTask< * the planner will wait for the observable to complete before continuing, but * use any state updates to communicate about state changes to its observers. */ - action(s: TState, c: Context): Promise; + action( + s: TState, + c: Context, + ): Promise | AsyncGenerator; /** * The task function grounds the task @@ -146,17 +149,17 @@ function ground< pipe( state, Effect.of, - when( - (s) => task.condition(s, context), - (s) => { - const e = task.effect(s, context); - if (Effect.is(e)) { - return e; - } else { - return IO(async () => task.action(s, context), e); - } - }, - ), + flatMap((s) => { + const e = task.effect(s, context); + if (Effect.is(e)) { + return e; + } else { + return IO( + () => task.action(s, context), + () => e, + ); + } + }), ); return Object.assign(fn, { id, @@ -252,7 +255,7 @@ export type ActionTaskWithEffectProps< TPath extends Path = '/', TOp extends TaskOp = 'update', > = Partial< - Omit, 'effect' | 'id' | 'action' | 'condition'> + Omit, 'effect' | 'id' | 'action'> > & { effect(s: TState, c: Context): Effect; };