selectorFn = {
const types = sels =>
sels.map(x => (checks.isRegExp(x) ? "regexp" : typeof x));
const typesStr = sels => types(sels).toString();
const selectorFn = defmulti(sel => typesStr(sel));
selectorFn.isa("function", "fn");
selectorFn.isa("function,string", "fn+to");
selectorFn.isa("string,function", "key+fn");
selectorFn.isa("string,function,string", "from+fn+to");
selectorFn.isa("string,string,function", "from+key+fn");
selectorFn.isa("string,string,function,string", "from+key+fn+to");
selectorFn.isa("string,string", "key+equal");
selectorFn.isa("string,number", "key+equal");
selectorFn.isa("string,string,string", "key+equal+to");
selectorFn.isa("string,number,string", "key+equal+to");
selectorFn.isa("string,string,string,string", "from+key+equal+to");
selectorFn.isa("string,string,number,string", "from+key+equal+to");
selectorFn.isa("string,regexp", "key+match");
selectorFn.isa("string,regexp,string", "key+match+to");
selectorFn.isa("string,string,regexp,string", "from+key+match+to");
const getK = k => obj => obj[k];
const compileSel = (from, keyFn, filterFn, to) => acc => {
const fr = [...acc[from]];
acc[to] = new Set(fr.filter(x => filterFn(keyFn(x))));
return acc;
};
selectorFn.add("fn", ([fn]) => compileSel(ALL, tx.identity, fn, ALL));
selectorFn.add("fn+to", ([fn, to]) => compileSel(ALL, tx.identity, fn, to));
selectorFn.add("from+fn+to", ([from, fn, to]) =>
compileSel(from, tx.identity, fn, to)
);
selectorFn.add("key+fn", ([key, fn]) => compileSel(ALL, getK(key), fn, ALL));
selectorFn.add("from+key+fn", ([from, key, fn]) =>
compileSel(from, getK(key), fn, ALL)
);
selectorFn.add("from+key+fn+to", ([from, key, fn, to]) =>
compileSel(from, getK(key), fn, to)
);
selectorFn.add("key+equal", ([key, equal, to]) =>
compileSel(ALL, getK(key), x => x == equal, ALL)
);
selectorFn.add("key+equal+to", ([key, equal, to]) =>
compileSel(ALL, getK(key), x => x == equal, to)
);
selectorFn.add("from+key+equal+to", ([from, key, equal, to]) =>
compileSel(from, getK(key), x => x == equal, to)
);
selectorFn.add("key+match", ([key, regexp]) =>
compileSel(ALL, getK(key), x => regexp.test(x), ALL)
);
selectorFn.add("key+match+to", ([key, regexp, to]) =>
compileSel(ALL, getK(key), x => regexp.test(x), to)
);
selectorFn.add("from+key+match+to", ([from, key, regexp, to]) =>
compileSel(from, getK(key), x => regexp.test(x), to)
);
return selectorFn;
}