@@ -47,6 +47,7 @@ import { useDomWidgetStore } from '@/stores/domWidgetStore'
4747import { useExecutionStore } from '@/stores/executionStore'
4848import { useExtensionStore } from '@/stores/extensionStore'
4949import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
50+ import { useNodeOutputStore } from '@/stores/imagePreviewStore'
5051import { KeyComboImpl , useKeybindingStore } from '@/stores/keybindingStore'
5152import { useModelStore } from '@/stores/modelStore'
5253import { SYSTEM_NODE_DEFS , useNodeDefStore } from '@/stores/nodeDefStore'
@@ -60,6 +61,10 @@ import type { ComfyExtension, MissingNodeType } from '@/types/comfy'
6061import { ExtensionManager } from '@/types/extensionTypes'
6162import { ColorAdjustOptions , adjustColor } from '@/utils/colorUtil'
6263import { graphToPrompt } from '@/utils/executionUtil'
64+ import {
65+ getNodeByExecutionId ,
66+ triggerCallbackOnAllNodes
67+ } from '@/utils/graphTraversalUtil'
6368import {
6469 executeWidgetsCallback ,
6570 fixLinkInputSlots ,
@@ -640,29 +645,21 @@ export class ComfyApp {
640645 } )
641646
642647 api . addEventListener ( 'executed' , ( { detail } ) => {
643- const output = this . nodeOutputs [ detail . display_node || detail . node ]
644- if ( detail . merge && output ) {
645- for ( const k in detail . output ?? { } ) {
646- const v = output [ k ]
647- if ( v instanceof Array ) {
648- output [ k ] = v . concat ( detail . output [ k ] )
649- } else {
650- output [ k ] = detail . output [ k ]
651- }
652- }
653- } else {
654- this . nodeOutputs [ detail . display_node || detail . node ] = detail . output
655- }
656- const node = this . graph . getNodeById ( detail . display_node || detail . node )
657- if ( node ) {
658- if ( node . onExecuted ) node . onExecuted ( detail . output )
648+ const nodeOutputStore = useNodeOutputStore ( )
649+ const executionId = String ( detail . display_node || detail . node )
650+
651+ nodeOutputStore . setNodeOutputsByExecutionId ( executionId , detail . output , {
652+ merge : detail . merge
653+ } )
654+
655+ const node = getNodeByExecutionId ( this . graph , executionId )
656+ if ( node && node . onExecuted ) {
657+ node . onExecuted ( detail . output )
659658 }
660659 } )
661660
662661 api . addEventListener ( 'execution_start' , ( ) => {
663- this . graph . nodes . forEach ( ( node ) => {
664- if ( node . onExecutionStart ) node . onExecutionStart ( )
665- } )
662+ triggerCallbackOnAllNodes ( this . graph , 'onExecutionStart' )
666663 } )
667664
668665 api . addEventListener ( 'execution_error' , ( { detail } ) => {
@@ -690,11 +687,13 @@ export class ComfyApp {
690687 api . addEventListener ( 'b_preview_with_metadata' , ( { detail } ) => {
691688 // Enhanced preview with explicit node context
692689 const { blob, displayNodeId } = detail
690+ const { setNodePreviewsByExecutionId, revokePreviewsByExecutionId } =
691+ useNodeOutputStore ( )
693692 // Ensure clean up if `executing` event is missed.
694- this . revokePreviews ( displayNodeId )
693+ revokePreviewsByExecutionId ( displayNodeId )
695694 const blobUrl = URL . createObjectURL ( blob )
696- // Preview cleanup is now handled in progress_state event to support multiple concurrent previews
697- this . nodePreviewImages [ displayNodeId ] = [ blobUrl ]
695+ // Preview cleanup is handled in progress_state event to support multiple concurrent previews
696+ setNodePreviewsByExecutionId ( displayNodeId , [ blobUrl ] )
698697 } )
699698
700699 api . init ( )
@@ -1673,25 +1672,13 @@ export class ComfyApp {
16731672 }
16741673 }
16751674
1676- /**
1677- * Frees memory allocated to image preview blobs for a specific node, by revoking the URLs associated with them.
1678- * @param nodeId ID of the node to revoke all preview images of
1679- */
1680- revokePreviews ( nodeId : NodeId ) {
1681- if ( ! this . nodePreviewImages [ nodeId ] ?. [ Symbol . iterator ] ) return
1682- for ( const url of this . nodePreviewImages [ nodeId ] ) {
1683- URL . revokeObjectURL ( url )
1684- }
1685- }
16861675 /**
16871676 * Clean current state
16881677 */
16891678 clean ( ) {
16901679 this . nodeOutputs = { }
1691- for ( const id of Object . keys ( this . nodePreviewImages ) ) {
1692- this . revokePreviews ( id )
1693- }
1694- this . nodePreviewImages = { }
1680+ const { revokeAllPreviews } = useNodeOutputStore ( )
1681+ revokeAllPreviews ( )
16951682 const executionStore = useExecutionStore ( )
16961683 executionStore . lastNodeErrors = null
16971684 executionStore . lastExecutionError = null
0 commit comments