breeze-client
Version:
Breeze data management for JavaScript clients
1 lines • 28.7 kB
Source Map (JSON)
{"version":3,"file":"breeze-client-mixin-save-queuing.mjs","sources":["../../src/mixin-save-queuing.ts","../../src/breeze-client-mixin-save-queuing.ts"],"sourcesContent":["//#region Copyright, Version, and Description\r\n/*\r\n * Copyright 2015-2021 IdeaBlade, Inc. All Rights Reserved.\r\n * Use, reproduction, distribution, and modification of this code is subject to the terms and\r\n * conditions of the IdeaBlade Breeze license, available at http://www.breezejs.com/license\r\n *\r\n * Author: Ward Bell\r\n * Version: 2.0.6 Steve Schmitt - convert to TypeScript, move to breeze-client repo, change enableSaveQueuing function\r\n * Version: 2.0.5 Ward Bell\r\n * --------------------------------------------------------------------------------\r\n * Adds \"Save Queuing\" capability to new EntityManagers\r\n *\r\n * Save Queuing automatically queues and defers an EntityManager.saveChanges call\r\n * when another save is in progress for that manager and the server has not yet responded.\r\n * This feature is helpful when your app needs to allow rapid, continuous changes\r\n * to entities that may be in the process of being saved.\r\n *\r\n * Without \"Save Queuing\", an EntityManager will throw an exception\r\n * when you call saveChanges for an entity which is currently being saved.\r\n *\r\n * !!! Use with caution !!!\r\n * It is usually better to disable user input while a save is in progress.\r\n * Save Queuing may be appropriate for simple \"auto-save\" scenarios\r\n * when the save latency is \"short\" (under a few seconds).\r\n *\r\n * Save Queuing is NOT intended for occassionally disconnected or offline scenarios.\r\n *\r\n * Save Queuing is experimental. It will not become a part of BreezeJS core\r\n * but might become an official Breeze plugin in future\r\n * although not necessarily in this form or with this API\r\n *\r\n * Must call EntityManager.enableSaveQueuing(true) to turn it on;\r\n * EntityManager.enableSaveQueuing(false) restores the manager's original\r\n * saveChanges method as it was at the time saveQueuing was first enabled.\r\n *\r\n * This module adds \"enableSaveQueuing\" to the EntityManager prototype.\r\n * Calling \"enableSaveQueuing(true)\" adds a new _saveQueuing object\r\n * to the manager instance.\r\n *\r\n * See DocCode:saveQueuingTests.js\r\n * https://github.com/Breeze/breeze.js.samples/blob/master/net/DocCode/DocCode/tests/saveQueuingTests.js\r\n *\r\n * LIMITATIONS\r\n * - Can't handle changes to the primary key (dangerous in any case)\r\n * - Assumes promises. Does not support the (deprecated) success and fail callbacks\r\n * - Does not queue saveOptions. The first one is re-used for all queued saves.\r\n * - Does not deal with export/import of entities while save is inflight\r\n * - Does not deal with rejectChanges while save is in flight\r\n * - Does not support parallel saves even when the change-sets are independent.\r\n * The native saveChanges allows such saves.\r\n * SaveQueuing does not; too complex and doesn't fit the primary scenario anyway.\r\n * - The resolved saveResult is the saveResult of the last completed save\r\n * - A queued save that might have succeeded if saved immediately\r\n * may fail because the server no longer accepts it later\r\n * - Prior to Breeze v.1.5.3, a queued save that might have succeeded\r\n * if saved immediately will fail if subsequently attempt to save\r\n * an invalid entity. Can detect and circumvent after v.1.5.3.\r\n *\r\n * All members of EntityManager._saveQueuing are internal;\r\n * touch them at your own risk.\r\n */\r\n//#endregion\r\nimport { Entity, EntityManager, KeyMapping, EntityState, SaveResult, breeze } from 'breeze-client';\r\n\r\n\r\nexport function enableSaveQueuing(em: EntityManager, enable: boolean = true) {\r\n let saveQueuing = em['_saveQueueing'] ||\r\n (em['_saveQueuing'] = new SaveQueuing(em));\r\n\r\n enable = (enable === undefined) ? true : enable;\r\n saveQueuing._isEnabled = enable;\r\n if (enable) {\r\n // delegate to save changes queuing\r\n em.saveChanges = saveChangesWithQueuing;\r\n } else {\r\n // revert to the native EntityManager.saveChanges\r\n em.saveChanges = em['_saveQueuing'].baseSaveChanges;\r\n }\r\n}\r\n\r\n/**\r\n * Replacement for EntityManager.saveChanges\r\n * This version queues saveChanges calls while a real save is in progress\r\n **/\r\nfunction saveChangesWithQueuing(entities: Entity[] | null, saveOptions: any) {\r\n try {\r\n // `this` is an EntityManager\r\n let saveQueuing = this._saveQueuing;\r\n if (saveQueuing.isSaving) {\r\n // save in progress; queue the save for later\r\n return saveQueuing.queueSaveChanges(entities);\r\n } else {\r\n // note that save is in progress; then save\r\n saveQueuing.isSaving = true;\r\n saveQueuing.saveOptions = saveOptions;\r\n return saveQueuing.saveChanges(entities, saveOptions);\r\n }\r\n } catch (err) {\r\n return Promise.reject(err);\r\n }\r\n}\r\n\r\n///////// SaveQueuing /////////\r\nclass SaveQueuing {\r\n entityManager: EntityManager;\r\n baseSaveChanges: () => Promise<any>;\r\n isSaving: boolean;\r\n _isEnabled: boolean;\r\n activeSaveDeferred: Deferred<SaveResult>;\r\n nextSaveDeferred: Deferred<SaveResult>;\r\n activeSaveMemo: SaveMemo;\r\n nextSaveMemo: SaveMemo;\r\n saveOptions: any;\r\n\r\n constructor(entityManager: EntityManager) {\r\n this.entityManager = entityManager;\r\n this.baseSaveChanges = entityManager.saveChanges;\r\n this.isSaving = false;\r\n }\r\n\r\n isEnabled() {\r\n return this._isEnabled;\r\n }\r\n\r\n getSavedNothingResult(): SaveResult {\r\n return { entities: [] as Entity[], keyMappings: [] as KeyMapping[] };\r\n }\r\n\r\n queueSaveChanges(entities: Entity[]) {\r\n let self = this; // `this` is a SaveQueuing\r\n let em = self.entityManager;\r\n\r\n let changes = entities || em.getChanges();\r\n if (changes.length === 0) {\r\n return Promise.resolve(this.getSavedNothingResult());\r\n }\r\n\r\n let valError = em.saveChangesValidateOnClient(changes);\r\n if (valError) {\r\n return Promise.reject(valError);\r\n }\r\n\r\n let saveMemo = self.nextSaveMemo || (self.nextSaveMemo = new SaveMemo());\r\n memoizeChanges();\r\n let deferred = self.nextSaveDeferred || (self.nextSaveDeferred = new Deferred<SaveResult>());\r\n return deferred.promise;\r\n\r\n function memoizeChanges() {\r\n if (changes.length === 0) { return; }\r\n let queuedChanges = saveMemo.queuedChanges;\r\n changes.forEach(e => {\r\n if (!e.entityAspect.isBeingSaved && queuedChanges.indexOf(e) === -1) {\r\n queuedChanges.push(e);\r\n }\r\n });\r\n\r\n saveMemo.updateEntityMemos(changes);\r\n }\r\n }\r\n\r\n saveChanges(entities: Entity[], saveOptions: any) {\r\n let self = this; // `this` is a SaveQueuing\r\n let promise = self.baseSaveChanges.call(self.entityManager, entities, saveOptions || self.saveOptions)\r\n .then(function (saveResult: SaveResult) { return self.saveSucceeded(saveResult); })\r\n .then(null, function (error: Error) { console.log(error); return self.saveFailed(error); });\r\n rememberAddedOriginalValues(entities); // do it after ... so don't send OrigValues to the server\r\n return promise;\r\n\r\n function rememberAddedOriginalValues(entities: Entity[]) {\r\n // added entities normally don't have original values but these will now\r\n let added = entities ?\r\n entities.filter(function (e) { return e.entityAspect.entityState.isAdded(); }) :\r\n self.entityManager.getEntities(null, EntityState.Added);\r\n added.forEach(entity => {\r\n let props = entity.entityType.dataProperties;\r\n let originalValues = entity.entityAspect.originalValues;\r\n props.forEach(dp => {\r\n if (dp.isPartOfKey) { return; }\r\n originalValues[dp.name] = entity.getProperty(dp.name);\r\n });\r\n });\r\n }\r\n }\r\n\r\n\r\n saveSucceeded(saveResult: SaveResult) {\r\n let self = this; // `this` is a SaveQueueing\r\n let activeSaveDeferred = self.activeSaveDeferred;\r\n let nextSaveDeferred = self.nextSaveDeferred;\r\n let nextSaveMemo = self.nextSaveMemo;\r\n\r\n\r\n // prepare as if nothing queued or left to save\r\n self.isSaving = false;\r\n self.activeSaveDeferred = null;\r\n self.activeSaveMemo = null;\r\n self.nextSaveDeferred = null;\r\n self.nextSaveMemo = null;\r\n\r\n if (nextSaveMemo) {\r\n // a save was queued since last save returned\r\n nextSaveMemo.pkFixup(saveResult.keyMappings);\r\n nextSaveMemo.applyToSavedEntities(self.entityManager, saveResult.entities);\r\n // remove detached entities from queuedChanges\r\n let queuedChanges = nextSaveMemo.queuedChanges.filter(e => {\r\n return !e.entityAspect.entityState.isDetached();\r\n });\r\n\r\n if (queuedChanges.length > 0) {\r\n // save again\r\n self.isSaving = true;\r\n // remember the queued changes that triggered this save\r\n self.activeSaveDeferred = nextSaveDeferred;\r\n self.activeSaveMemo = nextSaveMemo;\r\n self.saveChanges(queuedChanges, this.saveOptions);\r\n } else if (nextSaveDeferred) {\r\n nextSaveDeferred.resolve(this.getSavedNothingResult());\r\n }\r\n }\r\n\r\n if (activeSaveDeferred) { activeSaveDeferred.resolve(saveResult); }\r\n return saveResult; // for the current promise chain\r\n }\r\n\r\n saveFailed(error: Error) {\r\n let self = this; // `this` is a SaveQueueing\r\n error = new QueuedSaveFailedError(error, self);\r\n\r\n let activeSaveDeferred = self.activeSaveDeferred;\r\n let nextSaveDeferred = self.nextSaveDeferred;\r\n\r\n self.isSaving = false;\r\n self.activeSaveDeferred = null;\r\n self.activeSaveMemo = null;\r\n self.nextSaveDeferred = null;\r\n self.nextSaveMemo = null;\r\n\r\n if (activeSaveDeferred) { activeSaveDeferred.reject(error); }\r\n if (nextSaveDeferred) { nextSaveDeferred.reject(error); }\r\n\r\n return Promise.reject(error); // let promise chain hear error\r\n }\r\n}\r\n\r\n/// for backward compat with older Promise implementation\r\nclass Deferred<T> {\r\n resolve: (val: any) => void;\r\n reject: (err: any) => void;\r\n promise: Promise<T>;\r\n constructor() {\r\n this.promise = new Promise<T>(function (resolve: (val: any) => void, reject: (err: any) => void) {\r\n this.resolve = resolve;\r\n this.reject = reject;\r\n }.bind(this));\r\n }\r\n}\r\n\r\n\r\n////////// QueuedSaveFailedError /////////\r\n// Error sub-class thrown when rejecting queued saves.\r\nexport class QueuedSaveFailedError extends Error {\r\n name = \"QueuedSaveFailedError\";\r\n innerError: Error;\r\n message: string;\r\n failedSaveMemo: SaveMemo;\r\n nextSaveMemo: SaveMemo;\r\n\r\n // Error sub-class thrown when rejecting queued saves.\r\n // `innerError` is the actual save error\r\n // `failedSaveMemo` is the saveMemo that prompted this save\r\n // `nextSaveMemo` holds queued changes accumulated since that save.\r\n // You may try to recover using this info. Good luck with that.\r\n constructor(errObject: Error, saveQueuing: any) {\r\n super();\r\n this.innerError = errObject;\r\n this.message = \"Queued save failed: \" + errObject.message;\r\n this.failedSaveMemo = saveQueuing.activeSaveMemo;\r\n this.nextSaveMemo = saveQueuing.nextSaveMemo;\r\n }\r\n}\r\n\r\n////////// SaveMemo ////////////////\r\n// SaveMemo is a record of changes for a queued save, consisting of:\r\n// entityMemos: info about entities that are being saved and\r\n// have been changed since the save started\r\n// queuedChanges: entities that are queued for save but\r\n// are not currently being saved\r\nclass SaveMemo {\r\n entityMemos: { [key: string]: EntityMemo };\r\n queuedChanges: Entity[];\r\n constructor() {\r\n this.entityMemos = {};\r\n this.queuedChanges = [];\r\n }\r\n\r\n applyToSavedEntities(entityManager: EntityManager, savedEntities: Entity[]) {\r\n let entityMemos = this.entityMemos; // `this` is a SaveMemo\r\n let queuedChanges = this.queuedChanges;\r\n let restorePublishing = this.disableManagerPublishing(entityManager);\r\n try {\r\n savedEntities.forEach(saved => {\r\n let key = this.makeEntityMemoKey(saved);\r\n let entityMemo = entityMemos[key];\r\n let resave = entityMemo && entityMemo.applyToSavedEntity(saved);\r\n if (resave) {\r\n queuedChanges.push(saved);\r\n }\r\n });\r\n } finally {\r\n restorePublishing();\r\n // D#2651 hasChanges will be wrong if changes made while save in progress\r\n let hasChanges = queuedChanges.length > 0;\r\n // Must use breeze internal method to properly set this flag true\r\n if (hasChanges) { entityManager._setHasChanges(true); }\r\n }\r\n }\r\n\r\n private disableManagerPublishing(manager: EntityManager) {\r\n let Event = breeze.Event;\r\n Event.enable('entityChanged', manager, false);\r\n Event.enable('hasChangesChanged', manager, false);\r\n\r\n return function restorePublishing() {\r\n Event.enable('entityChanged', manager, true);\r\n Event.enable('hasChangesChanged', manager, true);\r\n };\r\n }\r\n\r\n pkFixup(keyMappings: KeyMapping[]) {\r\n let entityMemos = this.entityMemos; // `this` is a SaveMemo\r\n keyMappings.forEach(km => {\r\n let type = km.entityTypeName;\r\n let tempKey = type + '|' + km.tempValue;\r\n if (entityMemos[tempKey]) {\r\n entityMemos[type + '|' + km.realValue] = entityMemos[tempKey];\r\n delete entityMemos[tempKey];\r\n }\r\n for (let memoKey in entityMemos) {\r\n entityMemos[memoKey].fkFixup(km);\r\n }\r\n });\r\n }\r\n\r\n makeEntityMemoKey(entity: Entity) {\r\n let entityKey = entity.entityAspect.getKey();\r\n return entityKey.entityType.name + '|' + entityKey.values;\r\n }\r\n\r\n updateEntityMemos(changes: Entity[]) {\r\n let entityMemos = this.entityMemos; // `this` is a SaveMemo\r\n changes.forEach(change => {\r\n // only update entityMemo for entity being save\r\n if (!change.entityAspect.isBeingSaved) { return; }\r\n\r\n let key = this.makeEntityMemoKey(change);\r\n let entityMemo = entityMemos[key] || (entityMemos[key] = new EntityMemo(change));\r\n entityMemo.update();\r\n });\r\n }\r\n\r\n}\r\n\r\n\r\n\r\n///////// EntityMemo Type ///////////////\r\n// Information about an entity that is being saved\r\n// and which has been changed since that save started\r\nclass EntityMemo {\r\n entity: Entity;\r\n pendingChanges: any;\r\n isDeleted: boolean;\r\n constructor(entity: Entity) {\r\n this.entity = entity;\r\n this.pendingChanges = {};\r\n }\r\n\r\n\r\n applyToSavedEntity(saved: Entity) {\r\n let entityMemo = this;\r\n let aspect = saved.entityAspect;\r\n if (aspect.entityState.isDetached()) {\r\n return false;\r\n } else if (entityMemo.isDeleted) {\r\n aspect.setDeleted();\r\n return true;\r\n }\r\n // treat entity with pending changes as modified\r\n let props = Object.keys(entityMemo.pendingChanges);\r\n if (props.length === 0) {\r\n return false;\r\n }\r\n let originalValues = aspect.originalValues;\r\n props.forEach(name => {\r\n originalValues[name] = saved.getProperty(name);\r\n saved.setProperty(name, entityMemo.pendingChanges[name]);\r\n });\r\n aspect.setModified();\r\n return true;\r\n }\r\n\r\n fkFixup(keyMapping: KeyMapping) {\r\n let entityMemo = this;\r\n let type = entityMemo.entity.entityType;\r\n let fkProps = type.foreignKeyProperties;\r\n fkProps.forEach(fkProp => {\r\n if (fkProp.parentType.name === keyMapping.entityTypeName &&\r\n entityMemo.pendingChanges[fkProp.name] === keyMapping.tempValue) {\r\n entityMemo.pendingChanges[fkProp.name] = keyMapping.realValue;\r\n }\r\n });\r\n }\r\n\r\n // update the entityMemo of changes to an entity being saved\r\n // so that we know how to save it again later\r\n update() {\r\n let entityMemo = this;\r\n let props;\r\n let entity = entityMemo.entity;\r\n let aspect = entity.entityAspect;\r\n let stateName = aspect.entityState.name;\r\n switch (stateName) {\r\n case 'Added':\r\n let originalValues = aspect.originalValues;\r\n props = entity.entityType.dataProperties;\r\n props.forEach(dp => {\r\n if (dp.isPartOfKey) { return; }\r\n let name = dp.name;\r\n let value = entity.getProperty(name);\r\n if (originalValues[name] !== value) {\r\n entityMemo.pendingChanges[name] = value;\r\n }\r\n });\r\n break;\r\n\r\n case 'Deleted':\r\n entityMemo.isDeleted = true;\r\n entityMemo.pendingChanges = {};\r\n break;\r\n\r\n case 'Modified':\r\n props = Object.keys(aspect.originalValues);\r\n props.forEach(name => {\r\n entityMemo.pendingChanges[name] = entity.getProperty(name);\r\n });\r\n break;\r\n }\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './mixin-save-queuing';\n"],"names":[],"mappings":"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"}