Path: blob/main/components/gitpod-protocol/src/util/async-iterator.ts
2500 views
/**1* Copyright (c) 2020 Gitpod GmbH. All rights reserved.2* Licensed under the GNU Affero General Public License (AGPL).3* See License.AGPL.txt in the project root for license information.4*/56// Use asyncIterators with es20157if (typeof (Symbol as any).asyncIterator === "undefined") {8(Symbol as any).asyncIterator = Symbol.asyncIterator || Symbol("asyncIterator");9}1011export async function find<T>(it: AsyncIterableIterator<T>, predicate: (value: T) => boolean): Promise<T | undefined> {12for await (const t of it) {13if (predicate(t)) {14return t;15}16}17return undefined;18}19export async function filter<T>(it: AsyncIterableIterator<T>, predicate: (value: T) => boolean): Promise<T[]> {20const result = [];21for await (const t of it) {22if (predicate(t)) {23result.push(t);24}25}26return result;27}2829export interface AsyncCachingIterator<T> extends AsyncIterableIterator<T> {30resetCursor(): void;31}32export class AsyncCachingIteratorImpl<T> implements AsyncIterableIterator<T>, AsyncCachingIterator<T> {33protected cache: T[] = [];34protected cursor = 0;35protected cacheRead = false;3637constructor(protected readonly iterable: AsyncIterableIterator<T>) {}3839public resetCursor() {40this.cursor = 0;41this.cacheRead = false;42}4344public async next(value?: any): Promise<IteratorResult<T>> {45if (!this.cacheRead && this.cursor < this.cache.length) {46return {47done: false,48value: this.cache[this.cursor++],49};50}51this.cacheRead = true;5253// eslint-disable-next-line @typescript-eslint/no-unsafe-argument54const result = await this.iterable.next(value);55if (!result.done) {56this.cache.push(result.value);57}58return result;59}6061[Symbol.asyncIterator]() {62return this;63}64}656667