UNPKG

@itwin/presentation-hierarchies

Version:

A package for creating hierarchies based on data in iTwin.js iModels.

107 lines 3.24 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** * This is pretty much a combination of: * - https://github.com/benlesh/rxjs-for-await/blob/94f9cf9cb015ac3700dfd1850eb81d36962eb70f/src/index.ts#L33, * - https://github.com/ReactiveX/rxjs/blob/2587ee852eb43eeb0883a7787bac2944d823392b/packages/observable/src/observable.ts#L922. * * Our implementation uses a linked list rather than an array to store values, which is more efficient. * * @internal */ export async function* eachValueFrom(source) { const deferreds = new Queue(); const values = new Queue(); let error; let completed = false; const subs = source.subscribe({ next: (value) => { const deferred = deferreds.pop(); if (deferred) { deferred.resolve({ value, done: false }); } else { values.push(value); } }, error: (err) => { error = err; for (let deferred = deferreds.pop(); deferred !== undefined; deferred = deferreds.pop()) { deferred.reject(err); } }, complete: () => { completed = true; for (let deferred = deferreds.pop(); deferred !== undefined; deferred = deferreds.pop()) { deferred.resolve({ value: undefined, done: true }); } }, }); try { while (true) { const value = values.pop(); if (value !== undefined) { yield value; continue; } if (completed) { return; } if (error) { // eslint-disable-next-line @typescript-eslint/only-throw-error throw error; } const result = await new Promise((resolve, reject) => { deferreds.push({ resolve, reject }); }); if (result.done) { return; } yield result.value; } } catch (err) { throw err; /* https://github.com/bcoe/c8/issues/229#issuecomment-1248533082 */ /* c8 ignore next */ } finally { subs.unsubscribe(); } } class QueueEntry { value; next; constructor(value, next) { this.value = value; this.next = next; } } class Queue { _front; _back; push(item) { const entry = new QueueEntry(item); if (this._back) { this._back.next = entry; } this._back = entry; if (!this._front) { this._front = entry; } } pop() { if (!this._front) { return undefined; } const value = this._front.value; this._front = this._front.next; if (!this._front) { this._back = undefined; } return value; } } //# sourceMappingURL=EachValueFrom.js.map