UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

68 lines (57 loc) 1.86 kB
import {type SanityClient} from '@sanity/client' import {useMemoObservable} from 'react-rx' import {type Observable, of} from 'rxjs' import {catchError, map, shareReplay, startWith} from 'rxjs/operators' import {useSource} from '../studio' import {DEFAULT_STUDIO_CLIENT_OPTIONS} from '../studioClient' import {useClient} from './useClient' const EMPTY_ARRAY: [] = [] interface Features { enabled: boolean error: Error | null features: string[] isLoading: boolean } const INITIAL_LOADING_STATE: Features = { enabled: true, error: null, features: EMPTY_ARRAY, isLoading: true, } /** * fetches all the enabled features for this project */ function fetchFeatures({versionedClient}: {versionedClient: SanityClient}): Observable<string[]> { return versionedClient.observable.request<string[]>({ uri: `/features`, tag: 'features', }) } const cachedFeatureRequest = new Map<string, Observable<string[]>>() /** @internal */ export function useFeatureEnabled(featureKey: string): Features { const versionedClient = useClient(DEFAULT_STUDIO_CLIENT_OPTIONS) const {projectId} = useSource() if (!cachedFeatureRequest.get(projectId)) { const features = fetchFeatures({versionedClient}).pipe(shareReplay()) cachedFeatureRequest.set(projectId, features) } const featureInfo = useMemoObservable( () => (cachedFeatureRequest.get(projectId) || of(EMPTY_ARRAY)).pipe( map((features = []) => ({ isLoading: false, enabled: Boolean(features?.includes(featureKey)), features, error: null, })), startWith(INITIAL_LOADING_STATE), catchError((error: Error) => { return of({isLoading: false, enabled: false, features: EMPTY_ARRAY, error}) }), ), [featureKey, projectId], INITIAL_LOADING_STATE, ) return featureInfo }