dhxmvp
Version:
A complete boilerplate for building online, offline and syncable MVP Single Page Applications using DHTMLX.
1 lines • 8.87 kB
JavaScript
!function(e,t){"function"==typeof define&&define.amd?define(["backbone","underscore"],t):"object"==typeof exports?module.exports=t(require("backbone"),require("underscore")):e.returnExports=t(e.Backbone,e._)}(this,function(e,t){function n(){return(65536*(1+Math.random())|0).toString(16).substring(1)}function o(){return n()+n()+"-"+n()+"-"+n()+"-"+n()+"-"+n()+n()+n()}function i(e,n,o,i){this.schema=e,this.ready=n,this.error=null,this.transactions=[],this.db=null,this.nolog=o,this.onerror=i;var s=t.last(this.schema.migrations).version;this.nolog||r("opening database "+this.schema.id+" in version #"+s),this.dbRequest=indexedDB.open(this.schema.id,s),this.launchMigrationPath=function(n){var o=this.dbRequest.transaction,i=t.clone(e.migrations);this.migrate(o,i,n,{error:t.bind(function(e){this.error="Database not up to date. "+n+" expected was "+s},this)})},this.dbRequest.onblocked=function(e){this.nolog||r("connection to database blocked")},this.dbRequest.onsuccess=t.bind(function(e){this.db=e.target.result;var t=parseInt(this.db.version)||0,n=parseInt(s)||0;t===n?this.ready():t<n?this.launchMigrationPath(t):this.error="Database version is greater than current code "+t+" expected was "+n},this),this.dbRequest.onerror=t.bind(function(e){this.error="Couldn't not connect to the database",this.nolog||r("Couldn't not connect to the database"),this.onerror()},this),this.dbRequest.onabort=t.bind(function(e){this.error="Connection to the database aborted",this.nolog||r("Connection to the database aborted"),this.onerror()},this),this.dbRequest.onupgradeneeded=t.bind(function(e){this.db=e.target.result;var t=e.newVersion,n=e.oldVersion;n>99999999999&&(n=0),this.nolog||r("onupgradeneeded = "+n+" => "+t),this.launchMigrationPath(n)},this)}function r(e){"undefined"!=typeof console&&"function"==typeof console.log&&console.log(e)}function s(e,n,o){this.driver=new i(e,this.ready.bind(this),o,this.error.bind(this)),this.started=!1,this.failed=!1,this.stack=[],this.version=t.last(e.migrations).version,this.next=n}function a(n,o,i){if("closeall"==n)return t.invoke(d,"close"),d={},c&&c().resolve();if(!o||!t.isObject(o.database))return e.ajaxSync(n,o,i);var r=o.database;d[r.id]&&d[r.id].version!=t.last(r.migrations).version&&(d[r.id].close(),delete d[r.id]);var a,u;c&&(a=c(),u=a.promise(),u.abort=function(){i.abort=!0});var h=i.success;i.success=function(e,t){t||(h&&h(e),o.trigger("sync",o,e,i)),a&&(i.abort?a.reject():a.resolve(e))};var l=i.error;i.error=function(e){l&&l(e),a&&a.reject(e),o.trigger("error",o,e,i)};var f=function(){d[r.id].execute([n,o,i])};return d[r.id]?f():d[r.id]=new s(r,f,r.nolog),u}if("undefined"!=typeof indexedDB){var c=e.$&&e.$.Deferred;i.prototype={_track_transaction:function(e){this.transactions.push(e);var n=t.bind(function(){var t=this.transactions.indexOf(e);t!==-1&&this.transactions.splice(t)},this);e.oncomplete=n,e.onabort=n,e.onerror=n},migrate:function(e,t,n,o){e.onerror=o.error,e.onabort=o.error,this.nolog||r("migrate begin version from #"+n);var i=this,s=t.shift();s&&(!n||n<s.version?("undefined"==typeof s.before&&(s.before=function(e){e()}),"undefined"==typeof s.after&&(s.after=function(e){e()}),i.nolog||r("migrate begin before version #"+s.version),s.before(function(){i.nolog||r("migrate done before version #"+s.version),i.nolog||r("migrate begin migrate version #"+s.version),s.migrate(e,function(){i.nolog||r("migrate done migrate version #"+s.version),i.nolog||r("migrate begin after version #"+s.version),s.after(function(){i.nolog||r("migrate done after version #"+s.version),i.nolog||r("Migrated to "+s.version),0==t.length?i.nolog||(r("migrate setting transaction.oncomplete to finish version #"+s.version),e.oncomplete=function(){r("migrate done transaction.oncomplete version #"+s.version),r("Done migrating")}):(i.nolog||r("migrate end from version #"+n+" to "+s.version),i.migrate(e,t,n,o))})})})):(i.nolog||r("Skipping migration "+s.version),i.migrate(e,t,n,o)))},execute:function(e,t,n,o){switch(this.nolog||r("execute : "+t+" on "+e+" for "+n.id),t){case"create":this.create(e,n,o);break;case"read":n.id||n.cid?this.read(e,n,o):this.query(e,n,o);break;case"update":this.update(e,n,o);break;case"delete":n.id||n.cid?this["delete"](e,n,o):this.clear(e,n,o)}},create:function(e,n,i){var r,s=this.db.transaction([e],"readwrite"),a=s.objectStore(e),c=n.toJSON(),d=t.result(n,"idAttribute");void 0!==c[d]||a.autoIncrement||(c[d]=o()),s.onerror=function(e){i.error(e)},s.oncomplete=function(e){i.success(c)},r=a.keyPath?a.add(c):a.add(c,c[d])},update:function(e,n,i){var r,s=this.db.transaction([e],"readwrite"),a=s.objectStore(e),c=n.toJSON(),d=t.result(n,"idAttribute");c[d]||(c[d]=o()),r=a.keyPath?a.put(c):a.put(c,c[d]),r.onerror=function(e){i.error(e)},s.oncomplete=function(e){i.success(c)}},read:function(e,n,o){var i=this.db.transaction([e],"readonly");this._track_transaction(i);var r=i.objectStore(e),s=n.toJSON(),a=t.result(n,"idAttribute"),c=null;if(s[a])c=r.get(s[a]);else if(o.index){var d=r.index(o.index.name);c=d.get(o.index.value)}else{var u=0;t.each(r.indexNames,function(e){var n=r.index(e);if("string"==typeof n.keyPath&&1>u)void 0!==s[n.keyPath]&&(c=n.get(s[n.keyPath]),u=1);else if("object"==typeof n.keyPath&&n.keyPath.length>u){var o=!0,i=t.map(n.keyPath,function(e){return o=o&&void 0!==s[e],s[e]});o&&(c=n.get(i),u=n.keyPath.length)}})}c?(c.onsuccess=function(e){e.target.result?o.success(e.target.result):o.error("Not Found")},c.onerror=function(){o.error("Not Found")}):o.error("Not Found")},"delete":function(e,n,o){var i=this.db.transaction([e],"readwrite"),r=i.objectStore(e),s=n.toJSON(),a=r.keyPath||t.result(n,"idAttribute"),c=r["delete"](s[a]);i.oncomplete=function(e){o.success(null)},c.onerror=function(e){o.error("Not Deleted")}},clear:function(e,t,n){var o=this.db.transaction([e],"readwrite"),i=o.objectStore(e),r=i.clear();r.onsuccess=function(e){n.success(null)},r.onerror=function(e){n.error("Not Cleared")}},query:function(e,n,o){var i=[],r=0,s=0,a=this.db.transaction([e],"readonly"),c=t.result(n.model.prototype,"idAttribute"),d=null,u=a.objectStore(e),h=null,l=null,f=null,g=null;o.conditions?t.each(u.indexNames,function(e){d||(h=u.index(e),o.conditions[h.keyPath]instanceof Array?(l=o.conditions[h.keyPath][0]>o.conditions[h.keyPath][1]?o.conditions[h.keyPath][1]:o.conditions[h.keyPath][0],f=o.conditions[h.keyPath][0]>o.conditions[h.keyPath][1]?o.conditions[h.keyPath][0]:o.conditions[h.keyPath][1],g=IDBKeyRange.bound(l,f,!0,!0),d=o.conditions[h.keyPath][0]>o.conditions[h.keyPath][1]?h.openCursor(g,window.IDBCursor.PREV||"prev"):h.openCursor(g,window.IDBCursor.NEXT||"next")):"object"==typeof o.conditions[h.keyPath]&&("$gt"in o.conditions[h.keyPath]||"$gte"in o.conditions[h.keyPath])?(g="$gt"in o.conditions[h.keyPath]?IDBKeyRange.lowerBound(o.conditions[h.keyPath].$gt,!0):IDBKeyRange.lowerBound(o.conditions[h.keyPath].$gte),d=h.openCursor(g,window.IDBCursor.NEXT||"next")):"object"==typeof o.conditions[h.keyPath]&&("$lt"in o.conditions[h.keyPath]||"$lte"in o.conditions[h.keyPath])?(g="$lt"in o.conditions[h.keyPath]?IDBKeyRange.upperBound(o.conditions[h.keyPath].$lt,!0):IDBKeyRange.upperBound(o.conditions[h.keyPath].$lte),d=h.openCursor(g,window.IDBCursor.NEXT||"next")):void 0!=o.conditions[h.keyPath]&&(g=IDBKeyRange.only(o.conditions[h.keyPath]),d=h.openCursor(g)))}):o.range?(l=o.range[0]>o.range[1]?o.range[1]:o.range[0],f=o.range[0]>o.range[1]?o.range[0]:o.range[1],g=IDBKeyRange.bound(l,f),d=o.range[0]>o.range[1]?u.openCursor(g,window.IDBCursor.PREV||"prev"):u.openCursor(g,window.IDBCursor.NEXT||"next")):d=o.sort&&o.sort.index?o.sort.order===-1?u.index(o.sort.index).openCursor(null,window.IDBCursor.PREV||"prev"):u.index(o.sort.index).openCursor(null,window.IDBCursor.NEXT||"next"):u.openCursor(),"undefined"!=typeof d&&d?(d.onerror=function(e){o.error("readCursor error",e)},d.onsuccess=function(e){var t=e.target.result;if(t)if(o.abort||o.limit&&s>=o.limit)g&&o.conditions[h.keyPath]?t["continue"](o.conditions[h.keyPath][1]+1):t["continue"]();else if(o.offset&&o.offset>r)r++,t["continue"]();else{if(!o.filter||"function"!=typeof o.filter||o.filter(t.value))if(o.addIndividually)n.add(t.value);else if(o.clear){var a=u["delete"](t.value[c]);a.onsuccess=a.onerror=function(e){i.push(t.value)}}else i.push(t.value);s++,t["continue"]()}else o.addIndividually||o.clear?o.success(i,!0):o.success(i)}):o.error("No Cursor")},close:function(){this.db&&this.db.close()}},s.prototype={ready:function(){this.started=!0,t.each(this.stack,this.execute,this),this.stack=[],this.next()},error:function(){this.failed=!0,t.each(this.stack,this.execute,this),this.stack=[],this.next()},execute:function(e){this.started?this.driver.execute(e[2].storeName||e[1].storeName,e[0],e[1],e[2]):this.failed?e[2].error():this.stack.push(e)},close:function(){this.driver.close()}};var d={};return e.ajaxSync=e.sync,e.sync=a,{sync:a,debugLog:r}}});