dhxmvp
Version:
A complete boilerplate for building online, offline and syncable MVP Single Page Applications using DHTMLX.
1 lines • 11.3 kB
JavaScript
$dhx.ui.mvp.model.engine.declare({backboneIDB:function(){"strict";var e=function(){var e={database:{id:"dhxMVP__99999",description:"dhxMVP demo database",nolog:!0,migrations:[]},versions:{1:$dhx.ui.mvp.model.collection.get()},start:function(e){console.log("model.start() triggered"),e.onSuccess&&e.onSuccess()}},o={database:e.database,versions:e.versions,start:e.start};return o}();return e.subscriber=function(o,t){var n=1e4*(new Date).getTime();if(t.client_id!=$dhx.ui.session.client_id()){if(e.schema.io[t.collection]&&e.schema.io[t.collection][t.method])return console.log("backboneIDB Received Message: ",t),$dhx.jDBdStorage.storeObject("$dhx.mvp.ui.last_sync_time",$dhx.crypt.base64_encode(n)),t.model.notify=!1,void e.schema.io[t.collection][t.method]({record:t.model,onSuccess:function(){console.info("success "+t.method+"ing record: ",t.model.id||t.model)},onFail:function(){console.warn("discarding record: ",t.model)}});console.warn("backboneIDB Received Unknow Message: ",t)}},e.data=function(){var o={},t={},n={_collections:o,setIoAPI:function(o,t){e.schema.io[o]=function(o,t){var n={model:t,collection:o,create:function(o){o.model=this.model,o.collection=this.collection,e.schema._io._create(o)},update:function(o){o.model=this.model,o.collection=this.collection,e.schema._io._update(o)},destroy:function(o){o.model=this.model,o.collection=this.collection,e.schema._io._destroy(o)},read:function(o){o.model=this.model,o.collection=this.collection,e.schema._io._read(o)},readAll:function(o){o.model=this.model,o.collection=this.collection,e.schema._io._readAll(o)}};return n}(o,t)},_start:function(){console.info(" starting model.data ");for(var c in o)this.setIoAPI(c,o[c].item),t[o[c].item]=Backbone.Model.extend({database:e.database,storeName:c,nolog:!0,defaults:o[c].defaults,url:function(){return this.id?"/"+o[c].item+"/"+this.id:"/"+o[c].item},ajaxSync:function(){},incrementVersion:function(){var e=this.get("__v");console.log("version: ",e),e+=1,this.set({__v:e}),console.log('this.get("__v"): ',this.get("__v"))},initialize:function(){this.get("id"),this.on("change",this.onChange),this.on("sync",this.onSync),this.on("error",this.onError),this.on("destroy",this.onDestroy)},onSync:function(e,o,t){},onError:function(e,o,t){},onDestroy:function(e,o,t){},onChange:function(e,o,t){}}),t[c]=Backbone.Collection.extend({model:t[o[c].item],database:e.database,nolog:!0,storeName:c,url:c+".json"}),n[o[c].item]=function(e){return function(n){return new t[o[e].item](n)}}(c),n[c]=function(e){return function(){return new t[e]}}(c)}};return n}(),e.schema=function(){var o={setup:function(o){var t,n=null;for(n in e.versions){var c=Object.keys(e.versions[n]);c.forEach(function(o){var t=e.versions[n][o],c={};for(var s in t.defaults){var i=t.defaults[s];c[s]=i["default"]}e.data._collections[o]={item:t.item,defaults:c}}),t={version:parseInt(n),migrate:function(o,t){var c=[],s=Object.keys(e.versions[n]),i=s.length,r=0;console.log("store_names: ",s),s.forEach(function(t){var s=e.versions[n][t];c[t]=null,o.db.objectStoreNames.contains(t)||(c[t]=o.db.createObjectStore(t)),c[t]=o.objectStore(t);for(var a in s.defaults){var l=s.defaults[a];c[t].createIndex(a,a,{unique:l.unique||!1})}o.addEventListener("complete",function(o){r+=1,console.log(r,i),r==i&&console.log(e.data._collections)}),o.onsuccess=function(e){console.log(e)},o.addEventListener("success",function(e){console.log(e)})}),t()}},e.database.migrations.push(t)}console.info("model.schema setup is done!"),o.onSetup&&o.onSetup()},_get_collection_meta:function(o,t){var n=Object.keys(e.versions[o]),c=!1;return n.forEach(function(n){n==t&&(c=e.versions[o][n])}),c},_get_collection_item:function(o,t){var n=Object.keys(e.versions[o]),c=!1;return n.forEach(function(n){n==t&&(c=e.versions[o][n].item)}),c},_set_start_data:function(e){var t=o;return $dhx.isObject(e)?void(t.start_data=e):void alert("The start data does not have a valid format.\nApplication will not start.")},_get_start_data:function(){var e=o;return e.start_data||{}},_setLocalSyncTime:function(e,o){parseInt(o)>0&&(last_sync_time=$dhx.jDBdStorage.get("$dhx.mvp.ui.last_sync_time"),last_sync_time?(last_sync_time=$dhx.crypt.base64_decode(last_sync_time),$dhx.isNumber(parseInt(last_sync_time))&&parseInt(last_sync_time)<parseInt(o)&&(console.log("updating last_sync_time as ",e),$dhx.jDBdStorage.storeObject("$dhx.mvp.ui.last_sync_time",$dhx.crypt.base64_encode(e)))):(console.log("saving last_sync_time as ",e),$dhx.jDBdStorage.storeObject("$dhx.mvp.ui.last_sync_time",$dhx.crypt.base64_encode(e))))},msg_iterator_queue:function(e){o._received_messages_queue.push(e)},_received_messages_queue:[],_collections_to_sync_queue:[],_collections_to_sync:0,_collections_synced:0,_getAllMessagesFromPubNub:function(e,t,n){var c=o,s={start:e,channel:t,callback:function(e){var c=e[0],s=e[1],i=e[2],r=1e4*(new Date).getTime();o._setLocalSyncTime(r,i),_.forEach(c,o.msg_iterator_queue),100===c.length?o._getAllMessagesFromPubNub(s,t,n):n&&n()}};pubnub.history(s),s=null,c=null},_getLastMessagesFromPubNub:function(e,t,n){var c=o,s={end:e,channel:t,callback:function(e){var c=e[0],s=(e[1],e[2]),i=1e4*(new Date).getTime();o._setLocalSyncTime(i,s),_.forEach(c,o.msg_iterator_queue),100===c.length?o._getLastMessagesFromPubNub(s,t,n):n&&n()}};pubnub.history(s),s=null,c=null},_process_collections_to_sync:function(e){var t=null,n=$dhx.jDBdStorage.get("$dhx.mvp.ui.last_sync_time");n=n?parseInt($dhx.crypt.base64_decode(n)):0,o._collections_to_sync_queue.length>0?(t=o._collections_to_sync_queue.splice(0,1),0===n?o._getAllMessagesFromPubNub(n,t,function(){return o._collections_synced+=1,o._collections_synced==o._collections_to_sync?void o._process_received_messages(e):void o._process_collections_to_sync(e)}):o._getLastMessagesFromPubNub(n,t,function(){return o._collections_synced+=1,o._collections_synced==o._collections_to_sync?void o._process_received_messages(e):void o._process_collections_to_sync(e)})):e.onSuccess&&e.onSuccess()},_process_received_messages:function(e){var t={},n=function(e){t[e]=[]},c=function(e){"create"==e.method&&t[e.collection].push(e.model)};_.forEach(Object.keys(o.io),n),_.forEach(o._received_messages_queue,c),o._set_start_data(t),o.add_initial_data({onSuccess:function(){e.onSuccess&&e.onSuccess()}})},sync:function(e){o._collections_to_sync=Object.keys(o.io).length;for(var t in o.io)o._collections_to_sync_queue.push(t);o._process_collections_to_sync(e)},add_initial_data:function(t){var n=o,c=Object.keys(n._get_start_data()),s=(c.length,[]),i=[],r=[],a=[],l=null,d=function(e,o,t){var c=t.shift(),i=o.shift();o.length>0&&t.length>0?n.insert_records_into_table(s[c],i,function(n,c){d(e,o,t)}):0===o.length&&0===t.length?"undefined"==typeof c||"undefined"==typeof i?e&&e():n.insert_records_into_table(s[c],i,function(o,t){e&&e()}):e&&e()};c.forEach(function(o,t){l=e.schema._get_collection_item(1,o),s[l]=Backbone.Model.extend({database:e.database,storeName:o}),i[o]=Backbone.Collection.extend({database:e.database,storeName:o,model:s[l]}),r.push(o),a.push(l)}),d(function(){t.onSuccess&&t.onSuccess()},r,a)},insert_records_into_table:function(e,t,n){var c=o,s=c._get_start_data()[t].shift();s?(s.notify=!1,o.io[t].create({record:s,onSuccess:function(){c.insert_records_into_table(e,t,n)},onFail:function(){}})):n(e,t)},start:function(t){var n=o;t.onSetup=function(){e.data._start(),e.data[Object.keys(e.data._collections)[0]]().fetch({success:function(o,n,c){console.info("The collection "+Object.keys(e.data._collections)[0]+" was fetched and the indexedDB is done!"),t.onSuccess&&t.onSuccess()},error:function(e,o,t){console.log(e)}})},n.setup(t)},_io:{_create:function(o){var t,n="string"==typeof o.record?JSON.parse(o.record):o.record,c=new e.data[o.model],s=new $dhx.ui.mvp.model.helpers.schema.record({model:o.model,record:n}),i=function(e){c.save(e,{success:function(){o.onSuccess&&o.onSuccess(e),n.notify!==!1&&$dhx.ui.Mediator.notify("changeModel",{collection:o.collection,method:"create",model:e,options:null,client_id:$dhx.ui.session.client_id()})},error:function(e,t){dhtmlx.alert({text:"Error creating "+o.model+" model data locally",type:"alert-error"}),o.onFail&&o.onFail()}})};s.__v=+(s.__v||0),s.id?(t=new e.data[o.model]({id:s.id}),t.fetch({success:function(e){var t,n=!1;s.__v>e.get("__v")?i(s):(t="_io._create() -> Record rejected. The version of the record is not greater than local record version."+s,n={error:t},console.warn(t),o.onSuccess&&o.onSuccess(s,n),o.onFail&&o.onFail())},error:function(e,o){"Not Found"==o&&(console.info("Document "+s.id+" not found. I will create then.",s),i(s))}})):i(s)},_update:function(o){var t,n="string"==typeof o.record?JSON.parse(o.record):o.record,c=new e.data[o.model]({id:n.id}),s=!1,i=new $dhx.ui.mvp.model.helpers.schema.record({model:o.model,record:n}),r=0,a=function(e){c.save(e,{success:function(){o.onSuccess&&o.onSuccess(e),n.notify!==!1&&(e.id=n.id,$dhx.ui.Mediator.notify("changeModel",{collection:o.collection,method:"update",model:e,options:null,client_id:$dhx.ui.session.client_id()}))},error:function(e,t){dhtmlx.alert({text:"Error updating "+o.model+" model data locally",type:"alert-error"}),o.onFail&&o.onFail()}})};c.fetch({success:function(e){if(delete i.id,delete i._id,i.__v){if("number"!=typeof i.__v)throw"fDocument version(__v) shall to be a number";if(i.__v<0)throw"fDocument version(__v) shall to greater than zero";i.__v>e.get("__v")?a(i):(t="_io._update() -> Record rejected. The version of the record is not greater than local record version."+i,s={error:t},console.warn(t),o.onSuccess&&o.onSuccess(i,s),o.onFail&&o.onFail())}else r=+(e.get("__v")||0),r+=1,i.__v=r,a(i)},error:function(e,c){"Not Found"==c&&(t=""+o.model+" "+n.id+" not found",c={error:t},o.onSuccess&&o.onSuccess(i,c),dhtmlx.alert({text:t,type:"alert-error"}))}})},_destroy:function(o){var t="string"==typeof o.record?JSON.parse(o.record):o.record,n=new e.data[o.model]({id:t.id}),c=function(){n.destroy({success:function(){o.onSuccess&&o.onSuccess(t),t.notify!==!1&&$dhx.ui.Mediator.notify("changeModel",{collection:o.collection,method:"destroy",model:t,options:null,client_id:$dhx.ui.session.client_id()})},error:function(e,t){dhtmlx.alert({text:"Error deleting "+o.model+" model data locally",type:"alert-error"}),o.onFail&&o.onFail()}})};n.fetch({success:function(e){c()},error:function(e,n){"Not Found"==n&&(dhtmlx.alert({text:""+o.model+" "+t.id+" not found",type:"alert-error"}),o.onFail&&o.onFail())}})},_read:function(o){var t="string"==typeof o.record?JSON.parse(o.record):o.record,n=new e.data[o.model]({id:t.id});n.fetch({success:function(e){t=e.toJSON(),o.onSuccess&&o.onSuccess(e,t)},error:function(e,n){"Not Found"==n&&(dhtmlx.alert({text:""+o.model+" "+t.id+" not found",type:"alert-error"}),o.onFail&&o.onFail(e,n))}})},_readAll:function(o){var t={success:function(e,t,n){o.onSuccess&&o.onSuccess(e,t,n)},error:function(e,t){"Not Found"==t&&(dhtmlx.alert({text:""+o.collection+" not found",type:"alert-error"}),o.onFail&&o.onFail(e,t))}};o.sort&&(t.sort=o.sort),e.data[o.collection]().fetch(t)}},io:{}},t={start:o.start,_get_collection_meta:o._get_collection_meta,_get_collection_item:o._get_collection_item,_set_start_data:o._set_start_data,_get_start_data:o._get_start_data,add_initial_data:o.add_initial_data,sync:o.sync,io:o.io,_io:o._io};return t}(),e}()});