Skip to content

Commit 0f8034d

Browse files
committed
Initial commit of library
1 parent f3fedd9 commit 0f8034d

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

src/decko.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
2+
const EMPTY = {};
3+
const HOP = Object.prototype.hasOwnProperty;
4+
5+
let fns = {
6+
/** let cachedFn = memoize(originalFn); */
7+
memoize(fn, opt=EMPTY) {
8+
let cache = opt.cache || {};
9+
return function (...a) {
10+
let k = String(a[0]);
11+
if (opt.caseSensitive===false) k = k.toLowerCase();
12+
return HOP.call(cache,k) ? cache[k] : (cache[k] = fn.apply(this, a));
13+
};
14+
},
15+
16+
/** let throttled = debounce(10, console.log); */
17+
debounce(fn, opts) {
18+
if (typeof opts==='function') { let p = fn; fn = opts; opts = p; }
19+
let delay = opts && opts.delay || opts || 0,
20+
args, timer;
21+
return (...a) => {
22+
args = a;
23+
if (!timer) timer = setTimeout( () => {
24+
fn(...args);
25+
timer = args = null;
26+
}, delay);
27+
};
28+
},
29+
30+
bind(target, key, { value: fn }) {
31+
return {
32+
configurable: true,
33+
get() {
34+
let value = fn.bind(this);
35+
Object.defineProperty(this, key, {
36+
value,
37+
configurable: true,
38+
writable: true
39+
});
40+
return value;
41+
}
42+
};
43+
}
44+
}
45+
46+
47+
let memoize = multiMethod(fns.memoize),
48+
debounce = multiMethod(fns.debounce),
49+
bind = multiMethod((f,c)=>f.bind(c), ()=>fns.bind);
50+
51+
export { memoize, debounce, bind };
52+
export default { memoize, debounce, bind };
53+
54+
55+
/** Creates a function that supports the following calling styles:
56+
* d() - returns an unconfigured decorator
57+
* d(opts) - returns a configured decorator
58+
* d(fn, opts) - returns a decorated proxy to `fn`
59+
* d(target, key, desc) - the decorator itself
60+
*
61+
* @Example:
62+
* // simple identity deco:
63+
* let d = multiMethod( fn => fn );
64+
*
65+
* class Foo {
66+
* @d
67+
* bar() { }
68+
*
69+
* @d()
70+
* baz() { }
71+
*
72+
* @d({ opts })
73+
* bat() { }
74+
*
75+
* bap = d(() => {})
76+
* }
77+
*/
78+
function multiMethod(inner, deco) {
79+
deco = deco || inner.decorate || decorator(inner);
80+
let d = deco();
81+
return (...args) => {
82+
let l = args.length;
83+
return (l<2 ? deco : (l>2 ? d : inner))(...args);
84+
}
85+
}
86+
87+
/** Returns function supports the forms:
88+
* deco(target, key, desc) -> decorate a method
89+
* deco(Fn) -> call the decorator proxy on a function
90+
*/
91+
function decorator(fn) {
92+
return opt => (
93+
typeof opt==='function' ? fn(opt) : (target, key, desc) => {
94+
desc.value = fn(desc.value, opt);
95+
}
96+
);
97+
};

0 commit comments

Comments
 (0)