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
// 60Transform any value into Task
TaskRoll.of([1,2,3,4]).forEach( _ => {
console.log(_)
}).start()Starts execution of Task - task will not start without calling start.
TaskRoll.of().log('Hello World').start()Alternative way to start the evaluation of the task
await TaskRoll.of().log('Hello World').toPromise()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)
}) // 2Sets the value, alias to chain
TaskRoll.of(4).value(6).log( _ => _ ) // 6const multiply = TaskRoll.of().chain( _ => _ * 2)
TaskRoll.of([1,2,3]).map( multiply )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()TaskRoll.of([1,2,3]).forEach( _ => {
console.log(_)
})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) // 200Apply 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) // 20TaskRoll.of(5).valueTo('x') // ctx.state.x == 5TaskRoll.of().valueFrom('x') // ctx.value == 5In 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 hereExecute repeating task at background
TaskRoll.of(...).background( task => {
task.log('msg from bg').sleep(1000)
})Cleanup after task completes successfully or not.
TaskRoll.of(...)
.chain(doSomething)
.cleanup( async (ctx:TaskRollCtx) => {
// ctx.value
// ctx.state
})If task is cancelled (not committed)
TaskRoll.of(...)
.chain(doSomething)
.rollback( async (ctx:TaskRollCtx) => {
// ctx.value
// ctx.state
})TaskRoll.of('Hello World').setName('Hello World Process')TaskRoll.of('Hello World').log( _ => `${_}`)const obj = TaskRoll.of().serialize()TaskRoll.of().log('sleeping 1 sec').sleep(1000).log('awake')Accept changes (rollback is not called)
TaskRoll.of([1,2,3])
.map(doSomething)
.commit() Called when task ends
Projects which are solving similar problems