@etsoo/appscript 1.5.51 → 1.5.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -129,6 +129,11 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
129
129
  */
130
130
  get cachedUrl(): string | undefined | null;
131
131
  set cachedUrl(value: string | undefined | null);
132
+ /**
133
+ * Keep login or not
134
+ */
135
+ get keepLogin(): boolean;
136
+ set keepLogin(value: boolean);
132
137
  private _embedded;
133
138
  /**
134
139
  * Is embedded
@@ -154,6 +159,7 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
154
159
  protected passphrase: string;
155
160
  private apis;
156
161
  private tasks;
162
+ private clearInterval?;
157
163
  /**
158
164
  * Get persisted fields
159
165
  */
@@ -186,6 +192,10 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
186
192
  * Restore settings from persisted source
187
193
  */
188
194
  protected restore(): Promise<boolean>;
195
+ /**
196
+ * Dispose the application
197
+ */
198
+ dispose(): void;
189
199
  /**
190
200
  * Is valid password, override to implement custom check
191
201
  * @param password Input password
@@ -193,9 +203,8 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
193
203
  isValidPassword(password: string): boolean;
194
204
  /**
195
205
  * Persist settings to source when application exit
196
- * @param keepLogin Keep login or not
197
206
  */
198
- persist(keepLogin?: boolean): void;
207
+ persist(): void;
199
208
  /**
200
209
  * Add scheduled task
201
210
  * @param task Task, return false to stop
@@ -96,6 +96,25 @@ class CoreApp {
96
96
  set cachedUrl(value) {
97
97
  this.storage.setData(this.fields.cachedUrl, value);
98
98
  }
99
+ /**
100
+ * Keep login or not
101
+ */
102
+ get keepLogin() {
103
+ return this.storage.getData(this.fields.keepLogin) ?? false;
104
+ }
105
+ set keepLogin(value) {
106
+ const field = this.fields.headerToken;
107
+ if (!value) {
108
+ // Clear the token
109
+ this.clearCacheToken();
110
+ // Remove the token field
111
+ this.persistedFields.remove(field);
112
+ }
113
+ else if (!this.persistedFields.includes(field)) {
114
+ this.persistedFields.push(field);
115
+ }
116
+ this.storage.setData(this.fields.keepLogin, value);
117
+ }
99
118
  /**
100
119
  * Is embedded
101
120
  */
@@ -119,7 +138,7 @@ class CoreApp {
119
138
  this.fields.deviceId,
120
139
  this.fields.devicePassphrase,
121
140
  this.fields.serversideDeviceId,
122
- this.fields.headerToken
141
+ this.fields.keepLogin
123
142
  ];
124
143
  }
125
144
  /**
@@ -287,6 +306,20 @@ class CoreApp {
287
306
  }
288
307
  return false;
289
308
  }
309
+ /**
310
+ * Dispose the application
311
+ */
312
+ dispose() {
313
+ // Avoid duplicated call
314
+ if (!this._isReady)
315
+ return;
316
+ // Persist storage defined fields
317
+ this.persist();
318
+ // Clear the interval
319
+ this.clearInterval?.();
320
+ // Reset the status to false
321
+ this.isReady = false;
322
+ }
290
323
  /**
291
324
  * Is valid password, override to implement custom check
292
325
  * @param password Input password
@@ -303,29 +336,18 @@ class CoreApp {
303
336
  }
304
337
  /**
305
338
  * Persist settings to source when application exit
306
- * @param keepLogin Keep login or not
307
339
  */
308
- persist(keepLogin) {
309
- if (!keepLogin) {
310
- // Unconditional clear the cache for security
311
- this.clearCacheToken();
312
- }
340
+ persist() {
313
341
  // Devices
314
342
  const devices = this.storage.getPersistedData(this.fields.devices);
315
343
  if (devices != null) {
316
- const index = devices.indexOf(this.getDeviceId());
317
- if (index !== -1) {
318
- // Remove current device from the list
319
- devices.splice(index, 1);
344
+ if (devices.remove(this.getDeviceId()).length > 0) {
320
345
  this.storage.setPersistedData(this.fields.devices, devices);
321
346
  }
322
347
  }
323
348
  if (!this.authorized)
324
349
  return;
325
- const fields = keepLogin
326
- ? this.persistedFields
327
- : this.persistedFields.filter((f) => f !== this.fields.headerToken);
328
- this.storage.copyTo(fields);
350
+ this.storage.copyTo(this.persistedFields);
329
351
  }
330
352
  /**
331
353
  * Add scheduled task
@@ -683,6 +705,8 @@ class CoreApp {
683
705
  this.onAuthorized(authorized);
684
706
  // Everything is ready, update the state
685
707
  this.authorized = authorized;
708
+ // Persist
709
+ this.persist();
686
710
  }
687
711
  /**
688
712
  * On authorized or not callback
@@ -1532,7 +1556,7 @@ class CoreApp {
1532
1556
  * Setup tasks
1533
1557
  */
1534
1558
  setupTasks() {
1535
- shared_1.ExtendUtils.intervalFor(() => {
1559
+ this.clearInterval = shared_1.ExtendUtils.intervalFor(() => {
1536
1560
  // Exit when not authorized
1537
1561
  if (!this.authorized)
1538
1562
  return;
@@ -1590,6 +1614,8 @@ class CoreApp {
1590
1614
  * @param apiUrl Signout API URL
1591
1615
  */
1592
1616
  async signout() {
1617
+ // Clear the keep login status
1618
+ this.keepLogin = false;
1593
1619
  const token = this.getCacheToken();
1594
1620
  if (token) {
1595
1621
  const result = await new AuthApi_1.AuthApi(this).signout({
@@ -94,7 +94,7 @@ export interface RefreshTokenProps {
94
94
  /**
95
95
  * App fields
96
96
  */
97
- export declare const appFields: readonly ["headerToken", "serversideDeviceId", "deviceId", "devices", "devicePassphrase", "cachedUrl", "embedded"];
97
+ export declare const appFields: readonly ["headerToken", "serversideDeviceId", "deviceId", "devices", "devicePassphrase", "cachedUrl", "embedded", "keepLogin"];
98
98
  /**
99
99
  * Basic type template
100
100
  */
@@ -181,6 +181,10 @@ export interface IApp {
181
181
  * Cached URL
182
182
  */
183
183
  cachedUrl: string | undefined | null;
184
+ /**
185
+ * Keep login or not
186
+ */
187
+ keepLogin: boolean;
184
188
  /**
185
189
  * IP data
186
190
  */
@@ -294,6 +298,10 @@ export interface IApp {
294
298
  * @param callback Callback will be called when the IP is ready
295
299
  */
296
300
  detectIP(callback?: IDetectIPCallback): void;
301
+ /**
302
+ * Dispose the application
303
+ */
304
+ dispose(): void;
297
305
  /**
298
306
  * Download file
299
307
  * @param stream File stream
@@ -561,9 +569,8 @@ export interface IApp {
561
569
  signout(): Promise<void>;
562
570
  /**
563
571
  * Persist settings to source when application exit
564
- * @param keepLogin Keep login or not
565
572
  */
566
- persist(keepLogin?: boolean): void;
573
+ persist(): void;
567
574
  /**
568
575
  * Go to the login page
569
576
  * @param params Login parameters
@@ -11,5 +11,6 @@ exports.appFields = [
11
11
  'devices',
12
12
  'devicePassphrase',
13
13
  'cachedUrl',
14
- 'embedded'
14
+ 'embedded',
15
+ 'keepLogin'
15
16
  ];
@@ -52,9 +52,7 @@ var BusinessUtils;
52
52
  }
53
53
  });
54
54
  // Remove the default culture
55
- const index = allCultures.findIndex((a) => a.id === cultures[0].id);
56
- if (index !== -1)
57
- allCultures.splice(index, 1);
55
+ allCultures.remove((a) => a.id === cultures[0].id);
58
56
  // Sort
59
57
  allCultures.sortByProperty('id', cultures.map((c) => c.id));
60
58
  // Set back
@@ -247,12 +247,7 @@ class ShoppingCart {
247
247
  }
248
248
  else {
249
249
  ShoppingCart.clear(this.identifier, this.storage);
250
- const keys = this.keys;
251
- const index = keys.indexOf(this.identifier);
252
- if (index !== -1) {
253
- keys.splice(index, 1);
254
- this.keys = keys;
255
- }
250
+ this.keys.remove(this.identifier);
256
251
  }
257
252
  this.doChange('clear', []);
258
253
  }
@@ -129,6 +129,11 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
129
129
  */
130
130
  get cachedUrl(): string | undefined | null;
131
131
  set cachedUrl(value: string | undefined | null);
132
+ /**
133
+ * Keep login or not
134
+ */
135
+ get keepLogin(): boolean;
136
+ set keepLogin(value: boolean);
132
137
  private _embedded;
133
138
  /**
134
139
  * Is embedded
@@ -154,6 +159,7 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
154
159
  protected passphrase: string;
155
160
  private apis;
156
161
  private tasks;
162
+ private clearInterval?;
157
163
  /**
158
164
  * Get persisted fields
159
165
  */
@@ -186,6 +192,10 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
186
192
  * Restore settings from persisted source
187
193
  */
188
194
  protected restore(): Promise<boolean>;
195
+ /**
196
+ * Dispose the application
197
+ */
198
+ dispose(): void;
189
199
  /**
190
200
  * Is valid password, override to implement custom check
191
201
  * @param password Input password
@@ -193,9 +203,8 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
193
203
  isValidPassword(password: string): boolean;
194
204
  /**
195
205
  * Persist settings to source when application exit
196
- * @param keepLogin Keep login or not
197
206
  */
198
- persist(keepLogin?: boolean): void;
207
+ persist(): void;
199
208
  /**
200
209
  * Add scheduled task
201
210
  * @param task Task, return false to stop
@@ -93,6 +93,25 @@ export class CoreApp {
93
93
  set cachedUrl(value) {
94
94
  this.storage.setData(this.fields.cachedUrl, value);
95
95
  }
96
+ /**
97
+ * Keep login or not
98
+ */
99
+ get keepLogin() {
100
+ return this.storage.getData(this.fields.keepLogin) ?? false;
101
+ }
102
+ set keepLogin(value) {
103
+ const field = this.fields.headerToken;
104
+ if (!value) {
105
+ // Clear the token
106
+ this.clearCacheToken();
107
+ // Remove the token field
108
+ this.persistedFields.remove(field);
109
+ }
110
+ else if (!this.persistedFields.includes(field)) {
111
+ this.persistedFields.push(field);
112
+ }
113
+ this.storage.setData(this.fields.keepLogin, value);
114
+ }
96
115
  /**
97
116
  * Is embedded
98
117
  */
@@ -116,7 +135,7 @@ export class CoreApp {
116
135
  this.fields.deviceId,
117
136
  this.fields.devicePassphrase,
118
137
  this.fields.serversideDeviceId,
119
- this.fields.headerToken
138
+ this.fields.keepLogin
120
139
  ];
121
140
  }
122
141
  /**
@@ -284,6 +303,20 @@ export class CoreApp {
284
303
  }
285
304
  return false;
286
305
  }
306
+ /**
307
+ * Dispose the application
308
+ */
309
+ dispose() {
310
+ // Avoid duplicated call
311
+ if (!this._isReady)
312
+ return;
313
+ // Persist storage defined fields
314
+ this.persist();
315
+ // Clear the interval
316
+ this.clearInterval?.();
317
+ // Reset the status to false
318
+ this.isReady = false;
319
+ }
287
320
  /**
288
321
  * Is valid password, override to implement custom check
289
322
  * @param password Input password
@@ -300,29 +333,18 @@ export class CoreApp {
300
333
  }
301
334
  /**
302
335
  * Persist settings to source when application exit
303
- * @param keepLogin Keep login or not
304
336
  */
305
- persist(keepLogin) {
306
- if (!keepLogin) {
307
- // Unconditional clear the cache for security
308
- this.clearCacheToken();
309
- }
337
+ persist() {
310
338
  // Devices
311
339
  const devices = this.storage.getPersistedData(this.fields.devices);
312
340
  if (devices != null) {
313
- const index = devices.indexOf(this.getDeviceId());
314
- if (index !== -1) {
315
- // Remove current device from the list
316
- devices.splice(index, 1);
341
+ if (devices.remove(this.getDeviceId()).length > 0) {
317
342
  this.storage.setPersistedData(this.fields.devices, devices);
318
343
  }
319
344
  }
320
345
  if (!this.authorized)
321
346
  return;
322
- const fields = keepLogin
323
- ? this.persistedFields
324
- : this.persistedFields.filter((f) => f !== this.fields.headerToken);
325
- this.storage.copyTo(fields);
347
+ this.storage.copyTo(this.persistedFields);
326
348
  }
327
349
  /**
328
350
  * Add scheduled task
@@ -680,6 +702,8 @@ export class CoreApp {
680
702
  this.onAuthorized(authorized);
681
703
  // Everything is ready, update the state
682
704
  this.authorized = authorized;
705
+ // Persist
706
+ this.persist();
683
707
  }
684
708
  /**
685
709
  * On authorized or not callback
@@ -1529,7 +1553,7 @@ export class CoreApp {
1529
1553
  * Setup tasks
1530
1554
  */
1531
1555
  setupTasks() {
1532
- ExtendUtils.intervalFor(() => {
1556
+ this.clearInterval = ExtendUtils.intervalFor(() => {
1533
1557
  // Exit when not authorized
1534
1558
  if (!this.authorized)
1535
1559
  return;
@@ -1587,6 +1611,8 @@ export class CoreApp {
1587
1611
  * @param apiUrl Signout API URL
1588
1612
  */
1589
1613
  async signout() {
1614
+ // Clear the keep login status
1615
+ this.keepLogin = false;
1590
1616
  const token = this.getCacheToken();
1591
1617
  if (token) {
1592
1618
  const result = await new AuthApi(this).signout({
@@ -94,7 +94,7 @@ export interface RefreshTokenProps {
94
94
  /**
95
95
  * App fields
96
96
  */
97
- export declare const appFields: readonly ["headerToken", "serversideDeviceId", "deviceId", "devices", "devicePassphrase", "cachedUrl", "embedded"];
97
+ export declare const appFields: readonly ["headerToken", "serversideDeviceId", "deviceId", "devices", "devicePassphrase", "cachedUrl", "embedded", "keepLogin"];
98
98
  /**
99
99
  * Basic type template
100
100
  */
@@ -181,6 +181,10 @@ export interface IApp {
181
181
  * Cached URL
182
182
  */
183
183
  cachedUrl: string | undefined | null;
184
+ /**
185
+ * Keep login or not
186
+ */
187
+ keepLogin: boolean;
184
188
  /**
185
189
  * IP data
186
190
  */
@@ -294,6 +298,10 @@ export interface IApp {
294
298
  * @param callback Callback will be called when the IP is ready
295
299
  */
296
300
  detectIP(callback?: IDetectIPCallback): void;
301
+ /**
302
+ * Dispose the application
303
+ */
304
+ dispose(): void;
297
305
  /**
298
306
  * Download file
299
307
  * @param stream File stream
@@ -561,9 +569,8 @@ export interface IApp {
561
569
  signout(): Promise<void>;
562
570
  /**
563
571
  * Persist settings to source when application exit
564
- * @param keepLogin Keep login or not
565
572
  */
566
- persist(keepLogin?: boolean): void;
573
+ persist(): void;
567
574
  /**
568
575
  * Go to the login page
569
576
  * @param params Login parameters
@@ -8,5 +8,6 @@ export const appFields = [
8
8
  'devices',
9
9
  'devicePassphrase',
10
10
  'cachedUrl',
11
- 'embedded'
11
+ 'embedded',
12
+ 'keepLogin'
12
13
  ];
@@ -49,9 +49,7 @@ export var BusinessUtils;
49
49
  }
50
50
  });
51
51
  // Remove the default culture
52
- const index = allCultures.findIndex((a) => a.id === cultures[0].id);
53
- if (index !== -1)
54
- allCultures.splice(index, 1);
52
+ allCultures.remove((a) => a.id === cultures[0].id);
55
53
  // Sort
56
54
  allCultures.sortByProperty('id', cultures.map((c) => c.id));
57
55
  // Set back
@@ -244,12 +244,7 @@ export class ShoppingCart {
244
244
  }
245
245
  else {
246
246
  ShoppingCart.clear(this.identifier, this.storage);
247
- const keys = this.keys;
248
- const index = keys.indexOf(this.identifier);
249
- if (index !== -1) {
250
- keys.splice(index, 1);
251
- this.keys = keys;
252
- }
247
+ this.keys.remove(this.identifier);
253
248
  }
254
249
  this.doChange('clear', []);
255
250
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/appscript",
3
- "version": "1.5.51",
3
+ "version": "1.5.53",
4
4
  "description": "Applications shared TypeScript framework",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -52,9 +52,9 @@
52
52
  },
53
53
  "homepage": "https://github.com/ETSOO/AppScript#readme",
54
54
  "dependencies": {
55
- "@etsoo/notificationbase": "^1.1.50",
56
- "@etsoo/restclient": "^1.1.12",
57
- "@etsoo/shared": "^1.2.49",
55
+ "@etsoo/notificationbase": "^1.1.52",
56
+ "@etsoo/restclient": "^1.1.14",
57
+ "@etsoo/shared": "^1.2.51",
58
58
  "crypto-js": "^4.2.0"
59
59
  },
60
60
  "devDependencies": {
@@ -249,6 +249,26 @@ export abstract class CoreApp<
249
249
  this.storage.setData(this.fields.cachedUrl, value);
250
250
  }
251
251
 
252
+ /**
253
+ * Keep login or not
254
+ */
255
+ get keepLogin() {
256
+ return this.storage.getData<boolean>(this.fields.keepLogin) ?? false;
257
+ }
258
+ set keepLogin(value: boolean) {
259
+ const field = this.fields.headerToken;
260
+ if (!value) {
261
+ // Clear the token
262
+ this.clearCacheToken();
263
+
264
+ // Remove the token field
265
+ this.persistedFields.remove(field);
266
+ } else if (!this.persistedFields.includes(field)) {
267
+ this.persistedFields.push(field);
268
+ }
269
+ this.storage.setData(this.fields.keepLogin, value);
270
+ }
271
+
252
272
  private _embedded: boolean;
253
273
  /**
254
274
  * Is embedded
@@ -287,6 +307,8 @@ export abstract class CoreApp<
287
307
 
288
308
  private tasks: [() => PromiseLike<void | false>, number, number][] = [];
289
309
 
310
+ private clearInterval?: () => void;
311
+
290
312
  /**
291
313
  * Get persisted fields
292
314
  */
@@ -295,7 +317,7 @@ export abstract class CoreApp<
295
317
  this.fields.deviceId,
296
318
  this.fields.devicePassphrase,
297
319
  this.fields.serversideDeviceId,
298
- this.fields.headerToken
320
+ this.fields.keepLogin
299
321
  ];
300
322
  }
301
323
 
@@ -507,6 +529,23 @@ export abstract class CoreApp<
507
529
  return false;
508
530
  }
509
531
 
532
+ /**
533
+ * Dispose the application
534
+ */
535
+ dispose() {
536
+ // Avoid duplicated call
537
+ if (!this._isReady) return;
538
+
539
+ // Persist storage defined fields
540
+ this.persist();
541
+
542
+ // Clear the interval
543
+ this.clearInterval?.();
544
+
545
+ // Reset the status to false
546
+ this.isReady = false;
547
+ }
548
+
510
549
  /**
511
550
  * Is valid password, override to implement custom check
512
551
  * @param password Input password
@@ -525,34 +564,21 @@ export abstract class CoreApp<
525
564
 
526
565
  /**
527
566
  * Persist settings to source when application exit
528
- * @param keepLogin Keep login or not
529
567
  */
530
- persist(keepLogin?: boolean) {
531
- if (!keepLogin) {
532
- // Unconditional clear the cache for security
533
- this.clearCacheToken();
534
- }
535
-
568
+ persist() {
536
569
  // Devices
537
570
  const devices = this.storage.getPersistedData<string[]>(
538
571
  this.fields.devices
539
572
  );
540
573
  if (devices != null) {
541
- const index = devices.indexOf(this.getDeviceId());
542
- if (index !== -1) {
543
- // Remove current device from the list
544
- devices.splice(index, 1);
574
+ if (devices.remove(this.getDeviceId()).length > 0) {
545
575
  this.storage.setPersistedData(this.fields.devices, devices);
546
576
  }
547
577
  }
548
578
 
549
579
  if (!this.authorized) return;
550
580
 
551
- const fields = keepLogin
552
- ? this.persistedFields
553
- : this.persistedFields.filter((f) => f !== this.fields.headerToken);
554
-
555
- this.storage.copyTo(fields);
581
+ this.storage.copyTo(this.persistedFields);
556
582
  }
557
583
 
558
584
  /**
@@ -1064,6 +1090,9 @@ export abstract class CoreApp<
1064
1090
 
1065
1091
  // Everything is ready, update the state
1066
1092
  this.authorized = authorized;
1093
+
1094
+ // Persist
1095
+ this.persist();
1067
1096
  }
1068
1097
 
1069
1098
  /**
@@ -2106,7 +2135,7 @@ export abstract class CoreApp<
2106
2135
  * Setup tasks
2107
2136
  */
2108
2137
  protected setupTasks() {
2109
- ExtendUtils.intervalFor(() => {
2138
+ this.clearInterval = ExtendUtils.intervalFor(() => {
2110
2139
  // Exit when not authorized
2111
2140
  if (!this.authorized) return;
2112
2141
 
@@ -2169,6 +2198,9 @@ export abstract class CoreApp<
2169
2198
  * @param apiUrl Signout API URL
2170
2199
  */
2171
2200
  async signout() {
2201
+ // Clear the keep login status
2202
+ this.keepLogin = false;
2203
+
2172
2204
  const token = this.getCacheToken();
2173
2205
  if (token) {
2174
2206
  const result = await new AuthApi(this).signout(
package/src/app/IApp.ts CHANGED
@@ -133,7 +133,8 @@ export const appFields = [
133
133
  'devices',
134
134
  'devicePassphrase',
135
135
  'cachedUrl',
136
- 'embedded'
136
+ 'embedded',
137
+ 'keepLogin'
137
138
  ] as const;
138
139
 
139
140
  /**
@@ -240,6 +241,11 @@ export interface IApp {
240
241
  */
241
242
  cachedUrl: string | undefined | null;
242
243
 
244
+ /**
245
+ * Keep login or not
246
+ */
247
+ keepLogin: boolean;
248
+
243
249
  /**
244
250
  * IP data
245
251
  */
@@ -391,6 +397,11 @@ export interface IApp {
391
397
  */
392
398
  detectIP(callback?: IDetectIPCallback): void;
393
399
 
400
+ /**
401
+ * Dispose the application
402
+ */
403
+ dispose(): void;
404
+
394
405
  /**
395
406
  * Download file
396
407
  * @param stream File stream
@@ -758,9 +769,8 @@ export interface IApp {
758
769
 
759
770
  /**
760
771
  * Persist settings to source when application exit
761
- * @param keepLogin Keep login or not
762
772
  */
763
- persist(keepLogin?: boolean): void;
773
+ persist(): void;
764
774
 
765
775
  /**
766
776
  * Go to the login page
@@ -62,9 +62,7 @@ export namespace BusinessUtils {
62
62
  });
63
63
 
64
64
  // Remove the default culture
65
- const index = allCultures.findIndex((a) => a.id === cultures[0].id);
66
- if (index !== -1) allCultures.splice(index, 1);
67
-
65
+ allCultures.remove((a) => a.id === cultures[0].id);
68
66
  // Sort
69
67
  allCultures.sortByProperty(
70
68
  'id',
@@ -475,13 +475,7 @@ export class ShoppingCart<T extends ShoppingCartItem> {
475
475
  this.save();
476
476
  } else {
477
477
  ShoppingCart.clear(this.identifier, this.storage);
478
-
479
- const keys = this.keys;
480
- const index = keys.indexOf(this.identifier);
481
- if (index !== -1) {
482
- keys.splice(index, 1);
483
- this.keys = keys;
484
- }
478
+ this.keys.remove(this.identifier);
485
479
  }
486
480
 
487
481
  this.doChange('clear', []);