• 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) 2023 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 * Copyright (c) 2021 Huawei Device Co., Ltd.
59 * Licensed under the Apache License, Version 2.0 (the "License");
60 * you may not use this file except in compliance with the License.
61 * You may obtain a copy of the License at
62 *
63 *     http://www.apache.org/licenses/LICENSE-2.0
64 *
65 * Unless required by applicable law or agreed to in writing, software
66 * distributed under the License is distributed on an "AS IS" BASIS,
67 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68 * See the License for the specific language governing permissions and
69 * limitations under the License.
70 */
71/**
72 *
73 * LocalStorage
74 *
75 * Class implements a Map of ObservableObjectBase UI state variables.
76 * Instances can be created to manage UI state within a limited "local"
77 * access, and life cycle as defined by the app.
78 * AppStorage singleton is sub-class of LocalStorage for
79 * UI state of app-wide access and same life cycle as the app.
80 *
81 * @since 9
82 */
83class LocalStorage extends NativeLocalStorage {
84    /*
85      get access to provded LocalStorage instance thru Stake model
86      @StageModelOnly
87      @form
88      @since 10
89    */
90    static getShared() {
91        return LocalStorage.GetShared();
92    }
93    /**
94     * Construct new instance of LocalStorage
95     * initialzie with all properties and their values that Object.keys(params) returns
96     * Property values must not be undefined.
97     * @param initializingProperties Object containing keys and values. @see set() for valid values
98     *
99     * @since 9
100     */
101    constructor(initializingProperties = {}) {
102        super();
103
104        this.storage_ = new Map();
105        if (Object.keys(initializingProperties).length) {
106            this.initializeProps(initializingProperties);
107        }
108    }
109    /**
110     * clear storage and init with given properties
111     * @param initializingProperties
112     *
113     * not a public / sdk function
114     */
115    initializeProps(initializingProperties = {}) {
116
117        this.storage_.clear();
118        Object.keys(initializingProperties).filter((propName) => initializingProperties[propName] != undefined).forEach((propName) => this.addNewPropertyInternal(propName, initializingProperties[propName]));
119    }
120    /**
121     * Use before deleting owning Ability, window, or service UI
122     * (letting it go out of scope).
123     *
124     * This method orderly closes down a LocalStorage instance by calling @see clear().
125     * This requires that no property is left with one or more subscribers.
126     * @see clear() and @see delete()
127     * @returns true if all properties could be removed from storage
128     */
129    aboutToBeDeleted() {
130        return this.clear();
131    }
132    /**
133     * Check if LocalStorage has a property with given name
134     * return true if prooperty with given name exists
135     * same as ES6 Map.prototype.has()
136     * @param propName searched property
137     * @returns true if property with such name exists in LocalStorage
138     *
139     * @since 9
140     */
141    has(propName) {
142        return this.storage_.has(propName);
143    }
144    /**
145     * Provide names of all properties in LocalStorage
146     * same as ES6 Map.prototype.keys()
147     * @returns return a Map Iterator
148     *
149     * @since 9
150    */
151    keys() {
152        return this.storage_.keys();
153    }
154    /**
155     * Returns number of properties in LocalStorage
156     * same as Map.prototype.size()
157     * @param propName
158     * @returns return number of properties
159     *
160     * @since 9
161     */
162    size() {
163        return this.storage_.size;
164    }
165    /**
166     * Returns value of given property
167     * return undefined if no property with this name
168     * @param propName
169     * @returns property value if found or undefined
170     *
171     * @since 9
172     */
173    get(propName) {
174        var p = this.storage_.get(propName);
175        return (p) ? p.get() : undefined;
176    }
177    /**
178     * Set value of given property in LocalStorage
179     * Methosd sets nothing and returns false if property with this name does not exist
180     * or if newValue is `undefined` or `null` (`undefined`, `null` value are not allowed for state variables).
181     * @param propName
182     * @param newValue must be of type T and must not be undefined or null
183     * @returns true on success, i.e. when above conditions are satisfied, otherwise false
184     *
185     * @since 9
186     */
187    set(propName, newValue) {
188        if (newValue == undefined) {
189            stateMgmtConsole.warn(`${this.constructor.name}: set('${propName}') with newValue == undefined not allowed.`);
190            return false;
191        }
192        var p = this.storage_.get(propName);
193        if (p == undefined) {
194            stateMgmtConsole.warn(`${this.constructor.name}: set: no property ${propName} error.`);
195            return false;
196        }
197        p.set(newValue);
198        return true;
199    }
200    /**
201     * Set value of given property, if it exists, @see set() .
202     * Add property if no property with given name and initialize with given value.
203     * Do nothing and return false if newValuue is undefined or null
204     * (undefined, null value is not allowed for state variables)
205     * @param propName
206     * @param newValue must be of type T and must not be undefined or null
207     * @returns true on success, i.e. when above conditions are satisfied, otherwise false
208     *
209     * @since 9
210     */
211    setOrCreate(propName, newValue) {
212        if (newValue == undefined) {
213            stateMgmtConsole.warn(`${this.constructor.name}: setOrCreate('${propName}') with newValue == undefined not allowed.`);
214            return false;
215        }
216        var p = this.storage_.get(propName);
217        if (p) {
218
219            p.set(newValue);
220        }
221        else {
222
223            this.addNewPropertyInternal(propName, newValue);
224        }
225        return true;
226    }
227    /**
228     * Internal use helper function to create and initialize a new property.
229     * caller needs to be all the checking beforehand
230     * @param propName
231     * @param value
232     *
233     * Not a public / sdk method.
234     */
235    addNewPropertyInternal(propName, value) {
236        const newProp = (typeof value === "object") ?
237            new ObservedPropertyObject(value, undefined, propName)
238            : new ObservedPropertySimple(value, undefined, propName);
239        this.storage_.set(propName, newProp);
240        return newProp;
241    }
242    /**
243     * create and return a two-way sync "(link") to named property
244     * @param propName name of source property in LocalStorage
245     * @param linkUser IPropertySubscriber to be notified when source changes,
246     * @param subscribersName optional, the linkUser (subscriber) uses this name for the property
247     *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
248     * @returns  SynchedPropertyTwoWay{Simple|Object| object with given LocalStoage prop as its source.
249     *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
250     *           return undefiend if named property does not already exist in LocalStorage
251     *           Apps can use SDK functions of base class SubscribedPropertyAbstract<S>
252     *           return undefiend if named property does not already exist in LocalStorage
253     *
254     * @since 9
255     */
256    link(propName, linkUser, subscribersName) {
257        var p = this.storage_.get(propName);
258        if (p == undefined) {
259            stateMgmtConsole.warn(`${this.constructor.name}: link: no property ${propName} error.`);
260            return undefined;
261        }
262        let linkResult;
263        if (ViewStackProcessor.UsesNewPipeline()) {
264            linkResult = (p instanceof ObservedPropertySimple)
265                ? new SynchedPropertySimpleTwoWayPU(p, linkUser, propName)
266                : new SynchedPropertyObjectTwoWayPU(p, linkUser, propName);
267        }
268        else {
269            linkResult = p.createLink(linkUser, propName);
270        }
271        linkResult.setInfo(subscribersName);
272        return linkResult;
273    }
274    /**
275     * Like @see link(), but will create and initialize a new source property in LocalStorge if missing
276     * @param propName name of source property in LocalStorage
277     * @param defaultValue value to be used for initializing if new creating new property in LocalStorage
278     *        default value must be of type S, must not be undefined or null.
279     * @param linkUser IPropertySubscriber to be notified when return 'link' changes,
280     * @param subscribersName the linkUser (subscriber) uses this name for the property
281     *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
282     * @returns SynchedPropertyTwoWay{Simple|Object| object with given LocalStoage prop as  its source.
283     *          Apps can use SDK functions of base class SubscribedAbstractProperty<S>
284     *
285     * @since 9
286     */
287    setAndLink(propName, defaultValue, linkUser, subscribersName) {
288        var p = this.storage_.get(propName);
289        if (!p) {
290            this.setOrCreate(propName, defaultValue);
291        }
292        return this.link(propName, linkUser, subscribersName);
293    }
294    /**
295     * create and return a one-way sync ('prop') to named property
296     * @param propName name of source property in LocalStorage
297     * @param propUser IPropertySubscriber to be notified when source changes,
298     * @param subscribersName the linkUser (subscriber) uses this name for the property
299     *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
300     * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as  its source.
301     *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
302     *           return undefiend if named property does not already exist in LocalStorage.
303     *           Apps can use SDK functions of base class SubscribedPropertyAbstract<S>
304     *           return undefiend if named property does not already exist in LocalStorage.
305     * @since 9
306     */
307    prop(propName, propUser, subscribersName) {
308        var p = this.storage_.get(propName);
309        if (p == undefined) {
310            stateMgmtConsole.warn(`${this.constructor.name}: prop: no property ${propName} error.`);
311            return undefined;
312        }
313        let propResult;
314        if (ViewStackProcessor.UsesNewPipeline()) {
315            propResult = (p instanceof ObservedPropertySimple)
316                ? new SynchedPropertySimpleOneWayPU(p, propUser, propName)
317                : new SynchedPropertyObjectOneWayPU(p, propUser, propName);
318        }
319        else {
320            propResult = p.createProp(propUser, propName);
321        }
322        propResult.setInfo(subscribersName);
323        return propResult;
324    }
325    /**
326     * Like @see prop(), will create and initialize a new source property in LocalStorage if missing
327     * @param propName name of source property in LocalStorage
328     * @param defaultValue value to be used for initializing if new creating new property in LocalStorage.
329     *        default value must be of type S, must not be undefined or null.
330     * @param propUser IPropertySubscriber to be notified when returned 'prop' changes,
331     * @param subscribersName the propUser (subscriber) uses this name for the property
332     *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
333     * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as its source.
334     *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
335     * @since 9
336     */
337    setAndProp(propName, defaultValue, propUser, subscribersName) {
338        var p = this.storage_.get(propName);
339        if (!p) {
340            this.setOrCreate(propName, defaultValue);
341        }
342        return this.prop(propName, propUser, subscribersName);
343    }
344    /**
345     * Delete property from StorageBase
346     * Use with caution:
347     * Before deleting a prop from LocalStorage all its subscribers need to
348     * unsubscribe from the property.
349     * This method fails and returns false if given property still has subscribers
350     * Another reason for failing is unkmown property.
351     *
352     * Developer advise:
353     * Subscribers are created with @see link(), @see prop()
354     * and also via @LocalStorageLink and @LocalStorageProp state variable decorators.
355     * That means as long as their is a @Component instance that uses such decorated variable
356     * or a sync relationship with a SubscribedAbstractProperty variable the property can nit
357     * (and also should not!) be deleted from LocalStorage.
358     *
359     * @param propName
360     * @returns false if method failed
361     *
362     * @since 9
363    */
364    delete(propName) {
365        var p = this.storage_.get(propName);
366        if (p) {
367            if (p.numberOfSubscrbers()) {
368                stateMgmtConsole.error(`${this.constructor.name}: Attempt to delete property ${propName} that has \
369          ${p.numberOfSubscrbers()} subscribers. Subscribers need to unsubscribe before prop deletion.`);
370                return false;
371            }
372            p.aboutToBeDeleted();
373            this.storage_.delete(propName);
374            return true;
375        }
376        else {
377            stateMgmtConsole.warn(`${this.constructor.name}: Attempt to delete unknown property ${propName}.`);
378            return false;
379        }
380    }
381    /**
382     * delete all properties from the LocalStorage instance
383     * @see delete().
384     * precondition is that there are no subscribers.
385     * method returns false and deletes no poperties if there is any property
386     * that still has subscribers
387     *
388     * @since 9
389     */
390    clear() {
391        for (let propName of this.keys()) {
392            var p = this.storage_.get(propName);
393            if (p.numberOfSubscrbers()) {
394                stateMgmtConsole.error(`${this.constructor.name}.deleteAll: Attempt to delete property ${propName} that \
395          has ${p.numberOfSubscrbers()} subscribers. Subscribers need to unsubscribe before prop deletion.
396          Any @Component instance with a @StorageLink/Prop or @LocalStorageLink/Prop is a subscriber.`);
397                return false;
398            }
399        }
400        for (let propName of this.keys()) {
401            var p = this.storage_.get(propName);
402            p.aboutToBeDeleted();
403        }
404        this.storage_.clear();
405
406        return true;
407    }
408    /**
409     * Subscribe to value change notifications of named property
410     * Any object implementing ISinglePropertyChangeSubscriber interface
411     * and registerign itself to SubscriberManager can register
412     * Caution: do remember to unregister, otherwise the property will block
413     * cleanup, @see delete() and @see clear()
414     *
415     * @param propName property in LocalStorage to subscribe to
416     * @param subscriber object that implements ISinglePropertyChangeSubscriber interface
417     * @returns false if named property does not exist
418     *
419     * @since 9
420     */
421    subscribeToChangesOf(propName, subscriber) {
422        var p = this.storage_.get(propName);
423        if (p) {
424            p.addSubscriber(subscriber);
425            return true;
426        }
427        return false;
428    }
429    /**
430     * inverse of @see subscribeToChangesOf
431     * @param propName property in LocalStorage to subscribe to
432     * @param subscriberId id of the subscrber passed to @see subscribeToChangesOf
433     * @returns false if named property does not exist
434     *
435     * @since 9
436     */
437    unsubscribeFromChangesOf(propName, subscriberId) {
438        var p = this.storage_.get(propName);
439        if (p) {
440            p.removeSubscriber(null, subscriberId);
441            return true;
442        }
443        return false;
444    }
445    /**
446     * return number of subscribers to named property
447     *  useful for debug purposes
448     *
449     * Not a public / sdk function
450    */
451    numberOfSubscrbersTo(propName) {
452        var p = this.storage_.get(propName);
453        if (p) {
454            return p.numberOfSubscrbers();
455        }
456        return undefined;
457    }
458    __createSync(storagePropName, defaultValue, factoryFunc) {
459        let p = this.storage_.get(storagePropName);
460        if (p == undefined) {
461            // property named 'storagePropName' not yet in storage
462            // add new property to storage
463            if (defaultValue === undefined) {
464                stateMgmtConsole.error(`${this.constructor.name}.__createSync(${storagePropName}, non-existing property and undefined default value. ERROR.`);
465                return undefined;
466            }
467            p = this.addNewPropertyInternal(storagePropName, defaultValue);
468        }
469        return factoryFunc(p);
470    }
471}
472/*
473 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
474 * Licensed under the Apache License, Version 2.0 (the "License");
475 * you may not use this file except in compliance with the License.
476 * You may obtain a copy of the License at
477 *
478 *     http://www.apache.org/licenses/LICENSE-2.0
479 *
480 * Unless required by applicable law or agreed to in writing, software
481 * distributed under the License is distributed on an "AS IS" BASIS,
482 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
483 * See the License for the specific language governing permissions and
484 * limitations under the License.
485 */
486/**
487 *
488 * AppStorage
489 *
490 * Class implements a Map of ObservableObjectBase UI state variables.
491 * AppStorage singleton is sub-class of @see LocalStorage for
492 * UI state of app-wide access and same life cycle as the app.
493 *
494 * @since 7
495 */
496class AppStorage extends LocalStorage {
497    /**
498    * create and initialize singleton
499    * initialzie with all properties and their values that Object.keys(params) returns
500    * Property values must not be undefined.
501    *
502    * not a public / sdk function
503    */
504    static createSingleton(initializingPropersties) {
505        if (!AppStorage.instance_) {
506
507            AppStorage.instance_ = new AppStorage(initializingPropersties);
508        }
509        else {
510            stateMgmtConsole.error("AppStorage.createNewInstance(..): instance exists already, internal error!");
511        }
512    }
513    /**
514    * create and return a two-way sync "(link") to named property
515    *
516    * Same as @see LocalStorage.link()
517    *
518    * @param propName name of source property in AppStorage
519    * @param linkUser IPropertySubscriber to be notified when source changes,
520    * @param subscribersName the linkUser (subscriber) uses this name for the property
521    *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
522    * @returns  SynchedPropertyTwoWay{Simple|Object| object with given LocalStoage prop as its source.
523    *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
524    *           return undefiend if named property does not already exist in AppStorage
525    *
526    * @since 10
527    */
528    static link(key, linkUser, subscribersName) {
529        return AppStorage.getOrCreate().link(key, linkUser, subscribersName);
530    }
531    /**
532    * @see link
533    * @since 7
534    * @deprecated
535    */
536    static Link(key, linkUser, subscribersName) {
537        return AppStorage.getOrCreate().link(key, linkUser, subscribersName);
538    }
539    /**
540    * Like @see link(), but will create and initialize a new source property in LocalStorage if missing
541    *
542    * Same as @see LocalStorage.setAndLink()
543    *
544    * @param propName name of source property in AppStorage
545    * @param defaultValue value to be used for initializing if new creating new property in AppStorage
546    *        default value must be of type S, must not be undefined or null.
547    * @param linkUser IPropertySubscriber to be notified when return 'link' changes,
548    * @param subscribersName the linkUser (subscriber) uses this name for the property
549    *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
550    * @returns SynchedPropertyTwoWay{Simple|Object| object with given LocalStoage prop as  its source.
551    *          Apps can use SDK functions of base class SubscribedAbstractProperty<S>
552    *
553    * @since 10
554    */
555    static setAndLink(key, defaultValue, linkUser, subscribersName) {
556        return AppStorage.getOrCreate().setAndLink(key, defaultValue, linkUser, subscribersName);
557    }
558    /**
559    * @see setAndLink
560    * @since 7
561    * @deprecated
562    */
563    static SetAndLink(key, defaultValue, linkUser, subscribersName) {
564        return AppStorage.getOrCreate().setAndLink(key, defaultValue, linkUser, subscribersName);
565    }
566    /**
567    * create and return a one-way sync ('prop') to named property
568    *
569    * Same as @see LocalStorage.prop()
570    *
571    * @param propName name of source property in AppStorage
572    * @param propUser IPropertySubscriber to be notified when source changes,
573    * @param subscribersName the linkUser (subscriber) uses this name for the property
574    *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
575    * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as  its source.
576    *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
577    *           return undefiend if named property does not already exist in AppStorage.
578    * @since 10
579    */
580    static prop(propName, propUser, subscribersName) {
581        return AppStorage.getOrCreate().prop(propName, propUser, subscribersName);
582    }
583    /**
584    * @see prop
585    * @since 7
586    * @deprecated
587    */
588    static Prop(propName, propUser, subscribersName) {
589        return AppStorage.getOrCreate().prop(propName, propUser, subscribersName);
590    }
591    /**
592    * Like @see prop(), will create and initialize a new source property in AppStorage if missing
593    *
594    * Same as @see LocalStorage.setAndProp()
595    *
596    * @param propName name of source property in AppStorage
597    * @param defaultValue value to be used for initializing if new creating new property in AppStorage.
598    *        default value must be of type S, must not be undefined or null.
599    * @param propUser IPropertySubscriber to be notified when returned 'prop' changes,
600    * @param subscribersName the propUser (subscriber) uses this name for the property
601    *      this name will be used in propertyChange(propName) callback of IMultiPropertiesChangeSubscriber
602    * @returns  SynchedPropertyOneWay{Simple|Object| object with given LocalStoage prop as its source.
603    *           Apps can use SDK functions of base class SubscribedAbstractProperty<S>
604    *
605    * @since 10
606    */
607    static setAndProp(key, defaultValue, propUser, subscribersName) {
608        return AppStorage.getOrCreate().setAndProp(key, defaultValue, propUser, subscribersName);
609    }
610    /**
611    * @see setAndProp
612    * @since 7
613    * @deprecated
614    */
615    static SetAndProp(key, defaultValue, propUser, subscribersName) {
616        return AppStorage.getOrCreate().setAndProp(key, defaultValue, propUser, subscribersName);
617    }
618    /**
619    * Check if AppStorage has a property with given name
620    * return true if property with given name exists
621    * same as ES6 Map.prototype.has()
622    *
623    * Same as @see LocalStorage.has()
624    *
625    * @param propName searched property
626    * @returns true if property with such name exists in AppStorage
627    *
628    * @since 10
629    */
630    static has(key) {
631        return AppStorage.getOrCreate().has(key);
632    }
633    /**
634   * @see has()
635   * @since 7
636   * @deprecated
637   */
638    static Has(key) {
639        return AppStorage.getOrCreate().has(key);
640    }
641    /**
642    * Returns value of given property
643    * return undefined if no property with this name
644    *
645    * @Same as see LocalStorage.get()
646    *
647    * @param propName
648    * @returns property value if found or undefined
649    *
650    * @since 10
651    *
652    */
653    static get(key) {
654        return AppStorage.getOrCreate().get(key);
655    }
656    /**
657    * @see get
658    * @since 7
659    * @deprecated
660    *
661    */
662    static Get(key) {
663        return AppStorage.getOrCreate().get(key);
664    }
665    /**
666    * Set value of given property in AppStorage
667    * Method sets nothing and returns false if property with this name does not exist
668    * or if newValue is `undefined` or `null` (`undefined`, `null` value are not allowed for state variables).
669    *
670    * Same as @see LocalStorage.set
671    *
672    * @param propName
673    * @param newValue must be of type T and must not be undefined or null
674    * @returns true on success, i.e. when above conditions are satisfied, otherwise false
675    *
676    * @since 10
677    */
678    static set(key, newValue) {
679        return AppStorage.getOrCreate().set(key, newValue);
680    }
681    /**
682    * @see set
683    * @since 7
684    * @deprecated
685    */
686    static Set(key, newValue) {
687        return AppStorage.getOrCreate().set(key, newValue);
688    }
689    /**
690   * Set value of given property, if it exists, @see set() .
691   * Add property if no property with given name and initialize with given value.
692   * Do nothing and return false if newValuue is undefined or null
693   * (undefined, null value is not allowed for state variables)
694   *
695   * @see LocalStorage.setOrCreate()
696   *
697   * @param propName
698   * @param newValue must be of type T and must not be undefined or null
699   * @returns true on success, i.e. when above conditions are satisfied, otherwise false
700   *
701   * @since 10
702   */
703    static setOrCreate(key, newValue) {
704        AppStorage.getOrCreate().setOrCreate(key, newValue);
705    }
706    /**
707    * @see setOrCreate
708    * @since 7
709    * @deprecated
710    */
711    static SetOrCreate(key, newValue) {
712        AppStorage.getOrCreate().setOrCreate(key, newValue);
713    }
714    /**
715    * Delete property from StorageBase
716    * Use with caution:
717    * Before deleting a prop from AppStorage all its subscribers need to
718    * unsubscribe from the property.
719    * This method fails and returns false if given property still has subscribers
720    * Another reason for failing is unkmown property.
721    *
722    * Developer advise:
723    * Subscribers are created with @see link(), @see prop()
724    * and also via @LocalStorageLink and @LocalStorageProp state variable decorators.
725    * That means as long as their is a @Component instance that uses such decorated variable
726    * or a sync relationship with a SubscribedAbstractProperty variable the property can nit
727    * (and also should not!) be deleted from AppStorage.
728    *
729    * Same as @see LocalStorage.delete()
730    *
731    * @param propName
732    * @returns false if method failed
733    *
734    * @since 10
735    */
736    static delete(key) {
737        return AppStorage.getOrCreate().delete(key);
738    }
739    /**
740    * @see delete
741    * @since 7
742    * @deprecated
743    */
744    static Delete(key) {
745        return AppStorage.getOrCreate().delete(key);
746    }
747    /**
748    * Provide names of all properties in AppStorage
749    * same as ES6 Map.prototype.keys()
750    *
751    * Same as @see LocalStorage.keys()
752    *
753    * @returns return a Map Iterator
754    *
755    * @since 10
756   */
757    static keys() {
758        return AppStorage.getOrCreate().keys();
759    }
760    /**
761    * @see keys
762    * @since 7
763    * @deprecated
764    */
765    static Keys() {
766        return AppStorage.getOrCreate().keys();
767    }
768    /**
769    * Returns number of properties in AppStorage
770    * same as Map.prototype.size()
771    *
772    * Same as @see LocalStorage.size()
773    *
774    * @param propName
775    * @returns return number of properties
776    *
777    * @since 10
778    */
779    static size() {
780        return AppStorage.getOrCreate().size();
781    }
782    /**
783    * @see size
784    * @since 7
785    * @deprecated
786    */
787    static Size() {
788        return AppStorage.getOrCreate().size();
789    }
790    /**
791    * delete all properties from the AppStorage
792    *
793    * @see delete(), same as @see LocalStorage.clear()
794    *
795    * precondition is that there are no subscribers.
796    * method returns false and deletes no poperties if there is any property
797    * that still has subscribers
798    *
799    * @since 10
800    */
801    static clear() {
802        return AppStorage.getOrCreate().clear();
803    }
804    /**
805    * @see clear
806    * @since 7
807    * @deprecated
808    */
809    static Clear() {
810        return AppStorage.getOrCreate().clear();
811    }
812    /**
813    * Same as @see clear().
814    *
815    * @since 7, deprecated, used clear() instead!
816    *
817    */
818    static StaticClear() {
819        return AppStorage.clear();
820    }
821    /**
822    * not a public / sdk function
823    */
824    static aboutToBeDeleted() {
825        AppStorage.getOrCreate().aboutToBeDeleted();
826    }
827    /**
828     * return number of subscribers to named property
829     * useful for debug purposes
830     *
831     * not a public / sdk function
832    */
833    static numberOfSubscribersTo(propName) {
834        return AppStorage.getOrCreate().numberOfSubscrbersTo(propName);
835    }
836    /**
837    * Subscribe to value change notifications of named property
838    * Any object implementing ISinglePropertyChangeSubscriber interface
839    * and registerign itself to SubscriberManager can register
840    * Caution: do remember to unregister, otherwise the property will block
841    * cleanup, @see delete() and @see clear()
842    *
843    * Same as @see LocalStorage.subscribeToChangesOf()
844    *
845    * @param propName property in AppStorage to subscribe to
846    * @param subscriber object that implements ISinglePropertyChangeSubscriber interface
847    * @returns false if named property does not exist
848    *
849    * @since 10
850    */
851    static subscribeToChangesOf(propName, subscriber) {
852        return AppStorage.getOrCreate().subscribeToChangesOf(propName, subscriber);
853    }
854    /**
855    * @see subscribeToChangesOf
856    * @since 7
857    * @deprecated
858    */
859    static SubscribeToChangesOf(propName, subscriber) {
860        return AppStorage.getOrCreate().subscribeToChangesOf(propName, subscriber);
861    }
862    /**
863    * inverse of @see SubscribeToChangesOf,
864    * same as @see LocalStorage.subscribeToChangesOf()
865    *
866    * @param propName property in AppStorage to subscribe to
867    * @param subscriberId id of the subscrber passed to @see subscribeToChangesOf
868    * @returns false if named property does not exist
869    *
870    * @since 10
871    */
872    static unsubscribeFromChangesOf(propName, subscriberId) {
873        return AppStorage.getOrCreate().unsubscribeFromChangesOf(propName, subscriberId);
874    }
875    /**
876    * @see unsubscribeFromChangesOf
877    * @since 7
878    * @deprecated
879    */
880    static UnsubscribeFromChangesOf(propName, subscriberId) {
881        return AppStorage.getOrCreate().unsubscribeFromChangesOf(propName, subscriberId);
882    }
883    /**
884     * Unimplemented, currently all properties of AppStorage are mutable.
885     *
886     * @since 7, deprecated
887     */
888    static IsMutable(key) {
889        return true;
890    }
891    /**
892    * not a public / sdk function
893    */
894    static __createSync(storagePropName, defaultValue, factoryFunc) {
895        return AppStorage.getOrCreate().__createSync(storagePropName, defaultValue, factoryFunc);
896    }
897    /**
898    * not a public / sdk function
899    */
900    static getOrCreate() {
901        if (!AppStorage.instance_) {
902            stateMgmtConsole.warn("AppStorage instance missing. Use AppStorage.createInstance(initObj). Creating instance without any initialization.");
903            AppStorage.instance_ = new AppStorage({});
904        }
905        return AppStorage.instance_;
906    }
907    /** singleton class, app can not create instances
908    *
909    * not a public / sdk function
910    */
911    constructor(initializingProperties) {
912        super(initializingProperties);
913    }
914}
915// instance functions below:
916// Should all be protected, but TS lang does not allow access from static member to protected member
917AppStorage.instance_ = undefined;
918/*
919 * Copyright (c) 2022 Huawei Device Co., Ltd.
920 * Licensed under the Apache License, Version 2.0 (the "License");
921 * you may not use this file except in compliance with the License.
922 * You may obtain a copy of the License at
923 *
924 *     http://www.apache.org/licenses/LICENSE-2.0
925 *
926 * Unless required by applicable law or agreed to in writing, software
927 * distributed under the License is distributed on an "AS IS" BASIS,
928 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
929 * See the License for the specific language governing permissions and
930 * limitations under the License.
931 */
932/**
933 * Singleton class SubscriberManager implements IPropertySubscriberLookup
934 * public API to manage IPropertySubscriber
935 */
936class SubscriberManager {
937    /**
938      * check subscriber is known
939      * same as ES6 Map.prototype.has()
940      *
941      * @since 9
942      */
943    static Has(id) {
944        return SubscriberManager.GetInstance().has(id);
945    }
946    /**
947     *
948     * retrieve subscriber by id
949     * same as ES6 Map.prototype.get()
950     *
951     *  @since 9
952     */
953    static Find(id) {
954        return SubscriberManager.GetInstance().get(id);
955    }
956    /**
957     * unregister a subscriber
958     * same as ES6 Map.prototype.delete()
959     * @return boolean success or failure to delete
960     *
961     *  @since 9
962     */
963    static Delete(id) {
964        return SubscriberManager.GetInstance().delete(id);
965    }
966    /**
967    * add a new subscriber.
968    * The subscriber must have a new (unused) id (@see MakeId() )
969    * for add() to succeed.
970    * same as Map.prototype.set()
971    *
972    *  @since 9
973    */
974    static Add(newSubsriber) {
975        return SubscriberManager.GetInstance().add(newSubsriber);
976    }
977    /**
978     * Update recycle custom node element id.
979     */
980    static UpdateRecycleElmtId(oldId, newId) {
981        return SubscriberManager.GetInstance().updateRecycleElmtId(oldId, newId);
982    }
983    /**
984    *
985    * @returns a globally unique id to be assigned to a IPropertySubscriber objet
986    * Use MakeId() to assign a IPropertySubscriber object an id before calling @see add() .
987    *
988    *  @since 9
989   */
990    static MakeId() {
991        return SubscriberManager.GetInstance().makeId();
992    }
993    /**
994     * Check number of registered Subscriber / registered IDs.
995     * @returns number of registered unique ids.
996     *
997     *  @since 9
998     */
999    static NumberOfSubscribers() {
1000        return SubscriberManager.GetInstance().numberOfSubscribers();
1001    }
1002    /**
1003     *
1004     * internal (non-SDK) methods below
1005     *
1006    */
1007    /**
1008   * Get singleton, create it on first call
1009   * @returns SubscriberManager singleton
1010   *
1011   * internal function
1012   * This function will be removed soon, use static functions instead!
1013   * Note: Fnction gets used by transpiler output for both full update and partial update
1014   */
1015    static Get() {
1016        if (!SubscriberManager.instance_) {
1017            SubscriberManager.instance_ = new SubscriberManager();
1018        }
1019        return SubscriberManager.instance_;
1020    }
1021    /**
1022     * Get singleton, create it on first call
1023     * @returns SubscriberManager singleton
1024     *
1025     * internal function
1026     */
1027    static GetInstance() {
1028        if (!SubscriberManager.instance_) {
1029            SubscriberManager.instance_ = new SubscriberManager();
1030        }
1031        return SubscriberManager.instance_;
1032    }
1033    /**
1034     * for debug purposes dump all known subscriber's info to comsole
1035     *
1036     * not a public / sdk function
1037     */
1038    static DumpSubscriberInfo() {
1039        SubscriberManager.GetInstance().dumpSubscriberInfo();
1040    }
1041    /**
1042     * not a public / sdk function
1043     * @see Has
1044     */
1045    has(id) {
1046        return this.subscriberById_.has(id);
1047    }
1048    /**
1049     * not a public / sdk function
1050     * @see Get
1051     */
1052    get(id) {
1053        return this.subscriberById_.get(id);
1054    }
1055    /**
1056   * not a public / sdk function
1057   * @see Delete
1058   */
1059    delete(id) {
1060        if (!this.has(id)) {
1061            stateMgmtConsole.warn(`SubscriberManager.delete unknown id ${id} `);
1062            return false;
1063        }
1064        return this.subscriberById_.delete(id);
1065    }
1066    /**
1067   * not a public / sdk function
1068   * @see Add
1069   */
1070    add(newSubsriber) {
1071        if (this.has(newSubsriber.id__())) {
1072            return false;
1073        }
1074        this.subscriberById_.set(newSubsriber.id__(), newSubsriber);
1075        return true;
1076    }
1077    updateRecycleElmtId(oldId, newId) {
1078        if (!this.has(oldId)) {
1079            return false;
1080        }
1081        const subscriber = this.get(oldId);
1082        this.subscriberById_.delete(oldId);
1083        this.subscriberById_.set(newId, subscriber);
1084        return true;
1085    }
1086    /**
1087     * Method for testing purposes
1088     * @returns number of subscribers
1089     *
1090     * not a public / sdk function
1091     */
1092    numberOfSubscribers() {
1093        return this.subscriberById_.size;
1094    }
1095    /**
1096     * for debug purposes dump all known subscriber's info to comsole
1097     *
1098     * not a public / sdk function
1099     */
1100    dumpSubscriberInfo() {
1101
1102        for (let [id, subscriber] of this.subscriberById_) {
1103
1104        }
1105
1106    }
1107    /**
1108     *
1109     * @returns a globally unique id to be assigned to a Subscriber
1110     */
1111    makeId() {
1112        return ViewStackProcessor.MakeUniqueId();
1113    }
1114    /**
1115     * SubscriberManager is a singleton created by the framework
1116     * do not use
1117     *
1118     * internal method
1119     */
1120    constructor() {
1121        this.subscriberById_ = new Map();
1122
1123    }
1124}
1125/*
1126 * Copyright (c) 2022 Huawei Device Co., Ltd.
1127 * Licensed under the Apache License, Version 2.0 (the "License");
1128 * you may not use this file except in compliance with the License.
1129 * You may obtain a copy of the License at
1130 *
1131 *     http://www.apache.org/licenses/LICENSE-2.0
1132 *
1133 * Unless required by applicable law or agreed to in writing, software
1134 * distributed under the License is distributed on an "AS IS" BASIS,
1135 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1136 * See the License for the specific language governing permissions and
1137 * limitations under the License.
1138 */
1139/**
1140 *
1141 *   SubscribedAbstractProperty is base class of ObservedPropertyAbstract
1142 *   and includes these 3 functions that are part of the SDK.
1143 *
1144 *   SubscribedAbstractProperty<T> is the return type of
1145 *   - AppStorage static functions Link(), Prop(), SetAndLink(), and SetAndProp()
1146 *   - LocalStorage methods link(), prop(), setAndLink(), and setAndProp()
1147 *
1148 *   'T' can be boolean, string, number or custom class.
1149 *
1150 * Main functions
1151 *   @see get() reads the linked AppStorage/LocalStorage property value,
1152 *   @see set(newValue) write a new value to the synched AppStorage/LocalStorage property value
1153 *   @see aboutToBeDeleted() ends the sync relationship with the AppStorage/LocalStorage property
1154 *        The app must call this function before the SubscribedAbstractProperty<T> object
1155 *        goes out of scope.
1156 *
1157 * @since 7
1158*/
1159class SubscribedAbstractProperty {
1160}
1161/*
1162 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
1163 * Licensed under the Apache License, Version 2.0 (the "License");
1164 * you may not use this file except in compliance with the License.
1165 * You may obtain a copy of the License at
1166 *
1167 *     http://www.apache.org/licenses/LICENSE-2.0
1168 *
1169 * Unless required by applicable law or agreed to in writing, software
1170 * distributed under the License is distributed on an "AS IS" BASIS,
1171 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1172 * See the License for the specific language governing permissions and
1173 * limitations under the License.
1174 */
1175/**
1176 *
1177 * SubscribableAbstract
1178 *
1179 * This class is part of the SDK.
1180 * @since 10
1181 *
1182 * SubscribableAbstract is an abstract class that manages subscribers
1183 * to value changes. These subscribers are the implementation of
1184 * @State, @Link, @Provide, @Consume decorated variables inside the
1185 * framework. Each using @State, @Link, etc., decorated variable in
1186 * a @Component will make its own subscription. When the component
1187 * is created the subscription is added, and before the component
1188 * is deleted it unsubscribes
1189 *
1190 * An application may extend SubscribableAbstract for a custom class
1191 * that manages state data. @State, @Link, @Provide, @Consume
1192 * decorated variables can hold an Object that is instance of
1193 * SubscribableAbstract.
1194 *
1195 * About lifecycle: It is legal use for two @Components with two @State
1196 * decorated variables to share the same SubscribableAbstract object.
1197 * Each such decorated variable implementation makes its own
1198 * subscription to the SubscribableAbstract object. Hence, when both variables
1199 * have unsubscribed the SubscribableAbstract custom class may do its own
1200 * de-initialization, e.g. release held external resources.
1201 *
1202 * How to extend:
1203 * A subclass manages the get and set to one or several properties on its own.
1204 * The subclass needs to notify all relevant value changes to the framework for the
1205 * UI to be updated. Notification should only be given for class properties that
1206 * are used to generate the UI.
1207 *
1208 * A subclass must call super() in its constructor to let this base class
1209 * initialize itself.
1210 *
1211 * A subclass must call 'notifyPropertyHasChanged*(' after the relevant property
1212 * has changes. The framework will notify all dependent components to re-render.
1213 *
1214 * A sub-class may overwrite the 'addOwningProperty' function to add own
1215 * functionality, but it must call super.addowningOwningProperty(..). E.g.
1216 * the sub-class could connect to external resources upon the first subscriber.
1217 *
1218 * A sub-class may also overwrite the 'removeOwningProperty' function or
1219 * 'removeOwningPropertyById' function to add own functionality,
1220 * but it must call super.removeOwningProperty(..).
1221 * E.g. the sub-class could release held external resources upon loosing the
1222 * last subscriber.
1223 *
1224 */
1225class SubscribableAbstract {
1226    /**
1227     * make sure to call super() from subclass constructor!
1228     *
1229     * @since 10
1230     */
1231    constructor() {
1232        this.owningProperties_ = new Set();
1233
1234    }
1235    /**
1236    * A subsclass must call this function whenever one of its properties has
1237     * changed that is used to construct the UI.
1238     * @param propName name of the change property
1239     * @param newValue the property value after the change
1240     *
1241     * @since 10
1242     */
1243    notifyPropertyHasChanged(propName, newValue) {
1244
1245        this.owningProperties_.forEach((subscribedId) => {
1246            var owningProperty = SubscriberManager.Find(subscribedId);
1247            if (owningProperty) {
1248                if ('objectPropertyHasChangedPU' in owningProperty) {
1249                    // PU code path
1250                    owningProperty.objectPropertyHasChangedPU(this, propName);
1251                }
1252                // FU code path
1253                if ('hasChanged' in owningProperty) {
1254                    owningProperty.hasChanged(newValue);
1255                }
1256                if ('propertyHasChanged' in owningProperty) {
1257                    owningProperty.propertyHasChanged(propName);
1258                }
1259            }
1260            else {
1261                stateMgmtConsole.error(`SubscribableAbstract: notifyHasChanged: unknown subscriber.'${subscribedId}' error!.`);
1262            }
1263        });
1264    }
1265    /**
1266     * Provides the current number of subscribers.
1267     * Application may use this function to determine a shared object has no more remaining subscribers and can be deleted.
1268     * @returns number of current subscribers
1269     *
1270     * @since 10
1271     */
1272    numberOfSubscribers() {
1273        return this.owningProperties_.size;
1274    }
1275    /**
1276     * Method used by the framework to add subscribing decorated variables
1277     * Subclass may overwrite this function but must call the function of the base
1278     * class from its own implementation.
1279     * @param subscriber new subscriber that implements ISinglePropertyChangeSubscriber
1280     * and/or IMultiPropertiesChangeSubscriber interfaces
1281     *
1282     * @since 10
1283     */
1284    addOwningProperty(subscriber) {
1285
1286        this.owningProperties_.add(subscriber.id__());
1287    }
1288    /**
1289     * Method used by the framework to unsubscribing decorated variables
1290     * Subclass may overwrite this function but must call the function of the base
1291     * class from its own implementation.
1292     * @param subscriber subscriber that implements ISinglePropertyChangeSubscriber
1293     * and/or IMultiPropertiesChangeSubscriber interfaces
1294     *
1295     * @since 10
1296     */
1297    removeOwningProperty(property) {
1298        return this.removeOwningPropertyById(property.id__());
1299    }
1300    /**
1301     * Same as @see removeOwningProperty() but by Subscriber id.
1302     * @param subscriberId
1303    *
1304     * framework internal function, not to be used by applications.
1305     */
1306    removeOwningPropertyById(subscriberId) {
1307
1308        this.owningProperties_.delete(subscriberId);
1309    }
1310    /**
1311     * flush all subscribers / owning properties
1312     * This is needed when copying a SubscribableAbstract object to the localObject or @prop / SynchedPropertyObjectOneWay
1313     * - shallowCopy: copies the _reference to original_ Set. Hence, we must not modify this Set but assign a new Set
1314     * - deepCopy also (deep-) copies this class' owningProperties_ Set, incl. the numbers it includes. Assigning a new Set fixes.
1315     *
1316     */
1317    clearOwningProperties() {
1318        this.owningProperties_ = new Set();
1319    }
1320}
1321/**
1322 *  SubscribaleAbstract class with typo in its nam,e
1323 *
1324 * @depreciated, use SubscribableAbstract
1325 */
1326class SubscribaleAbstract extends SubscribableAbstract {
1327}
1328/*
1329 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
1330 * Licensed under the Apache License, Version 2.0 (the "License");
1331 * you may not use this file except in compliance with the License.
1332 * You may obtain a copy of the License at
1333 *
1334 *     http://www.apache.org/licenses/LICENSE-2.0
1335 *
1336 * Unless required by applicable law or agreed to in writing, software
1337 * distributed under the License is distributed on an "AS IS" BASIS,
1338 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1339 * See the License for the specific language governing permissions and
1340 * limitations under the License.
1341 */
1342/**
1343 * PersistentStorage
1344 *
1345 * Keeps current values of select AppStorage property properties persisted to file.
1346 *
1347 * since 9
1348 */
1349class PersistentStorage {
1350    /**
1351     *
1352     * @param storage method to be used by the framework to set the backend
1353     * this is to be done during startup
1354     *
1355     * internal function, not part of the SDK
1356     *
1357     */
1358    static configureBackend(storage) {
1359        PersistentStorage.storage_ = storage;
1360    }
1361    /**
1362     * private, use static functions!
1363     */
1364    static getOrCreate() {
1365        if (PersistentStorage.instance_) {
1366            // already initialized
1367            return PersistentStorage.instance_;
1368        }
1369        PersistentStorage.instance_ = new PersistentStorage();
1370        return PersistentStorage.instance_;
1371    }
1372    /**
1373     *
1374     * internal function, not part of the SDK
1375     */
1376    static aboutToBeDeleted() {
1377        if (!PersistentStorage.instance_) {
1378            return;
1379        }
1380        PersistentStorage.getOrCreate().aboutToBeDeleted();
1381        PersistentStorage.instance_ = undefined;
1382    }
1383    /**
1384     * Add property 'key' to AppStorage properties whose current value will be
1385     * persistent.
1386     * If AppStorage does not include this property it will be added and initializes
1387     * with given value
1388     *
1389     * @since 10
1390     *
1391     * @param key property name
1392     * @param defaultValue If AppStorage does not include this property it will be initialized with this value
1393     *
1394     */
1395    static persistProp(key, defaultValue) {
1396        PersistentStorage.getOrCreate().persistProp(key, defaultValue);
1397    }
1398    /**
1399     * @see persistProp
1400     * @deprecated
1401     */
1402    static PersistProp(key, defaultValue) {
1403        PersistentStorage.getOrCreate().persistProp(key, defaultValue);
1404    }
1405    /**
1406     * Reverse of @see persistProp
1407     * @param key no longer persist the property named key
1408     *
1409     * @since 10
1410     */
1411    static deleteProp(key) {
1412        PersistentStorage.getOrCreate().deleteProp(key);
1413    }
1414    /**
1415     * @see deleteProp
1416     * @deprecated
1417     */
1418    static DeleteProp(key) {
1419        PersistentStorage.getOrCreate().deleteProp(key);
1420    }
1421    /**
1422     * Persist given AppStorage properties with given names.
1423     * If a property does not exist in AppStorage, add it and initialize it with given value
1424     * works as @see persistProp for multiple properties.
1425     *
1426     * @param properties
1427     *
1428     * @since 10
1429     *
1430     */
1431    static persistProps(properties) {
1432        PersistentStorage.getOrCreate().persistProps(properties);
1433    }
1434    /**
1435     * @see persistProps
1436     * @deprecated
1437     */
1438    static PersistProps(properties) {
1439        PersistentStorage.getOrCreate().persistProps(properties);
1440    }
1441    /**
1442     * Inform persisted AppStorage property names
1443     * @returns array of AppStorage keys
1444     *
1445     * @since 10
1446     */
1447    static keys() {
1448        let result = [];
1449        const it = PersistentStorage.getOrCreate().keys();
1450        let val = it.next();
1451        while (!val.done) {
1452            result.push(val.value);
1453            val = it.next();
1454        }
1455        return result;
1456    }
1457    /**
1458     * @see keys
1459     * @deprecated
1460     */
1461    static Keys() {
1462        return PersistentStorage.keys();
1463    }
1464    /**
1465      * This methid offers a way to force writing the property value with given
1466      * key to persistent storage.
1467      * In the general case this is unnecessary as the framework observed changes
1468      * and triggers writing to disk by itself. For nested objects (e.g. array of
1469      * objects) however changes of a property of a property as not observed. This
1470      * is the case where the application needs to signal to the framework.
1471      *
1472      * @param key property that has changed
1473      *
1474      * @since 10
1475      *
1476      */
1477    static notifyHasChanged(propName) {
1478
1479        PersistentStorage.storage_.set(propName, PersistentStorage.getOrCreate().links_.get(propName).get());
1480    }
1481    /**
1482     * @see notifyHasChanged
1483     * @deprecated
1484     */
1485    static NotifyHasChanged(propName) {
1486
1487        PersistentStorage.storage_.set(propName, PersistentStorage.getOrCreate().links_.get(propName).get());
1488    }
1489    /**
1490     * all following methods are framework internal
1491     */
1492    constructor() {
1493        this.links_ = new Map();
1494        this.id_ = SubscriberManager.MakeId();
1495        SubscriberManager.Add(this);
1496    }
1497    keys() {
1498        return this.links_.keys();
1499    }
1500    persistProp(propName, defaultValue) {
1501        if (this.persistProp1(propName, defaultValue)) {
1502            // persist new prop
1503
1504            PersistentStorage.storage_.set(propName, this.links_.get(propName).get());
1505        }
1506    }
1507    // helper function to persist a property
1508    // does everything except writing prop to disk
1509    persistProp1(propName, defaultValue) {
1510
1511        if (defaultValue == null || defaultValue == undefined) {
1512            stateMgmtConsole.error(`PersistentStorage: persistProp for ${propName} called with 'null' or 'undefined' default value!`);
1513            return false;
1514        }
1515        if (this.links_.get(propName)) {
1516            stateMgmtConsole.warn(`PersistentStorage: persistProp: ${propName} is already persisted`);
1517            return false;
1518        }
1519        let link = AppStorage.link(propName, this);
1520        if (link) {
1521
1522            this.links_.set(propName, link);
1523        }
1524        else {
1525            let newValue = PersistentStorage.storage_.get(propName);
1526            let returnValue;
1527            if (newValue == undefined || newValue == null) {
1528
1529                returnValue = defaultValue;
1530            }
1531            else {
1532                returnValue = newValue;
1533            }
1534            link = AppStorage.setAndLink(propName, returnValue, this);
1535            this.links_.set(propName, link);
1536
1537        }
1538        return true;
1539    }
1540    persistProps(properties) {
1541        properties.forEach(property => this.persistProp1(property.key, property.defaultValue));
1542        this.write();
1543    }
1544    deleteProp(propName) {
1545        let link = this.links_.get(propName);
1546        if (link) {
1547            link.aboutToBeDeleted();
1548            this.links_.delete(propName);
1549            PersistentStorage.storage_.delete(propName);
1550
1551        }
1552        else {
1553            stateMgmtConsole.warn(`PersistentStorage: '${propName}' is not a persisted property warning.`);
1554        }
1555    }
1556    write() {
1557        this.links_.forEach((link, propName, map) => {
1558
1559            PersistentStorage.storage_.set(propName, link.get());
1560        });
1561    }
1562    propertyHasChanged(info) {
1563
1564        this.write();
1565    }
1566    syncPeerHasChanged(eventSource) {
1567
1568        this.write();
1569    }
1570    // public required by the interface, use the static method instead!
1571    aboutToBeDeleted() {
1572
1573        this.links_.forEach((val, key, map) => {
1574
1575            val.aboutToBeDeleted();
1576        });
1577        this.links_.clear();
1578        SubscriberManager.Delete(this.id__());
1579        PersistentStorage.storage_.clear();
1580    }
1581    id__() {
1582        return this.id_;
1583    }
1584}
1585PersistentStorage.instance_ = undefined;
1586;
1587/*
1588 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
1589 * Licensed under the Apache License, Version 2.0 (the "License");
1590 * you may not use this file except in compliance with the License.
1591 * You may obtain a copy of the License at
1592 *
1593 *     http://www.apache.org/licenses/LICENSE-2.0
1594 *
1595 * Unless required by applicable law or agreed to in writing, software
1596 * distributed under the License is distributed on an "AS IS" BASIS,
1597 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1598 * See the License for the specific language governing permissions and
1599 * limitations under the License.
1600 */
1601/**
1602 * Environment
1603 *
1604 * Injects device properties ("environment") into AppStorage
1605 *
1606 */
1607class Environment {
1608    static getOrCreate() {
1609        if (Environment.instance_) {
1610            // already initialized
1611            return Environment.instance_;
1612        }
1613        Environment.instance_ = new Environment();
1614        return Environment.instance_;
1615    }
1616    static configureBackend(envBackend) {
1617        Environment.envBackend_ = envBackend;
1618    }
1619    /**
1620     * @see configureBackend
1621     * @deprecated
1622     */
1623    static ConfigureBackend(envBackend) {
1624        Environment.envBackend_ = envBackend;
1625    }
1626    static aboutToBeDeleted() {
1627        if (!Environment.instance_) {
1628            return;
1629        }
1630        Environment.getOrCreate().aboutToBeDeleted();
1631        Environment.instance_ = undefined;
1632    }
1633    /**
1634     * @see aboutToBeDeleted
1635     * @deprecated
1636     */
1637    static AboutToBeDeleted() {
1638        Environment.aboutToBeDeleted();
1639    }
1640    static envProp(key, value) {
1641        return Environment.getOrCreate().envProp(key, value);
1642    }
1643    /**
1644     * @see envProp
1645     * @deprecated
1646     */
1647    static EnvProp(key, value) {
1648        return Environment.getOrCreate().envProp(key, value);
1649    }
1650    static envProps(props) {
1651        Environment.getOrCreate().envProps(props);
1652    }
1653    /**
1654     * @see envProps
1655     * @deprecated
1656     */
1657    static EnvProps(props) {
1658        Environment.getOrCreate().envProps(props);
1659    }
1660    static keys() {
1661        return Environment.getOrCreate().keys();
1662    }
1663    /**
1664     * @see keys
1665     * @deprecated
1666     */
1667    static Keys() {
1668        return Environment.getOrCreate().keys();
1669    }
1670    constructor() {
1671        this.props_ = new Map();
1672        Environment.envBackend_.onValueChanged(this.onValueChanged.bind(this));
1673    }
1674    envProp(key, value) {
1675        let prop = AppStorage.prop(key);
1676        if (prop) {
1677            stateMgmtConsole.warn(`Environment: envProp '${key}': Property already exists in AppStorage. Not using environment property.`);
1678            return false;
1679        }
1680        let tmp;
1681        switch (key) {
1682            case "accessibilityEnabled":
1683                tmp = Environment.envBackend_.getAccessibilityEnabled();
1684                break;
1685            case "colorMode":
1686                tmp = Environment.envBackend_.getColorMode();
1687                break;
1688            case "fontScale":
1689                tmp = Environment.envBackend_.getFontScale();
1690                break;
1691            case "fontWeightScale":
1692                tmp = Environment.envBackend_.getFontWeightScale().toFixed(2);
1693                break;
1694            case "layoutDirection":
1695                tmp = Environment.envBackend_.getLayoutDirection();
1696                break;
1697            case "languageCode":
1698                tmp = Environment.envBackend_.getLanguageCode();
1699                break;
1700            default:
1701                tmp = value;
1702        }
1703        if (!tmp && tmp !== 0) {
1704            tmp = value;
1705        }
1706        prop = AppStorage.setAndProp(key, tmp);
1707        if (!prop) {
1708            stateMgmtConsole.warn(`Environment: envProp '${key}': AppStorage setAndProp failed.`);
1709            return false;
1710        }
1711        this.props_.set(key, prop);
1712
1713        return true;
1714    }
1715    envProps(properties) {
1716        properties.forEach(property => {
1717            this.envProp(property.key, property.defaultValue);
1718
1719        });
1720    }
1721    keys() {
1722        let result = [];
1723        const it = this.props_.keys();
1724        let val = it.next();
1725        while (!val.done) {
1726            result.push(val.value);
1727            val = it.next();
1728        }
1729        return result;
1730    }
1731    onValueChanged(key, value) {
1732        let ok = AppStorage.set(key, value);
1733        if (ok) {
1734
1735        }
1736        else {
1737            stateMgmtConsole.warn(`Environment: onValueChanged: error changing ${key}! See results above.`);
1738        }
1739    }
1740    aboutToBeDeleted() {
1741        this.props_.forEach((val, key, map) => {
1742            val.aboutToBeDeleted();
1743            AppStorage.delete(key);
1744        });
1745    }
1746}
1747Environment.instance_ = undefined;
1748/*
1749 * Copyright (c) 2022 Huawei Device Co., Ltd.
1750 * Licensed under the Apache License, Version 2.0 (the "License");
1751 * you may not use this file except in compliance with the License.
1752 * You may obtain a copy of the License at
1753 *
1754 *     http://www.apache.org/licenses/LICENSE-2.0
1755 *
1756 * Unless required by applicable law or agreed to in writing, software
1757 * distributed under the License is distributed on an "AS IS" BASIS,
1758 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1759 * See the License for the specific language governing permissions and
1760 * limitations under the License.
1761 */
1762/**
1763 * state mgmt library uses its own class for logging
1764* allows to remap separately from other use of aceConsole
1765*
1766* everything in this file is framework internal
1767*/
1768class stateMgmtConsole {
1769    static log(...args) {
1770        aceConsole.log(...args);
1771    }
1772    static debug(...args) {
1773        aceConsole.debug(...args);
1774    }
1775    static info(...args) {
1776        aceConsole.info(...args);
1777    }
1778    static warn(...args) {
1779        aceConsole.warn(...args);
1780    }
1781    static error(...args) {
1782        aceConsole.error(...args);
1783    }
1784    static propertyAccess(...args) {
1785        // enable for fran gran debugging variables observation
1786        // this code line has been left in intentionally
1787        // aceConsole.debug(...args);
1788    }
1789    static applicationError(...args) {
1790        aceConsole.error(`FIX THIS APPLICATION ERROR \n`, ...args);
1791    }
1792}
1793class stateMgmtTrace {
1794    static scopedTrace(codeBlock, arg1, ...args) {
1795        aceTrace.begin(arg1, ...args);
1796        let result = codeBlock();
1797        aceTrace.end();
1798        return result;
1799    }
1800}
1801class errorReport {
1802    static varValueCheckFailed(params) {
1803        let msg = `@Component '${params.customComponent}': Illegal variable value error with decorated variable ${params.variableDeco} '${params.variableName}': `;
1804        msg += `failed validation: '${params.expectedType}`;
1805        try {
1806            msg += `, attempt to assign value type: '${typeof params.value}'`;
1807            msg += `, value: '${JSON.stringify(params.value, null, 4)}'`;
1808        }
1809        catch (e) { }
1810        msg += "!";
1811        throw new TypeError(msg);
1812    }
1813    static varObservationFailed(params) {
1814        let msg = `@Component '${params.customComponent}': decorated variable ${params.variableDeco} '${params.variableName}': `;
1815        msg += `its class is neither decorated with '@Observed' nor it is an instance of 'SubscribableAbstract'`;
1816        try {
1817            msg += `, attempt to assign value type: '${typeof params.value}'`;
1818            msg += `, value: '${JSON.stringify(params.value, null, 4)}'`;
1819        }
1820        catch (e) { }
1821        msg += "!";
1822        throw new TypeError(msg);
1823    }
1824}
1825/*
1826 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
1827 * Licensed under the Apache License, Version 2.0 (the "License");
1828 * you may not use this file except in compliance with the License.
1829 * You may obtain a copy of the License at
1830 *
1831 *     http://www.apache.org/licenses/LICENSE-2.0
1832 *
1833 * Unless required by applicable law or agreed to in writing, software
1834 * distributed under the License is distributed on an "AS IS" BASIS,
1835 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1836 * See the License for the specific language governing permissions and
1837 * limitations under the License.
1838 */
1839var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
1840    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1841    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1842    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1843    return c > 3 && r && Object.defineProperty(target, key, r), r;
1844};
1845/**
1846* @Observed class decorator
1847*
1848* usage:
1849*    @Observed class ClassA { ... }
1850*
1851* Causes every instance of decorated clss to be automatically wrapped inside an ObservedObject.
1852*
1853* Implemented by extending the decroaetd class by class named 'ObservableObjectClass'.
1854*
1855* It is permisstable to decorate the base and the extended class like thisNote: I
1856*   @Observed class ClassA { ...}
1857*   @Observed class ClassB extends ClassA { ... }
1858* and use
1859*   a = new ClassA();
1860*   b = new ClassB();
1861* Only one ES6 Proxy is added.
1862*
1863*
1864* Take note the decorator implementation extends the prototype chain.
1865*
1866* The prototype chain of a in above example is
1867*  - ObservableObjectClass prototype
1868*  - ClassA prototype
1869*  - Object prototype
1870*
1871* Snd the prototype chain of b is
1872*  - ObservableObjectClass prototype
1873*  - ClassB prototype
1874*  - ObservableObjectClass prototype
1875*  - ClassA prototype
1876*  - Object prototype
1877*
1878* The @Observed decorator is public, part of the SDK, starting from API 9.
1879*
1880*/
1881// define just once to get just one Symbol
1882const __IS_OBSERVED_PROXIED = Symbol("_____is_observed_proxied__");
1883function Observed(constructor_, _) {
1884
1885    let ObservedClass = class extends constructor_ {
1886        constructor(...args) {
1887            super(...args);
1888
1889            let isProxied = Reflect.has(this, __IS_OBSERVED_PROXIED);
1890            Object.defineProperty(this, __IS_OBSERVED_PROXIED, {
1891                value: true,
1892                enumerable: false,
1893                configurable: false,
1894                writable: false
1895            });
1896            if (isProxied) {
1897
1898                return this;
1899            }
1900            else {
1901
1902                return ObservedObject.createNewInternal(this, undefined);
1903            }
1904        }
1905    };
1906    return ObservedClass;
1907}
1908// force tsc to generate the __decorate data structure needed for @Observed
1909// tsc will not generate unless the @Observed class decorator is used at least once
1910let __IGNORE_FORCE_decode_GENERATION__ = class __IGNORE_FORCE_decode_GENERATION__ {
1911};
1912__IGNORE_FORCE_decode_GENERATION__ = __decorate([
1913    Observed
1914], __IGNORE_FORCE_decode_GENERATION__);
1915/**
1916 * class ObservedObject and supporting Handler classes,
1917 * Extends from ES6 Proxy. In adding to 'get' and 'set'
1918 * the clasess manage subscribers that receive notification
1919 * about proxies object being 'read' or 'changed'.
1920 *
1921 * These classes are framework internal / non-SDK
1922 *
1923 */
1924class SubscribableHandler {
1925    constructor(owningProperty) {
1926        this.owningProperties_ = new Set();
1927        if (owningProperty) {
1928            this.addOwningProperty(owningProperty);
1929        }
1930
1931    }
1932    addOwningProperty(subscriber) {
1933        if (subscriber) {
1934
1935            this.owningProperties_.add(subscriber.id__());
1936        }
1937        else {
1938            stateMgmtConsole.warn(`SubscribableHandler: addOwningProperty: undefined subscriber. - Internal error?`);
1939        }
1940    }
1941    /*
1942        the inverse function of createOneWaySync or createTwoWaySync
1943      */
1944    removeOwningProperty(property) {
1945        return this.removeOwningPropertyById(property.id__());
1946    }
1947    removeOwningPropertyById(subscriberId) {
1948
1949        this.owningProperties_.delete(subscriberId);
1950    }
1951    notifyObjectPropertyHasChanged(propName, newValue) {
1952
1953        this.owningProperties_.forEach((subscribedId) => {
1954            var owningProperty = SubscriberManager.Find(subscribedId);
1955            if (owningProperty) {
1956                if ('objectPropertyHasChangedPU' in owningProperty) {
1957                    // PU code path
1958                    owningProperty.objectPropertyHasChangedPU(this, propName);
1959                }
1960                // FU code path
1961                if ('hasChanged' in owningProperty) {
1962                    owningProperty.hasChanged(newValue);
1963                }
1964                if ('propertyHasChanged' in owningProperty) {
1965                    owningProperty.propertyHasChanged(propName);
1966                }
1967            }
1968            else {
1969                stateMgmtConsole.warn(`SubscribableHandler: notifyObjectPropertyHasChanged: unknown subscriber.'${subscribedId}' error!.`);
1970            }
1971        });
1972    }
1973    // notify a property has been 'read'
1974    // this functionality is in preparation for observed computed variables
1975    // enable calling from 'get' trap handler functions to this function once
1976    // adding support for observed computed variables
1977    notifyObjectPropertyHasBeenRead(propName) {
1978
1979        this.owningProperties_.forEach((subscribedId) => {
1980            var owningProperty = SubscriberManager.Find(subscribedId);
1981            if (owningProperty) {
1982                // PU code path
1983                if ('objectPropertyHasBeenReadPU' in owningProperty) {
1984                    owningProperty.objectPropertyHasBeenReadPU(this, propName);
1985                }
1986            }
1987        });
1988    }
1989    has(target, property) {
1990
1991        return (property === ObservedObject.__IS_OBSERVED_OBJECT) ? true : Reflect.has(target, property);
1992    }
1993    get(target, property, receiver) {
1994
1995        return (property === ObservedObject.__OBSERVED_OBJECT_RAW_OBJECT) ? target : Reflect.get(target, property, receiver);
1996    }
1997    set(target, property, newValue) {
1998        switch (property) {
1999            case SubscribableHandler.SUBSCRIBE:
2000                // assignment obsObj[SubscribableHandler.SUBSCRCRIBE] = subscriber
2001                this.addOwningProperty(newValue);
2002                return true;
2003                break;
2004            case SubscribableHandler.UNSUBSCRIBE:
2005                // assignment obsObj[SubscribableHandler.UNSUBSCRCRIBE] = subscriber
2006                this.removeOwningProperty(newValue);
2007                return true;
2008                break;
2009            default:
2010                if (Reflect.get(target, property) == newValue) {
2011                    return true;
2012                }
2013
2014                Reflect.set(target, property, newValue);
2015                this.notifyObjectPropertyHasChanged(property.toString(), newValue);
2016                return true;
2017                break;
2018        }
2019        // unreachable
2020        return false;
2021    }
2022}
2023SubscribableHandler.SUBSCRIBE = Symbol("_____subscribe__");
2024SubscribableHandler.UNSUBSCRIBE = Symbol("_____unsubscribe__");
2025class SubscribableDateHandler extends SubscribableHandler {
2026    constructor(owningProperty) {
2027        super(owningProperty);
2028    }
2029    /**
2030     * Get trap for Date type proxy
2031     * Functions that modify Date in-place are intercepted and replaced with a function
2032     * that executes the original function and notifies the handler of a change.
2033     * @param target Original Date object
2034     * @param property
2035     * @returns
2036     */
2037    get(target, property) {
2038        const dateSetFunctions = new Set(["setFullYear", "setMonth", "setDate", "setHours", "setMinutes", "setSeconds",
2039            "setMilliseconds", "setTime", "setUTCFullYear", "setUTCMonth", "setUTCDate", "setUTCHours", "setUTCMinutes",
2040            "setUTCSeconds", "setUTCMilliseconds"]);
2041        let ret = super.get(target, property);
2042        if (typeof ret === "function" && property.toString() && dateSetFunctions.has(property.toString())) {
2043            const self = this;
2044            return function () {
2045                // execute original function with given arguments
2046                let result = ret.apply(this, arguments);
2047                self.notifyObjectPropertyHasChanged(property.toString(), this);
2048                return result;
2049            }.bind(target); // bind "this" to target inside the function
2050        }
2051        else if (typeof ret === "function") {
2052            ret = ret.bind(target);
2053        }
2054        return ret;
2055    }
2056}
2057class ExtendableProxy {
2058    constructor(obj, handler) {
2059        return new Proxy(obj, handler);
2060    }
2061}
2062class ObservedObject extends ExtendableProxy {
2063    /**
2064     * Factory function for ObservedObjects /
2065     *  wrapping of objects for proxying
2066     *
2067     * @param rawObject unproxied Object or ObservedObject
2068     * @param objOwner owner of this Object to sign uop for propertyChange
2069     *          notifications
2070     * @returns the rawObject if object is already an ObservedObject,
2071     *          otherwise the newly created ObservedObject
2072     */
2073    static createNew(rawObject, owningProperty) {
2074        if (rawObject === null || rawObject === undefined) {
2075            stateMgmtConsole.error(`ObservedObject.CreateNew, input object must not be null or undefined.`);
2076            return rawObject;
2077        }
2078        if (ObservedObject.IsObservedObject(rawObject)) {
2079            ObservedObject.addOwningProperty(rawObject, owningProperty);
2080            return rawObject;
2081        }
2082        return ObservedObject.createNewInternal(rawObject, owningProperty);
2083    }
2084    static createNewInternal(rawObject, owningProperty) {
2085        let proxiedObject = new ObservedObject(rawObject, Array.isArray(rawObject) ? new class extends SubscribableHandler {
2086            constructor(owningProperty) {
2087                super(owningProperty);
2088                // In-place array modification functions
2089                // splice is also in-place modifying function, but we need to handle separately
2090                this.inPlaceModifications = new Set(["copyWithin", "fill", "reverse", "sort"]);
2091            }
2092            get(target, property, receiver) {
2093                let ret = super.get(target, property, receiver);
2094                if (ret && typeof ret === "function") {
2095                    const self = this;
2096                    const prop = property.toString();
2097                    // prop is the function name here
2098                    if (prop == "splice") {
2099                        // 'splice' self modifies the array, returns deleted array items
2100                        // means, alike other self-modifying functions, splice does not return the array itself.
2101                        return function () {
2102                            const result = ret.apply(target, arguments);
2103                            // prop is the function name here
2104                            // and result is the function return value
2105                            // functinon modifies none or more properties
2106                            self.notifyObjectPropertyHasChanged(prop, target);
2107                            return result;
2108                        }.bind(proxiedObject);
2109                    }
2110                    if (self.inPlaceModifications.has(prop)) {
2111                        // in place modfication function result == target, the raw array modified
2112
2113                        return function () {
2114                            const result = ret.apply(target, arguments);
2115                            // 'result' is the unproxied object
2116                            // functinon modifies none or more properties
2117                            self.notifyObjectPropertyHasChanged(prop, result);
2118                            // returning the 'proxiedObject' ensures that when chain calls also 2nd function call
2119                            // operates on the proxied object.
2120                            return proxiedObject;
2121                        }.bind(proxiedObject);
2122                    }
2123                    // binding the proxiedObject ensures that modifying functions like push() operate on the
2124                    // proxied array and each array change is notified.
2125                    return ret.bind(proxiedObject);
2126                }
2127                return ret;
2128            }
2129        }(owningProperty) // SubscribableArrayHandlerAnonymous
2130            : (rawObject instanceof Date)
2131                ? new SubscribableDateHandler(owningProperty)
2132                : new SubscribableHandler(owningProperty), owningProperty);
2133        return proxiedObject;
2134    }
2135    /*
2136      Return the unproxied object 'inside' the ObservedObject / the ES6 Proxy
2137      no set observation, no notification of changes!
2138      Use with caution, do not store any references
2139    */
2140    static GetRawObject(obj) {
2141        return !ObservedObject.IsObservedObject(obj) ? obj : obj[ObservedObject.__OBSERVED_OBJECT_RAW_OBJECT];
2142    }
2143    /**
2144     *
2145     * @param obj anything
2146     * @returns true if the parameter is an Object wrpped with a ObservedObject
2147     * Note: Since ES6 Proying is transparent, 'instance of' will not work. Use
2148     * this static function instead.
2149     */
2150    static IsObservedObject(obj) {
2151        return (obj && (typeof obj === "object") && Reflect.has(obj, ObservedObject.__IS_OBSERVED_OBJECT));
2152    }
2153    /**
2154     * add a subscriber to given ObservedObject
2155     * due to the proxy nature this static method approach needs to be used instead of a member
2156     * function
2157     * @param obj
2158     * @param subscriber
2159     * @returns false if given object is not an ObservedObject
2160     */
2161    static addOwningProperty(obj, subscriber) {
2162        if (!ObservedObject.IsObservedObject(obj) || subscriber == undefined) {
2163            return false;
2164        }
2165        obj[SubscribableHandler.SUBSCRIBE] = subscriber;
2166        return true;
2167    }
2168    /**
2169     * remove a subscriber to given ObservedObject
2170     * due to the proxy nature this static method approach needs to be used instead of a member
2171     * function
2172     * @param obj
2173     * @param subscriber
2174     * @returns false if given object is not an ObservedObject
2175     */
2176    static removeOwningProperty(obj, subscriber) {
2177        if (!ObservedObject.IsObservedObject(obj)) {
2178            return false;
2179        }
2180        obj[SubscribableHandler.UNSUBSCRIBE] = subscriber;
2181        return true;
2182    }
2183    /**
2184     * Utility function for debugging the prototype chain of given Object
2185     * The given object can be any Object, it is not required to be an ObservedObject
2186     * @param object
2187     * @returns multi-line string containing info about the prototype chain
2188     * on class in class hiararchy per line
2189     */
2190    static tracePrototypeChainOfObject(object) {
2191        let proto = Object.getPrototypeOf(object);
2192        let result = "";
2193        let sepa = "";
2194        while (proto) {
2195            result += `${sepa}${ObservedObject.tracePrototype(proto)}`;
2196            proto = Object.getPrototypeOf(proto);
2197            sepa = ",\n";
2198        }
2199        return result;
2200    }
2201    /**
2202     * Utility function for debugging all functions of given Prototype.
2203     * @returns string containing containing names of all functions and members of given Prototype
2204     */
2205    static tracePrototype(proto) {
2206        if (!proto) {
2207            return "";
2208        }
2209        let result = `${proto.constructor && proto.constructor.name ? proto.constructor.name : '<no class>'}: `;
2210        let sepa = "";
2211        for (let name of Object.getOwnPropertyNames(proto)) {
2212            result += `${sepa}${name}`;
2213            sepa = ", ";
2214        }
2215        ;
2216        return result;
2217    }
2218    /**
2219     * @Observed  decorator extends the decorated class. This function returns the prototype of the decorated class
2220     * @param proto
2221     * @returns prototype of the @Observed decorated class or 'proto' parameter if not  @Observed decorated
2222     */
2223    static getPrototypeOfObservedClass(proto) {
2224        return (proto.constructor && proto.constructor.name == "ObservedClass")
2225            ? Object.getPrototypeOf(proto.constructor.prototype)
2226            : proto;
2227    }
2228    /**
2229     * To create a new ObservableObject use CreateNew function
2230     *
2231     * constructor create a new ObservableObject and subscribe its owner to propertyHasChanged
2232     * notifications
2233     * @param obj  raw Object, if obj is a ObservableOject throws an error
2234     * @param objectOwner
2235     */
2236    constructor(obj, handler, objectOwningProperty) {
2237        super(obj, handler);
2238        if (ObservedObject.IsObservedObject(obj)) {
2239            stateMgmtConsole.error("ObservableOject constructor: INTERNAL ERROR: after jsObj is observedObject already");
2240        }
2241        if (objectOwningProperty != undefined) {
2242            this[SubscribableHandler.SUBSCRIBE] = objectOwningProperty;
2243        }
2244    } // end of constructor
2245}
2246ObservedObject.__IS_OBSERVED_OBJECT = Symbol("_____is_observed_object__");
2247ObservedObject.__OBSERVED_OBJECT_RAW_OBJECT = Symbol("_____raw_object__");
2248/*
2249 * Copyright (c) 2021 Huawei Device Co., Ltd.
2250 * Licensed under the Apache License, Version 2.0 (the "License");
2251 * you may not use this file except in compliance with the License.
2252 * You may obtain a copy of the License at
2253 *
2254 *     http://www.apache.org/licenses/LICENSE-2.0
2255 *
2256 * Unless required by applicable law or agreed to in writing, software
2257 * distributed under the License is distributed on an "AS IS" BASIS,
2258 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2259 * See the License for the specific language governing permissions and
2260 * limitations under the License.
2261 */
2262/*
2263   manage subscriptions to a property
2264   managing the property is left to sub
2265   classes
2266   Extended by ObservedProperty, SyncedPropertyOneWay
2267   and SyncedPropertyTwoWay
2268*/
2269class ObservedPropertyAbstract extends SubscribedAbstractProperty {
2270    constructor(subscribeMe, info) {
2271        super();
2272        this.subscribers_ = new Set();
2273        this.id_ = SubscriberManager.MakeId();
2274        SubscriberManager.Add(this);
2275        if (subscribeMe) {
2276            this.subscribers_.add(subscribeMe.id__());
2277        }
2278        if (info) {
2279            this.info_ = info;
2280        }
2281    }
2282    aboutToBeDeleted() {
2283        SubscriberManager.Delete(this.id__());
2284    }
2285    id__() {
2286        return this.id_;
2287    }
2288    info() {
2289        return this.info_;
2290    }
2291    setInfo(propName) {
2292        if (propName && propName != "") {
2293            this.info_ = propName;
2294        }
2295    }
2296    // Partial Update "*PU" classes will overwrite
2297    getUnmonitored() {
2298        return this.get();
2299    }
2300    // update the element id for recycle custom component
2301    updateElmtId(oldElmtId, newElmtId) {
2302        if (this.subscribers_.has(oldElmtId)) {
2303            this.subscribers_.delete(oldElmtId);
2304            this.subscribers_.add(newElmtId);
2305        }
2306    }
2307    // Method name is used to check object is of type ObservedPropertyAbstract
2308    // Do NOT override in derived classed, use addSubscriber
2309    subscribeMe(subscriber) {
2310
2311        this.subscribers_.add(subscriber.id__());
2312    }
2313    /*
2314      the inverse function of createOneWaySync or createTwoWaySync
2315      Do NOT override in derived classed, use removeSubscriber
2316    */
2317    unlinkSuscriber(subscriberId) {
2318        this.subscribers_.delete(subscriberId);
2319    }
2320    /*
2321      Virtualized version of the subscription mechanism - add subscriber
2322    */
2323    addSubscriber(subscriber) {
2324        if (subscriber) {
2325            this.subscribeMe(subscriber);
2326        }
2327    }
2328    /*
2329      Virtualized version of the subscription mechanism - remove subscriber
2330    */
2331    removeSubscriber(subscriber, id) {
2332        if (id) {
2333            this.unlinkSuscriber(id);
2334        }
2335        else if (subscriber) {
2336            this.unlinkSuscriber(subscriber.id__());
2337        }
2338    }
2339    notifyHasChanged(newValue) {
2340
2341        this.subscribers_.forEach((subscribedId) => {
2342            var subscriber = SubscriberManager.Find(subscribedId);
2343            if (subscriber) {
2344                // FU code path
2345                if ('hasChanged' in subscriber) {
2346                    subscriber.hasChanged(newValue);
2347                }
2348                if ('propertyHasChanged' in subscriber) {
2349                    subscriber.propertyHasChanged(this.info_);
2350                }
2351                // PU code path, only used for ObservedPropertySimple/Object stored inside App/LocalStorage
2352                // ObservedPropertySimplePU/ObjectPU  used in all other PU cases, has its own notifyPropertyHasChangedPU()
2353                if ('syncPeerHasChanged' in subscriber) {
2354                    subscriber.syncPeerHasChanged(this);
2355                }
2356            }
2357            else {
2358                stateMgmtConsole.warn(`ObservedPropertyAbstract[${this.id__()}, '${this.info() || "unknown"}']: notifyHasChanged: unknown subscriber ID '${subscribedId}' error!`);
2359            }
2360        });
2361    }
2362    notifyPropertyRead() {
2363
2364        this.subscribers_.forEach((subscribedId) => {
2365            var subscriber = SubscriberManager.Find(subscribedId);
2366            if (subscriber) {
2367                if ('propertyRead' in subscriber) {
2368                    subscriber.propertyRead(this.info_);
2369                }
2370            }
2371        });
2372    }
2373    /*
2374    return numebr of subscribers to this property
2375    mostly useful for unit testin
2376    */
2377    numberOfSubscrbers() {
2378        return this.subscribers_.size;
2379    }
2380    /**
2381     * provide a factory function that creates a SynchedPropertyXXXX of choice
2382     * that uses 'this' as source
2383     * @param factoryFunc
2384     * @returns
2385     */
2386    createSync(factoryFunc) {
2387        return factoryFunc(this);
2388    }
2389    /**
2390     * depreciated SDK function, not used anywhere by the framework
2391     */
2392    createTwoWaySync(subscribeMe, info) {
2393        stateMgmtConsole.warn("Using depreciated method 'createTwoWaySync'!");
2394        return this.createLink(subscribeMe, info);
2395    }
2396    /**
2397     * depreciated SDK function, not used anywhere by the framework
2398     */
2399    createOneWaySync(subscribeMe, info) {
2400        stateMgmtConsole.warn("Using depreciated method 'createOneWaySync' !");
2401        return this.createProp(subscribeMe, info);
2402    }
2403    /**
2404     * factory function for concrete 'object' or 'simple' ObservedProperty object
2405     * depending if value is Class object
2406     * or simple type (boolean | number | string)
2407     * @param value
2408     * @param owningView
2409     * @param thisPropertyName
2410     * @returns either
2411     */
2412    static CreateObservedObject(value, owningView, thisPropertyName) {
2413        return (typeof value === "object") ?
2414            new ObservedPropertyObject(value, owningView, thisPropertyName)
2415            : new ObservedPropertySimple(value, owningView, thisPropertyName);
2416    }
2417}
2418/*
2419 * Copyright (c) 2021 Huawei Device Co., Ltd.
2420 * Licensed under the Apache License, Version 2.0 (the "License");
2421 * you may not use this file except in compliance with the License.
2422 * You may obtain a copy of the License at
2423 *
2424 *     http://www.apache.org/licenses/LICENSE-2.0
2425 *
2426 * Unless required by applicable law or agreed to in writing, software
2427 * distributed under the License is distributed on an "AS IS" BASIS,
2428 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2429 * See the License for the specific language governing permissions and
2430 * limitations under the License.
2431 */
2432/**
2433 * ObservedPropertyObjectAbstract
2434 *
2435 * all definitions in this file are framework internal
2436 *
2437 * common base class of ObservedPropertyObject and
2438 * SyncedObjectPropertyTwoWay
2439 * adds the createObjectLink to the ObservedPropertyAbstract base
2440 */
2441class ObservedPropertyObjectAbstract extends ObservedPropertyAbstract {
2442    constructor(owningView, thisPropertyName) {
2443        super(owningView, thisPropertyName);
2444    }
2445}
2446/*
2447 * Copyright (c) 2021 Huawei Device Co., Ltd.
2448 * Licensed under the Apache License, Version 2.0 (the "License");
2449 * you may not use this file except in compliance with the License.
2450 * You may obtain a copy of the License at
2451 *
2452 *     http://www.apache.org/licenses/LICENSE-2.0
2453 *
2454 * Unless required by applicable law or agreed to in writing, software
2455 * distributed under the License is distributed on an "AS IS" BASIS,
2456 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2457 * See the License for the specific language governing permissions and
2458 * limitations under the License.
2459 */
2460/**
2461 *
2462 * ObservedPropertySimpleAbstract
2463 *
2464 * all definitions in this file are framework internal
2465 */
2466class ObservedPropertySimpleAbstract extends ObservedPropertyAbstract {
2467    constructor(owningView, propertyName) {
2468        super(owningView, propertyName);
2469    }
2470}
2471/*
2472 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2473 * Licensed under the Apache License, Version 2.0 (the "License");
2474 * you may not use this file except in compliance with the License.
2475 * You may obtain a copy of the License at
2476 *
2477 *     http://www.apache.org/licenses/LICENSE-2.0
2478 *
2479 * Unless required by applicable law or agreed to in writing, software
2480 * distributed under the License is distributed on an "AS IS" BASIS,
2481 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2482 * See the License for the specific language governing permissions and
2483 * limitations under the License.
2484 */
2485/**
2486 * ObservedPropertyObject
2487 *
2488 * all definitions in this file are framework internal
2489 *
2490 * class that holds an actual property value of type T
2491 * uses its base class to manage subscribers to this
2492 * property.
2493*/
2494class ObservedPropertyObject extends ObservedPropertyObjectAbstract {
2495    constructor(value, owningView, propertyName) {
2496        super(owningView, propertyName);
2497        this.setValueInternal(value);
2498    }
2499    aboutToBeDeleted(unsubscribeMe) {
2500        this.unsubscribeFromOwningProperty();
2501        if (unsubscribeMe) {
2502            this.unlinkSuscriber(unsubscribeMe.id__());
2503        }
2504        super.aboutToBeDeleted();
2505    }
2506    // notification from ObservedObject value one of its
2507    // props has chnaged. Implies the ObservedProperty has changed
2508    // Note: this function gets called when in this case:
2509    //       thisProp.aObsObj.aProp = 47  a object prop gets changed
2510    // It is NOT called when
2511    //    thisProp.aObsObj = new ClassA
2512    hasChanged(newValue) {
2513
2514        this.notifyHasChanged(this.wrappedValue_);
2515    }
2516    unsubscribeFromOwningProperty() {
2517        if (this.wrappedValue_) {
2518            if (this.wrappedValue_ instanceof SubscribaleAbstract) {
2519                this.wrappedValue_.removeOwningProperty(this);
2520            }
2521            else {
2522                ObservedObject.removeOwningProperty(this.wrappedValue_, this);
2523            }
2524        }
2525    }
2526    /*
2527      actually update this.wrappedValue_
2528      called needs to do value change check
2529      and also notify with this.aboutToChange();
2530    */
2531    setValueInternal(newValue) {
2532        if (typeof newValue !== 'object') {
2533
2534            return false;
2535        }
2536        this.unsubscribeFromOwningProperty();
2537        if (ObservedObject.IsObservedObject(newValue)) {
2538
2539            ObservedObject.addOwningProperty(newValue, this);
2540            this.wrappedValue_ = newValue;
2541        }
2542        else if (newValue instanceof SubscribaleAbstract) {
2543
2544            this.wrappedValue_ = newValue;
2545            this.wrappedValue_.addOwningProperty(this);
2546        }
2547        else {
2548
2549            this.wrappedValue_ = ObservedObject.createNew(newValue, this);
2550        }
2551        return true;
2552    }
2553    get() {
2554
2555        this.notifyPropertyRead();
2556        return this.wrappedValue_;
2557    }
2558    set(newValue) {
2559        if (this.wrappedValue_ == newValue) {
2560
2561            return;
2562        }
2563
2564        this.setValueInternal(newValue);
2565        this.notifyHasChanged(newValue);
2566    }
2567    /**
2568     * These functions are used
2569     *   LocalStorage.link  (also in partial update config)
2570     *   (FU)View.initializeConsumeinitializeConsume
2571     */
2572    createLink(subscribeOwner, linkPropName) {
2573        return new SynchedPropertyObjectTwoWay(this, subscribeOwner, linkPropName);
2574    }
2575    createProp(subscribeOwner, linkPropName) {
2576        throw new Error("Creating a 'Prop' property is unsupported for Object type property value.");
2577    }
2578}
2579/*
2580 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2581 * Licensed under the Apache License, Version 2.0 (the "License");
2582 * you may not use this file except in compliance with the License.
2583 * You may obtain a copy of the License at
2584 *
2585 *     http://www.apache.org/licenses/LICENSE-2.0
2586 *
2587 * Unless required by applicable law or agreed to in writing, software
2588 * distributed under the License is distributed on an "AS IS" BASIS,
2589 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2590 * See the License for the specific language governing permissions and
2591 * limitations under the License.
2592 */
2593/**
2594 * ObservedPropertySimple
2595 *
2596 * all definitions in this file are framework internal
2597 */
2598class ObservedPropertySimple extends ObservedPropertySimpleAbstract {
2599    constructor(value, owningView, propertyName) {
2600        super(owningView, propertyName);
2601        if (typeof value === "object") {
2602            throw new SyntaxError("ObservedPropertySimple value must not be an object");
2603        }
2604        this.setValueInternal(value);
2605    }
2606    aboutToBeDeleted(unsubscribeMe) {
2607        if (unsubscribeMe) {
2608            this.unlinkSuscriber(unsubscribeMe.id__());
2609        }
2610        super.aboutToBeDeleted();
2611    }
2612    hasChanged(newValue) {
2613
2614        this.notifyHasChanged(this.wrappedValue_);
2615    }
2616    /*
2617      actually update this.wrappedValue_
2618      called needs to do value change check
2619      and also notify with this.aboutToChange();
2620    */
2621    setValueInternal(newValue) {
2622
2623        this.wrappedValue_ = newValue;
2624    }
2625    get() {
2626
2627        this.notifyPropertyRead();
2628        return this.wrappedValue_;
2629    }
2630    set(newValue) {
2631        if (this.wrappedValue_ == newValue) {
2632
2633            return;
2634        }
2635
2636        this.setValueInternal(newValue);
2637        this.notifyHasChanged(newValue);
2638    }
2639    /**
2640   * These functions are meant for use in connection with the App Stoage and
2641   * business logic implementation.
2642   * the created Link and Prop will update when 'this' property value
2643   * changes.
2644   */
2645    createLink(subscribeOwner, linkPropName) {
2646        return ((subscribeOwner !== undefined) && ("rerender" in subscribeOwner)) ?
2647            new SynchedPropertySimpleTwoWayPU(this, subscribeOwner, linkPropName) :
2648            new SynchedPropertySimpleTwoWay(this, subscribeOwner, linkPropName);
2649    }
2650    createProp(subscribeOwner, linkPropName) {
2651        return new SynchedPropertySimpleOneWaySubscribing(this, subscribeOwner, linkPropName);
2652    }
2653}
2654/*
2655 * Copyright (c) 2021 Huawei Device Co., Ltd.
2656 * Licensed under the Apache License, Version 2.0 (the "License");
2657 * you may not use this file except in compliance with the License.
2658 * You may obtain a copy of the License at
2659 *
2660 *     http://www.apache.org/licenses/LICENSE-2.0
2661 *
2662 * Unless required by applicable law or agreed to in writing, software
2663 * distributed under the License is distributed on an "AS IS" BASIS,
2664 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2665 * See the License for the specific language governing permissions and
2666 * limitations under the License.
2667 */
2668/**
2669 * SynchedPropertyObjectTwoWay
2670 *
2671 * all definitions in this file are framework internal
2672 */
2673class SynchedPropertyObjectTwoWay extends ObservedPropertyObjectAbstract {
2674    constructor(linkSource, owningChildView, thisPropertyName) {
2675        super(owningChildView, thisPropertyName);
2676        this.changeNotificationIsOngoing_ = false;
2677        this.linkedParentProperty_ = linkSource;
2678        if (this.linkedParentProperty_) {
2679            // register to the parent property
2680            this.linkedParentProperty_.subscribeMe(this);
2681        }
2682        // register to the ObservedObject
2683        ObservedObject.addOwningProperty(this.getObject(), this);
2684    }
2685    /*
2686    like a destructor, need to call this before deleting
2687    the property.
2688    */
2689    aboutToBeDeleted() {
2690        if (this.linkedParentProperty_) {
2691            // unregister from parent of this link
2692            this.linkedParentProperty_.unlinkSuscriber(this.id__());
2693            // unregister from the ObservedObject
2694            ObservedObject.removeOwningProperty(this.getObject(), this);
2695        }
2696        super.aboutToBeDeleted();
2697    }
2698    getObject() {
2699        this.notifyPropertyRead();
2700        return (this.linkedParentProperty_ ? this.linkedParentProperty_.get() : undefined);
2701    }
2702    setObject(newValue) {
2703        if (this.linkedParentProperty_) {
2704            this.linkedParentProperty_.set(newValue);
2705        }
2706    }
2707    // this object is subscriber to ObservedObject
2708    // will call this cb function when property has changed
2709    hasChanged(newValue) {
2710        if (!this.changeNotificationIsOngoing_) {
2711
2712            this.notifyHasChanged(this.getObject());
2713        }
2714    }
2715    // get 'read through` from the ObservedProperty
2716    get() {
2717
2718        return this.getObject();
2719    }
2720    // set 'writes through` to the ObservedProperty
2721    set(newValue) {
2722        if (this.getObject() == newValue) {
2723
2724            return;
2725        }
2726
2727        ObservedObject.removeOwningProperty(this.getObject(), this);
2728        // the purpose of the changeNotificationIsOngoing_ is to avoid
2729        // circular notifications @Link -> source @State -> other but alos same @Link
2730        this.changeNotificationIsOngoing_ = true;
2731        this.setObject(newValue);
2732        ObservedObject.addOwningProperty(this.getObject(), this);
2733        this.notifyHasChanged(newValue);
2734        this.changeNotificationIsOngoing_ = false;
2735    }
2736    /**
2737   * These functions are meant for use in connection with the App Stoage and
2738   * business logic implementation.
2739   * the created Link and Prop will update when 'this' property value
2740   * changes.
2741   */
2742    createLink(subscribeOwner, linkPropName) {
2743        return new SynchedPropertyObjectTwoWay(this, subscribeOwner, linkPropName);
2744    }
2745    createProp(subscribeOwner, linkPropName) {
2746        throw new Error("Creating a 'Prop' property is unsupported for Object type property value.");
2747    }
2748}
2749/*
2750 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2751 * Licensed under the Apache License, Version 2.0 (the "License");
2752 * you may not use this file except in compliance with the License.
2753 * You may obtain a copy of the License at
2754 *
2755 *     http://www.apache.org/licenses/LICENSE-2.0
2756 *
2757 * Unless required by applicable law or agreed to in writing, software
2758 * distributed under the License is distributed on an "AS IS" BASIS,
2759 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2760 * See the License for the specific language governing permissions and
2761 * limitations under the License.
2762 */
2763/**
2764 * SynchedPropertySimpleOneWay
2765 *
2766 * all definitions in this file are framework internal
2767 */
2768class SynchedPropertySimpleOneWay extends ObservedPropertySimpleAbstract {
2769    constructor(value, subscribeMe, info) {
2770        super(subscribeMe, info);
2771        // add a test here that T is a simple type
2772        this.wrappedValue_ = value;
2773    }
2774    /*
2775      like a destructor, need to call this before deleting
2776      the property.
2777    */
2778    aboutToBeDeleted() {
2779        super.aboutToBeDeleted();
2780    }
2781    // get 'read through` from the ObservedProperty
2782    get() {
2783
2784        this.notifyPropertyRead();
2785        return this.wrappedValue_;
2786    }
2787    set(newValue) {
2788        if (this.wrappedValue_ == newValue) {
2789
2790            return;
2791        }
2792
2793        this.wrappedValue_ = newValue;
2794        this.notifyHasChanged(newValue);
2795    }
2796    /**
2797     * These functions are meant for use in connection with the App Stoage and
2798     * business logic implementation.
2799     * the created Link and Prop will update when 'this' property value
2800     * changes.
2801     */
2802    createLink(subscribeOwner, linkPropName) {
2803        throw new Error("Can not create a 'Link' from a 'Prop' property. ");
2804    }
2805    createProp(subscribeOwner, linkPropName) {
2806        throw new Error("Method not supported, create a SynchedPropertySimpleOneWaySubscribing from, where to create a Prop.");
2807    }
2808}
2809/*
2810  This exrension of SynchedPropertySimpleOneWay needs to be used for AppStorage
2811  because it needs to be notified about the source property changing
2812  ( there is no re-render process as in Views to update the wrappedValue )
2813*/
2814class SynchedPropertySimpleOneWaySubscribing extends SynchedPropertySimpleOneWay {
2815    constructor(linkedProperty, subscribeMe, info) {
2816        super(linkedProperty.get(), subscribeMe, info);
2817        this.linkedParentProperty_ = linkedProperty;
2818        this.linkedParentProperty_.subscribeMe(this);
2819    }
2820    aboutToBeDeleted() {
2821        // unregister from parent of this prop
2822        this.linkedParentProperty_.unlinkSuscriber(this.id__());
2823        super.aboutToBeDeleted();
2824    }
2825    hasChanged(newValue) {
2826
2827        this.set(newValue);
2828    }
2829    /**
2830     * These functions are meant for use in connection with the App Stoage and
2831     * business logic implementation.
2832     * the created Link and Prop will update when 'this' property value
2833     * changes.
2834     */
2835    createLink(subscribeOwner, linkPropName) {
2836        throw new Error("Can not create a 'Link' from a 'Prop' property. ");
2837    }
2838    createProp(subscribeOwner, propPropName) {
2839        return new SynchedPropertySimpleOneWaySubscribing(this, subscribeOwner, propPropName);
2840    }
2841}
2842/*
2843 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2844 * Licensed under the Apache License, Version 2.0 (the "License");
2845 * you may not use this file except in compliance with the License.
2846 * You may obtain a copy of the License at
2847 *
2848 *     http://www.apache.org/licenses/LICENSE-2.0
2849 *
2850 * Unless required by applicable law or agreed to in writing, software
2851 * distributed under the License is distributed on an "AS IS" BASIS,
2852 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2853 * See the License for the specific language governing permissions and
2854 * limitations under the License.
2855 */
2856/**
2857 * SynchedPropertySimpleTwoWay
2858 *
2859 * all definitions in this file are framework internal
2860 */
2861class SynchedPropertySimpleTwoWay extends ObservedPropertySimpleAbstract {
2862    constructor(source, owningView, owningViewPropNme) {
2863        super(owningView, owningViewPropNme);
2864        this.changeNotificationIsOngoing_ = false;
2865        this.source_ = source;
2866        this.source_.subscribeMe(this);
2867    }
2868    /*
2869    like a destructor, need to call this before deleting
2870    the property.
2871  */
2872    aboutToBeDeleted() {
2873        if (this.source_) {
2874            this.source_.unlinkSuscriber(this.id__());
2875            this.source_ = undefined;
2876        }
2877        super.aboutToBeDeleted();
2878    }
2879    // this object is subscriber to  SynchedPropertySimpleTwoWay
2880    // will call this cb function when property has changed
2881    // a set (newValue) is not done because get reads through for the source_
2882    hasChanged(newValue) {
2883        if (!this.changeNotificationIsOngoing_) {
2884
2885            this.notifyHasChanged(newValue);
2886        }
2887    }
2888    // get 'read through` from the ObservedProperty
2889    get() {
2890
2891        if (!this.source_) {
2892            stateMgmtConsole.error(`SynchedPropertySimpleTwoWay[${this.id__()}IP, '${this.info() || "unknown"}'] source_ is undefined: get value is undefined.`);
2893            return undefined;
2894        }
2895        this.notifyPropertyRead();
2896        return this.source_.get();
2897    }
2898    // set 'writes through` to the ObservedProperty
2899    set(newValue) {
2900        if (!this.source_) {
2901            stateMgmtConsole.error(`SynchedPropertySimpleTwoWay[${this.id__()}IP, '${this.info() || "unknown"}'] source_ is undefined: set '${newValue}' ignoring.`);
2902            return;
2903        }
2904        if (this.source_.get() == newValue) {
2905
2906            return;
2907        }
2908
2909        // the source_ ObservedProeprty will call: this.hasChanged(newValue);
2910        // the purpose of the changeNotificationIsOngoing_ is to avoid
2911        // circular notifications @Link -> source @State -> other but alos same @Link
2912        this.changeNotificationIsOngoing_ = true;
2913        this.source_.set(newValue);
2914        this.notifyHasChanged(newValue);
2915        this.changeNotificationIsOngoing_ = false;
2916    }
2917    /**
2918  * These functions are meant for use in connection with the App Stoage and
2919  * business logic implementation.
2920  * the created Link and Prop will update when 'this' property value
2921  * changes.
2922  */
2923    createLink(subscribeOwner, linkPropName) {
2924        return new SynchedPropertySimpleTwoWay(this, subscribeOwner, linkPropName);
2925    }
2926    createProp(subscribeOwner, propPropName) {
2927        return new SynchedPropertySimpleOneWaySubscribing(this, subscribeOwner, propPropName);
2928    }
2929}
2930/*
2931 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2932 * Licensed under the Apache License, Version 2.0 (the "License");
2933 * you may not use this file except in compliance with the License.
2934 * You may obtain a copy of the License at
2935 *
2936 *     http://www.apache.org/licenses/LICENSE-2.0
2937 *
2938 * Unless required by applicable law or agreed to in writing, software
2939 * distributed under the License is distributed on an "AS IS" BASIS,
2940 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2941 * See the License for the specific language governing permissions and
2942 * limitations under the License.
2943 */
2944/**
2945 * SynchedPropertyNesedObject
2946 *
2947 * all definitions in this file are framework internal
2948 */
2949class SynchedPropertyNesedObject extends ObservedPropertyObjectAbstract {
2950    /**
2951     * Construct a Property of a su component that links to a variable of parent view that holds an ObservedObject
2952     * example
2953     *   this.b.$a with b of type PC and a of type C, or
2954     *   this.$b[5] with this.b of type PC and array item b[5] of type C;
2955     *
2956     * @param subscribeMe
2957     * @param propName
2958     */
2959    constructor(obsObject, owningChildView, propertyName) {
2960        super(owningChildView, propertyName);
2961        this.obsObject_ = obsObject;
2962        // register to the ObservedObject
2963        ObservedObject.addOwningProperty(this.obsObject_, this);
2964    }
2965    /*
2966    like a destructor, need to call this before deleting
2967    the property.
2968    */
2969    aboutToBeDeleted() {
2970        // unregister from the ObservedObject
2971        ObservedObject.removeOwningProperty(this.obsObject_, this);
2972        super.aboutToBeDeleted();
2973    }
2974    // this object is subscriber to ObservedObject
2975    // will call this cb function when property has changed
2976    hasChanged(newValue) {
2977
2978        this.notifyHasChanged(this.obsObject_);
2979    }
2980    // get 'read through` from the ObservedProperty
2981    get() {
2982
2983        this.notifyPropertyRead();
2984        return this.obsObject_;
2985    }
2986    // set 'writes through` to the ObservedProperty
2987    set(newValue) {
2988        if (this.obsObject_ == newValue) {
2989
2990            return;
2991        }
2992
2993        // unsubscribe from the old value ObservedObject
2994        ObservedObject.removeOwningProperty(this.obsObject_, this);
2995        this.obsObject_ = newValue;
2996        // subscribe to the new value ObservedObject
2997        ObservedObject.addOwningProperty(this.obsObject_, this);
2998        // notify value change to subscribing View
2999        this.notifyHasChanged(this.obsObject_);
3000    }
3001    /**
3002   * These functions are meant for use in connection with the App Stoage and
3003   * business logic implementation.
3004   * the created Link and Prop will update when 'this' property value
3005   * changes.
3006   */
3007    createLink(subscribeOwner, linkPropName) {
3008        throw new Error("Method not supported for property linking to a nested objects.");
3009    }
3010    createProp(subscribeOwner, linkPropName) {
3011        throw new Error("Creating a 'Prop' proerty is unsuppoeted for Object type prperty value.");
3012    }
3013}
3014/*
3015 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3016 * Licensed under the Apache License, Version 2.0 (the "License");
3017 * you may not use this file except in compliance with the License.
3018 * You may obtain a copy of the License at
3019 *
3020 *     http://www.apache.org/licenses/LICENSE-2.0
3021 *
3022 * Unless required by applicable law or agreed to in writing, software
3023 * distributed under the License is distributed on an "AS IS" BASIS,
3024 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3025 * See the License for the specific language governing permissions and
3026 * limitations under the License.
3027 */
3028// Nativeview
3029// implemented in C++  for release
3030// and in utest/view_native_mock.ts for testing
3031class View extends NativeViewFullUpdate {
3032    get localStorage_() {
3033        if (!this.localStoragebackStore_) {
3034
3035            this.localStoragebackStore_ = new LocalStorage({ /* emty */});
3036        }
3037        return this.localStoragebackStore_;
3038    }
3039    set localStorage_(instance) {
3040        if (!instance) {
3041            // setting to undefined not allowed
3042            return;
3043        }
3044        if (this.localStoragebackStore_) {
3045            stateMgmtConsole.error(`${this.constructor.name} is setting LocalStorage instance twice`);
3046        }
3047        this.localStoragebackStore_ = instance;
3048    }
3049    /**
3050     * Create a View
3051     *
3052     * 1. option: top level View, specify
3053     *    - compilerAssignedUniqueChildId must specify
3054     *    - parent=undefined
3055     *    - localStorage  must provide if @LocalSTorageLink/Prop variables are used
3056     *      in this View or descendant Views.
3057     *
3058     * 2. option: not a top level View
3059     *    - compilerAssignedUniqueChildId must specify
3060     *    - parent must specify
3061     *    - localStorage do not specify, will inherit from parent View.
3062     *
3063     * @param compilerAssignedUniqueChildId Tw
3064     * @param parent
3065     * @param localStorage
3066     */
3067    constructor(compilerAssignedUniqueChildId, parent, localStorage) {
3068        super(compilerAssignedUniqueChildId, parent);
3069        this.propsUsedForRender = new Set();
3070        this.isRenderingInProgress = false;
3071        this.watchedProps = new Map();
3072        // my LocalStorge instance, shared with ancestor Views.
3073        // create a default instance on demand if none is initialized
3074        this.localStoragebackStore_ = undefined;
3075        this.id_ = SubscriberManager.MakeId();
3076        this.providedVars_ = parent ? new Map(parent.providedVars_)
3077            : new Map();
3078        this.localStoragebackStore_ = undefined;
3079        if (parent) {
3080            // this View is not a top-level View
3081
3082            this.setCardId(parent.getCardId());
3083            this.localStorage_ = parent.localStorage_;
3084        }
3085        else if (localStorage) {
3086            this.localStorage_ = localStorage;
3087
3088        }
3089        SubscriberManager.Add(this);
3090
3091    }
3092    // globally unique id, this is different from compilerAssignedUniqueChildId!
3093    id__() {
3094        return this.id_;
3095    }
3096    // temporary function, do not use, it will be removed soon!
3097    // prupsoe is to allow eDSL transpiler to fix a bug that
3098    // relies on this method
3099    id() {
3100        return this.id__();
3101    }
3102    propertyHasChanged(info) {
3103        if (info) {
3104            // need to sync container instanceId to switch instanceId in C++ side.
3105            this.syncInstanceId();
3106            if (this.propsUsedForRender.has(info)) {
3107
3108                this.markNeedUpdate();
3109            }
3110            else {
3111
3112            }
3113            let cb = this.watchedProps.get(info);
3114            if (cb) {
3115
3116                cb.call(this, info);
3117            }
3118            this.restoreInstanceId();
3119        } // if info avail.
3120    }
3121    propertyRead(info) {
3122
3123        if (info && (info != "unknown") && this.isRenderingInProgress) {
3124            this.propsUsedForRender.add(info);
3125        }
3126    }
3127    // for test purposes
3128    propertiesNeededToRender() {
3129        return this.propsUsedForRender;
3130    }
3131    aboutToRender() {
3132
3133        // reset
3134        this.propsUsedForRender = new Set();
3135        this.isRenderingInProgress = true;
3136    }
3137    aboutToContinueRender() {
3138        // do not reset
3139        this.isRenderingInProgress = true;
3140    }
3141    onRenderDone() {
3142        this.isRenderingInProgress = false;
3143
3144    }
3145    /**
3146     * Function to be called from the constructor of the sub component
3147     * to register a @Watch varibale
3148     * @param propStr name of the variable. Note from @Provide and @Consume this is
3149     *      the variable name and not the alias!
3150     * @param callback application defined member function of sub-class
3151     */
3152    declareWatch(propStr, callback) {
3153        this.watchedProps.set(propStr, callback);
3154    }
3155    /**
3156     * This View @Provide's a variable under given name
3157     * Call this function from the constructor of the sub class
3158     * @param providedPropName either the variable name or the alias defined as
3159     *        decorator param
3160     * @param store the backing store object for this variable (not the get/set variable!)
3161     */
3162    addProvidedVar(providedPropName, store) {
3163        if (this.providedVars_.has(providedPropName)) {
3164            throw new ReferenceError(`${this.constructor.name}: duplicate @Provide property with name ${providedPropName}.
3165      Property with this name is provided by one of the ancestor Views already.`);
3166        }
3167        this.providedVars_.set(providedPropName, store);
3168    }
3169    /**
3170     * Method for the sub-class to call from its constructor for resolving
3171     *       a @Consume variable and initializing its backing store
3172     *       with the yncedPropertyTwoWay<T> object created from the
3173     *       @Provide variable's backing store.
3174     * @param providedPropName the name of the @Provide'd variable.
3175     *     This is either the @Consume decortor parameter, or variable name.
3176     * @param consumeVarName the @Consume variable name (not the
3177     *            @Consume decortor parameter)
3178     * @returns initiaizing value of the @Consume backing store
3179     */
3180    initializeConsume(providedPropName, consumeVarName) {
3181        let providedVarStore = this.providedVars_.get(providedPropName);
3182        if (providedVarStore === undefined) {
3183            throw new ReferenceError(`${this.constructor.name}: missing @Provide property with name ${providedPropName}.
3184     Fail to resolve @Consume(${providedPropName}).`);
3185        }
3186        return providedVarStore.createLink(this, consumeVarName);
3187    }
3188}
3189/*
3190 * Copyright (c) 2022 Huawei Device Co., Ltd.
3191 * Licensed under the Apache License, Version 2.0 (the "License");
3192 * you may not use this file except in compliance with the License.
3193 * You may obtain a copy of the License at
3194 *
3195 *     http://www.apache.org/licenses/LICENSE-2.0
3196 *
3197 * Unless required by applicable law or agreed to in writing, software
3198 * distributed under the License is distributed on an "AS IS" BASIS,
3199 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3200 * See the License for the specific language governing permissions and
3201 * limitations under the License.
3202 */
3203/*
3204 * Copyright (c) 2022 Huawei Device Co., Ltd.
3205 * Licensed under the Apache License, Version 2.0 (the "License");
3206 * you may not use this file except in compliance with the License.
3207 * You may obtain a copy of the License at
3208 *
3209 *     http://www.apache.org/licenses/LICENSE-2.0
3210 *
3211 * Unless required by applicable law or agreed to in writing, software
3212 * distributed under the License is distributed on an "AS IS" BASIS,
3213 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3214 * See the License for the specific language governing permissions and
3215 * limitations under the License.
3216 */
3217var _a;
3218/**
3219 * ObservedPropertyAbstractPU aka ObservedPropertyAbstract for partial update
3220 *
3221 * all definitions in this file are framework internal
3222 */
3223class ObservedPropertyAbstractPU extends ObservedPropertyAbstract {
3224    constructor(subscriber, viewName) {
3225        super(subscriber, viewName);
3226        this.owningView_ = undefined;
3227        this.dependentElementIds_ = new Set();
3228        // when owning ViewPU is inActive, delay notifying changes
3229        this.delayedNotification_ = ObservedPropertyAbstractPU.DelayedNotifyChangesEnum.do_not_delay;
3230        Object.defineProperty(this, 'owningView_', { writable: true, enumerable: false });
3231        Object.defineProperty(this, 'subscriberRefs_', { writable: true, enumerable: false, value: new Set() });
3232        if (subscriber) {
3233            if (subscriber instanceof ViewPU) {
3234                this.owningView_ = subscriber;
3235            }
3236            else {
3237                this.subscriberRefs_.add(subscriber);
3238            }
3239        }
3240    }
3241    aboutToBeDeleted() {
3242        super.aboutToBeDeleted();
3243        this.subscriberRefs_.clear();
3244        this.owningView_ = undefined;
3245    }
3246    // dump basic info about this variable to a string, non-recursive, no subscriber info
3247    debugInfo() {
3248        const propSource = this.isPropSourceObservedPropertyFakeName();
3249        return (propSource)
3250            ? `internal source (ObservedPropertyPU) of @Prop ${propSource} [${this.id__()}]`
3251            : `${this.debugInfoDecorator()} '${this.info()}'[${this.id__()}] <${this.debugInfoOwningView()}>`;
3252    }
3253    debugInfoOwningView() {
3254        return `${this.owningView_ ? this.owningView_.debugInfo() : "owning @Component UNKNOWN"}`;
3255    }
3256    // dump info about owning view and subscribers (PU ones only)
3257    // use function only for debug output and DFX.
3258    debugInfoSubscribers() {
3259        return (this.owningView_)
3260            ? `owned by ${this.debugInfoOwningView()} `
3261            : `owned by: owning view not known`;
3262    }
3263    debugInfoSyncPeers() {
3264        if (!this.subscriberRefs_.size) {
3265            return "sync peers: none";
3266        }
3267        let result = `sync peers:\n`;
3268        let sepa = "";
3269        this.subscriberRefs_.forEach((subscriber) => {
3270            if ("debugInfo" in subscriber) {
3271                result += `    ${sepa}${subscriber.debugInfo()}`;
3272                sepa = ", ";
3273            }
3274        });
3275        return result;
3276    }
3277    debugInfoDependentElmtIds() {
3278        if (!this.dependentElementIds_.size) {
3279            return `dependent components: no dependent elmtIds`;
3280        }
3281        let result = this.dependentElementIds_.size < 25
3282            ? `dependent components: ${this.dependentElementIds_.size} elmtIds: `
3283            : `WARNING: high number of dependent components (consider app redesign): ${this.dependentElementIds_.size} elmtIds: `;
3284        let sepa = "";
3285        this.dependentElementIds_.forEach((elmtId) => {
3286            result += `${sepa}${this.owningView_.debugInfoElmtId(elmtId)}`;
3287            sepa = ", ";
3288        });
3289        return result;
3290    }
3291    /* for @Prop value from source we need to generate a @State
3292       that observes when this value changes. This ObservedPropertyPU
3293       sits inside SynchedPropertyOneWayPU.
3294       below methods invent a fake variable name for it
3295    */
3296    getPropSourceObservedPropertyFakeName() {
3297        return `${this.info()}_prop_fake_state_source___`;
3298    }
3299    isPropSourceObservedPropertyFakeName() {
3300        return this.info().endsWith("_prop_fake_state_source___")
3301            ? this.info().substring(0, this.info().length - "_prop_fake_state_source___".length)
3302            : false;
3303    }
3304    /*
3305      Virtualized version of the subscription mechanism - add subscriber
3306      Overrides implementation in ObservedPropertyAbstract<T>
3307    */
3308    addSubscriber(subscriber) {
3309        if (subscriber) {
3310            // ObservedPropertyAbstract will also add subscriber to
3311            // SubscriberManager map and to its own Set of subscribers as well
3312            // Something to improve in the future for PU path.
3313            // subscribeMe should accept IPropertySubscriber interface
3314            super.subscribeMe(subscriber);
3315            this.subscriberRefs_.add(subscriber);
3316        }
3317    }
3318    /*
3319      Virtualized version of the subscription mechanism - remove subscriber
3320      Overrides implementation in ObservedPropertyAbstract<T>
3321    */
3322    removeSubscriber(subscriber, id) {
3323        if (subscriber) {
3324            this.subscriberRefs_.delete(subscriber);
3325            if (!id) {
3326                id = subscriber.id__();
3327            }
3328        }
3329        super.unlinkSuscriber(id);
3330    }
3331    /**
3332     * put the property to delayed notification mode
3333     * feature is only used for @StorageLink/Prop, @LocalStorageLink/Prop
3334     */
3335    enableDelayedNotification() {
3336        if (this.delayedNotification_ != ObservedPropertyAbstractPU.DelayedNotifyChangesEnum.delay_notification_pending) {
3337
3338            this.delayedNotification_ = ObservedPropertyAbstractPU.DelayedNotifyChangesEnum.delay_none_pending;
3339        }
3340    }
3341    /*
3342       when moving from inActive to active state the owning ViewPU calls this function
3343       This solution is faster than ViewPU polling each variable to send back a viewPropertyHasChanged event
3344       with the elmtIds
3345
3346      returns undefined if variable has _not_ changed
3347      returns dependentElementIds_ Set if changed. This Set is empty if variable is not used to construct the UI
3348    */
3349    moveElmtIdsForDelayedUpdate() {
3350        const result = (this.delayedNotification_ == ObservedPropertyAbstractPU.DelayedNotifyChangesEnum.delay_notification_pending)
3351            ? this.dependentElementIds_
3352            : undefined;
3353
3354        this.delayedNotification_ = ObservedPropertyAbstractPU.DelayedNotifyChangesEnum.do_not_delay;
3355        return result;
3356    }
3357    notifyPropertyRead() {
3358        stateMgmtConsole.error(`${this.debugInfo()}: notifyPropertyRead, DO NOT USE with PU. Use \
3359                      notifyPropertyHasBeenReadPU`);
3360    }
3361    notifyPropertyHasBeenReadPU() {
3362
3363        this.subscriberRefs_.forEach((subscriber) => {
3364            if (subscriber) {
3365                // TODO
3366                // propertyHasBeenReadPU is not use in the code
3367                // defined by interface that is not used either: PropertyReadEventListener
3368                // Maybe compiler generated code has it?
3369                if ('propertyHasBeenReadPU' in subscriber) {
3370                    subscriber.propertyHasBeenReadPU(this);
3371                }
3372            }
3373        });
3374        this.recordDependentUpdate();
3375    }
3376    notifyPropertyHasChangedPU() {
3377
3378        if (this.owningView_) {
3379            if (this.delayedNotification_ == ObservedPropertyAbstractPU.DelayedNotifyChangesEnum.do_not_delay) {
3380                // send viewPropertyHasChanged right away
3381                this.owningView_.viewPropertyHasChanged(this.info_, this.dependentElementIds_);
3382            }
3383            else {
3384                // mark this @StorageLink/Prop or @LocalStorageLink/Prop variable has having changed and notification of viewPropertyHasChanged delivery pending
3385                this.delayedNotification_ = ObservedPropertyAbstractPU.DelayedNotifyChangesEnum.delay_notification_pending;
3386            }
3387        }
3388        this.subscriberRefs_.forEach((subscriber) => {
3389            if (subscriber) {
3390                if ('syncPeerHasChanged' in subscriber) {
3391                    subscriber.syncPeerHasChanged(this);
3392                }
3393                else {
3394                    stateMgmtConsole.warn(`${this.debugInfo()}: notifyPropertyHasChangedPU: unknown subscriber ID 'subscribedId' error!`);
3395                }
3396            }
3397        });
3398    }
3399    markDependentElementsDirty(view) {
3400        // TODO ace-ets2bundle, framework, complicated apps need to update together
3401        // this function will be removed after a short transition period.
3402        stateMgmtConsole.warn(`${this.debugInfo()}: markDependentElementsDirty no longer supported. App will work ok, but
3403        please update your ace-ets2bundle and recompile your application!`);
3404    }
3405    numberOfSubscrbers() {
3406        return this.subscriberRefs_.size + (this.owningView_ ? 1 : 0);
3407    }
3408    /*
3409     type checking for any supported type, as required for union type support
3410      see 1st parameter for explanation what is allowed
3411
3412      FIXME this expects the Map, Set patch to go in
3413    */
3414    checkIsSupportedValue(value) {
3415        return this.checkNewValue(`undefined, null, number, boolean, string, or Object but not function`, value, () => ((typeof value == "object" && typeof value != "function")
3416            || typeof value == "number" || typeof value == "string" || typeof value == "boolean")
3417            || (value == undefined || value == null));
3418    }
3419    /*
3420      type checking for allowed Object type value
3421      see 1st parameter for explanation what is allowed
3422
3423        FIXME this expects the Map, Set patch to go in
3424      */
3425    checkIsObject(value) {
3426        return this.checkNewValue(`undefined, null, Object including Array and instance of SubscribableAbstract and excluding function, Set, and Map`, value, () => (value == undefined || value == null || (typeof value == "object")));
3427    }
3428    /*
3429      type checking for allowed simple types value
3430      see 1st parameter for explanation what is allowed
3431   */
3432    checkIsSimple(value) {
3433        return this.checkNewValue(`undefined, number, boolean, string`, value, () => (value == undefined || typeof value == "number" || typeof value == "string" || typeof value == "boolean"));
3434    }
3435    checkNewValue(isAllowedComment, newValue, validator) {
3436        if (validator(newValue)) {
3437            return true;
3438        }
3439        // report error
3440        // current implementation throws an Exception
3441        errorReport.varValueCheckFailed({
3442            customComponent: this.debugInfoOwningView(),
3443            variableDeco: this.debugInfoDecorator(),
3444            variableName: this.info(),
3445            expectedType: isAllowedComment,
3446            value: newValue
3447        });
3448        // never gets here if errorReport.varValueCheckFailed throws an exception
3449        // but should nto depend on its implementation
3450        return false;
3451    }
3452    /**
3453     * factory function for concrete 'object' or 'simple' ObservedProperty object
3454     * depending if value is Class object
3455     * or simple type (boolean | number | string)
3456     * @param value
3457     * @param owningView
3458     * @param thisPropertyName
3459     * @returns either
3460     */
3461    static CreateObservedObject(value, owningView, thisPropertyName) {
3462        return (typeof value === "object") ?
3463            new ObservedPropertyObject(value, owningView, thisPropertyName)
3464            : new ObservedPropertySimple(value, owningView, thisPropertyName);
3465    }
3466    /**
3467     * during 'get' access recording take note of the created component and its elmtId
3468     * and add this component to the list of components who are dependent on this property
3469     */
3470    recordDependentUpdate() {
3471        const elmtId = ViewStackProcessor.GetElmtIdToAccountFor();
3472        if (elmtId < 0) {
3473            // not access recording
3474            return;
3475        }
3476
3477        this.dependentElementIds_.add(elmtId);
3478    }
3479    purgeDependencyOnElmtId(rmElmtId) {
3480
3481        this.dependentElementIds_.delete(rmElmtId);
3482    }
3483    SetPropertyUnchanged() {
3484        // function to be removed
3485        // keep it here until transpiler is updated.
3486    }
3487    // FIXME check, is this used from AppStorage.
3488    // unified Appstorage, what classes to use, and the API
3489    createLink(subscribeOwner, linkPropName) {
3490        throw new Error(`${this.debugInfo()}: createLink: Can not create a AppStorage 'Link' from this property.`);
3491    }
3492    createProp(subscribeOwner, linkPropName) {
3493        throw new Error(`${this.debugInfo()}: createProp: Can not create a AppStorage 'Prop' from a @State property. `);
3494    }
3495    /*
3496      Below empty functions required to keep as long as this class derives from FU version
3497      ObservedPropertyAbstract. Need to overwrite these functions to do nothing for PU
3498      */
3499    notifyHasChanged(_) {
3500        stateMgmtConsole.error(`${this.debugInfo()}: notifyHasChanged, DO NOT USE with PU. Use syncPeerHasChanged() \
3501                                            or objectPropertyHasChangedPU()`);
3502    }
3503    hasChanged(_) {
3504        // unused for PU
3505        // need to overwrite impl of base class with empty function.
3506    }
3507    propertyHasChanged(_) {
3508        // unused for PU
3509        // need to overwrite impl of base class with empty function.
3510    }
3511    propertyRead(_) {
3512        // unused for PU
3513        // need to overwrite impl of base class with empty function.
3514    }
3515}
3516ObservedPropertyAbstractPU.DelayedNotifyChangesEnum = (_a = class {
3517    },
3518    _a.do_not_delay = 0,
3519    _a.delay_none_pending = 1,
3520    _a.delay_notification_pending = 2,
3521    _a);
3522/*
3523 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3524 * Licensed under the Apache License, Version 2.0 (the "License");
3525 * you may not use this file except in compliance with the License.
3526 * You may obtain a copy of the License at
3527 *
3528 *     http://www.apache.org/licenses/LICENSE-2.0
3529 *
3530 * Unless required by applicable law or agreed to in writing, software
3531 * distributed under the License is distributed on an "AS IS" BASIS,
3532 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3533 * See the License for the specific language governing permissions and
3534 * limitations under the License.
3535 */
3536/**
3537 * ObservedPropertyObjectPU
3538 * implementation of @State and @Provide decorated variables of type class object
3539 *
3540 * all definitions in this file are framework internal
3541 *
3542 * class that holds an actual property value of type T
3543 * uses its base class to manage subscribers to this
3544 * property.
3545*/
3546class ObservedPropertyPU extends ObservedPropertyAbstractPU {
3547    constructor(localInitValue, owningView, propertyName) {
3548        super(owningView, propertyName);
3549        this.setValueInternal(localInitValue);
3550    }
3551    aboutToBeDeleted(unsubscribeMe) {
3552        this.unsubscribeWrappedObject();
3553        this.removeSubscriber(unsubscribeMe);
3554        super.aboutToBeDeleted();
3555    }
3556    debugInfoDecorator() {
3557        return `@State/@Provide (class ObservedPropertyPU)`;
3558    }
3559    /**
3560     * Called by a SynchedPropertyObjectTwoWayPU (@Link, @Consume) that uses this as sync peer when it has changed
3561     * @param eventSource
3562     */
3563    syncPeerHasChanged(eventSource) {
3564
3565        this.notifyPropertyHasChangedPU();
3566    }
3567    /**
3568     * Wraped ObservedObjectPU has changed
3569     * @param souceObject
3570     * @param changedPropertyName
3571     */
3572    objectPropertyHasChangedPU(souceObject, changedPropertyName) {
3573
3574        this.notifyPropertyHasChangedPU();
3575    }
3576    objectPropertyHasBeenReadPU(souceObject, changedPropertyName) {
3577
3578        this.notifyPropertyHasBeenReadPU();
3579    }
3580    unsubscribeWrappedObject() {
3581        if (this.wrappedValue_) {
3582            if (this.wrappedValue_ instanceof SubscribableAbstract) {
3583                this.wrappedValue_.removeOwningProperty(this);
3584            }
3585            else {
3586                ObservedObject.removeOwningProperty(this.wrappedValue_, this);
3587            }
3588        }
3589    }
3590    /*
3591      actually update this.wrappedValue_
3592      called needs to do value change check
3593      and also notify with this.aboutToChange();
3594    */
3595    setValueInternal(newValue) {
3596        if (newValue === this.wrappedValue_) {
3597
3598            return false;
3599        }
3600        if (!this.checkIsSupportedValue(newValue)) {
3601            return false;
3602        }
3603        this.unsubscribeWrappedObject();
3604        if (!newValue || typeof newValue !== 'object') {
3605            // undefined, null, simple type:
3606            // nothing to subscribe to in case of new value undefined || null || simple type
3607            this.wrappedValue_ = newValue;
3608        }
3609        else if (newValue instanceof SubscribableAbstract) {
3610
3611            this.wrappedValue_ = newValue;
3612            this.wrappedValue_.addOwningProperty(this);
3613        }
3614        else if (ObservedObject.IsObservedObject(newValue)) {
3615
3616            ObservedObject.addOwningProperty(newValue, this);
3617            this.wrappedValue_ = newValue;
3618        }
3619        else {
3620
3621            this.wrappedValue_ = ObservedObject.createNew(newValue, this);
3622        }
3623        return true;
3624    }
3625    get() {
3626
3627        this.notifyPropertyHasBeenReadPU();
3628        return this.wrappedValue_;
3629    }
3630    getUnmonitored() {
3631
3632        // unmonitored get access , no call to notifyPropertyRead !
3633        return this.wrappedValue_;
3634    }
3635    set(newValue) {
3636        if (this.wrappedValue_ === newValue) {
3637
3638            return;
3639        }
3640
3641        if (this.setValueInternal(newValue)) {
3642            this.notifyPropertyHasChangedPU();
3643        }
3644    }
3645}
3646// class definitions for backward compatibility
3647class ObservedPropertyObjectPU extends ObservedPropertyPU {
3648}
3649class ObservedPropertySimplePU extends ObservedPropertyPU {
3650}
3651/*
3652 * Copyright (c) 2022 Huawei Device Co., Ltd.
3653 * Licensed under the Apache License, Version 2.0 (the "License");
3654 * you may not use this file except in compliance with the License.
3655 * You may obtain a copy of the License at
3656 *
3657 *     http://www.apache.org/licenses/LICENSE-2.0
3658 *
3659 * Unless required by applicable law or agreed to in writing, software
3660 * distributed under the License is distributed on an "AS IS" BASIS,
3661 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3662 * See the License for the specific language governing permissions and
3663 * limitations under the License.
3664 */
3665/**
3666 * SynchedPropertyObjectOneWayPU
3667 * implementation  of @Prop decorated variables of type class object
3668 *
3669 * all definitions in this file are framework internal
3670 *
3671 */
3672/**
3673 * Initialisation scenarios:
3674 * -------------------------
3675 *
3676 * 1 - no local initialization, source provided (its ObservedObject value)
3677 *     wrap the ObservedObject into an ObservedPropertyObjectPU
3678 *     deep copy the ObservedObject into localCopyObservedObject_
3679 *
3680 * 2 - local initialization, no source provided
3681 *     app transpiled code calls set
3682 *     leave source_ undefined
3683 *     no deep copy needed, but provided local init might need wrapping inside an ObservedObject to set to
3684 *     localCopyObservedObject_
3685 *
3686 * 3  local initialization,  source provided (its ObservedObject value)
3687 *    current app transpiled code is not optional
3688 *    sets source in constructor, as in case 1
3689 *    calls set() to set the source value, but this will not deepcopy
3690 *
3691 * Update scenarios:
3692 * -----------------
3693 *
3694 * 1- assignment of a new Object value: this.aProp = new ClassA()
3695 *    rhs can be ObservedObject because of @Observed decoration or now
3696 *    notifyPropertyHasChangedPU
3697 *
3698 * 2- local ObservedObject member property change
3699 *    objectPropertyHasChangedPU called, eventSource is the ObservedObject stored in localCopyObservedObject_
3700 *    no need to copy, notifyPropertyHasChangedPU
3701 *
3702 * 3- Rerender of the custom component triggered from the parent
3703 *    reset() is called (code generated by the transpiler), set the value of source_ ,  if that causes a change will call syncPeerHasChanged
3704 *    syncPeerHasChanged need to deep copy the ObservedObject from source to localCopyObservedObject_
3705 *    notifyPropertyHasChangedPU
3706 *
3707 * 4- source_ ObservedObject member property change
3708 *     objectPropertyHasChangedPU called, eventSource is the ObservedObject stored source_.getUnmonitored
3709 *     notifyPropertyHasChangedPU
3710 */
3711class SynchedPropertyOneWayPU extends ObservedPropertyAbstractPU {
3712    constructor(source, owningChildView, thisPropertyName) {
3713        super(owningChildView, thisPropertyName);
3714        if (source && (typeof (source) === "object") && ("subscribeMe" in source)) {
3715            // code path for @(Local)StorageProp, the source is a ObservedPropertyObject<C> in a LocalStorage)
3716            this.source_ = source;
3717            this.sourceIsOwnObject = false;
3718            // subscribe to receive value change updates from LocalStorage source property
3719            this.source_.addSubscriber(this);
3720        }
3721        else {
3722            const sourceValue = source;
3723            if (this.checkIsSupportedValue(sourceValue)) {
3724                // code path for
3725                // 1- source is of same type C in parent, source is its value, not the backing store ObservedPropertyObject
3726                // 2- nested Object/Array inside observed another object/array in parent, source is its value
3727                if (typeof sourceValue == "object" && !((sourceValue instanceof SubscribableAbstract) || ObservedObject.IsObservedObject(sourceValue))) {
3728                    stateMgmtConsole.applicationError(`${this.debugInfo()}:  Provided source object's class is not instance of SubscribableAbstract,
3729              it also lacks @Observed class decorator. Object property changes will not be observed. Application error!`);
3730                }
3731
3732                this.source_ = new ObservedPropertyObjectPU(sourceValue, this, this.getPropSourceObservedPropertyFakeName());
3733                this.sourceIsOwnObject = true;
3734            }
3735        }
3736        if (this.source_ != undefined) {
3737            this.resetLocalValue(this.source_.get(), /* needCopyObject */ true);
3738        }
3739
3740    }
3741    /*
3742    like a destructor, need to call this before deleting
3743    the property.
3744    */
3745    aboutToBeDeleted() {
3746        if (this.source_) {
3747            this.source_.removeSubscriber(this);
3748            if (this.sourceIsOwnObject == true && this.source_.numberOfSubscrbers() == 0) {
3749
3750                this.source_.aboutToBeDeleted();
3751            }
3752            this.source_ = undefined;
3753        }
3754        super.aboutToBeDeleted();
3755    }
3756    debugInfoDecorator() {
3757        return `@Prop (class SynchedPropertyOneWayPU)`;
3758    }
3759    syncPeerHasChanged(eventSource) {
3760        if (this.source_ == undefined) {
3761            stateMgmtConsole.error(`${this.debugInfo()}: syncPeerHasChanged from peer ${eventSource && eventSource.debugInfo && eventSource.debugInfo()}. source_ undefined. Internal error.`);
3762            return;
3763        }
3764        if (eventSource && this.source_ == eventSource) {
3765            // defensive programming: should always be the case!
3766            const newValue = this.source_.getUnmonitored();
3767            if (this.checkIsSupportedValue(newValue)) {
3768
3769                if (this.resetLocalValue(newValue, /* needCopyObject */ true)) {
3770                    this.notifyPropertyHasChangedPU();
3771                }
3772            }
3773        }
3774        else {
3775            stateMgmtConsole.warn(`${this.debugInfo()}: syncPeerHasChanged: from peer '${eventSource === null || eventSource === void 0 ? void 0 : eventSource.debugInfo()}', Unexpected situation. syncPeerHasChanged from different sender than source_. Ignoring event.`);
3776        }
3777    }
3778    /**
3779     * event emited by wrapped ObservedObject, when one of its property values changes
3780     * @param souceObject
3781     * @param changedPropertyName
3782     */
3783    objectPropertyHasChangedPU(sourceObject, changedPropertyName) {
3784
3785        this.notifyPropertyHasChangedPU();
3786    }
3787    objectPropertyHasBeenReadPU(sourceObject, changedPropertyName) {
3788
3789        this.notifyPropertyHasBeenReadPU();
3790    }
3791    getUnmonitored() {
3792
3793        // unmonitored get access , no call to notifyPropertyRead !
3794        return this.localCopyObservedObject_;
3795    }
3796    get() {
3797
3798        this.notifyPropertyHasBeenReadPU();
3799        return this.localCopyObservedObject_;
3800    }
3801    // assignment to local variable in the form of this.aProp = <object value>
3802    // set 'writes through` to the ObservedObject
3803    set(newValue) {
3804        if (this.localCopyObservedObject_ === newValue) {
3805
3806            return;
3807        }
3808
3809        if (this.resetLocalValue(newValue, /* needCopyObject */ false)) {
3810            this.notifyPropertyHasChangedPU();
3811        }
3812    }
3813    // called when updated from parent
3814    reset(sourceChangedValue) {
3815
3816        if (this.source_ !== undefined && this.checkIsSupportedValue(sourceChangedValue)) {
3817            // if this.source_.set causes an actual change, then, ObservedPropertyObject source_ will call syncPeerHasChanged method
3818            this.source_.set(sourceChangedValue);
3819        }
3820    }
3821    /*
3822      unsubscribe from previous wrapped ObjectObject
3823      take a shallow or (TODO) deep copy
3824      copied Object might already be an ObservedObject (e.g. becurse of @Observed decorator) or might be raw
3825      Therefore, conditionally wrap the object, then subscribe
3826      return value true only if localCopyObservedObject_ has been changed
3827    */
3828    resetLocalValue(newObservedObjectValue, needCopyObject) {
3829        // note: We can not test for newObservedObjectValue == this.localCopyObservedObject_
3830        // here because the object might still be the same, but some property of it has changed
3831        if (!this.checkIsSupportedValue(newObservedObjectValue)) {
3832            return;
3833        }
3834        // unsubscribe from old local copy
3835        if (this.localCopyObservedObject_ instanceof SubscribableAbstract) {
3836            this.localCopyObservedObject_.removeOwningProperty(this);
3837        }
3838        else {
3839            ObservedObject.removeOwningProperty(this.localCopyObservedObject_, this);
3840        }
3841        // shallow/deep copy value
3842        // needed whenever newObservedObjectValue comes from source
3843        // not needed on a local set (aka when called from set() method)
3844        this.localCopyObservedObject_ = needCopyObject ? this.copyObject(newObservedObjectValue, this.info_) : newObservedObjectValue;
3845        if (typeof this.localCopyObservedObject_ == "object") {
3846            if (this.localCopyObservedObject_ instanceof SubscribableAbstract) {
3847                // deep copy will copy Set of subscribers as well. But local copy only has its own subscribers
3848                // not those of its parent value.
3849                this.localCopyObservedObject_.clearOwningProperties();
3850                this.localCopyObservedObject_.addOwningProperty(this);
3851            }
3852            else if (ObservedObject.IsObservedObject(this.localCopyObservedObject_)) {
3853                // case: new ObservedObject
3854                ObservedObject.addOwningProperty(this.localCopyObservedObject_, this);
3855            }
3856            else {
3857                // wrap newObservedObjectValue raw object as ObservedObject and subscribe to it
3858
3859                this.localCopyObservedObject_ = ObservedObject.createNew(this.localCopyObservedObject_, this);
3860            }
3861        }
3862        return true;
3863    }
3864    copyObject(value, propName) {
3865        // ViewStackProcessor.getApiVersion function is not present in API9
3866        // therefore shallowCopyObject will always be used in API version 9 and before
3867        // but the code in this file is the same regardless of API version
3868
3869        return ((typeof ViewStackProcessor["getApiVersion"] == "function") &&
3870            (ViewStackProcessor["getApiVersion"]() >= 10))
3871            ? this.deepCopyObject(value, propName)
3872            : this.shallowCopyObject(value, propName);
3873    }
3874    // API 9 code path
3875    shallowCopyObject(value, propName) {
3876        let rawValue = ObservedObject.GetRawObject(value);
3877        let copy;
3878        if (!rawValue || typeof rawValue !== 'object') {
3879            copy = rawValue;
3880        }
3881        else if (typeof rawValue != "object") {
3882            // FIXME would it be better to throw Exception here?
3883            stateMgmtConsole.error(`${this.debugInfo()}: shallowCopyObject: request to copy non-object value, actual type is '${typeof rawValue}'. Internal error! Setting copy:=original value.`);
3884            copy = rawValue;
3885        }
3886        else if (rawValue instanceof Array) {
3887            // case Array inside ObservedObject
3888            copy = ObservedObject.createNew([...rawValue], this);
3889            Object.setPrototypeOf(copy, Object.getPrototypeOf(rawValue));
3890        }
3891        else if (rawValue instanceof Date) {
3892            // case Date inside ObservedObject
3893            let d = new Date();
3894            d.setTime(rawValue.getTime());
3895            // subscribe, also Date gets wrapped / proxied by ObservedObject
3896            copy = ObservedObject.createNew(d, this);
3897        }
3898        else if (rawValue instanceof SubscribableAbstract) {
3899            // case SubscribableAbstract, no wrapping inside ObservedObject
3900            copy = Object.assign({}, rawValue);
3901            Object.setPrototypeOf(copy, Object.getPrototypeOf(rawValue));
3902            if (copy instanceof SubscribableAbstract) {
3903                // subscribe
3904                copy.addOwningProperty(this);
3905            }
3906        }
3907        else if (typeof rawValue == "object") {
3908            // case Object that is not Array, not Date, not SubscribableAbstract
3909            copy = ObservedObject.createNew(Object.assign({}, rawValue), this);
3910            Object.setPrototypeOf(copy, Object.getPrototypeOf(rawValue));
3911        }
3912        else {
3913            // TODO in PR "F": change to exception throwing:
3914            stateMgmtConsole.error(`${this.debugInfo()}: shallow failed. Attempt to copy unsupported value of type '${typeof rawValue}' .`);
3915            copy = rawValue;
3916        }
3917        return copy;
3918    }
3919    // API 10 code path
3920    deepCopyObject(obj, variable) {
3921        let copy = SynchedPropertyObjectOneWayPU.deepCopyObjectInternal(obj, variable);
3922        // this subscribe to the top level object/array of the copy
3923        // same as shallowCopy does
3924        if ((obj instanceof SubscribableAbstract) &&
3925            (copy instanceof SubscribableAbstract)) {
3926            copy.addOwningProperty(this);
3927        }
3928        else if (ObservedObject.IsObservedObject(obj) && ObservedObject.IsObservedObject(copy)) {
3929            ObservedObject.addOwningProperty(copy, this);
3930        }
3931        return copy;
3932        ;
3933    }
3934    // do not use this function from outside unless it is for testing purposes.
3935    static deepCopyObjectInternal(obj, variable) {
3936        if (!obj || typeof obj !== 'object') {
3937            return obj;
3938        }
3939        let stack = new Array();
3940        let copiedObjects = new Map();
3941        return getDeepCopyOfObjectRecursive(obj);
3942        function getDeepCopyOfObjectRecursive(obj) {
3943            if (!obj || typeof obj !== 'object') {
3944                return obj;
3945            }
3946            const alreadyCopiedObject = copiedObjects.get(obj);
3947            if (alreadyCopiedObject) {
3948                let msg = `@Prop deepCopyObject: Found reference to already copied object: Path ${variable ? variable : 'unknown variable'}`;
3949                stack.forEach(stackItem => msg += ` - ${stackItem.name}`);
3950
3951                return alreadyCopiedObject;
3952            }
3953            let copy;
3954            if (obj instanceof Set) {
3955                copy = new Set();
3956                for (const setKey of obj.keys()) {
3957                    stack.push({ name: setKey });
3958                    copiedObjects.set(obj, copy);
3959                    copy.add(getDeepCopyOfObjectRecursive(setKey));
3960                    stack.pop();
3961                }
3962            }
3963            else if (obj instanceof Map) {
3964                copy = new Map();
3965                for (const mapKey of obj.keys()) {
3966                    stack.push({ name: mapKey });
3967                    copiedObjects.set(obj, copy);
3968                    copy.set(mapKey, getDeepCopyOfObjectRecursive(obj.get(mapKey)));
3969                    stack.pop();
3970                }
3971            }
3972            else if (obj instanceof Date) {
3973                copy = new Date();
3974                copy.setTime(obj.getTime());
3975            }
3976            else if (obj instanceof Object) {
3977                copy = Array.isArray(obj) ? [] : {};
3978                Object.setPrototypeOf(copy, Object.getPrototypeOf(obj));
3979                for (const objKey of Object.keys(obj)) {
3980                    stack.push({ name: objKey });
3981                    copiedObjects.set(obj, copy);
3982                    Reflect.set(copy, objKey, getDeepCopyOfObjectRecursive(obj[objKey]));
3983                    stack.pop();
3984                }
3985            }
3986            return ObservedObject.IsObservedObject(obj) ? ObservedObject.createNew(copy, null) : copy;
3987        }
3988    }
3989}
3990// class definitions for backward compatibility
3991class SynchedPropertySimpleOneWayPU extends SynchedPropertyOneWayPU {
3992}
3993class SynchedPropertyObjectOneWayPU extends SynchedPropertyOneWayPU {
3994}
3995/*
3996 * Copyright (c) 2022 Huawei Device Co., Ltd.
3997 * Licensed under the Apache License, Version 2.0 (the "License");
3998 * you may not use this file except in compliance with the License.
3999 * You may obtain a copy of the License at
4000 *
4001 *     http://www.apache.org/licenses/LICENSE-2.0
4002 *
4003 * Unless required by applicable law or agreed to in writing, software
4004 * distributed under the License is distributed on an "AS IS" BASIS,
4005 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4006 * See the License for the specific language governing permissions and
4007 * limitations under the License.
4008 */
4009/**
4010 * SynchedPropertyObjectTwoWayPU
4011 * implementation of @Link and @Consume decorated variables of type class object
4012 *
4013 * all definitions in this file are framework internal
4014*/
4015class SynchedPropertyTwoWayPU extends ObservedPropertyAbstractPU {
4016    constructor(source, owningChildView, thisPropertyName) {
4017        super(owningChildView, thisPropertyName);
4018        this.changeNotificationIsOngoing_ = false;
4019        this.source_ = source;
4020        if (this.source_) {
4021            // register to the parent property
4022            this.source_.addSubscriber(this);
4023        }
4024        else {
4025            throw new SyntaxError(`${this.debugInfo()}: constructor: source variable in parent/ancestor @Component must be defined. Application error!`);
4026        }
4027    }
4028    /*
4029    like a destructor, need to call this before deleting
4030    the property.
4031    */
4032    aboutToBeDeleted() {
4033        // unregister from parent of this link
4034        if (this.source_) {
4035            this.source_.removeSubscriber(this);
4036            // unregister from the ObservedObject
4037            ObservedObject.removeOwningProperty(this.source_.getUnmonitored(), this);
4038        }
4039        super.aboutToBeDeleted();
4040    }
4041    debugInfoDecorator() {
4042        return `@Link/@Consume (class SynchedPropertyTwoWayPU)`;
4043    }
4044    isStorageLinkProp() {
4045        return (this.source_ && this.source_ instanceof ObservedPropertyAbstract && (!(this.source_ instanceof ObservedPropertyAbstractPU)));
4046    }
4047    setObject(newValue) {
4048        if (!this.source_) {
4049            throw new SyntaxError(`${this.debugInfo()}: setObject (assign a new value), no source variable in parent/ancestor \
4050                                                    @Component. Application error.`);
4051        }
4052        if (this.getUnmonitored() === newValue) {
4053
4054            return;
4055        }
4056
4057        if (this.checkIsSupportedValue(newValue)) {
4058            // the source_ ObservedProperty will call: this.syncPeerHasChanged(newValue);
4059            this.source_.set(newValue);
4060        }
4061    }
4062    /**
4063     * Called when sync peer ObservedPropertyObject or SynchedPropertyObjectTwoWay has changed value
4064     * that peer can be in either parent or child component if 'this' is used for a @Link
4065     * that peer can be in either ancestor or descendant component if 'this' is used for a @Consume
4066     * @param eventSource
4067     */
4068    syncPeerHasChanged(eventSource) {
4069        if (!this.changeNotificationIsOngoing_) {
4070
4071            this.notifyPropertyHasChangedPU();
4072        }
4073    }
4074    /**
4075     * called when wrapped ObservedObject has changed poperty
4076     * @param souceObject
4077     * @param changedPropertyName
4078     */
4079    objectPropertyHasChangedPU(sourceObject, changedPropertyName) {
4080
4081        this.notifyPropertyHasChangedPU();
4082    }
4083    objectPropertyHasBeenReadPU(sourceObject, changedPropertyName) {
4084
4085        this.notifyPropertyHasBeenReadPU();
4086    }
4087    getUnmonitored() {
4088
4089        // unmonitored get access , no call to otifyPropertyRead !
4090        return (this.source_ ? this.source_.getUnmonitored() : undefined);
4091    }
4092    // get 'read through` from the ObservedProperty
4093    get() {
4094
4095        this.notifyPropertyHasBeenReadPU();
4096        return this.getUnmonitored();
4097    }
4098    // set 'writes through` to the ObservedProperty
4099    set(newValue) {
4100        if (this.getUnmonitored() === newValue) {
4101
4102            return;
4103        }
4104
4105        // avoid circular notifications @Link -> source @State -> other but also back to same @Link
4106        this.changeNotificationIsOngoing_ = true;
4107        this.setObject(newValue);
4108        this.notifyPropertyHasChangedPU();
4109        this.changeNotificationIsOngoing_ = false;
4110    }
4111}
4112// class definitions for backward compatibility
4113class SynchedPropertyObjectTwoWayPU extends SynchedPropertyTwoWayPU {
4114}
4115class SynchedPropertySimpleTwoWayPU extends SynchedPropertyTwoWayPU {
4116}
4117/*
4118 * Copyright (c) 2022 Huawei Device Co., Ltd.
4119 * Licensed under the Apache License, Version 2.0 (the "License");
4120 * you may not use this file except in compliance with the License.
4121 * You may obtain a copy of the License at
4122 *
4123 *     http://www.apache.org/licenses/LICENSE-2.0
4124 *
4125 * Unless required by applicable law or agreed to in writing, software
4126 * distributed under the License is distributed on an "AS IS" BASIS,
4127 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4128 * See the License for the specific language governing permissions and
4129 * limitations under the License.
4130 */
4131/**
4132 * SynchedPropertyNestedObjectPU
4133 * implementation of @ObjectLink decorated variables
4134 *
4135 * all definitions in this file are framework internal
4136 *
4137 */
4138class SynchedPropertyNestedObjectPU extends ObservedPropertyAbstractPU {
4139    /**
4140     * Construct a Property of a su component that links to a variable of parent view that holds an ObservedObject
4141     * example
4142     *   this.b.$a with b of type PC and a of type C, or
4143     *   this.$b[5] with this.b of type PC and array item b[5] of type C;
4144     *
4145     * @param subscribeMe
4146     * @param propName
4147     */
4148    constructor(obsObject, owningChildView, propertyName) {
4149        super(owningChildView, propertyName);
4150        this.obsObject_ = obsObject;
4151        this.setValueInternal(obsObject);
4152    }
4153    /*
4154    like a destructor, need to call this before deleting
4155    the property.
4156    */
4157    aboutToBeDeleted() {
4158        // unregister from the ObservedObject
4159        ObservedObject.removeOwningProperty(this.obsObject_, this);
4160        super.aboutToBeDeleted();
4161    }
4162    debugInfoDecorator() {
4163        return `@ObjectLink (class SynchedPropertyNestedObjectPU)`;
4164    }
4165    objectPropertyHasChangedPU(eventSource, changedPropertyName) {
4166
4167        this.notifyPropertyHasChangedPU();
4168    }
4169    objectPropertyHasBeenReadPU(sourceObject, changedPropertyName) {
4170
4171        this.notifyPropertyHasBeenReadPU();
4172    }
4173    getUnmonitored() {
4174
4175        // unmonitored get access , no call to notifyPropertyRead !
4176        return this.obsObject_;
4177    }
4178    // get 'read through` from the ObservedProperty
4179    get() {
4180
4181        this.notifyPropertyHasBeenReadPU();
4182        return this.obsObject_;
4183    }
4184    // set 'writes through` to the ObservedProperty
4185    set(newValue) {
4186        if (this.obsObject_ === newValue) {
4187
4188            return;
4189        }
4190
4191        if (this.setValueInternal(newValue)) {
4192            // notify value change to subscribing View
4193            this.notifyPropertyHasChangedPU();
4194        }
4195    }
4196    setValueInternal(newValue) {
4197        if (!this.checkIsObject(newValue)) {
4198            return false;
4199        }
4200        if (this.obsObject_ != undefined) {
4201            if (this.obsObject_ instanceof SubscribableAbstract) {
4202                // unregister from SubscribableAbstract object
4203                this.obsObject_.removeOwningProperty(this);
4204            }
4205            else if (ObservedObject.IsObservedObject(this.obsObject_)) {
4206                // unregister from the ObservedObject
4207                ObservedObject.removeOwningProperty(this.obsObject_, this);
4208            }
4209        }
4210        this.obsObject_ = newValue;
4211        if (this.obsObject_ != undefined) {
4212            if (this.obsObject_ instanceof SubscribableAbstract) {
4213                // register to  SubscribableAbstract object
4214                this.obsObject_.addOwningProperty(this);
4215            }
4216            else if (ObservedObject.IsObservedObject(this.obsObject_)) {
4217                // register to the ObservedObject
4218                ObservedObject.addOwningProperty(this.obsObject_, this);
4219            }
4220            else {
4221                stateMgmtConsole.applicationError(`${this.debugInfo()}: set/init (method setValueInternal): assigned value is neither ObservedObject nor SubscribableAbstract. \
4222      value changes will bot be observed and UI will not update. forgot @Observed class decorator? Application error.`);
4223            }
4224        }
4225        return true;
4226    }
4227}
4228/** backward compatibility after typo in classname fix */
4229class SynchedPropertyNesedObjectPU extends SynchedPropertyNestedObjectPU {
4230}
4231/*
4232 * Copyright (c) 2023 Huawei Device Co., Ltd.
4233 * Licensed under the Apache License, Version 2.0 (the "License");
4234 * you may not use this file except in compliance with the License.
4235 * You may obtain a copy of the License at
4236 *
4237 *     http://www.apache.org/licenses/LICENSE-2.0
4238 *
4239 * Unless required by applicable law or agreed to in writing, software
4240 * distributed under the License is distributed on an "AS IS" BASIS,
4241 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4242 * See the License for the specific language governing permissions and
4243 * limitations under the License.
4244 */
4245// defined a globle function to clean up the removeItems when idle
4246function uiNodeCleanUpIdleTask() {
4247
4248    UINodeRegisterProxy.obtainDeletedElmtIds();
4249    UINodeRegisterProxy.unregisterElmtIdsFromViewPUs();
4250}
4251class UINodeRegisterProxy {
4252    constructor() {
4253        this.removeElementsInfo_ = new Array();
4254    }
4255    static obtainDeletedElmtIds() {
4256
4257        UINodeRegisterProxy.instance_.obtainDeletedElmtIds();
4258    }
4259    static unregisterElmtIdsFromViewPUs() {
4260
4261        UINodeRegisterProxy.instance_.unregisterElmtIdsFromViewPUs();
4262    }
4263    /* just get the remove items from the native side
4264    */
4265    obtainDeletedElmtIds() {
4266
4267        let removedElementsInfo = new Array();
4268        ViewStackProcessor.moveDeletedElmtIds(removedElementsInfo);
4269
4270        this.removeElementsInfo_ = removedElementsInfo;
4271    }
4272    unregisterElmtIdsFromViewPUs() {
4273
4274        if (this.removeElementsInfo_.length == 0) {
4275
4276            return;
4277        }
4278        let owningView;
4279        this.removeElementsInfo_.forEach((rmElmtInfo) => {
4280            const owningViewPUWeak = UINodeRegisterProxy.ElementIdToOwningViewPU_.get(rmElmtInfo.elmtId);
4281            if (owningViewPUWeak != undefined) {
4282                owningView = owningViewPUWeak.deref();
4283                if (owningView) {
4284                    owningView.purgeDeleteElmtId(rmElmtInfo.elmtId);
4285                }
4286                else {
4287                    stateMgmtConsole.warn(`elmtIds ${rmElmtInfo.elmtId} tag: ${rmElmtInfo.tag} has not been removed because of failure of updating the weakptr of viewpu. Internal error!.`);
4288                }
4289            }
4290            else {
4291                stateMgmtConsole.warn(`elmtIds ${rmElmtInfo.elmtId} tag: ${rmElmtInfo.tag} cannot find its owning viewpu, maybe this viewpu has already been abouttobedeleted. Internal error!`);
4292            }
4293        });
4294        this.removeElementsInfo_.length = 0;
4295    }
4296}
4297UINodeRegisterProxy.instance_ = new UINodeRegisterProxy();
4298UINodeRegisterProxy.ElementIdToOwningViewPU_ = new Map();
4299/*
4300 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
4301 * Licensed under the Apache License, Version 2.0 (the "License");
4302 * you may not use this file except in compliance with the License.
4303 * You may obtain a copy of the License at
4304 *
4305 *     http://www.apache.org/licenses/LICENSE-2.0
4306 *
4307 * Unless required by applicable law or agreed to in writing, software
4308 * distributed under the License is distributed on an "AS IS" BASIS,
4309 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4310 * See the License for the specific language governing permissions and
4311 * limitations under the License.
4312 *
4313 *  * ViewPU - View for Partial Update
4314 *
4315* all definitions in this file are framework internal
4316*/
4317// denotes a missing elemntId, this is the case during initial render
4318const UndefinedElmtId = -1;
4319// UpdateFuncRecord: misc framework-internal info related to updating of a UINode C++ object
4320// that TS side needs to know.
4321// updateFunc_  lambda function to update the UINode
4322// JS interface class reference (it only has static functions)
4323class UpdateFuncRecord {
4324    constructor(params) {
4325        this.updateFunc_ = params.updateFunc;
4326        this.classObject_ = params.classObject;
4327        this.node_ = params.node;
4328    }
4329    getUpdateFunc() {
4330        return this.updateFunc_;
4331    }
4332    getComponentClass() {
4333        return this.classObject_;
4334    }
4335    getComponentName() {
4336        return (this.classObject_ && ("name" in this.classObject_)) ? Reflect.get(this.classObject_, "name") : "unspecified UINode";
4337    }
4338    getPopFunc() {
4339        return (this.classObject_ && "pop" in this.classObject_) ? this.classObject_.pop : () => { };
4340    }
4341    getNode() {
4342        return this.node_;
4343    }
4344    setNode(node) {
4345        this.node_ = node;
4346    }
4347}
4348// NativeView
4349// implemented in C++  for release
4350// and in utest/view_native_mock.ts for testing
4351class ViewPU extends NativeViewPartialUpdate {
4352    /**
4353     * Create a View
4354     *
4355     * 1. option: top level View, specify
4356     *    - compilerAssignedUniqueChildId must specify
4357     *    - parent=undefined
4358     *    - localStorage  must provide if @LocalSTorageLink/Prop variables are used
4359     *      in this View or descendant Views.
4360     *
4361     * 2. option: not a top level View
4362     *    - compilerAssignedUniqueChildId must specify
4363     *    - parent must specify
4364     *    - localStorage do not specify, will inherit from parent View.
4365     *
4366    */
4367    constructor(parent, localStorage, elmtId = -1) {
4368        super();
4369        this.parent_ = undefined;
4370        this.childrenWeakrefMap_ = new Map();
4371        // flag for initgial rendering or re-render on-going.
4372        this.isRenderInProgress = false;
4373        // flag if active of inActive
4374        // inActive means updates are delayed
4375        this.isActive_ = true;
4376        // flag if {aboutToBeDeletedInternal} is called and the instance of ViewPU has not been GC.
4377        this.isDeleting_ = false;
4378        this.watchedProps = new Map();
4379        this.recycleManager = undefined;
4380        // Set of dependent elmtIds that need partial update
4381        // during next re-render
4382        this.dirtDescendantElementIds_ = new Set();
4383        // registry of update functions
4384        // the key is the elementId of the Component/Element that's the result of this function
4385        this.updateFuncByElmtId = new class UpdateFuncsByElmtId {
4386            constructor() {
4387                this.map_ = new Map();
4388            }
4389            delete(elmtId) {
4390                return this.map_.delete(elmtId);
4391            }
4392            set(elmtId, params) {
4393                (typeof params == "object") ?
4394                    this.map_.set(elmtId, new UpdateFuncRecord(params))
4395                    : this.map_.set(elmtId, new UpdateFuncRecord({ updateFunc: params }));
4396            }
4397            get(elmtId) {
4398                return this.map_.get(elmtId);
4399            }
4400            keys() {
4401                return this.map_.keys();
4402            }
4403            clear() {
4404                return this.map_.clear();
4405            }
4406            get size() {
4407                return this.map_.size;
4408            }
4409            forEach(callbackfn) {
4410                this.map_.forEach(callbackfn);
4411            }
4412            // dump info about known elmtIds to a string
4413            // use function only for debug output and DFX.
4414            debugInfoRegisteredElmtIds() {
4415                let result = "";
4416                let sepa = "";
4417                this.map_.forEach((value, elmtId) => {
4418                    result += `${sepa}${value.getComponentName()}[${elmtId}]`;
4419                    sepa = ", ";
4420                });
4421                return result;
4422            }
4423            debugInfoElmtId(elmtId) {
4424                const updateFuncEntry = this.map_.get(elmtId);
4425                return updateFuncEntry ? `'${updateFuncEntry.getComponentName()}[${elmtId}]'` : `'unknown component type'[${elmtId}]`;
4426            }
4427        };
4428        // set of all @Local/StorageLink/Prop variables owned by this ViwPU
4429        this.ownStorageLinksProps_ = new Set();
4430        // my LocalStorage instance, shared with ancestor Views.
4431        // create a default instance on demand if none is initialized
4432        this.localStoragebackStore_ = undefined;
4433        // if set use the elmtId also as the ViewPU object's subscribable id.
4434        // these matching is requiremrnt for updateChildViewById(elmtId) being able to
4435        // find the child ViewPU object by given elmtId
4436        this.id_ = elmtId == -1 ? SubscriberManager.MakeId() : elmtId;
4437        this.providedVars_ = parent ? new Map(parent.providedVars_)
4438            : new Map();
4439        this.localStoragebackStore_ = undefined;
4440
4441        if (parent) {
4442            // this View is not a top-level View
4443            this.setCardId(parent.getCardId());
4444            // Call below will set this.parent_ to parent as well
4445            parent.addChild(this);
4446        }
4447        else if (localStorage) {
4448            this.localStorage_ = localStorage;
4449
4450        }
4451        SubscriberManager.Add(this);
4452
4453    }
4454    get ownObservedPropertiesStore_() {
4455        if (!this.ownObservedPropertiesStore__) {
4456            // lazy init
4457            this.ownObservedPropertiesStore__ = new Set();
4458            this.obtainOwnObservedProperties();
4459        }
4460        return this.ownObservedPropertiesStore__;
4461    }
4462    obtainOwnObservedProperties() {
4463        Object.getOwnPropertyNames(this)
4464            .filter((propName) => {
4465            return propName.startsWith("__");
4466        })
4467            .forEach((propName) => {
4468            const stateVar = Reflect.get(this, propName);
4469            if ("notifyPropertyHasChangedPU" in stateVar) {
4470
4471                this.ownObservedPropertiesStore_.add(stateVar);
4472            }
4473        });
4474    }
4475    get localStorage_() {
4476        if (!this.localStoragebackStore_ && this.parent_) {
4477
4478            this.localStoragebackStore_ = this.parent_.localStorage_;
4479        }
4480        if (!this.localStoragebackStore_) {
4481
4482            this.localStoragebackStore_ = new LocalStorage({ /* empty */});
4483        }
4484        return this.localStoragebackStore_;
4485    }
4486    set localStorage_(instance) {
4487        if (!instance) {
4488            // setting to undefined not allowed
4489            return;
4490        }
4491        if (this.localStoragebackStore_) {
4492            stateMgmtConsole.applicationError(`${this.debugInfo()}: constructor: is setting LocalStorage instance twice. Application error.`);
4493        }
4494        this.localStoragebackStore_ = instance;
4495    }
4496    // globally unique id, this is different from compilerAssignedUniqueChildId!
4497    id__() {
4498        return this.id_;
4499    }
4500    updateId(elmtId) {
4501        this.id_ = elmtId;
4502    }
4503    // super class will call this function from
4504    // its aboutToBeDeleted implementation
4505    aboutToBeDeletedInternal() {
4506
4507        // tell UINodeRegisterProxy that all elmtIds under
4508        // this ViewPU should be treated as already unregistered
4509
4510        // purge the elementids owning by this viewpu from the updateFuncByElmtId and also the state variable dependent elementids
4511        Array.from(this.updateFuncByElmtId.keys()).forEach((elemId) => {
4512            this.purgeDeleteElmtId(elemId);
4513        });
4514        if (this.hasRecycleManager()) {
4515            this.getRecycleManager().purgeAllCachedRecycleNode();
4516        }
4517        // unregistration of ElementIDs
4518
4519        // it will unregister removed elementids from all the viewpu, equals purgeDeletedElmtIdsRecursively
4520        this.purgeDeletedElmtIds();
4521
4522        this.updateFuncByElmtId.clear();
4523        this.watchedProps.clear();
4524        this.providedVars_.clear();
4525        this.ownStorageLinksProps_.clear();
4526        if (this.parent_) {
4527            this.parent_.removeChild(this);
4528        }
4529        this.localStoragebackStore_ = undefined;
4530        this.isDeleting_ = true;
4531    }
4532    purgeDeleteElmtId(rmElmtId) {
4533
4534        const result = this.updateFuncByElmtId.delete(rmElmtId);
4535        if (result) {
4536            this.purgeVariableDependenciesOnElmtIdOwnFunc(rmElmtId);
4537            // it means rmElmtId has finished all the unregistration from the js side, ElementIdToOwningViewPU_  does not need to keep it
4538            UINodeRegisterProxy.ElementIdToOwningViewPU_.delete(rmElmtId);
4539        }
4540        return result;
4541    }
4542    debugInfo() {
4543        return `@Component '${this.constructor.name}'[${this.id__()}]`;
4544    }
4545    // dump info about known elmtIds to a string
4546    // use function only for debug output and DFX.
4547    debugInfoRegisteredElmtIds() {
4548        return this.updateFuncByElmtId.debugInfoRegisteredElmtIds();
4549    }
4550    // for given elmtIds look up their component name/type and format a string out of this info
4551    // use function only for debug output and DFX.
4552    debugInfoElmtIds(elmtIds) {
4553        let result = "";
4554        let sepa = "";
4555        elmtIds.forEach((elmtId) => {
4556            result += `${sepa}${this.debugInfoElmtId(elmtId)}`;
4557            sepa = ", ";
4558        });
4559        return result;
4560    }
4561    debugInfoElmtId(elmtId) {
4562        return this.updateFuncByElmtId.debugInfoElmtId(elmtId);
4563    }
4564    dumpStateVars() {
4565
4566        Object.getOwnPropertyNames(this)
4567            .filter((varName) => varName.startsWith("__"))
4568            .forEach((varName) => {
4569            const prop = Reflect.get(this, varName);
4570            const observedProp = prop;
4571            if ("debugInfoDecorator" in prop) {
4572
4573
4574
4575            }
4576        });
4577    }
4578    /**
4579   * ArkUI engine will call this function when the corresponding CustomNode's active status change.
4580   * @param active true for active, false for inactive
4581   */
4582    setActiveInternal(active) {
4583        if (this.isActive_ == active) {
4584
4585            return;
4586        }
4587
4588        this.isActive_ = active;
4589        if (this.isActive_) {
4590            this.onActiveInternal();
4591        }
4592        else {
4593            this.onInactiveInternal();
4594        }
4595    }
4596    onActiveInternal() {
4597        if (!this.isActive_) {
4598            return;
4599        }
4600
4601        this.performDelayedUpdate();
4602        for (const child of this.childrenWeakrefMap_.values()) {
4603            const childViewPU = child.deref();
4604            if (childViewPU) {
4605                childViewPU.setActiveInternal(this.isActive_);
4606            }
4607        }
4608    }
4609    onInactiveInternal() {
4610        if (this.isActive_) {
4611            return;
4612        }
4613
4614        for (const storageProp of this.ownStorageLinksProps_) {
4615            storageProp.enableDelayedNotification();
4616        }
4617        for (const child of this.childrenWeakrefMap_.values()) {
4618            const childViewPU = child.deref();
4619            if (childViewPU) {
4620                childViewPU.setActiveInternal(this.isActive_);
4621            }
4622        }
4623    }
4624    setParent(parent) {
4625        if (this.parent_ && parent) {
4626            stateMgmtConsole.warn(`${this.debugInfo()}: setChild: changing parent to '${parent === null || parent === void 0 ? void 0 : parent.debugInfo()} (unsafe operation)`);
4627        }
4628        this.parent_ = parent;
4629    }
4630    /**
4631     * add given child and set 'this' as its parent
4632     * @param child child to add
4633     * @returns returns false if child with given child's id already exists
4634     *
4635     * framework internal function
4636     * Note: Use of WeakRef ensures child and parent do not generate a cycle dependency.
4637     * The add. Set<ids> is required to reliably tell what children still exist.
4638     */
4639    addChild(child) {
4640        if (this.childrenWeakrefMap_.has(child.id__())) {
4641            stateMgmtConsole.warn(`${this.debugInfo()}: addChild '${child === null || child === void 0 ? void 0 : child.debugInfo()}' id already exists ${child.id__()}. Internal error!`);
4642            return false;
4643        }
4644        this.childrenWeakrefMap_.set(child.id__(), new WeakRef(child));
4645        child.setParent(this);
4646        return true;
4647    }
4648    /**
4649     * remove given child and remove 'this' as its parent
4650     * @param child child to add
4651     * @returns returns false if child with given child's id does not exist
4652     */
4653    removeChild(child) {
4654        const hasBeenDeleted = this.childrenWeakrefMap_.delete(child.id__());
4655        if (!hasBeenDeleted) {
4656            stateMgmtConsole.warn(`${this.debugInfo()}: removeChild '${child === null || child === void 0 ? void 0 : child.debugInfo()}', child id ${child.id__()} not known. Internal error!`);
4657        }
4658        else {
4659            child.setParent(undefined);
4660        }
4661        return hasBeenDeleted;
4662    }
4663    /**
4664     * Retrieve child by given id
4665     * @param id
4666     * @returns child if in map and weak ref can still be downreferenced
4667     */
4668    getChildById(id) {
4669        const childWeakRef = this.childrenWeakrefMap_.get(id);
4670        return childWeakRef ? childWeakRef.deref() : undefined;
4671    }
4672    updateStateVars(params) {
4673        stateMgmtConsole.error(`${this.debugInfo()}: updateStateVars unimplemented. Pls upgrade to latest eDSL transpiler version. Application error.`);
4674    }
4675    initialRenderView() {
4676        this.isRenderInProgress = true;
4677        this.initialRender();
4678        this.isRenderInProgress = false;
4679    }
4680    UpdateElement(elmtId) {
4681        if (elmtId == this.id__()) {
4682            // do not attempt to update itself.
4683            // a @Prop can add a dependency of the ViewPU onto itself. Ignore it.
4684            return;
4685        }
4686        // do not process an Element that has been marked to be deleted
4687        const entry = this.updateFuncByElmtId.get(elmtId);
4688        const updateFunc = entry ? entry.getUpdateFunc() : undefined;
4689        if ((updateFunc == undefined) || (typeof updateFunc !== "function")) {
4690            stateMgmtConsole.error(`${this.debugInfo()}: update function of elmtId ${elmtId} not found, internal error!`);
4691        }
4692        else {
4693            const componentName = entry.getComponentName();
4694
4695            this.isRenderInProgress = true;
4696            updateFunc(elmtId, /* isFirstRender */ false);
4697            // continue in native JSView
4698            // Finish the Update in JSView::JsFinishUpdateFunc
4699            // this function appends no longer used elmtIds (as receded by VSP) to the given allRmElmtIds array
4700            this.finishUpdateFunc(elmtId);
4701            this.isRenderInProgress = false;
4702
4703        }
4704    }
4705    /**
4706     * force a complete rerender / update by executing all update functions
4707     * exec a regular rerender first
4708     *
4709     * @param deep recurse all children as well
4710     *
4711     * framework internal functions, apps must not call
4712     */
4713    forceCompleteRerender(deep = false) {
4714        stateMgmtConsole.warn(`${this.debugInfo()}: forceCompleteRerender - start.`);
4715        // see which elmtIds are managed by this View
4716        // and clean up all book keeping for them
4717        this.purgeDeletedElmtIds();
4718        Array.from(this.updateFuncByElmtId.keys()).sort(ViewPU.compareNumber).forEach(elmtId => this.UpdateElement(elmtId));
4719        if (deep) {
4720            this.childrenWeakrefMap_.forEach((weakRefChild) => {
4721                const child = weakRefChild.deref();
4722                if (child) {
4723                    child.forceCompleteRerender(true);
4724                }
4725            });
4726        }
4727        stateMgmtConsole.warn(`${this.debugInfo()}: forceCompleteRerender - end`);
4728    }
4729    /**
4730     * force a complete rerender / update on specific node by executing update function.
4731     *
4732     * @param elmtId which node needs to update.
4733     *
4734     * framework internal functions, apps must not call
4735     */
4736    forceRerenderNode(elmtId) {
4737        // see which elmtIds are managed by this View
4738        // and clean up all book keeping for them
4739        this.purgeDeletedElmtIds();
4740        this.UpdateElement(elmtId);
4741        // remove elemtId from dirtDescendantElementIds.
4742        this.dirtDescendantElementIds_.delete(elmtId);
4743    }
4744    updateStateVarsOfChildByElmtId(elmtId, params) {
4745
4746        if (elmtId < 0) {
4747            stateMgmtConsole.warn(`${this.debugInfo()}: updateChildViewById(${elmtId}) - invalid elmtId - internal error!`);
4748            return;
4749        }
4750        let child = this.getChildById(elmtId);
4751        if (!child) {
4752            stateMgmtConsole.warn(`${this.debugInfo()}: updateChildViewById(${elmtId}) - no child with this elmtId - internal error!`);
4753            return;
4754        }
4755        child.updateStateVars(params);
4756
4757    }
4758    // implements IMultiPropertiesChangeSubscriber
4759    viewPropertyHasChanged(varName, dependentElmtIds) {
4760        stateMgmtTrace.scopedTrace(() => {
4761            if (this.isRenderInProgress) {
4762                stateMgmtConsole.applicationError(`${this.debugInfo()}: State variable '${varName}' has changed during render! It's illegal to change @Component state while build (initial render or re-render) is on-going. Application error!`);
4763            }
4764            this.syncInstanceId();
4765            if (dependentElmtIds.size && !this.isFirstRender()) {
4766                if (!this.dirtDescendantElementIds_.size) {
4767                    // mark ComposedElement dirty when first elmtIds are added
4768                    // do not need to do this every time
4769                    this.markNeedUpdate();
4770                }
4771
4772                for (const elmtId of dependentElmtIds) {
4773                    this.dirtDescendantElementIds_.add(elmtId);
4774                }
4775
4776            }
4777            else {
4778
4779
4780            }
4781            let cb = this.watchedProps.get(varName);
4782            if (cb) {
4783
4784                cb.call(this, varName);
4785            }
4786            this.restoreInstanceId();
4787        }, "ViewPU.viewPropertyHasChanged", this.constructor.name, varName, dependentElmtIds.size);
4788    }
4789    performDelayedUpdate() {
4790        stateMgmtTrace.scopedTrace(() => {
4791
4792            this.syncInstanceId();
4793            for (const storageProp of this.ownStorageLinksProps_) {
4794                const changedElmtIds = storageProp.moveElmtIdsForDelayedUpdate();
4795                if (changedElmtIds) {
4796                    const varName = storageProp.info();
4797                    if (changedElmtIds.size && !this.isFirstRender()) {
4798                        for (const elmtId of changedElmtIds) {
4799                            this.dirtDescendantElementIds_.add(elmtId);
4800                        }
4801                    }
4802
4803                    const cb = this.watchedProps.get(varName);
4804                    if (cb) {
4805
4806                        cb.call(this, varName);
4807                    }
4808                }
4809            } // for all ownStorageLinksProps_
4810            this.restoreInstanceId();
4811            if (this.dirtDescendantElementIds_.size) {
4812                this.markNeedUpdate();
4813            }
4814        }, "ViewPU.performDelayedUpdate", this.constructor.name);
4815    }
4816    /**
4817     * Function to be called from the constructor of the sub component
4818     * to register a @Watch varibale
4819     * @param propStr name of the variable. Note from @Provide and @Consume this is
4820     *      the variable name and not the alias!
4821     * @param callback application defined member function of sub-class
4822     */
4823    declareWatch(propStr, callback) {
4824        this.watchedProps.set(propStr, callback);
4825    }
4826    /**
4827     * This View @Provide's a variable under given name
4828     * Call this function from the constructor of the sub class
4829     * @param providedPropName either the variable name or the alias defined as
4830     *        decorator param
4831     * @param store the backing store object for this variable (not the get/set variable!)
4832     */
4833    addProvidedVar(providedPropName, store) {
4834        if (this.providedVars_.has(providedPropName)) {
4835            throw new ReferenceError(`${this.constructor.name}: duplicate @Provide property with name ${providedPropName}.
4836      Property with this name is provided by one of the ancestor Views already.`);
4837        }
4838        this.providedVars_.set(providedPropName, store);
4839    }
4840    /**
4841     * Method for the sub-class to call from its constructor for resolving
4842     *       a @Consume variable and initializing its backing store
4843     *       with the SyncedPropertyTwoWay<T> object created from the
4844     *       @Provide variable's backing store.
4845     * @param providedPropName the name of the @Provide'd variable.
4846     *     This is either the @Consume decorator parameter, or variable name.
4847     * @param consumeVarName the @Consume variable name (not the
4848     *            @Consume decorator parameter)
4849     * @returns initializing value of the @Consume backing store
4850     */
4851    initializeConsume(providedPropName, consumeVarName) {
4852        let providedVarStore = this.providedVars_.get(providedPropName);
4853        if (providedVarStore === undefined) {
4854            throw new ReferenceError(`${this.debugInfo()} missing @Provide property with name ${providedPropName}.
4855          Fail to resolve @Consume(${providedPropName}).`);
4856        }
4857        const factory = (source) => {
4858            const result = ((source instanceof ObservedPropertySimple) || (source instanceof ObservedPropertySimplePU))
4859                ? new SynchedPropertyObjectTwoWayPU(source, this, consumeVarName)
4860                : new SynchedPropertyObjectTwoWayPU(source, this, consumeVarName);
4861            stateMgmtConsole.error(`${this.debugInfo()}: The @Consume is instance of ${result.constructor.name}`);
4862            return result;
4863        };
4864        return providedVarStore.createSync(factory);
4865    }
4866    /**
4867     * given the elmtId of a child or child of child within this custom component
4868     * remember this component needs a partial update
4869     * @param elmtId
4870     */
4871    markElemenDirtyById(elmtId) {
4872        // TODO ace-ets2bundle, framework, compilated apps need to update together
4873        // this function will be removed after a short transiition periode
4874        stateMgmtConsole.applicationError(`${this.debugInfo()}: markElemenDirtyById no longer supported.
4875        Please update your ace-ets2bundle and recompile your application. Application error!`);
4876    }
4877    /**
4878     * For each recorded dirty Element in this custom component
4879     * run its update function
4880     *
4881     */
4882    updateDirtyElements() {
4883        do {
4884
4885            // see which elmtIds are managed by this View
4886            // and clean up all book keeping for them
4887            this.purgeDeletedElmtIds();
4888            // process all elmtIds marked as needing update in ascending order.
4889            // ascending order ensures parent nodes will be updated before their children
4890            // prior cleanup ensure no already deleted Elements have their update func executed
4891            Array.from(this.dirtDescendantElementIds_).sort(ViewPU.compareNumber).forEach(elmtId => {
4892                this.UpdateElement(elmtId);
4893                this.dirtDescendantElementIds_.delete(elmtId);
4894            });
4895            if (this.dirtDescendantElementIds_.size) {
4896                stateMgmtConsole.applicationError(`${this.debugInfo()}: New UINode objects added to update queue while re-render! - Likely caused by @Component state change during build phase, not allowed. Application error!`);
4897            }
4898        } while (this.dirtDescendantElementIds_.size);
4899
4900        this.dumpStateVars();
4901    }
4902    // request list of all (global) elmtIds of deleted UINodes and unregister from the all viewpus
4903    // this function equals purgeDeletedElmtIdsRecursively because it does unregistration for all viewpus
4904    purgeDeletedElmtIds() {
4905
4906        // request list of all (global) elmtIds of deleted UINodes that need to be unregistered
4907        UINodeRegisterProxy.obtainDeletedElmtIds();
4908        // unregister the removed elementids requested from the cpp side for all viewpus, it will make the first viewpu slower
4909        // than before, but the rest viewpu will be faster
4910        UINodeRegisterProxy.unregisterElmtIdsFromViewPUs();
4911
4912    }
4913    purgeVariableDependenciesOnElmtIdOwnFunc(elmtId) {
4914        this.ownObservedPropertiesStore_.forEach((stateVar) => {
4915            stateVar.purgeDependencyOnElmtId(elmtId);
4916        });
4917    }
4918    // executed on first render only
4919    // kept for backward compatibility with old ace-ets2bundle
4920    observeComponentCreation(compilerAssignedUpdateFunc) {
4921        const updateFunc = (elmtId, isFirstRender) => {
4922
4923            compilerAssignedUpdateFunc(elmtId, isFirstRender);
4924
4925        };
4926        const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
4927        // in observeComponentCreation function we do not get info about the component name, in
4928        // observeComponentCreation2 we do.
4929        this.updateFuncByElmtId.set(elmtId, { updateFunc: updateFunc });
4930        // add element id -> owningviewpu
4931        UINodeRegisterProxy.ElementIdToOwningViewPU_.set(elmtId, new WeakRef(this));
4932        updateFunc(elmtId, /* is first render */ true);
4933
4934    }
4935    // executed on first render only
4936    // added July 2023, replaces observeComponentCreation
4937    // classObject is the ES6 class object , mandatory to specify even the class lacks the pop function.
4938    // - prototype : Object is present for every ES6 class
4939    // - pop : () => void, static function present for JSXXX classes such as Column, TapGesture, etc.
4940    observeComponentCreation2(compilerAssignedUpdateFunc, classObject) {
4941        const _componentName = (classObject && ("name" in classObject)) ? Reflect.get(classObject, "name") : "unspecified UINode";
4942        const _popFunc = (classObject && "pop" in classObject) ? classObject.pop : () => { };
4943        const updateFunc = (elmtId, isFirstRender) => {
4944
4945            ViewStackProcessor.StartGetAccessRecordingFor(elmtId);
4946            compilerAssignedUpdateFunc(elmtId, isFirstRender);
4947            if (!isFirstRender) {
4948                _popFunc();
4949            }
4950            ViewStackProcessor.StopGetAccessRecording();
4951
4952        };
4953        const elmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
4954        this.updateFuncByElmtId.set(elmtId, { updateFunc: updateFunc, classObject: classObject });
4955        // add element id -> owningviewpu
4956        UINodeRegisterProxy.ElementIdToOwningViewPU_.set(elmtId, new WeakRef(this));
4957        updateFunc(elmtId, /* is first render */ true);
4958
4959    }
4960    getOrCreateRecycleManager() {
4961        if (!this.recycleManager) {
4962            this.recycleManager = new RecycleManager;
4963        }
4964        return this.recycleManager;
4965    }
4966    getRecycleManager() {
4967        return this.recycleManager;
4968    }
4969    hasRecycleManager() {
4970        return !(this.recycleManager === undefined);
4971    }
4972    initRecycleManager() {
4973        if (this.recycleManager) {
4974            stateMgmtConsole.error(`${this.debugInfo()}: init recycleManager multiple times. Internal error.`);
4975            return;
4976        }
4977        this.recycleManager = new RecycleManager;
4978    }
4979    /**
4980     * @function observeRecycleComponentCreation
4981     * @description custom node recycle creation
4982     * @param name custom node name
4983     * @param recycleUpdateFunc custom node recycle update which can be converted to a normal update function
4984     * @return void
4985     */
4986    observeRecycleComponentCreation(name, recycleUpdateFunc) {
4987        // convert recycle update func to update func
4988        const compilerAssignedUpdateFunc = (element, isFirstRender) => {
4989            recycleUpdateFunc(element, isFirstRender, undefined);
4990        };
4991        let node;
4992        // if there is no suitable recycle node, run a normal creation function.
4993        if (!this.hasRecycleManager() || !(node = this.getRecycleManager().popRecycleNode(name))) {
4994
4995            this.observeComponentCreation(compilerAssignedUpdateFunc);
4996            return;
4997        }
4998        // if there is a suitable recycle node, run a recycle update function.
4999        const newElmtId = ViewStackProcessor.AllocateNewElmetIdForNextComponent();
5000        const oldElmtId = node.id__();
5001        // store the current id and origin id, used for dirty element sort in {compareNumber}
5002        recycleUpdateFunc(newElmtId, /* is first render */ true, node);
5003        const oldEntry = this.updateFuncByElmtId.get(oldElmtId);
5004        this.updateFuncByElmtId.delete(oldElmtId);
5005        this.updateFuncByElmtId.set(newElmtId, {
5006            updateFunc: compilerAssignedUpdateFunc,
5007            classObject: oldEntry && oldEntry.getComponentClass(),
5008            node: oldEntry && oldEntry.getNode()
5009        });
5010        node.updateId(newElmtId);
5011        node.updateRecycleElmtId(oldElmtId, newElmtId);
5012        SubscriberManager.UpdateRecycleElmtId(oldElmtId, newElmtId);
5013    }
5014    // add current JS object to it's parent recycle manager
5015    recycleSelf(name) {
5016        if (this.parent_ && !this.parent_.isDeleting_) {
5017            this.parent_.getOrCreateRecycleManager().pushRecycleNode(name, this);
5018        }
5019        else {
5020            this.resetRecycleCustomNode();
5021            stateMgmtConsole.error(`${this.constructor.name}[${this.id__()}]: recycleNode must have a parent`);
5022        }
5023    }
5024    // performs the update on a branch within if() { branch } else if (..) { branch } else { branch }
5025    ifElseBranchUpdateFunction(branchId, branchfunc) {
5026        const oldBranchid = If.getBranchId();
5027        if (branchId == oldBranchid) {
5028
5029            return;
5030        }
5031        // branchid identifies uniquely the if .. <1> .. else if .<2>. else .<3>.branch
5032        // ifElseNode stores the most recent branch, so we can compare
5033        // removedChildElmtIds will be filled with the elmtIds of all childten and their children will be deleted in response to if .. else chnage
5034        let removedChildElmtIds = new Array();
5035        If.branchId(branchId, removedChildElmtIds);
5036        // purging these elmtIds from state mgmt will make sure no more update function on any deleted child wi;ll be executed
5037
5038        this.purgeDeletedElmtIds();
5039        branchfunc();
5040    }
5041    /**
5042     Partial updates for ForEach.
5043     * @param elmtId ID of element.
5044     * @param itemArray Array of items for use of itemGenFunc.
5045     * @param itemGenFunc Item generation function to generate new elements. If index parameter is
5046     *                    given set itemGenFuncUsesIndex to true.
5047     * @param idGenFunc   ID generation function to generate unique ID for each element. If index parameter is
5048     *                    given set idGenFuncUsesIndex to true.
5049     * @param itemGenFuncUsesIndex itemGenFunc optional index parameter is given or not.
5050     * @param idGenFuncUsesIndex idGenFunc optional index parameter is given or not.
5051     */
5052    forEachUpdateFunction(elmtId, itemArray, itemGenFunc, idGenFunc, itemGenFuncUsesIndex = false, idGenFuncUsesIndex = false) {
5053
5054        if (itemArray === null || itemArray === undefined) {
5055            stateMgmtConsole.applicationError(`${this.debugInfo()}: forEachUpdateFunction (ForEach re-render): input array is null or undefined error. Application error!`);
5056            return;
5057        }
5058        if (itemGenFunc === null || itemGenFunc === undefined) {
5059            stateMgmtConsole.applicationError(`${this.debugInfo()}: forEachUpdateFunction (ForEach re-render): Item generation function missing. Application error!`);
5060            return;
5061        }
5062        if (idGenFunc === undefined) {
5063
5064            idGenFuncUsesIndex = true;
5065            // catch possible error caused by Stringify and re-throw an Error with a meaningful (!) error message
5066            idGenFunc = (item, index) => {
5067                try {
5068                    return `${index}__${JSON.stringify(item)}`;
5069                }
5070                catch (e) {
5071                    throw new Error(`${this.debugInfo()}: ForEach id ${elmtId}: use of default id generator function not possible on provided data structure. Need to specify id generator function (ForEach 3rd parameter). Application Error!`);
5072                }
5073            };
5074        }
5075        let diffIndexArray = []; // New indexes compared to old one.
5076        let newIdArray = [];
5077        let idDuplicates = [];
5078        const arr = itemArray; // just to trigger a 'get' onto the array
5079        // ID gen is with index.
5080        if (idGenFuncUsesIndex) {
5081            // Create array of new ids.
5082            arr.forEach((item, indx) => {
5083                newIdArray.push(idGenFunc(item, indx));
5084            });
5085        }
5086        else {
5087            // Create array of new ids.
5088            arr.forEach((item, index) => {
5089                newIdArray.push(`${itemGenFuncUsesIndex ? index + '_' : ''}` + idGenFunc(item));
5090            });
5091        }
5092        // Set new array on C++ side.
5093        // C++ returns array of indexes of newly added array items.
5094        // these are indexes in new child list.
5095        ForEach.setIdArray(elmtId, newIdArray, diffIndexArray, idDuplicates);
5096        // Its error if there are duplicate IDs.
5097        if (idDuplicates.length > 0) {
5098            idDuplicates.forEach((indx) => {
5099                stateMgmtConsole.error(`Error: ${newIdArray[indx]} generated for ${indx}${indx < 4 ? indx == 2 ? "nd" : "rd" : "th"} array item ${arr[indx]}.`);
5100            });
5101            stateMgmtConsole.applicationError(`${this.debugInfo()}: Ids generated by the ForEach id gen function must be unique. Application error!`);
5102        }
5103
5104        // Item gen is with index.
5105
5106        // Create new elements if any.
5107        diffIndexArray.forEach((indx) => {
5108            ForEach.createNewChildStart(newIdArray[indx], this);
5109            if (itemGenFuncUsesIndex) {
5110                itemGenFunc(arr[indx], indx);
5111            }
5112            else {
5113                itemGenFunc(arr[indx]);
5114            }
5115            ForEach.createNewChildFinish(newIdArray[indx], this);
5116        });
5117
5118    }
5119    /**
5120       * CreateStorageLink and CreateStorageLinkPU are used by the implementation of @StorageLink and
5121       * @LocalStotrageLink in full update and partial update solution respectively.
5122       * These are not part of the public AppStorage API , apps should not use.
5123       * @param storagePropName - key in LocalStorage
5124       * @param defaultValue - value to use when creating a new prop in the LocalStotage
5125       * @param owningView - the View/ViewPU owning the @StorageLink/@LocalStorageLink variable
5126       * @param viewVariableName -  @StorageLink/@LocalStorageLink variable name
5127       * @returns SynchedPropertySimple/ObjectTwoWay/PU
5128       */
5129    createStorageLink(storagePropName, defaultValue, viewVariableName) {
5130        const appStorageLink = AppStorage.__createSync(storagePropName, defaultValue, (source) => (source === undefined)
5131            ? undefined
5132            : (source instanceof ObservedPropertySimple)
5133                ? new SynchedPropertyObjectTwoWayPU(source, this, viewVariableName)
5134                : new SynchedPropertyObjectTwoWayPU(source, this, viewVariableName));
5135        this.ownStorageLinksProps_.add(appStorageLink);
5136        return appStorageLink;
5137    }
5138    createStorageProp(storagePropName, defaultValue, viewVariableName) {
5139        const appStorageProp = AppStorage.__createSync(storagePropName, defaultValue, (source) => (source === undefined)
5140            ? undefined
5141            : (source instanceof ObservedPropertySimple)
5142                ? new SynchedPropertyObjectOneWayPU(source, this, viewVariableName)
5143                : new SynchedPropertyObjectOneWayPU(source, this, viewVariableName));
5144        this.ownStorageLinksProps_.add(appStorageProp);
5145        return appStorageProp;
5146    }
5147    createLocalStorageLink(storagePropName, defaultValue, viewVariableName) {
5148        const localStorageLink = this.localStorage_.__createSync(storagePropName, defaultValue, (source) => (source === undefined)
5149            ? undefined
5150            : (source instanceof ObservedPropertySimple)
5151                ? new SynchedPropertyObjectTwoWayPU(source, this, viewVariableName)
5152                : new SynchedPropertyObjectTwoWayPU(source, this, viewVariableName));
5153        this.ownStorageLinksProps_.add(localStorageLink);
5154        return localStorageLink;
5155    }
5156    createLocalStorageProp(storagePropName, defaultValue, viewVariableName) {
5157        const localStorageProp = this.localStorage_.__createSync(storagePropName, defaultValue, (source) => (source === undefined)
5158            ? undefined
5159            : (source instanceof ObservedPropertySimple)
5160                ? new SynchedPropertyObjectOneWayPU(source, this, viewVariableName)
5161                : new SynchedPropertyObjectOneWayPU(source, this, viewVariableName));
5162        this.ownStorageLinksProps_.add(localStorageProp);
5163        return localStorageProp;
5164    }
5165}
5166// Array.sort() converts array items to string to compare them, sigh!
5167ViewPU.compareNumber = (a, b) => {
5168    return (a < b) ? -1 : (a > b) ? 1 : 0;
5169};
5170/*
5171 * Copyright (c) 2023 Huawei Device Co., Ltd.
5172 * Licensed under the Apache License, Version 2.0 (the "License");
5173 * you may not use this file except in compliance with the License.
5174 * You may obtain a copy of the License at
5175 *
5176 *     http://www.apache.org/licenses/LICENSE-2.0
5177 *
5178 * Unless required by applicable law or agreed to in writing, software
5179 * distributed under the License is distributed on an "AS IS" BASIS,
5180 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5181 * See the License for the specific language governing permissions and
5182 * limitations under the License.
5183 *
5184 *  * RecycleManager - Recycle cache manager
5185 *
5186* all definitions in this file are framework internal
5187*/
5188/**
5189 * @class RecycleManager
5190 * @description manage the JS object cached of current node
5191 */
5192class RecycleManager {
5193    constructor() {
5194        // key: recycle node name
5195        // value: recycle node JS object
5196        this.cachedRecycleNodes = undefined;
5197        this.cachedRecycleNodes = new Map();
5198    }
5199    pushRecycleNode(name, node) {
5200        var _a;
5201        if (!this.cachedRecycleNodes.get(name)) {
5202            this.cachedRecycleNodes.set(name, new Array());
5203        }
5204        (_a = this.cachedRecycleNodes.get(name)) === null || _a === void 0 ? void 0 : _a.push(node);
5205    }
5206    popRecycleNode(name) {
5207        var _a;
5208        return (_a = this.cachedRecycleNodes.get(name)) === null || _a === void 0 ? void 0 : _a.pop();
5209    }
5210    // When parent JS View is deleted, release all cached nodes
5211    purgeAllCachedRecycleNode() {
5212        this.cachedRecycleNodes.forEach((nodes, _) => {
5213            nodes.forEach((node) => {
5214                node.resetRecycleCustomNode();
5215            });
5216        });
5217        this.cachedRecycleNodes.clear();
5218    }
5219}
5220/*
5221 * Copyright (c) 2022 Huawei Device Co., Ltd.
5222 * Licensed under the Apache License, Version 2.0 (the "License");
5223 * you may not use this file except in compliance with the License.
5224 * You may obtain a copy of the License at
5225 *
5226 *     http://www.apache.org/licenses/LICENSE-2.0
5227 *
5228 * Unless required by applicable law or agreed to in writing, software
5229 * distributed under the License is distributed on an "AS IS" BASIS,
5230 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5231 * See the License for the specific language governing permissions and
5232 * limitations under the License.
5233 *
5234 *  * ViewPU - View for Partial Update
5235 *
5236* all definitions in this file are framework internal
5237*/
5238/**
5239    given parameters for calling a @Builder function
5240    this function wraps the Object of type T inside a ES6 Proxy.
5241    Each param, i.e. Object property is either a function or a value.
5242    If it is a function the function can either return a value of expected
5243    parameter type or an ObservedPropertyabstract<T> where T is the exected
5244    parameter type. The latter is the case when passing a state variable by
5245    reference.
5246
5247    Two purposes:
5248    1 - @Builder function boxy accesses params a '$$.paramA'
5249        However paramA can be a function, so to obtain the value the
5250        access would need to be '$$.param()' The proxy executes
5251        the function and return s the result
5252    2 - said function returns to ObservedPropertyAbstract backing store of
5253        a calling @Component state variable (whenever the state var is
5254        provided to the @Builder function). For this case the proxy can provide
5255        - the value by executing paramA() to return the ObservedPropertyAbstract
5256          and further (monitored!) get() to read its value
5257        - when requested to return '__param1' it returns the ObservedPropertyAbstract
5258          object. The scenario is to use to init a @Link source.
5259  */
5260function makeBuilderParameterProxy(builderName, source) {
5261    return new Proxy(source, {
5262        set(target, prop, val) {
5263            throw Error(`@Builder '${builderName}': Invalid attempt to set(write to) parameter '${prop.toString()}' error!`);
5264        },
5265        get(target, prop) {
5266            const prop1 = prop.toString().trim().startsWith("__")
5267                ? prop.toString().trim().substring(2)
5268                : prop.toString().trim();
5269
5270            if (!(typeof target === "object") && (prop1 in target)) {
5271                throw Error(`@Builder '${builderName}': '${prop1}' used but not a function parameter error!`);
5272            }
5273            const value = target[prop1];
5274            if (typeof value !== "function") {
5275
5276                return value;
5277            }
5278            const funcRet = value();
5279            if ((typeof funcRet === "object") && ('get' in funcRet)) {
5280                if (prop1 !== prop) {
5281
5282                    return funcRet;
5283                }
5284                else {
5285
5286                    const result = funcRet.get();
5287
5288                    return result;
5289                }
5290            }
5291
5292            return funcRet;
5293        } // get
5294    }); // new Proxy
5295}
5296/*
5297 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
5298 * Licensed under the Apache License, Version 2.0 (the "License");
5299 * you may not use this file except in compliance with the License.
5300 * You may obtain a copy of the License at
5301 *
5302 *     http://www.apache.org/licenses/LICENSE-2.0
5303 *
5304 * Unless required by applicable law or agreed to in writing, software
5305 * distributed under the License is distributed on an "AS IS" BASIS,
5306 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5307 * See the License for the specific language governing permissions and
5308 * limitations under the License.
5309 */
5310
5311PersistentStorage.configureBackend(new Storage());
5312Environment.configureBackend(new EnvironmentSetting());
5313
5314