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

85 lines (75 loc) 2.89 kB
import {type SanityClient} from '@sanity/client' import {type SanityDocument} from '@sanity/types' import {combineLatest, type Observable, of} from 'rxjs' import {map, switchMap} from 'rxjs/operators' import {getIdPair, isRecord} from '../util' import {create_preview_availability} from './availability' import {type DraftsModelDocument, type ObservePathsFn, type PreviewPath} from './types' export function create_preview_documentPair( versionedClient: SanityClient, observePaths: ObservePathsFn, ): { observePathsDocumentPair: <T extends SanityDocument = SanityDocument>( id: string, paths: PreviewPath[], ) => Observable<DraftsModelDocument<T>> } { const {observeDocumentPairAvailability} = create_preview_availability( versionedClient, observePaths, ) const ALWAYS_INCLUDED_SNAPSHOT_PATHS: PreviewPath[] = [['_updatedAt'], ['_createdAt'], ['_type']] return {observePathsDocumentPair} function observePathsDocumentPair<T extends SanityDocument = SanityDocument>( id: string, paths: PreviewPath[], ): Observable<DraftsModelDocument<T>> { const {draftId, publishedId} = getIdPair(id) return observeDocumentPairAvailability(draftId).pipe( switchMap((availability) => { if (!availability.draft.available && !availability.published.available) { // short circuit, neither draft nor published is available so no point in trying to get a snapshot return of({ id: publishedId, type: null, draft: { availability: availability.draft, snapshot: undefined, }, published: { availability: availability.published, snapshot: undefined, }, }) } const snapshotPaths = [...paths, ...ALWAYS_INCLUDED_SNAPSHOT_PATHS] return combineLatest([ observePaths({_type: 'reference', _ref: draftId}, snapshotPaths), observePaths({_type: 'reference', _ref: publishedId}, snapshotPaths), ]).pipe( map(([draftSnapshot, publishedSnapshot]) => { // note: assume type is always the same const type = (isRecord(draftSnapshot) && '_type' in draftSnapshot && draftSnapshot._type) || (isRecord(publishedSnapshot) && '_type' in publishedSnapshot && publishedSnapshot._type) || null return { id: publishedId, type: typeof type === 'string' ? type : null, draft: { availability: availability.draft, snapshot: draftSnapshot as T, }, published: { availability: availability.published, snapshot: publishedSnapshot as T, }, } }), ) }), ) } }