UNPKG

@sanity/visual-editing

Version:

[![npm stat](https://img.shields.io/npm/dm/@sanity/visual-editing.svg?style=flat-square)](https://npm-stat.com/charts.html?package=@sanity/visual-editing) [![npm version](https://img.shields.io/npm/v/@sanity/visual-editing.svg?style=flat-square)](https://

73 lines (67 loc) 2.28 kB
import type {ClientPerspective, ContentSourceMapDocuments} from '@sanity/client' import {useCallback, useEffect, useRef} from 'react' import type {ElementState, SanityNode, VisualEditingNode} from '../types' function isEqualSets(a: Set<string>, b: Set<string>) { if (a === b) return true if (a.size !== b.size) return false for (const value of a) if (!b.has(value)) return false return true } /** * Hook for reporting in use documents to Presentation * @internal */ export function useReportDocuments( comlink: VisualEditingNode | undefined, elements: ElementState[], perspective: ClientPerspective, ): void { const lastReported = useRef< | { nodeIds: Set<string> perspective: ClientPerspective } | undefined >(undefined) const reportDocuments = useCallback( (documents: ContentSourceMapDocuments, perspective: ClientPerspective) => { comlink?.post('visual-editing/documents', { documents, perspective, }) }, [comlink], ) useEffect(() => { // Report only nodes of type `SanityNode`. Untransformed `SanityStegaNode` // nodes without an `id`, are not reported as they will not contain the // necessary document data. const nodes = elements .map((e) => { const {sanity} = e if (!sanity || !('id' in sanity)) return null return sanity }) .filter((s) => !!s) as SanityNode[] const nodeIds = new Set<string>(nodes.map((e) => e.id)) // Report if: // - Documents not yet reported // - Document IDs changed // - Perspective changed if ( !lastReported.current || !isEqualSets(nodeIds, lastReported.current.nodeIds) || perspective !== lastReported.current.perspective ) { const documentsOnPage: ContentSourceMapDocuments = Array.from(nodeIds).map((_id) => { const node = nodes.find((node) => node.id === _id)! const {type, projectId: _projectId, dataset: _dataset} = node return _projectId && _dataset ? {_id, _type: type!, _projectId, _dataset} : {_id, _type: type!} }) lastReported.current = {nodeIds, perspective} reportDocuments(documentsOnPage, perspective) } }, [elements, perspective, reportDocuments]) }