@sanity/client
Version:
Client for retrieving, creating and patching data from Sanity.io
75 lines (68 loc) • 2.27 kB
text/typescript
import {
finalize,
merge,
type MonoTypeOperatorFunction,
Observable,
share,
type ShareConfig,
tap,
} from 'rxjs'
export type ShareReplayLatestConfig<T> = ShareConfig<T> & {predicate: (value: T) => boolean}
/**
* A variant of share that takes a predicate function to determine which value to replay to new subscribers
* @param predicate - Predicate function to determine which value to replay
*/
export function shareReplayLatest<T>(predicate: (value: T) => boolean): MonoTypeOperatorFunction<T>
/**
* A variant of share that takes a predicate function to determine which value to replay to new subscribers
* @param config - ShareConfig with additional predicate function
*/
export function shareReplayLatest<T>(
config: ShareReplayLatestConfig<T>,
): MonoTypeOperatorFunction<T>
/**
* A variant of share that takes a predicate function to determine which value to replay to new subscribers
* @param configOrPredicate - Predicate function to determine which value to replay
* @param config - Optional ShareConfig
*/
export function shareReplayLatest<T>(
configOrPredicate: ShareReplayLatestConfig<T> | ShareReplayLatestConfig<T>['predicate'],
config?: ShareConfig<T>,
) {
return _shareReplayLatest(
typeof configOrPredicate === 'function'
? {predicate: configOrPredicate, ...config}
: configOrPredicate,
)
}
function _shareReplayLatest<T>(config: ShareReplayLatestConfig<T>): MonoTypeOperatorFunction<T> {
return (source: Observable<T>) => {
let latest: T | undefined
let emitted = false
// eslint-disable-next-line unused-imports/no-unused-vars
const {predicate, ...shareConfig} = config
const wrapped = source.pipe(
tap((value) => {
if (config.predicate(value)) {
emitted = true
latest = value
}
}),
finalize(() => {
emitted = false
latest = undefined
}),
share(shareConfig),
)
const emitLatest = new Observable<T>((subscriber) => {
if (emitted) {
subscriber.next(
// this cast is safe because of the emitted check which asserts that we got T from the source
latest as T,
)
}
subscriber.complete()
})
return merge(wrapped, emitLatest)
}
}