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

41 lines (35 loc) 1.58 kB
import {type SanityDocument} from '@sanity/types' import {useEffect, useState} from 'react' import {useAsObservable} from 'react-rx' import {from, of} from 'rxjs' import {catchError, debounceTime, switchMap} from 'rxjs/operators' import {isRecord, useSource} from 'sanity' const isSanityDocument = (value: unknown): value is SanityDocument => isRecord(value) && typeof value._id === 'string' && typeof value._type === 'string' export function usePreviewUrl(value: Partial<SanityDocument> | undefined): string | undefined { const [previewUrl, setPreviewUrl] = useState<string | undefined>(undefined) const [error, setError] = useState<unknown>(null) const {resolveProductionUrl} = useSource().document // @todo refactor out of useAsObservable, and instead use `of() + useMemoObservable` like we did for `useLoadableFromCreateLoadable` const value$ = useAsObservable(value) if (error) throw error useEffect(() => { value$ .pipe( // this so that the preview URL isn't fetched on every keystroke debounceTime(500), switchMap((document) => isSanityDocument(document) ? from(resolveProductionUrl({document})) : of(undefined), ), catchError((e) => { const message = isRecord(e) && typeof e.message === 'string' ? e.message : 'Unknown error' throw new Error(`An error was thrown while trying to get your preview url: ${message}`) }), ) .subscribe({ next: setPreviewUrl, error: setError, }) }, [resolveProductionUrl, value$]) return previewUrl }