@aspectus/promise-proxy
Version:
Promise proxiyng mechanics to easily extend promise functionality.
79 lines (62 loc) • 1.96 kB
JavaScript
/*
eslint-disable
prefer-arrow-callback,
prefer-object-spread,
no-param-reassign,
no-restricted-syntax,
no-continue,
no-prototype-builtins,
prefer-rest-params,
prefer-spread,
func-names
*/
import curry from 'ramda/src/curry';
import map from 'ramda/src/map';
import compose from 'ramda/src/compose';
export const makeProxy = curry(function makeProxy(methods, promise, data = {}) {
promise.$data = Object.assign({}, data, promise.$data);
promise.$chain = (promise.$chain || []).concat([{ promise, methods }]);
return promise;
});
export class PromiseProxy {
constructor(proxy) {
this.$proxy = proxy;
this.$data = proxy.$data;
this.$injectMethods();
}
$injectMethods() {
this.$proxy.$chain.forEach(({ methods }) => {
if (!methods) {
return;
}
for (const method in methods) {
if (!methods.hasOwnProperty(method)) {
continue;
}
this[method] = function () {
return methods[method].apply(this, arguments);
};
}
});
}
$apply(name, args) {
return this.$update(this.$proxy[name].apply(this.$proxy, args));
}
$update(promise) {
promise.$data = this.$proxy.$data;
promise.$chain = this.$proxy.$chain;
return new this.constructor(promise);
}
then() { return this.$apply('then', arguments); }
catch() { return this.$apply('catch', arguments); }
finally() { return this.$apply('finally', arguments); }
}
export const createProxyExecutor = curry(
(methods, proxy, data = {}) => makeProxy(methods, proxy.$proxy || proxy, data)
);
export const initProxy = proxy => new PromiseProxy(proxy.$proxy || proxy);
const composeExecutorCreator = obj => (typeof obj === 'function' ? obj : createProxyExecutor(obj));
export function composeProxies() {
return compose(initProxy, compose.apply(this, map(composeExecutorCreator, arguments)));
}
export const createProxy = composeProxies;