@@ -20,6 +20,7 @@ import {
2020 type ReplaySendResult ,
2121 TransportVersion ,
2222} from "@/types/index.js" ;
23+ import { bufferAsyncIterable } from "@/utils/asyncIterable.js" ;
2324import { handleGraphQLError } from "@/utils/errors.js" ;
2425import { isAbsent , isPresent } from "@/utils/optional.js" ;
2526import type { Version } from "@/version.js" ;
@@ -143,19 +144,20 @@ export class ReplaySDK {
143144 } ) ;
144145 }
145146
146- // Start the replay task
147- const result = await this . graphql . mutation ( LatestStartReplayTaskDocument , {
148- sessionId : sessionId as string ,
149- } ) ;
150-
151- const payload = result . startReplayTask ;
152- if ( isPresent ( payload . error ) ) {
153- handleGraphQLError ( payload . error ) ;
154- }
155- const task = new ReplayTask ( this . graphql , payload . task ! ) ;
147+ return this . waitForReplayTask ( async ( ) => {
148+ const result = await this . graphql . mutation (
149+ LatestStartReplayTaskDocument ,
150+ {
151+ sessionId : sessionId as string ,
152+ } ,
153+ ) ;
156154
157- // Wait for task to finish
158- return this . waitForReplayTask ( task ) ;
155+ const payload = result . startReplayTask ;
156+ if ( isPresent ( payload . error ) ) {
157+ handleGraphQLError ( payload . error ) ;
158+ }
159+ return new ReplayTask ( this . graphql , payload . task ! ) ;
160+ } ) ;
159161 }
160162
161163 private async sendV056 (
@@ -183,25 +185,35 @@ export class ReplaySDK {
183185 } ,
184186 } satisfies StartReplayTaskInput ;
185187
186- const result = await this . graphql . mutation ( V056StartReplayTaskDocument , {
187- sessionId : sessionId as string ,
188- input,
188+ return this . waitForReplayTask ( async ( ) => {
189+ const result = await this . graphql . mutation ( V056StartReplayTaskDocument , {
190+ sessionId : sessionId as string ,
191+ input,
192+ } ) ;
193+
194+ const payload = result . startReplayTask ;
195+ if ( isPresent ( payload . error ) ) {
196+ handleGraphQLError ( payload . error ) ;
197+ }
198+ return new ReplayTask ( this . graphql , payload . task ! ) ;
189199 } ) ;
200+ }
190201
191- const payload = result . startReplayTask ;
192- if ( isPresent ( payload . error ) ) {
193- handleGraphQLError ( payload . error ) ;
194- }
195- const task = new ReplayTask ( this . graphql , payload . task ! ) ;
202+ /**
203+ * Open the finished-task subscription before running `start`, then resolve
204+ * when the started task finishes.
205+ */
206+ private async waitForReplayTask (
207+ start : ( ) => Promise < ReplayTask > ,
208+ ) : Promise < ReplaySendResult > {
209+ const finished = bufferAsyncIterable ( this . tasks . finished ( ) ) ;
210+ const task = await start ( ) ;
196211
197- // Wait for task to finish
198- return this . waitForReplayTask ( task ) ;
199- }
212+ for await ( const result of finished ) {
213+ if ( result . task . id !== task . id ) {
214+ continue ;
215+ }
200216
201- private async waitForReplayTask ( task : ReplayTask ) : Promise < ReplaySendResult > {
202- for await ( const result of this . tasks . finished (
203- ( finished ) => finished . task . id === task . id ,
204- ) ) {
205217 const entry = await this . entries . get ( task . replayEntryId ) ;
206218 if ( isAbsent ( entry ) ) {
207219 throw new OtherUserError ( "INTERNAL" , "Replay entry not found" ) ;
0 commit comments