11import type { Edge } from 'reactflow'
22import { v4 as uuidv4 } from 'uuid'
3-
4- export function filterNewEdges ( edgesToAdd : Edge [ ] , currentEdges : Edge [ ] ) : Edge [ ] {
5- return edgesToAdd . filter ( ( edge ) => {
6- if ( edge . source === edge . target ) return false
7- return ! currentEdges . some (
8- ( e ) =>
9- e . source === edge . source &&
10- e . sourceHandle === edge . sourceHandle &&
11- e . target === edge . target &&
12- e . targetHandle === edge . targetHandle
13- )
14- } )
15- }
16-
173import { getBlockOutputs } from '@/lib/workflows/blocks/block-outputs'
4+ import { mergeSubBlockValues , mergeSubblockStateWithValues } from '@/lib/workflows/subblocks'
185import { getBlock } from '@/blocks'
196import { normalizeName } from '@/executor/constants'
207import { useSubBlockStore } from '@/stores/workflows/subblock/store'
@@ -32,6 +19,19 @@ const WEBHOOK_SUBBLOCK_FIELDS = ['webhookId', 'triggerPath']
3219
3320export { normalizeName }
3421
22+ export function filterNewEdges ( edgesToAdd : Edge [ ] , currentEdges : Edge [ ] ) : Edge [ ] {
23+ return edgesToAdd . filter ( ( edge ) => {
24+ if ( edge . source === edge . target ) return false
25+ return ! currentEdges . some (
26+ ( e ) =>
27+ e . source === edge . source &&
28+ e . sourceHandle === edge . sourceHandle &&
29+ e . target === edge . target &&
30+ e . targetHandle === edge . targetHandle
31+ )
32+ } )
33+ }
34+
3535export interface RegeneratedState {
3636 blocks : Record < string , BlockState >
3737 edges : Edge [ ]
@@ -201,27 +201,20 @@ export function prepareDuplicateBlockState(options: PrepareDuplicateBlockStateOp
201201 Object . entries ( subBlockValues ) . filter ( ( [ key ] ) => ! WEBHOOK_SUBBLOCK_FIELDS . includes ( key ) )
202202 )
203203
204- const mergedSubBlocks : Record < string , SubBlockState > = sourceBlock . subBlocks
204+ const baseSubBlocks : Record < string , SubBlockState > = sourceBlock . subBlocks
205205 ? JSON . parse ( JSON . stringify ( sourceBlock . subBlocks ) )
206206 : { }
207207
208208 WEBHOOK_SUBBLOCK_FIELDS . forEach ( ( field ) => {
209- if ( field in mergedSubBlocks ) {
210- delete mergedSubBlocks [ field ]
209+ if ( field in baseSubBlocks ) {
210+ delete baseSubBlocks [ field ]
211211 }
212212 } )
213213
214- Object . entries ( filteredSubBlockValues ) . forEach ( ( [ subblockId , value ] ) => {
215- if ( mergedSubBlocks [ subblockId ] ) {
216- mergedSubBlocks [ subblockId ] . value = value as SubBlockState [ 'value' ]
217- } else {
218- mergedSubBlocks [ subblockId ] = {
219- id : subblockId ,
220- type : 'short-input' ,
221- value : value as SubBlockState [ 'value' ] ,
222- }
223- }
224- } )
214+ const mergedSubBlocks = mergeSubBlockValues ( baseSubBlocks , filteredSubBlockValues ) as Record <
215+ string ,
216+ SubBlockState
217+ >
225218
226219 const block : BlockState = {
227220 id : newId ,
@@ -256,11 +249,16 @@ export function mergeSubblockState(
256249 workflowId ?: string ,
257250 blockId ?: string
258251) : Record < string , BlockState > {
259- const blocksToProcess = blockId ? { [ blockId ] : blocks [ blockId ] } : blocks
260252 const subBlockStore = useSubBlockStore . getState ( )
261253
262254 const workflowSubblockValues = workflowId ? subBlockStore . workflowValues [ workflowId ] || { } : { }
263255
256+ if ( workflowId ) {
257+ return mergeSubblockStateWithValues ( blocks , workflowSubblockValues , blockId )
258+ }
259+
260+ const blocksToProcess = blockId ? { [ blockId ] : blocks [ blockId ] } : blocks
261+
264262 return Object . entries ( blocksToProcess ) . reduce (
265263 ( acc , [ id , block ] ) => {
266264 if ( ! block ) {
@@ -339,9 +337,15 @@ export async function mergeSubblockStateAsync(
339337 workflowId ?: string ,
340338 blockId ?: string
341339) : Promise < Record < string , BlockState > > {
342- const blocksToProcess = blockId ? { [ blockId ] : blocks [ blockId ] } : blocks
343340 const subBlockStore = useSubBlockStore . getState ( )
344341
342+ if ( workflowId ) {
343+ const workflowValues = subBlockStore . workflowValues [ workflowId ] || { }
344+ return mergeSubblockStateWithValues ( blocks , workflowValues , blockId )
345+ }
346+
347+ const blocksToProcess = blockId ? { [ blockId ] : blocks [ blockId ] } : blocks
348+
345349 // Process blocks in parallel for better performance
346350 const processedBlockEntries = await Promise . all (
347351 Object . entries ( blocksToProcess ) . map ( async ( [ id , block ] ) => {
@@ -358,16 +362,7 @@ export async function mergeSubblockStateAsync(
358362 return null
359363 }
360364
361- let storedValue = null
362-
363- if ( workflowId ) {
364- const workflowValues = subBlockStore . workflowValues [ workflowId ]
365- if ( workflowValues ?. [ id ] ) {
366- storedValue = workflowValues [ id ] [ subBlockId ]
367- }
368- } else {
369- storedValue = subBlockStore . getValue ( id , subBlockId )
370- }
365+ const storedValue = subBlockStore . getValue ( id , subBlockId )
371366
372367 return [
373368 subBlockId ,
@@ -386,23 +381,6 @@ export async function mergeSubblockStateAsync(
386381 subBlockEntries . filter ( ( entry ) : entry is readonly [ string , SubBlockState ] => entry !== null )
387382 ) as Record < string , SubBlockState >
388383
389- // Add any values that exist in the store but aren't in the block structure
390- // This handles cases where block config has been updated but values still exist
391- // IMPORTANT: This includes runtime subblock IDs like webhookId, triggerPath, etc.
392- if ( workflowId ) {
393- const workflowValues = subBlockStore . workflowValues [ workflowId ]
394- const blockValues = workflowValues ?. [ id ] || { }
395- Object . entries ( blockValues ) . forEach ( ( [ subBlockId , value ] ) => {
396- if ( ! mergedSubBlocks [ subBlockId ] && value !== null && value !== undefined ) {
397- mergedSubBlocks [ subBlockId ] = {
398- id : subBlockId ,
399- type : 'short-input' ,
400- value : value as SubBlockState [ 'value' ] ,
401- }
402- }
403- } )
404- }
405-
406384 // Return the full block state with updated subBlocks (including orphaned values)
407385 return [
408386 id ,
0 commit comments