Created
August 27, 2016 13:07
-
-
Save alexandrebodin/299c2f6fc967d5d9e0010db1b92ac97c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Task from 'data.task'; | |
import R from 'ramda'; | |
const run = t => { | |
return t.fork( | |
err => console.log('err', err), | |
R.tap(console.log) | |
); | |
} | |
// Will run Identity on an object prop | |
const idProp = key => R.pipe( | |
R.prop(key), | |
R.identity | |
); | |
// Will chain on an object prop | |
const chainProp = R.curry((key, fn) => R.pipe( | |
R.prop(key), | |
R.chain(fn) | |
)); | |
// Will take an object spec and return a Task | |
// that will resolve to an object of the same shape | |
// with each underlying Task resolved | |
// | |
// basically considering an object as a traversable and runing all Task in parallel | |
const assembleSpec = (spec) => { | |
const arrSpec = R.toPairs(spec); | |
const results = []; | |
let rejected = false; | |
let finishedAll = false; | |
return new Task((reject, resolve) => { | |
arrSpec.forEach(([key, task]) => { | |
task.fork(guardReject, guardResolve(val => { | |
results.push([key, val]); | |
if (results.length === arrSpec.length) finishedAll = true; | |
})); | |
}); | |
function guardResolve(setter) { | |
return x => { | |
if (rejected) return; | |
setter(x); | |
if (finishedAll) return resolve(R.fromPairs(results)); | |
return x; | |
} | |
} | |
function guardReject(x) { | |
if (!rejected) { | |
rejected = true; | |
return reject(x); | |
} | |
} | |
}); | |
}; | |
const getContact = id => new Task((_, resolve) => resolve({id})); | |
const createEntity = R.curry((payload, user, contact) => { | |
return new Task((_, resolve) => { | |
setTimeout(() => { | |
resolve({ | |
...payload, | |
id: 1, | |
contactId: contact.id, | |
userId: user.id | |
}); | |
}, 1000); | |
}); | |
}); | |
const payload = { | |
field1: 'value of field 1' | |
}; | |
const user = { | |
id: 666 | |
}; | |
const updateContact = contact => { | |
return new Task((_, resolve) => { | |
resolve({ | |
...contact, | |
isActive: true, | |
}); | |
}); | |
} | |
const prog = R.pipe( | |
getContact, | |
R.applySpec({ | |
contact: R.identity, | |
beuz: R.chain(createEntity(payload, user)), | |
}), | |
R.applySpec({ | |
contact: chainProp('contact', updateContact), | |
beuz: idProp('beuz'), | |
}), | |
assembleSpec | |
)(10); | |
run(prog); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment