• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021 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 * Copyright (c) 2021 Huawei Device Co., Ltd.
17 * Licensed under the Apache License, Version 2.0 (the "License");
18 * you may not use this file except in compliance with the License.
19 * You may obtain a copy of the License at
20 *
21 *     http://www.apache.org/licenses/LICENSE-2.0
22 *
23 * Unless required by applicable law or agreed to in writing, software
24 * distributed under the License is distributed on an "AS IS" BASIS,
25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 * See the License for the specific language governing permissions and
27 * limitations under the License.
28 */
29/*
30 * Copyright (c) 2021 Huawei Device Co., Ltd.
31 * Licensed under the Apache License, Version 2.0 (the "License");
32 * you may not use this file except in compliance with the License.
33 * You may obtain a copy of the License at
34 *
35 *     http://www.apache.org/licenses/LICENSE-2.0
36 *
37 * Unless required by applicable law or agreed to in writing, software
38 * distributed under the License is distributed on an "AS IS" BASIS,
39 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40 * See the License for the specific language governing permissions and
41 * limitations under the License.
42 */
43/*
44 * Copyright (c) 2021 Huawei Device Co., Ltd.
45 * Licensed under the Apache License, Version 2.0 (the "License");
46 * you may not use this file except in compliance with the License.
47 * You may obtain a copy of the License at
48 *
49 *     http://www.apache.org/licenses/LICENSE-2.0
50 *
51 * Unless required by applicable law or agreed to in writing, software
52 * distributed under the License is distributed on an "AS IS" BASIS,
53 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
54 * See the License for the specific language governing permissions and
55 * limitations under the License.
56 */
57/**
58 *
59 * LocalStorage
60 *
61 * Class implements a Map of ObservableObjectBase UI state variables.
62 * Instances can be created to manage UI state within a limited "local"
63 * access, and life cycle as defined by the app.
64 * AppStorage singleton is sub-class of LocalStorage for
65 * UI state of app-wide access and same life cycle as the app.
66 *
67 * @since 9
68 */
69 class LocalStorage extends NativeLocalStorage {
70    /**
71     * Construct new instance of LocalStorage
72     * initialzie with all properties and their values that Object.keys(params) returns
73     * Property values must not be undefined.
74     * @param initializingProperties Object containing keys and values. @see set() for valid values
75     *
76     * @since 9
77     */
78    constructor(initializingProperties = {}) {
79        super();
80
81        this.storage_ = new Map();
82        if (Object.keys(initializingProperties).length) {
83            this.initializeProps(initializingProperties);
84        }
85    }
86    /**
87     * clear storage and init with given properties
88     * @param initializingProperties
89     *
90     * not a public / sdk function
91     */
92    initializeProps(initializingProperties = {}) {
93
94        this.storage_.clear();
95        Object.keys(initializingProperties).filter((propName) => initializingProperties[propName] != undefined).forEach((propName) => this.addNewPropertyInternal(propName, initializingProperties[propName]));
96    }
97    /**
98     * Use before deleting owning Ability, window, or service UI
99     * (letting it go out of scope).
100     *
101     * This method orderly closes down a LocalStorage instance by calling @see clear().
102     * This requires that no property is left with one or more subscribers.
103     * @see clear() and @see delete()
104     * @returns true if all properties could be removed from storage
105     */
106    aboutToBeDeleted() {
107        return this.clear();
108    }
109    /**
110     * Check if LocalStorage has a property with given name
111     * return true if prooperty with given name exists
112     * same as ES6 Map.prototype.has()
113     * @param propName searched property
114     * @returns true if property with such name exists in LocalStorage
115     *
116     * @since 9
117     */
118    has(propName) {
119        return this.storage_.has(propName);
120    }
121    /**
122     * Provide names of all properties in LocalStorage
123     * same as ES6 Map.prototype.keys()
124     * @returns return a Map Iterator
125     *
126     * @since 9
127    */
128    keys() {
129        return this.storage_.keys();
130    }
131    /**
132     * Returns number of properties in LocalStorage
133     * same as Map.prototype.size()
134     * @param propName
135     * @returns return number of properties
136     *
137     * @since 9
138     */
139    size() {
140        return this.storage_.size;
141    }
142    /**
143     * Returns value of given property
144     * return undefined if no property with this name
145     * @param propName
146     * @returns property value if found or undefined
147     *
148     * @since 9
149     */
150    get(propName) {
151        var p = this.storage_.get(propName);
152        return (p) ? p.get() : undefined;
153    }
154    /**
155     * Set value of given property in LocalStorage
156     * Methosd sets nothing and returns false if property with this name does not exist
157     * or if newValue is `undefined` or `null` (`undefined`, `null` value are not allowed for state variables).
158     * @param propName
159     * @param newValue must be of type T and must not be undefined or null
160     * @returns true on success, i.e. when above conditions are satisfied, otherwise false
161     *
162     * @since 9
163     */
164    set(propName, newValue) {
165        if (newValue == undefined) {
166            stateMgmtConsole.warn(`${this.constructor.name}: set('${propName}') with newValue == undefined not allowed.`);
167            return false;
168        }
169        var p = this.storage_.get(propName);
170        if (p == undefined) {
171            stateMgmtConsole.warn(`${this.constructor.name}: set: no property ${propName} error.`);
172            return false;
173        }
174        p.set(newValue);
175        return true;
176    }
177    /**
178     * Set value of given property, if it exists, @see set() .
179     * Add property if no property with given name and initialize with given value.
180     * Do nothing and return false if newValuue is undefined or null
181     * (undefined, null value is not allowed for state variables)
182     * @param propName
183     * @param newValue must be of type T and must not be undefined or null
184     * @returns true on success, i.e. when above conditions are satisfied, otherwise false
185     *
186     * @since 9
187     */
188    setOrCreate(propName, newValue) {
189        if (newValue == undefined) {
190            stateMgmtConsole.warn(`${this.constructor.name}: setOrCreate('${propName}') with newValue == undefined not allowed.`);
191            return false;
192        }
193        var p = this.storage_.get(propName);
194        if (p) {
195
196            p.set(newValue);
197        }
198        else {
199
200            this.addNewPropertyInternal(propName, newValue);
201        }
202        return true;
203    }
204    /**
205     * Internal use helper function to create and initialize a new property.
206     * caller needs to be all the checking beforehand
207     * @param propName
208     * @param value
209     *
210     * Not a public / sdk method.
211     */
212    addNewPropertyInternal(propName, value) {
213        const newProp = (typeof value === "object") ?
214            new ObservedPropertyObject(value, undefined, propName)
215            : new ObservedPropertySimple(value, undefined, propName);
216        this.storage_.set(propName, newProp);
217        return newProp;
218    }
219    /**
220     * create and return a two-way sync "(link") to named property
221     * @param propName name of source property in LocalStorage
222     * @param linkUser IPropertySubscriber to be notified when source changes,
223     * @param subscribersName optional, the linkUser (subscriber) uses this name for the property
224     *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
225     * @returns  SynchedPropertyTwoWay{Simple|Object| object with given LocalStoage prop as its source.
226     *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
227     *           return undefiend if named property does not already exist in LocalStorage
228     *           Apps can use SDK functions of base class SubscribedPropertyAbstract<S>
229     *           return undefiend if named property does not already exist in LocalStorage
230     *
231     * @since 9
232     */
233    link(propName, linkUser, subscribersName) {
234        var p = this.storage_.get(propName);
235        if (p == undefined) {
236            stateMgmtConsole.warn(`${this.constructor.name}: link: no property ${propName} error.`);
237            return undefined;
238        }
239        let linkResult = p.createLink(linkUser, propName);
240        linkResult.setInfo(subscribersName);
241        return linkResult;
242    }
243    /**
244     * Like @see link(), but will create and initialize a new source property in LocalStorge if missing
245     * @param propName name of source property in LocalStorage
246     * @param defaultValue value to be used for initializing if new creating new property in LocalStorage
247     *        default value must be of type S, must not be undefined or null.
248     * @param linkUser IPropertySubscriber to be notified when return 'link' changes,
249     * @param subscribersName the linkUser (subscriber) uses this name for the property
250     *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
251     * @returns SynchedPropertyTwoWay{Simple|Object| object with given LocalStoage prop as  its source.
252     *          Apps can use SDK functions of base class SubscribedAbstractProperty<S>
253     *
254     * @since 9
255     */
256    setAndLink(propName, defaultValue, linkUser, subscribersName) {
257        var p = this.storage_.get(propName);
258        if (!p) {
259            this.setOrCreate(propName, defaultValue);
260        }
261        return this.link(propName, linkUser, subscribersName);
262    }
263    /**
264     * create and return a one-way sync ('prop') to named property
265     * @param propName name of source property in LocalStorage
266     * @param propUser IPropertySubscriber to be notified when source changes,
267     * @param subscribersName the linkUser (subscriber) uses this name for the property
268     *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
269     * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as  its source.
270     *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
271     *           return undefiend if named property does not already exist in LocalStorage.
272     *           Apps can use SDK functions of base class SubscribedPropertyAbstract<S>
273     *           return undefiend if named property does not already exist in LocalStorage.
274     * @since 9
275     */
276    prop(propName, propUser, subscribersName) {
277        var p = this.storage_.get(propName);
278        if (p == undefined) {
279            stateMgmtConsole.warn(`${this.constructor.name}: prop: no property ${propName} error.`);
280            return undefined;
281        }
282        let propResult = p.createProp(propUser, propName);
283        propResult.setInfo(subscribersName);
284        return propResult;
285    }
286    /**
287     * Like @see prop(), will create and initialize a new source property in LocalStorage if missing
288     * @param propName name of source property in LocalStorage
289     * @param defaultValue value to be used for initializing if new creating new property in LocalStorage.
290     *        default value must be of type S, must not be undefined or null.
291     * @param propUser IPropertySubscriber to be notified when returned 'prop' changes,
292     * @param subscribersName the propUser (subscriber) uses this name for the property
293     *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
294     * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as its source.
295     *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
296     * @since 9
297     */
298    setAndProp(propName, defaultValue, propUser, subscribersName) {
299        var p = this.storage_.get(propName);
300        if (!p) {
301            this.setOrCreate(propName, defaultValue);
302        }
303        return this.prop(propName, propUser, subscribersName);
304    }
305    /**
306     * Delete property from StorageBase
307     * Use with caution:
308     * Before deleting a prop from LocalStorage all its subscribers need to
309     * unsubscribe from the property.
310     * This method fails and returns false if given property still has subscribers
311     * Another reason for failing is unkmown property.
312     *
313     * Developer advise:
314     * Subscribers are created with @see link(), @see prop()
315     * and also via @LocalStorageLink and @LocalStorageProp state variable decorators.
316     * That means as long as their is a @Component instance that uses such decorated variable
317     * or a sync relationship with a SubscribedAbstractProperty variable the property can nit
318     * (and also should not!) be deleted from LocalStorage.
319     *
320     * @param propName
321     * @returns false if method failed
322     *
323     * @since 9
324    */
325    delete(propName) {
326        var p = this.storage_.get(propName);
327        if (p) {
328            if (p.numberOfSubscrbers()) {
329                stateMgmtConsole.error(`${this.constructor.name}: Attempt to delete property ${propName} that has \
330          ${p.numberOfSubscrbers()} subscribers. Subscribers need to unsubscribe before prop deletion.`);
331                return false;
332            }
333            p.aboutToBeDeleted();
334            this.storage_.delete(propName);
335            return true;
336        }
337        else {
338            stateMgmtConsole.warn(`${this.constructor.name}: Attempt to delete unknown property ${propName}.`);
339            return false;
340        }
341    }
342    /**
343     * delete all properties from the LocalStorage instance
344     * @see delete().
345     * precondition is that there are no subscribers.
346     * method returns false and deletes no poperties if there is any property
347     * that still has subscribers
348     *
349     * @since 9
350     */
351    clear() {
352        for (let propName of this.keys()) {
353            var p = this.storage_.get(propName);
354            if (p.numberOfSubscrbers()) {
355                stateMgmtConsole.error(`${this.constructor.name}.deleteAll: Attempt to delete property ${propName} that \
356          has ${p.numberOfSubscrbers()} subscribers. Subscribers need to unsubscribe before prop deletion.
357          Any @Component instance with a @StorageLink/Prop or @LocalStorageLink/Prop is a subscriber.`);
358                return false;
359            }
360        }
361        for (let propName of this.keys()) {
362            var p = this.storage_.get(propName);
363            p.aboutToBeDeleted();
364        }
365        this.storage_.clear();
366        return true;
367    }
368    /**
369     * Subscribe to value change notifications of named property
370     * Any object implementing ISinglePropertyChangeSubscriber interface
371     * and registerign itself to SubscriberManager can register
372     * Caution: do remember to unregister, otherwise the property will block
373     * cleanup, @see delete() and @see clear()
374     *
375     * @param propName property in LocalStorage to subscribe to
376     * @param subscriber object that implements ISinglePropertyChangeSubscriber interface
377     * @returns false if named property does not exist
378     *
379     * @since 9
380     */
381    subscribeToChangesOf(propName, subscriber) {
382        var p = this.storage_.get(propName);
383        if (p) {
384            p.subscribeMe(subscriber);
385            return true;
386        }
387        return false;
388    }
389    /**
390     * inverse of @see subscribeToChangesOf
391     * @param propName property in LocalStorage to subscribe to
392     * @param subscriberId id of the subscrber passed to @see subscribeToChangesOf
393     * @returns false if named property does not exist
394     *
395     * @since 9
396     */
397    unsubscribeFromChangesOf(propName, subscriberId) {
398        var p = this.storage_.get(propName);
399        if (p) {
400            p.unlinkSuscriber(subscriberId);
401            return true;
402        }
403        return false;
404    }
405    /**
406     * return number of subscribers to named property
407     *  useful for debug purposes
408     *
409     * Not a public / sdk function
410    */
411    numberOfSubscrbersTo(propName) {
412        var p = this.storage_.get(propName);
413        if (p) {
414            return p.numberOfSubscrbers();
415        }
416        return undefined;
417    }
418    __createSync(storagePropName, defaultValue, factoryFunc) {
419        let p = this.storage_.get(storagePropName);
420        if (p == undefined) {
421            // property named 'storagePropName' not yet in storage
422            // add new property to storage
423            if (defaultValue === undefined) {
424                stateMgmtConsole.error(`${this.constructor.name}.__createSync(${storagePropName}, non-existing property and undefined default value. ERROR.`);
425                return undefined;
426            }
427            p = this.addNewPropertyInternal(storagePropName, defaultValue);
428        }
429        return factoryFunc(p);
430    }
431}
432/*
433 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
434 * Licensed under the Apache License, Version 2.0 (the "License");
435 * you may not use this file except in compliance with the License.
436 * You may obtain a copy of the License at
437 *
438 *     http://www.apache.org/licenses/LICENSE-2.0
439 *
440 * Unless required by applicable law or agreed to in writing, software
441 * distributed under the License is distributed on an "AS IS" BASIS,
442 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
443 * See the License for the specific language governing permissions and
444 * limitations under the License.
445 */
446/**
447 *
448 * AppStorage
449 *
450 * Class implements a Map of ObservableObjectBase UI state variables.
451 * AppStorage singleton is sub-class of @see LocalStorage for
452 * UI state of app-wide access and same life cycle as the app.
453 *
454 * @since 7
455 */
456class AppStorage extends LocalStorage {
457    /** singleton class, app can not create instances
458     *
459     * not a public / sdk function
460    */
461    constructor(initializingProperties) {
462        super(initializingProperties);
463    }
464    /**
465     * create and initialize singleton
466     * initialzie with all properties and their values that Object.keys(params) returns
467     * Property values must not be undefined.
468     *
469     * not a public / sdk function
470     */
471    static CreateSingleton(initializingPropersties) {
472        if (!AppStorage.Instance_) {
473
474            AppStorage.Instance_ = new AppStorage(initializingPropersties);
475        }
476        else {
477            stateMgmtConsole.error("AppStorage.CreateNewInstance(..): instance exists already, internal error!");
478        }
479    }
480    /**
481    * create and return a two-way sync "(link") to named property
482    *
483    * Same as @see LocalStorage.link()
484    *
485    * @param propName name of source property in AppStorage
486     * @param linkUser IPropertySubscriber to be notified when source changes,
487     * @param subscribersName the linkUser (subscriber) uses this name for the property
488     *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
489     * @returns  SynchedPropertyTwoWay{Simple|Object| object with given LocalStoage prop as its source.
490     *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
491     *           return undefiend if named property does not already exist in AppStorage
492     *
493     * @since 7
494     */
495    static Link(key, linkUser, subscribersName) {
496        return AppStorage.GetOrCreate().link(key, linkUser, subscribersName);
497    }
498    /**
499    * Like @see link(), but will create and initialize a new source property in LocalStorge if missing
500    *
501    * Same as @see LocalStorage.setAndLink()
502    *
503    * @param propName name of source property in AppStorage
504    * @param defaultValue value to be used for initializing if new creating new property in AppStorage
505    *        default value must be of type S, must not be undefined or null.
506    * @param linkUser IPropertySubscriber to be notified when return 'link' changes,
507    * @param subscribersName the linkUser (subscriber) uses this name for the property
508    *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
509    * @returns SynchedPropertyTwoWay{Simple|Object| object with given LocalStoage prop as  its source.
510    *          Apps can use SDK functions of base class SubscribedAbstractProperty<S>
511    *
512    * @since 7
513    */
514    static SetAndLink(key, defaultValue, linkUser, subscribersName) {
515        return AppStorage.GetOrCreate().setAndLink(key, defaultValue, linkUser, subscribersName);
516    }
517    /**
518   * create and return a one-way sync ('prop') to named property
519   *
520   * Same as @see LocalStorage.prop()
521   *
522   * @param propName name of source property in AppStorage
523   * @param propUser IPropertySubscriber to be notified when source changes,
524   * @param subscribersName the linkUser (subscriber) uses this name for the property
525   *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
526   * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as  its source.
527   *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
528   *           return undefiend if named property does not already exist in AppStorage.
529   * @since 7
530   */
531    static Prop(propName, propUser, subscribersName) {
532        return AppStorage.GetOrCreate().prop(propName, propUser, subscribersName);
533    }
534    /**
535   * Like @see prop(), will create and initialize a new source property in AppStorage if missing
536   *
537   * Same as @see LocalStorage.setAndProp()
538   *
539   * @param propName name of source property in AppStorage
540   * @param defaultValue value to be used for initializing if new creating new property in AppStorage.
541   *        default value must be of type S, must not be undefined or null.
542   * @param propUser IPropertySubscriber to be notified when returned 'prop' changes,
543   * @param subscribersName the propUser (subscriber) uses this name for the property
544   *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
545   * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as its source.
546   *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
547   *
548   * @since 7
549   */
550    static SetAndProp(key, defaultValue, propUser, subscribersName) {
551        return AppStorage.GetOrCreate().setAndProp(key, defaultValue, propUser, subscribersName);
552    }
553    /**
554     * Check if AppStorge has a property with given name
555     * return true if prooperty with given name exists
556     * same as ES6 Map.prototype.has()
557     *
558     * Same as @see LocalStorage.has()
559     *
560     * @param propName searched property
561     * @returns true if property with such name exists in AppStorage
562     *
563     * @since 7
564     */
565    static Has(key) {
566        return AppStorage.GetOrCreate().has(key);
567    }
568    /**
569    * Returns value of given property
570    * return undefined if no property with this name
571    *
572    *
573    * @Same as see LocalStorage.get()
574    *
575    * @param propName
576    * @returns property value if found or undefined
577    *
578    */
579    static Get(key) {
580        return AppStorage.GetOrCreate().get(key);
581    }
582    /**
583    * Set value of given property in AppStorage
584    * Methosd sets nothing and returns false if property with this name does not exist
585    * or if newValue is `undefined` or `null` (`undefined`, `null` value are not allowed for state variables).
586    *
587    * Same as @see LocalStorage.set
588    *
589    * @param propName
590    * @param newValue must be of type T and must not be undefined or null
591    * @returns true on success, i.e. when above conditions are satisfied, otherwise false
592    *
593    * @since 7
594    */
595    static Set(key, newValue) {
596        return AppStorage.GetOrCreate().set(key, newValue);
597    }
598    /**
599   * Set value of given property, if it exists, @see set() .
600   * Add property if no property with given name and initialize with given value.
601   * Do nothing and return false if newValuue is undefined or null
602   * (undefined, null value is not allowed for state variables)
603   *
604   * @see LocalStorage.setOrCreate()
605   *
606   * @param propName
607   * @param newValue must be of type T and must not be undefined or null
608   * @returns true on success, i.e. when above conditions are satisfied, otherwise false
609   *
610   * @since 7
611   */
612    static SetOrCreate(key, newValue) {
613        AppStorage.GetOrCreate().setOrCreate(key, newValue);
614    }
615    /**
616     * Delete property from StorageBase
617     * Use with caution:
618     * Before deleting a prop from AppStorage all its subscribers need to
619     * unsubscribe from the property.
620     * This method fails and returns false if given property still has subscribers
621     * Another reason for failing is unkmown property.
622     *
623     * Developer advise:
624     * Subscribers are created with @see link(), @see prop()
625     * and also via @LocalStorageLink and @LocalStorageProp state variable decorators.
626     * That means as long as their is a @Component instance that uses such decorated variable
627     * or a sync relationship with a SubscribedAbstractProperty variable the property can nit
628     * (and also should not!) be deleted from AppStorage.
629     *
630     * Same as @see LocalStorage.delete()
631     *
632     * @param propName
633     * @returns false if method failed
634     *
635     * @since 7
636    */
637    static Delete(key) {
638        return AppStorage.GetOrCreate().delete(key);
639    }
640    /**
641    * Provide names of all properties in AppStorage
642    * same as ES6 Map.prototype.keys()
643    *
644    * Same as @see LocalStorage.keys()
645    *
646    * @returns return a Map Iterator
647    *
648    * @since 7
649   */
650    static Keys() {
651        return AppStorage.GetOrCreate().keys();
652    }
653    /**
654     * Returns number of properties in AppStorage
655     * same as Map.prototype.size()
656     *
657     * Same as @see LocalStorage.size()
658     *
659     * @param propName
660     * @returns return number of properties
661     *
662     * @since 7
663     */
664    static Size() {
665        return AppStorage.GetOrCreate().size();
666    }
667    /**
668     * delete all properties from the AppStorage
669     *
670     * @see delete(), same as @see LocalStorage.clear()
671     *
672     * precondition is that there are no subscribers.
673     * method returns false and deletes no poperties if there is any property
674     * that still has subscribers
675     *
676     * @since 7
677     */
678    static Clear() {
679        return AppStorage.GetOrCreate().clear();
680    }
681    /**
682     * Same as @see Clear().
683     *
684     * @since 7, depreciated, used Clear() instead!
685     *
686     */
687    static StaticClear() {
688        return AppStorage.Clear();
689    }
690    /**
691    * not a public / sdk function
692    */
693    static AboutToBeDeleted() {
694        AppStorage.GetOrCreate().aboutToBeDeleted();
695    }
696    /**
697     * return number of subscribers to named property
698     * useful for debug purposes
699     *
700     * not a public / sdk function
701    */
702    static NumberOfSubscribersTo(propName) {
703        return AppStorage.GetOrCreate().numberOfSubscrbersTo(propName);
704    }
705    /**
706    * Subscribe to value change notifications of named property
707    * Any object implementing ISinglePropertyChangeSubscriber interface
708    * and registerign itself to SubscriberManager can register
709    * Caution: do remember to unregister, otherwise the property will block
710    * cleanup, @see delete() and @see clear()
711    *
712    * Same as @see LocalStorage.subscribeToChangesOf()
713    *
714    * @param propName property in AppStorage to subscribe to
715    * @param subscriber object that implements ISinglePropertyChangeSubscriber interface
716    * @returns false if named property does not exist
717    *
718    * @since 7
719    */
720    static SubscribeToChangesOf(propName, subscriber) {
721        return AppStorage.GetOrCreate().subscribeToChangesOf(propName, subscriber);
722    }
723    /**
724     * inverse of @see SubscribeToChangesOf,
725     * same as @see LocalStorage.subscribeToChangesOf()
726     *
727     * @param propName property in AppStorage to subscribe to
728     * @param subscriberId id of the subscrber passed to @see subscribeToChangesOf
729     * @returns false if named property does not exist
730     *
731     * @since 7
732     */
733    static UnsubscribeFromChangesOf(propName, subscriberId) {
734        return AppStorage.GetOrCreate().unsubscribeFromChangesOf(propName, subscriberId);
735    }
736    /**
737     * Unimplemenrted, currently all properties of AppStorage are mutable.
738     *
739     * @since 7, depreciated
740     */
741    static IsMutable(key) {
742        return true;
743    }
744    /**
745     * not a public / sdk function
746     */
747    static __CreateSync(storagePropName, defaultValue, factoryFunc) {
748        return AppStorage.GetOrCreate().__createSync(storagePropName, defaultValue, factoryFunc);
749    }
750    /**
751     * not a public / sdk function
752     */
753    static GetOrCreate() {
754        if (!AppStorage.Instance_) {
755            stateMgmtConsole.warn("AppStorage instance missing. Use AppStorage.CreateInstance(initObj). Creating instance without any initialization.");
756            AppStorage.Instance_ = new AppStorage({});
757        }
758        return AppStorage.Instance_;
759    }
760}
761// instance functions below:
762// Should all be protected, but TS lang does not allow access from static member to protected member
763AppStorage.Instance_ = undefined;
764/*
765 * Copyright (c) 2022 Huawei Device Co., Ltd.
766 * Licensed under the Apache License, Version 2.0 (the "License");
767 * you may not use this file except in compliance with the License.
768 * You may obtain a copy of the License at
769 *
770 *     http://www.apache.org/licenses/LICENSE-2.0
771 *
772 * Unless required by applicable law or agreed to in writing, software
773 * distributed under the License is distributed on an "AS IS" BASIS,
774 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
775 * See the License for the specific language governing permissions and
776 * limitations under the License.
777 */
778/**
779 * Singleton class SubscriberManager implements IPropertySubscriberLookup
780 * public API to manage IPropertySubscriber
781 */
782class SubscriberManager {
783    /**
784     * SubscriberManager is a singleton created by the framework
785     * do not use
786     *
787     * internal method
788     */
789    constructor() {
790        this.subscriberById_ = new Map();
791
792    }
793    /**
794      * check subscriber is known
795      * same as ES6 Map.prototype.has()
796      *
797      * @since 9
798      */
799    static Has(id) {
800        return SubscriberManager.GetInstance().has(id);
801    }
802    /**
803     *
804     * retrieve subscriber by id
805     * same as ES6 Map.prototype.get()
806     *
807     *  @since 9
808     */
809    static Find(id) {
810        return SubscriberManager.GetInstance().get(id);
811    }
812    /**
813     * unregister a subscriber
814     * same as ES6 Map.prototype.delete()
815     * @return boolean success or failure to delete
816     *
817     *  @since 9
818     */
819    static Delete(id) {
820        return SubscriberManager.GetInstance().delete(id);
821    }
822    /**
823    * add a new subscriber.
824    * The subscriber must have a new (unused) id (@see MakeId() )
825    * for add() to succeed.
826    * same as Map.prototype.set()
827    *
828    *  @since 9
829    */
830    static Add(newSubsriber) {
831        return SubscriberManager.GetInstance().add(newSubsriber);
832    }
833    /**
834    *
835    * @returns a globally unique id to be assigned to a IPropertySubscriber objet
836    * Use MakeId() to assign a IPropertySubscriber object an id before calling @see add() .
837    *
838    *  @since 9
839   */
840    static MakeId() {
841        return SubscriberManager.GetInstance().makeId();
842    }
843    /**
844     * Check number of registered Subscriber / registered IDs.
845     * @returns number of registered unique ids.
846     *
847     *  @since 9
848     */
849    static NumberOfSubscribers() {
850        return SubscriberManager.GetInstance().numberOfSubscribers();
851    }
852    /**
853     *
854     * internal (non-SDK) methods below
855     *
856    */
857    /**
858   * Get singleton, create it on first call
859   * @returns SubscriberManager singleton
860   *
861   * internal function
862   * This function will be removed soon, use static functions instead!
863   * Note: Fnction gets used by transpiler output for both full update and partial update
864   */
865    static Get() {
866        if (!SubscriberManager.instance_) {
867            SubscriberManager.instance_ = new SubscriberManager();
868        }
869        return SubscriberManager.instance_;
870    }
871    /**
872     * Get singleton, create it on first call
873     * @returns SubscriberManager singleton
874     *
875     * internal function
876     */
877    static GetInstance() {
878        if (!SubscriberManager.instance_) {
879            SubscriberManager.instance_ = new SubscriberManager();
880        }
881        return SubscriberManager.instance_;
882    }
883    /**
884     * for debug purposes dump all known subscriber's info to comsole
885     *
886     * not a public / sdk function
887     */
888    static DumpSubscriberInfo() {
889        SubscriberManager.GetInstance().dumpSubscriberInfo();
890    }
891    /**
892     * not a public / sdk function
893     * @see Has
894     */
895    has(id) {
896        return this.subscriberById_.has(id);
897    }
898    /**
899     * not a public / sdk function
900     * @see Get
901     */
902    get(id) {
903        return this.subscriberById_.get(id);
904    }
905    /**
906   * not a public / sdk function
907   * @see Delete
908   */
909    delete(id) {
910        if (!this.has(id)) {
911            stateMgmtConsole.warn(`SubscriberManager.delete unknown id ${id} `);
912            return false;
913        }
914        return this.subscriberById_.delete(id);
915    }
916    /**
917   * not a public / sdk function
918   * @see Add
919   */
920    add(newSubsriber) {
921        if (this.has(newSubsriber.id__())) {
922            return false;
923        }
924        this.subscriberById_.set(newSubsriber.id__(), newSubsriber);
925        return true;
926    }
927    /**
928     * Method for testing purposes
929     * @returns number of subscribers
930     *
931     * not a public / sdk function
932     */
933    numberOfSubscribers() {
934        return this.subscriberById_.size;
935    }
936    /**
937     * for debug purposes dump all known subscriber's info to comsole
938     *
939     * not a public / sdk function
940     */
941    dumpSubscriberInfo() {
942
943        for (let [id, subscriber] of this.subscriberById_) {
944
945        }
946
947    }
948    /**
949     *
950     * @returns a globally unique id to be assigned to a Subscriber
951     */
952    makeId() {
953        return ViewStackProcessor.MakeUniqueId();
954    }
955}
956/*
957 * Copyright (c) 2022 Huawei Device Co., Ltd.
958 * Licensed under the Apache License, Version 2.0 (the "License");
959 * you may not use this file except in compliance with the License.
960 * You may obtain a copy of the License at
961 *
962 *     http://www.apache.org/licenses/LICENSE-2.0
963 *
964 * Unless required by applicable law or agreed to in writing, software
965 * distributed under the License is distributed on an "AS IS" BASIS,
966 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
967 * See the License for the specific language governing permissions and
968 * limitations under the License.
969 */
970/**
971 *
972 *   SubscribedAbstractProperty is base class of ObservedPropertyAbstract
973 *   and includes these 3 functions that are part of the SDK.
974 *
975 *   SubscribedAbstractProperty<T> is the return type of
976 *   - AppStorage static functions Link(), Prop(), SetAndLink(), and SetAndProp()
977 *   - LocalStorage methods link(), prop(), setAndLink(), and setAndProp()
978 *
979 *   'T' can be boolean, string, number or custom class.
980 *
981 * Main functions
982 *   @see get() reads the linked AppStorage/LocalStorage property value,
983 *   @see set(newValue) write a new value to the synched AppStorage/LocalStorage property value
984 *   @see aboutToBeDeleted() ends the sync relationship with the AppStorage/LocalStorage property
985 *        The app must call this function before the SubscribedAbstractProperty<T> object
986 *        goes out of scope.
987 *
988 * @since 7
989*/
990class SubscribedAbstractProperty {
991}
992/*
993 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
994 * Licensed under the Apache License, Version 2.0 (the "License");
995 * you may not use this file except in compliance with the License.
996 * You may obtain a copy of the License at
997 *
998 *     http://www.apache.org/licenses/LICENSE-2.0
999 *
1000 * Unless required by applicable law or agreed to in writing, software
1001 * distributed under the License is distributed on an "AS IS" BASIS,
1002 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1003 * See the License for the specific language governing permissions and
1004 * limitations under the License.
1005 */
1006/**
1007 *
1008 * SubscriableAbstract
1009 *
1010 * This class is part of the SDK.
1011 * @since 9
1012 *
1013 * SubscriableAbstract is an abstract class that manages subscribers
1014 * to value changes. These subscribers are the implementation of
1015 * @State, @Link, @Provide, @Consume decorated variables inside the
1016 * framework. Each using @State, @Link, etc., decorated varibale in
1017 * a @Component will make its own subscription. When the component
1018 * is created the subscription is added, and before the component
1019 * is deleted it unsubscribes
1020 *
1021 * An application may extend SubscriableAbstract for a custom class
1022 * that manages state data. @State, @Link, @Provide, @Consume
1023 * decorated variables can hold an Object that is instance of
1024 * SubscribaleAbstract.
1025 *
1026 * About lifecycle: It is legal use for two @Components with two @State
1027 * decorated variables to share the same SubscribaleAbstract object.
1028 * Each such decorated variable implementation makes its own
1029 * subscription to the SubscribaleAbstract object. Hence, when both variables
1030 * have unsubscribed the SubscribaleAbstract custom class may do its own
1031 * de-initilialization, e.g. release held external resources.
1032 *
1033 * How to extend:
1034 * A subclass manages the get and set to one or several properties on its own.
1035 * The subclass needs to notify all relevant value changes to the framework for the
1036 * UI to be updated. Notification should only be given for class properties that
1037 * are used to generate the UI.
1038 *
1039 * A subclass must call super() in its constructor to let this base class
1040 * initialize itself.
1041 *
1042 * A subclass must call 'notifyPropertyHasChanged*(' after the relevant property
1043 * has changes. The framework will notify all dependent components to re-render.
1044 *
1045 * A sub-class may overwrite the 'addOwningProperty' function to add own
1046 * functionality, but it must call super.addowningOwningProperty(..). E.g.
1047 * the sub-class could connect to external resources upon the first subscriber.
1048 *
1049 * A sub-class may also overwrite the 'removeOwningProperty' function or
1050 * 'removeOwningPropertyById' function to add own functionality,
1051 * but it must call super.removeOwningProperty(..).
1052 * E.g. the sub-class could release held external resources upon loosing the
1053 * last subscriber.
1054 *
1055 */
1056class SubscribaleAbstract {
1057    /**
1058     * make sure to call super() from subclass constructor!
1059     *
1060     * @since 9
1061     */
1062    constructor() {
1063        this.owningProperties_ = new Set();
1064
1065    }
1066    /**
1067    * A subsclass must call this function whenever one of its properties has
1068     * changed that is used to construct the UI.
1069     * @param propName name of the change property
1070     * @param newValue the property value after the change
1071     *
1072     * @since 9
1073     */
1074    notifyPropertyHasChanged(propName, newValue) {
1075
1076        this.owningProperties_.forEach((subscribedId) => {
1077            var owningProperty = SubscriberManager.Find(subscribedId);
1078            if (owningProperty) {
1079                if ('hasChanged' in owningProperty) {
1080                    owningProperty.hasChanged(newValue);
1081                }
1082                if ('propertyHasChanged' in owningProperty) {
1083                    owningProperty.propertyHasChanged(propName);
1084                }
1085            }
1086            else {
1087                stateMgmtConsole.error(`SubscribaleAbstract: notifyHasChanged: unknown subscriber.'${subscribedId}' error!.`);
1088            }
1089        });
1090    }
1091    /**
1092     * Method used by the framework to add subscribing decorated variables
1093     * Subclass may overwrite this function but must call the function of the base
1094     * class from its own implementation.
1095     * @param subscriber new subscriber that implements ISinglePropertyChangeSubscriber
1096     * and/or IMultiPropertiesChangeSubscriber interfaces
1097     *
1098     * @since 9
1099     */
1100    addOwningProperty(subscriber) {
1101
1102        this.owningProperties_.add(subscriber.id__());
1103    }
1104    /**
1105     * Method used by the framework to ubsubscribing decorated variables
1106     * Subclass may overwrite this function but must call the function of the base
1107     * class from its own implementation.
1108     * @param subscriber subscriber that implements ISinglePropertyChangeSubscriber
1109     * and/or IMultiPropertiesChangeSubscriber interfaces
1110     *
1111     * @since 9
1112     */
1113    removeOwningProperty(property) {
1114        return this.removeOwningPropertyById(property.id__());
1115    }
1116    /**
1117     * Same as @see removeOwningProperty() but by Subscriber id.
1118     * @param subscriberId
1119    *
1120    * @since 9
1121     */
1122    removeOwningPropertyById(subscriberId) {
1123
1124        this.owningProperties_.delete(subscriberId);
1125    }
1126}
1127/*
1128 * Copyright (c) 2021 Huawei Device Co., Ltd.
1129 * Licensed under the Apache License, Version 2.0 (the "License");
1130 * you may not use this file except in compliance with the License.
1131 * You may obtain a copy of the License at
1132 *
1133 *     http://www.apache.org/licenses/LICENSE-2.0
1134 *
1135 * Unless required by applicable law or agreed to in writing, software
1136 * distributed under the License is distributed on an "AS IS" BASIS,
1137 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1138 * See the License for the specific language governing permissions and
1139 * limitations under the License.
1140 */
1141/**
1142 * PersistentStorage
1143 *
1144 * Keeps current values of select AppStorage property properties persisted to file.
1145 *
1146 * since 9
1147 */
1148class PersistentStorage {
1149    /**
1150     * all following methods are framework internal
1151     */
1152    constructor() {
1153        this.links_ = new Map();
1154        this.id_ = SubscriberManager.MakeId();
1155        SubscriberManager.Add(this);
1156    }
1157    /**
1158     *
1159     * @param storage method to be used by the framework to set the backend
1160     * this is to be done during startup
1161     *
1162     * internal function, not part of the SDK
1163     *
1164     */
1165    static ConfigureBackend(storage) {
1166        PersistentStorage.Storage_ = storage;
1167    }
1168    /**
1169     * private, use static functions!
1170     */
1171    static GetOrCreate() {
1172        if (PersistentStorage.Instance_) {
1173            // already initialized
1174            return PersistentStorage.Instance_;
1175        }
1176        PersistentStorage.Instance_ = new PersistentStorage();
1177        return PersistentStorage.Instance_;
1178    }
1179    /**
1180     *
1181     * internal function, not part of the SDK
1182     */
1183    static AboutToBeDeleted() {
1184        if (!PersistentStorage.Instance_) {
1185            return;
1186        }
1187        PersistentStorage.GetOrCreate().aboutToBeDeleted();
1188        PersistentStorage.Instance_ = undefined;
1189    }
1190    /**
1191     * Add property 'key' to AppStorage properties whose current value will be
1192     * persistemt.
1193     * If AppStorage does not include this property it will be added and initializes
1194     * with given value
1195     *
1196     * @since 9
1197     *
1198     * @param key property name
1199     * @param defaultValue If AppStorage does not include this property it will be initialized with this value
1200     *
1201     */
1202    static PersistProp(key, defaultValue) {
1203        PersistentStorage.GetOrCreate().persistProp(key, defaultValue);
1204    }
1205    /**
1206     * Reverse of @see PersistProp
1207     * @param key no longer persist the property named key
1208     *
1209     * @since 9
1210     */
1211    static DeleteProp(key) {
1212        PersistentStorage.GetOrCreate().deleteProp(key);
1213    }
1214    /**
1215     * Persist given AppStorage properties with given names.
1216     * If a property does not exist in AppStorage, add it and initialize it with given value
1217     * works as @see PersistProp for multiple properties.
1218     *
1219     * @param properties
1220     *
1221     * @since 9
1222     *
1223     */
1224    static PersistProps(properties) {
1225        PersistentStorage.GetOrCreate().persistProps(properties);
1226    }
1227    /**
1228     * Inform persisted AppStorage property names
1229     * @returns array of AppStorage keys
1230     *
1231     * @since 9
1232     */
1233    static Keys() {
1234        let result = [];
1235        const it = PersistentStorage.GetOrCreate().keys();
1236        let val = it.next();
1237        while (!val.done) {
1238            result.push(val.value);
1239            val = it.next();
1240        }
1241        return result;
1242    }
1243    /**
1244      * This methid offers a way to force writing the property value with given
1245      * key to persistent storage.
1246      * In the general case this is unnecessary as the framework observed changes
1247      * and triggers writing to disk by itself. For nested objects (e.g. array of
1248      * objects) however changes of a property of a property as not observed. This
1249      * is the case where the application needs to signal to the framework.
1250      *
1251      * @param key property that has changed
1252      *
1253      * @since 9
1254      *
1255      */
1256    static NotifyHasChanged(propName) {
1257
1258        PersistentStorage.Storage_.set(propName, PersistentStorage.GetOrCreate().links_.get(propName).get());
1259    }
1260    keys() {
1261        return this.links_.keys();
1262    }
1263    persistProp(propName, defaultValue) {
1264        if (this.persistProp1(propName, defaultValue)) {
1265            // persist new prop
1266
1267            PersistentStorage.Storage_.set(propName, this.links_.get(propName).get());
1268        }
1269    }
1270    // helper function to persist a property
1271    // does everything except writing prop to disk
1272    persistProp1(propName, defaultValue) {
1273        if (defaultValue == null || defaultValue == undefined) {
1274            stateMgmtConsole.error(`PersistentStorage: persistProp for ${propName} called with 'null' or 'undefined' default value!`);
1275            return false;
1276        }
1277        if (this.links_.get(propName)) {
1278            stateMgmtConsole.warn(`PersistentStorage: persistProp: ${propName} is already persisted`);
1279            return false;
1280        }
1281        let link = AppStorage.Link(propName, this);
1282        if (link) {
1283
1284            this.links_.set(propName, link);
1285        }
1286        else {
1287            let newValue = PersistentStorage.Storage_.get(propName);
1288            let returnValue;
1289            if (!newValue) {
1290
1291                returnValue = defaultValue;
1292            }
1293            else {
1294                returnValue = newValue;
1295            }
1296            link = AppStorage.SetAndLink(propName, returnValue, this);
1297            this.links_.set(propName, link);
1298
1299        }
1300        return true;
1301    }
1302    persistProps(properties) {
1303        properties.forEach(property => this.persistProp1(property.key, property.defaultValue));
1304        this.write();
1305    }
1306    deleteProp(propName) {
1307        let link = this.links_.get(propName);
1308        if (link) {
1309            link.aboutToBeDeleted();
1310            this.links_.delete(propName);
1311            PersistentStorage.Storage_.delete(propName);
1312
1313        }
1314        else {
1315            stateMgmtConsole.warn(`PersistentStorage: '${propName}' is not a persisted property warning.`);
1316        }
1317    }
1318    write() {
1319        this.links_.forEach((link, propName, map) => {
1320
1321            PersistentStorage.Storage_.set(propName, link.get());
1322        });
1323    }
1324    propertyHasChanged(info) {
1325
1326        this.write();
1327    }
1328    // public required by the interface, use the static method instead!
1329    aboutToBeDeleted() {
1330
1331        this.links_.forEach((val, key, map) => {
1332
1333            val.aboutToBeDeleted();
1334        });
1335        this.links_.clear();
1336        SubscriberManager.Delete(this.id__());
1337        PersistentStorage.Storage_.clear();
1338    }
1339    id__() {
1340        return this.id_;
1341    }
1342}
1343PersistentStorage.Instance_ = undefined;
1344;
1345/*
1346 * Copyright (c) 2021 Huawei Device Co., Ltd.
1347 * Licensed under the Apache License, Version 2.0 (the "License");
1348 * you may not use this file except in compliance with the License.
1349 * You may obtain a copy of the License at
1350 *
1351 *     http://www.apache.org/licenses/LICENSE-2.0
1352 *
1353 * Unless required by applicable law or agreed to in writing, software
1354 * distributed under the License is distributed on an "AS IS" BASIS,
1355 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1356 * See the License for the specific language governing permissions and
1357 * limitations under the License.
1358 */
1359/**
1360 * Environment
1361 *
1362 * Injects device properties ("environment") into AppStorage
1363 *
1364 */
1365class Environment {
1366    constructor() {
1367        this.props_ = new Map();
1368        Environment.EnvBackend_.onValueChanged(this.onValueChanged.bind(this));
1369    }
1370    static GetOrCreate() {
1371        if (Environment.Instance_) {
1372            // already initialized
1373            return Environment.Instance_;
1374        }
1375        Environment.Instance_ = new Environment();
1376        return Environment.Instance_;
1377    }
1378    static ConfigureBackend(envBackend) {
1379        Environment.EnvBackend_ = envBackend;
1380    }
1381    static AboutToBeDeleted() {
1382        if (!Environment.Instance_) {
1383            return;
1384        }
1385        Environment.GetOrCreate().aboutToBeDeleted();
1386        Environment.Instance_ = undefined;
1387    }
1388    static EnvProp(key, value) {
1389        return Environment.GetOrCreate().envProp(key, value);
1390    }
1391    static EnvProps(props) {
1392        Environment.GetOrCreate().envProps(props);
1393    }
1394    static Keys() {
1395        return Environment.GetOrCreate().keys();
1396    }
1397    envProp(key, value) {
1398        let prop = AppStorage.Prop(key);
1399        if (prop) {
1400            stateMgmtConsole.warn(`Environment: envProp '${key}': Property already exists in AppStorage. Not using environment property.`);
1401            return false;
1402        }
1403        let tmp;
1404        switch (key) {
1405            case "accessibilityEnabled":
1406                tmp = Environment.EnvBackend_.getAccessibilityEnabled();
1407                break;
1408            case "colorMode":
1409                tmp = Environment.EnvBackend_.getColorMode();
1410                break;
1411            case "fontScale":
1412                tmp = Environment.EnvBackend_.getFontScale();
1413                break;
1414            case "fontWeightScale":
1415                tmp = Environment.EnvBackend_.getFontWeightScale().toFixed(2);
1416                break;
1417            case "layoutDirection":
1418                tmp = Environment.EnvBackend_.getLayoutDirection();
1419                break;
1420            case "languageCode":
1421                tmp = Environment.EnvBackend_.getLanguageCode();
1422                break;
1423            default:
1424                tmp = value;
1425        }
1426        prop = AppStorage.SetAndProp(key, tmp);
1427        this.props_.set(key, prop);
1428
1429    }
1430    envProps(properties) {
1431        properties.forEach(property => {
1432            this.envProp(property.key, property.defaultValue);
1433
1434        });
1435    }
1436    keys() {
1437        let result = [];
1438        const it = this.props_.keys();
1439        let val = it.next();
1440        while (!val.done) {
1441            result.push(val.value);
1442            val = it.next();
1443        }
1444        return result;
1445    }
1446    onValueChanged(key, value) {
1447        let ok = AppStorage.Set(key, value);
1448        if (ok) {
1449
1450        }
1451        else {
1452            stateMgmtConsole.warn(`Environment: onValueChanged: error changing ${key}! See results above.`);
1453        }
1454    }
1455    aboutToBeDeleted() {
1456        this.props_.forEach((val, key, map) => {
1457            val.aboutToBeDeleted();
1458            AppStorage.Delete(key);
1459        });
1460    }
1461}
1462Environment.Instance_ = undefined;
1463/*
1464 * Copyright (c) 2022 Huawei Device Co., Ltd.
1465 * Licensed under the Apache License, Version 2.0 (the "License");
1466 * you may not use this file except in compliance with the License.
1467 * You may obtain a copy of the License at
1468 *
1469 *     http://www.apache.org/licenses/LICENSE-2.0
1470 *
1471 * Unless required by applicable law or agreed to in writing, software
1472 * distributed under the License is distributed on an "AS IS" BASIS,
1473 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1474 * See the License for the specific language governing permissions and
1475 * limitations under the License.
1476 */
1477/**
1478 * state mgmt library uses its own class for logging
1479* allows to remap separately from other use of aceConsole
1480*
1481* everything in this file is framework internal
1482*/
1483class stateMgmtConsole {
1484    static log(...args) {
1485        aceConsole.log(...args);
1486    }
1487    static debug(...args) {
1488        aceConsole.debug(...args);
1489    }
1490    static info(...args) {
1491        aceConsole.info(...args);
1492    }
1493    static warn(...args) {
1494        aceConsole.warn(...args);
1495    }
1496    static error(...args) {
1497        aceConsole.error(...args);
1498    }
1499}
1500/*
1501 * Copyright (c) 2022 Huawei Device Co., Ltd.
1502 * Licensed under the Apache License, Version 2.0 (the "License");
1503 * you may not use this file except in compliance with the License.
1504 * You may obtain a copy of the License at
1505 *
1506 *     http://www.apache.org/licenses/LICENSE-2.0
1507 *
1508 * Unless required by applicable law or agreed to in writing, software
1509 * distributed under the License is distributed on an "AS IS" BASIS,
1510 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1511 * See the License for the specific language governing permissions and
1512 * limitations under the License.
1513 */
1514class DistributedStorage {
1515    constructor(sessionId, notifier) {
1516        this.links_ = new Map();
1517        this.id_ = SubscriberManager.MakeId();
1518        SubscriberManager.Add(this);
1519        this.aviliable_ = false;
1520        this.notifier_ = notifier;
1521    }
1522    keys() {
1523        let result = [];
1524        const it = this.links_.keys();
1525        let val = it.next();
1526        while (!val.done) {
1527            result.push(val.value);
1528            val = it.next();
1529        }
1530        return result;
1531    }
1532    distributeProp(propName, defaultValue) {
1533        if (this.link(propName, defaultValue)) {
1534
1535        }
1536    }
1537    distributeProps(properties) {
1538        properties.forEach(property => this.link(property.key, property.defaultValue));
1539    }
1540    link(propName, defaultValue) {
1541        if (defaultValue == null || defaultValue == undefined) {
1542            stateMgmtConsole.error(`DistributedStorage: linkProp for ${propName} called with 'null' or 'undefined' default value!`);
1543            return false;
1544        }
1545        if (this.links_.get(propName)) {
1546            stateMgmtConsole.warn(`DistributedStorage: linkProp: ${propName} is already exist`);
1547            return false;
1548        }
1549        let link = AppStorage.Link(propName, this);
1550        if (link) {
1551
1552            this.links_.set(propName, link);
1553            this.setDistributedProp(propName, defaultValue);
1554        }
1555        else {
1556            let returnValue = defaultValue;
1557            if (this.aviliable_) {
1558                let newValue = this.getDistributedProp(propName);
1559                if (newValue == null) {
1560
1561                    this.setDistributedProp(propName, defaultValue);
1562                }
1563                else {
1564                    returnValue = newValue;
1565                }
1566            }
1567            link = AppStorage.SetAndLink(propName, returnValue, this);
1568            this.links_.set(propName, link);
1569
1570        }
1571        return true;
1572    }
1573    deleteProp(propName) {
1574        let link = this.links_.get(propName);
1575        if (link) {
1576            link.aboutToBeDeleted();
1577            this.links_.delete(propName);
1578            if (this.aviliable_) {
1579                this.storage_.delete(propName);
1580            }
1581        }
1582        else {
1583            stateMgmtConsole.warn(`DistributedStorage: '${propName}' is not a distributed property warning.`);
1584        }
1585    }
1586    write(key) {
1587        let link = this.links_.get(key);
1588        if (link) {
1589            this.setDistributedProp(key, link.get());
1590        }
1591    }
1592    // public required by the interface, use the static method instead!
1593    aboutToBeDeleted() {
1594
1595        this.links_.forEach((val, key, map) => {
1596
1597            val.aboutToBeDeleted();
1598        });
1599        this.links_.clear();
1600        SubscriberManager.Delete(this.id__());
1601    }
1602    id__() {
1603        return this.id_;
1604    }
1605    propertyHasChanged(info) {
1606
1607        this.write(info);
1608    }
1609    onDataOnChange(propName) {
1610        let link = this.links_.get(propName);
1611        let newValue = this.getDistributedProp(propName);
1612        if (link && newValue != null) {
1613
1614            link.set(newValue);
1615        }
1616    }
1617    onConnected(status) {
1618
1619        if (!this.aviliable_) {
1620            this.syncProp();
1621            this.aviliable_ = true;
1622        }
1623        if (this.notifier_ != null) {
1624            this.notifier_(status);
1625        }
1626    }
1627    syncProp() {
1628        this.links_.forEach((val, key) => {
1629            let newValue = this.getDistributedProp(key);
1630            if (newValue == null) {
1631                this.setDistributedProp(key, val.get());
1632            }
1633            else {
1634                val.set(newValue);
1635            }
1636        });
1637    }
1638    setDistributedProp(key, value) {
1639        if (!this.aviliable_) {
1640            stateMgmtConsole.warn(`DistributedStorage is not aviliable`);
1641            return;
1642        }
1643        stateMgmtConsole.error(`DistributedStorage value is object ${key}-${JSON.stringify(value)}`);
1644        if (typeof value == 'object') {
1645            this.storage_.set(key, JSON.stringify(value));
1646            return;
1647        }
1648        this.storage_.set(key, value);
1649    }
1650    getDistributedProp(key) {
1651        let value = this.storage_.get(key);
1652        if (typeof value == 'string') {
1653            try {
1654                let returnValue = JSON.parse(value);
1655                return returnValue;
1656            }
1657            finally {
1658                return value;
1659            }
1660        }
1661        return value;
1662    }
1663}
1664;
1665/*
1666 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
1667 * Licensed under the Apache License, Version 2.0 (the "License");
1668 * you may not use this file except in compliance with the License.
1669 * You may obtain a copy of the License at
1670 *
1671 *     http://www.apache.org/licenses/LICENSE-2.0
1672 *
1673 * Unless required by applicable law or agreed to in writing, software
1674 * distributed under the License is distributed on an "AS IS" BASIS,
1675 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1676 * See the License for the specific language governing permissions and
1677 * limitations under the License.
1678 */
1679/**
1680* @Observed Decorator function, use
1681*    @Observed class ClassA { ... }
1682* when defining ClassA
1683*
1684* Can also be used to create a new Object and wrap it in
1685* ObservedObject by calling
1686*   obsObj = Observed(ClassA)(params to ClassA constructor)
1687*
1688* Note this works only for classes, not for ClassA[]
1689* Also does not work for classes with genetics it seems
1690* In that case use factory function
1691*   obsObj = ObservedObject.createNew<ClassA[]>([])
1692*/
1693function Observed(target) {
1694    var original = target;
1695    // the new constructor behaviour
1696    var f = function (...args) {
1697
1698        return ObservedObject.createNew(new original(...args), undefined);
1699        //    return new ObservedObject<C>(new original(...args), undefined);
1700    };
1701    Object.setPrototypeOf(f, Object.getPrototypeOf(original));
1702    // return new constructor (will override original)
1703    return f;
1704}
1705class SubscribableHandler {
1706    constructor(owningProperty) {
1707        this.owningProperties_ = new Set();
1708        if (owningProperty) {
1709            this.addOwningProperty(owningProperty);
1710        }
1711
1712    }
1713    addOwningProperty(subscriber) {
1714        if (subscriber) {
1715
1716            this.owningProperties_.add(subscriber.id__());
1717        }
1718        else {
1719            stateMgmtConsole.warn(`SubscribableHandler: addOwningProperty: undefined subscriber. - Internal error?`);
1720        }
1721    }
1722    /*
1723        the inverse function of createOneWaySync or createTwoWaySync
1724      */
1725    removeOwningProperty(property) {
1726        return this.removeOwningPropertyById(property.id__());
1727    }
1728    removeOwningPropertyById(subscriberId) {
1729
1730        this.owningProperties_.delete(subscriberId);
1731    }
1732    notifyPropertyHasChanged(propName, newValue) {
1733
1734        this.owningProperties_.forEach((subscribedId) => {
1735            var owningProperty = SubscriberManager.Find(subscribedId);
1736            if (owningProperty) {
1737                if ('hasChanged' in owningProperty) {
1738                    owningProperty.hasChanged(newValue);
1739                }
1740                if ('propertyHasChanged' in owningProperty) {
1741                    owningProperty.propertyHasChanged(propName);
1742                }
1743            }
1744            else {
1745                stateMgmtConsole.warn(`SubscribableHandler: notifyHasChanged: unknown subscriber.'${subscribedId}' error!.`);
1746            }
1747        });
1748    }
1749    get(target, property) {
1750        return (property === SubscribableHandler.IS_OBSERVED_OBJECT) ? true :
1751            (property === SubscribableHandler.RAW_OBJECT) ? target : target[property];
1752    }
1753    set(target, property, newValue) {
1754        switch (property) {
1755            case SubscribableHandler.SUBSCRIBE:
1756                // assignment obsObj[SubscribableHandler.SUBSCRCRIBE] = subscriber
1757                this.addOwningProperty(newValue);
1758                return true;
1759                break;
1760            case SubscribableHandler.UNSUBSCRIBE:
1761                // assignment obsObj[SubscribableHandler.UN_SUBSCRCRIBE] = subscriber
1762                this.removeOwningProperty(newValue);
1763                return true;
1764                break;
1765            default:
1766                if (target[property] == newValue) {
1767                    return true;
1768                }
1769                target[property] = newValue;
1770                this.notifyPropertyHasChanged(property.toString(), newValue);
1771                return true;
1772                break;
1773        }
1774        // unreachable
1775        return false;
1776    }
1777}
1778SubscribableHandler.IS_OBSERVED_OBJECT = Symbol("_____is_observed_object__");
1779SubscribableHandler.RAW_OBJECT = Symbol("_____raw_object__");
1780SubscribableHandler.SUBSCRIBE = Symbol("_____subscribe__");
1781SubscribableHandler.UNSUBSCRIBE = Symbol("_____unsubscribe__");
1782class ExtendableProxy {
1783    constructor(obj, handler) {
1784        return new Proxy(obj, handler);
1785    }
1786}
1787class ObservedObject extends ExtendableProxy {
1788    /**
1789     * Factory function for ObservedObjects /
1790     *  wrapping of objects for proxying
1791     *
1792     * @param rawObject unproxied Object or ObservedObject
1793     * @param objOwner owner of this Object to sign uop for propertyChange
1794     *          notifications
1795     * @returns the rawObject if object is already an ObservedObject,
1796     *          otherwise the newly created ObservedObject
1797     */
1798    static createNew(rawObject, owningProperty) {
1799        if (rawObject === null || rawObject === undefined) {
1800            stateMgmtConsole.error(`ObservedObject.CreateNew, input object must not be null or undefined.`);
1801            return null;
1802        }
1803        if (ObservedObject.IsObservedObject(rawObject)) {
1804            ObservedObject.addOwningProperty(rawObject, owningProperty);
1805            return rawObject;
1806        }
1807        else {
1808            return new ObservedObject(rawObject, owningProperty);
1809        }
1810    }
1811    /*
1812      Return the unproxied object 'inside' the ObservedObject / the ES6 Proxy
1813      no set observation, no notification of changes!
1814      Use with caution, do not store any references
1815    */
1816    static GetRawObject(obj) {
1817        return !ObservedObject.IsObservedObject(obj) ? obj : obj[SubscribableHandler.RAW_OBJECT];
1818    }
1819    /**
1820     *
1821     * @param obj anything
1822     * @returns true if the parameter is an Object wrpped with a ObservedObject
1823     * Note: Since ES6 Proying is transparent, 'instance of' will not work. Use
1824     * this static function instead.
1825     */
1826    static IsObservedObject(obj) {
1827        return obj ? (obj[SubscribableHandler.IS_OBSERVED_OBJECT] === true) : false;
1828    }
1829    static addOwningProperty(obj, subscriber) {
1830        if (!ObservedObject.IsObservedObject(obj)) {
1831            return false;
1832        }
1833        obj[SubscribableHandler.SUBSCRIBE] = subscriber;
1834        return true;
1835    }
1836    static removeOwningProperty(obj, subscriber) {
1837        if (!ObservedObject.IsObservedObject(obj)) {
1838            return false;
1839        }
1840        obj[SubscribableHandler.UNSUBSCRIBE] = subscriber;
1841        return true;
1842    }
1843    /**
1844     * Create a new ObservableObject and subscribe its owner to propertyHasChanged
1845     * ntifications
1846     * @param obj  raw Object, if obj is a ObservableOject throws an error
1847     * @param objectOwner
1848     */
1849    constructor(obj, objectOwningProperty) {
1850        if (ObservedObject.IsObservedObject(obj)) {
1851            throw new Error("Invalid constructor argument error: ObservableObject contructor called with an ObservedObject as parameer");
1852        }
1853        let handler = new SubscribableHandler(objectOwningProperty);
1854        super(obj, handler);
1855        if (ObservedObject.IsObservedObject(obj)) {
1856            stateMgmtConsole.error("ObservableOject constructor: INTERNAL ERROR: after jsObj is observedObject already");
1857        }
1858    } // end of constructor
1859}
1860/*
1861 * Copyright (c) 2021 Huawei Device Co., Ltd.
1862 * Licensed under the Apache License, Version 2.0 (the "License");
1863 * you may not use this file except in compliance with the License.
1864 * You may obtain a copy of the License at
1865 *
1866 *     http://www.apache.org/licenses/LICENSE-2.0
1867 *
1868 * Unless required by applicable law or agreed to in writing, software
1869 * distributed under the License is distributed on an "AS IS" BASIS,
1870 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1871 * See the License for the specific language governing permissions and
1872 * limitations under the License.
1873 */
1874/*
1875   manage subscriptions to a property
1876   managing the property is left to sub
1877   classes
1878   Extended by ObservedProperty, SyncedPropertyOneWay
1879   and SyncedPropertyTwoWay
1880*/
1881class ObservedPropertyAbstract extends SubscribedAbstractProperty {
1882    constructor(subscribeMe, info) {
1883        super();
1884        this.subscribers_ = new Set();
1885        this.id_ = SubscriberManager.MakeId();
1886        SubscriberManager.Add(this);
1887        if (subscribeMe) {
1888            this.subscribers_.add(subscribeMe.id__());
1889        }
1890        if (info) {
1891            this.info_ = info;
1892        }
1893    }
1894    aboutToBeDeleted() {
1895        SubscriberManager.Delete(this.id__());
1896    }
1897    id__() {
1898        return this.id_;
1899    }
1900    info() {
1901        return this.info_;
1902    }
1903    setInfo(propName) {
1904        if (propName && propName != "") {
1905            this.info_ = propName;
1906        }
1907    }
1908    // Partial Update "*PU" classes will overwrite
1909    getUnmonitored() {
1910        return this.get();
1911    }
1912    subscribeMe(subscriber) {
1913
1914        this.subscribers_.add(subscriber.id__());
1915    }
1916    /*
1917      the inverse function of createOneWaySync or createTwoWaySync
1918    */
1919    unlinkSuscriber(subscriberId) {
1920        this.subscribers_.delete(subscriberId);
1921    }
1922    notifyHasChanged(newValue) {
1923
1924        this.subscribers_.forEach((subscribedId) => {
1925            var subscriber = SubscriberManager.Find(subscribedId);
1926            if (subscriber) {
1927                if ('hasChanged' in subscriber) {
1928                    subscriber.hasChanged(newValue);
1929                }
1930                if ('propertyHasChanged' in subscriber) {
1931                    subscriber.propertyHasChanged(this.info_);
1932                }
1933            }
1934            else {
1935                stateMgmtConsole.warn(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: notifyHasChanged: unknown subscriber ID '${subscribedId}' error!`);
1936            }
1937        });
1938    }
1939    notifyPropertyRead() {
1940
1941        this.subscribers_.forEach((subscribedId) => {
1942            var subscriber = SubscriberManager.Find(subscribedId);
1943            if (subscriber) {
1944                if ('propertyRead' in subscriber) {
1945                    subscriber.propertyRead(this.info_);
1946                }
1947            }
1948        });
1949    }
1950    /*
1951    return numebr of subscribers to this property
1952    mostly useful for unit testin
1953    */
1954    numberOfSubscrbers() {
1955        return this.subscribers_.size;
1956    }
1957    /**
1958     * provide a factory function that creates a SynchedPropertyXXXX of choice
1959     * that uses 'this' as source
1960     * @param factoryFunc
1961     * @returns
1962     */
1963    createSync(factoryFunc) {
1964        return factoryFunc(this);
1965    }
1966    /**
1967     * depreciated SDK function, not used anywhere by the framework
1968     */
1969    createTwoWaySync(subscribeMe, info) {
1970        stateMgmtConsole.warn("Using depreciated method 'createTwoWaySync'!");
1971        return this.createLink(subscribeMe, info);
1972    }
1973    /**
1974     * depreciated SDK function, not used anywhere by the framework
1975     */
1976    createOneWaySync(subscribeMe, info) {
1977        stateMgmtConsole.warn("Using depreciated method 'createOneWaySync' !");
1978        return this.createProp(subscribeMe, info);
1979    }
1980    /**
1981     * factory function for concrete 'object' or 'simple' ObservedProperty object
1982     * depending if value is Class object
1983     * or simple type (boolean | number | string)
1984     * @param value
1985     * @param owningView
1986     * @param thisPropertyName
1987     * @returns either
1988     */
1989    static CreateObservedObject(value, owningView, thisPropertyName) {
1990        return (typeof value === "object") ?
1991            new ObservedPropertyObject(value, owningView, thisPropertyName)
1992            : new ObservedPropertySimple(value, owningView, thisPropertyName);
1993    }
1994}
1995/*
1996 * Copyright (c) 2021 Huawei Device Co., Ltd.
1997 * Licensed under the Apache License, Version 2.0 (the "License");
1998 * you may not use this file except in compliance with the License.
1999 * You may obtain a copy of the License at
2000 *
2001 *     http://www.apache.org/licenses/LICENSE-2.0
2002 *
2003 * Unless required by applicable law or agreed to in writing, software
2004 * distributed under the License is distributed on an "AS IS" BASIS,
2005 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2006 * See the License for the specific language governing permissions and
2007 * limitations under the License.
2008 */
2009/**
2010 * ObservedPropertyObjectAbstract
2011 *
2012 * all definitions in this file are framework internal
2013 *
2014 * common base class of ObservedPropertyObject and
2015 * SyncedObjectPropertyTwoWay
2016 * adds the createObjectLink to the ObservedPropertyAbstract base
2017 */
2018class ObservedPropertyObjectAbstract extends ObservedPropertyAbstract {
2019    constructor(owningView, thisPropertyName) {
2020        super(owningView, thisPropertyName);
2021    }
2022}
2023/*
2024 * Copyright (c) 2021 Huawei Device Co., Ltd.
2025 * Licensed under the Apache License, Version 2.0 (the "License");
2026 * you may not use this file except in compliance with the License.
2027 * You may obtain a copy of the License at
2028 *
2029 *     http://www.apache.org/licenses/LICENSE-2.0
2030 *
2031 * Unless required by applicable law or agreed to in writing, software
2032 * distributed under the License is distributed on an "AS IS" BASIS,
2033 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2034 * See the License for the specific language governing permissions and
2035 * limitations under the License.
2036 */
2037/**
2038 *
2039 * ObservedPropertySimpleAbstract
2040 *
2041 * all definitions in this file are framework internal
2042 */
2043class ObservedPropertySimpleAbstract extends ObservedPropertyAbstract {
2044    constructor(owningView, propertyName) {
2045        super(owningView, propertyName);
2046    }
2047}
2048/*
2049 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2050 * Licensed under the Apache License, Version 2.0 (the "License");
2051 * you may not use this file except in compliance with the License.
2052 * You may obtain a copy of the License at
2053 *
2054 *     http://www.apache.org/licenses/LICENSE-2.0
2055 *
2056 * Unless required by applicable law or agreed to in writing, software
2057 * distributed under the License is distributed on an "AS IS" BASIS,
2058 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2059 * See the License for the specific language governing permissions and
2060 * limitations under the License.
2061 */
2062/**
2063 * ObservedPropertyObject
2064 *
2065 * all definitions in this file are framework internal
2066 *
2067 * class that holds an actual property value of type T
2068 * uses its base class to manage subscribers to this
2069 * property.
2070*/
2071class ObservedPropertyObject extends ObservedPropertyObjectAbstract {
2072    constructor(value, owningView, propertyName) {
2073        super(owningView, propertyName);
2074        this.setValueInternal(value);
2075    }
2076    aboutToBeDeleted(unsubscribeMe) {
2077        this.unsubscribeFromOwningProperty();
2078        if (unsubscribeMe) {
2079            this.unlinkSuscriber(unsubscribeMe.id__());
2080        }
2081        super.aboutToBeDeleted();
2082    }
2083    // notification from ObservedObject value one of its
2084    // props has chnaged. Implies the ObservedProperty has changed
2085    // Note: this function gets called when in this case:
2086    //       thisProp.aObsObj.aProp = 47  a object prop gets changed
2087    // It is NOT called when
2088    //    thisProp.aObsObj = new ClassA
2089    hasChanged(newValue) {
2090
2091        this.notifyHasChanged(this.wrappedValue_);
2092    }
2093    unsubscribeFromOwningProperty() {
2094        if (this.wrappedValue_) {
2095            if (this.wrappedValue_ instanceof SubscribaleAbstract) {
2096                this.wrappedValue_.removeOwningProperty(this);
2097            }
2098            else {
2099                ObservedObject.removeOwningProperty(this.wrappedValue_, this);
2100            }
2101        }
2102    }
2103    /*
2104      actually update this.wrappedValue_
2105      called needs to do value change check
2106      and also notify with this.aboutToChange();
2107    */
2108    setValueInternal(newValue) {
2109        if (typeof newValue !== 'object') {
2110
2111            return false;
2112        }
2113        this.unsubscribeFromOwningProperty();
2114        if (ObservedObject.IsObservedObject(newValue)) {
2115
2116            ObservedObject.addOwningProperty(newValue, this);
2117            this.wrappedValue_ = newValue;
2118        }
2119        else if (newValue instanceof SubscribaleAbstract) {
2120
2121            this.wrappedValue_ = newValue;
2122            this.wrappedValue_.addOwningProperty(this);
2123        }
2124        else {
2125
2126            this.wrappedValue_ = ObservedObject.createNew(newValue, this);
2127        }
2128        return true;
2129    }
2130    get() {
2131
2132        this.notifyPropertyRead();
2133        return this.wrappedValue_;
2134    }
2135    set(newValue) {
2136        if (this.wrappedValue_ == newValue) {
2137
2138            return;
2139        }
2140
2141        this.setValueInternal(newValue);
2142        this.notifyHasChanged(newValue);
2143    }
2144    /**
2145     * These functions are used
2146     *   LocalStorage.link  (also in partial update config)
2147     *   (FU)View.initializeConsumeinitializeConsume
2148     */
2149    createLink(subscribeOwner, linkPropName) {
2150        return new SynchedPropertyObjectTwoWay(this, subscribeOwner, linkPropName);
2151    }
2152    createProp(subscribeOwner, linkPropName) {
2153        throw new Error("Creating a 'Prop' property is unsupported for Object type property value.");
2154    }
2155}
2156/*
2157 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2158 * Licensed under the Apache License, Version 2.0 (the "License");
2159 * you may not use this file except in compliance with the License.
2160 * You may obtain a copy of the License at
2161 *
2162 *     http://www.apache.org/licenses/LICENSE-2.0
2163 *
2164 * Unless required by applicable law or agreed to in writing, software
2165 * distributed under the License is distributed on an "AS IS" BASIS,
2166 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2167 * See the License for the specific language governing permissions and
2168 * limitations under the License.
2169 */
2170/**
2171 * ObservedPropertySimple
2172 *
2173 * all definitions in this file are framework internal
2174 */
2175class ObservedPropertySimple extends ObservedPropertySimpleAbstract {
2176    constructor(value, owningView, propertyName) {
2177        super(owningView, propertyName);
2178        if (typeof value === "object") {
2179            throw new SyntaxError("ObservedPropertySimple value must not be an object");
2180        }
2181        this.setValueInternal(value);
2182    }
2183    aboutToBeDeleted(unsubscribeMe) {
2184        if (unsubscribeMe) {
2185            this.unlinkSuscriber(unsubscribeMe.id__());
2186        }
2187        super.aboutToBeDeleted();
2188    }
2189    hasChanged(newValue) {
2190
2191        this.notifyHasChanged(this.wrappedValue_);
2192    }
2193    /*
2194      actually update this.wrappedValue_
2195      called needs to do value change check
2196      and also notify with this.aboutToChange();
2197    */
2198    setValueInternal(newValue) {
2199
2200        this.wrappedValue_ = newValue;
2201    }
2202    get() {
2203
2204        this.notifyPropertyRead();
2205        return this.wrappedValue_;
2206    }
2207    set(newValue) {
2208        if (this.wrappedValue_ == newValue) {
2209
2210            return;
2211        }
2212
2213        this.setValueInternal(newValue);
2214        this.notifyHasChanged(newValue);
2215    }
2216    /**
2217   * These functions are meant for use in connection with the App Stoage and
2218   * business logic implementation.
2219   * the created Link and Prop will update when 'this' property value
2220   * changes.
2221   */
2222    createLink(subscribeOwner, linkPropName) {
2223        return ((subscribeOwner !== undefined) && ("rerender" in subscribeOwner)) ?
2224            new SynchedPropertySimpleTwoWayPU(this, subscribeOwner, linkPropName) :
2225            new SynchedPropertySimpleTwoWay(this, subscribeOwner, linkPropName);
2226    }
2227    createProp(subscribeOwner, linkPropName) {
2228        return new SynchedPropertySimpleOneWaySubscribing(this, subscribeOwner, linkPropName);
2229    }
2230}
2231/*
2232 * Copyright (c) 2021 Huawei Device Co., Ltd.
2233 * Licensed under the Apache License, Version 2.0 (the "License");
2234 * you may not use this file except in compliance with the License.
2235 * You may obtain a copy of the License at
2236 *
2237 *     http://www.apache.org/licenses/LICENSE-2.0
2238 *
2239 * Unless required by applicable law or agreed to in writing, software
2240 * distributed under the License is distributed on an "AS IS" BASIS,
2241 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2242 * See the License for the specific language governing permissions and
2243 * limitations under the License.
2244 */
2245/**
2246 * SynchedPropertyObjectTwoWay
2247 *
2248 * all definitions in this file are framework internal
2249 */
2250class SynchedPropertyObjectTwoWay extends ObservedPropertyObjectAbstract {
2251    constructor(linkSource, owningChildView, thisPropertyName) {
2252        super(owningChildView, thisPropertyName);
2253        this.changeNotificationIsOngoing_ = false;
2254        this.linkedParentProperty_ = linkSource;
2255        // register to the parent property
2256        this.linkedParentProperty_.subscribeMe(this);
2257        // register to the ObservedObject
2258        ObservedObject.addOwningProperty(this.getObject(), this);
2259    }
2260    /*
2261    like a destructor, need to call this before deleting
2262    the property.
2263    */
2264    aboutToBeDeleted() {
2265        if (this.linkedParentProperty_) {
2266            // unregister from parent of this link
2267            this.linkedParentProperty_.unlinkSuscriber(this.id__());
2268            // unregister from the ObservedObject
2269            ObservedObject.removeOwningProperty(this.getObject(), this);
2270        }
2271        super.aboutToBeDeleted();
2272    }
2273    getObject() {
2274        this.notifyPropertyRead();
2275        return (this.linkedParentProperty_ ? this.linkedParentProperty_.get() : undefined);
2276    }
2277    setObject(newValue) {
2278        if (this.linkedParentProperty_) {
2279            this.linkedParentProperty_.set(newValue);
2280        }
2281    }
2282    // this object is subscriber to ObservedObject
2283    // will call this cb function when property has changed
2284    hasChanged(newValue) {
2285        if (!this.changeNotificationIsOngoing_) {
2286
2287            this.notifyHasChanged(this.getObject());
2288        }
2289    }
2290    // get 'read through` from the ObservedProperty
2291    get() {
2292
2293        return this.getObject();
2294    }
2295    // set 'writes through` to the ObservedProperty
2296    set(newValue) {
2297        if (this.getObject() == newValue) {
2298
2299            return;
2300        }
2301
2302        ObservedObject.removeOwningProperty(this.getObject(), this);
2303        // the purpose of the changeNotificationIsOngoing_ is to avoid
2304        // circular notifications @Link -> source @State -> other but alos same @Link
2305        this.changeNotificationIsOngoing_ = true;
2306        this.setObject(newValue);
2307        ObservedObject.addOwningProperty(this.getObject(), this);
2308        this.notifyHasChanged(newValue);
2309        this.changeNotificationIsOngoing_ = false;
2310    }
2311    /**
2312   * These functions are meant for use in connection with the App Stoage and
2313   * business logic implementation.
2314   * the created Link and Prop will update when 'this' property value
2315   * changes.
2316   */
2317    createLink(subscribeOwner, linkPropName) {
2318        return new SynchedPropertyObjectTwoWay(this, subscribeOwner, linkPropName);
2319    }
2320    createProp(subscribeOwner, linkPropName) {
2321        throw new Error("Creating a 'Prop' property is unsupported for Object type property value.");
2322    }
2323}
2324/*
2325 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2326 * Licensed under the Apache License, Version 2.0 (the "License");
2327 * you may not use this file except in compliance with the License.
2328 * You may obtain a copy of the License at
2329 *
2330 *     http://www.apache.org/licenses/LICENSE-2.0
2331 *
2332 * Unless required by applicable law or agreed to in writing, software
2333 * distributed under the License is distributed on an "AS IS" BASIS,
2334 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2335 * See the License for the specific language governing permissions and
2336 * limitations under the License.
2337 */
2338/**
2339 * SynchedPropertySimpleOneWay
2340 *
2341 * all definitions in this file are framework internal
2342 */
2343class SynchedPropertySimpleOneWay extends ObservedPropertySimpleAbstract {
2344    constructor(value, subscribeMe, info) {
2345        super(subscribeMe, info);
2346        // add a test here that T is a simple type
2347        this.wrappedValue_ = value;
2348    }
2349    /*
2350      like a destructor, need to call this before deleting
2351      the property.
2352    */
2353    aboutToBeDeleted() {
2354        super.aboutToBeDeleted();
2355    }
2356    // get 'read through` from the ObservedProperty
2357    get() {
2358
2359        this.notifyPropertyRead();
2360        return this.wrappedValue_;
2361    }
2362    set(newValue) {
2363        if (this.wrappedValue_ == newValue) {
2364
2365            return;
2366        }
2367
2368        this.wrappedValue_ = newValue;
2369        this.notifyHasChanged(newValue);
2370    }
2371    /**
2372     * These functions are meant for use in connection with the App Stoage and
2373     * business logic implementation.
2374     * the created Link and Prop will update when 'this' property value
2375     * changes.
2376     */
2377    createLink(subscribeOwner, linkPropName) {
2378        throw new Error("Can not create a 'Link' from a 'Prop' property. ");
2379    }
2380    createProp(subscribeOwner, linkPropName) {
2381        throw new Error("Method not supported, create a SynchedPropertySimpleOneWaySubscribing from, where to create a Prop.");
2382    }
2383}
2384/*
2385  This exrension of SynchedPropertySimpleOneWay needs to be used for AppStorage
2386  because it needs to be notified about the source property changing
2387  ( there is no re-render process as in Views to update the wrappedValue )
2388*/
2389class SynchedPropertySimpleOneWaySubscribing extends SynchedPropertySimpleOneWay {
2390    constructor(linkedProperty, subscribeMe, info) {
2391        super(linkedProperty.get(), subscribeMe, info);
2392        this.linkedParentProperty_ = linkedProperty;
2393        this.linkedParentProperty_.subscribeMe(this);
2394    }
2395    aboutToBeDeleted() {
2396        // unregister from parent of this prop
2397        this.linkedParentProperty_.unlinkSuscriber(this.id__());
2398        super.aboutToBeDeleted();
2399    }
2400    hasChanged(newValue) {
2401
2402        this.set(newValue);
2403    }
2404    /**
2405     * These functions are meant for use in connection with the App Stoage and
2406     * business logic implementation.
2407     * the created Link and Prop will update when 'this' property value
2408     * changes.
2409     */
2410    createLink(subscribeOwner, linkPropName) {
2411        throw new Error("Can not create a 'Link' from a 'Prop' property. ");
2412    }
2413    createProp(subscribeOwner, propPropName) {
2414        return new SynchedPropertySimpleOneWaySubscribing(this, subscribeOwner, propPropName);
2415    }
2416}
2417/*
2418 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2419 * Licensed under the Apache License, Version 2.0 (the "License");
2420 * you may not use this file except in compliance with the License.
2421 * You may obtain a copy of the License at
2422 *
2423 *     http://www.apache.org/licenses/LICENSE-2.0
2424 *
2425 * Unless required by applicable law or agreed to in writing, software
2426 * distributed under the License is distributed on an "AS IS" BASIS,
2427 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2428 * See the License for the specific language governing permissions and
2429 * limitations under the License.
2430 */
2431/**
2432 * SynchedPropertySimpleTwoWay
2433 *
2434 * all definitions in this file are framework internal
2435 */
2436class SynchedPropertySimpleTwoWay extends ObservedPropertySimpleAbstract {
2437    constructor(source, owningView, owningViewPropNme) {
2438        super(owningView, owningViewPropNme);
2439        this.changeNotificationIsOngoing_ = false;
2440        this.source_ = source;
2441        this.source_.subscribeMe(this);
2442    }
2443    /*
2444    like a destructor, need to call this before deleting
2445    the property.
2446  */
2447    aboutToBeDeleted() {
2448        if (this.source_) {
2449            this.source_.unlinkSuscriber(this.id__());
2450            this.source_ = undefined;
2451        }
2452        super.aboutToBeDeleted();
2453    }
2454    // this object is subscriber to  SynchedPropertySimpleTwoWay
2455    // will call this cb function when property has changed
2456    // a set (newValue) is not done because get reads through for the source_
2457    hasChanged(newValue) {
2458        if (!this.changeNotificationIsOngoing_) {
2459
2460            this.notifyHasChanged(newValue);
2461        }
2462    }
2463    // get 'read through` from the ObservedProperty
2464    get() {
2465
2466        if (!this.source_) {
2467            stateMgmtConsole.error(`SynchedPropertySimpleTwoWay[${this.id__()}IP, '${this.info() || "unknown"}'] source_ is undefined: get value is undefined.`);
2468            return undefined;
2469        }
2470        this.notifyPropertyRead();
2471        return this.source_.get();
2472    }
2473    // set 'writes through` to the ObservedProperty
2474    set(newValue) {
2475        if (!this.source_) {
2476            stateMgmtConsole.error(`SynchedPropertySimpleTwoWay[${this.id__()}IP, '${this.info() || "unknown"}'] source_ is undefined: set '${newValue}' ignoring.`);
2477            return;
2478        }
2479        if (this.source_.get() == newValue) {
2480
2481            return;
2482        }
2483
2484        // the source_ ObservedProeprty will call: this.hasChanged(newValue);
2485        // the purpose of the changeNotificationIsOngoing_ is to avoid
2486        // circular notifications @Link -> source @State -> other but alos same @Link
2487        this.changeNotificationIsOngoing_ = true;
2488        this.source_.set(newValue);
2489        this.notifyHasChanged(newValue);
2490        this.changeNotificationIsOngoing_ = false;
2491    }
2492    /**
2493  * These functions are meant for use in connection with the App Stoage and
2494  * business logic implementation.
2495  * the created Link and Prop will update when 'this' property value
2496  * changes.
2497  */
2498    createLink(subscribeOwner, linkPropName) {
2499        return new SynchedPropertySimpleTwoWay(this, subscribeOwner, linkPropName);
2500    }
2501    createProp(subscribeOwner, propPropName) {
2502        return new SynchedPropertySimpleOneWaySubscribing(this, subscribeOwner, propPropName);
2503    }
2504}
2505/*
2506 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2507 * Licensed under the Apache License, Version 2.0 (the "License");
2508 * you may not use this file except in compliance with the License.
2509 * You may obtain a copy of the License at
2510 *
2511 *     http://www.apache.org/licenses/LICENSE-2.0
2512 *
2513 * Unless required by applicable law or agreed to in writing, software
2514 * distributed under the License is distributed on an "AS IS" BASIS,
2515 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2516 * See the License for the specific language governing permissions and
2517 * limitations under the License.
2518 */
2519/**
2520 * SynchedPropertyNesedObject
2521 *
2522 * all definitions in this file are framework internal
2523 */
2524class SynchedPropertyNesedObject extends ObservedPropertyObjectAbstract {
2525    /**
2526     * Construct a Property of a su component that links to a variable of parent view that holds an ObservedObject
2527     * example
2528     *   this.b.$a with b of type PC and a of type C, or
2529     *   this.$b[5] with this.b of type PC and array item b[5] of type C;
2530     *
2531     * @param subscribeMe
2532     * @param propName
2533     */
2534    constructor(obsObject, owningChildView, propertyName) {
2535        super(owningChildView, propertyName);
2536        this.obsObject_ = obsObject;
2537        // register to the ObservedObject
2538        ObservedObject.addOwningProperty(this.obsObject_, this);
2539    }
2540    /*
2541    like a destructor, need to call this before deleting
2542    the property.
2543    */
2544    aboutToBeDeleted() {
2545        // unregister from the ObservedObject
2546        ObservedObject.removeOwningProperty(this.obsObject_, this);
2547        super.aboutToBeDeleted();
2548    }
2549    // this object is subscriber to ObservedObject
2550    // will call this cb function when property has changed
2551    hasChanged(newValue) {
2552
2553        this.notifyHasChanged(this.obsObject_);
2554    }
2555    // get 'read through` from the ObservedProperty
2556    get() {
2557
2558        this.notifyPropertyRead();
2559        return this.obsObject_;
2560    }
2561    // set 'writes through` to the ObservedProperty
2562    set(newValue) {
2563        if (this.obsObject_ == newValue) {
2564
2565            return;
2566        }
2567
2568        // unsubscribe from the old value ObservedObject
2569        ObservedObject.removeOwningProperty(this.obsObject_, this);
2570        this.obsObject_ = newValue;
2571        // subscribe to the new value ObservedObject
2572        ObservedObject.addOwningProperty(this.obsObject_, this);
2573        // notify value change to subscribing View
2574        this.notifyHasChanged(this.obsObject_);
2575    }
2576    /**
2577   * These functions are meant for use in connection with the App Stoage and
2578   * business logic implementation.
2579   * the created Link and Prop will update when 'this' property value
2580   * changes.
2581   */
2582    createLink(subscribeOwner, linkPropName) {
2583        throw new Error("Method not supported for property linking to a nested objects.");
2584    }
2585    createProp(subscribeOwner, linkPropName) {
2586        throw new Error("Creating a 'Prop' proerty is unsuppoeted for Object type prperty value.");
2587    }
2588}
2589/*
2590 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2591 * Licensed under the Apache License, Version 2.0 (the "License");
2592 * you may not use this file except in compliance with the License.
2593 * You may obtain a copy of the License at
2594 *
2595 *     http://www.apache.org/licenses/LICENSE-2.0
2596 *
2597 * Unless required by applicable law or agreed to in writing, software
2598 * distributed under the License is distributed on an "AS IS" BASIS,
2599 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2600 * See the License for the specific language governing permissions and
2601 * limitations under the License.
2602 */
2603// Nativeview
2604// implemented in C++  for release
2605// and in utest/view_native_mock.ts for testing
2606class View extends NativeViewFullUpdate {
2607    /**
2608     * Create a View
2609     *
2610     * 1. option: top level View, specify
2611     *    - compilerAssignedUniqueChildId must specify
2612     *    - parent=undefined
2613     *    - localStorage  must provide if @LocalSTorageLink/Prop variables are used
2614     *      in this View or descendant Views.
2615     *
2616     * 2. option: not a top level View
2617     *    - compilerAssignedUniqueChildId must specify
2618     *    - parent must specify
2619     *    - localStorage do not specify, will inherit from parent View.
2620     *
2621     * @param compilerAssignedUniqueChildId Tw
2622     * @param parent
2623     * @param localStorage
2624     */
2625    constructor(compilerAssignedUniqueChildId, parent, localStorage) {
2626        super(compilerAssignedUniqueChildId, parent);
2627        this.propsUsedForRender = new Set();
2628        this.isRenderingInProgress = false;
2629        this.watchedProps = new Map();
2630        // my LocalStorge instance, shared with ancestor Views.
2631        // create a default instance on demand if none is initialized
2632        this.localStoragebackStore_ = undefined;
2633        this.id_ = SubscriberManager.MakeId();
2634        this.providedVars_ = parent ? new Map(parent.providedVars_)
2635            : new Map();
2636        this.localStoragebackStore_ = undefined;
2637        if (parent) {
2638            // this View is not a top-level View
2639
2640            this.setCardId(parent.getCardId());
2641            this.localStorage_ = parent.localStorage_;
2642        }
2643        else if (localStorage) {
2644            this.localStorage_ = localStorage;
2645
2646        }
2647        SubscriberManager.Add(this);
2648
2649    }
2650    get localStorage_() {
2651        if (!this.localStoragebackStore_) {
2652
2653            this.localStoragebackStore_ = new LocalStorage({ /* emty */});
2654        }
2655        return this.localStoragebackStore_;
2656    }
2657    set localStorage_(instance) {
2658        if (!instance) {
2659            // setting to undefined not allowed
2660            return;
2661        }
2662        if (this.localStoragebackStore_) {
2663            stateMgmtConsole.error(`${this.constructor.name} is setting LocalStorage instance twice`);
2664        }
2665        this.localStoragebackStore_ = instance;
2666    }
2667    // globally unique id, this is different from compilerAssignedUniqueChildId!
2668    id__() {
2669        return this.id_;
2670    }
2671    // temporary function, do not use, it will be removed soon!
2672    // prupsoe is to allow eDSL transpiler to fix a bug that
2673    // relies on this method
2674    id() {
2675        return this.id__();
2676    }
2677    propertyHasChanged(info) {
2678        if (info) {
2679            // need to sync container instanceId to switch instanceId in C++ side.
2680            this.syncInstanceId();
2681            if (this.propsUsedForRender.has(info)) {
2682
2683                this.markNeedUpdate();
2684            }
2685            else {
2686
2687            }
2688            let cb = this.watchedProps.get(info);
2689            if (cb) {
2690
2691                cb.call(this, info);
2692            }
2693            this.restoreInstanceId();
2694        } // if info avail.
2695    }
2696    propertyRead(info) {
2697
2698        if (info && (info != "unknown") && this.isRenderingInProgress) {
2699            this.propsUsedForRender.add(info);
2700        }
2701    }
2702    // for test purposes
2703    propertiesNeededToRender() {
2704        return this.propsUsedForRender;
2705    }
2706    aboutToRender() {
2707
2708        // reset
2709        this.propsUsedForRender = new Set();
2710        this.isRenderingInProgress = true;
2711    }
2712    aboutToContinueRender() {
2713        // do not reset
2714        this.isRenderingInProgress = true;
2715    }
2716    onRenderDone() {
2717        this.isRenderingInProgress = false;
2718
2719    }
2720    /**
2721     * Function to be called from the constructor of the sub component
2722     * to register a @Watch varibale
2723     * @param propStr name of the variable. Note from @Provide and @Consume this is
2724     *      the variable name and not the alias!
2725     * @param callback application defined member function of sub-class
2726     */
2727    declareWatch(propStr, callback) {
2728        this.watchedProps.set(propStr, callback);
2729    }
2730    /**
2731     * This View @Provide's a variable under given name
2732     * Call this function from the constructor of the sub class
2733     * @param providedPropName either the variable name or the alias defined as
2734     *        decorator param
2735     * @param store the backing store object for this variable (not the get/set variable!)
2736     */
2737    addProvidedVar(providedPropName, store) {
2738        if (this.providedVars_.has(providedPropName)) {
2739            throw new ReferenceError(`${this.constructor.name}: duplicate @Provide property with name ${providedPropName}.
2740      Property with this name is provided by one of the ancestor Views already.`);
2741        }
2742        this.providedVars_.set(providedPropName, store);
2743    }
2744    /**
2745     * Method for the sub-class to call from its constructor for resolving
2746     *       a @Consume variable and initializing its backing store
2747     *       with the yncedPropertyTwoWay<T> object created from the
2748     *       @Provide variable's backing store.
2749     * @param providedPropName the name of the @Provide'd variable.
2750     *     This is either the @Consume decortor parameter, or variable name.
2751     * @param consumeVarName the @Consume variable name (not the
2752     *            @Consume decortor parameter)
2753     * @returns initiaizing value of the @Consume backing store
2754     */
2755    initializeConsume(providedPropName, consumeVarName) {
2756        let providedVarStore = this.providedVars_.get(providedPropName);
2757        if (providedVarStore === undefined) {
2758            throw new ReferenceError(`${this.constructor.name}: missing @Provide property with name ${providedPropName}.
2759     Fail to resolve @Consume(${providedPropName}).`);
2760        }
2761        return providedVarStore.createLink(this, consumeVarName);
2762    }
2763}
2764/*
2765 * Copyright (c) 2022 Huawei Device Co., Ltd.
2766 * Licensed under the Apache License, Version 2.0 (the "License");
2767 * you may not use this file except in compliance with the License.
2768 * You may obtain a copy of the License at
2769 *
2770 *     http://www.apache.org/licenses/LICENSE-2.0
2771 *
2772 * Unless required by applicable law or agreed to in writing, software
2773 * distributed under the License is distributed on an "AS IS" BASIS,
2774 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2775 * See the License for the specific language governing permissions and
2776 * limitations under the License.
2777 */
2778/**
2779 * ObservedPropertyAbstractPU aka ObservedPropertyAbstract for partial update
2780 *
2781 * all definitions in this file are framework internal
2782 */
2783class ObservedPropertyAbstractPU extends ObservedPropertyAbstract {
2784    constructor(subscribingView, viewName) {
2785        super(subscribingView, viewName);
2786        this.dependentElementIds_ = new Set();
2787    }
2788    notifyHasChanged(newValue) {
2789
2790        this.subscribers_.forEach((subscribedId) => {
2791            var subscriber = SubscriberManager.Find(subscribedId);
2792            if (subscriber) {
2793                if ('hasChanged' in subscriber) {
2794                    subscriber.hasChanged(newValue);
2795                }
2796                if ('viewPropertyHasChanged' in subscriber) {
2797                    subscriber.viewPropertyHasChanged(this.info_, this.dependentElementIds_);
2798                }
2799                else if ('propertyHasChanged' in subscriber) {
2800                    subscriber.propertyHasChanged(this.info_);
2801                }
2802            }
2803            else {
2804                stateMgmtConsole.warn(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: notifyHasChanged: unknown subscriber ID '${subscribedId}' error!`);
2805            }
2806        });
2807    }
2808    notifyPropertyRead() {
2809        super.notifyPropertyRead();
2810        this.recordDependentUpdate();
2811    }
2812    markDependentElementsDirty(view) {
2813        // TODO ace-ets2bundle, framework, compilated apps need to update together
2814        // this function will be removed after a short transiition periode
2815        stateMgmtConsole.warn(`markDependentElementsDirty no longer supported. App will work ok, but
2816        please update your ace-ets2bundle and recompile your application!`);
2817    }
2818    /**
2819     * factory function for concrete 'object' or 'simple' ObservedProperty object
2820     * depending if value is Class object
2821     * or simple type (boolean | number | string)
2822     * @param value
2823     * @param owningView
2824     * @param thisPropertyName
2825     * @returns either
2826     */
2827    static CreateObservedObject(value, owningView, thisPropertyName) {
2828        return (typeof value === "object") ?
2829            new ObservedPropertyObject(value, owningView, thisPropertyName)
2830            : new ObservedPropertySimple(value, owningView, thisPropertyName);
2831    }
2832    /**
2833     * during 'get' access recording take note of the created component and its elmtId
2834     * and add this component to the list of components who are dependent on this property
2835     */
2836    recordDependentUpdate() {
2837        const elmtId = ViewStackProcessor.GetElmtIdToAccountFor();
2838        if (elmtId < 0) {
2839            // not access recording
2840            return;
2841        }
2842
2843        this.dependentElementIds_.add(elmtId);
2844    }
2845    purgeDependencyOnElmtId(rmElmtId) {
2846
2847        this.dependentElementIds_.delete(rmElmtId);
2848    }
2849    SetPropertyUnchanged() {
2850        // function to be removed
2851        // keep it here until transpiler is updated.
2852    }
2853    // FIXME check, is this used from AppStorage.
2854    // unified Appstorage, what classes to use, and the API
2855    createLink(subscribeOwner, linkPropName) {
2856        throw new Error("Can not create a AppStorage 'Link' from a @State property. ");
2857    }
2858    createProp(subscribeOwner, linkPropName) {
2859        throw new Error("Can not create a AppStorage 'Prop' from a @State property. ");
2860    }
2861}
2862/*
2863 * Copyright (c) 2021 Huawei Device Co., Ltd.
2864 * Licensed under the Apache License, Version 2.0 (the "License");
2865 * you may not use this file except in compliance with the License.
2866 * You may obtain a copy of the License at
2867 *
2868 *     http://www.apache.org/licenses/LICENSE-2.0
2869 *
2870 * Unless required by applicable law or agreed to in writing, software
2871 * distributed under the License is distributed on an "AS IS" BASIS,
2872 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2873 * See the License for the specific language governing permissions and
2874 * limitations under the License.
2875 */
2876/**
2877 * ObservedPropertyObjectAbstractPU
2878 *
2879 * common bbase class of ObservedPropertyObjectPU and
2880 * SyncedObjectPropertyTwoWayPU
2881 * adds the createObjectLink to the ObservedPropertyAbstract base
2882 *
2883 * all definitions in this file are framework internal
2884 */
2885class ObservedPropertyObjectAbstractPU extends ObservedPropertyAbstractPU {
2886    constructor(owningView, thisPropertyName) {
2887        super(owningView, thisPropertyName);
2888    }
2889}
2890/*
2891 * Copyright (c) 2021 Huawei Device Co., Ltd.
2892 * Licensed under the Apache License, Version 2.0 (the "License");
2893 * you may not use this file except in compliance with the License.
2894 * You may obtain a copy of the License at
2895 *
2896 *     http://www.apache.org/licenses/LICENSE-2.0
2897 *
2898 * Unless required by applicable law or agreed to in writing, software
2899 * distributed under the License is distributed on an "AS IS" BASIS,
2900 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2901 * See the License for the specific language governing permissions and
2902 * limitations under the License.
2903 */
2904/**
2905 * ObservedPropertySimpleAbstractPU
2906 *
2907 * all definitions in this file are framework internal
2908 */
2909class ObservedPropertySimpleAbstractPU extends ObservedPropertyAbstractPU {
2910    constructor(owningView, propertyName) {
2911        super(owningView, propertyName);
2912    }
2913}
2914/*
2915 * Copyright (c) 2022 Huawei Device Co., Ltd.
2916 * Licensed under the Apache License, Version 2.0 (the "License");
2917 * you may not use this file except in compliance with the License.
2918 * You may obtain a copy of the License at
2919 *
2920 *     http://www.apache.org/licenses/LICENSE-2.0
2921 *
2922 * Unless required by applicable law or agreed to in writing, software
2923 * distributed under the License is distributed on an "AS IS" BASIS,
2924 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2925 * See the License for the specific language governing permissions and
2926 * limitations under the License.
2927 */
2928/**
2929 * ObservedPropertyObjectPU
2930 *
2931 * all definitions in this file are framework internal
2932 *
2933 * class that holds an actual property value of type T
2934 * uses its base class to manage subscribers to this
2935 * property.
2936*/
2937class ObservedPropertyObjectPU extends ObservedPropertyObjectAbstractPU {
2938    constructor(value, owningView, propertyName) {
2939        super(owningView, propertyName);
2940        this.setValueInternal(value);
2941    }
2942    aboutToBeDeleted(unsubscribeMe) {
2943        this.unsubscribeFromOwningProperty();
2944        if (unsubscribeMe) {
2945            this.unlinkSuscriber(unsubscribeMe.id__());
2946        }
2947        super.aboutToBeDeleted();
2948    }
2949    // notification from ObservedObject value one of its
2950    // props has chnaged. Implies the ObservedProperty has changed
2951    // Note: this function gets called when in this case:
2952    //       thisProp.aObsObj.aProp = 47  a object prop gets changed
2953    // It is NOT called when
2954    //    thisProp.aObsObj = new ClassA
2955    hasChanged(newValue) {
2956
2957        this.notifyHasChanged(this.wrappedValue_);
2958    }
2959    unsubscribeFromOwningProperty() {
2960        if (this.wrappedValue_) {
2961            if (this.wrappedValue_ instanceof SubscribaleAbstract) {
2962                this.wrappedValue_.removeOwningProperty(this);
2963            }
2964            else {
2965                ObservedObject.removeOwningProperty(this.wrappedValue_, this);
2966            }
2967        }
2968    }
2969    /*
2970      actually update this.wrappedValue_
2971      called needs to do value change check
2972      and also notify with this.aboutToChange();
2973    */
2974    setValueInternal(newValue) {
2975        if (typeof newValue !== 'object') {
2976
2977            return false;
2978        }
2979        this.unsubscribeFromOwningProperty();
2980        if (ObservedObject.IsObservedObject(newValue)) {
2981
2982            ObservedObject.addOwningProperty(newValue, this);
2983            this.wrappedValue_ = newValue;
2984        }
2985        else if (newValue instanceof SubscribaleAbstract) {
2986
2987            this.wrappedValue_ = newValue;
2988            this.wrappedValue_.addOwningProperty(this);
2989        }
2990        else {
2991
2992            this.wrappedValue_ = ObservedObject.createNew(newValue, this);
2993        }
2994        return true;
2995    }
2996    get() {
2997
2998        this.notifyPropertyRead();
2999        return this.wrappedValue_;
3000    }
3001    getUnmonitored() {
3002
3003        // unmonitored get access , no call to otifyPropertyRead !
3004        return this.wrappedValue_;
3005    }
3006    set(newValue) {
3007        if (this.wrappedValue_ == newValue) {
3008
3009            return;
3010        }
3011
3012        this.setValueInternal(newValue);
3013        this.notifyHasChanged(newValue);
3014    }
3015}
3016/*
3017 * Copyright (c) 2022 Huawei Device Co., Ltd.
3018 * Licensed under the Apache License, Version 2.0 (the "License");
3019 * you may not use this file except in compliance with the License.
3020 * You may obtain a copy of the License at
3021 *
3022 *     http://www.apache.org/licenses/LICENSE-2.0
3023 *
3024 * Unless required by applicable law or agreed to in writing, software
3025 * distributed under the License is distributed on an "AS IS" BASIS,
3026 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3027 * See the License for the specific language governing permissions and
3028 * limitations under the License.
3029 */
3030/**
3031 * ObservedPropertySimplePU
3032 *
3033 * class that holds an actual property value of type T
3034 * uses its base class to manage subscribers to this
3035 * property.
3036 *
3037 * all definitions in this file are framework internal
3038*/
3039class ObservedPropertySimplePU extends ObservedPropertySimpleAbstractPU {
3040    constructor(value, owningView, propertyName) {
3041        super(owningView, propertyName);
3042        if (typeof value === "object") {
3043            throw new SyntaxError("ObservedPropertySimple value must not be an object");
3044        }
3045        this.setValueInternal(value);
3046    }
3047    aboutToBeDeleted(unsubscribeMe) {
3048        if (unsubscribeMe) {
3049            this.unlinkSuscriber(unsubscribeMe.id__());
3050        }
3051        super.aboutToBeDeleted();
3052    }
3053    hasChanged(newValue) {
3054
3055        this.notifyHasChanged(this.wrappedValue_);
3056    }
3057    /*
3058      actually update this.wrappedValue_
3059      called needs to do value change check
3060      and also notify with this.aboutToChange();
3061    */
3062    setValueInternal(newValue) {
3063
3064        this.wrappedValue_ = newValue;
3065    }
3066    getUnmonitored() {
3067
3068        // unmonitored get access , no call to otifyPropertyRead !
3069        return this.wrappedValue_;
3070    }
3071    get() {
3072
3073        this.notifyPropertyRead();
3074        return this.wrappedValue_;
3075    }
3076    set(newValue) {
3077        if (this.wrappedValue_ == newValue) {
3078
3079            return;
3080        }
3081
3082        this.setValueInternal(newValue);
3083        this.notifyHasChanged(newValue);
3084    }
3085}
3086/*
3087 * Copyright (c) 2022 Huawei Device Co., Ltd.
3088 * Licensed under the Apache License, Version 2.0 (the "License");
3089 * you may not use this file except in compliance with the License.
3090 * You may obtain a copy of the License at
3091 *
3092 *     http://www.apache.org/licenses/LICENSE-2.0
3093 *
3094 * Unless required by applicable law or agreed to in writing, software
3095 * distributed under the License is distributed on an "AS IS" BASIS,
3096 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3097 * See the License for the specific language governing permissions and
3098 * limitations under the License.
3099 */
3100class SynchedPropertyObjectOneWayPU extends ObservedPropertyObjectAbstractPU {
3101    constructor(source, owningChildView, thisPropertyName) {
3102        super(owningChildView, thisPropertyName);
3103        if (source && (typeof (source) === "object") && ("notifyHasChanged" in source) && ("subscribeMe" in source)) {
3104            // code path for @(Local)StorageProp
3105            this.source_ = source;
3106            // subscribe to receive value change updates from LocalStorage source property
3107            this.source_.subscribeMe(this);
3108        }
3109        else {
3110            // code path for @Prop
3111            if (!ObservedObject.IsObservedObject(source)) {
3112                stateMgmtConsole.warn(`@Prop ${this.info()}  Provided source object's class
3113           lacks @Observed class decorator. Object property changes will not be observed.`);
3114            }
3115            this.source_ = new ObservedPropertyObjectPU(source, this, thisPropertyName);
3116        }
3117        // deep copy source Object and wrap it
3118        this.setWrapperValue(this.source_.get());
3119
3120    }
3121    /*
3122    like a destructor, need to call this before deleting
3123    the property.
3124    */
3125    aboutToBeDeleted() {
3126        if (this.source_) {
3127            this.source_.unlinkSuscriber(this.id__());
3128            this.source_ = undefined;
3129        }
3130        super.aboutToBeDeleted();
3131    }
3132    // this object is subscriber to this.source_
3133    // when source notifies a property change, copy its value to local backing store
3134    // the guard for newValue being an Object is needed because also property changes of wrappedValue_
3135    // are notified via this function. We ignore those, these are handled correctly by propertyHasChanged
3136    hasChanged(newValue) {
3137        if (typeof newValue == "object") {
3138
3139            this.setWrapperValue(newValue);
3140            this.notifyHasChanged(ObservedObject.GetRawObject(this.wrappedValue_));
3141        }
3142    }
3143    propertyHasChanged(propName) {
3144
3145        this.notifyHasChanged(ObservedObject.GetRawObject(this.wrappedValue_));
3146    }
3147    getUnmonitored() {
3148
3149        // unmonitored get access , no call to notifyPropertyRead !
3150        return this.wrappedValue_;
3151    }
3152    // get 'read through` from the ObservedObject
3153    get() {
3154
3155        this.notifyPropertyRead();
3156        return this.wrappedValue_;
3157    }
3158    // assignment to local variable in the form of this.aProp = <object value>
3159    // set 'writes through` to the ObservedObject
3160    set(newValue) {
3161        if (this.wrappedValue_ == newValue) {
3162
3163            return;
3164        }
3165
3166        if (!ObservedObject.IsObservedObject(newValue)) {
3167            stateMgmtConsole.warn(`@Prop ${this.info()} Set: Provided new object's class
3168         lacks @Observed class decorator. Object property changes will not be observed.`);
3169        }
3170        this.setWrapperValue(newValue);
3171        this.notifyHasChanged(this.wrappedValue_);
3172    }
3173    reset(sourceChangedValue) {
3174
3175        // if set causes an actual change, then, ObservedPropertyObject source_ will call hasChanged
3176        this.source_.set(sourceChangedValue);
3177    }
3178    setWrapperValue(value) {
3179        let rawValue = ObservedObject.GetRawObject(value);
3180        if (rawValue instanceof Array) {
3181            this.wrappedValue_ = ObservedObject.createNew([...rawValue], this);
3182        }
3183        else {
3184            this.wrappedValue_ = ObservedObject.createNew(Object.assign({}, rawValue), this);
3185        }
3186    }
3187}
3188/*
3189 * Copyright (c) 2022 Huawei Device Co., Ltd.
3190 * Licensed under the Apache License, Version 2.0 (the "License");
3191 * you may not use this file except in compliance with the License.
3192 * You may obtain a copy of the License at
3193 *
3194 *     http://www.apache.org/licenses/LICENSE-2.0
3195 *
3196 * Unless required by applicable law or agreed to in writing, software
3197 * distributed under the License is distributed on an "AS IS" BASIS,
3198 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3199 * See the License for the specific language governing permissions and
3200 * limitations under the License.
3201 */
3202/**
3203 * SynchedPropertyObjectTwoWayPU
3204 *
3205 * all definitions in this file are framework internal
3206 */
3207class SynchedPropertyObjectTwoWayPU extends ObservedPropertyObjectAbstractPU {
3208    constructor(linkSource, owningChildView, thisPropertyName) {
3209        super(owningChildView, thisPropertyName);
3210        this.changeNotificationIsOngoing_ = false;
3211        if (linkSource) {
3212            this.linkedParentProperty_ = linkSource;
3213            // register to the parent property
3214            this.linkedParentProperty_.subscribeMe(this);
3215            // register to the ObservedObject
3216            ObservedObject.addOwningProperty(this.linkedParentProperty_.get(), this);
3217        }
3218    }
3219    /*
3220    like a destructor, need to call this before deleting
3221    the property.
3222    */
3223    aboutToBeDeleted() {
3224        // unregister from parent of this link
3225        if (this.linkedParentProperty_) {
3226            this.linkedParentProperty_.unlinkSuscriber(this.id__());
3227            // unregister from the ObservedObject
3228            ObservedObject.removeOwningProperty(this.linkedParentProperty_.getUnmonitored(), this);
3229        }
3230        super.aboutToBeDeleted();
3231    }
3232    setObject(newValue) {
3233        if (!this.linkedParentProperty_) {
3234            stateMgmtConsole.warn(`SynchedPropertyObjectTwoWayPU[${this.id__()}, '${this.info() || "unknown"}']: setObject, no linked parent property.`);
3235            return;
3236        }
3237        this.linkedParentProperty_.set(newValue);
3238    }
3239    // this object is subscriber to ObservedObject
3240    // will call this cb function when property has changed
3241    hasChanged(newValue) {
3242        if (!this.changeNotificationIsOngoing_) {
3243
3244            this.notifyHasChanged(this.getUnmonitored());
3245        }
3246    }
3247    getUnmonitored() {
3248
3249        // unmonitored get access , no call to otifyPropertyRead !
3250        return (this.linkedParentProperty_ ? this.linkedParentProperty_.getUnmonitored() : undefined);
3251    }
3252    // get 'read through` from the ObservedProperty
3253    get() {
3254
3255        this.notifyPropertyRead();
3256        return this.getUnmonitored();
3257    }
3258    // set 'writes through` to the ObservedProperty
3259    set(newValue) {
3260        if (this.getUnmonitored() == newValue) {
3261
3262            return;
3263        }
3264
3265        ObservedObject.removeOwningProperty(this.getUnmonitored(), this);
3266        // avoid circular notifications @Link -> source @State -> other but also back to same @Link
3267        this.changeNotificationIsOngoing_ = true;
3268        this.setObject(newValue);
3269        ObservedObject.addOwningProperty(this.getUnmonitored(), this);
3270        this.notifyHasChanged(newValue);
3271        this.changeNotificationIsOngoing_ = false;
3272    }
3273}
3274/*
3275 * Copyright (c) 2022 Huawei Device Co., Ltd.
3276 * Licensed under the Apache License, Version 2.0 (the "License");
3277 * you may not use this file except in compliance with the License.
3278 * You may obtain a copy of the License at
3279 *
3280 *     http://www.apache.org/licenses/LICENSE-2.0
3281 *
3282 * Unless required by applicable law or agreed to in writing, software
3283 * distributed under the License is distributed on an "AS IS" BASIS,
3284 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3285 * See the License for the specific language governing permissions and
3286 * limitations under the License.
3287 */
3288/**
3289 * SynchedPropertySimpleOneWayPU
3290 *
3291 * all definitions in this file are framework internal
3292 */
3293class SynchedPropertySimpleOneWayPU extends ObservedPropertySimpleAbstractPU {
3294    constructor(source, subscribeMe, thisPropertyName) {
3295        super(subscribeMe, thisPropertyName);
3296        if (source && (typeof (source) === "object") && ("notifyHasChanged" in source) && ("subscribeMe" in source)) {
3297            // code path for @(Local)StorageProp
3298            this.source_ = source;
3299            // subscribe to receive value chnage updates from LocalStorge source property
3300            this.source_.subscribeMe(this);
3301        }
3302        else {
3303            // code path for @Prop
3304            this.source_ = new ObservedPropertySimple(source, this, thisPropertyName);
3305        }
3306        // use own backing store for value to avoid
3307        // value changes to be propagated back to source
3308        this.wrappedValue_ = this.source_.getUnmonitored();
3309    }
3310    /*
3311      like a destructor, need to call this before deleting
3312      the property.
3313    */
3314    aboutToBeDeleted() {
3315        if (this.source_) {
3316            this.source_.unlinkSuscriber(this.id__());
3317            this.source_ = undefined;
3318        }
3319        super.aboutToBeDeleted();
3320    }
3321    // implements  ISinglePropertyChangeSubscriber<T>:
3322    // this object is subscriber to this.source_
3323    // when source notifies a change, copy its value to local backing store
3324    hasChanged(newValue) {
3325
3326        this.wrappedValue_ = newValue;
3327        this.notifyHasChanged(newValue);
3328    }
3329    getUnmonitored() {
3330
3331        // unmonitored get access , no call to otifyPropertyRead !
3332        return this.wrappedValue_;
3333    }
3334    // get 'read through` from the ObservedProperty
3335    get() {
3336
3337        this.notifyPropertyRead();
3338        return this.wrappedValue_;
3339    }
3340    set(newValue) {
3341        if (this.wrappedValue_ == newValue) {
3342
3343            return;
3344        }
3345
3346        this.wrappedValue_ = newValue;
3347        this.notifyHasChanged(newValue);
3348    }
3349    reset(sourceChangedValue) {
3350
3351        // if set causes an actual change, then, ObservedPropertySimple source_ will call hasChanged
3352        this.source_.set(sourceChangedValue);
3353    }
3354}
3355/*
3356 * Copyright (c) 2022 Huawei Device Co., Ltd.
3357 * Licensed under the Apache License, Version 2.0 (the "License");
3358 * you may not use this file except in compliance with the License.
3359 * You may obtain a copy of the License at
3360 *
3361 *     http://www.apache.org/licenses/LICENSE-2.0
3362 *
3363 * Unless required by applicable law or agreed to in writing, software
3364 * distributed under the License is distributed on an "AS IS" BASIS,
3365 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3366 * See the License for the specific language governing permissions and
3367 * limitations under the License.
3368 */
3369/**
3370 * SynchedPropertySimpleTwoWayPU
3371 *
3372 * all definitions in this file are framework internal
3373 */
3374class SynchedPropertySimpleTwoWayPU extends ObservedPropertySimpleAbstractPU {
3375    constructor(source, owningView, owningViewPropNme) {
3376        super(owningView, owningViewPropNme);
3377        this.changeNotificationIsOngoing_ = false;
3378        this.source_ = source;
3379        this.source_.subscribeMe(this);
3380    }
3381    /*
3382    like a destructor, need to call this before deleting
3383    the property.
3384  */
3385    aboutToBeDeleted() {
3386        if (this.source_) {
3387            this.source_.unlinkSuscriber(this.id__());
3388            this.source_ = undefined;
3389        }
3390        super.aboutToBeDeleted();
3391    }
3392    // this object is subscriber to  SynchedPropertySimpleTwoWayPU
3393    // will call this cb function when property has changed
3394    // a set (newValue) is not done because get reads through for the source_
3395    hasChanged(newValue) {
3396        if (!this.changeNotificationIsOngoing_) {
3397
3398            this.notifyHasChanged(newValue);
3399        }
3400    }
3401    getUnmonitored() {
3402
3403        return (this.source_ ? this.source_.getUnmonitored() : undefined);
3404    }
3405    // get 'read through` from the ObservedProperty
3406    get() {
3407
3408        this.notifyPropertyRead();
3409        return this.getUnmonitored();
3410    }
3411    // set 'writes through` to the ObservedProperty
3412    set(newValue) {
3413        if (!this.source_) {
3414
3415            return;
3416        }
3417        if (this.source_.get() == newValue) {
3418
3419            return;
3420        }
3421
3422        // avoid circular notifications @Link -> source @State -> other but also to same @Link
3423        this.changeNotificationIsOngoing_ = true;
3424        // the source_ ObservedProeprty will call: this.hasChanged(newValue);
3425        this.source_.set(newValue);
3426        this.notifyHasChanged(newValue);
3427        this.changeNotificationIsOngoing_ = false;
3428    }
3429}
3430/*
3431 * Copyright (c) 2022 Huawei Device Co., Ltd.
3432 * Licensed under the Apache License, Version 2.0 (the "License");
3433 * you may not use this file except in compliance with the License.
3434 * You may obtain a copy of the License at
3435 *
3436 *     http://www.apache.org/licenses/LICENSE-2.0
3437 *
3438 * Unless required by applicable law or agreed to in writing, software
3439 * distributed under the License is distributed on an "AS IS" BASIS,
3440 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3441 * See the License for the specific language governing permissions and
3442 * limitations under the License.
3443 */
3444/**
3445 * SynchedPropertyNesedObjectPU
3446 *
3447 * all definitions in this file are framework internal
3448 *
3449 */
3450class SynchedPropertyNesedObjectPU extends ObservedPropertyObjectAbstractPU {
3451    /**
3452     * Construct a Property of a su component that links to a variable of parent view that holds an ObservedObject
3453     * example
3454     *   this.b.$a with b of type PC and a of type C, or
3455     *   this.$b[5] with this.b of type PC and array item b[5] of type C;
3456     *
3457     * @param subscribeMe
3458     * @param propName
3459     */
3460    constructor(obsObject, owningChildView, propertyName) {
3461        super(owningChildView, propertyName);
3462        this.obsObject_ = obsObject;
3463        // register to the ObservedObject
3464        ObservedObject.addOwningProperty(this.obsObject_, this);
3465    }
3466    /*
3467    like a destructor, need to call this before deleting
3468    the property.
3469    */
3470    aboutToBeDeleted() {
3471        // unregister from the ObservedObject
3472        ObservedObject.removeOwningProperty(this.obsObject_, this);
3473        super.aboutToBeDeleted();
3474    }
3475    // this object is subscriber to ObservedObject
3476    // will call this cb function when property has changed
3477    hasChanged(newValue) {
3478
3479        this.notifyHasChanged(this.obsObject_);
3480    }
3481    getUnmonitored() {
3482        //
3483        // unmonitored get access , no call to otifyPropertyRead !
3484        return this.obsObject_;
3485    }
3486    // get 'read through` from the ObservedProperty
3487    get() {
3488
3489        this.notifyPropertyRead();
3490        return this.obsObject_;
3491    }
3492    // set 'writes through` to the ObservedProperty
3493    set(newValue) {
3494        if (this.obsObject_ == newValue) {
3495
3496            return;
3497        }
3498
3499        // unsubscribe from the old value ObservedObject
3500        ObservedObject.removeOwningProperty(this.obsObject_, this);
3501        this.obsObject_ = newValue;
3502        // subscribe to the new value ObservedObject
3503        ObservedObject.addOwningProperty(this.obsObject_, this);
3504        // notify value change to subscribing View
3505        this.notifyHasChanged(this.obsObject_);
3506    }
3507}
3508/*
3509 * Copyright (c) 2022 Huawei Device Co., Ltd.
3510 * Licensed under the Apache License, Version 2.0 (the "License");
3511 * you may not use this file except in compliance with the License.
3512 * You may obtain a copy of the License at
3513 *
3514 *     http://www.apache.org/licenses/LICENSE-2.0
3515 *
3516 * Unless required by applicable law or agreed to in writing, software
3517 * distributed under the License is distributed on an "AS IS" BASIS,
3518 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3519 * See the License for the specific language governing permissions and
3520 * limitations under the License.
3521 *
3522 *  * ViewPU - View for Partial Update
3523 *
3524* all definitions in this file are framework internal
3525*/
3526// denotes a missing elemntId, this is the case during initial render
3527const UndefinedElmtId = -1;
3528// Nativeview
3529// implemented in C++  for release
3530// and in utest/view_native_mock.ts for testing
3531class ViewPU extends NativeViewPartialUpdate {
3532    /**
3533     * Create a View
3534     *
3535     * 1. option: top level View, specify
3536     *    - compilerAssignedUniqueChildId must specify
3537     *    - parent=undefined
3538     *    - localStorage  must provide if @LocalSTorageLink/Prop variables are used
3539     *      in this View or descendant Views.
3540     *
3541     * 2. option: not a top level View
3542     *    - compilerAssignedUniqueChildId must specify
3543     *    - parent must specify
3544     *    - localStorage do not specify, will inherit from parent View.
3545     *
3546    */
3547    constructor(parent, localStorage, elmtId = -1) {
3548        super();
3549        this.parent_ = undefined;
3550        this.childrenWeakrefMap_ = new Map();
3551        this.watchedProps = new Map();
3552        // Set of dependent elmtIds that need partial update
3553        // during next re-render
3554        this.dirtDescendantElementIds_ = new Set();
3555        // registry of update functions
3556        // the key is the elementId of the Component/Element that's the result of this function
3557        this.updateFuncByElmtId = new Map();
3558        // my LocalStorge instance, shared with ancestor Views.
3559        // create a default instance on demand if none is initialized
3560        this.localStoragebackStore_ = undefined;
3561        // if set use the elmtId also as the ViewPU object's subscribable id.
3562        // these matching is requiremrnt for updateChildViewById(elmtId) being able to
3563        // find the child ViewPU object by given elmtId
3564        this.id_ = elmtId == -1 ? SubscriberManager.MakeId() : elmtId;
3565        this.providedVars_ = parent ? new Map(parent.providedVars_)
3566            : new Map();
3567        this.localStoragebackStore_ = undefined;
3568        if (parent) {
3569            // this View is not a top-level View
3570
3571            this.setCardId(parent.getCardId());
3572            this.localStorage_ = parent.localStorage_;
3573            parent.addChild(this);
3574        }
3575        else if (localStorage) {
3576            this.localStorage_ = localStorage;
3577
3578        }
3579        SubscriberManager.Add(this);
3580
3581    }
3582    get localStorage_() {
3583        if (!this.localStoragebackStore_) {
3584
3585            this.localStoragebackStore_ = new LocalStorage({ /* emty */});
3586        }
3587        return this.localStoragebackStore_;
3588    }
3589    set localStorage_(instance) {
3590        if (!instance) {
3591            // setting to undefined not allowed
3592            return;
3593        }
3594        if (this.localStoragebackStore_) {
3595            stateMgmtConsole.error(`${this.constructor.name} is setting LocalStorage instance twice`);
3596        }
3597        this.localStoragebackStore_ = instance;
3598    }
3599    // globally unique id, this is different from compilerAssignedUniqueChildId!
3600    id__() {
3601        return this.id_;
3602    }
3603    // super class will call this function from
3604    // its aboutToBeDeleted implementation
3605    aboutToBeDeletedInternal() {
3606        // When a custom component is deleted, need to notify the C++ side to clean the corresponding deletion cache Map,
3607        // because after the deletion, can no longer clean the RemoveIds cache on the C++ side through the
3608        // updateDirtyElements function.
3609        let removedElmtIds = [];
3610        this.updateFuncByElmtId.forEach((value, key) => {
3611            this.purgeVariableDependenciesOnElmtId(key);
3612            removedElmtIds.push(key);
3613        });
3614        this.deletedElmtIdsHaveBeenPurged(removedElmtIds);
3615        this.updateFuncByElmtId.clear();
3616        this.watchedProps.clear();
3617        this.providedVars_.clear();
3618        if (this.parent_) {
3619            this.parent_.removeChild(this);
3620        }
3621    }
3622    setParent(parent) {
3623        if (this.parent_ && parent) {
3624            stateMgmtConsole.warn(`ViewPU('${this.constructor.name}', ${this.id__()}).setChild: changing parent to '${parent.constructor.name}', id ${parent.id__()} (unsafe operation)`);
3625        }
3626        this.parent_ = parent;
3627    }
3628    /**
3629     * add given child and set 'this' as its parent
3630     * @param child child to add
3631     * @returns returns false if child with given child's id already exists
3632     *
3633     * framework internal function
3634     * Note: Use of WeakRef ensures child and parent do not generate a cycle dependency.
3635     * The add. Set<ids> is required to reliably tell what children still exist.
3636     */
3637    addChild(child) {
3638        if (this.childrenWeakrefMap_.has(child.id__())) {
3639            stateMgmtConsole.warn(`ViewPU('${this.constructor.name}', ${this.id__()}).addChild '${child.constructor.name}' id already exists ${child.id__()} !`);
3640            return false;
3641        }
3642        this.childrenWeakrefMap_.set(child.id__(), new WeakRef(child));
3643        child.setParent(this);
3644        return true;
3645    }
3646    /**
3647     * remove given child and remove 'this' as its parent
3648     * @param child child to add
3649     * @returns returns false if child with given child's id does not exist
3650     */
3651    removeChild(child) {
3652        const hasBeenDeleted = this.childrenWeakrefMap_.delete(child.id__());
3653        if (!hasBeenDeleted) {
3654            stateMgmtConsole.warn(`ViewPU('${this.constructor.name}', ${this.id__()}).removeChild '${child.constructor.name}', child id ${child.id__()} not known!`);
3655        }
3656        else {
3657            child.setParent(undefined);
3658        }
3659        return hasBeenDeleted;
3660    }
3661    /**
3662     * Retrieve child by given id
3663     * @param id
3664     * @returns child if in map and weak ref can still be downreferenced
3665     */
3666    getChildById(id) {
3667        const childWeakRef = this.childrenWeakrefMap_.get(id);
3668        return childWeakRef ? childWeakRef.deref() : undefined;
3669    }
3670    updateStateVars(params) {
3671        stateMgmtConsole.warn("ViewPU.updateStateVars unimplemented. Pls upgrade to latest eDSL transpiler version.");
3672    }
3673    initialRenderView() {
3674        this.initialRender();
3675    }
3676    UpdateElement(elmtId) {
3677        // do not process an Element that has been marked to be deleted
3678        const updateFunc = this.updateFuncByElmtId.get(elmtId);
3679        if ((updateFunc == undefined) || (typeof updateFunc !== "function")) {
3680            stateMgmtConsole.error(`${this.constructor.name}[${this.id__()}]: update function of ElementId ${elmtId} not found, internal error!`);
3681        }
3682        else {
3683
3684            updateFunc(elmtId, /* isFirstRender */ false);
3685            // continue in native JSView
3686            // Finish the Update in JSView::JsFinishUpdateFunc
3687            // this function appends no longer used elmtIds (as recrded by VSP) to the given allRmElmtIds array
3688            this.finishUpdateFunc(elmtId);
3689
3690        }
3691    }
3692    /**
3693     * force a complete rerender / update by executing all update functions
3694     * exec a regular rerender first
3695     *
3696     * @param deep recurse all children as well
3697     *
3698     * framework internal functions, apps must not call
3699     */
3700    forceCompleteRerender(deep = false) {
3701        stateMgmtConsole.warn(`ViewPU('${this.constructor.name}', ${this.id__()}).forceCompleteRerender - start.`);
3702        // request list of all (gloabbly) deleted elmtIds;
3703        let deletedElmtIds = [];
3704        this.getDeletedElemtIds(deletedElmtIds);
3705        // see which elmtIds are managed by this View
3706        // and clean up all book keeping for them
3707        this.purgeDeletedElmtIds(deletedElmtIds);
3708        Array.from(this.updateFuncByElmtId.keys()).sort(ViewPU.compareNumber).forEach(elmtId => this.UpdateElement(elmtId));
3709        if (deep) {
3710            this.childrenWeakrefMap_.forEach((weakRefChild) => {
3711                const child = weakRefChild.deref();
3712                if (child) {
3713                    child.forceCompleteRerender(true);
3714                }
3715            });
3716        }
3717        stateMgmtConsole.warn(`ViewPU('${this.constructor.name}', ${this.id__()}).forceCompleteRerender - end`);
3718    }
3719    /**
3720     * force a complete rerender / update on specific node by executing update function.
3721     *
3722     * @param elmtId which node needs to update.
3723     *
3724     * framework internal functions, apps must not call
3725     */
3726    forceRerenderNode(elmtId) {
3727        // request list of all (gloabbly) deleted elmtIds;
3728        let deletedElmtIds = [];
3729        this.getDeletedElemtIds(deletedElmtIds);
3730        // see which elmtIds are managed by this View
3731        // and clean up all book keeping for them
3732        this.purgeDeletedElmtIds(deletedElmtIds);
3733        this.UpdateElement(elmtId);
3734        // remove elemtId from dirtDescendantElementIds.
3735        this.dirtDescendantElementIds_.delete(elmtId);
3736    }
3737    updateStateVarsOfChildByElmtId(elmtId, params) {
3738
3739        if (elmtId < 0) {
3740            stateMgmtConsole.warn(`ViewPU('${this.constructor.name}', ${this.id__()}).updateChildViewById(${elmtId}) - invalid elmtId - internal error!`);
3741            return;
3742        }
3743        let child = this.getChildById(elmtId);
3744        if (!child) {
3745            stateMgmtConsole.warn(`ViewPU('${this.constructor.name}', ${this.id__()}).updateChildViewById(${elmtId}) - no child with this elmtId - internal error!`);
3746            return;
3747        }
3748        child.updateStateVars(params);
3749
3750    }
3751    // implements IMultiPropertiesChangeSubscriber
3752    viewPropertyHasChanged(varName, dependentElmtIds) {
3753
3754        this.syncInstanceId();
3755        if (dependentElmtIds.size && !this.isFirstRender()) {
3756            if (!this.dirtDescendantElementIds_.size) {
3757                // mark Composedelement dirty when first elmtIds are added
3758                // do not need to do this every time
3759                this.markNeedUpdate();
3760            }
3761
3762            const union = new Set([...this.dirtDescendantElementIds_, ...dependentElmtIds]);
3763            this.dirtDescendantElementIds_ = union;
3764
3765        }
3766        let cb = this.watchedProps.get(varName);
3767        if (cb) {
3768
3769            cb.call(this, varName);
3770        }
3771        this.restoreInstanceId();
3772    }
3773    /**
3774     * Function to be called from the constructor of the sub component
3775     * to register a @Watch varibale
3776     * @param propStr name of the variable. Note from @Provide and @Consume this is
3777     *      the variable name and not the alias!
3778     * @param callback application defined member function of sub-class
3779     */
3780    declareWatch(propStr, callback) {
3781        this.watchedProps.set(propStr, callback);
3782    }
3783    /**
3784     * This View @Provide's a variable under given name
3785     * Call this function from the constructor of the sub class
3786     * @param providedPropName either the variable name or the alias defined as
3787     *        decorator param
3788     * @param store the backing store object for this variable (not the get/set variable!)
3789     */
3790    addProvidedVar(providedPropName, store) {
3791        if (this.providedVars_.has(providedPropName)) {
3792            throw new ReferenceError(`${this.constructor.name}: duplicate @Provide property with name ${providedPropName}.
3793      Property with this name is provided by one of the ancestor Views already.`);
3794        }
3795        this.providedVars_.set(providedPropName, store);
3796    }
3797    /**
3798     * Method for the sub-class to call from its constructor for resolving
3799     *       a @Consume variable and initializing its backing store
3800     *       with the yncedPropertyTwoWay<T> object created from the
3801     *       @Provide variable's backing store.
3802     * @param providedPropName the name of the @Provide'd variable.
3803     *     This is either the @Consume decortor parameter, or variable name.
3804     * @param consumeVarName the @Consume variable name (not the
3805     *            @Consume decortor parameter)
3806     * @returns initiaizing value of the @Consume backing store
3807     */
3808    initializeConsume(providedPropName, consumeVarName) {
3809        let providedVarStore = this.providedVars_.get(providedPropName);
3810        if (providedVarStore === undefined) {
3811            throw new ReferenceError(`${this.constructor.name}: missing @Provide property with name ${providedPropName}.
3812     Fail to resolve @Consume(${providedPropName}).`);
3813        }
3814        return providedVarStore.createSync((source) => (source instanceof ObservedPropertySimple)
3815            ? new SynchedPropertySimpleTwoWayPU(source, this, consumeVarName)
3816            : new SynchedPropertyObjectTwoWayPU(source, this, consumeVarName));
3817    }
3818    /**
3819     * given the elmtid of a child or child of child within this custom component
3820     * remember this component needs a partial update
3821     * @param elmtId
3822     */
3823    markElemenDirtyById(elmtId) {
3824        // TODO ace-ets2bundle, framework, compilated apps need to update together
3825        // this function will be removed after a short transiition periode
3826        stateMgmtConsole.error(`markElemenDirtyById no longer supported.
3827        Please update your ace-ets2bundle and recompile your application!`);
3828    }
3829    /**
3830     * For each recorded dirty Element in this custom component
3831     * run its update function
3832     *
3833     */
3834    updateDirtyElements() {
3835        do {
3836
3837            // request list of all (gloabbly) deleteelmtIds;
3838            let deletedElmtIds = [];
3839            this.getDeletedElemtIds(deletedElmtIds);
3840            // see which elmtIds are managed by this View
3841            // and clean up all book keeping for them
3842            this.purgeDeletedElmtIds(deletedElmtIds);
3843            // process all elmtIds marked as needing update in ascending order.
3844            // ascending order ensures parent nodes will be updated before their children
3845            // prior cleanup ensure no already deleted Elements have their update func executed
3846            Array.from(this.dirtDescendantElementIds_).sort(ViewPU.compareNumber).forEach(elmtId => {
3847                this.UpdateElement(elmtId);
3848                this.dirtDescendantElementIds_.delete(elmtId);
3849            });
3850        } while (this.dirtDescendantElementIds_.size);
3851    }
3852    //  given a list elementIds removes these from state variables dependency list and from elmtId -> updateFunc map
3853    purgeDeletedElmtIds(rmElmtIds) {
3854        if (rmElmtIds.length == 0) {
3855            return;
3856        }
3857
3858        // rmElmtIds is the array of ElemntIds that
3859        let removedElmtIds = [];
3860        rmElmtIds.forEach((elmtId) => {
3861            // remove entry from Map elmtId -> update function
3862            if (this.updateFuncByElmtId.delete(elmtId)) {
3863                // for each state var, remove dependent elmtId (if present)
3864                // purgeVariableDependenciesOnElmtId needs to be generated by the compiler
3865                this.purgeVariableDependenciesOnElmtId(elmtId);
3866                // keep track of elmtId that has been de-registered
3867                removedElmtIds.push(elmtId);
3868            }
3869        });
3870        this.deletedElmtIdsHaveBeenPurged(removedElmtIds);
3871
3872
3873    }
3874    // the current executed update function
3875    observeComponentCreation(compilerAssignedUpdateFunc) {
3876        const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
3877
3878        compilerAssignedUpdateFunc(elmtId, /* is first rneder */ true);
3879        this.updateFuncByElmtId.set(elmtId, compilerAssignedUpdateFunc);
3880
3881    }
3882    // performs the update on a branch within if() { branch } else if (..) { branch } else { branch }
3883    ifElseBranchUpdateFunction(branchId, branchfunc) {
3884        const oldBranchid = If.getBranchId();
3885        if (branchId == oldBranchid) {
3886
3887            return;
3888        }
3889        If.branchId(branchId);
3890        branchfunc();
3891    }
3892    /**
3893     Partial updates for ForEach.
3894     * @param elmtId ID of element.
3895     * @param itemArray Array of items for use of itemGenFunc.
3896     * @param itemGenFunc Item generation function to generate new elements. If index parameter is
3897     *                    given set itemGenFuncUsesIndex to true.
3898     * @param idGenFunc   ID generation function to generate unique ID for each element. If index parameter is
3899     *                    given set idGenFuncUsesIndex to true.
3900     * @param itemGenFuncUsesIndex itemGenFunc optional index parameter is given or not.
3901     * @param idGenFuncUsesIndex idGenFunc optional index parameter is given or not.
3902     */
3903    forEachUpdateFunction(elmtId, itemArray, itemGenFunc, idGenFunc, itemGenFuncUsesIndex = false, idGenFuncUsesIndex = false) {
3904
3905        if (itemArray === null || itemArray === undefined) {
3906            stateMgmtConsole.error(`ForEach input array is null or undefined error.`);
3907            return;
3908        }
3909        if (itemGenFunc === null || itemGenFunc === undefined) {
3910            stateMgmtConsole.error(`Error: Item generation function not defined in forEach function.`);
3911            return;
3912        }
3913        if (idGenFunc === undefined) {
3914
3915            idGenFunc = (item, index) => `${index}__${JSON.stringify(item)}`;
3916            idGenFuncUsesIndex = true;
3917        }
3918        let diffIndexArray = []; // New indexes compared to old one.
3919        let newIdArray = [];
3920        let idDuplicates = [];
3921        const arr = itemArray; // just to trigger a 'get' onto the array
3922        // ID gen is with index.
3923        if (idGenFuncUsesIndex) {
3924
3925            // Create array of new ids.
3926            arr.forEach((item, indx) => {
3927                newIdArray.push(idGenFunc(item, indx));
3928            });
3929        }
3930        else {
3931            // Create array of new ids.
3932
3933            arr.forEach((item, index) => {
3934                newIdArray.push(`${itemGenFuncUsesIndex ? index + '_' : ''}` + idGenFunc(item));
3935            });
3936        }
3937        // Set new array on C++ side.
3938        // C++ returns array of indexes of newly added array items.
3939        // these are indexes in new child list.
3940        ForEach.setIdArray(elmtId, newIdArray, diffIndexArray, idDuplicates);
3941        // Its error if there are duplicate IDs.
3942        if (idDuplicates.length > 0) {
3943            idDuplicates.forEach((indx) => {
3944                stateMgmtConsole.error(`Error: ${newIdArray[indx]} generated for ${indx}${indx < 4 ? indx == 2 ? "nd" : "rd" : "th"} array item ${arr[indx]}.`);
3945            });
3946            stateMgmtConsole.error(`Ids generated by the ForEach id gen function must be unique, error.`);
3947        }
3948
3949        // Item gen is with index.
3950
3951        // Create new elements if any.
3952        diffIndexArray.forEach((indx) => {
3953            ForEach.createNewChildStart(newIdArray[indx], this);
3954            if (itemGenFuncUsesIndex) {
3955                itemGenFunc(arr[indx], indx);
3956            }
3957            else {
3958                itemGenFunc(arr[indx]);
3959            }
3960            ForEach.createNewChildFinish(newIdArray[indx], this);
3961        });
3962    }
3963    /**
3964       * CreateStorageLink and CreateStorageLinkPU are used by the implementation of @StorageLink and
3965       * @LocalStotrageLink in full update and partial update solution respectively.
3966       * These are not part of the public AppStorage API , apps should not use.
3967       * @param storagePropName - key in LocalStorage
3968       * @param defaultValue - value to use when creating a new prop in the LocalStotage
3969       * @param owningView - the View/ViewPU owning the @StorageLink/@LocalStorageLink variable
3970       * @param viewVariableName -  @StorageLink/@LocalStorageLink variable name
3971       * @returns SynchedPropertySimple/ObjectTwoWay/PU
3972       */
3973    createStorageLink(storagePropName, defaultValue, viewVariableName) {
3974        return AppStorage.__CreateSync(storagePropName, defaultValue, (source) => (source === undefined)
3975            ? undefined
3976            : (source instanceof ObservedPropertySimple)
3977                ? new SynchedPropertySimpleTwoWayPU(source, this, viewVariableName)
3978                : new SynchedPropertyObjectTwoWayPU(source, this, viewVariableName));
3979    }
3980    createStorageProp(storagePropName, defaultValue, viewVariableName) {
3981        return AppStorage.__CreateSync(storagePropName, defaultValue, (source) => (source === undefined)
3982            ? undefined
3983            : (source instanceof ObservedPropertySimple)
3984                ? new SynchedPropertySimpleOneWayPU(source, this, viewVariableName)
3985                : new SynchedPropertyObjectOneWayPU(source, this, viewVariableName));
3986    }
3987    createLocalStorageLink(storagePropName, defaultValue, viewVariableName) {
3988        return this.localStorage_.__createSync(storagePropName, defaultValue, (source) => (source === undefined)
3989            ? undefined
3990            : (source instanceof ObservedPropertySimple)
3991                ? new SynchedPropertySimpleTwoWayPU(source, this, viewVariableName)
3992                : new SynchedPropertyObjectTwoWayPU(source, this, viewVariableName));
3993    }
3994    createLocalStorageProp(storagePropName, defaultValue, viewVariableName) {
3995        return this.localStorage_.__createSync(storagePropName, defaultValue, (source) => (source === undefined)
3996            ? undefined
3997            : (source instanceof ObservedPropertySimple)
3998                ? new SynchedPropertySimpleOneWayPU(source, this, viewVariableName)
3999                : new SynchedPropertyObjectOneWayPU(source, this, viewVariableName));
4000    }
4001}
4002// Array.sort() converts array items to string to compare them, sigh!
4003ViewPU.compareNumber = (a, b) => {
4004    return (a < b) ? -1 : (a > b) ? 1 : 0;
4005};
4006/*
4007 * Copyright (c) 2022 Huawei Device Co., Ltd.
4008 * Licensed under the Apache License, Version 2.0 (the "License");
4009 * you may not use this file except in compliance with the License.
4010 * You may obtain a copy of the License at
4011 *
4012 *     http://www.apache.org/licenses/LICENSE-2.0
4013 *
4014 * Unless required by applicable law or agreed to in writing, software
4015 * distributed under the License is distributed on an "AS IS" BASIS,
4016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4017 * See the License for the specific language governing permissions and
4018 * limitations under the License.
4019 *
4020 *  * ViewPU - View for Partial Update
4021 *
4022* all definitions in this file are framework internal
4023*/
4024/**
4025    given parameters for calling a @Builder function
4026    this function wraps the Object of type T inside a ES6 Proxy.
4027    Each param, i.e. Object property is either a function or a value.
4028    If it is a function the function can either return a value of expected
4029    parameter type or an ObservedPropertyabstract<T> where T is the exected
4030    parameter type. The latter is the case when passing a state variable by
4031    reference.
4032
4033    Two purposes:
4034    1 - @Builder function boxy accesses params a '$$.paramA'
4035        However paramA can be a function, so to obtain the value the
4036        access would need to be '$$.param()' The proxy executes
4037        the function and return s the result
4038    2 - said function returns to ObservedPropertyAbstract backing store of
4039        a calling @Component state variable (whenever the state var is
4040        provided to the @Builder function). For this case the proxy can provide
4041        - the value by executing paramA() to return the ObservedPropertyAbstract
4042          and further (monitored!) get() to read its value
4043        - when requested to return '__param1' it returns the ObservedPropertyAbstract
4044          object. The scenario is to use to init a @Link source.
4045  */
4046function makeBuilderParameterProxy(builderName, source) {
4047    return new Proxy(source, {
4048        set(target, prop, val) {
4049            throw Error(`@Builder '${builderName}': Invalid attempt to set(write to) parameter '${prop.toString()}' error!`);
4050        },
4051        get(target, prop) {
4052            const prop1 = prop.toString().trim().startsWith("__")
4053                ? prop.toString().trim().substring(2)
4054                : prop.toString().trim();
4055
4056            if (!(typeof target === "object") && (prop1 in target)) {
4057                throw Error(`@Builder '${builderName}': '${prop1}' used but not a function parameter error!`);
4058            }
4059            const value = target[prop1];
4060            if (typeof value !== "function") {
4061
4062                return value;
4063            }
4064            const funcRet = value();
4065            if ((typeof funcRet === "object") && ('get' in funcRet)) {
4066                if (prop1 !== prop) {
4067
4068                    return funcRet;
4069                }
4070                else {
4071
4072                    const result = funcRet.get();
4073
4074                    return result;
4075                }
4076            }
4077
4078            return funcRet;
4079        } // get
4080    }); // new Proxy
4081}
4082/*
4083 * Copyright (c) 2021 Huawei Device Co., Ltd.
4084 * Licensed under the Apache License, Version 2.0 (the "License");
4085 * you may not use this file except in compliance with the License.
4086 * You may obtain a copy of the License at
4087 *
4088 *     http://www.apache.org/licenses/LICENSE-2.0
4089 *
4090 * Unless required by applicable law or agreed to in writing, software
4091 * distributed under the License is distributed on an "AS IS" BASIS,
4092 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4093 * See the License for the specific language governing permissions and
4094 * limitations under the License.
4095 */
4096
4097PersistentStorage.ConfigureBackend(new Storage());
4098Environment.ConfigureBackend(new EnvironmentSetting());
4099
4100