@@ -27,6 +27,9 @@ import {
2727// Re-export for use in other modules
2828export { execDuringStreaming } ;
2929
30+ // Import mutation queue
31+ import { initMappings , flushQueue , clearQueue } from './mutationQueue' ;
32+
3033// Re-export replState as pyodideState for backwards compatibility
3134export { replState as pyodideState } ;
3235
@@ -298,14 +301,23 @@ async function runStreamingLoop(
298301export async function runStreamingSimulation (
299302 code : string ,
300303 duration : string ,
301- onUpdate ?: ( result : SimulationResult ) => void
304+ onUpdate ?: ( result : SimulationResult ) => void ,
305+ nodeVars ?: Map < string , string > ,
306+ connVars ?: Map < string , string >
302307) : Promise < SimulationResult | null > {
303308 // Ensure initialized
304309 const state = get ( replState ) ;
305310 if ( ! state . initialized ) {
306311 await initRepl ( ) ;
307312 }
308313
314+ // Initialize mutation queue mappings for this run
315+ if ( nodeVars && connVars ) {
316+ initMappings ( nodeVars , connVars ) ;
317+ } else {
318+ clearQueue ( ) ;
319+ }
320+
309321 streamingActive = true ;
310322
311323 // Update simulation state - preserve result structure for smooth transition
@@ -421,6 +433,13 @@ if 'sim' not in dir() or sim is None:
421433 raise RuntimeError("No simulation to continue. Run a simulation first.")
422434 ` ) ;
423435
436+ // Apply any pending graph mutations before continuing
437+ const mutationCode = flushQueue ( ) ;
438+ if ( mutationCode ) {
439+ await exec ( mutationCode ) ;
440+ consoleStore . info ( 'Applied graph mutations' ) ;
441+ }
442+
424443 // Start streaming generator with reset=False and optimized tickrate
425444 await exec ( generateStreamingStartCode ( durationExpr , STREAMING_TICKRATE , false ) ) ;
426445
@@ -476,6 +495,26 @@ if 'sim' not in dir() or sim is None:
476495 }
477496}
478497
498+ /**
499+ * Stage pending graph mutations into the simulation.
500+ * If streaming: injects via execDuringStreaming (applied between generator steps).
501+ * If paused: executes directly via exec.
502+ * Returns true if mutations were applied, false if nothing to stage.
503+ */
504+ export async function stageMutations ( ) : Promise < boolean > {
505+ const code = flushQueue ( ) ;
506+ if ( ! code ) return false ;
507+
508+ if ( streamingActive ) {
509+ execDuringStreaming ( code ) ;
510+ consoleStore . info ( 'Staged changes (applied during streaming)' ) ;
511+ } else {
512+ await exec ( code ) ;
513+ consoleStore . info ( 'Staged changes applied' ) ;
514+ }
515+ return true ;
516+ }
517+
479518/**
480519 * Reset simulation state completely.
481520 * Use when loading a new model or creating a new graph.
0 commit comments