Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/core/src/preview/getPreviewState.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {NEVER} from 'rxjs'
import {describe, it} from 'vitest'

import {sourceFor} from '../config/sanityConfig'
import {createSanityInstance, type SanityInstance} from '../store/createSanityInstance'
import {type StoreState} from '../store/createStoreState'
import {insecureRandomId} from '../utils/ids'
Expand All @@ -18,7 +19,11 @@ vi.mock('./subscribeToStateAndFetchBatches.ts')

describe('getPreviewState', () => {
let instance: SanityInstance
const docHandle = {documentId: 'exampleId', documentType: 'exampleType'}
const docHandle = {
documentId: 'exampleId',
documentType: 'exampleType',
source: sourceFor({projectId: 'test', dataset: 'test'}),
}
let state: StoreState<PreviewStoreState & {extra?: unknown}>

beforeEach(() => {
Expand Down
8 changes: 6 additions & 2 deletions packages/core/src/preview/getPreviewState.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {omit} from 'lodash-es'

import {type DocumentHandle} from '../config/sanityConfig'
import {type DocumentSource} from '../config/sanityConfig'
import {bindActionByDataset} from '../store/createActionBinder'
import {type SanityInstance} from '../store/createSanityInstance'
import {
Expand All @@ -20,7 +20,11 @@ import {STABLE_EMPTY_PREVIEW} from './util'
/**
* @beta
*/
export type GetPreviewStateOptions = DocumentHandle
export type GetPreviewStateOptions = {
documentId: string
documentType: string
source: DocumentSource
}

/**
* @beta
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/preview/resolvePreview.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {of} from 'rxjs'
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'

import {createDocumentHandle} from '../config/handles'
import {sourceFor} from '../config/sanityConfig'
import {createSanityInstance, type SanityInstance} from '../store/createSanityInstance'
import {type StateSource} from '../store/createStateSourceAction'
import {getPreviewState} from './getPreviewState'
Expand Down Expand Up @@ -31,10 +31,11 @@ describe('resolvePreview', () => {
})

it('resolves a preview and returns the first emitted value with results', async () => {
const docHandle = createDocumentHandle({
const docHandle = {
documentId: 'doc123',
documentType: 'movie',
})
source: sourceFor({projectId: 'p', dataset: 'd'}),
}

const result = await resolvePreview(instance, docHandle)

Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/preview/resolvePreview.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import {filter, firstValueFrom} from 'rxjs'

import {type DocumentHandle} from '../config/sanityConfig'
import {bindActionByDataset} from '../store/createActionBinder'
import {getPreviewState} from './getPreviewState'
import {getPreviewState, type GetPreviewStateOptions} from './getPreviewState'
import {previewStore} from './previewStore'

/**
* @beta
*/
export type ResolvePreviewOptions = DocumentHandle
export type ResolvePreviewOptions = GetPreviewStateOptions

/**
* @beta
Expand Down
28 changes: 20 additions & 8 deletions packages/react/src/hooks/preview/useDocumentPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import {type DocumentHandle, getPreviewState, type PreviewValue, resolvePreview} from '@sanity/sdk'
import {useCallback, useSyncExternalStore} from 'react'
import {
getPreviewState,
type GetPreviewStateOptions,
type PreviewValue,
resolvePreview,
} from '@sanity/sdk'
import {useCallback, useMemo, useSyncExternalStore} from 'react'
import {distinctUntilChanged, EMPTY, Observable, startWith, switchMap} from 'rxjs'

import {useSanityInstance} from '../context/useSanityInstance'
import {type SourceOptions} from '../../type'
import {useSanityInstanceAndSource} from '../context/useSanityInstance'

/**
* @public
* @category Types
*/
export interface useDocumentPreviewOptions extends DocumentHandle {
export interface useDocumentPreviewOptions
extends Omit<GetPreviewStateOptions, 'source'>,
SourceOptions {
/**
* Optional ref object to track visibility. When provided, preview resolution
* only occurs when the referenced element is visible in the viewport.
Expand Down Expand Up @@ -81,10 +89,14 @@ export interface useDocumentPreviewResults {
*/
export function useDocumentPreview({
ref,
projectId,
dataset,
source,
...docHandle
}: useDocumentPreviewOptions): useDocumentPreviewResults {
const instance = useSanityInstance(docHandle)
const stateSource = getPreviewState(instance, docHandle)
const [instance, actualSource] = useSanityInstanceAndSource({projectId, dataset, source})
const options = useMemo(() => ({...docHandle, source: actualSource}), [docHandle, actualSource])
const stateSource = getPreviewState(instance, options)

// Create subscribe function for useSyncExternalStore
const subscribe = useCallback(
Expand Down Expand Up @@ -131,9 +143,9 @@ export function useDocumentPreview({
// Create getSnapshot function to return current state
const getSnapshot = useCallback(() => {
const currentState = stateSource.getCurrent()
if (currentState.data === null) throw resolvePreview(instance, docHandle)
if (currentState.data === null) throw resolvePreview(instance, options)
return currentState as useDocumentPreviewResults
}, [docHandle, instance, stateSource])
}, [instance, options, stateSource])

return useSyncExternalStore(subscribe, getSnapshot)
}
Loading