@@ -17,11 +17,7 @@ import type { ConfiguredIntegrationDescriptor, ProviderAuthenticationSession } f
1717interface StoredSession {
1818 id : string ;
1919 accessToken : string ;
20- account ?: {
21- label ?: string ;
22- displayName ?: string ;
23- id : string ;
24- } ;
20+ account ?: { label ?: string ; displayName ?: string ; id : string } ;
2521 scopes : string [ ] ;
2622 cloud ?: boolean ;
2723 expiresAt ?: string ;
@@ -30,7 +26,8 @@ interface StoredSession {
3026}
3127
3228export interface ConfiguredIntegrationsChangeEvent {
33- ids : IntegrationIds [ ] ;
29+ readonly added : readonly IntegrationIds [ ] ;
30+ readonly removed : readonly IntegrationIds [ ] ;
3431}
3532
3633export class ConfiguredIntegrationService implements Disposable {
@@ -171,7 +168,7 @@ export class ConfiguredIntegrationService implements Disposable {
171168 await this . container . storage . store ( 'integrations:configured' , configured ) ;
172169 }
173170
174- private async addConfigured ( descriptor : ConfiguredIntegrationDescriptor ) : Promise < void > {
171+ private async addOrUpdateConfigured ( descriptor : ConfiguredIntegrationDescriptor ) : Promise < void > {
175172 const descriptors = this . configured . get ( descriptor . integrationId ) ?? [ ] ;
176173 const existing = descriptors . find (
177174 d =>
@@ -180,39 +177,57 @@ export class ConfiguredIntegrationService implements Disposable {
180177 d . cloud === descriptor . cloud ,
181178 ) ;
182179
180+ let changed = false ;
183181 if ( existing != null ) {
184182 if ( existing . expiresAt === descriptor . expiresAt && existing . scopes === descriptor . scopes ) {
185183 return ;
186184 }
187185
188- //remove the existing descriptor from the array
189- const index = descriptors . indexOf ( existing ) ;
190- descriptors . splice ( index , 1 ) ;
186+ // Only fire the change event if the scopes changes (i.e. ignore any expiresAt changes)
187+ changed = existing . scopes !== descriptor . scopes ;
188+
189+ // remove the existing descriptor from the array
190+ descriptors . splice ( descriptors . indexOf ( existing ) , 1 ) ;
191+ } else {
192+ changed = true ;
191193 }
192194
193195 descriptors . push ( descriptor ) ;
194196 this . configured . set ( descriptor . integrationId , descriptors ) ;
195- this . queueDidChange ( descriptor . integrationId ) ;
197+
198+ if ( changed ) {
199+ this . fireChange ( descriptor . integrationId ) ;
200+ }
196201 await this . storeConfigured ( ) ;
197202 }
198203
199- private async removeConfigured ( id : IntegrationIds , options ?: { cloud ?: boolean ; domain ?: string } ) : Promise < void > {
200- const descriptors = this . configured
201- . get ( id )
202- ?. filter ( d =>
203- options ?. cloud === true
204- ? ! ( d . cloud === true && d . domain === options ?. domain )
205- : options ?. cloud === false
206- ? ! ( d . cloud === false && d . domain === options ?. domain )
207- : d . domain !== options ?. domain ,
208- ) ;
209-
210- if ( descriptors != null && descriptors . length === 0 ) {
211- this . configured . delete ( id ) ;
204+ private async removeConfigured (
205+ id : IntegrationIds ,
206+ options : { cloud : boolean | undefined ; domain : string | undefined } ,
207+ ) : Promise < void > {
208+ let changed = false ;
209+ const descriptors = [ ] ;
210+
211+ for ( const d of this . configured . get ( id ) ?? [ ] ) {
212+ if (
213+ d . domain === options . domain &&
214+ ( options ?. cloud == null ||
215+ ( options ?. cloud === true && d . cloud === true ) ||
216+ ( options ?. cloud === false && d . cloud === false ) )
217+ ) {
218+ changed = true ;
219+ continue ;
220+ }
221+
222+ descriptors . push ( d ) ;
223+ }
224+
225+ this . configured . set ( id , descriptors ) ;
226+
227+ if ( changed ) {
228+ this . fireChange ( undefined , id ) ;
212229 }
213230
214- this . configured . set ( id , descriptors ?? [ ] ) ;
215- this . queueDidChange ( id ) ;
216231 await this . storeConfigured ( ) ;
217232 }
218233
@@ -300,7 +315,7 @@ export class ConfiguredIntegrationService implements Disposable {
300315 JSON . stringify ( session ) ,
301316 ) ;
302317
303- await this . addConfigured ( {
318+ await this . addOrUpdateConfigured ( {
304319 integrationId : id ,
305320 domain : isSelfHostedIntegrationId ( id ) ? session . domain : undefined ,
306321 expiresAt : session . expiresAt ,
@@ -327,7 +342,7 @@ export class ConfiguredIntegrationService implements Disposable {
327342 configured . length === 0 ||
328343 ! configured . some ( c => c . domain === domain && c . integrationId === id )
329344 ) {
330- await this . addConfigured ( {
345+ await this . addOrUpdateConfigured ( {
331346 integrationId : id ,
332347 domain : domain ,
333348 expiresAt : storedSession . expiresAt ,
@@ -373,16 +388,26 @@ export class ConfiguredIntegrationService implements Disposable {
373388 return descriptor . domain ;
374389 }
375390
376- private changedIds = new Set < IntegrationIds > ( ) ;
377- private debouncedFireDidChange ?: ( ) => void ;
378- private queueDidChange ( id : IntegrationIds ) {
379- this . debouncedFireDidChange ??= debounce ( ( ) => {
380- this . _onDidChange . fire ( { ids : [ ...this . changedIds ] } ) ;
381- this . changedIds . clear ( ) ;
382- } , 300 ) ;
383-
384- this . changedIds . add ( id ) ;
385- this . debouncedFireDidChange ( ) ;
391+ private _addedIds = new Set < IntegrationIds > ( ) ;
392+ private _removedIds = new Set < IntegrationIds > ( ) ;
393+ private _fireChangeDebounced ?: ( ) => void ;
394+ private fireChange ( added ?: IntegrationIds , removed ?: IntegrationIds ) {
395+ this . _fireChangeDebounced ??= debounce ( ( ) => {
396+ const added = [ ...this . _addedIds ] ;
397+ this . _addedIds . clear ( ) ;
398+ const removed = [ ...this . _removedIds ] ;
399+ this . _removedIds . clear ( ) ;
400+
401+ this . _onDidChange . fire ( { added : added , removed : removed } ) ;
402+ } , 250 ) ;
403+
404+ if ( added != null ) {
405+ this . _addedIds . add ( added ) ;
406+ }
407+ if ( removed != null ) {
408+ this . _removedIds . add ( removed ) ;
409+ }
410+ this . _fireChangeDebounced ( ) ;
386411 }
387412}
388413
0 commit comments