@@ -10,6 +10,7 @@ import type {
1010 APISimStartParams ,
1111 PinReadResponse ,
1212} from './APITypes.js' ;
13+ import { PausePoint , type PausePointParams } from './PausePoint.js' ;
1314import { readVersion } from './readVersion.js' ;
1415
1516const DEFAULT_SERVER = process . env . WOKWI_CLI_SERVER ?? 'wss://wokwi.com/api/ws/beta' ;
@@ -19,10 +20,12 @@ export class APIClient {
1920 private socket : WebSocket ;
2021 private connectionAttempts = 0 ;
2122 private lastId = 0 ;
23+ private lastPausePointId = 0 ;
2224 private closed = false ;
2325 private _running = false ;
2426 private _lastNanos = 0 ;
2527 private readonly apiEvents = new EventTarget ( ) ;
28+ private readonly pausePoints = new Map < string , PausePoint > ( ) ;
2629 private readonly pendingCommands = new Map <
2730 string ,
2831 [ ( result : any ) => void , ( error : Error ) => void ]
@@ -139,9 +142,9 @@ export class APIClient {
139142 return await this . sendCommand ( 'sim:pause' ) ;
140143 }
141144
142- async simResume ( pauseAfter ?: number , { waitForBytes } : { waitForBytes ?: number [ ] } = { } ) {
145+ async simResume ( pauseAfter ?: number ) {
143146 this . _running = true ;
144- return await this . sendCommand ( 'sim:resume' , { pauseAfter, waitForBytes } ) ;
147+ return await this . sendCommand ( 'sim:resume' , { pauseAfter } ) ;
145148 }
146149
147150 async simRestart ( { pause } : { pause ?: boolean } = { } ) {
@@ -162,6 +165,15 @@ export class APIClient {
162165 } ) ;
163166 }
164167
168+ get pausedPromise ( ) {
169+ if ( ! this . _running ) {
170+ return Promise . resolve ( ) ;
171+ }
172+ return new Promise < APIEvent < any > > ( ( resolve ) => {
173+ this . listen ( 'sim:pause' , resolve , { once : true } ) ;
174+ } ) ;
175+ }
176+
165177 serialMonitorWritable ( ) {
166178 return new Writable ( {
167179 write : ( chunk , encoding , callback ) => {
@@ -196,6 +208,46 @@ export class APIClient {
196208 } ) ;
197209 }
198210
211+ async addPausePoint ( params : PausePointParams , resume = false ) {
212+ const id = `pp${ this . lastPausePointId ++ } _${ params . type } ` ;
213+ const commands = [ this . sendCommand ( 'pause-point:add' , { id, ...params } ) ] ;
214+ if ( resume && ! this . _running ) {
215+ commands . push ( this . simResume ( ) ) ;
216+ this . _running = true ;
217+ }
218+ await Promise . all ( commands ) ;
219+ const pausePoint = new PausePoint ( id , params ) ;
220+ this . pausePoints . set ( id , pausePoint ) ;
221+ return pausePoint ;
222+ }
223+
224+ async removePausePoint ( pausePoint : PausePoint ) {
225+ if ( this . pausePoints . has ( pausePoint . id ) ) {
226+ this . pausePoints . delete ( pausePoint . id ) ;
227+ await this . sendCommand ( 'pause-point:remove' , { id : pausePoint . id } ) ;
228+ return true ;
229+ }
230+ return false ;
231+ }
232+
233+ async atNanos ( nanos : number ) {
234+ const pausePoint = await this . addPausePoint ( { type : 'time-absolute' , nanos } ) ;
235+ await pausePoint . promise ;
236+ }
237+
238+ async delay ( nanos : number ) {
239+ const pausePoint = await this . addPausePoint ( { type : 'time-relative' , nanos } , true ) ;
240+ await pausePoint . promise ;
241+ }
242+
243+ async waitForSerialBytes ( bytes : number [ ] | Uint8Array ) {
244+ if ( bytes instanceof Uint8Array ) {
245+ bytes = Array . from ( bytes ) ;
246+ }
247+ const pausePoint = await this . addPausePoint ( { type : 'serial-bytes' , bytes } , true ) ;
248+ await pausePoint . promise ;
249+ }
250+
199251 async sendCommand < T = unknown > ( command : string , params ?: any ) {
200252 return await new Promise < T > ( ( resolve , reject ) => {
201253 const id = this . lastId ++ ;
@@ -251,6 +303,12 @@ export class APIClient {
251303 processEvent ( message : APIEvent ) {
252304 if ( message . event === 'sim:pause' ) {
253305 this . _running = false ;
306+ const pausePointId : string = message . payload . pausePoint ;
307+ const pausePoint = this . pausePoints . get ( pausePointId ) ;
308+ if ( pausePoint ) {
309+ pausePoint . resolve ( message . payload . pausePointInfo ) ;
310+ this . pausePoints . delete ( pausePointId ) ;
311+ }
254312 }
255313 this . _lastNanos = message . nanos ;
256314 this . apiEvents . dispatchEvent ( new CustomEvent < APIEvent > ( message . event , { detail : message } ) ) ;
0 commit comments