import run, {call} from './coroutines'
/**
* Wraps a normal function into a generator function
* that <code>yield</code>s on a regular basis
* @param {Function} fn - the function to be wrapped
* @param {number} [frequency=8] -
* the number of times the function should be called
* before performing a <code>yield</code>
* @returns {Coroutine} The wrapped yielding
* version of the function passed
*/
export function yielding(fn, frequency = 16) {
let yieldCount = 0;
if(fn._yielding) return fn;
let result = function* (...params) {
let result = fn(...params);
if (yieldCount++ % frequency === 0) {
yield;
}
return result;
};
result._yielding = true
return result
}
/**
* @callback PromiseFn
* @param {...*} [parameters] the parameters for the function
* @return {Promise} a promise for the result of the function
*/
/**
* Returns a function that will execute the passed
* Coroutine and return a Promise for its result. The
* returned function will take any number of parameters
* and pass them on to the coroutine.
*
* @param {Coroutine} coroutine - The coroutine to run
* @returns {PromiseFn|Function} a function that can be called to execute the coroutine
* and return its result on completion
*/
export function wrapAsPromise(coroutine) {
const result = function (...params) {
return run(coroutine(...params))
};
result.with = function (...params) {
return call(result, ...params)
}
return result
}
export function curryRight(fn, supplied, execute) {
if(fn.length > supplied.length) {
return function(...params) {
return curryRight.call(this, fn, [...params, ...supplied], execute)
}
}
return execute.apply(this, supplied)
}