diff options
Diffstat (limited to 'remote/test/puppeteer/packages/puppeteer-core/src/common/HandleIterator.ts')
-rw-r--r-- | remote/test/puppeteer/packages/puppeteer-core/src/common/HandleIterator.ts | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/common/HandleIterator.ts b/remote/test/puppeteer/packages/puppeteer-core/src/common/HandleIterator.ts new file mode 100644 index 0000000000..c88003ed71 --- /dev/null +++ b/remote/test/puppeteer/packages/puppeteer-core/src/common/HandleIterator.ts @@ -0,0 +1,76 @@ +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +import type {JSHandle} from '../api/JSHandle.js'; +import {DisposableStack, disposeSymbol} from '../util/disposable.js'; + +import type {AwaitableIterable, HandleFor} from './types.js'; + +const DEFAULT_BATCH_SIZE = 20; + +/** + * This will transpose an iterator JSHandle into a fast, Puppeteer-side iterator + * of JSHandles. + * + * @param size - The number of elements to transpose. This should be something + * reasonable. + */ +async function* fastTransposeIteratorHandle<T>( + iterator: JSHandle<AwaitableIterator<T>>, + size: number +) { + using array = await iterator.evaluateHandle(async (iterator, size) => { + const results = []; + while (results.length < size) { + const result = await iterator.next(); + if (result.done) { + break; + } + results.push(result.value); + } + return results; + }, size); + const properties = (await array.getProperties()) as Map<string, HandleFor<T>>; + const handles = properties.values(); + using stack = new DisposableStack(); + stack.defer(() => { + for (using handle of handles) { + handle[disposeSymbol](); + } + }); + yield* handles; + return properties.size === 0; +} + +/** + * This will transpose an iterator JSHandle in batches based on the default size + * of {@link fastTransposeIteratorHandle}. + */ + +async function* transposeIteratorHandle<T>( + iterator: JSHandle<AwaitableIterator<T>> +) { + let size = DEFAULT_BATCH_SIZE; + while (!(yield* fastTransposeIteratorHandle(iterator, size))) { + size <<= 1; + } +} + +type AwaitableIterator<T> = Iterator<T> | AsyncIterator<T>; + +/** + * @internal + */ +export async function* transposeIterableHandle<T>( + handle: JSHandle<AwaitableIterable<T>> +): AsyncIterableIterator<HandleFor<T>> { + using generatorHandle = await handle.evaluateHandle(iterable => { + return (async function* () { + yield* iterable; + })(); + }); + yield* transposeIteratorHandle(generatorHandle); +} |