ix
Version:
The Interactive Extensions for JavaScript
89 lines (87 loc) • 3.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.memoize = exports.MemoizeAsyncBuffer = void 0;
const tslib_1 = require("tslib");
const asynciterablex_js_1 = require("../asynciterablex.js");
const _refcountlist_js_1 = require("../../iterable/operators/_refcountlist.js");
const create_js_1 = require("../create.js");
const aborterror_js_1 = require("../../aborterror.js");
/** @ignore */
class MemoizeAsyncBuffer extends asynciterablex_js_1.AsyncIterableX {
constructor(source, buffer) {
super();
this._error = null;
this._shared = null;
this._stopped = false;
this._source = source;
this._buffer = buffer;
}
[Symbol.asyncIterator](signal) {
(0, aborterror_js_1.throwIfAborted)(signal);
return this._getIterable(0);
}
_getIterable(offset = 0) {
return tslib_1.__asyncGenerator(this, arguments, function* _getIterable_1() {
let i = offset - 1;
let done = false;
const buffer = this._buffer;
try {
do {
if (++i < buffer.count) {
yield yield tslib_1.__await(buffer.get(i));
continue;
}
if (this._stopped) {
throw this._error;
}
if (this._shared === null) {
this._shared = this._source.next().then((r) => {
this._shared = null;
if (!r.done) {
buffer.push(r.value);
}
return r;
});
}
({ done } = yield tslib_1.__await(this._shared.catch((e) => {
this._error = e;
this._stopped = true;
throw e;
})));
if (!done) {
yield yield tslib_1.__await(buffer.get(i));
}
} while (!done);
}
finally {
buffer.done();
}
});
}
}
exports.MemoizeAsyncBuffer = MemoizeAsyncBuffer;
/**
* Memoizes the source sequence within a selector function where a specified number of iterators can get access
* to all of the sequence's elements without causing multiple iterations over the source.
*
* @template TSource Source sequence element type.
* @template TResult Result sequence element type.
* @param {number} [readerCount=-1] Number of iterators that can access the underlying buffer. Once every
* iterator has obtained an element from the buffer, the element is removed from the buffer.
* @param {(value: AsyncIterable<TSource>) => AsyncIterable<TResult>} [selector] Selector function with memoized access
* to the source sequence for a specified number of iterators.
* @returns {(OperatorAsyncFunction<TSource, TSource | TResult>)} Sequence resulting from applying the selector function to the
* memoized view over the source sequence.
*/
function memoize(readerCount = -1, selector) {
return function memoizeOperatorFunction(source) {
if (!selector) {
return readerCount === -1
? new MemoizeAsyncBuffer(source[Symbol.asyncIterator](), new _refcountlist_js_1.MaxRefCountList())
: new MemoizeAsyncBuffer(source[Symbol.asyncIterator](), new _refcountlist_js_1.RefCountList(readerCount));
}
return (0, create_js_1.create)(() => selector(memoize(readerCount)(source))[Symbol.asyncIterator]());
};
}
exports.memoize = memoize;
//# sourceMappingURL=memoize.js.map