@@ -26,6 +26,7 @@ import {
2626import { randomFloat } from '@sim/utils/random'
2727import { loadWorkflowFromNormalizedTablesRaw } from '@sim/workflow-persistence/load'
2828import { mergeSubBlockValues } from '@sim/workflow-persistence/subblocks'
29+ import type { DbOrTx } from '@sim/workflow-persistence/types'
2930import {
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
20172026async 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