/** @license Copyright (c) 2025 trading_peter This program is available under Apache License Version 2.0 */ export class Store { constructor() { this._data = new Map(); this._instancesPerKey = new Map(); } /** * Subscribe instance properties to store changes * @param {Object} instance - Instance to subscribe * @param {string|Array} keys - Keys to subscribe to */ subscribe(instance, keys) { if (!Array.isArray(keys)) { keys = [keys]; } keys.forEach(key => { let targetProperty; if (typeof key === 'object') { targetProperty = key.targetProperty; key = key.key; } this._addInstance(instance, key, targetProperty); }); } /** * Write a value to the store * @param {string} key - Key to write to * @param {any} value - Value to store */ write(key, value) { this._data.set(key, value); const instances = this._instancesPerKey.get(key); if (Array.isArray(instances)) { instances.forEach(entry => { this._notifyInstance(entry.instance, key, value, entry.targetProperty); }); } } /** * Read a value from the store * @param {string} key - Key to read * @returns {any} Stored value */ read(key) { return this._data.get(key); } /** * Unsubscribe an instance from all store changes * @param {Object} instance - Instance to unsubscribe */ unsubscribe(instance) { this._instancesPerKey.forEach((instances, key) => { const remainingInstances = instances.filter(entry => entry.instance !== instance); if (remainingInstances.length === 0) { this._instancesPerKey.delete(key); } else { this._instancesPerKey.set(key, remainingInstances); } }); } _addInstance(instance, key, targetProperty) { if (!this._instancesPerKey.has(key)) { this._instancesPerKey.set(key, [{ instance, targetProperty }]); } else { this._instancesPerKey.get(key).push({ instance, targetProperty }); } if (this._data.has(key)) { this._notifyInstance(instance, key, this._data.get(key), targetProperty); } } _notifyInstance(instance, key, value, targetProperty) { if (instance.storeUpdated) { instance.storeUpdated(key, value, targetProperty); } else { instance[targetProperty || key] = value; } } } // Backwards compatibility layer for the mixin export const StoreSubcriber = function(superClass) { return class extends superClass { constructor() { super(); this._store = window.defaultStore = window.defaultStore || new Store(); } storeSubscribe(keys) { this._store.subscribe(this, keys); } storeWrite(key, value) { this._store.write(key, value); } disconnectedCallback() { if (super.disconnectedCallback) { super.disconnectedCallback(); } this._store.unsubscribe(this); } storeUpdated(key, newValue, targetProperty) { this[targetProperty || key] = newValue; } }; };