@@ -152,9 +152,8 @@ export class RadialUrchin {
152152 this . historyView = null ;
153153 this . balanceHistory = [ ] ;
154154 this . isHistoryOpen = false ;
155- this . historyRunCounter = 0 ;
156155 this . maxHistoryEntries = MAX_HISTORY_ENTRIES ;
157- this . lastSnapshotSource = null ;
156+ this . lastSnapshotSignature = null ;
158157
159158 this . handleResize = this . handleResize . bind ( this ) ;
160159 this . handlePointerMove = this . handlePointerMove . bind ( this ) ;
@@ -452,7 +451,7 @@ export class RadialUrchin {
452451 this . updateHistoryUi ( ) ;
453452 }
454453
455- captureBalanceSnapshot ( schedule ) {
454+ captureBalanceSnapshot ( schedule , signature ) {
456455 if ( ! schedule || typeof schedule !== 'object' ) {
457456 return ;
458457 }
@@ -476,8 +475,7 @@ export class RadialUrchin {
476475 return ;
477476 }
478477
479- this . historyRunCounter += 1 ;
480- const runNumber = this . historyRunCounter ;
478+ const runNumber = this . balanceHistory . length + 1 ;
481479 const timestamp = this . extractScheduleTimestamp ( schedule ) ;
482480 const entry = {
483481 id : `${ runNumber } -${ Date . now ( ) } ` ,
@@ -489,14 +487,50 @@ export class RadialUrchin {
489487 segments : segments . map ( ( segment ) => ( { ...segment } ) ) ,
490488 } ;
491489
492- this . balanceHistory . unshift ( entry ) ;
493- if ( this . balanceHistory . length > this . maxHistoryEntries ) {
494- this . balanceHistory . length = this . maxHistoryEntries ;
490+ if ( signature ) {
491+ entry . signature = signature ;
495492 }
496493
494+ const nextHistory = [ entry , ...this . balanceHistory ] ;
495+ if ( nextHistory . length > this . maxHistoryEntries ) {
496+ nextHistory . length = this . maxHistoryEntries ;
497+ }
498+ this . balanceHistory = nextHistory ;
499+
497500 this . updateHistoryUi ( { refreshEntries : true } ) ;
498501 }
499502
503+ computeScheduleSignature ( schedule ) {
504+ if ( ! schedule || typeof schedule !== 'object' ) {
505+ return null ;
506+ }
507+
508+ const timestamp = this . extractScheduleTimestamp ( schedule ) ;
509+ if ( timestamp ) {
510+ return `timestamp:${ timestamp } ` ;
511+ }
512+
513+ const events = Array . isArray ( schedule . events ) ? schedule . events : [ ] ;
514+ if ( ! events . length ) {
515+ return null ;
516+ }
517+
518+ const parts = events . map ( ( event ) => {
519+ const label = event ?. label || event ?. activity || '' ;
520+ const start = typeof event ?. start === 'string' ? event . start : '' ;
521+ const end = typeof event ?. end === 'string' ? event . end : '' ;
522+ const agent =
523+ typeof event ?. agent === 'string'
524+ ? event . agent
525+ : typeof event ?. metadata ?. agent === 'string'
526+ ? event . metadata . agent
527+ : '' ;
528+ return `${ label } |${ start } |${ end } |${ agent } ` ;
529+ } ) ;
530+
531+ return `events:${ parts . join ( ';' ) } ` ;
532+ }
533+
500534 extractScheduleTimestamp ( schedule ) {
501535 if ( ! schedule || typeof schedule !== 'object' ) {
502536 return null ;
@@ -599,19 +633,20 @@ export class RadialUrchin {
599633 this . updateLegend ( ) ;
600634 this . refreshModeButtons ( ) ;
601635 this . render ( ) ;
602- this . lastSnapshotSource = null ;
636+ this . lastSnapshotSignature = null ;
603637 if ( this . isHistoryOpen ) {
604638 this . isHistoryOpen = false ;
605639 }
606640 this . updateHistoryUi ( ) ;
607641 return ;
608642 }
609643
610- if ( payload && payload !== this . lastSnapshotSource ) {
611- this . captureBalanceSnapshot ( payload ) ;
612- }
613644 if ( payload ) {
614- this . lastSnapshotSource = payload ;
645+ const snapshotSignature = this . computeScheduleSignature ( payload ) ;
646+ if ( snapshotSignature !== this . lastSnapshotSignature ) {
647+ this . captureBalanceSnapshot ( payload , snapshotSignature ) ;
648+ }
649+ this . lastSnapshotSignature = snapshotSignature ;
615650 }
616651
617652 try {
0 commit comments