UNPKG

@aspectus/promise-proxy

Version:

Promise proxiyng mechanics to easily extend promise functionality.

79 lines (62 loc) 1.96 kB
/* 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;