UNPKG

@schukai/monster

Version:

Monster is a simple library for creating fast, robust and lightweight websites.

90 lines (74 loc) 2.38 kB
/** * Copyright © Volker Schukai and all contributing authors, {{copyRightYear}}. All rights reserved. * Node module: @schukai/monster * * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3). * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html * * For those who do not wish to adhere to the AGPLv3, a commercial license is available. * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms. * For more information about purchasing a commercial license, please contact Volker Schukai. * * SPDX-License-Identifier: AGPL-3.0 */ import { diff } from "../../data/diff.mjs"; import { Pathfinder } from "../../data/pathfinder.mjs"; import { isObject, isPrimitive } from "../../types/is.mjs"; import { Observer } from "../../types/observer.mjs"; import { clone } from "../../util/clone.mjs"; export { handleDataSourceChanges, datasourceLinkedElementSymbol }; /** * @private * @type {symbol} */ const datasourceLinkedElementSymbol = Symbol("datasourceLinkedElement"); const dataChangeVersionSymbol = Symbol("dataChangeVersion"); /** * @private */ function handleDataSourceChanges(force = false) { if (!this[datasourceLinkedElementSymbol]) { return; } const version = (this[dataChangeVersionSymbol] || 0) + 1; this[dataChangeVersionSymbol] = version; let data = this[datasourceLinkedElementSymbol]?.data; if (isPrimitive(data)) { throw new Error("Data must be an object or an array"); } const actualData = JSON.stringify(this.getOption("data")); const actualDataAsObj = JSON.parse(actualData); const path = this.getOption("mapping.data"); if (path) { data = new Pathfinder(data).getVia(path); } if (isObject(data)) { const tmp = []; const keys = Object.keys(data); for (const key of keys) { tmp.push(data[key]); } data = tmp; } const index = this.getOption("mapping.index"); if (index !== undefined && index !== null) { data = data?.[index]; } if (data === undefined || data === null) { data = []; } queueMicrotask(() => { if (this[dataChangeVersionSymbol] !== version) { return; } if (force) { this.setOption("data", clone(data)); return; } const result = diff(data, actualDataAsObj); if (result.length === 0) { return; } this.setOption("data", data); }); }