Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions packages/core/src/document/applyDocumentActions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ describe('applyDocumentActions', () => {
}

// Call applyDocumentActions with a fixed transactionId for reproducibility.
const applyPromise = applyDocumentActions(instance, action, {
const applyPromise = applyDocumentActions(instance, {
actions: [action],
transactionId: 'txn-success',
})

Expand Down Expand Up @@ -128,7 +129,8 @@ describe('applyDocumentActions', () => {
}

// Call applyDocumentActions with a fixed transactionId.
const applyPromise = applyDocumentActions(instance, action, {
const applyPromise = applyDocumentActions(instance, {
actions: [action],
transactionId: 'txn-error',
})

Expand Down Expand Up @@ -160,7 +162,8 @@ describe('applyDocumentActions', () => {
dataset: 'd',
}
// Call applyDocumentActions with the context using childInstance, but with action requiring parent's config
const applyPromise = applyDocumentActions(childInstance, action, {
const applyPromise = applyDocumentActions(childInstance, {
actions: [action],
transactionId: 'txn-child-match',
})

Expand Down
58 changes: 9 additions & 49 deletions packages/core/src/document/applyDocumentActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ export interface ActionsResult<TDocument extends SanityDocument = SanityDocument

/** @beta */
export interface ApplyDocumentActionsOptions {
/**
* List of actions to apply.
*/
actions: DocumentAction[]

/**
* Optionally provide an ID to be used as this transaction ID
*/
Expand All @@ -41,16 +46,12 @@ export function applyDocumentActions<
TProjectId extends string = string,
>(
instance: SanityInstance,
action:
| DocumentAction<TDocumentType, TDataset, TProjectId>
| DocumentAction<TDocumentType, TDataset, TProjectId>[],
options?: ApplyDocumentActionsOptions,
options: ApplyDocumentActionsOptions,
): Promise<ActionsResult<SanityDocument<TDocumentType, `${TProjectId}.${TDataset}`>>>
/** @beta */
export function applyDocumentActions(
instance: SanityInstance,
action: DocumentAction | DocumentAction[],
options?: ApplyDocumentActionsOptions,
options: ApplyDocumentActionsOptions,
): Promise<ActionsResult>

/** @beta */
Expand All @@ -64,50 +65,9 @@ const boundApplyDocumentActions = bindActionByDataset(documentStore, _applyDocum

/** @internal */
async function _applyDocumentActions(
{instance, state}: StoreContext<DocumentStoreState>,
actionOrActions: DocumentAction | DocumentAction[],
{transactionId = crypto.randomUUID(), disableBatching}: ApplyDocumentActionsOptions = {},
{state}: StoreContext<DocumentStoreState>,
{actions, transactionId = crypto.randomUUID(), disableBatching}: ApplyDocumentActionsOptions,
): Promise<ActionsResult> {
const actions = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions]
Copy link
Member

@ryanbonial ryanbonial Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like moving these checks to the React package, useApplyDocumentActions, would allow developers using the core package directly to pass invalid actions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don’t actually validate the actions in core, though? If you’re using core methods you must pass data which matches the TypeScript definition or bad things happen.

I’ve just dropped support for having either an array or an object in core, but I don’t think there’s much difference from that.


let projectId
let dataset
for (const action of actions) {
if (action.projectId) {
if (!projectId) projectId = action.projectId
if (action.projectId !== projectId) {
throw new Error(
`Mismatched project IDs found in actions. All actions must belong to the same project. Found "${action.projectId}" but expected "${projectId}".`,
)
}

if (action.dataset) {
if (!dataset) dataset = action.dataset
if (action.dataset !== dataset) {
throw new Error(
`Mismatched datasets found in actions. All actions must belong to the same dataset. Found "${action.dataset}" but expected "${dataset}".`,
)
}
}
}
}

if (
(projectId && projectId !== instance.config.projectId) ||
(dataset && dataset !== instance.config.dataset)
) {
const matchedInstance = instance.match({projectId, dataset})
if (!matchedInstance) {
throw new Error(
`Could not find a matching instance for projectId: "${projectId}" and dataset: "${dataset}"`,
)
}
return boundApplyDocumentActions(matchedInstance, actionOrActions, {
disableBatching,
transactionId,
})
}

const {events} = state.get()

const transaction: QueuedTransaction = {
Expand Down
Loading
Loading