Files
2025-11-25 22:42:56 +01:00

94 lines
2.3 KiB
JavaScript

'use strict';
const { AigleProxy } = require('aigle-core');
const Aigle = require('../aigle');
const { map } = require('../map');
const { mapValues } = require('../mapValues');
const { INTERNAL, PENDING, apply, callProxyReciever } = require('./util');
module.exports = { createProxy };
class MixinProxy extends AigleProxy {
constructor(func, exec, args) {
super();
this._promise = new Aigle(INTERNAL);
this._func = func;
this._args = args;
this._execute = exec;
if (args[0] === PENDING) {
this._set = this._callResolve;
this._callResolve = exec;
}
}
_callResolve(value) {
this._promise._resolve(value);
}
_callReject(reason) {
this._promise._reject(reason);
}
}
function execute(value) {
const { _args } = this;
if (_args[0] === PENDING) {
_args[0] = value;
this._callResolve = this._set;
}
callProxyReciever(apply(this._func, _args), this);
return this._promise;
}
function executeWithPromisify(value) {
const { _args } = this;
if (_args[0] === PENDING) {
_args[0] = value;
this._callResolve = this._set;
} else {
value = _args[0];
}
const iterator = _args[1];
const isFunc = typeof iterator === 'function';
if (isFunc && Array.isArray(value)) {
callIterator(this, map, array => {
let index = 0;
_args[1] = () => array[index++];
callProxyReciever(apply(this._func, _args), this);
});
} else if (isFunc && value && typeof value === 'object') {
callIterator(this, mapValues, object => {
let index = 0;
const keys = Object.keys(object);
_args[1] = () => object[keys[index++]];
callProxyReciever(apply(this._func, _args), this);
});
} else {
callProxyReciever(apply(this._func, _args), this);
}
return this._promise;
}
function callIterator(proxy, func, onFulfilled) {
const [collection, iterator] = proxy._args;
const p = func(collection, (value, key) => iterator(value, key, collection));
return p._resolved === 1
? onFulfilled(p._value)
: p.then(onFulfilled, error => proxy._callReject(error));
}
/**
* @private
* @param {function} func
* @param {boolean} promisify
*/
function createProxy(func, promisify) {
const exec = promisify ? executeWithPromisify : execute;
return class extends MixinProxy {
constructor(...args) {
super(func, exec, args);
}
};
}