Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
8 lines
No EOL
4 KiB
JavaScript
8 lines
No EOL
4 KiB
JavaScript
;'use strict';(function(exports){function Datastore(name){this.name=name;}
|
|
Datastore.prototype={name:'',DB_VERSION:1,datastore:null,lastRevision:null,db:null,get revisionName(){return this.name+'_revision';},get idbName(){return this.name+'_mirror';},get storeName(){return this.name+'_store';},init:function(){var revisionString=localStorage.getItem(this.revisionName);if(revisionString){this.lastRevision=JSON.parse(revisionString);}
|
|
return new Promise((resolve,reject)=>{var req=window.indexedDB.open(this.idbName,this.DB_VERSION);req.onupgradeneeded=this.upgradeSchema.bind(this);req.onsuccess=(e)=>{this.db=e.target.result;resolve();if(!navigator.getDataStores){console.error('DataStore API is unavailable');return;}
|
|
navigator.getDataStores(this.name).then((stores)=>{if(stores.length<1){console.error(this.name+' inaccessible');return;}
|
|
this.datastore=stores[0];this.datastore.addEventListener('change',this.onChange.bind(this));this.synchronise();},(e)=>{console.error('Error getting datastore',e);});};req.onerror=(e)=>{console.error('Error opening datastore mirror database',e);reject(e);};});},upgradeSchema:function(e){var db=e.target.result;var fromVersion=e.oldVersion;if(fromVersion<1){var store=db.createObjectStore(this.storeName,{keyPath:'id'});store.createIndex('data','data',{unique:false});}},synchronise:function(){this._syncQueue=(this._syncQueue||Promise.resolve()).then(()=>this._synchronise());return this._syncQueue;},_synchronise:function(){return new Promise((resolve,reject)=>{var cursor=this.datastore.sync(this.lastRevision);var self=this;function cursorResolve(task){var promises=[];switch(task.operation){case'update':case'add':promises.push(self.set(task.data));break;case'remove':promises.push(self.remove(task.id));break;case'clear':promises.push(self.clear());break;case'done':self.updateRevision();resolve();return;}
|
|
promises.push(cursor.next());Promise.all(promises).then((results)=>{cursorResolve(results.pop());},reject);}
|
|
cursor.next().then(cursorResolve,reject);});},set:function(data){return new Promise((resolve,reject)=>{var txn=this.db.transaction([this.storeName],'readwrite');txn.oncomplete=function onComplete(data,resolve){resolve();document.dispatchEvent(new CustomEvent(this.name+'-set',{detail:{id:data.id}}));}.bind(this,data,resolve);txn.onerror=reject;try{txn.objectStore(this.storeName).put({id:data.id,data:data});}catch(e){console.error('Error putting data in '+this.idbName+':',e);resolve();}});},remove:function(id){return new Promise((resolve,reject)=>{var txn=this.db.transaction([this.storeName],'readwrite');txn.oncomplete=function onComplete(id,resolve){resolve();document.dispatchEvent(new CustomEvent(this.name+'-removed',{detail:{id:id}}));}.bind(this,id,resolve);txn.onerror=reject;try{txn.objectStore(this.storeName).delete(id);}catch(e){console.error('Error deleting data from '+this.idbName+':',e);resolve();}});},clear:function(){return new Promise((resolve,reject)=>{var txn=this.db.transaction([this.storeName],'readwrite');txn.oncomplete=function onComplete(resolve){resolve();document.dispatchEvent(new CustomEvent(this.name+'-cleared'));}.bind(this,resolve);txn.onerror=reject;txn.objectStore(this.storeName).clear();});},updateRevision:function(){this.lastRevision=this.datastore.revisionId;localStorage.setItem(this.revisionName,JSON.stringify(this.lastRevision));},onChange:function(e){this.synchronise().then(()=>{},(error)=>{console.error('Failed to handle '+this.name+' change',error);});},get:function(id){return new Promise((resolve,reject)=>{var txn=this.db.transaction([this.storeName],'readonly');txn.onerror=reject;txn.objectStore(this.storeName).get(id).onsuccess=(event)=>{resolve(event.target.result);};});},getAll:function(filter=()=>true){return new Promise((resolve,reject)=>{var results=[];var txn=this.db.transaction([this.storeName],'readonly');txn.onerror=reject;txn.oncomplete=()=>{resolve(results);};txn.objectStore(this.storeName).openCursor().onsuccess=(event)=>{var cursor=event.target.result;if(cursor){if(filter(cursor.value)){results.push(cursor.value);}
|
|
cursor.continue();}};});}};exports.Datastore=Datastore;}(window)); |