@@ -5,15 +5,17 @@ import {
5
5
type PrepareViewOptions ,
6
6
} from '@sanity/types'
7
7
import { isPlainObject } from 'lodash'
8
- import { type Observable , of as observableOf } from 'rxjs'
8
+ import { type Observable , of } from 'rxjs'
9
9
import { map , switchMap } from 'rxjs/operators'
10
10
11
+ import { type ObserveForPreviewFn } from './documentPreviewStore'
11
12
import {
12
13
type ApiConfig ,
14
+ type ObserveDocumentTypeFromIdFn ,
15
+ type ObservePathsFn ,
13
16
type PreparedSnapshot ,
14
17
type Previewable ,
15
18
type PreviewableType ,
16
- type PreviewPath ,
17
19
} from './types'
18
20
import { getPreviewPaths } from './utils/getPreviewPaths'
19
21
import { invokePrepare , prepareForPreview } from './utils/prepareForPreview'
@@ -26,29 +28,30 @@ function isReference(value: unknown): value is {_ref: string} {
26
28
return isPlainObject ( value )
27
29
}
28
30
29
- // Takes a value and its type and prepares a snapshot for it that can be passed to a preview component
31
+ /**
32
+ * Takes a value and its type and prepares a snapshot for it that can be passed to a preview component
33
+ * @internal
34
+ */
30
35
export function createPreviewObserver ( context : {
31
- observeDocumentTypeFromId : ( id : string , apiConfig ?: ApiConfig ) => Observable < string | undefined >
32
- observePaths : ( value : Previewable , paths : PreviewPath [ ] , apiConfig ?: ApiConfig ) => any
33
- } ) : (
34
- value : Previewable ,
35
- type : PreviewableType ,
36
- viewOptions ?: PrepareViewOptions ,
37
- apiConfig ?: ApiConfig ,
38
- ) => Observable < PreparedSnapshot > {
36
+ observeDocumentTypeFromId : ObserveDocumentTypeFromIdFn
37
+ observePaths : ObservePathsFn
38
+ } ) : ObserveForPreviewFn {
39
39
const { observeDocumentTypeFromId, observePaths} = context
40
40
41
41
return function observeForPreview (
42
42
value : Previewable ,
43
43
type : PreviewableType ,
44
- viewOptions ?: PrepareViewOptions ,
45
- apiConfig ?: ApiConfig ,
44
+ options : {
45
+ viewOptions ?: PrepareViewOptions
46
+ apiConfig ?: ApiConfig
47
+ } = { } ,
46
48
) : Observable < PreparedSnapshot > {
49
+ const { viewOptions = { } , apiConfig} = options
47
50
if ( isCrossDatasetReferenceSchemaType ( type ) ) {
48
51
// if the value is of type crossDatasetReference, but has no _ref property, we cannot prepare any value for the preview
49
52
// and the most appropriate thing to do is to return `undefined` for snapshot
50
53
if ( ! isCrossDatasetReference ( value ) ) {
51
- return observableOf ( { snapshot : undefined } )
54
+ return of ( { snapshot : undefined } )
52
55
}
53
56
54
57
const refApiConfig = { projectId : value . _projectId , dataset : value . _dataset }
@@ -57,32 +60,36 @@ export function createPreviewObserver(context: {
57
60
switchMap ( ( typeName ) => {
58
61
if ( typeName ) {
59
62
const refType = type . to . find ( ( toType ) => toType . type === typeName )
60
- return observeForPreview ( value , refType as any , { } , refApiConfig )
63
+ if ( refType ) {
64
+ return observeForPreview ( value , refType , { apiConfig : refApiConfig , viewOptions} )
65
+ }
61
66
}
62
- return observableOf ( { snapshot : undefined } )
67
+ return of ( { snapshot : undefined } )
63
68
} ) ,
64
69
)
65
70
}
66
71
if ( isReferenceSchemaType ( type ) ) {
67
72
// if the value is of type reference, but has no _ref property, we cannot prepare any value for the preview
68
73
// and the most appropriate thing to do is to return `undefined` for snapshot
69
74
if ( ! isReference ( value ) ) {
70
- return observableOf ( { snapshot : undefined } )
75
+ return of ( { snapshot : undefined } )
71
76
}
72
77
// Previewing references actually means getting the referenced value,
73
78
// and preview using the preview config of its type
74
- // todo: We need a way of knowing the type of the referenced value by looking at the reference record alone
79
+ // We do this since there's no way of knowing the type of the referenced value by looking at the reference value alone
75
80
return observeDocumentTypeFromId ( value . _ref ) . pipe (
76
81
switchMap ( ( typeName ) => {
77
82
if ( typeName ) {
78
83
const refType = type . to . find ( ( toType ) => toType . name === typeName )
79
- return observeForPreview ( value , refType as any )
84
+ if ( refType ) {
85
+ return observeForPreview ( value , refType )
86
+ }
80
87
}
81
88
// todo: in case we can't read the document type, we can figure out the reason why e.g. whether it's because
82
89
// the document doesn't exist or it's not readable due to lack of permission.
83
90
// We can use the "observeDocumentAvailability" function
84
91
// for this, but currently not sure if needed
85
- return observableOf ( { snapshot : undefined } )
92
+ return of ( { snapshot : undefined } )
86
93
} ) ,
87
94
)
88
95
}
@@ -91,7 +98,7 @@ export function createPreviewObserver(context: {
91
98
return observePaths ( value , paths , apiConfig ) . pipe (
92
99
map ( ( snapshot ) => ( {
93
100
type : type ,
94
- snapshot : snapshot && prepareForPreview ( snapshot , type as any , viewOptions ) ,
101
+ snapshot : snapshot ? prepareForPreview ( snapshot , type , viewOptions ) : null ,
95
102
} ) ) ,
96
103
)
97
104
}
@@ -100,7 +107,7 @@ export function createPreviewObserver(context: {
100
107
// the SchemaType doesn't have a `select` field. The schema compiler
101
108
// provides a default `preview` implementation for `object`s, `image`s,
102
109
// `file`s, and `document`s
103
- return observableOf ( {
110
+ return of ( {
104
111
type,
105
112
snapshot :
106
113
value && isRecord ( value ) ? invokePrepare ( type , value , viewOptions ) . returnValue : null ,
0 commit comments