@sanity/sdk 2.3.1 → 2.5.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 (55) hide show
  1. package/dist/index.d.ts +173 -105
  2. package/dist/index.js +354 -122
  3. package/dist/index.js.map +1 -1
  4. package/package.json +12 -11
  5. package/src/_exports/index.ts +30 -0
  6. package/src/agent/agentActions.test.ts +81 -0
  7. package/src/agent/agentActions.ts +139 -0
  8. package/src/auth/authStore.test.ts +13 -13
  9. package/src/auth/refreshStampedToken.test.ts +16 -16
  10. package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +6 -6
  11. package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +4 -4
  12. package/src/auth/utils.ts +36 -0
  13. package/src/client/clientStore.test.ts +151 -0
  14. package/src/client/clientStore.ts +39 -1
  15. package/src/comlink/controller/actions/destroyController.test.ts +2 -2
  16. package/src/comlink/controller/actions/getOrCreateChannel.test.ts +6 -6
  17. package/src/comlink/controller/actions/getOrCreateController.test.ts +5 -5
  18. package/src/comlink/controller/actions/getOrCreateController.ts +1 -1
  19. package/src/comlink/controller/actions/releaseChannel.test.ts +3 -2
  20. package/src/comlink/controller/comlinkControllerStore.test.ts +4 -4
  21. package/src/comlink/node/actions/getOrCreateNode.test.ts +7 -7
  22. package/src/comlink/node/actions/releaseNode.test.ts +2 -2
  23. package/src/comlink/node/comlinkNodeStore.test.ts +4 -3
  24. package/src/config/sanityConfig.ts +49 -3
  25. package/src/document/actions.test.ts +34 -0
  26. package/src/document/actions.ts +31 -7
  27. package/src/document/applyDocumentActions.test.ts +9 -6
  28. package/src/document/applyDocumentActions.ts +9 -49
  29. package/src/document/documentStore.test.ts +148 -107
  30. package/src/document/documentStore.ts +40 -10
  31. package/src/document/permissions.test.ts +9 -9
  32. package/src/document/permissions.ts +17 -7
  33. package/src/document/processActions.test.ts +345 -0
  34. package/src/document/processActions.ts +185 -2
  35. package/src/document/reducers.ts +13 -6
  36. package/src/presence/presenceStore.ts +13 -7
  37. package/src/preview/previewStore.test.ts +10 -2
  38. package/src/preview/previewStore.ts +2 -1
  39. package/src/preview/subscribeToStateAndFetchBatches.test.ts +8 -5
  40. package/src/preview/subscribeToStateAndFetchBatches.ts +9 -3
  41. package/src/projection/projectionStore.test.ts +18 -2
  42. package/src/projection/projectionStore.ts +2 -1
  43. package/src/projection/subscribeToStateAndFetchBatches.test.ts +6 -5
  44. package/src/projection/subscribeToStateAndFetchBatches.ts +9 -3
  45. package/src/query/queryStore.ts +7 -4
  46. package/src/releases/getPerspectiveState.ts +2 -2
  47. package/src/releases/releasesStore.ts +10 -4
  48. package/src/store/createActionBinder.test.ts +8 -6
  49. package/src/store/createActionBinder.ts +50 -14
  50. package/src/store/createStateSourceAction.test.ts +12 -11
  51. package/src/store/createStateSourceAction.ts +6 -6
  52. package/src/store/createStoreInstance.test.ts +29 -16
  53. package/src/store/createStoreInstance.ts +6 -5
  54. package/src/store/defineStore.test.ts +1 -1
  55. package/src/store/defineStore.ts +12 -7
@@ -1,6 +1,7 @@
1
1
  import {SanityEncoder} from '@sanity/mutate'
2
2
  import {type PatchMutation as SanityMutatePatchMutation} from '@sanity/mutate/_unstable_store'
3
3
  import {type PatchMutation, type PatchOperations} from '@sanity/types'
4
+ import {type SanityDocument} from 'groq'
4
5
 
5
6
  import {type DocumentHandle, type DocumentTypeHandle} from '../config/sanityConfig'
6
7
  import {getPublishedId} from '../utils/ids'
@@ -24,6 +25,17 @@ export interface CreateDocumentAction<
24
25
  TProjectId extends string = string,
25
26
  > extends DocumentTypeHandle<TDocumentType, TDataset, TProjectId> {
26
27
  type: 'document.create'
28
+ /**
29
+ * Optional initial field values for the document.
30
+ * These values will be set when the document is created.
31
+ * System fields (_id, _type, _rev, _createdAt, _updatedAt) are omitted as they are set automatically.
32
+ */
33
+ initialValue?: Partial<
34
+ Omit<
35
+ SanityDocument<TDocumentType, `${TProjectId}.${TDataset}`>,
36
+ '_id' | '_type' | '_rev' | '_createdAt' | '_updatedAt'
37
+ >
38
+ >
27
39
  }
28
40
 
29
41
  /**
@@ -111,6 +123,7 @@ export type DocumentAction<
111
123
  /**
112
124
  * Creates a `CreateDocumentAction` object.
113
125
  * @param doc - A handle identifying the document type, dataset, and project. An optional `documentId` can be provided.
126
+ * @param initialValue - Optional initial field values for the document. (System fields are omitted as they are set automatically.)
114
127
  * @returns A `CreateDocumentAction` object ready for dispatch.
115
128
  * @beta
116
129
  */
@@ -120,11 +133,20 @@ export function createDocument<
120
133
  TProjectId extends string = string,
121
134
  >(
122
135
  doc: DocumentTypeHandle<TDocumentType, TDataset, TProjectId>,
136
+ initialValue?: Partial<
137
+ Omit<
138
+ SanityDocument<TDocumentType, `${TProjectId}.${TDataset}`>,
139
+ '_id' | '_type' | '_rev' | '_createdAt' | '_updatedAt'
140
+ >
141
+ >,
123
142
  ): CreateDocumentAction<TDocumentType, TDataset, TProjectId> {
124
143
  return {
125
144
  type: 'document.create',
126
145
  ...doc,
127
- ...(doc.documentId && {documentId: getPublishedId(doc.documentId)}),
146
+ ...(doc.documentId && {
147
+ documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId),
148
+ }),
149
+ ...(initialValue && {initialValue}),
128
150
  }
129
151
  }
130
152
 
@@ -144,7 +166,7 @@ export function deleteDocument<
144
166
  return {
145
167
  type: 'document.delete',
146
168
  ...doc,
147
- documentId: getPublishedId(doc.documentId),
169
+ documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId),
148
170
  }
149
171
  }
150
172
 
@@ -208,12 +230,14 @@ export function editDocument<
208
230
  doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
209
231
  patches?: PatchOperations | PatchOperations[] | SanityMutatePatchMutation,
210
232
  ): EditDocumentAction<TDocumentType, TDataset, TProjectId> {
233
+ const documentId = doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId)
234
+
211
235
  if (isSanityMutatePatch(patches)) {
212
236
  const converted = convertSanityMutatePatch(patches) ?? []
213
237
  return {
214
238
  ...doc,
215
239
  type: 'document.edit',
216
- documentId: getPublishedId(doc.documentId),
240
+ documentId,
217
241
  patches: converted,
218
242
  }
219
243
  }
@@ -221,7 +245,7 @@ export function editDocument<
221
245
  return {
222
246
  ...doc,
223
247
  type: 'document.edit',
224
- documentId: getPublishedId(doc.documentId),
248
+ documentId,
225
249
  ...(patches && {patches: Array.isArray(patches) ? patches : [patches]}),
226
250
  }
227
251
  }
@@ -242,7 +266,7 @@ export function publishDocument<
242
266
  return {
243
267
  type: 'document.publish',
244
268
  ...doc,
245
- documentId: getPublishedId(doc.documentId),
269
+ documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId),
246
270
  }
247
271
  }
248
272
 
@@ -262,7 +286,7 @@ export function unpublishDocument<
262
286
  return {
263
287
  type: 'document.unpublish',
264
288
  ...doc,
265
- documentId: getPublishedId(doc.documentId),
289
+ documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId),
266
290
  }
267
291
  }
268
292
 
@@ -282,6 +306,6 @@ export function discardDocument<
282
306
  return {
283
307
  type: 'document.discard',
284
308
  ...doc,
285
- documentId: getPublishedId(doc.documentId),
309
+ documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId),
286
310
  }
287
311
  }
@@ -48,11 +48,11 @@ describe('applyDocumentActions', () => {
48
48
  }
49
49
  state = createStoreState(initialState)
50
50
  instance = createSanityInstance({projectId: 'p', dataset: 'd'})
51
+ const key = {name: 'p.d', projectId: 'p', dataset: 'd'}
51
52
 
52
53
  vi.mocked(bindActionByDataset).mockImplementation(
53
- (_storeDef, action) =>
54
- (instanceParam: SanityInstance, ...params: unknown[]) =>
55
- action({instance: instanceParam, state}, ...params),
54
+ (_storeDef, action) => (instanceParam: SanityInstance, options) =>
55
+ action({instance: instanceParam, state, key}, options),
56
56
  )
57
57
  // Import dynamically to ensure mocks are set up before the module under test is loaded
58
58
  const module = await import('./applyDocumentActions')
@@ -72,7 +72,8 @@ describe('applyDocumentActions', () => {
72
72
  }
73
73
 
74
74
  // Call applyDocumentActions with a fixed transactionId for reproducibility.
75
- const applyPromise = applyDocumentActions(instance, action, {
75
+ const applyPromise = applyDocumentActions(instance, {
76
+ actions: [action],
76
77
  transactionId: 'txn-success',
77
78
  })
78
79
 
@@ -128,7 +129,8 @@ describe('applyDocumentActions', () => {
128
129
  }
129
130
 
130
131
  // Call applyDocumentActions with a fixed transactionId.
131
- const applyPromise = applyDocumentActions(instance, action, {
132
+ const applyPromise = applyDocumentActions(instance, {
133
+ actions: [action],
132
134
  transactionId: 'txn-error',
133
135
  })
134
136
 
@@ -160,7 +162,8 @@ describe('applyDocumentActions', () => {
160
162
  dataset: 'd',
161
163
  }
162
164
  // Call applyDocumentActions with the context using childInstance, but with action requiring parent's config
163
- const applyPromise = applyDocumentActions(childInstance, action, {
165
+ const applyPromise = applyDocumentActions(childInstance, {
166
+ actions: [action],
164
167
  transactionId: 'txn-child-match',
165
168
  })
166
169
 
@@ -24,6 +24,11 @@ export interface ActionsResult<TDocument extends SanityDocument = SanityDocument
24
24
 
25
25
  /** @beta */
26
26
  export interface ApplyDocumentActionsOptions {
27
+ /**
28
+ * List of actions to apply.
29
+ */
30
+ actions: DocumentAction[]
31
+
27
32
  /**
28
33
  * Optionally provide an ID to be used as this transaction ID
29
34
  */
@@ -41,16 +46,12 @@ export function applyDocumentActions<
41
46
  TProjectId extends string = string,
42
47
  >(
43
48
  instance: SanityInstance,
44
- action:
45
- | DocumentAction<TDocumentType, TDataset, TProjectId>
46
- | DocumentAction<TDocumentType, TDataset, TProjectId>[],
47
- options?: ApplyDocumentActionsOptions,
49
+ options: ApplyDocumentActionsOptions,
48
50
  ): Promise<ActionsResult<SanityDocument<TDocumentType, `${TProjectId}.${TDataset}`>>>
49
51
  /** @beta */
50
52
  export function applyDocumentActions(
51
53
  instance: SanityInstance,
52
- action: DocumentAction | DocumentAction[],
53
- options?: ApplyDocumentActionsOptions,
54
+ options: ApplyDocumentActionsOptions,
54
55
  ): Promise<ActionsResult>
55
56
 
56
57
  /** @beta */
@@ -64,50 +65,9 @@ const boundApplyDocumentActions = bindActionByDataset(documentStore, _applyDocum
64
65
 
65
66
  /** @internal */
66
67
  async function _applyDocumentActions(
67
- {instance, state}: StoreContext<DocumentStoreState>,
68
- actionOrActions: DocumentAction | DocumentAction[],
69
- {transactionId = crypto.randomUUID(), disableBatching}: ApplyDocumentActionsOptions = {},
68
+ {state}: StoreContext<DocumentStoreState>,
69
+ {actions, transactionId = crypto.randomUUID(), disableBatching}: ApplyDocumentActionsOptions,
70
70
  ): Promise<ActionsResult> {
71
- const actions = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions]
72
-
73
- let projectId
74
- let dataset
75
- for (const action of actions) {
76
- if (action.projectId) {
77
- if (!projectId) projectId = action.projectId
78
- if (action.projectId !== projectId) {
79
- throw new Error(
80
- `Mismatched project IDs found in actions. All actions must belong to the same project. Found "${action.projectId}" but expected "${projectId}".`,
81
- )
82
- }
83
-
84
- if (action.dataset) {
85
- if (!dataset) dataset = action.dataset
86
- if (action.dataset !== dataset) {
87
- throw new Error(
88
- `Mismatched datasets found in actions. All actions must belong to the same dataset. Found "${action.dataset}" but expected "${dataset}".`,
89
- )
90
- }
91
- }
92
- }
93
- }
94
-
95
- if (
96
- (projectId && projectId !== instance.config.projectId) ||
97
- (dataset && dataset !== instance.config.dataset)
98
- ) {
99
- const matchedInstance = instance.match({projectId, dataset})
100
- if (!matchedInstance) {
101
- throw new Error(
102
- `Could not find a matching instance for projectId: "${projectId}" and dataset: "${dataset}"`,
103
- )
104
- }
105
- return boundApplyDocumentActions(matchedInstance, actionOrActions, {
106
- disableBatching,
107
- transactionId,
108
- })
109
- }
110
-
111
71
  const {events} = state.get()
112
72
 
113
73
  const transaction: QueuedTransaction = {