• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2022 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 7
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   /**
66   * Like @see link(), but will create and initialize a new source property in LocalStorge if missing
67   *
68   * Same as @see LocalStorage.setAndLink()
69   *
70   * @param propName name of source property in AppStorage
71   * @param defaultValue value to be used for initializing if new creating new property in AppStorage
72   *        default value must be of type S, must not be undefined or null.
73   * @param linkUser IPropertySubscriber to be notified when return 'link' changes,
74   * @param subscribersName the linkUser (subscriber) uses this name for the property
75   *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
76   * @returns SynchedPropertyTwoWay{Simple|Object| object with given LocalStoage prop as  its source.
77   *          Apps can use SDK functions of base class SubscribedAbstractProperty<S>
78   *
79   * @since 7
80   */
81  public static SetAndLink<T>(key: string, defaultValue: T, linkUser?: IPropertySubscriber, subscribersName?: string): SubscribedAbstractProperty<T> {
82    return AppStorage.GetOrCreate().setAndLink(key, defaultValue, linkUser, subscribersName);
83  }
84
85    /**
86   * create and return a one-way sync ('prop') to named property
87   *
88   * Same as @see LocalStorage.prop()
89   *
90   * @param propName name of source property in AppStorage
91   * @param propUser IPropertySubscriber to be notified when source changes,
92   * @param subscribersName the linkUser (subscriber) uses this name for the property
93   *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
94   * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as  its source.
95   *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
96   *           return undefiend if named property does not already exist in AppStorage.
97   * @since 7
98   */
99  public static Prop<T>(propName: string, propUser?: IPropertySubscriber, subscribersName?: string): SubscribedAbstractProperty<T> {
100    return AppStorage.GetOrCreate().prop(propName, propUser, subscribersName);
101  }
102
103    /**
104   * Like @see prop(), will create and initialize a new source property in AppStorage if missing
105   *
106   * Same as @see LocalStorage.setAndProp()
107   *
108   * @param propName name of source property in AppStorage
109   * @param defaultValue value to be used for initializing if new creating new property in AppStorage.
110   *        default value must be of type S, must not be undefined or null.
111   * @param propUser IPropertySubscriber to be notified when returned 'prop' changes,
112   * @param subscribersName the propUser (subscriber) uses this name for the property
113   *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
114   * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as its source.
115   *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
116   *
117   * @since 7
118   */
119  public static SetAndProp<S>(key: string, defaultValue: S, propUser?: IPropertySubscriber, subscribersName?: string): SubscribedAbstractProperty<S> {
120    return AppStorage.GetOrCreate().setAndProp(key, defaultValue, propUser, subscribersName);
121  }
122
123
124  /**
125   * Check if AppStorge has a property with given name
126   * return true if prooperty with given name exists
127   * same as ES6 Map.prototype.has()
128   *
129   * Same as @see LocalStorage.has()
130   *
131   * @param propName searched property
132   * @returns true if property with such name exists in AppStorage
133   *
134   * @since 7
135   */
136  public static Has(key: string): boolean {
137    return AppStorage.GetOrCreate().has(key);
138  }
139
140
141   /**
142   * Returns value of given property
143   * return undefined if no property with this name
144   *
145   *
146   * @Same as see LocalStorage.get()
147   *
148   * @param propName
149   * @returns property value if found or undefined
150   *
151   */
152  public static Get<T>(key: string): T | undefined {
153    return AppStorage.GetOrCreate().get(key);
154  }
155
156   /**
157   * Set value of given property in AppStorage
158   * Methosd sets nothing and returns false if property with this name does not exist
159   * or if newValue is `undefined` or `null` (`undefined`, `null` value are not allowed for state variables).
160   *
161   * Same as @see LocalStorage.set
162   *
163   * @param propName
164   * @param newValue must be of type T and must not be undefined or null
165   * @returns true on success, i.e. when above conditions are satisfied, otherwise false
166   *
167   * @since 7
168   */
169  public static Set<T>(key: string, newValue: T): boolean {
170    return AppStorage.GetOrCreate().set(key, newValue);
171  }
172
173    /**
174   * Set value of given property, if it exists, @see set() .
175   * Add property if no property with given name and initialize with given value.
176   * Do nothing and return false if newValuue is undefined or null
177   * (undefined, null value is not allowed for state variables)
178   *
179   * @see LocalStorage.setOrCreate()
180   *
181   * @param propName
182   * @param newValue must be of type T and must not be undefined or null
183   * @returns true on success, i.e. when above conditions are satisfied, otherwise false
184   *
185   * @since 7
186   */
187  public static SetOrCreate<T>(key: string, newValue: T): void {
188    AppStorage.GetOrCreate().setOrCreate(key, newValue);
189  }
190
191
192  /**
193   * Delete property from StorageBase
194   * Use with caution:
195   * Before deleting a prop from AppStorage all its subscribers need to
196   * unsubscribe from the property.
197   * This method fails and returns false if given property still has subscribers
198   * Another reason for failing is unkmown property.
199   *
200   * Developer advise:
201   * Subscribers are created with @see link(), @see prop()
202   * and also via @LocalStorageLink and @LocalStorageProp state variable decorators.
203   * That means as long as their is a @Component instance that uses such decorated variable
204   * or a sync relationship with a SubscribedAbstractProperty variable the property can nit
205   * (and also should not!) be deleted from AppStorage.
206   *
207   * Same as @see LocalStorage.delete()
208   *
209   * @param propName
210   * @returns false if method failed
211   *
212   * @since 7
213  */
214  public static Delete(key: string): boolean {
215    return AppStorage.GetOrCreate().delete(key);
216  }
217
218   /**
219   * Provide names of all properties in AppStorage
220   * same as ES6 Map.prototype.keys()
221   *
222   * Same as @see LocalStorage.keys()
223   *
224   * @returns return a Map Iterator
225   *
226   * @since 7
227  */
228  public static Keys(): IterableIterator<string> {
229    return AppStorage.GetOrCreate().keys();
230  }
231
232
233  /**
234   * Returns number of properties in AppStorage
235   * same as Map.prototype.size()
236   *
237   * Same as @see LocalStorage.size()
238   *
239   * @param propName
240   * @returns return number of properties
241   *
242   * @since 7
243   */
244  public static Size(): number {
245    return AppStorage.GetOrCreate().size();
246  }
247
248  /**
249   * delete all properties from the AppStorage
250   *
251   * @see delete(), same as @see LocalStorage.clear()
252   *
253   * precondition is that there are no subscribers.
254   * method returns false and deletes no poperties if there is any property
255   * that still has subscribers
256   *
257   * @since 7
258   */
259   public static Clear(): boolean {
260    return AppStorage.GetOrCreate().clear();
261  }
262
263  /**
264   * Same as @see Clear().
265   *
266   * @since 7, depreciated, used Clear() instead!
267   *
268   */
269  public static StaticClear(): boolean {
270    return AppStorage.Clear();
271  }
272
273  /**
274  * not a public / sdk function
275  */
276  public static AboutToBeDeleted(): void {
277    AppStorage.GetOrCreate().aboutToBeDeleted();
278  }
279
280
281  /**
282   * return number of subscribers to named property
283   * useful for debug purposes
284   *
285   * not a public / sdk function
286  */
287  public static NumberOfSubscribersTo(propName: string): number | undefined {
288    return AppStorage.GetOrCreate().numberOfSubscrbersTo(propName);
289  }
290
291
292   /**
293   * Subscribe to value change notifications of named property
294   * Any object implementing ISinglePropertyChangeSubscriber interface
295   * and registerign itself to SubscriberManager can register
296   * Caution: do remember to unregister, otherwise the property will block
297   * cleanup, @see delete() and @see clear()
298   *
299   * Same as @see LocalStorage.subscribeToChangesOf()
300   *
301   * @param propName property in AppStorage to subscribe to
302   * @param subscriber object that implements ISinglePropertyChangeSubscriber interface
303   * @returns false if named property does not exist
304   *
305   * @since 7
306   */
307  public static SubscribeToChangesOf<T>(propName: string, subscriber: ISinglePropertyChangeSubscriber<T>): boolean {
308    return AppStorage.GetOrCreate().subscribeToChangesOf(propName, subscriber);
309  }
310
311
312  /**
313   * inverse of @see SubscribeToChangesOf,
314   * same as @see LocalStorage.subscribeToChangesOf()
315   *
316   * @param propName property in AppStorage to subscribe to
317   * @param subscriberId id of the subscrber passed to @see subscribeToChangesOf
318   * @returns false if named property does not exist
319   *
320   * @since 7
321   */
322  public static UnsubscribeFromChangesOf(propName: string, subscriberId: number): boolean {
323    return AppStorage.GetOrCreate().unsubscribeFromChangesOf(propName, subscriberId);
324  }
325
326  /**
327   * Unimplemenrted, currently all properties of AppStorage are mutable.
328   *
329   * @since 7, depreciated
330   */
331  public static IsMutable(key: string): boolean {
332    return true;
333  }
334
335  /**
336   * not a public / sdk function
337   */
338
339  public static __CreateSync<T>(storagePropName: string, defaultValue: T,
340    factoryFunc: SynchedPropertyFactoryFunc): ObservedPropertyAbstract<T> {
341    return AppStorage.GetOrCreate().__createSync(storagePropName, defaultValue, factoryFunc);
342  }
343
344  // instance functions below:
345  // Should all be protected, but TS lang does not allow access from static member to protected member
346
347  private static Instance_: AppStorage = undefined;
348
349  /**
350   * not a public / sdk function
351   */
352  private static GetOrCreate(): AppStorage {
353    if (!AppStorage.Instance_) {
354      stateMgmtConsole.warn("AppStorage instance missing. Use AppStorage.CreateInstance(initObj). Creating instance without any initialization.");
355      AppStorage.Instance_ = new AppStorage({});
356    }
357    return AppStorage.Instance_;
358  }
359
360  /** singleton class, app can not create instances
361   *
362   * not a public / sdk function
363  */
364  protected constructor(initializingProperties: Object) {
365    super(initializingProperties);
366  }
367}
368
369
370