Skip to content

Instantly share code, notes, and snippets.

@alexandrebodin
Created August 27, 2016 13:07
Show Gist options
  • Save alexandrebodin/299c2f6fc967d5d9e0010db1b92ac97c to your computer and use it in GitHub Desktop.
Save alexandrebodin/299c2f6fc967d5d9e0010db1b92ac97c to your computer and use it in GitHub Desktop.
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