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