Skip to content

Commit

Permalink
fix(base): wait for all chunked requests to arrive before continuing (#…
Browse files Browse the repository at this point in the history
…4017)

Our previous approach of chunking document availability requests did not wait for all the chunks to finish before returning the results. The debounceCollect utility expects an observable that returns all results in one go, but because we returned a stream that would emit the chunks one-by-one as they arrived, we would only handle the first emission, which would not include the whole result set, breaking assumptions further down the line.

This patch fixes the issue by reducing over each emission, successively add them to an array. (the reduce operator will wait for the stream to finish before emitting a single reduced value).
  • Loading branch information
bjoerge committed Dec 22, 2022
1 parent d5ef5ca commit 3b6915b
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion packages/@sanity/base/src/preview/availability.ts
@@ -1,6 +1,6 @@
/* eslint-disable max-nested-callbacks */
import {combineLatest, defer, from, Observable, of} from 'rxjs'
import {distinctUntilChanged, map, mergeMap, switchMap} from 'rxjs/operators'
import {distinctUntilChanged, map, mergeMap, reduce, switchMap} from 'rxjs/operators'
import shallowEquals from 'shallow-equals'
import {flatten, keyBy} from 'lodash'
import {getDraftId, getPublishedId} from '../util/draftUtils'
Expand Down Expand Up @@ -99,12 +99,23 @@ function chunkDocumentIds(documentIds: string[]): string[][] {
return chunks
}

/**
* Mutative concat
* @param array
* @param chunks
*/
function mutConcat<T>(array: T[], chunks: T[]) {
array.push(...chunks)
return array
}

const fetchDocumentReadability = debounceCollect(function fetchDocumentReadability(
args: string[][]
): Observable<DocumentAvailability[]> {
const uniqueIds = [...new Set(flatten(args))]
return from(chunkDocumentIds(uniqueIds)).pipe(
mergeMap(fetchDocumentReadabilityChunked, 10),
reduce(mutConcat, []),
map((res) => args.map(([id]) => res[uniqueIds.indexOf(id)]))
)
},
Expand Down

0 comments on commit 3b6915b

Please sign in to comment.