@sanity/sdk 3.0.0-rc.0 → 3.0.0-rc.2
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.
- package/README.md +12 -0
- package/dist/_exports/_internal.d.ts +163 -0
- package/dist/_exports/_internal.d.ts.map +1 -0
- package/dist/_exports/_internal.js +332 -0
- package/dist/_exports/_internal.js.map +1 -0
- package/dist/_exports/agent.d.ts +65 -0
- package/dist/_exports/agent.d.ts.map +1 -0
- package/dist/_exports/agent.js +71 -0
- package/dist/_exports/agent.js.map +1 -0
- package/dist/_exports/comlink.d.ts +118 -0
- package/dist/_exports/comlink.d.ts.map +1 -0
- package/dist/_exports/comlink.js +69 -0
- package/dist/_exports/comlink.js.map +1 -0
- package/dist/authStore-CtE9bLHW.js +754 -0
- package/dist/authStore-CtE9bLHW.js.map +1 -0
- package/dist/authStore-DKFX8fn7.d.ts +3179 -0
- package/dist/authStore-DKFX8fn7.d.ts.map +1 -0
- package/dist/clientStore-BtE2-q2i.js +90 -0
- package/dist/clientStore-BtE2-q2i.js.map +1 -0
- package/dist/createSanityInstance-DUI1bGIg.d.ts +278 -0
- package/dist/createSanityInstance-DUI1bGIg.d.ts.map +1 -0
- package/dist/createStateSourceAction-BOKtqFNm.js +300 -0
- package/dist/createStateSourceAction-BOKtqFNm.js.map +1 -0
- package/dist/getEnv-D5RGkQLu.js +8 -0
- package/dist/getEnv-D5RGkQLu.js.map +1 -0
- package/dist/getNodeState-CR3__B2D.js +67 -0
- package/dist/getNodeState-CR3__B2D.js.map +1 -0
- package/dist/index.d.ts +3 -2332
- package/dist/index.js +4171 -4332
- package/dist/index.js.map +1 -1
- package/dist/logger-DAtJb5RQ.js +173 -0
- package/dist/logger-DAtJb5RQ.js.map +1 -0
- package/dist/object-CxXlSVg7.js +83 -0
- package/dist/object-CxXlSVg7.js.map +1 -0
- package/dist/queryStore-DPf9sN3V.js +1346 -0
- package/dist/queryStore-DPf9sN3V.js.map +1 -0
- package/dist/rolldown-runtime-vyAXikos.js +9 -0
- package/dist/setCleanupTimeout-BiM6q1KF.js +31 -0
- package/dist/setCleanupTimeout-BiM6q1KF.js.map +1 -0
- package/dist/telemetryManager-Dq_qCkeI.js +127 -0
- package/dist/telemetryManager-Dq_qCkeI.js.map +1 -0
- package/dist/version-BChjsi4u.js +9 -0
- package/dist/version-BChjsi4u.js.map +1 -0
- package/package.json +47 -52
- package/src/_exports/_internal.ts +27 -0
- package/src/_exports/agent.ts +19 -0
- package/src/_exports/comlink.ts +16 -0
- package/src/_exports/index.ts +125 -64
- package/src/access/checkPermissions.test.ts +55 -0
- package/src/access/checkPermissions.ts +54 -0
- package/src/agent/agentActions.test.ts +16 -60
- package/src/agent/agentActions.ts +25 -38
- package/src/applications/applications.test-d.ts +88 -0
- package/src/applications/applications.test.ts +130 -0
- package/src/applications/applications.ts +367 -0
- package/src/auth/authLogger.ts +30 -0
- package/src/auth/authStore.test.ts +194 -13
- package/src/auth/authStore.ts +58 -26
- package/src/auth/getOrganizationVerificationState.test.ts +18 -17
- package/src/auth/getOrganizationVerificationState.ts +4 -4
- package/src/auth/handleAuthCallback.test.ts +35 -1
- package/src/auth/handleAuthCallback.ts +25 -6
- package/src/auth/logout.test.ts +75 -2
- package/src/auth/logout.ts +23 -4
- package/src/auth/refreshStampedToken.test.ts +219 -469
- package/src/auth/refreshStampedToken.ts +79 -195
- package/src/auth/studioAuth.ts +1 -1
- package/src/auth/studioModeAuth.ts +2 -1
- package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +146 -13
- package/src/auth/subscribeToStateAndFetchCurrentUser.ts +37 -6
- package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +2 -0
- package/src/client/clientStore.test.ts +62 -37
- package/src/client/clientStore.ts +45 -75
- package/src/client/liveEvents.test.ts +151 -0
- package/src/client/liveEvents.ts +107 -0
- package/src/comlink/controller/actions/destroyController.test.ts +4 -1
- package/src/comlink/controller/actions/getOrCreateChannel.test.ts +4 -1
- package/src/comlink/controller/actions/getOrCreateChannel.ts +2 -2
- package/src/comlink/controller/actions/getOrCreateController.test.ts +4 -1
- package/src/comlink/controller/actions/releaseChannel.test.ts +1 -1
- package/src/comlink/controller/comlinkControllerStore.test.ts +4 -1
- package/src/comlink/node/actions/getOrCreateNode.test.ts +9 -3
- package/src/comlink/node/actions/getOrCreateNode.ts +2 -2
- package/src/comlink/node/actions/releaseNode.test.ts +7 -4
- package/src/comlink/node/comlinkNodeStore.test.ts +2 -2
- package/src/comlink/node/getNodeState.test.ts +1 -1
- package/src/comlink/node/getNodeState.ts +2 -1
- package/src/comments/addonDatasetStore.test.ts +215 -0
- package/src/comments/addonDatasetStore.ts +249 -0
- package/src/comments/buildCommentThreads.test.ts +83 -0
- package/src/comments/buildCommentThreads.ts +54 -0
- package/src/comments/commentActions.test.ts +540 -0
- package/src/comments/commentActions.ts +555 -0
- package/src/comments/commentFieldPath.test.ts +40 -0
- package/src/comments/commentFieldPath.ts +44 -0
- package/src/comments/commentsConstants.ts +80 -0
- package/src/comments/commentsStore.test.ts +419 -0
- package/src/comments/commentsStore.ts +483 -0
- package/src/comments/normalizeComment.test.ts +116 -0
- package/src/comments/normalizeComment.ts +45 -0
- package/src/comments/observeComments.test.ts +193 -0
- package/src/comments/observeComments.ts +113 -0
- package/src/comments/reducers.test.ts +277 -0
- package/src/comments/reducers.ts +316 -0
- package/src/comments/types.ts +249 -0
- package/src/comments/weakenReferences.test.ts +47 -0
- package/src/comments/weakenReferences.ts +29 -0
- package/src/config/__tests__/handles.test.ts +18 -12
- package/src/config/handles.ts +25 -7
- package/src/config/sanityConfig.ts +40 -82
- package/src/datasets/datasets.test.ts +2 -2
- package/src/datasets/datasets.ts +10 -4
- package/src/document/actions.test.ts +115 -33
- package/src/document/actions.ts +212 -15
- package/src/document/applyDocumentActions.test.ts +35 -13
- package/src/document/applyDocumentActions.ts +30 -9
- package/src/document/documentConstants.ts +15 -0
- package/src/document/documentStore.concurrency.test.ts +1306 -0
- package/src/document/documentStore.test.ts +753 -273
- package/src/document/documentStore.ts +197 -75
- package/src/document/events.test.ts +57 -2
- package/src/document/events.ts +82 -26
- package/src/document/listen.test.ts +56 -0
- package/src/document/listen.ts +74 -21
- package/src/document/listenerEventOperators.test.ts +311 -0
- package/src/document/listenerEventOperators.ts +217 -0
- package/src/document/patchOperations.test.ts +76 -2
- package/src/document/patchOperations.ts +60 -1
- package/src/document/permissions.test.ts +107 -60
- package/src/document/permissions.ts +44 -19
- package/src/document/processActions/create.ts +138 -0
- package/src/document/processActions/delete.ts +100 -0
- package/src/document/processActions/discard.ts +63 -0
- package/src/document/processActions/edit.ts +154 -0
- package/src/document/processActions/processActions.ts +218 -0
- package/src/document/processActions/publish.ts +120 -0
- package/src/document/processActions/releaseArchive.ts +77 -0
- package/src/document/processActions/releaseCreate.ts +59 -0
- package/src/document/processActions/releaseDelete.ts +65 -0
- package/src/document/processActions/releaseEdit.ts +37 -0
- package/src/document/processActions/releasePublish.ts +45 -0
- package/src/document/processActions/releaseSchedule.ts +87 -0
- package/src/document/processActions/releaseUtil.ts +31 -0
- package/src/document/processActions/shared.ts +308 -0
- package/src/document/processActions/unpublish.ts +85 -0
- package/src/document/processActions.test.ts +1129 -121
- package/src/document/reducers.test.ts +772 -64
- package/src/document/reducers.ts +205 -51
- package/src/document/resourceRules.test.ts +178 -0
- package/src/document/resourceRules.ts +117 -0
- package/src/document/sharedListener.test.ts +16 -14
- package/src/document/sharedListener.ts +24 -8
- package/src/document/util.test.ts +46 -0
- package/src/document/util.ts +50 -0
- package/src/favorites/favorites.test.ts +5 -6
- package/src/installations/installations.test-d.ts +73 -0
- package/src/installations/installations.test.ts +62 -0
- package/src/installations/installations.ts +206 -0
- package/src/organization/organization.test-d.ts +36 -0
- package/src/organization/organization.test.ts +138 -0
- package/src/organization/organization.ts +138 -0
- package/src/organizations/organizations.test-d.ts +56 -0
- package/src/organizations/organizations.test.ts +150 -0
- package/src/organizations/organizations.ts +107 -0
- package/src/presence/bifurTransport.test.ts +201 -9
- package/src/presence/bifurTransport.ts +98 -14
- package/src/presence/paths.test.ts +70 -0
- package/src/presence/paths.ts +41 -0
- package/src/presence/presenceStore.test.ts +915 -24
- package/src/presence/presenceStore.ts +576 -104
- package/src/presence/types.ts +175 -3
- package/src/preview/previewProjectionUtils.test.ts +9 -22
- package/src/preview/previewProjectionUtils.ts +7 -3
- package/src/preview/types.ts +0 -15
- package/src/project/project.test-d.ts +37 -0
- package/src/project/project.test.ts +157 -12
- package/src/project/project.ts +138 -25
- package/src/projection/getProjectionState.test.ts +18 -20
- package/src/projection/getProjectionState.ts +23 -3
- package/src/projection/projectionQuery.ts +5 -5
- package/src/projection/projectionStore.test.ts +1 -9
- package/src/projection/resolveProjection.test.ts +1 -2
- package/src/projection/resolveProjection.ts +16 -0
- package/src/projection/subscribeToStateAndFetchBatches.test.ts +1 -1
- package/src/projection/subscribeToStateAndFetchBatches.ts +32 -23
- package/src/projects/projects.test-d.ts +32 -0
- package/src/projects/projects.test.ts +108 -42
- package/src/projects/projects.ts +63 -27
- package/src/query/queryStore.test.ts +259 -123
- package/src/query/queryStore.ts +85 -69
- package/src/query/reducers.test.ts +0 -42
- package/src/query/reducers.ts +2 -18
- package/src/releases/getPerspectiveState.test.ts +17 -23
- package/src/releases/getPerspectiveState.ts +8 -20
- package/src/releases/observeReleases.test.ts +127 -0
- package/src/releases/observeReleases.ts +102 -0
- package/src/releases/releasesStore.test.ts +100 -53
- package/src/releases/releasesStore.ts +69 -44
- package/src/releases/utils/sortReleases.test.ts +38 -2
- package/src/releases/utils/sortReleases.ts +15 -10
- package/src/store/createActionBinder.test.ts +109 -90
- package/src/store/createActionBinder.ts +36 -28
- package/src/store/createSanityInstance.test.ts +15 -13
- package/src/store/createSanityInstance.ts +14 -2
- package/src/store/createStateSourceAction.test.ts +64 -2
- package/src/store/createStateSourceAction.ts +38 -43
- package/src/store/createStoreInstance.test.ts +4 -2
- package/src/store/fetcherStore.test-d.ts +121 -0
- package/src/store/fetcherStore.test.ts +299 -0
- package/src/store/fetcherStore.ts +801 -0
- package/src/telemetry/environment.test.ts +119 -0
- package/src/telemetry/environment.ts +92 -0
- package/src/telemetry/events.ts +42 -0
- package/src/telemetry/initTelemetry.test.ts +432 -0
- package/src/telemetry/initTelemetry.ts +218 -0
- package/src/telemetry/telemetryManager.test.ts +327 -0
- package/src/telemetry/telemetryManager.ts +199 -0
- package/src/users/reducers.test.ts +3 -1
- package/src/users/reducers.ts +5 -6
- package/src/users/types.ts +4 -4
- package/src/users/usersStore.test.ts +16 -12
- package/src/users/usersStore.ts +5 -1
- package/src/utils/buildQuery.test.ts +14 -0
- package/src/utils/buildQuery.ts +17 -0
- package/src/utils/createFetcherStore.test.ts +7 -5
- package/src/utils/createFetcherStore.ts +8 -5
- package/src/utils/getStagingApiHost.test.ts +21 -0
- package/src/utils/getStagingApiHost.ts +14 -0
- package/src/utils/ids.test.ts +1 -29
- package/src/utils/ids.ts +0 -10
- package/src/utils/includeShape.ts +36 -0
- package/src/utils/isImportError.test.ts +72 -0
- package/src/utils/isImportError.ts +34 -0
- package/src/utils/logger.test.ts +12 -0
- package/src/utils/logger.ts +8 -3
- package/src/utils/object.test.ts +95 -0
- package/src/utils/object.ts +142 -0
- package/src/utils/setCleanupTimeout.ts +37 -0
- package/src/document/processActions.ts +0 -707
- package/src/utils/defineIntent.test.ts +0 -477
- package/src/utils/defineIntent.ts +0 -244
package/src/document/actions.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import {type ReleaseDocument} from '@sanity/client'
|
|
1
2
|
import {SanityEncoder} from '@sanity/mutate'
|
|
2
3
|
import {type PatchMutation as SanityMutatePatchMutation} from '@sanity/mutate/_unstable_store'
|
|
3
|
-
import {type PatchMutation, type PatchOperations
|
|
4
|
+
import {type PatchMutation, type PatchOperations} from '@sanity/types'
|
|
5
|
+
import {type SanityDocument} from 'groq'
|
|
4
6
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
+
import {
|
|
8
|
+
type DocumentHandle,
|
|
9
|
+
type DocumentTypeHandle,
|
|
10
|
+
type ReleaseHandle,
|
|
11
|
+
} from '../config/sanityConfig'
|
|
12
|
+
import {getEffectiveDocumentId} from './util'
|
|
7
13
|
|
|
8
14
|
const isSanityMutatePatch = (value: unknown): value is SanityMutatePatchMutation => {
|
|
9
15
|
if (typeof value !== 'object' || !value) return false
|
|
@@ -30,7 +36,10 @@ export interface CreateDocumentAction<
|
|
|
30
36
|
* System fields (_id, _type, _rev, _createdAt, _updatedAt) are omitted as they are set automatically.
|
|
31
37
|
*/
|
|
32
38
|
initialValue?: Partial<
|
|
33
|
-
Omit<
|
|
39
|
+
Omit<
|
|
40
|
+
SanityDocument<TDocumentType, `${TProjectId}.${TDataset}`>,
|
|
41
|
+
'_id' | '_type' | '_rev' | '_createdAt' | '_updatedAt'
|
|
42
|
+
>
|
|
34
43
|
>
|
|
35
44
|
}
|
|
36
45
|
|
|
@@ -59,6 +68,21 @@ export interface EditDocumentAction<
|
|
|
59
68
|
> extends DocumentHandle<TDocumentType, TDataset, TProjectId> {
|
|
60
69
|
type: 'document.edit'
|
|
61
70
|
patches?: PatchOperations[]
|
|
71
|
+
/**
|
|
72
|
+
* When `true`, the given `patches` are forwarded verbatim to the server and
|
|
73
|
+
* applied as-is locally, instead of being re-derived by diffing document
|
|
74
|
+
* snapshots. This preserves the operational intent of the patches (e.g.
|
|
75
|
+
* keyed array inserts/unsets), which lets concurrent edits from other
|
|
76
|
+
* clients interleave coherently instead of being overwritten by
|
|
77
|
+
* position-based patches computed from a stale snapshot.
|
|
78
|
+
*
|
|
79
|
+
* Use this when the patches were produced by an editor that tracks its own
|
|
80
|
+
* operations (e.g. a collaborative text editor). During a rebase onto a
|
|
81
|
+
* changed remote document, preserved patches are re-applied operationally;
|
|
82
|
+
* if a patch can no longer apply, the transaction is skipped and reported
|
|
83
|
+
* as a `rebase-error` document event.
|
|
84
|
+
*/
|
|
85
|
+
preserveOperations?: boolean
|
|
62
86
|
}
|
|
63
87
|
|
|
64
88
|
/**
|
|
@@ -116,6 +140,17 @@ export type DocumentAction<
|
|
|
116
140
|
| UnpublishDocumentAction<TDocumentType, TDataset, TProjectId>
|
|
117
141
|
| DiscardDocumentAction<TDocumentType, TDataset, TProjectId>
|
|
118
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Union of every action accepted by `applyDocumentActions` — both document-
|
|
145
|
+
* level actions and release-lifecycle actions.
|
|
146
|
+
* @beta
|
|
147
|
+
*/
|
|
148
|
+
export type Action<
|
|
149
|
+
TDocumentType extends string = string,
|
|
150
|
+
TDataset extends string = string,
|
|
151
|
+
TProjectId extends string = string,
|
|
152
|
+
> = DocumentAction<TDocumentType, TDataset, TProjectId> | ReleaseAction
|
|
153
|
+
|
|
119
154
|
/**
|
|
120
155
|
* Creates a `CreateDocumentAction` object.
|
|
121
156
|
* @param doc - A handle identifying the document type, dataset, and project. An optional `documentId` can be provided.
|
|
@@ -130,15 +165,21 @@ export function createDocument<
|
|
|
130
165
|
>(
|
|
131
166
|
doc: DocumentTypeHandle<TDocumentType, TDataset, TProjectId>,
|
|
132
167
|
initialValue?: Partial<
|
|
133
|
-
Omit<
|
|
168
|
+
Omit<
|
|
169
|
+
SanityDocument<TDocumentType, `${TProjectId}.${TDataset}`>,
|
|
170
|
+
'_id' | '_type' | '_rev' | '_createdAt' | '_updatedAt'
|
|
171
|
+
>
|
|
134
172
|
>,
|
|
135
173
|
): CreateDocumentAction<TDocumentType, TDataset, TProjectId> {
|
|
174
|
+
// users may pass in an explicit documentId -- make sure we format it correctly for the action
|
|
175
|
+
let effectiveDocumentId
|
|
176
|
+
if (typeof doc.documentId === 'string') {
|
|
177
|
+
effectiveDocumentId = getEffectiveDocumentId({...doc, documentId: doc.documentId})
|
|
178
|
+
}
|
|
136
179
|
return {
|
|
137
180
|
type: 'document.create',
|
|
138
181
|
...doc,
|
|
139
|
-
...(
|
|
140
|
-
documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId),
|
|
141
|
-
}),
|
|
182
|
+
...(effectiveDocumentId && {documentId: effectiveDocumentId}),
|
|
142
183
|
...(initialValue && {initialValue}),
|
|
143
184
|
}
|
|
144
185
|
}
|
|
@@ -156,10 +197,11 @@ export function deleteDocument<
|
|
|
156
197
|
>(
|
|
157
198
|
doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
|
|
158
199
|
): DeleteDocumentAction<TDocumentType, TDataset, TProjectId> {
|
|
200
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc)
|
|
159
201
|
return {
|
|
160
202
|
type: 'document.delete',
|
|
161
203
|
...doc,
|
|
162
|
-
documentId:
|
|
204
|
+
documentId: effectiveDocumentId,
|
|
163
205
|
}
|
|
164
206
|
}
|
|
165
207
|
|
|
@@ -174,12 +216,25 @@ function convertSanityMutatePatch(
|
|
|
174
216
|
})
|
|
175
217
|
}
|
|
176
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Options for creating an `EditDocumentAction`.
|
|
221
|
+
* @beta
|
|
222
|
+
*/
|
|
223
|
+
export interface EditDocumentOptions {
|
|
224
|
+
/**
|
|
225
|
+
* Forward the given patches verbatim instead of re-deriving them by
|
|
226
|
+
* diffing document snapshots. See {@link EditDocumentAction.preserveOperations}.
|
|
227
|
+
*/
|
|
228
|
+
preserveOperations?: boolean
|
|
229
|
+
}
|
|
230
|
+
|
|
177
231
|
/**
|
|
178
232
|
* Creates an `EditDocumentAction` object with patches for modifying a document.
|
|
179
233
|
* Accepts patches in either the standard `PatchOperations` format or as a `SanityMutatePatchMutation` from `@sanity/mutate`.
|
|
180
234
|
*
|
|
181
235
|
* @param doc - A handle uniquely identifying the document to be edited.
|
|
182
236
|
* @param sanityMutatePatch - A patch mutation object from `@sanity/mutate`.
|
|
237
|
+
* @param options - Options controlling how the patches are processed.
|
|
183
238
|
* @returns An `EditDocumentAction` object ready for dispatch.
|
|
184
239
|
* @beta
|
|
185
240
|
*/
|
|
@@ -190,12 +245,14 @@ export function editDocument<
|
|
|
190
245
|
>(
|
|
191
246
|
doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
|
|
192
247
|
sanityMutatePatch: SanityMutatePatchMutation,
|
|
248
|
+
options?: EditDocumentOptions,
|
|
193
249
|
): EditDocumentAction<TDocumentType, TDataset, TProjectId>
|
|
194
250
|
/**
|
|
195
251
|
* Creates an `EditDocumentAction` object with patches for modifying a document.
|
|
196
252
|
*
|
|
197
253
|
* @param doc - A handle uniquely identifying the document to be edited.
|
|
198
254
|
* @param patches - A single patch operation or an array of patch operations.
|
|
255
|
+
* @param options - Options controlling how the patches are processed.
|
|
199
256
|
* @returns An `EditDocumentAction` object ready for dispatch.
|
|
200
257
|
* @beta
|
|
201
258
|
*/
|
|
@@ -206,6 +263,7 @@ export function editDocument<
|
|
|
206
263
|
>(
|
|
207
264
|
doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
|
|
208
265
|
patches?: PatchOperations | PatchOperations[],
|
|
266
|
+
options?: EditDocumentOptions,
|
|
209
267
|
): EditDocumentAction<TDocumentType, TDataset, TProjectId>
|
|
210
268
|
/**
|
|
211
269
|
* Creates an `EditDocumentAction` object with patches for modifying a document.
|
|
@@ -213,6 +271,7 @@ export function editDocument<
|
|
|
213
271
|
*
|
|
214
272
|
* @param doc - A handle uniquely identifying the document to be edited.
|
|
215
273
|
* @param patches - Patches in various formats (`PatchOperations`, `PatchOperations[]`, or `SanityMutatePatchMutation`).
|
|
274
|
+
* @param options - Options controlling how the patches are processed.
|
|
216
275
|
* @returns An `EditDocumentAction` object ready for dispatch.
|
|
217
276
|
*/
|
|
218
277
|
export function editDocument<
|
|
@@ -222,24 +281,28 @@ export function editDocument<
|
|
|
222
281
|
>(
|
|
223
282
|
doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
|
|
224
283
|
patches?: PatchOperations | PatchOperations[] | SanityMutatePatchMutation,
|
|
284
|
+
options?: EditDocumentOptions,
|
|
225
285
|
): EditDocumentAction<TDocumentType, TDataset, TProjectId> {
|
|
226
|
-
const
|
|
286
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc)
|
|
287
|
+
const preserveOperations = options?.preserveOperations && {preserveOperations: true as const}
|
|
227
288
|
|
|
228
289
|
if (isSanityMutatePatch(patches)) {
|
|
229
290
|
const converted = convertSanityMutatePatch(patches) ?? []
|
|
230
291
|
return {
|
|
231
292
|
...doc,
|
|
232
293
|
type: 'document.edit',
|
|
233
|
-
documentId,
|
|
294
|
+
documentId: effectiveDocumentId,
|
|
234
295
|
patches: converted,
|
|
296
|
+
...preserveOperations,
|
|
235
297
|
}
|
|
236
298
|
}
|
|
237
299
|
|
|
238
300
|
return {
|
|
239
301
|
...doc,
|
|
240
302
|
type: 'document.edit',
|
|
241
|
-
documentId,
|
|
303
|
+
documentId: effectiveDocumentId,
|
|
242
304
|
...(patches && {patches: Array.isArray(patches) ? patches : [patches]}),
|
|
305
|
+
...preserveOperations,
|
|
243
306
|
}
|
|
244
307
|
}
|
|
245
308
|
|
|
@@ -256,10 +319,11 @@ export function publishDocument<
|
|
|
256
319
|
>(
|
|
257
320
|
doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
|
|
258
321
|
): PublishDocumentAction<TDocumentType, TDataset, TProjectId> {
|
|
322
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc)
|
|
259
323
|
return {
|
|
260
324
|
type: 'document.publish',
|
|
261
325
|
...doc,
|
|
262
|
-
documentId:
|
|
326
|
+
documentId: effectiveDocumentId,
|
|
263
327
|
}
|
|
264
328
|
}
|
|
265
329
|
|
|
@@ -276,10 +340,11 @@ export function unpublishDocument<
|
|
|
276
340
|
>(
|
|
277
341
|
doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
|
|
278
342
|
): UnpublishDocumentAction<TDocumentType, TDataset, TProjectId> {
|
|
343
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc)
|
|
279
344
|
return {
|
|
280
345
|
type: 'document.unpublish',
|
|
281
346
|
...doc,
|
|
282
|
-
documentId:
|
|
347
|
+
documentId: effectiveDocumentId,
|
|
283
348
|
}
|
|
284
349
|
}
|
|
285
350
|
|
|
@@ -296,9 +361,141 @@ export function discardDocument<
|
|
|
296
361
|
>(
|
|
297
362
|
doc: DocumentHandle<TDocumentType, TDataset, TProjectId>,
|
|
298
363
|
): DiscardDocumentAction<TDocumentType, TDataset, TProjectId> {
|
|
364
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc)
|
|
299
365
|
return {
|
|
300
366
|
type: 'document.discard',
|
|
301
367
|
...doc,
|
|
302
|
-
documentId:
|
|
368
|
+
documentId: effectiveDocumentId,
|
|
303
369
|
}
|
|
304
370
|
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Creates a new release. The `releaseId` must be unique within the current
|
|
374
|
+
* retention period.
|
|
375
|
+
* @beta
|
|
376
|
+
*/
|
|
377
|
+
export interface CreateReleaseAction extends ReleaseHandle {
|
|
378
|
+
type: 'release.create'
|
|
379
|
+
metadata: ReleaseDocument['metadata']
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Patches the metadata of an existing release.
|
|
384
|
+
* @beta
|
|
385
|
+
*/
|
|
386
|
+
export interface EditReleaseAction extends ReleaseHandle {
|
|
387
|
+
type: 'release.edit'
|
|
388
|
+
patch: PatchOperations
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Publishes all version documents in a release.
|
|
393
|
+
* @beta
|
|
394
|
+
*/
|
|
395
|
+
export interface PublishReleaseAction extends ReleaseHandle {
|
|
396
|
+
type: 'release.publish'
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Schedules a release to be published at the given UTC time. Locks the
|
|
401
|
+
* version documents server-side until the release is unscheduled or published.
|
|
402
|
+
* @beta
|
|
403
|
+
*/
|
|
404
|
+
export interface ScheduleReleaseAction extends ReleaseHandle {
|
|
405
|
+
type: 'release.schedule'
|
|
406
|
+
publishAt: string
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Unschedules a release that was previously scheduled, returning it to the
|
|
411
|
+
* active editable state.
|
|
412
|
+
* @beta
|
|
413
|
+
*/
|
|
414
|
+
export interface UnscheduleReleaseAction extends ReleaseHandle {
|
|
415
|
+
type: 'release.unschedule'
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Archives an active release. Version documents within the release are
|
|
420
|
+
* removed and no longer queryable, though still recoverable through history
|
|
421
|
+
* during the retention period.
|
|
422
|
+
* @beta
|
|
423
|
+
*/
|
|
424
|
+
export interface ArchiveReleaseAction extends ReleaseHandle {
|
|
425
|
+
type: 'release.archive'
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Restores an archived release. Only possible during the retention period.
|
|
430
|
+
* @beta
|
|
431
|
+
*/
|
|
432
|
+
export interface UnarchiveReleaseAction extends ReleaseHandle {
|
|
433
|
+
type: 'release.unarchive'
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Permanently deletes an archived or published release. To remove an active
|
|
438
|
+
* release, use the archive action first.
|
|
439
|
+
* @beta
|
|
440
|
+
*/
|
|
441
|
+
export interface DeleteReleaseAction extends ReleaseHandle {
|
|
442
|
+
type: 'release.delete'
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Union of all release actions that can be dispatched alongside document
|
|
447
|
+
* actions through `applyDocumentActions`.
|
|
448
|
+
* @beta
|
|
449
|
+
*/
|
|
450
|
+
export type ReleaseAction =
|
|
451
|
+
| CreateReleaseAction
|
|
452
|
+
| EditReleaseAction
|
|
453
|
+
| PublishReleaseAction
|
|
454
|
+
| ScheduleReleaseAction
|
|
455
|
+
| UnscheduleReleaseAction
|
|
456
|
+
| ArchiveReleaseAction
|
|
457
|
+
| UnarchiveReleaseAction
|
|
458
|
+
| DeleteReleaseAction
|
|
459
|
+
|
|
460
|
+
/** @beta */
|
|
461
|
+
export function createRelease(
|
|
462
|
+
handle: ReleaseHandle,
|
|
463
|
+
metadata: ReleaseDocument['metadata'] = {releaseType: 'undecided'},
|
|
464
|
+
): CreateReleaseAction {
|
|
465
|
+
return {type: 'release.create', ...handle, metadata}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/** @beta */
|
|
469
|
+
export function editRelease(handle: ReleaseHandle, patch: PatchOperations): EditReleaseAction {
|
|
470
|
+
return {type: 'release.edit', ...handle, patch}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/** @beta */
|
|
474
|
+
export function publishRelease(handle: ReleaseHandle): PublishReleaseAction {
|
|
475
|
+
return {type: 'release.publish', ...handle}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/** @beta */
|
|
479
|
+
export function scheduleRelease(handle: ReleaseHandle, publishAt: string): ScheduleReleaseAction {
|
|
480
|
+
return {type: 'release.schedule', ...handle, publishAt}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/** @beta */
|
|
484
|
+
export function unscheduleRelease(handle: ReleaseHandle): UnscheduleReleaseAction {
|
|
485
|
+
return {type: 'release.unschedule', ...handle}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/** @beta */
|
|
489
|
+
export function archiveRelease(handle: ReleaseHandle): ArchiveReleaseAction {
|
|
490
|
+
return {type: 'release.archive', ...handle}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/** @beta */
|
|
494
|
+
export function unarchiveRelease(handle: ReleaseHandle): UnarchiveReleaseAction {
|
|
495
|
+
return {type: 'release.unarchive', ...handle}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/** @beta */
|
|
499
|
+
export function deleteRelease(handle: ReleaseHandle): DeleteReleaseAction {
|
|
500
|
+
return {type: 'release.delete', ...handle}
|
|
501
|
+
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
// applyDocumentActions.test.ts
|
|
2
1
|
import {type SanityDocument} from '@sanity/types'
|
|
3
2
|
import {Subject} from 'rxjs'
|
|
4
3
|
import {describe, expect, it} from 'vitest'
|
|
5
4
|
|
|
6
5
|
import {bindActionByResource} from '../store/createActionBinder'
|
|
7
6
|
import {createSanityInstance, type SanityInstance} from '../store/createSanityInstance'
|
|
8
|
-
import {} from '../store/createStateSourceAction'
|
|
9
7
|
import {createStoreState, type StoreState} from '../store/createStoreState'
|
|
10
8
|
import {type DocumentAction} from './actions'
|
|
11
9
|
import {type DocumentStoreState} from './documentStore'
|
|
@@ -47,7 +45,7 @@ describe('applyDocumentActions', () => {
|
|
|
47
45
|
events: eventsSubject,
|
|
48
46
|
}
|
|
49
47
|
state = createStoreState(initialState)
|
|
50
|
-
instance = createSanityInstance()
|
|
48
|
+
instance = createSanityInstance({projectId: 'p', dataset: 'd'})
|
|
51
49
|
const key = {name: 'p.d', resource: {projectId: 'p', dataset: 'd'}}
|
|
52
50
|
|
|
53
51
|
vi.mocked(bindActionByResource).mockImplementation(
|
|
@@ -69,7 +67,6 @@ describe('applyDocumentActions', () => {
|
|
|
69
67
|
documentId: 'doc1',
|
|
70
68
|
documentType: 'example',
|
|
71
69
|
patches: [{set: {foo: 'bar'}}],
|
|
72
|
-
resource: {projectId: 'p', dataset: 'd'},
|
|
73
70
|
}
|
|
74
71
|
|
|
75
72
|
// Call applyDocumentActions with a fixed transactionId for reproducibility.
|
|
@@ -128,7 +125,6 @@ describe('applyDocumentActions', () => {
|
|
|
128
125
|
documentId: 'doc1',
|
|
129
126
|
documentType: 'example',
|
|
130
127
|
patches: [{set: {foo: 'error'}}],
|
|
131
|
-
resource: {projectId: 'p', dataset: 'd'},
|
|
132
128
|
}
|
|
133
129
|
|
|
134
130
|
// Call applyDocumentActions with a fixed transactionId.
|
|
@@ -150,24 +146,26 @@ describe('applyDocumentActions', () => {
|
|
|
150
146
|
await expect(applyPromise).rejects.toThrow('Simulated error')
|
|
151
147
|
})
|
|
152
148
|
|
|
153
|
-
it('uses explicit resource
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
149
|
+
it('uses the explicit resource when it does not match the instance config', async () => {
|
|
150
|
+
// The instance is configured for one resource...
|
|
151
|
+
const scopedInstance = createSanityInstance({projectId: 'child-p', dataset: 'child-d'})
|
|
152
|
+
// ...while the action refers to a different one
|
|
157
153
|
const action: DocumentAction = {
|
|
158
154
|
type: 'document.edit',
|
|
159
155
|
documentId: 'doc1',
|
|
160
156
|
documentType: 'example',
|
|
161
157
|
patches: [{set: {foo: 'childTest'}}],
|
|
162
|
-
|
|
158
|
+
projectId: 'p',
|
|
159
|
+
dataset: 'd',
|
|
163
160
|
}
|
|
164
|
-
|
|
161
|
+
// The explicit `resource` option should win over the instance's own config
|
|
162
|
+
const applyPromise = applyDocumentActions(scopedInstance, {
|
|
165
163
|
actions: [action],
|
|
166
164
|
transactionId: 'txn-child-match',
|
|
167
165
|
resource: {projectId: 'p', dataset: 'd'},
|
|
168
166
|
})
|
|
169
167
|
|
|
170
|
-
// Simulate an applied transaction
|
|
168
|
+
// Simulate an applied transaction for the explicitly-passed resource
|
|
171
169
|
const appliedTx: AppliedTransaction = {
|
|
172
170
|
transactionId: 'txn-child-match',
|
|
173
171
|
actions: [action],
|
|
@@ -198,6 +196,30 @@ describe('applyDocumentActions', () => {
|
|
|
198
196
|
const submittedResult = await result.submitted()
|
|
199
197
|
expect(submittedResult).toEqual(acceptedResult)
|
|
200
198
|
|
|
201
|
-
|
|
199
|
+
scopedInstance.dispose()
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
it('normalizes actions for the bound resource before queueing', async () => {
|
|
203
|
+
// A plain edit action with no `liveEdit` flag. Canvas forces liveEdit, so
|
|
204
|
+
// the queued action should come back with `liveEdit: true` — proving that
|
|
205
|
+
// `applyDocumentActions` runs `normalizeActionsForResource`.
|
|
206
|
+
const action: DocumentAction = {
|
|
207
|
+
type: 'document.edit',
|
|
208
|
+
documentId: 'doc1',
|
|
209
|
+
documentType: 'sanity.canvas.document',
|
|
210
|
+
patches: [{set: {foo: 'bar'}}],
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Don't await — we only need to inspect the synchronously-queued transaction.
|
|
214
|
+
applyDocumentActions(instance, {
|
|
215
|
+
actions: [action],
|
|
216
|
+
transactionId: 'txn-normalize',
|
|
217
|
+
resource: {canvasId: 'c'},
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
const queued = state.get().queued.find((t) => t.transactionId === 'txn-normalize')
|
|
221
|
+
expect(queued).toBeDefined()
|
|
222
|
+
const [queuedAction] = queued!.actions
|
|
223
|
+
expect(queuedAction).toMatchObject({type: 'document.edit', liveEdit: true})
|
|
202
224
|
})
|
|
203
225
|
})
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {type
|
|
2
|
-
import {type SanityDocument} from '@sanity/types'
|
|
1
|
+
import {type SanityDocument} from 'groq'
|
|
3
2
|
import {distinctUntilChanged, filter, first, firstValueFrom, map, race} from 'rxjs'
|
|
4
3
|
|
|
5
4
|
import {type DocumentResource} from '../config/sanityConfig'
|
|
6
5
|
import {bindActionByResource} from '../store/createActionBinder'
|
|
7
6
|
import {type SanityInstance} from '../store/createSanityInstance'
|
|
8
7
|
import {type StoreContext} from '../store/defineStore'
|
|
9
|
-
import {type
|
|
8
|
+
import {type Action} from './actions'
|
|
10
9
|
import {documentStore, type DocumentStoreState} from './documentStore'
|
|
10
|
+
import {type DocumentTransactionSubmissionResult} from './events'
|
|
11
11
|
import {type DocumentSet} from './processMutations'
|
|
12
12
|
import {type AppliedTransaction, type QueuedTransaction, queueTransaction} from './reducers'
|
|
13
|
+
import {normalizeActionsForResource} from './resourceRules'
|
|
13
14
|
|
|
14
15
|
/** @beta */
|
|
15
16
|
export interface ActionsResult<TDocument extends SanityDocument = SanityDocument> {
|
|
@@ -20,20 +21,21 @@ export interface ActionsResult<TDocument extends SanityDocument = SanityDocument
|
|
|
20
21
|
appeared: string[]
|
|
21
22
|
updated: string[]
|
|
22
23
|
disappeared: string[]
|
|
23
|
-
submitted: () =>
|
|
24
|
+
submitted: () => Promise<DocumentTransactionSubmissionResult>
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
/** @beta */
|
|
27
28
|
export interface ApplyDocumentActionsOptions {
|
|
28
29
|
/**
|
|
29
|
-
* List of actions to apply.
|
|
30
|
+
* List of actions to apply. Accepts both document actions and release
|
|
31
|
+
* lifecycle actions because they share the same transaction pipeline.
|
|
30
32
|
*/
|
|
31
|
-
actions:
|
|
33
|
+
actions: Action[]
|
|
32
34
|
|
|
33
35
|
/**
|
|
34
36
|
* The resource to which the documents being acted on belong.
|
|
35
37
|
*/
|
|
36
|
-
resource
|
|
38
|
+
resource?: DocumentResource
|
|
37
39
|
|
|
38
40
|
/**
|
|
39
41
|
* Optionally provide an ID to be used as this transaction ID
|
|
@@ -45,6 +47,15 @@ export interface ApplyDocumentActionsOptions {
|
|
|
45
47
|
disableBatching?: boolean
|
|
46
48
|
}
|
|
47
49
|
|
|
50
|
+
/** @beta */
|
|
51
|
+
export function applyDocumentActions<
|
|
52
|
+
TDocumentType extends string = string,
|
|
53
|
+
TDataset extends string = string,
|
|
54
|
+
TProjectId extends string = string,
|
|
55
|
+
>(
|
|
56
|
+
instance: SanityInstance,
|
|
57
|
+
options: ApplyDocumentActionsOptions,
|
|
58
|
+
): Promise<ActionsResult<SanityDocument<TDocumentType, `${TProjectId}.${TDataset}`>>>
|
|
48
59
|
/** @beta */
|
|
49
60
|
export function applyDocumentActions(
|
|
50
61
|
instance: SanityInstance,
|
|
@@ -63,13 +74,23 @@ const boundApplyDocumentActions = bindActionByResource(documentStore, _applyDocu
|
|
|
63
74
|
/** @internal */
|
|
64
75
|
async function _applyDocumentActions(
|
|
65
76
|
{state}: StoreContext<DocumentStoreState>,
|
|
66
|
-
{
|
|
77
|
+
{
|
|
78
|
+
actions,
|
|
79
|
+
resource,
|
|
80
|
+
transactionId = crypto.randomUUID(),
|
|
81
|
+
disableBatching,
|
|
82
|
+
}: ApplyDocumentActionsOptions,
|
|
67
83
|
): Promise<ActionsResult> {
|
|
68
84
|
const {events} = state.get()
|
|
69
85
|
|
|
86
|
+
// Rewrite edit actions to match the bound resource's editing model (e.g.
|
|
87
|
+
// forcing liveEdit for Canvas, stripping unsupported release perspectives).
|
|
88
|
+
// Non-edit and release actions pass through unchanged.
|
|
89
|
+
const normalizedActions = normalizeActionsForResource(actions, resource)
|
|
90
|
+
|
|
70
91
|
const transaction: QueuedTransaction = {
|
|
71
92
|
transactionId,
|
|
72
|
-
actions,
|
|
93
|
+
actions: normalizedActions,
|
|
73
94
|
...(disableBatching && {disableBatching}),
|
|
74
95
|
}
|
|
75
96
|
|
|
@@ -8,3 +8,18 @@
|
|
|
8
8
|
export const DOCUMENT_STATE_CLEAR_DELAY = 1000
|
|
9
9
|
export const INITIAL_OUTGOING_THROTTLE_TIME = 1000
|
|
10
10
|
export const API_VERSION = 'v2025-05-06'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Base delay (ms) before retrying a document listener after an `OutOfSyncError`.
|
|
14
|
+
* Backoff doubles on each successive retry, capped at {@link OUT_OF_SYNC_RETRY_MAX_DELAY}.
|
|
15
|
+
*/
|
|
16
|
+
export const OUT_OF_SYNC_RETRY_BASE_DELAY = 500
|
|
17
|
+
export const OUT_OF_SYNC_RETRY_MAX_DELAY = 10_000
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Base delay (ms) before retrying the dataset ACL fetch after a transient
|
|
21
|
+
* failure (a network error or 5xx response). Backoff doubles on each
|
|
22
|
+
* successive retry, capped at {@link ACL_RETRY_MAX_DELAY}.
|
|
23
|
+
*/
|
|
24
|
+
export const ACL_RETRY_BASE_DELAY = 500
|
|
25
|
+
export const ACL_RETRY_MAX_DELAY = 10_000
|