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

88 lines (80 loc) 3.12 kB
import {type SanityClient} from '@sanity/client' import {type MendozaPatch, type TransactionLogEventWithEffects} from '@sanity/types' import {BehaviorSubject, filter, map, type Observable} from 'rxjs' import {getDraftId, getPublishedId, isVersionId} from '../../util/draftUtils' import {getDocumentVariantType} from '../../util/getDocumentVariantType' import {type DocumentRemoteMutationEvent} from '../_legacy/document/buffered-doc/types' import {remoteSnapshots, type WithVersion} from '../_legacy/document/document-pair' import {getEditEvents, getEffectState} from './getEditEvents' import {remoteMutationToTransaction} from './utils' interface GetRemoteTransactionsSubscriptionOptions { client: SanityClient documentId: string documentType: string isLiveEdit: boolean serverActionsEnabled: Observable<boolean> onRefetch: () => void } export function getRemoteTransactionsSubscription({ client, isLiveEdit, documentId, documentType, serverActionsEnabled, onRefetch, }: GetRemoteTransactionsSubscriptionOptions) { const remoteTransactions$ = new BehaviorSubject<TransactionLogEventWithEffects[]>([]) const remoteEdits$ = remoteTransactions$.pipe( map((transactions) => getEditEvents(transactions, documentId, isLiveEdit)), ) const documentVariantType = getDocumentVariantType(documentId) const onMutationReceived = (remoteMutation: WithVersion<DocumentRemoteMutationEvent> | null) => { if (!remoteMutation) return // If the remote mutation happened to a published document we need to re-fetch the events. // If it happens to a version, we need to add the mutation to the list of events. // If it happens to a draft: we need to decide if it looks like an event // Looks like an event: we need to refetch the events list (e.g. publish, discard) // Doesn't look like an event: we need to add the mutation to the list of events. const variant = remoteMutation.version if (variant !== documentVariantType) { // The mutation is not for the current document variant, we don't need to do anything. return } if (variant === 'published' && !isLiveEdit) { onRefetch() return } const effectState = getEffectState({ apply: remoteMutation.effects.apply as MendozaPatch, revert: remoteMutation.effects.revert as MendozaPatch, }) if (effectState === 'created' || effectState === 'deleted') { onRefetch() remoteTransactions$.next([]) return } remoteTransactions$.next([ ...remoteTransactions$.value, remoteMutationToTransaction(remoteMutation), ]) } const subscription = remoteSnapshots( client, { draftId: getDraftId(documentId), publishedId: getPublishedId(documentId), ...(isVersionId(documentId) ? { versionId: documentId, } : {}), }, documentType, serverActionsEnabled, ).pipe(filter((event) => event.type === 'remoteMutation')) return { remoteTransactions$, remoteEdits$, subscribe: () => subscription.subscribe(onMutationReceived), } }