UNPKG

@pilotlab/data

Version:

A luxurious user experience framework, developed by your friends at Pilot.

204 lines 9.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const is_1 = require("@pilotlab/is"); const nodes_1 = require("@pilotlab/nodes"); const debug_1 = require("@pilotlab/debug"); const result_1 = require("@pilotlab/result"); const signals_1 = require("@pilotlab/signals"); const attributeEnums_1 = require("./attributes/attributeEnums"); const attributeBase_1 = require("./attributes/attributeBase"); const attributeRoot_1 = require("./attributes/attributeRoot"); const attributeChangeOptions_1 = require("./attributes/attributeChangeOptions"); const attributeCreateOptions_1 = require("./attributes/attributeCreateOptions"); const ids_1 = require("@pilotlab/ids"); const dataEnums_1 = require("./dataEnums"); const sha1_1 = require("@pilotlab/sha1"); const commands_1 = require("@pilotlab/commands"); debug_1.Debug.setCategoryMode('data_save', false); class Data extends attributeBase_1.default { constructor(data, isStoreKey = true, dataStore, isSaveDataTypes = false, isAutoSave = false, key, label, progressTracker, isInitialize = true) { super(attributeRoot_1.default.create, data, attributeEnums_1.DataType.COLLECTION, label, key, nodes_1.NodeType.ROOT, false); this.isStoreKey = true; this.p_keyAutoGenerationType = dataEnums_1.KeyAutoGenerationType.SESSION_UNIQUE; this.p_isAutoHash = false; this._isAutoSave = false; /** * This will be set to true if autoSave() was called while isAutoSave was false. * This triggers a save of the data immediately after isAutoSave is set to true. */ this._isAutoSaveQueued = false; /*====================================================================* START: Signals *====================================================================*/ this.storeSet = new signals_1.Signal(true); /** * Dispatched after a response is received back from the data store when data has been saved. * Completes with the response from the data store. */ this.saved = new signals_1.Signal(false); /*====================================================================* START: Signals *====================================================================*/ this.saveTriggered = new signals_1.Signal(false); //===== Save this._saveDebounceDelayInMilliseconds = 125; this.isStoreKey = isStoreKey; if (isInitialize) this.initialize(data, dataStore, isSaveDataTypes, isAutoSave, progressTracker); } initialize(data, dataStore, isSaveDataTypes = false, isAutoSave = false, progressTracker) { return super.p_initialize([data, dataStore, isSaveDataTypes, isAutoSave, progressTracker]); } p_onInitializeStarted(result, args) { const data = args[0]; const dataStore = args[1]; const isSaveDataTypes = args[2]; const isAutoSave = args[3]; const progressTracker = args[4]; super.p_onInitializeStarted(new result_1.Result(), [data, attributeEnums_1.DataType.COLLECTION, nodes_1.NodeType.ROOT]).then(() => { this.p_value.changed.listen((args) => { this.p_onChanged(args); }); if (is_1.default.notEmpty(dataStore)) this.store = dataStore; if (!this.isStoreKey) { if (this.p_keyAutoGenerationType === dataEnums_1.KeyAutoGenerationType.SESSION_UNIQUE) { this.p_key = ids_1.Identifier.getSessionUniqueInteger().toString(); } else this.p_key = ids_1.Identifier.generate(); } else { this.p_key = ids_1.Identifier.generate(); } this._isSaveDataTypes = isSaveDataTypes; this._isAutoSave = isAutoSave; this._saveCommand = new commands_1.ThrottlingCommand(() => { let result = new result_1.Result(); let data = this.toObject(this.isSaveDataTypes); if (is_1.default.empty(data) || is_1.default.empty(this.key) || typeof this.key !== 'string') return result.resolve(false); //----- Reset _isAutoSaveQueued this._isAutoSaveQueued = false; if (!this.hash.omitFromDataStore && this.p_isAutoHash) { sha1_1.SHA1.hash(JSON.stringify(data)).then((hash) => { data['hash'] = hash; debug_1.Debug.log('saving to database', 'Data._saveCommand', 'data_save'); debug_1.Debug.log(data, 'Data._saveCommand', 'data_save'); this._dataStore.save(data, this.key).then((response) => { if (is_1.default.notEmpty(response) && typeof response === 'string') this._revision = response; result.resolve(response); this.saved.dispatch(response); }); }); } else { debug_1.Debug.log('saving to database', 'Data._saveCommand', 'data_save'); debug_1.Debug.log(data, 'Data._saveCommand', 'data_save'); this._dataStore.save(data, this.key).then((response) => { if (is_1.default.notEmpty(response) && typeof response === 'string') this._revision = response; result.resolve(response); this.saved.dispatch(response); }); } return result; }, null, this, this._saveDebounceDelayInMilliseconds); this.p_value.update(data, attributeChangeOptions_1.default.signal.durationZero, progressTracker).then(() => result.resolve(data)); }); return result; } /*====================================================================* START: Properties *====================================================================*/ /** * If the key is stored, this will be a globally unique ID, used to identify the data * object associated with this entity in the data store. */ set key(value) { this.p_key = value; if (this.isStoreKey) this.save(); } /** * The revision ID, which may be managed by the database and can be used to determine * if the data associated with this entity is up-to-date. */ get revision() { return this._revision; } /** * An SHA-1 hash representing the precise contents of the associated blob or text. * Can be used to check the uniqueness of a data object to avoid storing duplicates. */ get hash() { return this.p_value.get('hash', new attributeCreateOptions_1.default('', attributeEnums_1.DataType.STRING, null, null, null, attributeChangeOptions_1.default.zero)); } get isAutoHash() { return this.p_isAutoHash; } set isAutoHash(value) { this.p_isAutoHash = value; } //===== DataStore /** * The data store where the data associated with this entity will be stored. */ get store() { return this._dataStore; } set store(value) { this._dataStore = value; this.storeSet.dispatch(value); } //===== Save /** * Determines whether a dataType property is saved with the data objects, * which can be used to verify the data's type when the object is deserialized. */ get isSaveDataTypes() { return this._isSaveDataTypes; } set isSaveDataTypes(value) { this._isSaveDataTypes = value; } /** * Toggles auto-save functionality. * Can be used to pause auto-saving while changes to the data are batched. */ get isAutoSave() { return this._isAutoSave; } set isAutoSave(value) { if (this._isAutoSave === value) return; this._isAutoSave = value; if (value && this._isAutoSaveQueued) this.save(); } p_onChanged(args) { if (is_1.default.empty(args)) return; if (args.changeOptions.isSave && is_1.default.notEmpty(this.key)) { this.autoSave(); this.saveTriggered.dispatch(args); } } /*====================================================================* START: Public Methods *====================================================================*/ update(data, changeOptions = attributeChangeOptions_1.default.default, progressTracker) { return this.p_value.update(data, changeOptions, progressTracker); } save() { if (is_1.default.empty(this._dataStore)) { //----- Save immediately after the data store has been set. this.storeSet.listenOnce(() => this.save()); return result_1.Result.resolve(null); } return this._saveCommand.debounce(); } autoSave() { if (!this.isAutoSave) this._isAutoSaveQueued = true; else if (is_1.default.notEmpty(this.key)) this.save(); } delete() { if (is_1.default.empty(this.key) || typeof this.key !== 'string') return result_1.Result.resolve(false); let result = new result_1.Result(); this._dataStore.delete(this.key).then((isSuccess) => { result.resolve(isSuccess); }, (e) => { result.reject(e); }); return result; } } // End of class exports.Data = Data; exports.default = Data; //# sourceMappingURL=data.js.map