%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home/vacivi36/ava/lib/amd/build/local/reactive/
Upload File :
Create Path :
Current File : /home/vacivi36/ava/lib/amd/build/local/reactive/statemanager.min.js.map

{"version":3,"file":"statemanager.min.js","sources":["../../../src/local/reactive/statemanager.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Reactive simple state manager.\n *\n * The state manager contains the state data, trigger update events and\n * can lock and unlock the state data.\n *\n * This file contains the three main elements of the state manager:\n * - State manager: the public class to alter the state, dispatch events and process update messages.\n * - Proxy handler: a private class to keep track of the state object changes.\n * - StateMap class: a private class extending Map class that triggers event when a state list is modifed.\n *\n * @module     core/local/reactive/stateManager\n * @class     core/local/reactive/stateManager\n * @copyright  2021 Ferran Recio <ferran@moodle.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\n/**\n * State manager class.\n *\n * This class handle the reactive state and ensure only valid mutations can modify the state.\n * It also provide methods to apply batch state update messages (see processUpdates function doc\n * for more details on update messages).\n *\n * Implementing a deep state manager is complex and will require many frontend resources. To keep\n * the state fast and simple, the state can ONLY store two kind of data:\n *  - Object with attributes\n *  - Sets of objects with id attributes.\n *\n * This is an example of a valid state:\n *\n * {\n *  course: {\n *      name: 'course name',\n *      shortname: 'courseshort',\n *      sectionlist: [21, 34]\n *  },\n *  sections: [\n *      {id: 21, name: 'Topic 1', visible: true},\n *      {id: 34, name: 'Topic 2', visible: false,\n *  ],\n * }\n *\n * The following cases are NOT allowed at a state ROOT level (throws an exception if they are assigned):\n *  - Simple values (strings, boolean...).\n *  - Arrays of simple values.\n *  - Array of objects without ID attribute (all arrays will be converted to maps and requires an ID).\n *\n * Thanks to those limitations it can simplify the state update messages and the event names. If You\n * need to store simple data, just group them in an object.\n *\n * To grant any state change triggers the proper events, the class uses two private structures:\n * - proxy handler: any object stored in the state is proxied using this class.\n * - StateMap class: any object set in the state will be converted to StateMap using the\n *   objects id attribute.\n */\nexport default class StateManager {\n\n    /**\n     * Create a basic reactive state store.\n     *\n     * The state manager is meant to work with native JS events. To ensure each reactive module can use\n     * it in its own way, the parent element must provide a valid event dispatcher function and an optional\n     * DOM element to anchor the event.\n     *\n     * @param {function} dispatchEvent the function to dispatch the custom event when the state changes.\n     * @param {element} target the state changed custom event target (document if none provided)\n     */\n    constructor(dispatchEvent, target) {\n\n        // The dispatch event function.\n        /** @package */\n        this.dispatchEvent = dispatchEvent;\n\n        // The DOM container to trigger events.\n        /** @package */\n        this.target = target ?? document;\n\n        // State can be altered freely until initial state is set.\n        /** @package */\n        this.readonly = false;\n\n        // List of state changes pending to be published as events.\n        /** @package */\n        this.eventsToPublish = [];\n\n        // The update state types functions.\n        /** @package */\n        this.updateTypes = {\n            \"create\": this.defaultCreate.bind(this),\n            \"update\": this.defaultUpdate.bind(this),\n            \"delete\": this.defaultDelete.bind(this),\n            \"put\": this.defaultPut.bind(this),\n            \"override\": this.defaultOverride.bind(this),\n            \"remove\": this.defaultRemove.bind(this),\n            \"prepareFields\": this.defaultPrepareFields.bind(this),\n        };\n\n        // The state_loaded event is special because it only happens one but all components\n        // may react to that state, even if they are registered after the setIinitialState.\n        // For these reason we use a promise for that event.\n        this.initialPromise = new Promise((resolve) => {\n            const initialStateDone = (event) => {\n                resolve(event.detail.state);\n            };\n            this.target.addEventListener('state:loaded', initialStateDone);\n        });\n    }\n\n    /**\n     * Loads the initial state.\n     *\n     * Note this method will trigger a state changed event with \"state:loaded\" actionname.\n     *\n     * The state mode will be set to read only when the initial state is loaded.\n     *\n     * @param {object} initialState\n     */\n    setInitialState(initialState) {\n\n        if (this.state !== undefined) {\n            throw Error('Initial state can only be initialized ones');\n        }\n\n        // Create the state object.\n        const state = new Proxy({}, new Handler('state', this, true));\n        for (const [prop, propValue] of Object.entries(initialState)) {\n            state[prop] = propValue;\n        }\n        this.state = state;\n\n        // When the state is loaded we can lock it to prevent illegal changes.\n        this.readonly = true;\n\n        this.dispatchEvent({\n            action: 'state:loaded',\n            state: this.state,\n        }, this.target);\n    }\n\n    /**\n     * Generate a promise that will be resolved when the initial state is loaded.\n     *\n     * In most cases the final state will be loaded using an ajax call. This is the reason\n     * why states manager are created unlocked and won't be reactive until the initial state is set.\n     *\n     * @return {Promise} the resulting promise\n     */\n    getInitialPromise() {\n        return this.initialPromise;\n    }\n\n    /**\n     * Locks or unlocks the state to prevent illegal updates.\n     *\n     * Mutations use this method to modify the state. Once the state is updated, they must\n     * block again the state.\n     *\n     * All changes done while the state is writable will be registered using registerStateAction.\n     * When the state is set again to read only the method will trigger _publishEvents to communicate\n     * changes to all watchers.\n     *\n     * @param {bool} readonly if the state is in read only mode enabled\n     */\n    setReadOnly(readonly) {\n\n        this.readonly = readonly;\n\n        let mode = 'off';\n\n        // When the state is in readonly again is time to publish all pending events.\n        if (this.readonly) {\n            mode = 'on';\n            this._publishEvents();\n        }\n\n        // Dispatch a read only event.\n        this.dispatchEvent({\n            action: `readmode:${mode}`,\n            state: this.state,\n            element: null,\n        }, this.target);\n    }\n\n    /**\n     * Add methods to process update state messages.\n     *\n     * The state manager provide a default update, create and delete methods. However,\n     * some applications may require to override the default methods or even add new ones\n     * like \"refresh\" or \"error\".\n     *\n     * @param {Object} newFunctions the new update types functions.\n     */\n    addUpdateTypes(newFunctions) {\n        for (const [updateType, updateFunction] of Object.entries(newFunctions)) {\n            if (typeof updateFunction === 'function') {\n                this.updateTypes[updateType] = updateFunction.bind(newFunctions);\n            }\n        }\n    }\n\n    /**\n     * Process a state updates array and do all the necessary changes.\n     *\n     * Note this method unlocks the state while it is executing and relocks it\n     * when finishes.\n     *\n     * @param {array} updates\n     * @param {Object} updateTypes optional functions to override the default update types.\n     */\n    processUpdates(updates, updateTypes) {\n        if (!Array.isArray(updates)) {\n            throw Error('State updates must be an array');\n        }\n        this.setReadOnly(false);\n        updates.forEach((update) => {\n            if (update.name === undefined) {\n                throw Error('Missing state update name');\n            }\n            this.processUpdate(\n                update.name,\n                update.action,\n                update.fields,\n                updateTypes\n            );\n        });\n        this.setReadOnly(true);\n    }\n\n    /**\n     * Process a single state update.\n     *\n     * Note this method will not lock or unlock the state by itself.\n     *\n     * @param {string} updateName the state element to update\n     * @param {string} action to action to perform\n     * @param {object} fields the new data\n     * @param {Object} updateTypes optional functions to override the default update types.\n     */\n    processUpdate(updateName, action, fields, updateTypes) {\n\n        if (!fields) {\n            throw Error('Missing state update fields');\n        }\n\n        if (updateTypes === undefined) {\n            updateTypes = {};\n        }\n\n        action = action ?? 'update';\n\n        const method = updateTypes[action] ?? this.updateTypes[action];\n\n        if (method === undefined) {\n            throw Error(`Unkown update action ${action}`);\n        }\n\n        // Some state data may require some cooking before sending to the\n        // state. Reactive instances can overrdide the default fieldDefaults\n        // method to add extra logic to all updates.\n        const prepareFields = updateTypes.prepareFields ?? this.updateTypes.prepareFields;\n\n        method(this, updateName, prepareFields(this, updateName, fields));\n    }\n\n    /**\n     * Prepare fields for processing.\n     *\n     * This method is used to add default values or calculations from the frontend side.\n     *\n     * @param {Object} stateManager the state manager\n     * @param {String} updateName the state element to update\n     * @param {Object} fields the new data\n     * @returns {Object} final fields data\n     */\n    defaultPrepareFields(stateManager, updateName, fields) {\n        return fields;\n    }\n\n\n    /**\n     * Process a create state message.\n     *\n     * @param {Object} stateManager the state manager\n     * @param {String} updateName the state element to update\n     * @param {Object} fields the new data\n     */\n    defaultCreate(stateManager, updateName, fields) {\n\n        let state = stateManager.state;\n\n        // Create can be applied only to lists, not to objects.\n        if (state[updateName] instanceof StateMap) {\n            state[updateName].add(fields);\n            return;\n        }\n        state[updateName] = fields;\n    }\n\n    /**\n     * Process a delete state message.\n     *\n     * @param {Object} stateManager the state manager\n     * @param {String} updateName the state element to update\n     * @param {Object} fields the new data\n     */\n    defaultDelete(stateManager, updateName, fields) {\n\n        // Get the current value.\n        let current = stateManager.get(updateName, fields.id);\n        if (!current) {\n            throw Error(`Inexistent ${updateName} ${fields.id}`);\n        }\n\n        // Process deletion.\n        let state = stateManager.state;\n\n        if (state[updateName] instanceof StateMap) {\n            state[updateName].delete(fields.id);\n            return;\n        }\n        delete state[updateName];\n    }\n\n    /**\n     * Process a remove state message.\n     *\n     * @param {Object} stateManager the state manager\n     * @param {String} updateName the state element to update\n     * @param {Object} fields the new data\n     */\n    defaultRemove(stateManager, updateName, fields) {\n\n        // Get the current value.\n        let current = stateManager.get(updateName, fields.id);\n        if (!current) {\n            return;\n        }\n\n        // Process deletion.\n        let state = stateManager.state;\n\n        if (state[updateName] instanceof StateMap) {\n            state[updateName].delete(fields.id);\n            return;\n        }\n        delete state[updateName];\n    }\n\n    /**\n     * Process a update state message.\n     *\n     * @param {Object} stateManager the state manager\n     * @param {String} updateName the state element to update\n     * @param {Object} fields the new data\n     */\n    defaultUpdate(stateManager, updateName, fields) {\n\n        // Get the current value.\n        let current = stateManager.get(updateName, fields.id);\n        if (!current) {\n            throw Error(`Inexistent ${updateName} ${fields.id}`);\n        }\n\n        // Execute updates.\n        for (const [fieldName, fieldValue] of Object.entries(fields)) {\n            current[fieldName] = fieldValue;\n        }\n    }\n\n    /**\n     * Process a put state message.\n     *\n     * @param {Object} stateManager the state manager\n     * @param {String} updateName the state element to update\n     * @param {Object} fields the new data\n     */\n    defaultPut(stateManager, updateName, fields) {\n\n        // Get the current value.\n        let current = stateManager.get(updateName, fields.id);\n        if (current) {\n            // Update attributes.\n            for (const [fieldName, fieldValue] of Object.entries(fields)) {\n                current[fieldName] = fieldValue;\n            }\n        } else {\n            // Create new object.\n            let state = stateManager.state;\n            if (state[updateName] instanceof StateMap) {\n                state[updateName].add(fields);\n                return;\n            }\n            state[updateName] = fields;\n        }\n    }\n\n    /**\n     * Process an override state message.\n     *\n     * @param {Object} stateManager the state manager\n     * @param {String} updateName the state element to update\n     * @param {Object} fields the new data\n     */\n    defaultOverride(stateManager, updateName, fields) {\n\n        // Get the current value.\n        let current = stateManager.get(updateName, fields.id);\n        if (current) {\n            // Remove any unnecessary fields.\n            for (const [fieldName] of Object.entries(current)) {\n                if (fields[fieldName] === undefined) {\n                    delete current[fieldName];\n                }\n            }\n            // Update field.\n            for (const [fieldName, fieldValue] of Object.entries(fields)) {\n                current[fieldName] = fieldValue;\n            }\n        } else {\n            // Create the element if not exists.\n            let state = stateManager.state;\n            if (state[updateName] instanceof StateMap) {\n                state[updateName].add(fields);\n                return;\n            }\n            state[updateName] = fields;\n        }\n    }\n\n    /**\n     * Get an element from the state or form an alternative state object.\n     *\n     * The altstate param is used by external update functions that gets the current\n     * state as param.\n     *\n     * @param {String} name the state object name\n     * @param {*} id and object id for state maps.\n     * @return {Object|undefined} the state object found\n     */\n    get(name, id) {\n        const state = this.state;\n\n        let current = state[name];\n        if (current instanceof StateMap) {\n            if (id === undefined) {\n                throw Error(`Missing id for ${name} state update`);\n            }\n            current = state[name].get(id);\n        }\n\n        return current;\n    }\n\n    /**\n     * Register a state modification and generate the necessary events.\n     *\n     * This method is used mainly by proxy helpers to dispatch state change event.\n     * However, mutations can use it to inform components about non reactive changes\n     * in the state (only the two first levels of the state are reactive).\n     *\n     * Each action can produce several events:\n     * - The specific attribute updated, created or deleter (example: \"cm.visible:updated\")\n     * - The general state object updated, created or deleted (example: \"cm:updated\")\n     * - If the element has an ID attribute, the specific event with id (example: \"cm[42].visible:updated\")\n     * - If the element has an ID attribute, the general event with id (example: \"cm[42]:updated\")\n     * - A generic state update event \"state:update\"\n     *\n     * @param {string} field the affected state field name\n     * @param {string|null} prop the affecter field property (null if affect the full object)\n     * @param {string} action the action done (created/updated/deleted)\n     * @param {*} data the affected data\n     */\n    registerStateAction(field, prop, action, data) {\n\n        let parentAction = 'updated';\n\n        if (prop !== null) {\n            this.eventsToPublish.push({\n                eventName: `${field}.${prop}:${action}`,\n                eventData: data,\n                action,\n            });\n        } else {\n            parentAction = action;\n        }\n\n        // Trigger extra events if the element has an ID attribute.\n        if (data.id !== undefined) {\n            if (prop !== null) {\n                this.eventsToPublish.push({\n                    eventName: `${field}[${data.id}].${prop}:${action}`,\n                    eventData: data,\n                    action,\n                });\n            }\n            this.eventsToPublish.push({\n                eventName: `${field}[${data.id}]:${parentAction}`,\n                eventData: data,\n                action: parentAction,\n            });\n        }\n\n        // Register the general change.\n        this.eventsToPublish.push({\n            eventName: `${field}:${parentAction}`,\n            eventData: data,\n            action: parentAction,\n        });\n\n        // Register state updated event.\n        this.eventsToPublish.push({\n            eventName: `state:updated`,\n            eventData: data,\n            action: 'updated',\n        });\n    }\n\n    /**\n     * Internal method to publish events.\n     *\n     * This is a private method, it will be invoked when the state is set back to read only mode.\n     */\n    _publishEvents() {\n        const fieldChanges = this.eventsToPublish;\n        this.eventsToPublish = [];\n\n        // Dispatch a transaction start event.\n        this.dispatchEvent({\n            action: 'transaction:start',\n            state: this.state,\n            element: null,\n            changes: fieldChanges,\n        }, this.target);\n\n        // State changes can be registered in any order. However it will avoid many\n        // components errors if they are sorted to have creations-updates-deletes in case\n        // some component needs to create or destroy DOM elements before updating them.\n        fieldChanges.sort((a, b) => {\n            const weights = {\n                created: 0,\n                updated: 1,\n                deleted: 2,\n            };\n            const aweight = weights[a.action] ?? 0;\n            const bweight = weights[b.action] ?? 0;\n            // In case both have the same weight, the eventName length decide.\n            if (aweight === bweight) {\n                return a.eventName.length - b.eventName.length;\n            }\n            return aweight - bweight;\n        });\n\n        // List of the published events to prevent redundancies.\n        let publishedEvents = new Set();\n\n        fieldChanges.forEach((event) => {\n\n            const eventkey = `${event.eventName}.${event.eventData.id ?? 0}`;\n\n            if (!publishedEvents.has(eventkey)) {\n                this.dispatchEvent({\n                    action: event.eventName,\n                    state: this.state,\n                    element: event.eventData\n                }, this.target);\n\n                publishedEvents.add(eventkey);\n            }\n        });\n\n        // Dispatch a transaction end event.\n        this.dispatchEvent({\n            action: 'transaction:end',\n            state: this.state,\n            element: null,\n        }, this.target);\n    }\n}\n\n// Proxy helpers.\n\n/**\n * The proxy handler.\n *\n * This class will inform any value change directly to the state manager.\n *\n * The proxied variable will throw an error if it is altered when the state manager is\n * in read only mode.\n */\nclass Handler {\n\n    /**\n     * Class constructor.\n     *\n     * @param {string} name the variable name used for identify triggered actions\n     * @param {StateManager} stateManager the state manager object\n     * @param {boolean} proxyValues if new values must be proxied (used only at state root level)\n     */\n    constructor(name, stateManager, proxyValues) {\n        this.name = name;\n        this.stateManager = stateManager;\n        this.proxyValues = proxyValues ?? false;\n    }\n\n    /**\n     * Set trap to trigger events when the state changes.\n     *\n     * @param {object} obj the source object (not proxied)\n     * @param {string} prop the attribute to set\n     * @param {*} value the value to save\n     * @param {*} receiver the proxied element to be attached to events\n     * @returns {boolean} if the value is set\n     */\n    set(obj, prop, value, receiver) {\n\n        // Only mutations should be able to set state values.\n        if (this.stateManager.readonly) {\n            throw new Error(`State locked. Use mutations to change ${prop} value in ${this.name}.`);\n        }\n\n        // Check any data change.\n        if (JSON.stringify(obj[prop]) === JSON.stringify(value)) {\n            return true;\n        }\n\n        const action = (obj[prop] !== undefined) ? 'updated' : 'created';\n\n        // Proxy value if necessary (used at state root level).\n        if (this.proxyValues) {\n            if (Array.isArray(value)) {\n                obj[prop] = new StateMap(prop, this.stateManager).loadValues(value);\n            } else {\n                obj[prop] = new Proxy(value, new Handler(prop, this.stateManager));\n            }\n        } else {\n            obj[prop] = value;\n        }\n\n        // If the state is not ready yet means the initial state is not yet loaded.\n        if (this.stateManager.state === undefined) {\n            return true;\n        }\n\n        this.stateManager.registerStateAction(this.name, prop, action, receiver);\n\n        return true;\n    }\n\n    /**\n     * Delete property trap to trigger state change events.\n     *\n     * @param {*} obj the affected object (not proxied)\n     * @param {*} prop the prop to delete\n     * @returns {boolean} if prop is deleted\n     */\n    deleteProperty(obj, prop) {\n        // Only mutations should be able to set state values.\n        if (this.stateManager.readonly) {\n            throw new Error(`State locked. Use mutations to delete ${prop} in ${this.name}.`);\n        }\n        if (prop in obj) {\n\n            delete obj[prop];\n\n            this.stateManager.registerStateAction(this.name, prop, 'deleted', obj);\n        }\n        return true;\n    }\n}\n\n/**\n * Class to add events dispatching to the JS Map class.\n *\n * When the state has a list of objects (with IDs) it will be converted into a StateMap.\n * StateMap is used almost in the same way as a regular JS map. Because all elements have an\n * id attribute, it has some specific methods:\n *  - add: a convenient method to add an element without specifying the key (\"id\" attribute will be used as a key).\n *  - loadValues: to add many elements at once wihout specifying keys (\"id\" attribute will be used).\n *\n * Apart, the main difference between regular Map and MapState is that this one will inform any change to the\n * state manager.\n */\nclass StateMap extends Map {\n\n    /**\n     * Create a reactive Map.\n     *\n     * @param {string} name the property name\n     * @param {StateManager} stateManager the state manager\n     * @param {iterable} iterable an iterable object to create the Map\n     */\n    constructor(name, stateManager, iterable) {\n        // We don't have any \"this\" until be call super.\n        super(iterable);\n        this.name = name;\n        this.stateManager = stateManager;\n    }\n\n    /**\n     * Set an element into the map.\n     *\n     * Each value needs it's own id attribute. Objects without id will be rejected.\n     * The function will throw an error if the value id and the key are not the same.\n     *\n     * @param {*} key the key to store\n     * @param {*} value the value to store\n     * @returns {Map} the resulting Map object\n     */\n    set(key, value) {\n\n        // Only mutations should be able to set state values.\n        if (this.stateManager.readonly) {\n            throw new Error(`State locked. Use mutations to change ${key} value in ${this.name}.`);\n        }\n\n        // Normalize keys as string to prevent json decoding errors.\n        key = this.normalizeKey(key);\n\n        this.checkValue(value);\n\n        if (key === undefined || key === null) {\n            throw Error('State lists keys cannot be null or undefined');\n        }\n\n        // ID is mandatory and should be the same as the key.\n        if (this.normalizeKey(value.id) !== key) {\n            throw new Error(`State error: ${this.name} list element ID (${value.id}) and key (${key}) mismatch`);\n        }\n\n        const action = (super.has(key)) ? 'updated' : 'created';\n\n        // Save proxied data into the list.\n        const result = super.set(key, new Proxy(value, new Handler(this.name, this.stateManager)));\n\n        // If the state is not ready yet means the initial state is not yet loaded.\n        if (this.stateManager.state === undefined) {\n            return result;\n        }\n\n        this.stateManager.registerStateAction(this.name, null, action, super.get(key));\n\n        return result;\n    }\n\n    /**\n     * Check if a value is valid to be stored in a a State List.\n     *\n     * Only objects with id attribute can be stored in State lists.\n     *\n     * This method throws an error if the value is not valid.\n     *\n     * @param {object} value (with ID)\n     */\n    checkValue(value) {\n        if (!typeof value === 'object' && value !== null) {\n            throw Error('State lists can contain objects only');\n        }\n\n        if (value.id === undefined) {\n            throw Error('State lists elements must contain at least an id attribute');\n        }\n    }\n\n    /**\n     * Return a normalized key value for state map.\n     *\n     * Regular maps uses strict key comparissons but state maps are indexed by ID.JSON conversions\n     * and webservices sometimes do unexpected types conversions so we convert any integer key to string.\n     *\n     * @param {*} key the provided key\n     * @returns {string}\n     */\n    normalizeKey(key) {\n        return String(key).valueOf();\n    }\n\n    /**\n     * Insert a new element int a list.\n     *\n     * Each value needs it's own id attribute. Objects withouts id will be rejected.\n     *\n     * @param {object} value the value to add (needs an id attribute)\n     * @returns {Map} the resulting Map object\n     */\n    add(value) {\n        this.checkValue(value);\n        return this.set(value.id, value);\n    }\n\n    /**\n     * Return a state map element.\n     *\n     * @param {*} key the element id\n     * @return {Object}\n     */\n    get(key) {\n        return super.get(this.normalizeKey(key));\n    }\n\n    /**\n     * Check whether an element with the specified key exists or not.\n     *\n     * @param {*} key the key to find\n     * @return {boolean}\n     */\n    has(key) {\n        return super.has(this.normalizeKey(key));\n    }\n\n    /**\n     * Delete an element from the map.\n     *\n     * @param {*} key\n     * @returns {boolean}\n     */\n    delete(key) {\n        // State maps uses only string keys to avoid strict comparisons.\n        key = this.normalizeKey(key);\n\n        // Only mutations should be able to set state values.\n        if (this.stateManager.readonly) {\n            throw new Error(`State locked. Use mutations to change ${key} value in ${this.name}.`);\n        }\n\n        const previous = super.get(key);\n\n        const result = super.delete(key);\n        if (!result) {\n            return result;\n        }\n\n        this.stateManager.registerStateAction(this.name, null, 'deleted', previous);\n\n        return result;\n    }\n\n    /**\n     * Return a suitable structure for JSON conversion.\n     *\n     * This function is needed because new values are compared in JSON. StateMap has Private\n     * attributes which cannot be stringified (like this.stateManager which will produce an\n     * infinite recursivity).\n     *\n     * @returns {array}\n     */\n    toJSON() {\n        let result = [];\n        this.forEach((value) => {\n            result.push(value);\n        });\n        return result;\n    }\n\n    /**\n     * Insert a full list of values using the id attributes as keys.\n     *\n     * This method is used mainly to initialize the list. Note each element is indexed by its \"id\" attribute.\n     * This is a basic restriction of StateMap. All elements need an id attribute, otherwise it won't be saved.\n     *\n     * @param {iterable} values the values to load\n     * @returns {StateMap} return the this value\n     */\n    loadValues(values) {\n        values.forEach((data) => {\n            this.checkValue(data);\n            let key = data.id;\n            let newvalue = new Proxy(data, new Handler(this.name, this.stateManager));\n            this.set(key, newvalue);\n        });\n        return this;\n    }\n}\n"],"names":["constructor","dispatchEvent","target","document","readonly","eventsToPublish","updateTypes","this","defaultCreate","bind","defaultUpdate","defaultDelete","defaultPut","defaultOverride","defaultRemove","defaultPrepareFields","initialPromise","Promise","resolve","addEventListener","event","detail","state","setInitialState","initialState","undefined","Error","Proxy","Handler","prop","propValue","Object","entries","action","getInitialPromise","setReadOnly","mode","_publishEvents","element","addUpdateTypes","newFunctions","updateType","updateFunction","processUpdates","updates","Array","isArray","forEach","update","name","processUpdate","fields","updateName","method","prepareFields","stateManager","StateMap","add","get","id","delete","current","fieldName","fieldValue","registerStateAction","field","data","parentAction","push","eventName","eventData","fieldChanges","changes","sort","a","b","weights","created","updated","deleted","aweight","bweight","length","publishedEvents","Set","eventkey","has","proxyValues","set","obj","value","receiver","JSON","stringify","loadValues","deleteProperty","Map","iterable","key","normalizeKey","checkValue","super","result","String","valueOf","previous","toJSON","values","newvalue"],"mappings":"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"}

Zerion Mini Shell 1.0