mreframe
Version:
A reagent/re-frame imitation that uses Mithril instead
67 lines (60 loc) • 3 kB
text/coffeescript
exports.identity = identity = (x) => x
exports.type = type = (x) => unless x? then x else Object.getPrototypeOf(x).constructor
exports.keys = keys = (x) => Object.keys x or {}
exports.vals = vals = (x) => Object.values x or {}
_entries = Object.entries or ((o) => keys(o).map (k) => [k, o[k]])
exports.entries = entries = (o) => _entries o or {}
_dict = Object.fromEntries or ((kvs) => merge ...kvs.map ([k, v]) => [k]: v)
exports.dict = (x) => _dict x or []
exports.isArray = isArray = Array.isArray
exports.isDict = isDict = (x) => (type x) is Object
exports.isFn = (x) => (typeof x) is 'function'
exports.merge = merge = (...os) => Object.assign {}, ...os
exports.assoc = assoc = (o, k, v) =>
o = if isArray(o) and Number.isInteger(k) and k >= 0 then o[..] else {o...}
o[k] = v
o
exports.dissoc = (o, ...ks) =>
o = if isArray(o) then o[..] else {o...}
ks.forEach (k) => delete o[k]
o
exports.update = update = (o, k, f, ...args) => assoc o, k, f o?[k], ...args
exports.getIn = getIn = (o, path) => path.reduce ((x, k) => x?[k]), o
exports.assocIn = assocIn = (o, path, v) =>
if path.length < 2 then assoc o, path[0], v
else update o, path[0], assocIn, path[1..], v
exports.updateIn = (o, path, f, ...args) => assocIn o, path, (f (getIn o, path), ...args)
# dissocIn = (o, path, ...ks) => updateIn o, path, dissoc, ...ks
exports.chunks = (xs, n) => Array.from length: (Math.ceil xs.length / n),
(_, i) => xs[n*i ... n*(i+1)] # /
exports.flatten = flatten = (xs) => unless isArray xs then xs else xs.flatMap flatten
exports.repr = (x) => JSON.stringify x, replacer
exports.identical = identical = (a, b) => a is b or (a isnt a and b isnt b)
exports.eq = eq = (a, b) => a is b or
if a isnt a then b isnt b
else if isArray a then (isArray b) and eqArr a, b, eq
else (isDict a) and (isDict b) and eqObj a, b
exports.eqShallow = eqShallow = (a, b) => a is b or
if a isnt a then b isnt b
else if isArray a then (isArray b) and eqArr a, b, identical
else (isDict a) and (isDict b) and eqObjShallow a, b
sorter = (o) => _dict (entries o).sort()
replacer = (_, v) =>
if type(v) is RegExp then "#{v}"
else unless isDict v then v
else sorter v
eqArr = (xs, ys, eq) => xs.length is ys.length and xs.every (x, i) => eq x, ys[i]
eqObj = (a, b, aks = (keys a), bks = new Set(keys b)) =>
aks.length is bks.size and aks.every((k) => bks.has(k)) and aks.every (k) => eq a[k], b[k]
eqObjShallow = (a, b, aks = (keys a)) =>
aks.length is keys(b).length and aks.every (k) => k of b and identical a[k], b[k]
exports.chain = (x, ...fs) => fs.map((f) => if isArray f then f else [f]).reduce ((x, f) => f[0] x, ...f[1..]), x
exports.multi = (dispatch=identity) =>
_methods = new Map
_default = => throw TypeError "Invalid arguments"
self = Object.assign (
(...args) => ((_methods.get dispatch ...args) or _default) ...args
), {
when: (k, f) => _methods.set k, f; self
default: (f) => _default = f; self
}