All files / custom-element/mixins StateMetadataInitializerMixin.ts

100% Statements 22/22
80% Branches 16/20
100% Functions 6/6
100% Lines 21/21

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82    25x                         77x   77x   8x   8x           15x       7x               8x         77x   77x   77x   77x   5x                     77x   77x   77x   669x   3x     669x     77x       15x
import { CustomElementMetadata, CustomElementStateMetadata } from "../interfaces";
 
const StateMetadataInitializerMixin = Base =>
 
    class StateMetadataInitializer extends Base {
 
        static readonly _isMetadataInitializer = true;
 
        /**
         * The state to track in the class
         */
        static state: () => Record<string, CustomElementStateMetadata>;
 
        protected static initializeState(metadata: CustomElementMetadata): void {
 
            const state = this.getAllState();
 
            Object.entries(state).forEach(([name, stateMetadata]) => {
 
                (stateMetadata as CustomElementStateMetadata).name = name; // Set the name of the state property
 
                Object.defineProperty(
                    this.prototype,
                    name,
                    {
                        get(): any {
 
                            return this._state[name];
                        },
                        set(this: any, value: unknown) {
 
                            this.setState(name, value);
                        },
                        configurable: true,
                        enumerable: true,
                    }
                );
 
                // Add it to the metadata properties so the properties of the instances can be validated and initialized
                metadata.state.set(name, stateMetadata as CustomElementStateMetadata);
            });
 
            // Add the properties of the state base class if any so we can validate and initialize
            // the values of the properties of the state of the base class in the instance
            let baseClass = Object.getPrototypeOf(this.prototype)?.constructor;
 
            Eif (baseClass !== undefined) {
 
                const baseClassMetadata = baseClass.metadata;
 
                if (baseClassMetadata !== undefined) {
 
                    metadata.state = new Map([...metadata.state, ...baseClassMetadata.state]);
                }
            }
        }
 
        /**
         * Retrieve the state of this and the base mixins
         * @returns The merged state
         */
        static getAllState(): Record<string, CustomElementStateMetadata> {
 
            let state = this.state || {};
 
            let baseClass = Object.getPrototypeOf(this.prototype)?.constructor;
 
            while (baseClass._isMetadataInitializer === true) {
 
                if (baseClass.state !== undefined) {
 
                    state = { ...state, ...baseClass.state };
                }
 
                baseClass = Object.getPrototypeOf(baseClass.prototype)?.constructor;
            }
 
            return state;
        }
    }
 
export default StateMetadataInitializerMixin;