UNPKG

@apollo/client

Version:

A fully-featured caching GraphQL client.

68 lines 2.86 kB
import { EMPTY, Observable } from "rxjs"; /** * Like `combineLatest` but with some differences: * * - It only works on arrays as an input * - Batches updates to each array index that contains a referentially equal * observable * - Doesn't allow for custom scheduler * - Expects array of constructed observables instead of `Array<ObservableInput>` */ export function combineLatestBatched(observables) { if (observables.length === 0) { return EMPTY; } return new Observable((observer) => { const { length } = observables; // Keeps track of current values for each observable const values = new Array(length); // Used to batch an update each item in the array that share an observable // so that they can be emitted together. const indexesByObservable = new Map(); observables.forEach((source, idx) => { if (!indexesByObservable.has(source)) { indexesByObservable.set(source, new Set()); } indexesByObservable.get(source).add(idx); }); // Track the number of active subscriptions so we know when to complete this // observable let active = indexesByObservable.size; // Track how many observables are left to emit their first value let remainingFirstValues = indexesByObservable.size; let currentBatch; // Subscribe to each unique observable instead of the raw source array of // observables since we want at most 1-subscription per unique observable. // This ensures an update can write to multiple indexes before emitting the // result. indexesByObservable.forEach((indexes, source) => { let hasFirstValue = false; const subscription = source.subscribe({ next: (value) => { indexes.forEach((idx) => (values[idx] = value)); if (!hasFirstValue) { hasFirstValue = true; remainingFirstValues--; } if (!remainingFirstValues) { currentBatch ||= new Set(observables.filter((obs) => obs.dirty)); currentBatch.delete(source); if (!currentBatch.size) { observer.next(values.slice()); currentBatch = undefined; } } }, complete: () => { active--; if (!active) { observer.complete(); } }, error: observer.error.bind(observer), }); observer.add(subscription); }); }); } //# sourceMappingURL=combineLatestBatched.js.map