Asynchronous computation builder
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
dist/src
src
.gitignore
README.md

README.md

TaskRoll

https://www.npmjs.com/package/taskroll

npm i taskroll

Creates lazily evaluated tasks, which calcualate asyncronouse tasks in syncronous manner. Tasks can be composed like Promises or Futures. Main features:

  • Lazy evaluation
  • Stack safety
  • Continuation guarding
  • Cancellation support with syncronous reversed rollback
  • Catches exceptions.
  • Inspectable immutable context after each computation
  • Supports functions returning promises
  • Holds state which can hold data or callable Tasks
  const mapper = TaskRoll.of().value( _ => _ * 15)
  const show_slowly = TaskRoll.of()
    .log( _ => _ )
    .sleep(1000)
  const task = TaskRoll.of()
    .map(mapper)
    .forEach(show_slowly)

  TaskRoll.of([1,2,3,4]).chain(task).start()
  // 15
  // 30
  // 45
  // 60

.of(value:any)

Transform any value into Task

TaskRoll.of([1,2,3,4]).forEach( _ => {
  console.log(_)
}).start()

.start()

Starts execution of Task - task will not start without calling start.

TaskRoll.of().log('Hello World').start()

toPromise()

Alternative way to start the evaluation of the task

await TaskRoll.of().log('Hello World').toPromise()

.chain( (value:any) => any )

const multiply = TaskRoll.of().chain( _ => _ * 2)

Result of the chain can also be another Task which is evaluated

TaskRoll.of(1).chain( _ => {
  return TaskRoll.of( _ + 1)
}) // 2

.value( value?:any)

Sets the value, alias to chain

TaskRoll.of(4).value(6).log( _ => _ ) // 6

.map( (value:any) => any )

const multiply = TaskRoll.of().chain( _ => _ * 2)
TaskRoll.of([1,2,3]).map( multiply )

.cond( condition:any, fn:any, elseFn?:any )

If condition is true evaluate fn else elseFn

const longer_than_5 = TaskRoll.of().chain( _ =>  _.length > 5)
const compare =  TaskRoll.of()
    .cond(longer_than_5, 
        TaskRoll.of().log( _ => `${_}.length > 5`),
        TaskRoll.of().log( _ => `${_}.length <= 5`),
    )
await TaskRoll.of(['ABC', 'Chevy Van', 'Trekk']).map( compare ).toPromise()

.forEach( (value:any) => any )

TaskRoll.of([1,2,3]).forEach( _ => {
  console.log(_)
})

.fn( name:string, value?:any)

Create Task based function in state. Can be used to signal events.

const multiply = TaskRoll.of().chain( _ => _ * 2)
const lazyvalue = TaskRoll.of(100)
TaskRoll.of().fn('multiply', multiply)
  .value(11)
  .call('multiply') // 22
  .call('multiply', lazyvalue) // 200
  .call(multiply, lazyvalue)   // 200

.call( fn:TaskRoll, value?:any)

Apply Task to the value programmatically

const multiply = TaskRoll.of().chain( _ => _ * 2)
const slowValue = TaskRoll.of(10).sleep(1000)

TaskRoll.of(4).call(multiply)           // 8
TaskRoll.of().call(multiply,3)          // 6
TaskRoll.of().call(multiply,slowValue)  // 20

.valueTo( string )

TaskRoll.of(5).valueTo('x')   // ctx.state.x == 5

.valueFrom( string )

TaskRoll.of().valueFrom('x')   // ctx.value == 5

.fork( (task:TaskRoll) => any )

In case we want to use the current value for something but preseve original we can fork the execution.

TaskRoll.of(5)
  .fork( task => {
    task.chain( _ => _ * 10 ) // 50
      .log( _ => _)
  })
  .log( _ => _) // still 5 here

.background( (task:TaskRoll) => any )

Execute repeating task at background

TaskRoll.of(...).background( task => {
  task.log('msg from bg').sleep(1000)
})

.cleanup( async fn => any )

Cleanup after task completes successfully or not.

TaskRoll.of(...)
  .chain(doSomething)
  .cleanup( async (ctx:TaskRollCtx) => {
    // ctx.value
    // ctx.state
  })

.rollback( async fn => any )

If task is cancelled (not committed)

TaskRoll.of(...)
  .chain(doSomething)
  .rollback( async  (ctx:TaskRollCtx) => {
    // ctx.value
    // ctx.state
  })

.setName( string)

TaskRoll.of('Hello World').setName('Hello World Process')

.log( string | (value:any) => string )

TaskRoll.of('Hello World').log( _ => `${_}`)

.serialize() => Object

const obj = TaskRoll.of().serialize()

.sleep( number )

TaskRoll.of().log('sleeping 1 sec').sleep(1000).log('awake')

.commit()

Accept changes (rollback is not called)

TaskRoll.of([1,2,3])
  .map(doSomething)
  .commit() 

.onFulfilled( (ctx:TaskRollCtx) => void )

Called when task ends

Related projects

Projects which are solving similar problems