focused
Version:
Lens/Optics library for JavaScript
71 lines (63 loc) • 1.79 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.idLens = idLens;
exports.lensProxy = lensProxy;
var _lens = require("./lens");
var _traversal = require("./traversal");
var _operations = require("./operations");
// idLens : SimpleLens<S,S>
function idLens(_, f, s) {
return f(s);
}
/**
* returns a Proxy object for easing creation & composition of optics
*
* const _ = lensProxy()
* _.name <=> prop("name")
* _.todo.title <=> compose(prop("todo"), prop("title"))
*
* For convenience, safe access to non existing is provided by perfixng the prop name with '$'
*
* _.$name <=> maybeProp("name")
*
* You can also insert other optics usin '$' method of the proxy lensProxy, for example
*
* _.todos.$(each).title <=> compose(prop("todos"), each, prop("title"))
*
* is a traversal that focuses on all titles of the todo array
*/
function getOrCreateLens(memo, parent, key) {
let l = memo.get(key);
if (l == null) {
let child;
const num = Number(key);
if (String(num) === key) {
child = (0, _lens.index)(num);
} else if (key[0] === "$") {
child = (0, _traversal.maybeProp)(key.slice(1));
} else {
child = (0, _lens.prop)(key);
}
l = lensProxy((0, _operations.compose2)(parent, child));
memo.set(key, l);
}
return l;
}
function lensProxy(parent = idLens) {
const memo = new Map();
return new Proxy(() => {}, {
get(target, key) {
if (key === "$") {
return child => {
return lensProxy((0, _operations.compose2)(parent, child));
};
}
return getOrCreateLens(memo, parent, key);
},
apply(target, thiz, [F, f, s]) {
return parent(F, f, s);
}
});
}