@@ -248,6 +248,16 @@ export class GoogleCalendar
248248 ) : Promise < void > {
249249 const { authToken, calendarId } = options ;
250250
251+ // Check if sync is already in progress for this calendar
252+ const syncInProgress = await this . get < boolean > ( `sync_lock_${ calendarId } ` ) ;
253+ if ( syncInProgress ) {
254+ console . log ( `Sync already in progress for calendar ${ calendarId } , skipping` ) ;
255+ return ;
256+ }
257+
258+ // Set sync lock
259+ await this . set ( `sync_lock_${ calendarId } ` , true ) ;
260+
251261 // Create callback token for parent
252262 const callbackToken = await this . tools . callbacks . createFromParent (
253263 callback ,
@@ -295,8 +305,9 @@ export class GoogleCalendar
295305 await this . clear ( `calendar_watch_${ calendarId } ` ) ;
296306 }
297307
298- // Clear sync state
308+ // Clear sync state and lock
299309 await this . clear ( `sync_state_${ calendarId } ` ) ;
310+ await this . clear ( `sync_lock_${ calendarId } ` ) ;
300311 }
301312
302313 private async setupCalendarWatch (
@@ -358,7 +369,9 @@ export class GoogleCalendar
358369
359370 const state = await this . get < SyncState > ( `sync_state_${ calendarId } ` ) ;
360371 if ( ! state ) {
361- throw new Error ( "No sync state found" ) ;
372+ console . warn ( `No sync state found for calendar ${ calendarId } , sync may have been superseded` ) ;
373+ await this . clear ( `sync_lock_${ calendarId } ` ) ;
374+ return ;
362375 }
363376
364377 // Convert date strings back to Date objects after deserialization
@@ -402,6 +415,8 @@ export class GoogleCalendar
402415 if ( mode === "full" ) {
403416 await this . clear ( `sync_state_${ calendarId } ` ) ;
404417 }
418+ // Always clear lock when sync completes (no more batches)
419+ await this . clear ( `sync_lock_${ calendarId } ` ) ;
405420 }
406421 } catch ( error ) {
407422 console . error (
0 commit comments