diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-11-20 06:45:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-11-20 06:45:41 +0000 |
commit | 9d45e42dc0298ea8241132142d3100358fe99dc4 (patch) | |
tree | 8435105a23089a82f8298490dff6e3e4218930b4 /src | |
parent | Initial commit. (diff) | |
download | decko-9d45e42dc0298ea8241132142d3100358fe99dc4.tar.xz decko-9d45e42dc0298ea8241132142d3100358fe99dc4.zip |
Adding upstream version 1.2.0.upstream/1.2.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/decko.d.ts | 30 | ||||
-rw-r--r-- | src/decko.js | 98 |
2 files changed, 128 insertions, 0 deletions
diff --git a/src/decko.d.ts b/src/decko.d.ts new file mode 100644 index 0000000..e65c737 --- /dev/null +++ b/src/decko.d.ts @@ -0,0 +1,30 @@ +/** + * + */ +export function bind<T>( + target: Object, + propertyKey: string | symbol, + descriptor?: TypedPropertyDescriptor<T> +): TypedPropertyDescriptor<T> | void; +export function bind(): MethodDecorator; + +/** + * @param caseSensitive Makes cache keys case-insensitive + * @param cache Presupply cache storage, for seeding or sharing entries + */ + +export function memoize<T>( + target: Object, + propertyKey: string | symbol, + descriptor?: TypedPropertyDescriptor<T> +): TypedPropertyDescriptor<T> | void; +export function memoize(caseSensitive?: boolean, cache?: Object): MethodDecorator; +/** + * @param delay number + */ +export function debounce<T>( + target: Object, + propertyKey: string | symbol, + descriptor?: TypedPropertyDescriptor<T> +): TypedPropertyDescriptor<T> | void; +export function debounce(delay?: number): MethodDecorator;
\ No newline at end of file diff --git a/src/decko.js b/src/decko.js new file mode 100644 index 0000000..298e092 --- /dev/null +++ b/src/decko.js @@ -0,0 +1,98 @@ + +const EMPTY = {}; +const HOP = Object.prototype.hasOwnProperty; + +let fns = { + /** let cachedFn = memoize(originalFn); */ + memoize(fn, opt=EMPTY) { + let cache = opt.cache || {}; + return function(...a) { + let k = String(a[0]); + if (opt.caseSensitive===false) k = k.toLowerCase(); + return HOP.call(cache,k) ? cache[k] : (cache[k] = fn.apply(this, a)); + }; + }, + + /** let throttled = debounce(10, console.log); */ + debounce(fn, opts) { + if (typeof opts==='function') { let p = fn; fn = opts; opts = p; } + let delay = opts && opts.delay || opts || 0, + args, context, timer; + return function(...a) { + args = a; + context = this; + if (!timer) timer = setTimeout( () => { + fn.apply(context, args); + args = context = timer = null; + }, delay); + }; + }, + + bind(target, key, { value: fn }) { + return { + configurable: true, + get() { + let value = fn.bind(this); + Object.defineProperty(this, key, { + value, + configurable: true, + writable: true + }); + return value; + } + }; + } +}; + + +let memoize = multiMethod(fns.memoize), + debounce = multiMethod(fns.debounce), + bind = multiMethod((f,c)=>f.bind(c), ()=>fns.bind); + +export { memoize, debounce, bind }; +export default { memoize, debounce, bind }; + + +/** Creates a function that supports the following calling styles: + * d() - returns an unconfigured decorator + * d(opts) - returns a configured decorator + * d(fn, opts) - returns a decorated proxy to `fn` + * d(target, key, desc) - the decorator itself + * + * @Example: + * // simple identity deco: + * let d = multiMethod( fn => fn ); + * + * class Foo { + * @d + * bar() { } + * + * @d() + * baz() { } + * + * @d({ opts }) + * bat() { } + * + * bap = d(() => {}) + * } + */ +function multiMethod(inner, deco) { + deco = deco || inner.decorate || decorator(inner); + let d = deco(); + return (...args) => { + let l = args.length; + return (l<2 ? deco : (l>2 ? d : inner))(...args); + }; +} + +/** Returns function supports the forms: + * deco(target, key, desc) -> decorate a method + * deco(Fn) -> call the decorator proxy on a function + */ +function decorator(fn) { + return opt => ( + typeof opt==='function' ? fn(opt) : (target, key, desc) => { + desc.value = fn(desc.value, opt, target, key, desc); + } + ); +} |