1
- import { type SanityClient } from '@sanity/client'
2
1
import { difference , flatten , memoize } from 'lodash'
3
2
import {
4
3
combineLatest ,
@@ -46,14 +45,29 @@ type Cache = {
46
45
[ id : string ] : CachedFieldObserver [ ]
47
46
}
48
47
48
+ /**
49
+ * Note: this should be the minimal interface createObserveFields needs to function
50
+ * It should be kept compatible with the Sanity Client
51
+ */
52
+ export interface ClientLike {
53
+ withConfig ( config : ApiConfig ) : ClientLike
54
+ observable : {
55
+ fetch : (
56
+ query : string ,
57
+ params : Record < string , string > ,
58
+ options : { tag : string } ,
59
+ ) => Observable < unknown >
60
+ }
61
+ }
62
+
49
63
/**
50
64
* Creates a function that allows observing individual fields on a document.
51
65
* It will automatically debounce and batch requests, and maintain an in-memory cache of the latest field values
52
66
* @param options - Options to use when creating the observer
53
67
* @internal
54
68
*/
55
69
export function createObserveFields ( options : {
56
- client : SanityClient
70
+ client : ClientLike
57
71
invalidationChannel : Observable < InvalidationChannelEvent >
58
72
} ) {
59
73
const { client : currentDatasetClient , invalidationChannel} = options
@@ -63,11 +77,11 @@ export function createObserveFields(options: {
63
77
)
64
78
}
65
79
66
- function fetchAllDocumentPathsWith ( client : SanityClient ) {
80
+ function fetchAllDocumentPathsWith ( client : ClientLike ) {
67
81
return function fetchAllDocumentPath ( selections : Selection [ ] ) {
68
82
const combinedSelections = combineSelections ( selections )
69
83
return client . observable
70
- . fetch ( toQuery ( combinedSelections ) , { } , { tag : 'preview.document-paths' } as any )
84
+ . fetch ( toQuery ( combinedSelections ) , { } , { tag : 'preview.document-paths' } )
71
85
. pipe ( map ( ( result : any ) => reassemble ( result , combinedSelections ) ) )
72
86
}
73
87
}
@@ -140,9 +154,10 @@ export function createObserveFields(options: {
140
154
fields : FieldName [ ] ,
141
155
apiConfig ?: ApiConfig ,
142
156
) : CachedFieldObserver {
143
- let latest : T | null = null
157
+ // Note: `undefined` means the memo has not been set, while `null` means the memo is explicitly set to null (e.g. we did fetch, but got null back)
158
+ let latest : T | undefined | null = undefined
144
159
const changes$ = merge (
145
- defer ( ( ) => ( latest === null ? EMPTY : observableOf ( latest ) ) ) ,
160
+ defer ( ( ) => ( latest === undefined ? EMPTY : observableOf ( latest ) ) ) ,
146
161
( apiConfig
147
162
? ( crossDatasetListenFields ( id , fields , apiConfig ) as any )
148
163
: currentDatasetListenFields ( id , fields ) ) as Observable < T > ,
0 commit comments