1
+ import { PromiseDelegate } from '@lumino/coreutils' ;
2
+
1
3
import {
2
4
ISecret ,
3
5
ISecretsConnector ,
@@ -26,6 +28,12 @@ export class SecretsManager implements ISecretsManager {
26
28
*/
27
29
constructor ( options : SecretsManager . IOptions ) {
28
30
this . _connector = options . connector ;
31
+ this . _ready = new PromiseDelegate < void > ( ) ;
32
+ this . _ready . resolve ( ) ;
33
+ }
34
+
35
+ get ready ( ) : Promise < void > {
36
+ return this . _ready . promise ;
29
37
}
30
38
31
39
/**
@@ -49,6 +57,7 @@ export class SecretsManager implements ISecretsManager {
49
57
if ( ! this . _connector . list ) {
50
58
return ;
51
59
}
60
+ await this . _ready . promise ;
52
61
return await this . _connector . list ( namespace ) ;
53
62
}
54
63
@@ -85,15 +94,15 @@ export class SecretsManager implements ISecretsManager {
85
94
// Fill the password if the input is empty and a value is fetched by the data
86
95
// connector.
87
96
input . value = secret . value ;
88
- input . dispatchEvent ( new Event ( 'change ' ) ) ;
97
+ input . dispatchEvent ( new Event ( 'input ' ) ) ;
89
98
if ( callback ) {
90
99
callback ( secret . value ) ;
91
100
}
92
101
} else if ( input . value && input . value !== secret ?. value ) {
93
102
// Otherwise save the current input value using the data connector.
94
103
this . _set ( attachedId , { namespace, id, value : input . value } ) ;
95
104
}
96
- input . addEventListener ( 'change ' , this . _onchange ) ;
105
+ input . addEventListener ( 'input ' , this . _onInput ) ;
97
106
}
98
107
99
108
/**
@@ -121,6 +130,7 @@ export class SecretsManager implements ISecretsManager {
121
130
if ( ! this . _connector . fetch ) {
122
131
return ;
123
132
}
133
+ await this . _ready . promise ;
124
134
return this . _connector . fetch ( id ) ;
125
135
}
126
136
@@ -144,20 +154,23 @@ export class SecretsManager implements ISecretsManager {
144
154
this . _connector . remove ( id ) ;
145
155
}
146
156
147
- /**
148
- * Function triggered when the input value changed.
149
- */
150
- private _onchange = ( e : Event ) : void => {
157
+ private _onInput = async ( e : Event ) : Promise < void > => {
158
+ // Wait for an hypothetic current password saving.
159
+ await this . _ready . promise ;
160
+ // Reset the ready status.
161
+ this . _ready = new PromiseDelegate < void > ( ) ;
151
162
const target = e . target as HTMLInputElement ;
152
163
const attachedId = target . dataset . secretsId ;
153
164
if ( attachedId ) {
154
165
const splitId = attachedId . split ( ':' ) ;
155
166
const namespace = splitId . shift ( ) ;
156
167
const id = splitId . join ( ':' ) ;
157
168
if ( namespace && id ) {
158
- this . _set ( attachedId , { namespace, id, value : target . value } ) ;
169
+ await this . _set ( attachedId , { namespace, id, value : target . value } ) ;
159
170
}
160
171
}
172
+ // resolve the ready status.
173
+ this . _ready . resolve ( ) ;
161
174
} ;
162
175
163
176
/**
@@ -166,13 +179,14 @@ export class SecretsManager implements ISecretsManager {
166
179
private _detach ( attachedId : string ) : void {
167
180
const input = this . _attachedInputs . get ( attachedId ) ;
168
181
if ( input ) {
169
- input . removeEventListener ( 'change ' , this . _onchange ) ;
182
+ input . removeEventListener ( 'input ' , this . _onInput ) ;
170
183
}
171
184
this . _attachedInputs . delete ( attachedId ) ;
172
185
}
173
186
174
187
private _connector : ISecretsConnector ;
175
188
private _attachedInputs = new Map < string , HTMLInputElement > ( ) ;
189
+ private _ready : PromiseDelegate < void > ;
176
190
}
177
191
178
192
namespace Private {
0 commit comments