UNPKG

@nx/devkit

Version:

The Nx Devkit is used to customize Nx for different technologies and use cases. It contains many utility functions for reading and writing files, updating configuration, working with Abstract Syntax Trees(ASTs), and more. Learn more about [extending Nx by

364 lines (363 loc) • 9.4 kB
"use strict"; // Remove this if https://github.com/benlesh/rxjs-for-await/issues/15 is addressed Object.defineProperty(exports, "__esModule", { value: true }); exports.Deferred = void 0; exports.eachValueFrom = eachValueFrom; exports.bufferedValuesFrom = bufferedValuesFrom; exports.latestValueFrom = latestValueFrom; exports.nextValueFrom = nextValueFrom; class Deferred { constructor() { this.resolve = null; this.reject = null; this.promise = new Promise((a, b) => { this.resolve = a; this.reject = b; }); } } exports.Deferred = Deferred; const RESOLVED = Promise.resolve(); /** * Will subscribe to the `source` observable provided, * * Allowing a `for await..of` loop to iterate over every * value that the source emits. * * **WARNING**: If the async loop is slower than the observable * producing values, the values will build up in a buffer * and you could experience an out of memory error. * * This is a lossless subscription method. No value * will be missed or duplicated. * * Example usage: * * ```ts * async function test() { * const source$ = getSomeObservable(); * * for await(const value of eachValueFrom(source$)) { * console.log(value); * } * } * ``` * * @param source the Observable source to await values from */ async function* eachValueFrom(source) { const deferreds = []; const values = []; let hasError = false; let error = null; let completed = false; const subs = source.subscribe({ next: (value) => { if (deferreds.length > 0) { deferreds.shift().resolve({ value, done: false }); } else { values.push(value); } }, error: (err) => { hasError = true; error = err; while (deferreds.length > 0) { deferreds.shift().reject(err); } }, complete: () => { completed = true; while (deferreds.length > 0) { deferreds.shift().resolve({ value: undefined, done: true }); } }, }); try { while (true) { if (values.length > 0) { yield values.shift(); } else if (completed) { return; } else if (hasError) { throw error; } else { const d = new Deferred(); deferreds.push(d); const result = await d.promise; if (result.done) { return; } else { yield result.value; } } } } catch (err) { throw err; } finally { subs.unsubscribe(); } } /** * Will subscribe to the `source` observable provided * and build the emitted values up in a buffer. Allowing * `for await..of` loops to iterate and get the buffer * on each loop. * * This is a lossless subscription method. No value * will be missed or duplicated. * * Example usage: * * ```ts * async function test() { * const source$ = getSomeObservable(); * * for await(const buffer of bufferedValuesFrom(source$)) { * for (const value of buffer) { * console.log(value); * } * } * } * ``` * * @param source the Observable source to await values from */ async function* bufferedValuesFrom(source) { let deferred = null; const buffer = []; let hasError = false; let error = null; let completed = false; const subs = source.subscribe({ next: (value) => { if (deferred) { deferred.resolve(RESOLVED.then(() => { const bufferCopy = buffer.slice(); buffer.length = 0; return { value: bufferCopy, done: false }; })); deferred = null; } buffer.push(value); }, error: (err) => { hasError = true; error = err; if (deferred) { deferred.reject(err); deferred = null; } }, complete: () => { completed = true; if (deferred) { deferred.resolve({ value: undefined, done: true }); deferred = null; } }, }); try { while (true) { if (buffer.length > 0) { const bufferCopy = buffer.slice(); buffer.length = 0; yield bufferCopy; } else if (completed) { return; } else if (hasError) { throw error; } else { deferred = new Deferred(); const result = await deferred.promise; if (result.done) { return; } else { yield result.value; } } } } catch (err) { throw err; } finally { subs.unsubscribe(); } } /** * Will subscribe to the provided `source` observable, * allowing `for await..of` loops to iterate and get the * most recent value that was emitted. Will not iterate out * the same emission twice. * * This is a lossy subscription method. Do not use if * every value is important. * * Example usage: * * ```ts * async function test() { * const source$ = getSomeObservable(); * * for await(const value of latestValueFrom(source$)) { * console.log(value); * } * } * ``` * * @param source the Observable source to await values from */ async function* latestValueFrom(source) { let deferred = undefined; let latestValue; let hasLatestValue = false; let hasError = false; let error = null; let completed = false; const subs = source.subscribe({ next: (value) => { hasLatestValue = true; latestValue = value; if (deferred) { deferred.resolve(RESOLVED.then(() => { hasLatestValue = false; return { value: latestValue, done: false }; })); } }, error: (err) => { hasError = true; error = err; if (deferred) { deferred.reject(err); } }, complete: () => { completed = true; if (deferred) { hasLatestValue = false; deferred.resolve({ value: undefined, done: true }); } }, }); try { while (true) { if (hasLatestValue) { await RESOLVED; const value = latestValue; hasLatestValue = false; yield value; } else if (completed) { return; } else if (hasError) { throw error; } else { deferred = new Deferred(); const result = await deferred.promise; if (result.done) { return; } else { yield result.value; } } } } catch (err) { throw err; } finally { subs.unsubscribe(); } } /** * Subscribes to the provided `source` observable and allows * `for await..of` loops to iterate over it, such that * all values are dropped until the iteration occurs, then * the very next value that arrives is provided to the * `for await` loop. * * This is a lossy subscription method. Do not use if * every value is important. * * Example usage: * * ```ts * async function test() { * const source$ = getSomeObservable(); * * for await(const value of nextValueFrom(source$)) { * console.log(value); * } * } * ``` * * @param source the Observable source to await values from */ async function* nextValueFrom(source) { let deferred = undefined; let hasError = false; let error = null; let completed = false; const subs = source.subscribe({ next: (value) => { if (deferred) { deferred.resolve({ value, done: false }); } }, error: (err) => { hasError = true; error = err; if (deferred) { deferred.reject(err); } }, complete: () => { completed = true; if (deferred) { deferred.resolve({ value: undefined, done: true }); } }, }); try { while (true) { if (completed) { return; } else if (hasError) { throw error; } else { deferred = new Deferred(); const result = await deferred.promise; if (result.done) { return; } else { yield result.value; } } } } catch (err) { throw err; } finally { subs.unsubscribe(); } }