• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/**
17 *
18 * AppStorage
19 *
20 * Class implements a Map of ObservableObjectBase UI state variables.
21 * AppStorage singleton is sub-class of @see LocalStorage for
22 * UI state of app-wide access and same life cycle as the app.
23 *
24 * @since 7
25 */
26
27class AppStorage extends LocalStorage {
28    /**
29    * create and initialize singleton
30    * initialzie with all properties and their values that Object.keys(params) returns
31    * Property values must not be undefined.
32    *
33    * not a public / sdk function
34    */
35    public static createSingleton(initializingPropersties?: Object): void {
36        if (!AppStorage.instance_) {
37            stateMgmtConsole.debug('Creating AppStorage instance.');
38            AppStorage.instance_ = new AppStorage(initializingPropersties);
39        } else {
40            stateMgmtConsole.error('AppStorage.createNewInstance(..): instance exists already, internal error!');
41        }
42    }
43
44
45    /**
46     * Obtain a handle or an alias to AppStorage property with given name.
47     *
48     * @param propName AppStorage property name
49     * @returns AbstractProperty object is property with given name exists
50     * undefined otherwise
51     *
52     * @since 12
53     */
54    public static ref<T>(propName: string): AbstractProperty<T> | undefined {
55        return AppStorage.getOrCreate().ref(propName);
56    }
57
58
59    /**
60     * Obtain a handle or an alias to AppStorage property with given name.
61     *
62     * If property does not exist in AppStorage, create it with given default value.
63     *
64     * @param propName LocalStorage property name
65     * @param defaultValue If property does not exist in AppStorage,
66     *        create it with given default value.
67     * @returns AbstractProperty object
68     *
69     * @since 12
70     */
71    public static setAndRef<T>(propName: string, defaultValue: T): AbstractProperty<T> {
72        return AppStorage.getOrCreate().setAndRef(propName, defaultValue);
73    }
74
75
76    /**
77    * create and return a two-way sync "(link") to named property
78    *
79    * Same as @see LocalStorage.link()
80    *
81    * @param propName name of source property in AppStorage
82    * @param linkUser IPropertySubscriber to be notified when source changes,
83    * @param subscribersName the linkUser (subscriber) uses this name for the property
84    *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
85    * @returns  SynchedPropertyTwoWay{Simple|Object| object with given LocalStoage prop as its source.
86    *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
87    *           return undefiend if named property does not already exist in AppStorage
88    *
89    * @since 10
90    */
91    public static link<T>(key: string, linkUser?: IPropertySubscriber, subscribersName?: string): SubscribedAbstractProperty<T> {
92        return AppStorage.getOrCreate().link(key, linkUser, subscribersName);
93    }
94
95    /**
96    * @see link
97    * @since 7
98    * @deprecated
99    */
100    public static Link<T>(key: string, linkUser?: IPropertySubscriber, subscribersName?: string): SubscribedAbstractProperty<T> {
101        return AppStorage.getOrCreate().link(key, linkUser, subscribersName);
102    }
103
104    /**
105    * Like @see link(), but will create and initialize a new source property in LocalStorage if missing
106    *
107    * Same as @see LocalStorage.setAndLink()
108    *
109    * @param propName name of source property in AppStorage
110    * @param defaultValue value to be used for initializing if new creating new property in AppStorage
111    *        default value must be of type S, must not be undefined or null.
112    * @param linkUser IPropertySubscriber to be notified when return 'link' changes,
113    * @param subscribersName the linkUser (subscriber) uses this name for the property
114    *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
115    * @returns SynchedPropertyTwoWay{Simple|Object| object with given LocalStoage prop as  its source.
116    *          Apps can use SDK functions of base class SubscribedAbstractProperty<S>
117    *
118    * @since 10
119    */
120    public static setAndLink<T>(key: string, defaultValue: T, linkUser?: IPropertySubscriber, subscribersName?: string): SubscribedAbstractProperty<T> {
121        return AppStorage.getOrCreate().setAndLink(key, defaultValue, linkUser, subscribersName);
122    }
123
124    /**
125    * @see setAndLink
126    * @since 7
127    * @deprecated
128    */
129    public static SetAndLink<T>(key: string, defaultValue: T, linkUser?: IPropertySubscriber, subscribersName?: string): SubscribedAbstractProperty<T> {
130        return AppStorage.getOrCreate().setAndLink(key, defaultValue, linkUser, subscribersName);
131    }
132
133    /**
134    * create and return a one-way sync ('prop') to named property
135    *
136    * Same as @see LocalStorage.prop()
137    *
138    * @param propName name of source property in AppStorage
139    * @param propUser IPropertySubscriber to be notified when source changes,
140    * @param subscribersName the linkUser (subscriber) uses this name for the property
141    *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
142    * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as  its source.
143    *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
144    *           return undefiend if named property does not already exist in AppStorage.
145    * @since 10
146    */
147    public static prop<T>(propName: string, propUser?: IPropertySubscriber, subscribersName?: string): SubscribedAbstractProperty<T> {
148        return AppStorage.getOrCreate().prop(propName, propUser, subscribersName);
149    }
150
151    /**
152    * @see prop
153    * @since 7
154    * @deprecated
155    */
156    public static Prop<T>(propName: string, propUser?: IPropertySubscriber, subscribersName?: string): SubscribedAbstractProperty<T> {
157        return AppStorage.getOrCreate().prop(propName, propUser, subscribersName);
158    }
159
160    /**
161    * Like @see prop(), will create and initialize a new source property in AppStorage if missing
162    *
163    * Same as @see LocalStorage.setAndProp()
164    *
165    * @param propName name of source property in AppStorage
166    * @param defaultValue value to be used for initializing if new creating new property in AppStorage.
167    *        default value must be of type S, must not be undefined or null.
168    * @param propUser IPropertySubscriber to be notified when returned 'prop' changes,
169    * @param subscribersName the propUser (subscriber) uses this name for the property
170    *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
171    * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as its source.
172    *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
173    *
174    * @since 10
175    */
176    public static setAndProp<S>(key: string, defaultValue: S, propUser?: IPropertySubscriber, subscribersName?: string): SubscribedAbstractProperty<S> {
177        return AppStorage.getOrCreate().setAndProp(key, defaultValue, propUser, subscribersName);
178    }
179
180    /**
181    * @see setAndProp
182    * @since 7
183    * @deprecated
184    */
185    public static SetAndProp<S>(key: string, defaultValue: S, propUser?: IPropertySubscriber, subscribersName?: string): SubscribedAbstractProperty<S> {
186        return AppStorage.getOrCreate().setAndProp(key, defaultValue, propUser, subscribersName);
187    }
188
189
190    /**
191    * Check if AppStorage has a property with given name
192    * return true if property with given name exists
193    * same as ES6 Map.prototype.has()
194    *
195    * Same as @see LocalStorage.has()
196    *
197    * @param propName searched property
198    * @returns true if property with such name exists in AppStorage
199    *
200    * @since 10
201    */
202    public static has(key: string): boolean {
203        return AppStorage.getOrCreate().has(key);
204    }
205
206    /**
207   * @see has()
208   * @since 7
209   * @deprecated
210   */
211    public static Has(key: string): boolean {
212        return AppStorage.getOrCreate().has(key);
213    }
214
215    /**
216    * Returns value of given property
217    * return undefined if no property with this name
218    *
219    * @Same as see LocalStorage.get()
220    *
221    * @param propName
222    * @returns property value if found or undefined
223    *
224    * @since 10
225    *
226    */
227    public static get<T>(key: string): T | undefined {
228        return AppStorage.getOrCreate().get(key);
229    }
230
231    /**
232    * @see get
233    * @since 7
234    * @deprecated
235    *
236    */
237    public static Get<T>(key: string): T | undefined {
238        return AppStorage.getOrCreate().get(key);
239    }
240
241    /**
242    * Set value of given property in AppStorage
243    * Method sets nothing and returns false if property with this name does not exist
244    * or if newValue is `undefined` or `null` (`undefined`, `null` value are not allowed for state variables).
245    *
246    * Same as @see LocalStorage.set
247    *
248    * @param propName
249    * @param newValue must be of type T and must not be undefined or null
250    * @returns true on success, i.e. when above conditions are satisfied, otherwise false
251    *
252    * @since 10
253    */
254    public static set<T>(key: string, newValue: T): boolean {
255        return AppStorage.getOrCreate().set(key, newValue);
256    }
257
258    /**
259    * @see set
260    * @since 7
261    * @deprecated
262    */
263    public static Set<T>(key: string, newValue: T): boolean {
264        return AppStorage.getOrCreate().set(key, newValue);
265    }
266
267    /**
268   * Set value of given property, if it exists, @see set() .
269   * Add property if no property with given name and initialize with given value.
270   * Do nothing and return false if newValuue is undefined or null
271   * (undefined, null value is not allowed for state variables)
272   *
273   * @see LocalStorage.setOrCreate()
274   *
275   * @param propName
276   * @param newValue must be of type T and must not be undefined or null
277   * @returns true on success, i.e. when above conditions are satisfied, otherwise false
278   *
279   * @since 10
280   */
281    public static setOrCreate<T>(key: string, newValue: T): void {
282        AppStorage.getOrCreate().setOrCreate(key, newValue);
283    }
284
285    /**
286    * @see setOrCreate
287    * @since 7
288    * @deprecated
289    */
290    public static SetOrCreate<T>(key: string, newValue: T): void {
291        AppStorage.getOrCreate().setOrCreate(key, newValue);
292    }
293
294
295    /**
296    * Delete property from StorageBase
297    * Use with caution:
298    * Before deleting a prop from AppStorage all its subscribers need to
299    * unsubscribe from the property.
300    * This method fails and returns false if given property still has subscribers
301    * Another reason for failing is unkmown property.
302    *
303    * Developer advise:
304    * Subscribers are created with @see link(), @see prop()
305    * and also via @LocalStorageLink and @LocalStorageProp state variable decorators.
306    * That means as long as their is a @Component instance that uses such decorated variable
307    * or a sync relationship with a SubscribedAbstractProperty variable the property can nit
308    * (and also should not!) be deleted from AppStorage.
309    *
310    * Same as @see LocalStorage.delete()
311    *
312    * @param propName
313    * @returns false if method failed
314    *
315    * @since 10
316    */
317    public static delete(key: string): boolean {
318        return AppStorage.getOrCreate().delete(key);
319    }
320
321    /**
322    * @see delete
323    * @since 7
324    * @deprecated
325    */
326    public static Delete(key: string): boolean {
327        return AppStorage.getOrCreate().delete(key);
328    }
329
330    /**
331    * Provide names of all properties in AppStorage
332    * same as ES6 Map.prototype.keys()
333    *
334    * Same as @see LocalStorage.keys()
335    *
336    * @returns return a Map Iterator
337    *
338    * @since 10
339   */
340    public static keys(): IterableIterator<string> {
341        return AppStorage.getOrCreate().keys();
342    }
343
344    /**
345    * @see keys
346    * @since 7
347    * @deprecated
348    */
349    public static Keys(): IterableIterator<string> {
350        return AppStorage.getOrCreate().keys();
351    }
352
353    /**
354    * Returns number of properties in AppStorage
355    * same as Map.prototype.size()
356    *
357    * Same as @see LocalStorage.size()
358    *
359    * @param propName
360    * @returns return number of properties
361    *
362    * @since 10
363    */
364    public static size(): number {
365        return AppStorage.getOrCreate().size();
366    }
367
368    /**
369    * @see size
370    * @since 7
371    * @deprecated
372    */
373    public static Size(): number {
374        return AppStorage.getOrCreate().size();
375    }
376
377    /**
378    * delete all properties from the AppStorage
379    *
380    * @see delete(), same as @see LocalStorage.clear()
381    *
382    * precondition is that there are no subscribers.
383    * method returns false and deletes no poperties if there is any property
384    * that still has subscribers
385    *
386    * @since 10
387    */
388    public static clear(): boolean {
389        return AppStorage.getOrCreate().clear();
390    }
391
392    /**
393    * @see clear
394    * @since 7
395    * @deprecated
396    */
397    public static Clear(): boolean {
398        return AppStorage.getOrCreate().clear();
399    }
400
401    /**
402    * Same as @see clear().
403    *
404    * @since 7, deprecated, used clear() instead!
405    *
406    */
407    public static StaticClear(): boolean {
408        return AppStorage.clear();
409    }
410
411    /**
412    * not a public / sdk function
413    */
414    public static aboutToBeDeleted(): void {
415        AppStorage.getOrCreate().aboutToBeDeleted();
416    }
417
418    /**
419    * Subscribe to value change notifications of named property
420    * Any object implementing ISinglePropertyChangeSubscriber interface
421    * and registerign itself to SubscriberManager can register
422    * Caution: do remember to unregister, otherwise the property will block
423    * cleanup, @see delete() and @see clear()
424    *
425    * Same as @see LocalStorage.subscribeToChangesOf()
426    *
427    * @param propName property in AppStorage to subscribe to
428    * @param subscriber object that implements ISinglePropertyChangeSubscriber interface
429    * @returns false if named property does not exist
430    *
431    * @since 10
432    */
433    public static subscribeToChangesOf<T>(propName: string, subscriber: ISinglePropertyChangeSubscriber<T>): boolean {
434        return AppStorage.getOrCreate().subscribeToChangesOf(propName, subscriber);
435    }
436
437
438    /**
439    * @see subscribeToChangesOf
440    * @since 7
441    * @deprecated
442    */
443    public static SubscribeToChangesOf<T>(propName: string, subscriber: ISinglePropertyChangeSubscriber<T>): boolean {
444        return AppStorage.getOrCreate().subscribeToChangesOf(propName, subscriber);
445    }
446
447    /**
448    * inverse of @see SubscribeToChangesOf,
449    * same as @see LocalStorage.subscribeToChangesOf()
450    *
451    * @param propName property in AppStorage to subscribe to
452    * @param subscriberId id of the subscrber passed to @see subscribeToChangesOf
453    * @returns false if named property does not exist
454    *
455    * @since 10
456    */
457    public static unsubscribeFromChangesOf(propName: string, subscriberId: number): boolean {
458        return AppStorage.getOrCreate().unsubscribeFromChangesOf(propName, subscriberId);
459    }
460
461    /**
462    * @see unsubscribeFromChangesOf
463    * @since 7
464    * @deprecated
465    */
466    public static UnsubscribeFromChangesOf(propName: string, subscriberId: number): boolean {
467        return AppStorage.getOrCreate().unsubscribeFromChangesOf(propName, subscriberId);
468    }
469
470    /**
471     * Unimplemented, currently all properties of AppStorage are mutable.
472     *
473     * @since 7, deprecated
474     */
475    public static IsMutable(key: string): boolean {
476        return true;
477    }
478
479    /**
480    * not a public / sdk function
481    */
482
483    public static __createSync<T>(storagePropName: string, defaultValue: T,
484        factoryFunc: SynchedPropertyFactoryFunc): ObservedPropertyAbstract<T> {
485        return AppStorage.getOrCreate().__createSync(storagePropName, defaultValue, factoryFunc);
486    }
487
488    // instance functions below:
489    // Should all be protected, but TS lang does not allow access from static member to protected member
490
491    private static instance_: AppStorage = undefined;
492
493    /**
494    * not a public / sdk function
495    */
496    private static getOrCreate(): AppStorage {
497        if (!AppStorage.instance_) {
498            AppStorage.instance_ = new AppStorage({});
499        }
500        return AppStorage.instance_;
501    }
502
503    /** singleton class, app can not create instances
504    *
505    * not a public / sdk function
506    */
507    protected constructor(initializingProperties: Object) {
508        super(initializingProperties);
509    }
510}
511
512
513