Compare commits
	
		
			6 Commits
		
	
	
		
			feature/is
			...
			pouchdb-pr
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 2301d43b45 | ||
|   | 50016db052 | ||
|   | 629ec8950b | ||
|   | bca4eaf9c2 | ||
|   | 15ddd43cf0 | ||
|   | 0c90b46d6e | 
| @@ -81,7 +81,8 @@ | ||||
|             openmct.legacyRegistry.enable.bind(openmct.legacyRegistry) | ||||
|         ); | ||||
|  | ||||
|         openmct.install(openmct.plugins.LocalStorage()); | ||||
|         // openmct.install(openmct.plugins.LocalStorage()); | ||||
|         openmct.install(openmct.plugins.PouchDB()); | ||||
|         openmct.install(openmct.plugins.Espresso()); | ||||
|         openmct.install(openmct.plugins.MyItems()); | ||||
|         openmct.install(openmct.plugins.Generator()); | ||||
|   | ||||
| @@ -62,6 +62,7 @@ | ||||
|     "node-sass": "^4.14.1", | ||||
|     "painterro": "^1.0.35", | ||||
|     "printj": "^1.2.1", | ||||
|     "pouchdb": "^7.2.2", | ||||
|     "raw-loader": "^0.5.1", | ||||
|     "request": "^2.69.0", | ||||
|     "split": "^1.0.0", | ||||
|   | ||||
							
								
								
									
										222
									
								
								src/plugins/persistence/pouchdb/PouchObjectProvider.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										222
									
								
								src/plugins/persistence/pouchdb/PouchObjectProvider.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,222 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2020, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| import CouchDocument from "../couch/CouchDocument"; | ||||
| import CouchObjectQueue from "../couch/CouchObjectQueue"; | ||||
| import PouchDB from 'pouchdb'; | ||||
|  | ||||
| const REV = "_rev"; | ||||
| const ID = "_id"; | ||||
| const HEARTBEAT = 50000; | ||||
|  | ||||
| export default class CouchObjectProvider { | ||||
|     // options { | ||||
|     //      url: couchdb url, | ||||
|     //      disableObserve: disable auto feed from couchdb to keep objects in sync, | ||||
|     //      filter: selector to find objects to sync in couchdb | ||||
|     //      } | ||||
|     constructor(openmct, options, namespace) { | ||||
|         options = this._normalize(options); | ||||
|         this.openmct = openmct; | ||||
|         this.url = options.url; | ||||
|         this.remoteCouch = options.remoteCouch; | ||||
|         this.namespace = namespace; | ||||
|         this.objectQueue = {}; | ||||
|         this.observers = {}; | ||||
|  | ||||
|         this.pouchdb = new PouchDB(options.name); | ||||
|         this.observeChanges(); | ||||
|  | ||||
|         let replicateOptions = {live: true}; | ||||
|         this.pouchdb.replicate.to(this.remoteCouch, replicateOptions, this.logError); | ||||
|         this.pouchdb.replicate.from(this.remoteCouch, replicateOptions, this.logError); | ||||
|     } | ||||
|  | ||||
|     //backwards compatibility, options used to be a url. Now it's an object | ||||
|     _normalize(options) { | ||||
|         if (typeof options === 'string') { | ||||
|             return { | ||||
|                 url: options | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         return options; | ||||
|     } | ||||
|  | ||||
|     observeChanges() { | ||||
|         this.pouchdb.changes({ | ||||
|             since: 'now', | ||||
|             live: true | ||||
|           }).on('change', this.updateObject.bind(this)); | ||||
|     } | ||||
|  | ||||
|     observe(identifier, callback) { | ||||
|         const keyString = this.openmct.objects.makeKeyString(identifier); | ||||
|         this.observers[keyString] = this.observers[keyString] || []; | ||||
|         this.observers[keyString].push(callback); | ||||
|  | ||||
|         return () => { | ||||
|             this.observers[keyString] = this.observers[keyString].filter(observer => observer !== callback); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     logError(error) { | ||||
|         console.log(error); | ||||
|     } | ||||
|  | ||||
|     async updateObject(response) { | ||||
|         const object = {}; | ||||
|         object.identifier = { | ||||
|             namespace: this.namespace, | ||||
|             key: response.id | ||||
|         }; | ||||
|         let keyString = this.openmct.objects.makeKeyString(object.identifier); | ||||
|         let observersForObject = this.observers[keyString]; | ||||
|  | ||||
|         if (observersForObject) { | ||||
|             observersForObject.forEach(async (observer) => { | ||||
|                 const updatedObject = await this.get(object.identifier); | ||||
|                 observer(updatedObject); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Check the response to a create/update/delete request; | ||||
|     // track the rev if it's valid, otherwise return false to | ||||
|     // indicate that the request failed. | ||||
|     // persist any queued objects | ||||
|     checkResponse(response, intermediateResponse) { | ||||
|         let requestSuccess = false; | ||||
|         const id = response ? response.id : undefined; | ||||
|         let rev; | ||||
|         if (response && response.ok) { | ||||
|             rev = response.rev; | ||||
|             requestSuccess = true; | ||||
|         } | ||||
|  | ||||
|         intermediateResponse.resolve(requestSuccess); | ||||
|  | ||||
|         if (id) { | ||||
|             if (!this.objectQueue[id]) { | ||||
|                 this.objectQueue[id] = new CouchObjectQueue(undefined, rev); | ||||
|             } | ||||
|  | ||||
|             this.objectQueue[id].updateRevision(rev); | ||||
|             this.objectQueue[id].pending = false; | ||||
|             if (this.objectQueue[id].hasNext()) { | ||||
|                 this.updateQueued(id); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     getModel(response) { | ||||
|         if (response && response.model) { | ||||
|             let key = response[ID]; | ||||
|             let object = response.model; | ||||
|             object.identifier = { | ||||
|                 namespace: this.namespace, | ||||
|                 key: key | ||||
|             }; | ||||
|             if (!this.objectQueue[key]) { | ||||
|                 this.objectQueue[key] = new CouchObjectQueue(undefined, response[REV]); | ||||
|             } | ||||
|  | ||||
|             this.objectQueue[key].updateRevision(response[REV]); | ||||
|  | ||||
|             return object; | ||||
|         } else { | ||||
|             return undefined; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     get(identifier, abortSignal) { | ||||
|         return this.pouchdb.get(identifier.key).then(this.getModel.bind(this)); | ||||
|     } | ||||
|  | ||||
|     abortGetChanges() { | ||||
|         if (this.controller) { | ||||
|             this.controller.abort(); | ||||
|             this.controller = undefined; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     getIntermediateResponse() { | ||||
|         let intermediateResponse = {}; | ||||
|         intermediateResponse.promise = new Promise(function (resolve, reject) { | ||||
|             intermediateResponse.resolve = resolve; | ||||
|             intermediateResponse.reject = reject; | ||||
|         }); | ||||
|  | ||||
|         return intermediateResponse; | ||||
|     } | ||||
|  | ||||
|     enqueueObject(key, model, intermediateResponse) { | ||||
|         if (this.objectQueue[key]) { | ||||
|             this.objectQueue[key].enqueue({ | ||||
|                 model, | ||||
|                 intermediateResponse | ||||
|             }); | ||||
|         } else { | ||||
|             this.objectQueue[key] = new CouchObjectQueue({ | ||||
|                 model, | ||||
|                 intermediateResponse | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     create(model) { | ||||
|         let intermediateResponse = this.getIntermediateResponse(); | ||||
|         const key = model.identifier.key; | ||||
|         this.enqueueObject(key, model, intermediateResponse); | ||||
|         this.objectQueue[key].pending = true; | ||||
|         const queued = this.objectQueue[key].dequeue(); | ||||
|         let document = new CouchDocument(key, queued.model); | ||||
|         this.pouchdb.put(document).then((response) => { | ||||
|             this.checkResponse(response, queued.intermediateResponse); | ||||
|         }); | ||||
|  | ||||
|         return intermediateResponse.promise; | ||||
|     } | ||||
|  | ||||
|     updateQueued(key) { | ||||
|         if (!this.objectQueue[key].pending) { | ||||
|             this.objectQueue[key].pending = true; | ||||
|             const queued = this.objectQueue[key].dequeue(); | ||||
|             let document = new CouchDocument(key, queued.model, this.objectQueue[key].rev); | ||||
|  | ||||
|             this.pouchdb.put(document).then((response) => { | ||||
|                 this.checkResponse(response, queued.intermediateResponse); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     update(model) { | ||||
|         let intermediateResponse = this.getIntermediateResponse(); | ||||
|         const key = model.identifier.key; | ||||
|         this.enqueueObject(key, model, intermediateResponse); | ||||
|         this.updateQueued(key); | ||||
|  | ||||
|         return intermediateResponse.promise; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										34
									
								
								src/plugins/persistence/pouchdb/plugin.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/plugins/persistence/pouchdb/plugin.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2020, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| import PouchObjectProvider from './PouchObjectProvider'; | ||||
| const NAMESPACE = ''; | ||||
| const PERSISTENCE_SPACE = 'mct'; | ||||
|  | ||||
| export default function PouchPlugin(options) { | ||||
|     return function install(openmct) { | ||||
|         options = options || {name: 'openmct', remoteCouch: 'http://127.0.0.1:5984/openmct'}; | ||||
|  | ||||
|         install.pouchProvider = new PouchObjectProvider(openmct, options, NAMESPACE); | ||||
|         openmct.objects.addProvider(PERSISTENCE_SPACE, install.pouchProvider); | ||||
|     }; | ||||
| } | ||||
| @@ -65,7 +65,8 @@ define([ | ||||
|     './interceptors/plugin', | ||||
|     './performanceIndicator/plugin', | ||||
|     './CouchDBSearchFolder/plugin', | ||||
|     './timeline/plugin' | ||||
|     './timeline/plugin', | ||||
|     './persistence/pouchdb/plugin' | ||||
| ], function ( | ||||
|     _, | ||||
|     UTCTimeSystem, | ||||
| @@ -111,7 +112,8 @@ define([ | ||||
|     ObjectInterceptors, | ||||
|     PerformanceIndicator, | ||||
|     CouchDBSearchFolder, | ||||
|     Timeline | ||||
|     Timeline, | ||||
|     PouchDB | ||||
| ) { | ||||
|     const bundleMap = { | ||||
|         LocalStorage: 'platform/persistence/local', | ||||
| @@ -212,6 +214,7 @@ define([ | ||||
|     plugins.PerformanceIndicator = PerformanceIndicator.default; | ||||
|     plugins.CouchDBSearchFolder = CouchDBSearchFolder.default; | ||||
|     plugins.Timeline = Timeline.default; | ||||
|     plugins.PouchDB = PouchDB.default; | ||||
|  | ||||
|     return plugins; | ||||
| }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user