@@ -8,7 +8,7 @@ import { Emitter, Event, PauseableEmitter } from 'vs/base/common/event';
8
8
import { Disposable , dispose , MutableDisposable } from 'vs/base/common/lifecycle' ;
9
9
import { mark } from 'vs/base/common/performance' ;
10
10
import { isUndefinedOrNull } from 'vs/base/common/types' ;
11
- import { InMemoryStorageDatabase , IStorage , Storage , StorageHint } from 'vs/base/parts/storage/common/storage' ;
11
+ import { InMemoryStorageDatabase , IStorage , IStorageChangeEvent , Storage , StorageHint , StorageValue } from 'vs/base/parts/storage/common/storage' ;
12
12
import { createDecorator } from 'vs/platform/instantiation/common/instantiation' ;
13
13
import { isUserDataProfile , IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile' ;
14
14
import { IAnyWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace' ;
@@ -35,6 +35,13 @@ export interface IWillSaveStateEvent {
35
35
readonly reason : WillSaveStateReason ;
36
36
}
37
37
38
+ export interface IStorageEntry {
39
+ readonly key : string ;
40
+ readonly value : StorageValue ;
41
+ readonly scope : StorageScope ;
42
+ readonly target : StorageTarget ;
43
+ }
44
+
38
45
export interface IStorageService {
39
46
40
47
readonly _serviceBrand : undefined ;
@@ -119,7 +126,16 @@ export interface IStorageService {
119
126
* @param target allows to define the target of the storage operation
120
127
* to either the current machine or user.
121
128
*/
122
- store ( key : string , value : string | boolean | number | undefined | null | object , scope : StorageScope , target : StorageTarget ) : void ;
129
+ store ( key : string , value : StorageValue , scope : StorageScope , target : StorageTarget ) : void ;
130
+
131
+ /**
132
+ * Allows to store multiple values in a bulk operation. Events will only
133
+ * be emitted when all values have been stored.
134
+ *
135
+ * @param external a hint to indicate the source of the operation is external,
136
+ * such as settings sync or profile changes.
137
+ */
138
+ storeAll ( entries : Array < IStorageEntry > , external : boolean ) : void ;
123
139
124
140
/**
125
141
* Delete an element stored under the provided key from storage.
@@ -229,6 +245,15 @@ export interface IStorageValueChangeEvent {
229
245
* removed.
230
246
*/
231
247
readonly target : StorageTarget | undefined ;
248
+
249
+ /**
250
+ * A hint how the storage change event was triggered. If
251
+ * `true`, the storage change was triggered by an external
252
+ * source, such as:
253
+ * - another process (for example another window)
254
+ * - operations such as settings sync or profiles change
255
+ */
256
+ readonly external ?: boolean ;
232
257
}
233
258
234
259
export interface IStorageTargetChangeEvent {
@@ -332,7 +357,8 @@ export abstract class AbstractStorageService extends Disposable implements IStor
332
357
return this . initializationPromise ;
333
358
}
334
359
335
- protected emitDidChangeValue ( scope : StorageScope , key : string ) : void {
360
+ protected emitDidChangeValue ( scope : StorageScope , event : IStorageChangeEvent ) : void {
361
+ const { key, external } = event ;
336
362
337
363
// Specially handle `TARGET_KEY`
338
364
if ( key === TARGET_KEY ) {
@@ -356,7 +382,7 @@ export abstract class AbstractStorageService extends Disposable implements IStor
356
382
357
383
// Emit any other key to outside
358
384
else {
359
- this . _onDidChangeValue . fire ( { scope, key, target : this . getKeyTargets ( scope ) [ key ] } ) ;
385
+ this . _onDidChangeValue . fire ( { scope, key, target : this . getKeyTargets ( scope ) [ key ] , external } ) ;
360
386
}
361
387
}
362
388
@@ -388,11 +414,19 @@ export abstract class AbstractStorageService extends Disposable implements IStor
388
414
return this . getStorage ( scope ) ?. getObject ( key , fallbackValue ) ;
389
415
}
390
416
391
- store ( key : string , value : string | boolean | number | undefined | null | object , scope : StorageScope , target : StorageTarget ) : void {
417
+ storeAll ( entries : Array < IStorageEntry > , external : boolean ) : void {
418
+ this . withPausedEmitters ( ( ) => {
419
+ for ( const entry of entries ) {
420
+ this . store ( entry . key , entry . value , entry . scope , entry . target , external ) ;
421
+ }
422
+ } ) ;
423
+ }
424
+
425
+ store ( key : string , value : StorageValue , scope : StorageScope , target : StorageTarget , external = false ) : void {
392
426
393
427
// We remove the key for undefined/null values
394
428
if ( isUndefinedOrNull ( value ) ) {
395
- this . remove ( key , scope ) ;
429
+ this . remove ( key , scope , external ) ;
396
430
return ;
397
431
}
398
432
@@ -403,11 +437,11 @@ export abstract class AbstractStorageService extends Disposable implements IStor
403
437
this . updateKeyTarget ( key , scope , target ) ;
404
438
405
439
// Store actual value
406
- this . getStorage ( scope ) ?. set ( key , value ) ;
440
+ this . getStorage ( scope ) ?. set ( key , value , external ) ;
407
441
} ) ;
408
442
}
409
443
410
- remove ( key : string , scope : StorageScope ) : void {
444
+ remove ( key : string , scope : StorageScope , external = false ) : void {
411
445
412
446
// Update our datastructures but send events only after
413
447
this . withPausedEmitters ( ( ) => {
@@ -416,7 +450,7 @@ export abstract class AbstractStorageService extends Disposable implements IStor
416
450
this . updateKeyTarget ( key , scope , undefined ) ;
417
451
418
452
// Remove actual key
419
- this . getStorage ( scope ) ?. delete ( key ) ;
453
+ this . getStorage ( scope ) ?. delete ( key , external ) ;
420
454
} ) ;
421
455
}
422
456
@@ -450,22 +484,22 @@ export abstract class AbstractStorageService extends Disposable implements IStor
450
484
return keys ;
451
485
}
452
486
453
- private updateKeyTarget ( key : string , scope : StorageScope , target : StorageTarget | undefined ) : void {
487
+ private updateKeyTarget ( key : string , scope : StorageScope , target : StorageTarget | undefined , external = false ) : void {
454
488
455
489
// Add
456
490
const keyTargets = this . getKeyTargets ( scope ) ;
457
491
if ( typeof target === 'number' ) {
458
492
if ( keyTargets [ key ] !== target ) {
459
493
keyTargets [ key ] = target ;
460
- this . getStorage ( scope ) ?. set ( TARGET_KEY , JSON . stringify ( keyTargets ) ) ;
494
+ this . getStorage ( scope ) ?. set ( TARGET_KEY , JSON . stringify ( keyTargets ) , external ) ;
461
495
}
462
496
}
463
497
464
498
// Remove
465
499
else {
466
500
if ( typeof keyTargets [ key ] === 'number' ) {
467
501
delete keyTargets [ key ] ;
468
- this . getStorage ( scope ) ?. set ( TARGET_KEY , JSON . stringify ( keyTargets ) ) ;
502
+ this . getStorage ( scope ) ?. set ( TARGET_KEY , JSON . stringify ( keyTargets ) , external ) ;
469
503
}
470
504
}
471
505
}
@@ -595,7 +629,7 @@ export abstract class AbstractStorageService extends Disposable implements IStor
595
629
// Copy over previous keys if `preserveData`
596
630
if ( preserveData ) {
597
631
for ( const [ key , value ] of oldStorage ) {
598
- newStorage . set ( key , value ) ;
632
+ newStorage . set ( key , value , true ) ;
599
633
}
600
634
}
601
635
@@ -607,13 +641,13 @@ export abstract class AbstractStorageService extends Disposable implements IStor
607
641
608
642
const newValue = newStorage . get ( key ) ;
609
643
if ( newValue !== oldValue ) {
610
- this . emitDidChangeValue ( scope , key ) ;
644
+ this . emitDidChangeValue ( scope , { key, external : true } ) ;
611
645
}
612
646
}
613
647
614
648
for ( const [ key ] of newStorage . items ) {
615
649
if ( ! handledkeys . has ( key ) ) {
616
- this . emitDidChangeValue ( scope , key ) ;
650
+ this . emitDidChangeValue ( scope , { key, external : true } ) ;
617
651
}
618
652
}
619
653
}
@@ -647,9 +681,9 @@ export class InMemoryStorageService extends AbstractStorageService {
647
681
constructor ( ) {
648
682
super ( ) ;
649
683
650
- this . _register ( this . workspaceStorage . onDidChangeStorage ( key => this . emitDidChangeValue ( StorageScope . WORKSPACE , key ) ) ) ;
651
- this . _register ( this . profileStorage . onDidChangeStorage ( key => this . emitDidChangeValue ( StorageScope . PROFILE , key ) ) ) ;
652
- this . _register ( this . applicationStorage . onDidChangeStorage ( key => this . emitDidChangeValue ( StorageScope . APPLICATION , key ) ) ) ;
684
+ this . _register ( this . workspaceStorage . onDidChangeStorage ( e => this . emitDidChangeValue ( StorageScope . WORKSPACE , e ) ) ) ;
685
+ this . _register ( this . profileStorage . onDidChangeStorage ( e => this . emitDidChangeValue ( StorageScope . PROFILE , e ) ) ) ;
686
+ this . _register ( this . applicationStorage . onDidChangeStorage ( e => this . emitDidChangeValue ( StorageScope . APPLICATION , e ) ) ) ;
653
687
}
654
688
655
689
protected getStorage ( scope : StorageScope ) : IStorage {
0 commit comments