Skip to content

Commit b46daae

Browse files
committed
improvement(realtime): share the writable-block check across subblock writes
1 parent 34fdb94 commit b46daae

1 file changed

Lines changed: 22 additions & 26 deletions

File tree

apps/realtime/src/database/operations.ts

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
import { randomFloat } from '@sim/utils/random'
2727
import { loadWorkflowFromNormalizedTablesRaw } from '@sim/workflow-persistence/load'
2828
import { mergeSubBlockValues } from '@sim/workflow-persistence/subblocks'
29+
import type { DbOrTx } from '@sim/workflow-persistence/types'
2930
import {
3031
filterAcyclicEdges,
3132
filterUniqueWorkflowEdges,
@@ -1989,18 +1990,8 @@ async function handleSubflowOperationTx(
19891990
}
19901991
}
19911992

1992-
interface SubblockUpdateBlockRecord {
1993-
id: string
1994-
subBlocks: unknown
1995-
locked: boolean
1996-
data: unknown
1997-
}
1998-
19991993
/** Every block in the workflow by id, for the locked-container check subblock writes need. */
2000-
async function loadSubblockUpdateBlocks(
2001-
tx: Pick<typeof db, 'select'>,
2002-
workflowId: string
2003-
): Promise<Record<string, SubblockUpdateBlockRecord>> {
1994+
async function loadSubblockUpdateBlocks(tx: DbOrTx, workflowId: string) {
20041995
const allBlocks = await tx
20051996
.select({
20061997
id: workflowBlocks.id,
@@ -2013,6 +2004,24 @@ async function loadSubblockUpdateBlocks(
20132004
return Object.fromEntries(allBlocks.map((block) => [block.id, block]))
20142005
}
20152006

2007+
/**
2008+
* The block a subblock write targets, rejecting one that is missing, locked, or in a locked
2009+
* container.
2010+
*/
2011+
function getWritableSubblockUpdateBlock(
2012+
blocksById: Awaited<ReturnType<typeof loadSubblockUpdateBlocks>>,
2013+
blockId: string
2014+
) {
2015+
const block = blocksById[blockId]
2016+
if (!block) {
2017+
throw new Error(`Block ${blockId} not found`)
2018+
}
2019+
if (isWorkflowBlockProtected(blockId, blocksById)) {
2020+
throw new Error(`Block ${blockId} is locked or inside a locked container`)
2021+
}
2022+
return block
2023+
}
2024+
20162025
// Subblock operations - targeted value updates without replacing workflow state
20172026
async function handleSubblockOperationTx(
20182027
tx: any,
@@ -2035,14 +2044,7 @@ async function handleSubblockOperationTx(
20352044
throw new Error('Missing required fields for subblock batch update')
20362045
}
20372046

2038-
const block = blocksById[blockId]
2039-
if (!block) {
2040-
throw new Error(`Block ${blockId} not found`)
2041-
}
2042-
2043-
if (isWorkflowBlockProtected(blockId, blocksById)) {
2044-
throw new Error(`Block ${blockId} is locked or inside a locked container`)
2045-
}
2047+
const block = getWritableSubblockUpdateBlock(blocksById, blockId)
20462048

20472049
const subBlocks = { ...((block.subBlocks as Record<string, any>) || {}) }
20482050
const currentSubBlock = subBlocks[subblockId]
@@ -2078,13 +2080,7 @@ async function handleSubblockOperationTx(
20782080
}
20792081

20802082
const blocksById = await loadSubblockUpdateBlocks(tx, workflowId)
2081-
const block = blocksById[blockId]
2082-
if (!block) {
2083-
throw new Error(`Block ${blockId} not found`)
2084-
}
2085-
if (isWorkflowBlockProtected(blockId, blocksById)) {
2086-
throw new Error(`Block ${blockId} is locked or inside a locked container`)
2087-
}
2083+
const block = getWritableSubblockUpdateBlock(blocksById, blockId)
20882084

20892085
const subBlocks = {
20902086
...((block.subBlocks as Record<string, Record<string, unknown>> | null) || {}),

0 commit comments

Comments
 (0)