Skip to content

Instantly share code, notes, and snippets.

@jeffpeterson
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeffpeterson/b3ca8998c4f1fabdcd1a to your computer and use it in GitHub Desktop.
Save jeffpeterson/b3ca8998c4f1fabdcd1a to your computer and use it in GitHub Desktop.
spool
export default spool
// thread first (left) argument
export function spool(s, r) {
return _spool(s, r, (r, args) => [r, ...args])
}
// thread last (right) argument
export function spoor(s, r) {
return _spool(s, r, (r, args) => [...args, r])
}
function _spool(shape, __r, fn) {
const s = {__r};
for (const k in shape) {
s[k] = function(...args) {
return _set(this, shape[k](...fn(this.__r, args)))
}
}
return r => _set(s, r)
}
function _set(s, r) {
if (r === undefined) return s
const o = Object.create(s)
o.__r = r
return o
}
import spool from './spool'
const math = spool({
add(x, n) { return x + n },
sub(x, n) { return x - n },
})
math(5).add(12).sub(1).__r // -> 16
import mori from 'mori'
import {spoor} from 'spool'
const m = spoor(mori)
// m().vector(1,2,3,4,5).map(x => x + 1).intoArray().__r // [2,3,4,5,6]
import spool from 'spool'
// var req = client().databases(1).collections(2).items(3).get()
// client(req.__r).post().__r // {"path":["/api/v1","databases",1,"collections",2,"items",3],"method":"POST"}
const client = spool({
databases,
collections,
items,
get,
post,
put,
}, {})
function collections(r, id) {
return path(r, ['collections', id])
}
function databases(r, id) {
return path(r, ['databases', id])
}
function items(r, id) {
return path(r, ['items', id])
}
function get(r, id) {
return method(r, 'GET')
}
function post(r, id) {
return method(r, 'POST')
}
function put(r, id) {
return method(r, 'PUT')
}
/////////////////////////////////////////////
function method(r, method) {
return merge(r, {method})
}
function path(r, p) {
return nest(r, {path: p})
}
function headers(r, headers) {
return merge(r, {headers})
}
function nest(...rs) {
return {
...merge(...rs),
path: [].concat(...rs.map(r => r.path).filter(p => p)),
}
}
function merge(...rs) {
return rs.reduce((o, r) => {
for (const k in r) o[k] = _merge(o[k], r[k])
return o
}, {})
}
function _merge(a, b) {
if (!a) return b
if (!b) return a
return typeof a === 'object' && typeof b === 'object' ? merge(a, b) : b;
}
@jeffpeterson
Copy link
Author

not sure how to expose __r

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment