86 lines
2.0 KiB
JavaScript
86 lines
2.0 KiB
JavaScript
'use strict';
|
|
|
|
const {none, final, isFinal, getFinalValue, many, isMany, getManyValues} = require('../defs');
|
|
|
|
const next = async (value, fns, index, push) => {
|
|
for (let i = index; i <= fns.length; ++i) {
|
|
if (value && typeof value.then == 'function') {
|
|
// thenable
|
|
value = await value;
|
|
}
|
|
if (value === none) break;
|
|
if (isFinal(value)) {
|
|
const val = getFinalValue(value);
|
|
val !== none && push(val);
|
|
break;
|
|
}
|
|
if (isMany(value)) {
|
|
const values = getManyValues(value);
|
|
if (i == fns.length) {
|
|
values.forEach(val => push(val));
|
|
} else {
|
|
for (let j = 0; j < values.length; ++j) {
|
|
await next(values[j], fns, i, push);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if (value && typeof value.next == 'function') {
|
|
// generator
|
|
for (;;) {
|
|
let data = value.next();
|
|
if (data && typeof data.then == 'function') {
|
|
data = await data;
|
|
}
|
|
if (data.done) break;
|
|
if (i == fns.length) {
|
|
push(data.value);
|
|
} else {
|
|
await next(data.value, fns, i, push);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
if (i == fns.length) {
|
|
push(value);
|
|
break;
|
|
}
|
|
value = fns[i](value);
|
|
}
|
|
};
|
|
|
|
const nop = () => {};
|
|
|
|
const asFun = (...fns) => {
|
|
fns = fns.filter(fn => fn);
|
|
if (!fns.length) return nop;
|
|
if (Symbol.asyncIterator && fns[0][Symbol.asyncIterator]) {
|
|
fns[0] = fns[0][Symbol.asyncIterator];
|
|
} else if (Symbol.iterator && fns[0][Symbol.iterator]) {
|
|
fns[0] = fns[0][Symbol.iterator];
|
|
}
|
|
return async value => {
|
|
const results = [];
|
|
await next(value, fns, 0, value => results.push(value));
|
|
switch (results.length) {
|
|
case 0:
|
|
return none;
|
|
case 1:
|
|
return results[0];
|
|
}
|
|
return many(results);
|
|
};
|
|
};
|
|
|
|
asFun.next = next;
|
|
|
|
asFun.none = none;
|
|
asFun.final = final;
|
|
asFun.isFinal = isFinal;
|
|
asFun.getFinalValue = getFinalValue;
|
|
asFun.many = many;
|
|
asFun.isMany = isMany;
|
|
asFun.getManyValues = getManyValues;
|
|
|
|
module.exports = asFun;
|