@@ -133,6 +133,7 @@ import {
133133 mergeAll ,
134134 Observable ,
135135 of ,
136+ pairwise ,
136137 pipe ,
137138 ReplaySubject ,
138139 BehaviorSubject ,
@@ -1510,7 +1511,7 @@ export function subscribeSelections({ onChange, g }) {
15101511 * The inner {@link Observable} for a label will complete if the label is removed from the screen.
15111512 * </p><p>
15121513 * @function labelUpdates
1513- * @param {@link GraphistryState } [g] A {@link GraphistryState} {@link Observable} or depricated , cache an object.
1514+ * @param {@link GraphistryState } [g] A {@link GraphistryState} {@link Observable} or deprecated , cache an object.
15141515 * @return {Observable<Observable<LabelEvent>> } An {@link Observable} of inner {Observables}, where each
15151516 * inner {@link Observable} represents the lifetime of a label in the visualization.
15161517 * @example
@@ -1670,6 +1671,48 @@ export function subscribeLabels({ onChange, onExit, onError, g }) {
16701671 . subscribe ( { error : onError } ) ;
16711672}
16721673
1674+ /**
1675+ * Subscribe to graph simulation completion event
1676+ * @function playUpdates
1677+ * @param {@link GraphistryState } [g] A {@link GraphistryState} {@link Observable}
1678+ * @return {Subscription } A {@link Subscription} that can be used to react to the play updates
1679+ * @example
1680+ * GraphistryJS(document.getElementById('viz'))
1681+ * .pipe(
1682+ * map(playUpdates),
1683+ * tap(() => console.log('Play completed')),
1684+ * })
1685+ * .subscribe();
1686+ */
1687+ export function playUpdates ( g ) {
1688+ if ( ! ( g . subscriptionAPIVersion >= 1 ) ) {
1689+ return throwError ( ( ) => new Error ( 'playUpdates is not available the currently embedded graphistry viz.' ) ) ;
1690+ }
1691+
1692+ const selectionPath = ".labels" ;
1693+ return ( new BehaviorSubject ( 'Initialize playUpdates stream' )
1694+ . pipe (
1695+ tap ( ( ) => {
1696+ console . debug ( 'postMessage subscription' , '@client-api.playUpdate' ) ;
1697+ g . iFrame . contentWindow . postMessage ( { type : 'graphistry-subscribe' , agent : 'graphistryjs' , path : selectionPath } , '*' ) ;
1698+ } ) ,
1699+ finalize ( ( ) => {
1700+ console . debug ( 'postMessage unsubscribe' , '@client-api.playUpdate' ) ;
1701+ g . iFrame . contentWindow . postMessage ( { type : 'graphistry-unsubscribe' , agent : 'graphistryjs' , path : selectionPath } , '*' ) ;
1702+ } ) ,
1703+ switchMap ( ( ) =>
1704+ fromEvent ( window , 'message' ) . pipe (
1705+ map ( o => o . data ) ,
1706+ filter ( o => o && o . type === 'graphistry-sub-update' && o . path === selectionPath ) ,
1707+ map ( o => o . data ) ,
1708+ pairwise ( ) ,
1709+ filter ( ( [ { simulating : prevSim } , { simulating : currSim } ] ) => prevSim && ! currSim ) ,
1710+ shareReplay ( { bufferSize : 1 , refCount : true } )
1711+ ) ,
1712+ )
1713+ ) ) ;
1714+ }
1715+
16731716class GraphistryState {
16741717
16751718 constructor ( subscriptionAPIVersion , iFrame , models , result ) {
@@ -1768,7 +1811,7 @@ function addCallbacks(obs, target) {
17681811 target . labelUpdates = labelUpdates ; // lift(obs, labelUpdates);
17691812 target . subscribeLabels = subscribeLabels ; //lift(obs, subscribeLabels);
17701813 target . selectionUpdates = selectionUpdates ; // lift(obs, selectionUpdates);
1771- target . subscribeLabels
1814+ target . playUpdates = playUpdates ;
17721815 return target ;
17731816}
17741817
0 commit comments