d25d482dc2
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
237 lines
7.0 KiB
TypeScript
237 lines
7.0 KiB
TypeScript
import { UNDO_REDO_OPERATIONS } from '@sim/realtime-protocol/constants'
|
|
import { generateId } from '@sim/utils/id'
|
|
import type { Edge } from 'reactflow'
|
|
import type {
|
|
BatchAddBlocksOperation,
|
|
BatchAddEdgesOperation,
|
|
BatchMoveBlocksOperation,
|
|
BatchRemoveBlocksOperation,
|
|
BatchRemoveEdgesOperation,
|
|
BatchUpdateParentOperation,
|
|
BatchUpdateSubblocksOperation,
|
|
Operation,
|
|
OperationEntry,
|
|
} from '@/stores/undo-redo/types'
|
|
import { mergeSubblockState } from '@/stores/workflows/utils'
|
|
import type { BlockState } from '@/stores/workflows/workflow/types'
|
|
|
|
export function createOperationEntry(operation: Operation, inverse: Operation): OperationEntry {
|
|
return {
|
|
id: generateId(),
|
|
operation,
|
|
inverse,
|
|
createdAt: Date.now(),
|
|
}
|
|
}
|
|
|
|
export function createInverseOperation(operation: Operation): Operation {
|
|
switch (operation.type) {
|
|
case UNDO_REDO_OPERATIONS.BATCH_ADD_BLOCKS: {
|
|
const op = operation as BatchAddBlocksOperation
|
|
return {
|
|
...operation,
|
|
type: UNDO_REDO_OPERATIONS.BATCH_REMOVE_BLOCKS,
|
|
data: {
|
|
blockSnapshots: op.data.blockSnapshots,
|
|
edgeSnapshots: op.data.edgeSnapshots,
|
|
subBlockValues: op.data.subBlockValues,
|
|
},
|
|
} as BatchRemoveBlocksOperation
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.BATCH_REMOVE_BLOCKS: {
|
|
const op = operation as BatchRemoveBlocksOperation
|
|
return {
|
|
...operation,
|
|
type: UNDO_REDO_OPERATIONS.BATCH_ADD_BLOCKS,
|
|
data: {
|
|
blockSnapshots: op.data.blockSnapshots,
|
|
edgeSnapshots: op.data.edgeSnapshots,
|
|
subBlockValues: op.data.subBlockValues,
|
|
},
|
|
} as BatchAddBlocksOperation
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.BATCH_ADD_EDGES: {
|
|
const op = operation as BatchAddEdgesOperation
|
|
return {
|
|
...operation,
|
|
type: UNDO_REDO_OPERATIONS.BATCH_REMOVE_EDGES,
|
|
data: {
|
|
edgeSnapshots: op.data.edgeSnapshots,
|
|
},
|
|
} as BatchRemoveEdgesOperation
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.BATCH_REMOVE_EDGES: {
|
|
const op = operation as BatchRemoveEdgesOperation
|
|
return {
|
|
...operation,
|
|
type: UNDO_REDO_OPERATIONS.BATCH_ADD_EDGES,
|
|
data: {
|
|
edgeSnapshots: op.data.edgeSnapshots,
|
|
},
|
|
} as BatchAddEdgesOperation
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.BATCH_MOVE_BLOCKS: {
|
|
const op = operation as BatchMoveBlocksOperation
|
|
return {
|
|
...operation,
|
|
type: UNDO_REDO_OPERATIONS.BATCH_MOVE_BLOCKS,
|
|
data: {
|
|
moves: op.data.moves.map((m) => ({
|
|
blockId: m.blockId,
|
|
before: m.after,
|
|
after: m.before,
|
|
})),
|
|
},
|
|
} as BatchMoveBlocksOperation
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.UPDATE_PARENT:
|
|
return {
|
|
...operation,
|
|
data: {
|
|
blockId: operation.data.blockId,
|
|
oldParentId: operation.data.newParentId,
|
|
newParentId: operation.data.oldParentId,
|
|
oldPosition: operation.data.newPosition,
|
|
newPosition: operation.data.oldPosition,
|
|
affectedEdges: operation.data.affectedEdges,
|
|
},
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.BATCH_UPDATE_PARENT: {
|
|
const op = operation as BatchUpdateParentOperation
|
|
return {
|
|
...operation,
|
|
data: {
|
|
updates: op.data.updates.map((u) => ({
|
|
blockId: u.blockId,
|
|
oldParentId: u.newParentId,
|
|
newParentId: u.oldParentId,
|
|
oldPosition: u.newPosition,
|
|
newPosition: u.oldPosition,
|
|
affectedEdges: u.affectedEdges,
|
|
})),
|
|
},
|
|
} as BatchUpdateParentOperation
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.APPLY_DIFF:
|
|
return {
|
|
...operation,
|
|
data: {
|
|
baselineSnapshot: operation.data.proposedState,
|
|
proposedState: operation.data.baselineSnapshot,
|
|
diffAnalysis: operation.data.diffAnalysis,
|
|
},
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.ACCEPT_DIFF:
|
|
return {
|
|
...operation,
|
|
data: {
|
|
beforeAccept: operation.data.afterAccept,
|
|
afterAccept: operation.data.beforeAccept,
|
|
diffAnalysis: operation.data.diffAnalysis,
|
|
baselineSnapshot: operation.data.baselineSnapshot,
|
|
},
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.REJECT_DIFF:
|
|
return {
|
|
...operation,
|
|
data: {
|
|
beforeReject: operation.data.afterReject,
|
|
afterReject: operation.data.beforeReject,
|
|
diffAnalysis: operation.data.diffAnalysis,
|
|
baselineSnapshot: operation.data.baselineSnapshot,
|
|
},
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.BATCH_TOGGLE_ENABLED:
|
|
return {
|
|
...operation,
|
|
data: {
|
|
blockIds: operation.data.blockIds,
|
|
previousStates: operation.data.previousStates,
|
|
},
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.BATCH_TOGGLE_HANDLES:
|
|
return {
|
|
...operation,
|
|
data: {
|
|
blockIds: operation.data.blockIds,
|
|
previousStates: operation.data.previousStates,
|
|
},
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.BATCH_TOGGLE_LOCKED:
|
|
return {
|
|
...operation,
|
|
data: {
|
|
blockIds: operation.data.blockIds,
|
|
previousStates: operation.data.previousStates,
|
|
},
|
|
}
|
|
|
|
case UNDO_REDO_OPERATIONS.BATCH_UPDATE_SUBBLOCKS: {
|
|
const op = operation as BatchUpdateSubblocksOperation
|
|
return {
|
|
...operation,
|
|
data: {
|
|
updates: op.data.updates.map((update) => ({
|
|
blockId: update.blockId,
|
|
subBlockId: update.subBlockId,
|
|
before: update.after,
|
|
after: update.before,
|
|
})),
|
|
subflowUpdates: op.data.subflowUpdates?.map((update) => ({
|
|
blockId: update.blockId,
|
|
blockType: update.blockType,
|
|
fieldId: update.fieldId,
|
|
before: update.after,
|
|
after: update.before,
|
|
})),
|
|
},
|
|
} as BatchUpdateSubblocksOperation
|
|
}
|
|
|
|
default: {
|
|
const exhaustiveCheck: never = operation
|
|
throw new Error(`Unhandled operation type: ${(exhaustiveCheck as Operation).type}`)
|
|
}
|
|
}
|
|
}
|
|
|
|
export function captureLatestEdges(edges: Edge[], blockIds: string[]): Edge[] {
|
|
return edges.filter((e) => blockIds.includes(e.source) || blockIds.includes(e.target))
|
|
}
|
|
|
|
export function captureLatestSubBlockValues(
|
|
blocks: Record<string, BlockState>,
|
|
workflowId: string,
|
|
blockIds: string[]
|
|
): Record<string, Record<string, unknown>> {
|
|
const values: Record<string, Record<string, unknown>> = {}
|
|
blockIds.forEach((blockId) => {
|
|
const merged = mergeSubblockState(blocks, workflowId, blockId)
|
|
const block = merged[blockId]
|
|
if (block?.subBlocks) {
|
|
const blockValues: Record<string, unknown> = {}
|
|
Object.entries(block.subBlocks).forEach(([subBlockId, subBlock]) => {
|
|
if (subBlock.value !== null && subBlock.value !== undefined) {
|
|
blockValues[subBlockId] = subBlock.value
|
|
}
|
|
})
|
|
if (Object.keys(blockValues).length > 0) {
|
|
values[blockId] = blockValues
|
|
}
|
|
}
|
|
})
|
|
return values
|
|
}
|