@sanity/sdk 2.9.0 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/_chunks-dts/utils.d.ts +105 -51
  2. package/dist/_chunks-es/createGroqSearchFilter.js +131 -54
  3. package/dist/_chunks-es/createGroqSearchFilter.js.map +1 -1
  4. package/dist/_chunks-es/version.js +1 -1
  5. package/dist/_exports/_internal.d.ts +1 -1
  6. package/dist/index.d.ts +2 -2
  7. package/dist/index.js +119 -73
  8. package/dist/index.js.map +1 -1
  9. package/package.json +8 -10
  10. package/src/_exports/index.ts +8 -0
  11. package/src/client/clientStore.test.ts +30 -30
  12. package/src/client/clientStore.ts +47 -47
  13. package/src/comlink/controller/actions/getOrCreateChannel.ts +2 -2
  14. package/src/comlink/node/actions/getOrCreateNode.ts +2 -2
  15. package/src/config/sanityConfig.ts +72 -12
  16. package/src/document/applyDocumentActions.test.ts +7 -7
  17. package/src/document/applyDocumentActions.ts +5 -5
  18. package/src/document/documentStore.test.ts +68 -62
  19. package/src/document/documentStore.ts +36 -36
  20. package/src/document/processActions.ts +2 -2
  21. package/src/document/reducers.ts +4 -4
  22. package/src/document/sharedListener.ts +7 -7
  23. package/src/presence/bifurTransport.test.ts +46 -6
  24. package/src/presence/bifurTransport.ts +13 -1
  25. package/src/presence/presenceStore.test.ts +96 -0
  26. package/src/presence/presenceStore.ts +96 -24
  27. package/src/preview/getPreviewState.ts +1 -1
  28. package/src/preview/previewProjectionUtils.test.ts +4 -4
  29. package/src/preview/previewProjectionUtils.ts +7 -7
  30. package/src/preview/resolvePreview.ts +5 -1
  31. package/src/projection/getProjectionState.ts +4 -4
  32. package/src/projection/projectionStore.test.ts +2 -2
  33. package/src/projection/resolveProjection.ts +2 -2
  34. package/src/projection/subscribeToStateAndFetchBatches.test.ts +1 -1
  35. package/src/projection/subscribeToStateAndFetchBatches.ts +12 -11
  36. package/src/query/queryStore.test.ts +12 -12
  37. package/src/query/queryStore.ts +10 -10
  38. package/src/query/reducers.ts +3 -3
  39. package/src/releases/getPerspectiveState.ts +5 -5
  40. package/src/releases/releasesStore.test.ts +6 -6
  41. package/src/releases/releasesStore.ts +9 -9
  42. package/src/store/createActionBinder.test.ts +31 -31
  43. package/src/store/createActionBinder.ts +43 -38
  44. package/src/store/createSanityInstance.ts +2 -3
  45. package/src/users/reducers.ts +3 -4
  46. package/src/utils/createFetcherStore.ts +6 -4
  47. package/src/utils/isImportError.test.ts +72 -0
  48. package/src/utils/isImportError.ts +34 -0
  49. package/src/utils/object.test.ts +95 -0
  50. package/src/utils/object.ts +142 -0
@@ -1,7 +1,7 @@
1
1
  import {type SanityProjectionResult} from 'groq'
2
2
  import {filter, firstValueFrom} from 'rxjs'
3
3
 
4
- import {bindActionBySourceAndPerspective} from '../store/createActionBinder'
4
+ import {bindActionByResourceAndPerspective} from '../store/createActionBinder'
5
5
  import {type SanityInstance} from '../store/createSanityInstance'
6
6
  import {getProjectionState, type ProjectionOptions} from './getProjectionState'
7
7
  import {projectionStore} from './projectionStore'
@@ -38,7 +38,7 @@ export function resolveProjection(
38
38
  /**
39
39
  * @beta
40
40
  */
41
- const _resolveProjection = bindActionBySourceAndPerspective(
41
+ const _resolveProjection = bindActionByResourceAndPerspective(
42
42
  projectionStore,
43
43
  (
44
44
  {instance}: {instance: SanityInstance},
@@ -17,7 +17,7 @@ describe('subscribeToStateAndFetchBatches', () => {
17
17
  let state: StoreState<ProjectionStoreState>
18
18
  const key = {
19
19
  name: 'test.test:drafts',
20
- source: {projectId: 'test', dataset: 'test'},
20
+ resource: {projectId: 'test', dataset: 'test'},
21
21
  perspective: 'drafts' as const,
22
22
  }
23
23
 
@@ -1,4 +1,4 @@
1
- import {isEqual} from 'lodash-es'
1
+ import {DocumentId} from '@sanity/id-utils'
2
2
  import {
3
3
  combineLatest,
4
4
  debounceTime,
@@ -16,10 +16,11 @@ import {
16
16
  tap,
17
17
  } from 'rxjs'
18
18
 
19
- import {isDatasetSource} from '../config/sanityConfig'
19
+ import {isDatasetResource} from '../config/sanityConfig'
20
20
  import {getQueryState, resolveQuery} from '../query/queryStore'
21
21
  import {type BoundPerspectiveKey} from '../store/createActionBinder'
22
22
  import {type StoreContext} from '../store/defineStore'
23
+ import {isDeepEqual} from '../utils/object'
23
24
  import {
24
25
  createProjectionQuery,
25
26
  processProjectionQuery,
@@ -42,22 +43,22 @@ interface StatusQueryResult {
42
43
  export const subscribeToStateAndFetchBatches = ({
43
44
  state,
44
45
  instance,
45
- key: {source, perspective},
46
+ key: {resource, perspective},
46
47
  }: StoreContext<ProjectionStoreState, BoundPerspectiveKey>): Subscription => {
47
48
  const documentProjections$ = state.observable.pipe(
48
49
  map((s) => s.documentProjections),
49
- distinctUntilChanged(isEqual),
50
+ distinctUntilChanged(isDeepEqual),
50
51
  )
51
52
 
52
53
  const activeDocumentIds$ = state.observable.pipe(
53
- map(({subscriptions}) => new Set(Object.keys(subscriptions))),
54
+ map(({subscriptions}) => new Set(Object.keys(subscriptions).map((id) => DocumentId(id)))),
54
55
  distinctUntilChanged(isSetEqual),
55
56
  )
56
57
 
57
58
  const pendingUpdateSubscription = activeDocumentIds$
58
59
  .pipe(
59
60
  debounceTime(BATCH_DEBOUNCE_TIME),
60
- startWith(new Set<string>()),
61
+ startWith(new Set<DocumentId>()),
61
62
  pairwise(),
62
63
  tap(([prevIds, currIds]) => {
63
64
  const newIds = [...currIds].filter((id) => !prevIds.has(id))
@@ -89,7 +90,7 @@ export const subscribeToStateAndFetchBatches = ({
89
90
 
90
91
  const queryTrigger$ = combineLatest([activeDocumentIds$, documentProjections$]).pipe(
91
92
  debounceTime(BATCH_DEBOUNCE_TIME),
92
- distinctUntilChanged(isEqual),
93
+ distinctUntilChanged(isDeepEqual),
93
94
  )
94
95
 
95
96
  const queryExecutionSubscription = queryTrigger$
@@ -113,7 +114,7 @@ export const subscribeToStateAndFetchBatches = ({
113
114
  perspective,
114
115
  },
115
116
  // temporary guard here until we're ready for everything to be queried via global API
116
- ...(source && !isDatasetSource(source) ? {source} : {}),
117
+ ...(resource && !isDatasetResource(resource) ? {resource} : {}),
117
118
  })
118
119
 
119
120
  const querySource$ = defer(() => {
@@ -128,7 +129,7 @@ export const subscribeToStateAndFetchBatches = ({
128
129
  perspective,
129
130
  },
130
131
  // temporary guard here until we're ready for everything to be queried via global API in v3
131
- ...(source && !isDatasetSource(source) ? {source} : {}),
132
+ ...(resource && !isDatasetResource(resource) ? {resource} : {}),
132
133
  }),
133
134
  ).pipe(switchMap(() => observable))
134
135
  }
@@ -154,7 +155,7 @@ export const subscribeToStateAndFetchBatches = ({
154
155
  perspective: 'raw',
155
156
  },
156
157
  // temporary guard here until we're ready for everything to be queried via global API
157
- ...(source && !isDatasetSource(source) ? {source} : {}),
158
+ ...(resource && !isDatasetResource(resource) ? {resource} : {}),
158
159
  })
159
160
 
160
161
  const statusQuerySource$ = defer(() => {
@@ -169,7 +170,7 @@ export const subscribeToStateAndFetchBatches = ({
169
170
  perspective: 'raw',
170
171
  },
171
172
  // temporary guard here until we're ready for everything to be queried via global API
172
- ...(source && !isDatasetSource(source) ? {source} : {}),
173
+ ...(resource && !isDatasetResource(resource) ? {resource} : {}),
173
174
  }),
174
175
  ).pipe(switchMap(() => observable))
175
176
  }
@@ -3,7 +3,7 @@ import {delay, filter, firstValueFrom, Observable, of, Subject} from 'rxjs'
3
3
  import {beforeEach, describe, expect, it, vi} from 'vitest'
4
4
 
5
5
  import {getClientState} from '../client/clientStore'
6
- import {isCanvasSource} from '../config/sanityConfig'
6
+ import {isCanvasResource} from '../config/sanityConfig'
7
7
  import {createSanityInstance, type SanityInstance} from '../store/createSanityInstance'
8
8
  import {type StateSource} from '../store/createStateSourceAction'
9
9
  import {getQueryState, resolveQuery} from './queryStore'
@@ -448,21 +448,21 @@ describe('queryStore', () => {
448
448
  base.dispose()
449
449
  })
450
450
 
451
- it('uses source from params when passed in query options (listenForNewSubscribersAndFetch)', async () => {
451
+ it('uses resource from params when passed in query options (listenForNewSubscribersAndFetch)', async () => {
452
452
  const query = '*[_type == "movie"]'
453
453
  const mediaLibrarySource = {mediaLibraryId: 'ml123'}
454
454
 
455
- const state = getQueryState(instance, {query, source: mediaLibrarySource})
455
+ const state = getQueryState(instance, {query, resource: mediaLibrarySource})
456
456
  const unsubscribe = state.subscribe()
457
457
 
458
458
  await firstValueFrom(state.observable.pipe(filter((i) => i !== undefined)))
459
459
 
460
- // Verify getClientState was called with the source from params in listenForNewSubscribersAndFetch
461
- // This call includes projectId, dataset, and source
460
+ // Verify getClientState was called with the resource from params in listenForNewSubscribersAndFetch
461
+ // This call includes projectId, dataset, and resource
462
462
  expect(getClientState).toHaveBeenCalledWith(
463
463
  instance,
464
464
  expect.objectContaining({
465
- source: expect.objectContaining({
465
+ resource: expect.objectContaining({
466
466
  mediaLibraryId: 'ml123',
467
467
  }),
468
468
  }),
@@ -471,22 +471,22 @@ describe('queryStore', () => {
471
471
  unsubscribe()
472
472
  })
473
473
 
474
- it('uses source from store context key when not a dataset source (listenToLiveClientAndSetLastLiveEventIds)', async () => {
474
+ it('uses resource from store context key when not a dataset resource (listenToLiveClientAndSetLastLiveEventIds)', async () => {
475
475
  const query = '*[_type == "movie"]'
476
476
  const canvasSource = {canvasId: 'canvas456'}
477
477
 
478
- const state = getQueryState(instance, {query, source: canvasSource})
478
+ const state = getQueryState(instance, {query, resource: canvasSource})
479
479
  const unsubscribe = state.subscribe()
480
480
 
481
481
  await firstValueFrom(state.observable.pipe(filter((i) => i !== undefined)))
482
482
 
483
- // Verify getClientState was called with the canvas source for live events
484
- // The source is extracted from the store key and passed when it's not a dataset source
485
- // This call only has apiVersion and source (no projectId/dataset)
483
+ // Verify getClientState was called with the canvas resource for live events
484
+ // The resource is extracted from the store key and passed when it's not a dataset resource
485
+ // This call only has apiVersion and resource (no projectId/dataset)
486
486
  const calls = vi.mocked(getClientState).mock.calls
487
487
  const liveClientCall = calls.find(
488
488
  ([_instance, options]) =>
489
- isCanvasSource(options.source!) && options.source.canvasId === 'canvas456',
489
+ isCanvasResource(options.resource!) && options.resource.canvasId === 'canvas456',
490
490
  )
491
491
  expect(liveClientCall).toBeDefined()
492
492
 
@@ -24,7 +24,7 @@ import {
24
24
  } from 'rxjs'
25
25
 
26
26
  import {getClientState} from '../client/clientStore'
27
- import {type DatasetHandle, isDatasetSource} from '../config/sanityConfig'
27
+ import {type DatasetHandle, isDatasetResource} from '../config/sanityConfig'
28
28
  /*
29
29
  * Although this is an import dependency cycle, it is not a logical cycle:
30
30
  * 1. queryStore uses getPerspectiveState when resolving release perspectives
@@ -35,7 +35,7 @@ import {type DatasetHandle, isDatasetSource} from '../config/sanityConfig'
35
35
  // eslint-disable-next-line import/no-cycle
36
36
  import {getPerspectiveState} from '../releases/getPerspectiveState'
37
37
  import {isReleasePerspective} from '../releases/utils/isReleasePerspective'
38
- import {bindActionBySource, type BoundSourceKey} from '../store/createActionBinder'
38
+ import {bindActionByResource, type BoundResourceKey} from '../store/createActionBinder'
39
39
  import {type SanityInstance} from '../store/createSanityInstance'
40
40
  import {
41
41
  createStateSourceAction,
@@ -117,7 +117,7 @@ function normalizeOptionsWithPerspective(
117
117
  }
118
118
  }
119
119
 
120
- const queryStore = defineStore<QueryStoreState, BoundSourceKey>({
120
+ const queryStore = defineStore<QueryStoreState, BoundResourceKey>({
121
121
  name: 'QueryStore',
122
122
  getInitialState: () => ({queries: {}}),
123
123
  initialize(context) {
@@ -173,7 +173,7 @@ const listenForNewSubscribersAndFetch = ({state, instance}: StoreContext<QuerySt
173
173
  projectId,
174
174
  dataset,
175
175
  tag,
176
- source,
176
+ resource,
177
177
  perspective: perspectiveFromOptions,
178
178
  ...restOptions
179
179
  } = parseQueryKey(group$.key)
@@ -190,7 +190,7 @@ const listenForNewSubscribersAndFetch = ({state, instance}: StoreContext<QuerySt
190
190
  apiVersion: QUERY_STORE_API_VERSION,
191
191
  projectId,
192
192
  dataset,
193
- source,
193
+ resource,
194
194
  }).observable
195
195
 
196
196
  return combineLatest({
@@ -226,12 +226,12 @@ const listenForNewSubscribersAndFetch = ({state, instance}: StoreContext<QuerySt
226
226
  const listenToLiveClientAndSetLastLiveEventIds = ({
227
227
  state,
228
228
  instance,
229
- key: {source},
230
- }: StoreContext<QueryStoreState, BoundSourceKey>) => {
229
+ key: {resource},
230
+ }: StoreContext<QueryStoreState, BoundResourceKey>) => {
231
231
  const liveMessages$ = getClientState(instance, {
232
232
  apiVersion: QUERY_STORE_API_VERSION,
233
233
  // temporary guard here until we're ready for everything to be queried via global api
234
- ...(source && !isDatasetSource(source) ? {source} : {}),
234
+ ...(resource && !isDatasetResource(resource) ? {resource} : {}),
235
235
  }).observable.pipe(
236
236
  switchMap((client) =>
237
237
  defer(() =>
@@ -316,7 +316,7 @@ export function getQueryState(
316
316
  ): ReturnType<typeof _getQueryState> {
317
317
  return _getQueryState(...args)
318
318
  }
319
- const _getQueryState = bindActionBySource(
319
+ const _getQueryState = bindActionByResource(
320
320
  queryStore,
321
321
  createStateSourceAction({
322
322
  selector: ({state, instance}: SelectorContext<QueryStoreState>, options: QueryOptions) => {
@@ -375,7 +375,7 @@ export function resolveQuery<TData>(
375
375
  export function resolveQuery(...args: Parameters<typeof _resolveQuery>): Promise<unknown> {
376
376
  return _resolveQuery(...args)
377
377
  }
378
- const _resolveQuery = bindActionBySource(
378
+ const _resolveQuery = bindActionByResource(
379
379
  queryStore,
380
380
  ({state, instance}, {signal, ...options}: ResolveQueryOptions) => {
381
381
  const normalized = normalizeOptionsWithPerspective(instance, options)
@@ -1,4 +1,4 @@
1
- import {omit} from 'lodash-es'
1
+ import {omitProperty} from '../utils/object'
2
2
 
3
3
  interface QueryState {
4
4
  syncTags?: string[]
@@ -54,7 +54,7 @@ export const removeSubscriber =
54
54
  const prevQuery = prev.queries[key]
55
55
  if (!prevQuery) return prev
56
56
  const subscribers = prevQuery.subscribers.filter((id) => id !== subscriptionId)
57
- if (!subscribers.length) return {...prev, queries: omit(prev.queries, key)}
57
+ if (!subscribers.length) return {...prev, queries: omitProperty(prev.queries, key)}
58
58
  return {...prev, queries: {...prev.queries, [key]: {...prevQuery, subscribers}}}
59
59
  }
60
60
 
@@ -64,7 +64,7 @@ export const cancelQuery =
64
64
  const prevQuery = prev.queries[key]
65
65
  if (!prevQuery) return prev
66
66
  if (prevQuery.subscribers.length) return prev
67
- return {...prev, queries: omit(prev.queries, key)}
67
+ return {...prev, queries: omitProperty(prev.queries, key)}
68
68
  }
69
69
 
70
70
  export const initializeQuery =
@@ -1,7 +1,7 @@
1
1
  import {createSelector} from 'reselect'
2
2
 
3
- import {type DocumentSource, type PerspectiveHandle} from '../config/sanityConfig'
4
- import {bindActionBySource, type BoundStoreAction} from '../store/createActionBinder'
3
+ import {type DocumentResource, type PerspectiveHandle} from '../config/sanityConfig'
4
+ import {bindActionByResource, type BoundStoreAction} from '../store/createActionBinder'
5
5
  import {createStateSourceAction, type SelectorContext} from '../store/createStateSourceAction'
6
6
  /*
7
7
  * Although this is an import dependency cycle, it is not a logical cycle:
@@ -26,7 +26,7 @@ const selectActiveReleases = (context: SelectorContext<ReleasesStoreState>) =>
26
26
  context.state.activeReleases
27
27
  const selectOptions = (
28
28
  _context: SelectorContext<ReleasesStoreState>,
29
- options: PerspectiveHandle & {projectId?: string; dataset?: string; source?: DocumentSource},
29
+ options: PerspectiveHandle & {projectId?: string; dataset?: string; resource?: DocumentResource},
30
30
  ) => options
31
31
 
32
32
  const memoizedOptionsSelector = createSelector(
@@ -105,11 +105,11 @@ let _boundGetPerspectiveState: BoundGetPerspectiveState | undefined
105
105
  */
106
106
  export const getPerspectiveState: BoundGetPerspectiveState = (instance, ...rest) => {
107
107
  if (!_boundGetPerspectiveState) {
108
- _boundGetPerspectiveState = bindActionBySource(
108
+ _boundGetPerspectiveState = bindActionByResource(
109
109
  releasesStore,
110
110
  _getPerspectiveStateSelector,
111
111
  ) as BoundGetPerspectiveState
112
112
  }
113
- // bindActionBySource keyFn destructures { source } from the first param, so pass {} when no options
113
+ // bindActionByResource keyFn destructures { resource } from the first param, so pass {} when no options
114
114
  return _boundGetPerspectiveState(instance, ...(rest.length ? rest : [{}]))
115
115
  }
@@ -39,7 +39,7 @@ describe('releasesStore', () => {
39
39
  expect.objectContaining({
40
40
  query: 'releases::all()',
41
41
  perspective: 'raw',
42
- source: undefined,
42
+ resource: undefined,
43
43
  tag: 'releases',
44
44
  }),
45
45
  )
@@ -73,7 +73,7 @@ describe('releasesStore', () => {
73
73
  } as ReleaseDocument,
74
74
  ]
75
75
 
76
- const state = getActiveReleasesState(instance, {source: {projectId: 'test', dataset: 'test'}})
76
+ const state = getActiveReleasesState(instance, {resource: {projectId: 'test', dataset: 'test'}})
77
77
 
78
78
  const [observer] = subscriber.mock.lastCall!
79
79
 
@@ -92,7 +92,7 @@ describe('releasesStore', () => {
92
92
  observable: releasesSubject.asObservable(),
93
93
  } as StateSource<ReleaseDocument[] | undefined>)
94
94
 
95
- const state = getActiveReleasesState(instance, {source: {projectId: 'test', dataset: 'test'}})
95
+ const state = getActiveReleasesState(instance, {resource: {projectId: 'test', dataset: 'test'}})
96
96
 
97
97
  // Initial state should be default
98
98
  expect(state.getCurrent()).toBeUndefined() // Default initial state
@@ -139,7 +139,7 @@ describe('releasesStore', () => {
139
139
  observable: of([]),
140
140
  } as StateSource<ReleaseDocument[] | undefined>)
141
141
 
142
- const state = getActiveReleasesState(instance, {source: {projectId: 'test', dataset: 'test'}})
142
+ const state = getActiveReleasesState(instance, {resource: {projectId: 'test', dataset: 'test'}})
143
143
 
144
144
  await new Promise((resolve) => setTimeout(resolve, 0))
145
145
 
@@ -153,7 +153,7 @@ describe('releasesStore', () => {
153
153
  getCurrent: () => null as unknown as ReleaseDocument[] | undefined,
154
154
  observable: of(null as unknown as ReleaseDocument[] | undefined),
155
155
  } as StateSource<ReleaseDocument[] | undefined>)
156
- const state = getActiveReleasesState(instance, {source: {projectId: 'test', dataset: 'test'}})
156
+ const state = getActiveReleasesState(instance, {resource: {projectId: 'test', dataset: 'test'}})
157
157
  await new Promise((resolve) => setTimeout(resolve, 0))
158
158
  expect(state.getCurrent()).toEqual([])
159
159
 
@@ -175,7 +175,7 @@ describe('releasesStore', () => {
175
175
  observable: subject.asObservable(),
176
176
  } as StateSource<ReleaseDocument[] | undefined>)
177
177
 
178
- const state = getActiveReleasesState(instance, {source: {projectId: 'test', dataset: 'test'}})
178
+ const state = getActiveReleasesState(instance, {resource: {projectId: 'test', dataset: 'test'}})
179
179
 
180
180
  subject.error(new Error('Query failed'))
181
181
 
@@ -1,7 +1,7 @@
1
1
  import {type SanityDocument} from '@sanity/types'
2
2
  import {map} from 'rxjs'
3
3
 
4
- import {type DocumentSource, isDatasetSource} from '../config/sanityConfig'
4
+ import {type DocumentResource, isDatasetResource} from '../config/sanityConfig'
5
5
  /*
6
6
  * Although this is an import dependency cycle, it is not a logical cycle:
7
7
  * 1. releasesStore uses queryStore as a data source
@@ -11,7 +11,7 @@ import {type DocumentSource, isDatasetSource} from '../config/sanityConfig'
11
11
  */
12
12
  // eslint-disable-next-line import/no-cycle
13
13
  import {getQueryState} from '../query/queryStore'
14
- import {bindActionBySource, type BoundSourceKey} from '../store/createActionBinder'
14
+ import {bindActionByResource, type BoundResourceKey} from '../store/createActionBinder'
15
15
  import {type SanityInstance} from '../store/createSanityInstance'
16
16
  import {createStateSourceAction, type StateSource} from '../store/createStateSourceAction'
17
17
  import {defineStore, type StoreContext} from '../store/defineStore'
@@ -41,7 +41,7 @@ export interface ReleasesStoreState {
41
41
  error?: unknown
42
42
  }
43
43
 
44
- export const releasesStore = defineStore<ReleasesStoreState, BoundSourceKey>({
44
+ export const releasesStore = defineStore<ReleasesStoreState, BoundResourceKey>({
45
45
  name: 'Releases',
46
46
  getInitialState: (): ReleasesStoreState => ({
47
47
  activeReleases: undefined,
@@ -56,7 +56,7 @@ export const releasesStore = defineStore<ReleasesStoreState, BoundSourceKey>({
56
56
  * Get the active releases from the store.
57
57
  * @internal
58
58
  */
59
- const _getActiveReleasesState = bindActionBySource(
59
+ const _getActiveReleasesState = bindActionByResource(
60
60
  releasesStore,
61
61
  createStateSourceAction({
62
62
  selector: ({state}, _?) => state.activeReleases,
@@ -69,9 +69,9 @@ const _getActiveReleasesState = bindActionBySource(
69
69
  */
70
70
  export const getActiveReleasesState = (
71
71
  instance: SanityInstance,
72
- options?: {source?: DocumentSource},
72
+ options?: {resource?: DocumentResource},
73
73
  ): StateSource<ReleaseDocument[] | undefined> =>
74
- // bindActionBySource keyFn destructures { source } from the first param, so pass {} when no options
74
+ // bindActionByResource keyFn destructures { resource } from the first param, so pass {} when no options
75
75
  _getActiveReleasesState(instance, options ?? {})
76
76
 
77
77
  const RELEASES_QUERY = 'releases::all()'
@@ -79,12 +79,12 @@ const RELEASES_QUERY = 'releases::all()'
79
79
  const subscribeToReleases = ({
80
80
  instance,
81
81
  state,
82
- key: {source},
83
- }: StoreContext<ReleasesStoreState, BoundSourceKey>) => {
82
+ key: {resource},
83
+ }: StoreContext<ReleasesStoreState, BoundResourceKey>) => {
84
84
  const {observable: releases$} = getQueryState<ReleaseDocument[]>(instance, {
85
85
  query: RELEASES_QUERY,
86
86
  perspective: 'raw',
87
- source: source && !isDatasetSource(source) ? source : undefined,
87
+ resource: resource && !isDatasetResource(resource) ? resource : undefined,
88
88
  tag: 'releases',
89
89
  })
90
90
  return releases$
@@ -1,10 +1,10 @@
1
1
  import {beforeEach, describe, expect, it, vi} from 'vitest'
2
2
 
3
- import {type DocumentSource} from '../config/sanityConfig'
3
+ import {type DocumentResource} from '../config/sanityConfig'
4
4
  import {
5
5
  bindActionByDataset,
6
- bindActionBySource,
7
- bindActionBySourceAndPerspective,
6
+ bindActionByResource,
7
+ bindActionByResourceAndPerspective,
8
8
  bindActionGlobally,
9
9
  createActionBinder,
10
10
  } from './createActionBinder'
@@ -161,28 +161,28 @@ describe('bindActionGlobally', () => {
161
161
  })
162
162
  })
163
163
 
164
- describe('bindActionBySource', () => {
165
- it('should throw an error when provided an invalid source', () => {
164
+ describe('bindActionByResource', () => {
165
+ it('should throw an error when provided an invalid resource', () => {
166
166
  const storeDefinition = {
167
167
  name: 'SourceStore',
168
168
  getInitialState: () => ({counter: 0}),
169
169
  }
170
170
  const action = vi.fn((_context) => 'success')
171
- const boundAction = bindActionBySource(storeDefinition, action)
171
+ const boundAction = bindActionByResource(storeDefinition, action)
172
172
  const instance = createSanityInstance({projectId: 'proj1', dataset: 'ds1'})
173
173
 
174
174
  expect(() =>
175
- boundAction(instance, {source: {invalid: 'source'} as unknown as DocumentSource}),
176
- ).toThrow('Received invalid source:')
175
+ boundAction(instance, {resource: {invalid: 'resource'} as unknown as DocumentResource}),
176
+ ).toThrow('Received invalid resource:')
177
177
  })
178
178
 
179
- it('should throw an error when no source provided and projectId/dataset are missing', () => {
179
+ it('should throw an error when no resource provided and projectId/dataset are missing', () => {
180
180
  const storeDefinition = {
181
181
  name: 'SourceStore',
182
182
  getInitialState: () => ({counter: 0}),
183
183
  }
184
184
  const action = vi.fn((_context) => 'success')
185
- const boundAction = bindActionBySource(storeDefinition, action)
185
+ const boundAction = bindActionByResource(storeDefinition, action)
186
186
  const instance = createSanityInstance({projectId: '', dataset: ''})
187
187
 
188
188
  expect(() => boundAction(instance, {})).toThrow(
@@ -190,47 +190,47 @@ describe('bindActionBySource', () => {
190
190
  )
191
191
  })
192
192
 
193
- it('should work correctly with a valid dataset source', () => {
193
+ it('should work correctly with a valid dataset resource', () => {
194
194
  const storeDefinition = {
195
195
  name: 'SourceStore',
196
196
  getInitialState: () => ({counter: 0}),
197
197
  }
198
198
  const action = vi.fn((_context) => 'success')
199
- const boundAction = bindActionBySource(storeDefinition, action)
199
+ const boundAction = bindActionByResource(storeDefinition, action)
200
200
  const instance = createSanityInstance({projectId: 'proj1', dataset: 'ds1'})
201
201
 
202
202
  const result = boundAction(instance, {
203
- source: {projectId: 'proj2', dataset: 'ds2'},
203
+ resource: {projectId: 'proj2', dataset: 'ds2'},
204
204
  })
205
205
  expect(result).toBe('success')
206
206
  })
207
207
  })
208
208
 
209
- describe('bindActionBySourceAndPerspective', () => {
210
- it('should throw an error when provided an invalid source', () => {
209
+ describe('bindActionByResourceAndPerspective', () => {
210
+ it('should throw an error when provided an invalid resource', () => {
211
211
  const storeDefinition = {
212
212
  name: 'PerspectiveStore',
213
213
  getInitialState: () => ({counter: 0}),
214
214
  }
215
215
  const action = vi.fn((_context) => 'success')
216
- const boundAction = bindActionBySourceAndPerspective(storeDefinition, action)
216
+ const boundAction = bindActionByResourceAndPerspective(storeDefinition, action)
217
217
  const instance = createSanityInstance({projectId: 'proj1', dataset: 'ds1'})
218
218
 
219
219
  expect(() =>
220
220
  boundAction(instance, {
221
- source: {invalid: 'source'} as unknown as DocumentSource,
221
+ resource: {invalid: 'resource'} as unknown as DocumentResource,
222
222
  perspective: 'drafts',
223
223
  }),
224
- ).toThrow('Received invalid source:')
224
+ ).toThrow('Received invalid resource:')
225
225
  })
226
226
 
227
- it('should throw an error when no source provided and projectId/dataset are missing', () => {
227
+ it('should throw an error when no resource provided and projectId/dataset are missing', () => {
228
228
  const storeDefinition = {
229
229
  name: 'PerspectiveStore',
230
230
  getInitialState: () => ({counter: 0}),
231
231
  }
232
232
  const action = vi.fn((_context) => 'success')
233
- const boundAction = bindActionBySourceAndPerspective(storeDefinition, action)
233
+ const boundAction = bindActionByResourceAndPerspective(storeDefinition, action)
234
234
  const instance = createSanityInstance({projectId: '', dataset: ''})
235
235
 
236
236
  expect(() => boundAction(instance, {perspective: 'drafts'})).toThrow(
@@ -238,33 +238,33 @@ describe('bindActionBySourceAndPerspective', () => {
238
238
  )
239
239
  })
240
240
 
241
- it('should work correctly with a valid dataset source and explicit perspective', () => {
241
+ it('should work correctly with a valid dataset resource and explicit perspective', () => {
242
242
  const storeDefinition = {
243
243
  name: 'PerspectiveStore',
244
244
  getInitialState: () => ({counter: 0}),
245
245
  }
246
246
  const action = vi.fn((_context) => 'success')
247
- const boundAction = bindActionBySourceAndPerspective(storeDefinition, action)
247
+ const boundAction = bindActionByResourceAndPerspective(storeDefinition, action)
248
248
  const instance = createSanityInstance({projectId: 'proj1', dataset: 'ds1'})
249
249
 
250
250
  const result = boundAction(instance, {
251
- source: {projectId: 'proj2', dataset: 'ds2'},
251
+ resource: {projectId: 'proj2', dataset: 'ds2'},
252
252
  perspective: 'drafts',
253
253
  })
254
254
  expect(result).toBe('success')
255
255
  })
256
256
 
257
- it('should work correctly with valid dataset source and no perspective (falls back to drafts)', () => {
257
+ it('should work correctly with valid dataset resource and no perspective (falls back to drafts)', () => {
258
258
  const storeDefinition = {
259
259
  name: 'PerspectiveStore',
260
260
  getInitialState: () => ({counter: 0}),
261
261
  }
262
262
  const action = vi.fn((_context) => 'success')
263
- const boundAction = bindActionBySourceAndPerspective(storeDefinition, action)
263
+ const boundAction = bindActionByResourceAndPerspective(storeDefinition, action)
264
264
  const instance = createSanityInstance({projectId: 'proj1', dataset: 'ds1'})
265
265
 
266
266
  const result = boundAction(instance, {
267
- source: {projectId: 'proj1', dataset: 'ds1'},
267
+ resource: {projectId: 'proj1', dataset: 'ds1'},
268
268
  })
269
269
  expect(result).toBe('success')
270
270
  })
@@ -275,7 +275,7 @@ describe('bindActionBySourceAndPerspective', () => {
275
275
  getInitialState: () => ({counter: 0}),
276
276
  }
277
277
  const action = vi.fn((context) => context.key)
278
- const boundAction = bindActionBySourceAndPerspective(storeDefinition, action)
278
+ const boundAction = bindActionByResourceAndPerspective(storeDefinition, action)
279
279
  const instance = createSanityInstance({
280
280
  projectId: 'proj1',
281
281
  dataset: 'ds1',
@@ -300,7 +300,7 @@ describe('bindActionBySourceAndPerspective', () => {
300
300
  context.state.counter += increment
301
301
  return context.state.counter
302
302
  })
303
- const boundAction = bindActionBySourceAndPerspective(storeDefinition, action)
303
+ const boundAction = bindActionByResourceAndPerspective(storeDefinition, action)
304
304
  // Use unique project/dataset so we don't reuse stores from other tests
305
305
  const instance = createSanityInstance({
306
306
  projectId: 'perspective-isolation',
@@ -322,7 +322,7 @@ describe('bindActionBySourceAndPerspective', () => {
322
322
  getInitialState: () => ({counter: 0}),
323
323
  }
324
324
  const action = vi.fn((_context) => 'success')
325
- const boundAction = bindActionBySourceAndPerspective(storeDefinition, action)
325
+ const boundAction = bindActionByResourceAndPerspective(storeDefinition, action)
326
326
  const instance = createSanityInstance({projectId: 'proj1', dataset: 'ds1'})
327
327
 
328
328
  const result = boundAction(instance, {
@@ -339,7 +339,7 @@ describe('bindActionBySourceAndPerspective', () => {
339
339
  )
340
340
  })
341
341
 
342
- it('should reuse same store when same source and perspective are used', () => {
342
+ it('should reuse same store when same resource and perspective are used', () => {
343
343
  const storeDefinition = {
344
344
  name: 'PerspectiveStore',
345
345
  getInitialState: () => ({counter: 0}),
@@ -348,7 +348,7 @@ describe('bindActionBySourceAndPerspective', () => {
348
348
  context.state.counter += increment
349
349
  return context.state.counter
350
350
  })
351
- const boundAction = bindActionBySourceAndPerspective(storeDefinition, action)
351
+ const boundAction = bindActionByResourceAndPerspective(storeDefinition, action)
352
352
  // Use unique project/dataset so we don't reuse stores from other tests
353
353
  const instance = createSanityInstance({
354
354
  projectId: 'perspective-reuse',