(function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n(require("dexie"),require("dexie-observable")):"function"==typeof define&&define.amd?define(["dexie","dexie-observable"],n):((e="undefined"!=typeof globalThis?globalThis:e||self).Dexie=e.Dexie||{},e.Dexie.Syncable=n(e.Dexie))})(this,function(e){"use strict";function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var E=n(e),c=E.default.Promise;function b(e){return n.prototype.save=function(){return E.default.vip(function(){return e.save()})},n;function n(e,n){this.nodeID=e,n&&E.default.extend(this,n)}}function C(u){return function(e){var c={},n=(e.forEach(function(e){var n;c.hasOwnProperty(e.table)||(c[e.table]=((n={})[1]=[],n[3]=[],n[2]=[],n)),c[e.table][e.type].push(e)}),Object.keys(c)),e=n.map(function(e){return u.table(e)});return u.transaction("rw",e,function(){n.forEach(function(e){var n,t,o,r=u.table(e),a=!r.schema.primKey.keyPath,i=c[e][1],s=c[e][3],e=c[e][2];0<i.length&&r.bulkPut(i.map(function(e){return e.obj}),a?i.map(function(e){return e.key}):void 0),0<e.length&&(n=r,a=(t=e).map(function(e){return e.key}),o={},n.where(":id").anyOf(a).raw().each(function(e,n){o[n.primaryKey+""]=e}).then(function(){var e=t.filter(function(e){return o.hasOwnProperty(e.key+"")}).map(function(n){var t=o[n.key+""];return Object.keys(n.mods).forEach(function(e){E.default.setByKeyPath(t,e,n.mods[e])}),t});return n.bulkPut(e)})),0<s.length&&r.bulkDelete(s.map(function(e){return e.key}))})})}}function m(e){if(0===e.remoteBaseRevisions.length)return{maxClientRevision:1/0,remoteBaseRevision:null};for(var n=e.remoteBaseRevisions.length-1;0<=n;--n)if(e.myRevision>=e.remoteBaseRevisions[n].local)return{maxClientRevision:n===e.remoteBaseRevisions.length-1?1/0:e.remoteBaseRevisions[n+1].local,remoteBaseRevision:e.remoteBaseRevisions[n].remote};return{maxClientRevision:e.remoteBaseRevisions[0].local,remoteBaseRevision:null}}function g(e,n){switch(e.type){case 1:switch(n.type){case 1:return n;case 2:return t=n,i=E.default.deepClone(e),Object.keys(t.mods).forEach(function(e){E.default.setByKeyPath(i.obj,e,t.mods[e])}),i;case 3:return n}break;case 2:switch(n.type){case 1:return n;case 2:return o=e,r=n,a=E.default.deepClone(o),Object.keys(r.mods).forEach(function(n){var t=!1;Object.keys(o.mods).filter(function(e){return 0===n.indexOf(e+".")}).forEach(function(e){E.default.setByKeyPath(a.mods[e],n.substr(e.length+1),r.mods[n]),t=!0}),t||(a.mods[n]=r.mods[n]),Object.keys(o.mods).filter(function(e){return 0===e.indexOf(n+".")}).forEach(function(e){delete a.mods[e]})}),a;case 3:return n}break;case 3:switch(n.type){case 1:return n;case 2:case 3:return e}}var o,r,a,t,i}function r(b,v,e){var p=e;return function(e,o){var u,l,f,i,s,c,d,y,h,r,n,t=function(e,n,t,o){var r={},a=0,i=!1,s=l.id,c=e;return u.transaction("r",u._changes,function(){return u._changes.where("rev").between(e,t,!1,!0).until(function(){if(a===n)return i=!0}).each(function(e){var n,t;c=e.rev,e.source!==s&&(n={type:e.type,table:e.table,key:e.key},1===e.type?n.obj=e.obj:2===e.type&&(n.mods=e.mods),e=e.table+":"+e.key,(t=r[e])?(t=g(t,n),r[e]=t):(r[e]=n,++a))})}).then(function(){var e=Object.keys(r).map(function(e){return r[e]});return f.hasMoreToGive=i,o(e,i,{myRevision:c})})},a=(i=u=b,c=p,d=t,y=f=v,h=o,function e(t,r,n){var a=!1;return n.until(function(){if(r.length===c)return a=!0}).each(function(e,n){r.push({type:1,table:t.currentTable,key:n.key,obj:n.value}),t.currentKey=n.key}).then(function(){var o;return a?(y.hasMoreToGive=!0,h(r,null,!0,{dbUploadState:t})):0===t.tablesToUpload.length?(o=m(s),d(t.localBaseRevision,c-r.length,o.maxClientRevision,function(e,n,t){return r=r.concat(e),t.dbUploadState=null,h(r,o.remoteBaseRevision,n,t)})):(t.currentTable=t.tablesToUpload.shift(),e(t,r,i.table(t.currentTable).orderBy(":id")))})});return 0<=(s=l=e).myRevision?(r=m(e),t(e.myRevision,p,r.maxClientRevision,function(e,n,t){return o(e,r.remoteBaseRevision,n,t)})):null===e.dbUploadState?0===(t=b.tables.filter(function(e){return e.schema.observable}).map(function(e){return e.name})).length?E.default.Promise.resolve(o([],null,!1,{})):(n={tablesToUpload:t,currentTable:t.shift(),currentKey:null},b._changes.orderBy("rev").last(function(e){n.localBaseRevision=e&&e.rev||0;e=b.table(n.currentTable).orderBy(":id");return a(n,[],e)})):(t=e.dbUploadState.currentKey?b.table(e.dbUploadState.currentTable).where(":id").above(e.dbUploadState.currentKey):b.table(n.currentTable).orderBy(":id"),a(E.default.deepClone(e.dbUploadState),[],t))}}var _={ERROR:-1,OFFLINE:0,CONNECTING:1,ONLINE:2,SYNCING:3,ERROR_WILL_RETRY:4},S=E.default.Promise;function v(v,p,m,g,N){a=v;var a,R=function e(n,t,o){function r(){return n.ongoingOperation?n.ongoingOperation=n.ongoingOperation.then(function(){return e(n,t,o)}):n.ongoingOperation=E.default.ignoreTransaction(function(){return E.default.vip(function(){return t()})}).finally(function(){delete n.ongoingOperation}),n.ongoingOperation}return o?a._localSyncNode&&o===a._localSyncNode.id?r():E.default.Promise.reject(new E.default.DatabaseClosedError):a.isOpen()?r():E.default.Promise.reject(new E.default.DatabaseClosedError)},O={hasMoreToGive:!0};function w(){return v._localSyncNode&&v._localSyncNode.id===m}return function(l,u){var f,s=r(v,O,p.partialsThreshold),d=u.url;function y(e){l.status!==e&&(l.status=e,l.save().then(function(){v.syncable.on.statusChanged.fire(e,d),v.observable.broadcastMessage("syncStatusChanged",{newStatus:e,url:d},!1)}).catch("DatabaseClosedError",function(){}))}return u.on("disconnect",function(e){isNaN(e)||y(e)}),y(_.CONNECTING),c();function c(){return R(c,function(){return t(l,e)},m)}function e(e,r,a,n){var t=new S(function(t,o){N.p=function(e){o(e)},E.default.asap(function(){try{p.sync(l.syncContext,d,g,r,l.appliedRemoteRevision,e,a,b,i,function(e){t(e)},n)}catch(e){n(e,1/0)}function n(e,n){o(e),w()&&(!isNaN(n)&&n<1/0?(setTimeout(function(){w()&&(y(_.SYNCING),c().catch("DatabaseClosedError",h))},n),y(_.ERROR_WILL_RETRY),f&&f.disconnect&&f.disconnect(),f=null):h(e))}})});return t.then(function(){}).finally(function(){N.p=null});function i(){return Object.keys(n).forEach(function(e){E.default.setByKeyPath(l,e,n[e])}),t.then(o),l.save()}}function h(e){u.disconnect(_.ERROR,e)}function t(a,i){return s(a,function e(n,t,o,r){return 0===n.length&&"myRevision"in r&&r.myRevision!==a.myRevision?(Object.keys(r).forEach(function(e){E.default.setByKeyPath(a,e,r[e])}),a.save().catch("DatabaseClosedError",function(){}),s(a,e)):i(n,t,o,r)})}function b(e,n,t){var o,r,a,i,s,c=function(e,n){return o.transaction("rw!",o._uncommittedChanges,function(){return o._uncommittedChanges.bulkAdd(e.map(function(e){var n={node:r.id,type:e.type,table:e.table,key:e.key};return e.obj&&(n.obj=e.obj),e.mods&&(n.mods=e.mods),n}))}).then(function(){return r.appliedRemoteRevision=n,r.save()})},u=(i=r=l,s=C(a=o=v),function(n,o){var e=a.tables.filter(function(e){return"_changes"===e.name||"_uncommittedChanges"===e.name||e.schema.observable});return a.transaction("rw!",e,function(){var e=E.default.currentTransaction,t=0;return a._changes.orderBy("rev").last(function(e){t=e&&e.rev||0}).then(function(){return e.source=i.id,a._uncommittedChanges.where("node").equals(i.id).toArray()}).then(function(e){return s(e)}).then(function(){return a._uncommittedChanges.where("node").equals(i.id).delete()}).then(function(){return s(n)}).then(function(){return a._changes.orderBy("rev").last()}).then(function(e){e=e&&e.rev||0;if(i.appliedRemoteRevision=o,i.remoteBaseRevisions.push({remote:o,local:e}),i.myRevision===t&&(i.myRevision=e),1<i.remoteBaseRevisions.length)for(var n=i.remoteBaseRevisions.length-1;0<n;--n)if(i.myRevision>=i.remoteBaseRevisions[n].local){i.remoteBaseRevisions.splice(0,n);break}i.save().catch(function(e){console.warn("Dexie.Syncable: Unable to save SyncNode after applying remote changes: "+(e.stack||e))})})})});return R(b,function(){return w()?(t?c:u)(e,n).catch(function(e){return h(e),S.reject(e)}):S.reject(new E.default.DatabaseClosedError)},m)}function o(e){var r,a,i;function s(){t(l,function(e,n,t,o){p.sync(l.syncContext,d,g,n,l.appliedRemoteRevision,e,t,b,function(){Object.keys(o).forEach(function(e){E.default.setByKeyPath(l,e,o[e])}),l.save().catch("DatabaseClosedError",function(){})},function(e){f&&(f=e,t?s():!isNaN(e.again)&&e.again<1/0?(y(_.ONLINE),setTimeout(function(){f&&(y(_.SYNCING),s())},e.again)):u.disconnect(_.OFFLINE))},function(e,n){!isNaN(n)&&n<1/0?f&&(setTimeout(function(){f&&(y(_.SYNCING),s())},n),y(_.ERROR_WILL_RETRY)):h(e)})}).catch(h)}function n(){f&&(y(_.SYNCING),i?a=!0:c())}function c(){f&&(i=!(a=!1),t(l,function(e,n,t,o){f&&(0<e.length?r.react(e,n,t,function(){Object.keys(o).forEach(function(e){E.default.setByKeyPath(l,e,o[e])}),l.save().catch("DatabaseClosedError",function(){}),c()}):(i=!1,a?c():y(_.ONLINE)))}).catch(function(e){console.error("Got ".concat(e.message," caught by reactToChanges")),h(e)}))}w()?(f=e,u.on("disconnect",function(){if(f){if(f.react)try{f.disconnect()}catch(e){}f=null}}),e.react?(r=e,v.on("changes",n),u.on("disconnect",function(){v.on.changes.unsubscribe(n)}),c()):O.hasMoreToGive?s():f&&!isNaN(f.again)&&f.again<1/0?(y(_.ONLINE),setTimeout(function(){f&&(y(_.SYNCING),s())},f.again)):u.disconnect(_.OFFLINE)):e.disconnect&&e.disconnect()}}}function a(y,h){return function(t,u,l,f,d){var e,n=h.filter(function(e){return e.url===l});return 0<n.length?(e=n[0],E.default.getObjectDiff(e.syncOptions,f,e={}),0!==Object.keys(e).length?y.syncable.disconnect(l).then(o):n[0].connectPromise):o();function o(){var o={p:null},n=v(y,t,d,f,o);r=y,a=u,i=l;var r,a,i,e=function(o){return r.transaction("rw",r._syncNodes,r._changes,function(){if(i)return r._syncNodes.where("url").equalsIgnoreCase(i).first(function(n){var e,t;return n?(e=b(n),n.syncContext=new e(n.id,n.syncContext),n.syncProtocol=a,n.syncOptions=o,r._syncNodes.put(n)):((n=new r.observable.SyncNode).myRevision=-1,n.appliedRemoteRevision=null,n.remoteBaseRevisions=[],n.type="remote",n.syncProtocol=a,n.url=i,n.syncOptions=o,n.lastHeartBeat=Date.now(),n.dbUploadState=null,t=b(n),E.default.Promise.resolve(function(){if(!1===o.initialUpload)return r._changes.toCollection().lastKey(function(e){n.myRevision=e})}()).then(function(){r._syncNodes.add(n).then(function(e){n.syncContext=new t(e),r._syncNodes.put(n)})})),n});throw new Error("Url cannot be empty")})}(f).then(function(e){return n(e,c)}),s=!1,c={url:l,status:_.OFFLINE,connectPromise:e,syncOptions:f,on:E.default.Events(null,"disconnect"),disconnect:function(e,n){var t=h.indexOf(c);0<=t&&h.splice(t,1),n&&o.p&&o.p(n),s||c.on.disconnect.fire(e,n),s=!0}};return h.push(c),e}}}var i=E.default.override,u=E.default.Promise,l=E.default.Observable;function f(t){if(!/^(3|4)\./.test(E.default.version))throw new Error("Missing dexie version 3.x or 4.x");if(!t.observable||"4.0.1-beta.13"!==t.observable.version&&!/^(3|4)\./.test(t.observable.version))throw new Error("Missing dexie-observable version 3.x or 4.x");if(t.syncable){if("4.0.1-beta.13"!==t.syncable.version)throw new Error("Mixed versions of dexie-syncable")}else{var s,n,o=[],e=a(t,o),r=(n=e,function(e,r,a,i){if(s.isOpen()){if(s._localSyncNode)return s._localSyncNode.isMaster?n(e,r,a,i,s._localSyncNode.id):s.table("_syncNodes").where("isMaster").above(0).first(function(e){return s.observable.sendMessage("connect",{protocolName:r,url:a,options:i},e.id,{wantReply:!0})});throw new Error("Precondition failed: local sync node is missing. Make sure Dexie.Observable is active!")}return s.hasBeenClosed()?c.reject(new E.default.DatabaseClosedError):s.hasFailed()?c.reject(new E.default.InvalidStateError("Dexie.Syncable: Cannot connect. Database has failed to open")):new c(function(t,o){s.on("ready",function(){return s._syncNodes.get({url:a},function(e){var n=s.syncable.connect(r,a,i);if(n.then(t,o),!e||!e.appliedRemoteRevision)return n})}),s.open().catch(function(e){o(new E.default.InvalidStateError("Dexie.Syncable: Couldn't connect. Database failed to open",e))})})});(s=t).on("message",function(e){E.default.vip(function(){"connect"===e.type?t.syncable.connect(e.message.protocolName,e.message.url,e.message.options).then(e.resolve,e.reject):"disconnect"===e.type?t.syncable.disconnect(e.message.url).then(e.resolve,e.reject):"syncStatusChanged"===e.type&&t.syncable.on.statusChanged.fire(e.message.newStatus,e.message.url)})}),t.on("cleanup",function(e){e&&E.default.ignoreTransaction(function(){return E.default.vip(function(){return t._syncNodes.where({type:"remote"}).filter(function(e){return e.status!==_.OFFLINE}).toArray(function(e){return u.all(e.map(function(n){return t.syncable.connect(n.syncProtocol,n.url,n.syncOptions).catch(function(e){console.warn("Dexie.Syncable: Could not connect to ".concat(n.url,". ").concat(e.stack||e))})}))})})}).catch("DatabaseClosedError",function(){})}),t.on("ready",function(){t._localSyncNode&&t._localSyncNode.isMaster&&t._syncNodes.where("type").equals("remote").and(function(e){return e.status!==_.OFFLINE}).toArray(function(e){e.forEach(function(e){return t.syncable.connect(e.syncProtocol,e.url,e.syncOptions).catch(function(){})})}).catch("DatabaseClosedError",function(){})},!0),t.syncable={version:"4.0.1-beta.13"},t.syncable.getStatus=function(e,n){return(t.isOpen()?E.default.vip(function(){return t._syncNodes.where("url").equals(e).first(function(e){return e?e.status:_.OFFLINE})}):u.resolve(f.Statuses.OFFLINE)).then(n)},t.syncable.getOptions=function(e,n){return t.transaction("r?",t._syncNodes,function(){return t._syncNodes.where("url").equals(e).first(function(e){return e.syncOptions}).then(n)})},t.syncable.list=function(){return t.transaction("r?",t._syncNodes,function(){return t._syncNodes.where("type").equals("remote").toArray(function(e){return e.map(function(e){return e.url})})})},t.syncable.on=E.default.Events(t,{statusChanged:"asap"}),t.syncable.disconnect=function(n){return E.default.ignoreTransaction(function(){return u.resolve().then(function(){return t._localSyncNode&&t._localSyncNode.isMaster?u.all(o.filter(function(e){return e.url===n}).map(function(e){return e.disconnect(_.OFFLINE)})):t._syncNodes.where("isMaster").above(0).first(function(e){return t.observable.sendMessage("disconnect",{url:n},e.id,{wantReply:!0})})}).then(function(){return t._syncNodes.where("url").equals(n).modify(function(e){e.status=_.OFFLINE})})})},t.syncable.connect=function(e,n,t){t=t||{};var o=f.registeredProtocols[e];return o?r(o,e,n,t):u.reject(new Error("ISyncProtocol '"+e+"' is not registered in Dexie.Syncable.registerSyncProtocol()"))},t.syncable.delete=function(e){return t.syncable.disconnect(e).then(function(){return t.transaction("rw!",t._syncNodes,t._changes,t._uncommittedChanges,function(){var n;return t._syncNodes.where("url").equals(e).toArray(function(e){return e.map(function(e){return e.id})}).then(function(e){return n=e,t._syncNodes.where("id").anyOf(e).delete()}).then(function(){return t._uncommittedChanges.where("node").anyOf(n).delete()})}).then(function(){l.deleteOldChanges(t)})})},t.syncable.unsyncedChanges=function(e){return t._syncNodes.where("url").equals(e).first(function(e){return t._changes.where("rev").above(e.myRevision).toArray()})},t.close=i(t.close,function(e){return function(){return o.forEach(function(e){e.disconnect()}),e.apply(this,arguments)}}),Object.defineProperty(t.observable.SyncNode.prototype,"save",{enumerable:!1,configurable:!0,writable:!0,value:function(){var e=this;return t.transaction("rw?",t._syncNodes,function(){return t._syncNodes.put(e)})}})}}if(f.version="4.0.1-beta.13",f.Statuses=_,f.StatusTexts={"-1":"ERROR",0:"OFFLINE",1:"CONNECTING",2:"ONLINE",3:"SYNCING",4:"ERROR_WILL_RETRY"},f.registeredProtocols={},f.registerSyncProtocol=function(e,n){var t=n.partialsThreshold;if("number"==typeof t){if(isNaN(t)||t<0)throw new Error("The given number for the threshold is not supported")}else n.partialsThreshold=1/0;f.registeredProtocols[e]=n},E.default.Syncable){if("4.0.1-beta.13"!==E.default.Syncable.version)throw new Error("Mixed versions of dexie-syncable")}else E.default.Syncable=f,E.default.addons.push(f);return E.default.Syncable});