UNPKG

@constructorfleet/ultimate-govee

Version:

Library for interacting with Govee devices written in Typescript.

206 lines 6.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DeltaMap = void 0; const rxjs_1 = require("rxjs"); class DeltaMap extends Map { constructor(itemsOrSettings, settings) { super(); this.deltaSubject$ = new rxjs_1.ReplaySubject(1); this.delta$ = this.deltaSubject$.asObservable(); this.publishEmpty = true; this.publish = true; this.copyAll = false; this.clearDelta(); if (itemsOrSettings && Symbol.iterator in Object(itemsOrSettings)) { this.initializeContent(itemsOrSettings); this.publishDelta(); } if (!settings) { settings = itemsOrSettings; } if (settings) { this.initializeSettings(settings); } } /** * Process constructor content, can be overriden and extended in subclasses */ initializeContent(entries) { Array.from(entries).forEach((entry) => this.doSet(entry[0], entry[1])); } /** * Process constructor settings, can be overriden and extended in subclasses */ initializeSettings(settings) { this.isUpdated = settings.isModified; this.publishEmpty = settings.publishEmpty ?? true; this.copyAll = settings.copyAll ?? false; } /** * Publish modification to delta$ if there are changes or if it is the first time called. */ publishDelta() { if (this.publish && (this.added.size > 0 || this.modified.size > 0 || this.deleted.size > 0 || this.publishEmpty)) { this.deltaSubject$.next(this.getDelta()); this.publishEmpty = false; this.clearDelta(); } } /** * @returns _true_ if the ObservableMap _delta$_ has subscribers */ get observed() { return this.deltaSubject$.observed; } /** * Pauses and combines all delta updates until _resumeDelta_ is called. */ pauseDelta() { this.publish = false; } /** * Publishes all pending _added_, _modified_ or _deleted_ entries if there are any. */ resumeDelta() { this.publish = true; this.publishDelta(); } /** * Return current value of the delta */ getDelta() { return { all: this.copyAll ? new Map(this) : this, added: this.added, modified: this.modified, deleted: this.deleted, }; } /** * Clears the current delta without publishing updates to subscribers. * * WARNING: This method can mess up publication integrity, * only use in DeltaMaps without subscriptions. */ clearDelta() { this.added = new Map(); this.deleted = new Map(); this.modified = new Map(); this.existedBeforeDelta = undefined; } /** * Adds or modifies an entry and notifies changes through _delta$_. * * If an existing entry is the same according to the _compare_ function, nothing is changed * @override */ set(id, value) { this.doSet(id, value); this.publishDelta(); return this; } /** * _set_ delta logic. * Determines if it is an _add_ or a _modify_ and updates the delta. * Can be extended and/or overridden in subclasses */ doSet(id, value) { if (this.added.has(id)) { // already in added, update add super.set(id, value); this.added.set(id, value); } else { this.deleted.delete(id); const prevEntry = this.get(id); if (prevEntry) { // existing entry if (!this.isUpdated || this.isUpdated(value, prevEntry)) { // modified entry super.set(id, value); this.modified.set(id, value); } } else { // new entry super.set(id, value); if (this.existedBeforeDelta?.has(id)) { this.modified.set(id, value); } else { this.added.set(id, value); } } } } /** * Deletes an entry and notifies deletions through _delta$_ if the entry exists. * @override */ delete(id) { const deleted = this.doDelete(id); this.publishDelta(); return deleted; } /** * _delete_ delta logic. * Determines if it exists and updates the delta. * Can be extended and/or overridden in subclasses */ doDelete(id) { const deletedItem = this.get(id); super.delete(id); if (this.added.has(id)) { this.added.delete(id); return true; } if (deletedItem) { if (!this.publish) { if (!this.existedBeforeDelta) { this.existedBeforeDelta = new Set(); } this.existedBeforeDelta.add(id); } this.modified.delete(id); this.deleted.set(id, deletedItem); return true; } return false; } /** * Deletes multiple entries at once and notifies changes through _delta$_. */ deleteMultiple(entrieIds) { Array.from(entrieIds).forEach((entryId) => this.doDelete(entryId)); this.publishDelta(); } /** * Clears all entries and notifies deletions through _delta$_. * @override */ clear() { if (this.deltaSubject$.observed) { this.clearDelta(); this.forEach((value, key) => this.deleted.set(key, value)); super.clear(); this.publishDelta(); } else { super.clear(); } } /** * Clears any remaining entries and completes the delta$ observable */ close() { this.resumeDelta(); this.clear(); this.deltaSubject$.complete(); } } exports.DeltaMap = DeltaMap; //# sourceMappingURL=delta-map.observable.js.map