ix
Version:
The Interactive Extensions for JavaScript
342 lines (340 loc) • 12.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.from = exports.as = exports.FromObservableAsyncIterable = exports.FromPromiseIterable = exports.FromAsyncIterable = exports.FromArrayIterable = exports.AsyncSink = exports.AsyncIterableX = void 0;
const tslib_1 = require("tslib");
const bindcallback_js_1 = require("../util/bindcallback.js");
const identity_js_1 = require("../util/identity.js");
const isiterable_js_1 = require("../util/isiterable.js");
const tolength_js_1 = require("../util/tolength.js");
const aborterror_js_1 = require("../aborterror.js");
/**
* This class serves as the base for all operations which support [Symbol.asyncIterator].
*/
class AsyncIterableX {
/** @nocollapse */
forEach(projection, thisArg, signal) {
var _a, e_1, _b, _c;
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const source = signal ? new WithAbortAsyncIterable(this, signal) : this;
let i = 0;
try {
for (var _d = true, source_1 = tslib_1.__asyncValues(source), source_1_1; source_1_1 = yield source_1.next(), _a = source_1_1.done, !_a; _d = true) {
_c = source_1_1.value;
_d = false;
const item = _c;
yield projection.call(thisArg, item, i++, signal);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (!_d && !_a && (_b = source_1.return)) yield _b.call(source_1);
}
finally { if (e_1) throw e_1.error; }
}
});
}
pipe(...args) {
let i = -1;
const n = args.length;
let acc = this;
while (++i < n) {
acc = args[i](AsyncIterableX.as(acc));
}
return acc;
}
/** @nocollapse */
static from(source, selector = identity_js_1.identityAsync, thisArg) {
const fn = (0, bindcallback_js_1.bindCallback)(selector, thisArg, 2);
if ((0, isiterable_js_1.isIterable)(source) || (0, isiterable_js_1.isAsyncIterable)(source)) {
return new FromAsyncIterable(source, fn);
}
if ((0, isiterable_js_1.isPromise)(source)) {
return new FromPromiseIterable(source, fn);
}
if ((0, isiterable_js_1.isObservable)(source)) {
return new FromObservableAsyncIterable(source, fn);
}
if ((0, isiterable_js_1.isArrayLike)(source)) {
return new FromArrayIterable(source, fn);
}
if ((0, isiterable_js_1.isIterator)(source)) {
return new FromAsyncIterable({ [Symbol.asyncIterator]: () => source }, fn);
}
throw new TypeError('Input type not supported');
}
/**
* Converts the input into an async-iterable sequence.
*
* @param {*} source The source to convert to an async-iterable sequence.
* @returns {AsyncIterableX<*>} An async-iterable containing the input.
*/
/** @nocollapse */
static as(source) {
if (source instanceof AsyncIterableX) {
return source;
}
if (typeof source === 'string') {
return new FromArrayIterable([source], identity_js_1.identityAsync);
}
if ((0, isiterable_js_1.isIterable)(source) || (0, isiterable_js_1.isAsyncIterable)(source)) {
return new FromAsyncIterable(source, identity_js_1.identityAsync);
}
if ((0, isiterable_js_1.isPromise)(source)) {
return new FromPromiseIterable(source, identity_js_1.identityAsync);
}
if ((0, isiterable_js_1.isObservable)(source)) {
return new FromObservableAsyncIterable(source, identity_js_1.identityAsync);
}
if ((0, isiterable_js_1.isArrayLike)(source)) {
return new FromArrayIterable(source, identity_js_1.identityAsync);
}
return new FromArrayIterable([source], identity_js_1.identityAsync);
}
}
exports.AsyncIterableX = AsyncIterableX;
AsyncIterableX.prototype[Symbol.toStringTag] = 'AsyncIterableX';
Object.defineProperty(AsyncIterableX, Symbol.hasInstance, {
writable: true,
configurable: true,
value(inst) {
return !!(inst && inst[Symbol.toStringTag] === 'AsyncIterableX');
},
});
const ARRAY_VALUE = 'value';
const ARRAY_ERROR = 'error';
/** @ignore */
/** @ignore */
class AsyncSink {
constructor() {
this._ended = false;
this._values = [];
this._resolvers = [];
}
[Symbol.asyncIterator]() {
return this;
}
write(value) {
this._push({ type: ARRAY_VALUE, value });
}
error(error) {
this._push({ type: ARRAY_ERROR, error });
}
_push(item) {
if (this._ended) {
throw new Error('AsyncSink already ended');
}
if (this._resolvers.length > 0) {
const { resolve, reject } = this._resolvers.shift();
if (item.type === ARRAY_ERROR) {
reject(item.error);
}
else {
resolve({ done: false, value: item.value });
}
}
else {
this._values.push(item);
}
}
next() {
if (this._values.length > 0) {
const { type, value, error } = this._values.shift();
if (type === ARRAY_ERROR) {
return Promise.reject(error);
}
else {
return Promise.resolve({ done: false, value });
}
}
if (this._ended) {
return Promise.resolve({ done: true });
}
return new Promise((resolve, reject) => {
this._resolvers.push({ resolve, reject });
});
}
end() {
while (this._resolvers.length > 0) {
this._resolvers.shift().resolve({ done: true });
}
this._ended = true;
}
}
exports.AsyncSink = AsyncSink;
/** @ignore */
class FromArrayIterable extends AsyncIterableX {
constructor(source, selector) {
super();
this._source = source;
this._selector = selector;
}
[Symbol.asyncIterator]() {
return tslib_1.__asyncGenerator(this, arguments, function* _a() {
let i = 0;
const length = (0, tolength_js_1.toLength)(this._source.length);
while (i < length) {
yield yield tslib_1.__await(yield tslib_1.__await(this._selector(this._source[i], i++)));
}
});
}
}
exports.FromArrayIterable = FromArrayIterable;
/** @ignore */
class FromAsyncIterable extends AsyncIterableX {
constructor(source, selector) {
super();
this._source = source;
this._selector = selector;
}
[Symbol.asyncIterator](signal) {
return tslib_1.__asyncGenerator(this, arguments, function* _a() {
var _b, e_2, _c, _d, _e, e_3, _f, _g;
let i = 0;
if (signal && this._source instanceof AsyncIterableX) {
try {
for (var _h = true, _j = tslib_1.__asyncValues(new WithAbortAsyncIterable(this._source, signal)), _k; _k = yield tslib_1.__await(_j.next()), _b = _k.done, !_b; _h = true) {
_d = _k.value;
_h = false;
const item = _d;
yield yield tslib_1.__await(yield tslib_1.__await(this._selector(item, i++)));
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (!_h && !_b && (_c = _j.return)) yield tslib_1.__await(_c.call(_j));
}
finally { if (e_2) throw e_2.error; }
}
}
else {
(0, aborterror_js_1.throwIfAborted)(signal);
try {
for (var _l = true, _m = tslib_1.__asyncValues(this._source), _o; _o = yield tslib_1.__await(_m.next()), _e = _o.done, !_e; _l = true) {
_g = _o.value;
_l = false;
const item = _g;
(0, aborterror_js_1.throwIfAborted)(signal);
const value = yield tslib_1.__await(this._selector(item, i++));
(0, aborterror_js_1.throwIfAborted)(signal);
yield yield tslib_1.__await(value);
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (!_l && !_e && (_f = _m.return)) yield tslib_1.__await(_f.call(_m));
}
finally { if (e_3) throw e_3.error; }
}
}
});
}
}
exports.FromAsyncIterable = FromAsyncIterable;
/** @ignore */
class FromPromiseIterable extends AsyncIterableX {
constructor(source, selector) {
super();
this._source = source;
this._selector = selector;
}
[Symbol.asyncIterator]() {
return tslib_1.__asyncGenerator(this, arguments, function* _a() {
const item = yield tslib_1.__await(this._source);
yield yield tslib_1.__await(yield tslib_1.__await(this._selector(item, 0)));
});
}
}
exports.FromPromiseIterable = FromPromiseIterable;
/** @ignore */
class FromObservableAsyncIterable extends AsyncIterableX {
constructor(observable, selector) {
super();
this._observable = observable;
this._selector = selector;
}
[Symbol.asyncIterator](signal) {
return tslib_1.__asyncGenerator(this, arguments, function* _a() {
(0, aborterror_js_1.throwIfAborted)(signal);
const sink = new AsyncSink();
const subscription = this._observable.subscribe({
next(value) {
sink.write(value);
},
error(err) {
sink.error(err);
},
complete() {
sink.end();
},
});
function onAbort() {
sink.error(new aborterror_js_1.AbortError());
}
if (signal) {
signal.addEventListener('abort', onAbort);
}
let i = 0;
try {
for (let next; !(next = yield tslib_1.__await(sink.next())).done;) {
(0, aborterror_js_1.throwIfAborted)(signal);
yield yield tslib_1.__await(yield tslib_1.__await(this._selector(next.value, i++)));
}
}
finally {
if (signal) {
signal.removeEventListener('abort', onAbort);
}
subscription.unsubscribe();
}
});
}
}
exports.FromObservableAsyncIterable = FromObservableAsyncIterable;
class WithAbortAsyncIterable {
constructor(source, signal) {
this._source = source;
this._signal = signal;
}
[Symbol.asyncIterator]() {
// @ts-ignore
return this._source[Symbol.asyncIterator](this._signal);
}
}
try {
((isBrowser) => {
if (isBrowser) {
return;
}
AsyncIterableX.prototype['pipe'] = nodePipe;
const readableOpts = (x, opts = x._writableState || { objectMode: true }) => opts;
function nodePipe(...args) {
let i = -1;
let end;
const n = args.length;
let prev = this;
let next;
while (++i < n) {
next = args[i];
if (typeof next === 'function') {
prev = next(AsyncIterableX.as(prev));
}
else if ((0, isiterable_js_1.isWritableNodeStream)(next)) {
({ end = true } = args[i + 1] || {});
// prettier-ignore
return (0, isiterable_js_1.isReadableNodeStream)(prev) ? prev.pipe(next, { end }) :
AsyncIterableX.as(prev).toNodeStream(readableOpts(next)).pipe(next, { end });
}
}
return prev;
}
})(typeof window === 'object' && typeof document === 'object' && document.nodeType === 9);
}
catch (e) {
/* */
}
exports.as = AsyncIterableX.as;
exports.from = AsyncIterableX.from;
//# sourceMappingURL=asynciterablex.js.map