@basictech/react 0.1.1-beta.0 → 0.2.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -34,8 +34,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
34
34
  var require_dexie = __commonJS({
35
35
  "../../node_modules/dexie/dist/dexie.js"(exports, module2) {
36
36
  "use strict";
37
- (function(global2, factory) {
38
- typeof exports === "object" && typeof module2 !== "undefined" ? module2.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, global2.Dexie = factory());
37
+ (function(global3, factory) {
38
+ typeof exports === "object" && typeof module2 !== "undefined" ? module2.exports = factory() : typeof define === "function" && define.amd ? define(factory) : (global3 = typeof globalThis !== "undefined" ? globalThis : global3 || self, global3.Dexie = factory());
39
39
  })(exports, function() {
40
40
  "use strict";
41
41
  var extendStatics = function(d, b) {
@@ -131,7 +131,7 @@ var require_dexie = __commonJS({
131
131
  function slice(args, start, end) {
132
132
  return _slice.call(args, start, end);
133
133
  }
134
- function override(origFunc, overridedFactory) {
134
+ function override3(origFunc, overridedFactory) {
135
135
  return overridedFactory(origFunc);
136
136
  }
137
137
  function assert(b) {
@@ -466,7 +466,7 @@ var require_dexie = __commonJS({
466
466
  fullNameExceptions.ModifyError = ModifyError;
467
467
  fullNameExceptions.DexieError = DexieError;
468
468
  fullNameExceptions.BulkError = BulkError;
469
- function nop() {
469
+ function nop2() {
470
470
  }
471
471
  function mirror(val) {
472
472
  return val;
@@ -485,7 +485,7 @@ var require_dexie = __commonJS({
485
485
  };
486
486
  }
487
487
  function hookCreatingChain(f1, f2) {
488
- if (f1 === nop)
488
+ if (f1 === nop2)
489
489
  return f2;
490
490
  return function() {
491
491
  var res = f1.apply(this, arguments);
@@ -503,7 +503,7 @@ var require_dexie = __commonJS({
503
503
  };
504
504
  }
505
505
  function hookDeletingChain(f1, f2) {
506
- if (f1 === nop)
506
+ if (f1 === nop2)
507
507
  return f2;
508
508
  return function() {
509
509
  f1.apply(this, arguments);
@@ -517,7 +517,7 @@ var require_dexie = __commonJS({
517
517
  };
518
518
  }
519
519
  function hookUpdatingChain(f1, f2) {
520
- if (f1 === nop)
520
+ if (f1 === nop2)
521
521
  return f2;
522
522
  return function(modifications) {
523
523
  var res = f1.apply(this, arguments);
@@ -534,7 +534,7 @@ var require_dexie = __commonJS({
534
534
  };
535
535
  }
536
536
  function reverseStoppableEventChain(f1, f2) {
537
- if (f1 === nop)
537
+ if (f1 === nop2)
538
538
  return f2;
539
539
  return function() {
540
540
  if (f2.apply(this, arguments) === false)
@@ -542,8 +542,8 @@ var require_dexie = __commonJS({
542
542
  return f1.apply(this, arguments);
543
543
  };
544
544
  }
545
- function promisableChain(f1, f2) {
546
- if (f1 === nop)
545
+ function promisableChain2(f1, f2) {
546
+ if (f1 === nop2)
547
547
  return f2;
548
548
  return function() {
549
549
  var res = f1.apply(this, arguments);
@@ -592,10 +592,10 @@ var require_dexie = __commonJS({
592
592
  global: true,
593
593
  ref: 0,
594
594
  unhandleds: [],
595
- onunhandled: nop,
595
+ onunhandled: nop2,
596
596
  pgp: false,
597
597
  env: {},
598
- finalize: nop
598
+ finalize: nop2
599
599
  };
600
600
  var PSD = globalPSD;
601
601
  var microtickQueue = [];
@@ -1033,7 +1033,7 @@ var require_dexie = __commonJS({
1033
1033
  return true;
1034
1034
  }
1035
1035
  if (("" + nativePromiseThen).indexOf("[native code]") === -1) {
1036
- incrementExpectedAwaits = decrementExpectedAwaits = nop;
1036
+ incrementExpectedAwaits = decrementExpectedAwaits = nop2;
1037
1037
  }
1038
1038
  function onPossibleParallellAsync(possiblePromise) {
1039
1039
  if (task.echoes && possiblePromise && possiblePromise.constructor === NativePromise) {
@@ -1144,7 +1144,7 @@ var require_dexie = __commonJS({
1144
1144
  if (!db._state.isBeingOpened) {
1145
1145
  if (!db._state.autoOpen)
1146
1146
  return rejection(new exceptions.DatabaseClosed());
1147
- db.open().catch(nop);
1147
+ db.open().catch(nop2);
1148
1148
  }
1149
1149
  return db._state.dbReadyPromise.then(function() {
1150
1150
  return tempTransaction(db, mode, storeNames, fn);
@@ -1691,7 +1691,7 @@ var require_dexie = __commonJS({
1691
1691
  if (!chainFunction)
1692
1692
  chainFunction = reverseStoppableEventChain;
1693
1693
  if (!defaultFunction)
1694
- defaultFunction = nop;
1694
+ defaultFunction = nop2;
1695
1695
  var context = {
1696
1696
  subscribers: [],
1697
1697
  fire: defaultFunction,
@@ -1743,10 +1743,10 @@ var require_dexie = __commonJS({
1743
1743
  this.name = name;
1744
1744
  this.schema = tableSchema;
1745
1745
  this.hook = db._allTables[name] ? db._allTables[name].hook : Events(null, {
1746
- "creating": [hookCreatingChain, nop],
1746
+ "creating": [hookCreatingChain, nop2],
1747
1747
  "reading": [pureFunctionChain, mirror],
1748
- "updating": [hookUpdatingChain, nop],
1749
- "deleting": [hookDeletingChain, nop]
1748
+ "updating": [hookUpdatingChain, nop2],
1749
+ "deleting": [hookDeletingChain, nop2]
1750
1750
  });
1751
1751
  });
1752
1752
  }
@@ -1830,10 +1830,10 @@ var require_dexie = __commonJS({
1830
1830
  return c = advancer;
1831
1831
  }, function(val) {
1832
1832
  cursor.stop(val);
1833
- c = nop;
1833
+ c = nop2;
1834
1834
  }, function(e) {
1835
1835
  cursor.fail(e);
1836
- c = nop;
1836
+ c = nop2;
1837
1837
  }))
1838
1838
  wrappedFn(cursor.value, cursor, function(advancer) {
1839
1839
  return c = advancer;
@@ -3773,7 +3773,7 @@ var require_dexie = __commonJS({
3773
3773
  return this;
3774
3774
  };
3775
3775
  Version2.prototype.upgrade = function(upgradeFunction) {
3776
- this._cfg.contentUpgrade = promisableChain(this._cfg.contentUpgrade || nop, upgradeFunction);
3776
+ this._cfg.contentUpgrade = promisableChain2(this._cfg.contentUpgrade || nop2, upgradeFunction);
3777
3777
  return this;
3778
3778
  };
3779
3779
  return Version2;
@@ -3817,11 +3817,11 @@ var require_dexie = __commonJS({
3817
3817
  }
3818
3818
  function _onDatabaseCreated(_a2, name) {
3819
3819
  var indexedDB2 = _a2.indexedDB, IDBKeyRange = _a2.IDBKeyRange;
3820
- !hasDatabasesNative(indexedDB2) && name !== DBNAMES_DB && getDbNamesTable(indexedDB2, IDBKeyRange).put({ name }).catch(nop);
3820
+ !hasDatabasesNative(indexedDB2) && name !== DBNAMES_DB && getDbNamesTable(indexedDB2, IDBKeyRange).put({ name }).catch(nop2);
3821
3821
  }
3822
3822
  function _onDatabaseDeleted(_a2, name) {
3823
3823
  var indexedDB2 = _a2.indexedDB, IDBKeyRange = _a2.IDBKeyRange;
3824
- !hasDatabasesNative(indexedDB2) && name !== DBNAMES_DB && getDbNamesTable(indexedDB2, IDBKeyRange).delete(name).catch(nop);
3824
+ !hasDatabasesNative(indexedDB2) && name !== DBNAMES_DB && getDbNamesTable(indexedDB2, IDBKeyRange).delete(name).catch(nop2);
3825
3825
  }
3826
3826
  function vip(fn) {
3827
3827
  return newScope(function() {
@@ -4193,7 +4193,7 @@ var require_dexie = __commonJS({
4193
4193
  return db.on.ready.fire(db.vip);
4194
4194
  })).then(function fireRemainders() {
4195
4195
  if (state.onReadyBeingFired.length > 0) {
4196
- var remainders_1 = state.onReadyBeingFired.reduce(promisableChain, nop);
4196
+ var remainders_1 = state.onReadyBeingFired.reduce(promisableChain2, nop2);
4197
4197
  state.onReadyBeingFired = [];
4198
4198
  return DexiePromise.resolve(vip(function() {
4199
4199
  return remainders_1(db.vip);
@@ -4473,25 +4473,25 @@ var require_dexie = __commonJS({
4473
4473
  var _a2 = dxTrans.table(tableName).hook, deleting = _a2.deleting, creating = _a2.creating, updating = _a2.updating;
4474
4474
  switch (req.type) {
4475
4475
  case "add":
4476
- if (creating.fire === nop)
4476
+ if (creating.fire === nop2)
4477
4477
  break;
4478
4478
  return dxTrans._promise("readwrite", function() {
4479
4479
  return addPutOrDelete(req);
4480
4480
  }, true);
4481
4481
  case "put":
4482
- if (creating.fire === nop && updating.fire === nop)
4482
+ if (creating.fire === nop2 && updating.fire === nop2)
4483
4483
  break;
4484
4484
  return dxTrans._promise("readwrite", function() {
4485
4485
  return addPutOrDelete(req);
4486
4486
  }, true);
4487
4487
  case "delete":
4488
- if (deleting.fire === nop)
4488
+ if (deleting.fire === nop2)
4489
4489
  break;
4490
4490
  return dxTrans._promise("readwrite", function() {
4491
4491
  return addPutOrDelete(req);
4492
4492
  }, true);
4493
4493
  case "deleteRange":
4494
- if (deleting.fire === nop)
4494
+ if (deleting.fire === nop2)
4495
4495
  break;
4496
4496
  return dxTrans._promise("readwrite", function() {
4497
4497
  return deleteRange(req);
@@ -5286,9 +5286,9 @@ var require_dexie = __commonJS({
5286
5286
  isBeingOpened: false,
5287
5287
  onReadyBeingFired: null,
5288
5288
  openComplete: false,
5289
- dbReadyResolve: nop,
5289
+ dbReadyResolve: nop2,
5290
5290
  dbReadyPromise: null,
5291
- cancelOpen: nop,
5291
+ cancelOpen: nop2,
5292
5292
  openCanceller: null,
5293
5293
  autoSchema: true,
5294
5294
  PR1398_maxLoop: 3,
@@ -5302,8 +5302,8 @@ var require_dexie = __commonJS({
5302
5302
  });
5303
5303
  this._state = state;
5304
5304
  this.name = name;
5305
- this.on = Events(this, "populate", "blocked", "versionchange", "close", { ready: [promisableChain, nop] });
5306
- this.on.ready.subscribe = override(this.on.ready.subscribe, function(subscribe) {
5305
+ this.on = Events(this, "populate", "blocked", "versionchange", "close", { ready: [promisableChain2, nop2] });
5306
+ this.on.ready.subscribe = override3(this.on.ready.subscribe, function(subscribe) {
5307
5307
  return function(subscriber, bSticky) {
5308
5308
  Dexie3.vip(function() {
5309
5309
  var state2 = _this._state;
@@ -5422,7 +5422,7 @@ var require_dexie = __commonJS({
5422
5422
  reject(new exceptions.DatabaseClosed());
5423
5423
  return;
5424
5424
  }
5425
- _this.open().catch(nop);
5425
+ _this.open().catch(nop2);
5426
5426
  }
5427
5427
  _this._state.dbReadyPromise.then(resolve, reject);
5428
5428
  }).then(fn);
@@ -5612,17 +5612,17 @@ var require_dexie = __commonJS({
5612
5612
  return Dexie3;
5613
5613
  }();
5614
5614
  var symbolObservable = typeof Symbol !== "undefined" && "observable" in Symbol ? Symbol.observable : "@@observable";
5615
- var Observable = function() {
5616
- function Observable2(subscribe) {
5615
+ var Observable3 = function() {
5616
+ function Observable4(subscribe) {
5617
5617
  this._subscribe = subscribe;
5618
5618
  }
5619
- Observable2.prototype.subscribe = function(x, error, complete) {
5619
+ Observable4.prototype.subscribe = function(x, error, complete) {
5620
5620
  return this._subscribe(!x || typeof x === "function" ? { next: x, error, complete } : x);
5621
5621
  };
5622
- Observable2.prototype[symbolObservable] = function() {
5622
+ Observable4.prototype[symbolObservable] = function() {
5623
5623
  return this;
5624
5624
  };
5625
- return Observable2;
5625
+ return Observable4;
5626
5626
  }();
5627
5627
  var domDeps;
5628
5628
  try {
@@ -5636,7 +5636,7 @@ var require_dexie = __commonJS({
5636
5636
  function liveQuery2(querier) {
5637
5637
  var hasValue = false;
5638
5638
  var currentValue;
5639
- var observable = new Observable(function(observer) {
5639
+ var observable = new Observable3(function(observer) {
5640
5640
  var scopeFuncIsAsync = isAsyncFunction(querier);
5641
5641
  function execute(ctx) {
5642
5642
  var wasRootExec = beginMicroTickScope();
@@ -5814,7 +5814,7 @@ var require_dexie = __commonJS({
5814
5814
  derive,
5815
5815
  extend,
5816
5816
  props,
5817
- override,
5817
+ override: override3,
5818
5818
  Events,
5819
5819
  on: globalEvents,
5820
5820
  liveQuery: liveQuery2,
@@ -5957,7 +5957,2029 @@ module.exports = __toCommonJS(src_exports);
5957
5957
  // src/AuthContext.tsx
5958
5958
  var import_react = require("react");
5959
5959
  var import_jwt_decode = require("jwt-decode");
5960
- var import_sync = require("@repo/sync");
5960
+
5961
+ // ../../node_modules/uuid/dist/esm-node/stringify.js
5962
+ var byteToHex = [];
5963
+ for (let i = 0; i < 256; ++i) {
5964
+ byteToHex.push((i + 256).toString(16).slice(1));
5965
+ }
5966
+ function unsafeStringify(arr, offset = 0) {
5967
+ return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
5968
+ }
5969
+
5970
+ // ../../node_modules/uuid/dist/esm-node/rng.js
5971
+ var import_node_crypto = __toESM(require("crypto"));
5972
+ var rnds8Pool = new Uint8Array(256);
5973
+ var poolPtr = rnds8Pool.length;
5974
+ function rng() {
5975
+ if (poolPtr > rnds8Pool.length - 16) {
5976
+ import_node_crypto.default.randomFillSync(rnds8Pool);
5977
+ poolPtr = 0;
5978
+ }
5979
+ return rnds8Pool.slice(poolPtr, poolPtr += 16);
5980
+ }
5981
+
5982
+ // ../../node_modules/uuid/dist/esm-node/v7.js
5983
+ var _seqLow = null;
5984
+ var _seqHigh = null;
5985
+ var _msecs = 0;
5986
+ function v7(options, buf, offset) {
5987
+ options = options || {};
5988
+ let i = buf && offset || 0;
5989
+ const b = buf || new Uint8Array(16);
5990
+ const rnds = options.random || (options.rng || rng)();
5991
+ const msecs = options.msecs !== void 0 ? options.msecs : Date.now();
5992
+ let seq = options.seq !== void 0 ? options.seq : null;
5993
+ let seqHigh = _seqHigh;
5994
+ let seqLow = _seqLow;
5995
+ if (msecs > _msecs && options.msecs === void 0) {
5996
+ _msecs = msecs;
5997
+ if (seq !== null) {
5998
+ seqHigh = null;
5999
+ seqLow = null;
6000
+ }
6001
+ }
6002
+ if (seq !== null) {
6003
+ if (seq > 2147483647) {
6004
+ seq = 2147483647;
6005
+ }
6006
+ seqHigh = seq >>> 19 & 4095;
6007
+ seqLow = seq & 524287;
6008
+ }
6009
+ if (seqHigh === null || seqLow === null) {
6010
+ seqHigh = rnds[6] & 127;
6011
+ seqHigh = seqHigh << 8 | rnds[7];
6012
+ seqLow = rnds[8] & 63;
6013
+ seqLow = seqLow << 8 | rnds[9];
6014
+ seqLow = seqLow << 5 | rnds[10] >>> 3;
6015
+ }
6016
+ if (msecs + 1e4 > _msecs && seq === null) {
6017
+ if (++seqLow > 524287) {
6018
+ seqLow = 0;
6019
+ if (++seqHigh > 4095) {
6020
+ seqHigh = 0;
6021
+ _msecs++;
6022
+ }
6023
+ }
6024
+ } else {
6025
+ _msecs = msecs;
6026
+ }
6027
+ _seqHigh = seqHigh;
6028
+ _seqLow = seqLow;
6029
+ b[i++] = _msecs / 1099511627776 & 255;
6030
+ b[i++] = _msecs / 4294967296 & 255;
6031
+ b[i++] = _msecs / 16777216 & 255;
6032
+ b[i++] = _msecs / 65536 & 255;
6033
+ b[i++] = _msecs / 256 & 255;
6034
+ b[i++] = _msecs & 255;
6035
+ b[i++] = seqHigh >>> 4 & 15 | 112;
6036
+ b[i++] = seqHigh & 255;
6037
+ b[i++] = seqLow >>> 13 & 63 | 128;
6038
+ b[i++] = seqLow >>> 5 & 255;
6039
+ b[i++] = seqLow << 3 & 255 | rnds[10] & 7;
6040
+ b[i++] = rnds[11];
6041
+ b[i++] = rnds[12];
6042
+ b[i++] = rnds[13];
6043
+ b[i++] = rnds[14];
6044
+ b[i++] = rnds[15];
6045
+ return buf || unsafeStringify(b);
6046
+ }
6047
+ var v7_default = v7;
6048
+
6049
+ // ../../node_modules/dexie/import-wrapper.mjs
6050
+ var import_dexie = __toESM(require_dexie(), 1);
6051
+ var DexieSymbol = Symbol.for("Dexie");
6052
+ var Dexie = globalThis[DexieSymbol] || (globalThis[DexieSymbol] = import_dexie.default);
6053
+ if (import_dexie.default.semVer !== Dexie.semVer) {
6054
+ throw new Error(`Two different versions of Dexie loaded in the same app: ${import_dexie.default.semVer} and ${Dexie.semVer}`);
6055
+ }
6056
+ var {
6057
+ liveQuery,
6058
+ mergeRanges,
6059
+ rangesOverlap,
6060
+ RangeSet,
6061
+ cmp,
6062
+ Entity,
6063
+ PropModSymbol,
6064
+ PropModification,
6065
+ replacePrefix,
6066
+ add,
6067
+ remove
6068
+ } = Dexie;
6069
+ var import_wrapper_default = Dexie;
6070
+
6071
+ // ../../node_modules/dexie-observable/dist/dexie-observable.es.js
6072
+ function nop() {
6073
+ }
6074
+ function promisableChain(f1, f2) {
6075
+ if (f1 === nop)
6076
+ return f2;
6077
+ return function() {
6078
+ var res = f1.apply(this, arguments);
6079
+ if (res && typeof res.then === "function") {
6080
+ var thiz = this, args = arguments;
6081
+ return res.then(function() {
6082
+ return f2.apply(thiz, args);
6083
+ });
6084
+ }
6085
+ return f2.apply(this, arguments);
6086
+ };
6087
+ }
6088
+ function createUUID() {
6089
+ var d = Date.now();
6090
+ var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
6091
+ var r = (d + Math.random() * 16) % 16 | 0;
6092
+ d = Math.floor(d / 16);
6093
+ return (c === "x" ? r : r & 7 | 8).toString(16);
6094
+ });
6095
+ return uuid;
6096
+ }
6097
+ function initOverrideCreateTransaction(db, wakeupObservers) {
6098
+ return function overrideCreateTransaction(origFunc) {
6099
+ return function(mode, storenames, dbschema, parent) {
6100
+ if (db.dynamicallyOpened())
6101
+ return origFunc.apply(this, arguments);
6102
+ var addChanges = false;
6103
+ if (mode === "readwrite" && storenames.some(function(storeName) {
6104
+ return dbschema[storeName] && dbschema[storeName].observable;
6105
+ })) {
6106
+ addChanges = true;
6107
+ storenames = storenames.slice(0);
6108
+ if (storenames.indexOf("_changes") === -1)
6109
+ storenames.push("_changes");
6110
+ }
6111
+ var trans = origFunc.call(this, mode, storenames, dbschema, parent);
6112
+ if (addChanges) {
6113
+ trans._lastWrittenRevision = 0;
6114
+ trans.on("complete", function() {
6115
+ if (trans._lastWrittenRevision) {
6116
+ if (!parent) {
6117
+ if (wakeupObservers.timeoutHandle)
6118
+ clearTimeout(wakeupObservers.timeoutHandle);
6119
+ wakeupObservers.timeoutHandle = setTimeout(function() {
6120
+ delete wakeupObservers.timeoutHandle;
6121
+ wakeupObservers(trans._lastWrittenRevision);
6122
+ }, 25);
6123
+ } else {
6124
+ var rootTransaction = function findRootTransaction(trans2) {
6125
+ return trans2.parent ? findRootTransaction(trans2.parent) : trans2;
6126
+ }(parent);
6127
+ rootTransaction._lastWrittenRevision = Math.max(trans._lastWrittenRevision, rootTransaction.lastWrittenRevision || 0);
6128
+ }
6129
+ }
6130
+ });
6131
+ if (trans.parent && trans.parent.source)
6132
+ trans.source = trans.parent.source;
6133
+ }
6134
+ return trans;
6135
+ };
6136
+ };
6137
+ }
6138
+ function initWakeupObservers(db, Observable3, localStorage) {
6139
+ return function wakeupObservers(lastWrittenRevision) {
6140
+ if (Observable3.latestRevision[db.name] < lastWrittenRevision) {
6141
+ Observable3.latestRevision[db.name] = lastWrittenRevision;
6142
+ import_wrapper_default.ignoreTransaction(function() {
6143
+ Observable3.on("latestRevisionIncremented").fire(db.name, lastWrittenRevision);
6144
+ });
6145
+ if (localStorage)
6146
+ localStorage.setItem("Dexie.Observable/latestRevision/" + db.name, lastWrittenRevision);
6147
+ }
6148
+ };
6149
+ }
6150
+ var CREATE = 1;
6151
+ var UPDATE = 2;
6152
+ var DELETE = 3;
6153
+ function initCreatingHook(db, table) {
6154
+ return function creatingHook(primKey, obj, trans) {
6155
+ var rv = void 0;
6156
+ if (primKey === void 0 && table.schema.primKey.uuid) {
6157
+ primKey = rv = import_wrapper_default.Observable.createUUID();
6158
+ if (table.schema.primKey.keyPath) {
6159
+ import_wrapper_default.setByKeyPath(obj, table.schema.primKey.keyPath, primKey);
6160
+ }
6161
+ }
6162
+ var change = {
6163
+ source: trans.source || null,
6164
+ table: table.name,
6165
+ key: primKey === void 0 ? null : primKey,
6166
+ type: CREATE,
6167
+ obj
6168
+ };
6169
+ var promise = db._changes.add(change).then(function(rev) {
6170
+ trans._lastWrittenRevision = Math.max(trans._lastWrittenRevision, rev);
6171
+ return rev;
6172
+ });
6173
+ this.onsuccess = function(resultKey) {
6174
+ if (primKey != resultKey)
6175
+ promise._then(function() {
6176
+ change.key = resultKey;
6177
+ db._changes.put(change);
6178
+ });
6179
+ };
6180
+ this.onerror = function() {
6181
+ promise._then(function(rev) {
6182
+ db._changes.delete(rev);
6183
+ });
6184
+ };
6185
+ return rv;
6186
+ };
6187
+ }
6188
+ function initUpdatingHook(db, tableName) {
6189
+ return function updatingHook(mods, primKey, oldObj, trans) {
6190
+ var modsWithoutUndefined = {};
6191
+ var anythingChanged = false;
6192
+ var newObj = import_wrapper_default.deepClone(oldObj);
6193
+ for (var propPath in mods) {
6194
+ var mod = mods[propPath];
6195
+ if (typeof mod === "undefined") {
6196
+ import_wrapper_default.delByKeyPath(newObj, propPath);
6197
+ modsWithoutUndefined[propPath] = null;
6198
+ anythingChanged = true;
6199
+ } else {
6200
+ var currentValue = import_wrapper_default.getByKeyPath(oldObj, propPath);
6201
+ if (mod !== currentValue && JSON.stringify(mod) !== JSON.stringify(currentValue)) {
6202
+ import_wrapper_default.setByKeyPath(newObj, propPath, mod);
6203
+ modsWithoutUndefined[propPath] = mod;
6204
+ anythingChanged = true;
6205
+ }
6206
+ }
6207
+ }
6208
+ if (anythingChanged) {
6209
+ var change = {
6210
+ source: trans.source || null,
6211
+ table: tableName,
6212
+ key: primKey,
6213
+ type: UPDATE,
6214
+ mods: modsWithoutUndefined,
6215
+ oldObj,
6216
+ obj: newObj
6217
+ };
6218
+ var promise = db._changes.add(change);
6219
+ this.onsuccess = function() {
6220
+ promise._then(function(rev) {
6221
+ trans._lastWrittenRevision = Math.max(trans._lastWrittenRevision, rev);
6222
+ });
6223
+ };
6224
+ this.onerror = function() {
6225
+ promise._then(function(rev) {
6226
+ db._changes.delete(rev);
6227
+ });
6228
+ };
6229
+ }
6230
+ };
6231
+ }
6232
+ function initDeletingHook(db, tableName) {
6233
+ return function deletingHook(primKey, obj, trans) {
6234
+ var promise = db._changes.add({
6235
+ source: trans.source || null,
6236
+ table: tableName,
6237
+ key: primKey,
6238
+ type: DELETE,
6239
+ oldObj: obj
6240
+ }).then(function(rev) {
6241
+ trans._lastWrittenRevision = Math.max(trans._lastWrittenRevision, rev);
6242
+ return rev;
6243
+ }).catch(function(e) {
6244
+ console.log(obj);
6245
+ console.log(e.stack);
6246
+ });
6247
+ this.onerror = function() {
6248
+ promise._then(function(rev) {
6249
+ db._changes.delete(rev);
6250
+ });
6251
+ };
6252
+ };
6253
+ }
6254
+ function initCrudMonitor(db) {
6255
+ return function crudMonitor(table) {
6256
+ if (table.hook._observing)
6257
+ return;
6258
+ table.hook._observing = true;
6259
+ var tableName = table.name;
6260
+ table.hook("creating").subscribe(initCreatingHook(db, table));
6261
+ table.hook("updating").subscribe(initUpdatingHook(db, tableName));
6262
+ table.hook("deleting").subscribe(initDeletingHook(db, tableName));
6263
+ };
6264
+ }
6265
+ function initOnStorage(Observable3) {
6266
+ return function onStorage(event) {
6267
+ if (event.key && event.key.indexOf("Dexie.Observable/") === 0) {
6268
+ var parts = event.key.split("/");
6269
+ var prop = parts[1];
6270
+ var dbname = parts[2];
6271
+ if (prop === "latestRevision") {
6272
+ var rev = parseInt(event.newValue, 10);
6273
+ if (!isNaN(rev) && rev > Observable3.latestRevision[dbname]) {
6274
+ Observable3.latestRevision[dbname] = rev;
6275
+ import_wrapper_default.ignoreTransaction(function() {
6276
+ Observable3.on("latestRevisionIncremented").fire(dbname, rev);
6277
+ });
6278
+ }
6279
+ } else if (prop.indexOf("deadnode:") === 0) {
6280
+ var nodeID = parseInt(prop.split(":")[1], 10);
6281
+ if (event.newValue) {
6282
+ Observable3.on.suicideNurseCall.fire(dbname, nodeID);
6283
+ }
6284
+ } else if (prop === "intercomm") {
6285
+ if (event.newValue) {
6286
+ Observable3.on.intercomm.fire(dbname);
6287
+ }
6288
+ }
6289
+ }
6290
+ };
6291
+ }
6292
+ function initOverrideOpen(db, SyncNode, crudMonitor) {
6293
+ return function overrideOpen(origOpen) {
6294
+ return function() {
6295
+ Object.keys(db._allTables).forEach(function(tableName) {
6296
+ var table = db._allTables[tableName];
6297
+ if (table.schema.observable) {
6298
+ crudMonitor(table);
6299
+ }
6300
+ if (table.name === "_syncNodes") {
6301
+ table.mapToClass(SyncNode);
6302
+ }
6303
+ });
6304
+ return origOpen.apply(this, arguments);
6305
+ };
6306
+ };
6307
+ }
6308
+ var Promise$2 = import_wrapper_default.Promise;
6309
+ function initIntercomm(db, Observable3, SyncNode, mySyncNode, localStorage) {
6310
+ var requestsWaitingForReply = {};
6311
+ db.observable.sendMessage = function(type, message, destinationNode, options) {
6312
+ options = options || {};
6313
+ if (!mySyncNode.node)
6314
+ return options.wantReply ? Promise$2.reject(new import_wrapper_default.DatabaseClosedError()) : Promise$2.resolve();
6315
+ var msg = { message, destinationNode, sender: mySyncNode.node.id, type };
6316
+ import_wrapper_default.extend(msg, options);
6317
+ return import_wrapper_default.ignoreTransaction(function() {
6318
+ var tables = ["_intercomm"];
6319
+ if (options.wantReply)
6320
+ tables.push("_syncNodes");
6321
+ var promise = db.transaction("rw", tables, function() {
6322
+ if (options.wantReply) {
6323
+ return db._syncNodes.where("id").equals(destinationNode).count(function(receiverAlive) {
6324
+ if (receiverAlive)
6325
+ return db._intercomm.add(msg);
6326
+ else
6327
+ return db._syncNodes.where("isMaster").above(0).first(function(masterNode) {
6328
+ msg.destinationNode = masterNode.id;
6329
+ return db._intercomm.add(msg);
6330
+ });
6331
+ });
6332
+ } else {
6333
+ return db._intercomm.add(msg);
6334
+ }
6335
+ }).then(function(messageId) {
6336
+ var rv = null;
6337
+ if (options.wantReply) {
6338
+ rv = new Promise$2(function(resolve, reject) {
6339
+ requestsWaitingForReply[messageId.toString()] = { resolve, reject };
6340
+ });
6341
+ }
6342
+ if (localStorage) {
6343
+ localStorage.setItem("Dexie.Observable/intercomm/" + db.name, messageId.toString());
6344
+ }
6345
+ Observable3.on.intercomm.fire(db.name);
6346
+ return rv;
6347
+ });
6348
+ if (!options.wantReply) {
6349
+ promise.catch(function() {
6350
+ });
6351
+ return;
6352
+ } else {
6353
+ return promise;
6354
+ }
6355
+ });
6356
+ };
6357
+ db.observable.broadcastMessage = function(type, message, bIncludeSelf) {
6358
+ if (!mySyncNode.node)
6359
+ return;
6360
+ var mySyncNodeId = mySyncNode.node.id;
6361
+ import_wrapper_default.ignoreTransaction(function() {
6362
+ db._syncNodes.toArray(function(nodes) {
6363
+ return Promise$2.all(nodes.filter(function(node) {
6364
+ return node.type === "local" && (bIncludeSelf || node.id !== mySyncNodeId);
6365
+ }).map(function(node) {
6366
+ return db.observable.sendMessage(type, message, node.id);
6367
+ }));
6368
+ }).catch(function() {
6369
+ });
6370
+ });
6371
+ };
6372
+ function consumeIntercommMessages() {
6373
+ if (!mySyncNode.node)
6374
+ return Promise$2.reject(new import_wrapper_default.DatabaseClosedError());
6375
+ return import_wrapper_default.ignoreTransaction(function() {
6376
+ return db.transaction("rw", "_intercomm", function() {
6377
+ return db._intercomm.where({ destinationNode: mySyncNode.node.id }).toArray(function(messages) {
6378
+ messages.forEach(function(msg) {
6379
+ return consumeMessage(msg);
6380
+ });
6381
+ return db._intercomm.where("id").anyOf(messages.map(function(msg) {
6382
+ return msg.id;
6383
+ })).delete();
6384
+ });
6385
+ });
6386
+ });
6387
+ }
6388
+ function consumeMessage(msg) {
6389
+ if (msg.type === "response") {
6390
+ var request = requestsWaitingForReply[msg.requestId.toString()];
6391
+ if (request) {
6392
+ if (msg.isFailure) {
6393
+ request.reject(msg.message.error);
6394
+ } else {
6395
+ request.resolve(msg.message.result);
6396
+ }
6397
+ delete requestsWaitingForReply[msg.requestId.toString()];
6398
+ }
6399
+ } else {
6400
+ msg.resolve = function(result) {
6401
+ db.observable.sendMessage("response", { result }, msg.sender, { requestId: msg.id });
6402
+ };
6403
+ msg.reject = function(error) {
6404
+ db.observable.sendMessage("response", { error: error.toString() }, msg.sender, { isFailure: true, requestId: msg.id });
6405
+ };
6406
+ db.on.message.fire(msg);
6407
+ }
6408
+ }
6409
+ function onIntercomm(dbname) {
6410
+ if (dbname === db.name) {
6411
+ consumeIntercommMessages().catch("DatabaseClosedError", function() {
6412
+ });
6413
+ }
6414
+ }
6415
+ return {
6416
+ onIntercomm,
6417
+ consumeIntercommMessages
6418
+ };
6419
+ }
6420
+ function overrideParseStoresSpec(origFunc) {
6421
+ return function(stores, dbSchema) {
6422
+ stores["_changes"] = "++rev";
6423
+ stores["_syncNodes"] = "++id,myRevision,lastHeartBeat,&url,isMaster,type,status";
6424
+ stores["_intercomm"] = "++id,destinationNode";
6425
+ stores["_uncommittedChanges"] = "++id,node";
6426
+ origFunc.call(this, stores, dbSchema);
6427
+ Object.keys(dbSchema).forEach(function(tableName) {
6428
+ var schema = dbSchema[tableName];
6429
+ if (schema.primKey.name.indexOf("$$") === 0) {
6430
+ schema.primKey.uuid = true;
6431
+ schema.primKey.name = schema.primKey.name.substr(2);
6432
+ schema.primKey.keyPath = schema.primKey.keyPath.substr(2);
6433
+ }
6434
+ });
6435
+ Object.keys(dbSchema).forEach(function(tableName) {
6436
+ if (tableName.indexOf("_") !== 0 && tableName.indexOf("$") !== 0) {
6437
+ dbSchema[tableName].observable = true;
6438
+ }
6439
+ });
6440
+ };
6441
+ }
6442
+ function deleteOldChanges(db) {
6443
+ var CHUNK_SIZE = 100;
6444
+ import_wrapper_default.ignoreTransaction(function() {
6445
+ return db._syncNodes.orderBy("myRevision").first(function(oldestNode) {
6446
+ return db._changes.where("rev").below(oldestNode.myRevision).limit(CHUNK_SIZE).primaryKeys();
6447
+ }).then(function(keysToDelete) {
6448
+ if (keysToDelete.length === 0)
6449
+ return;
6450
+ return db._changes.bulkDelete(keysToDelete).then(function() {
6451
+ if (keysToDelete.length === CHUNK_SIZE) {
6452
+ setTimeout(function() {
6453
+ return db.isOpen() && deleteOldChanges(db);
6454
+ }, 500);
6455
+ }
6456
+ });
6457
+ });
6458
+ }).catch(function() {
6459
+ });
6460
+ }
6461
+ var global2 = self;
6462
+ var DatabaseChange = import_wrapper_default.defineClass({
6463
+ rev: Number,
6464
+ source: String,
6465
+ table: String,
6466
+ key: Object,
6467
+ type: Number,
6468
+ obj: Object,
6469
+ mods: Object,
6470
+ oldObj: Object
6471
+ // DELETE: oldObj contains the object deleted. UPDATE: oldObj contains the old object before updates applied.
6472
+ });
6473
+ var override = import_wrapper_default.override;
6474
+ var Promise$1 = import_wrapper_default.Promise;
6475
+ var browserIsShuttingDown = false;
6476
+ function Observable(db) {
6477
+ if (!/^(3|4)\./.test(import_wrapper_default.version))
6478
+ throw new Error("Missing dexie version 3.x or 4.x");
6479
+ if (db.observable) {
6480
+ if (db.observable.version !== "{version}")
6481
+ throw new Error("Mixed versions of dexie-observable");
6482
+ return;
6483
+ }
6484
+ var NODE_TIMEOUT = 2e4, HIBERNATE_GRACE_PERIOD = 2e4, LOCAL_POLL = 500, HEARTBEAT_INTERVAL = NODE_TIMEOUT - 5e3;
6485
+ var localStorage = Observable.localStorageImpl;
6486
+ var SyncNode = import_wrapper_default.defineClass({
6487
+ //id: Number,
6488
+ myRevision: Number,
6489
+ type: String,
6490
+ lastHeartBeat: Number,
6491
+ deleteTimeStamp: Number,
6492
+ url: String,
6493
+ isMaster: Number,
6494
+ // Below properties should be extended in Dexie.Syncable. Not here. They apply to remote nodes only (type == "remote"):
6495
+ syncProtocol: String,
6496
+ syncContext: null,
6497
+ syncOptions: Object,
6498
+ connected: false,
6499
+ status: Number,
6500
+ appliedRemoteRevision: null,
6501
+ remoteBaseRevisions: [{ local: Number, remote: null }],
6502
+ dbUploadState: {
6503
+ tablesToUpload: [String],
6504
+ currentTable: String,
6505
+ currentKey: null,
6506
+ localBaseRevision: Number
6507
+ }
6508
+ });
6509
+ db.observable = { version: "{version}" };
6510
+ db.observable.SyncNode = SyncNode;
6511
+ var wakeupObservers = initWakeupObservers(db, Observable, localStorage);
6512
+ var overrideCreateTransaction = initOverrideCreateTransaction(db, wakeupObservers);
6513
+ var crudMonitor = initCrudMonitor(db);
6514
+ var overrideOpen = initOverrideOpen(db, SyncNode, crudMonitor);
6515
+ var mySyncNode = { node: null };
6516
+ var intercomm = initIntercomm(db, Observable, SyncNode, mySyncNode, localStorage);
6517
+ var onIntercomm = intercomm.onIntercomm;
6518
+ var consumeIntercommMessages = intercomm.consumeIntercommMessages;
6519
+ Object.defineProperty(db, "_localSyncNode", {
6520
+ get: function() {
6521
+ return mySyncNode.node;
6522
+ }
6523
+ });
6524
+ var pollHandle = null, heartbeatHandle = null;
6525
+ if (import_wrapper_default.fake) {
6526
+ db.version(1).stores({
6527
+ _syncNodes: "++id,myRevision,lastHeartBeat",
6528
+ _changes: "++rev",
6529
+ _intercomm: "++id,destinationNode",
6530
+ _uncommittedChanges: "++id,node"
6531
+ });
6532
+ db._syncNodes.mapToClass(SyncNode);
6533
+ db._changes.mapToClass(DatabaseChange);
6534
+ mySyncNode.node = new SyncNode({
6535
+ myRevision: 0,
6536
+ type: "local",
6537
+ lastHeartBeat: Date.now(),
6538
+ deleteTimeStamp: null
6539
+ });
6540
+ }
6541
+ db.Version.prototype._parseStoresSpec = override(db.Version.prototype._parseStoresSpec, overrideParseStoresSpec);
6542
+ db.on.addEventType({
6543
+ changes: "asap",
6544
+ cleanup: [promisableChain, nop],
6545
+ message: "asap"
6546
+ });
6547
+ db._createTransaction = override(db._createTransaction, overrideCreateTransaction);
6548
+ Observable.latestRevision[db.name] = Observable.latestRevision[db.name] || 0;
6549
+ db.open = override(db.open, overrideOpen);
6550
+ db.close = override(db.close, function(origClose) {
6551
+ return function() {
6552
+ if (db.dynamicallyOpened())
6553
+ return origClose.apply(this, arguments);
6554
+ if (wakeupObservers.timeoutHandle) {
6555
+ clearTimeout(wakeupObservers.timeoutHandle);
6556
+ delete wakeupObservers.timeoutHandle;
6557
+ }
6558
+ Observable.on("latestRevisionIncremented").unsubscribe(onLatestRevisionIncremented);
6559
+ Observable.on("suicideNurseCall").unsubscribe(onSuicide);
6560
+ Observable.on("intercomm").unsubscribe(onIntercomm);
6561
+ Observable.on("beforeunload").unsubscribe(onBeforeUnload);
6562
+ if (mySyncNode.node && mySyncNode.node.id) {
6563
+ Observable.on.suicideNurseCall.fire(db.name, mySyncNode.node.id);
6564
+ if (localStorage) {
6565
+ localStorage.setItem("Dexie.Observable/deadnode:" + mySyncNode.node.id.toString() + "/" + db.name, "dead");
6566
+ }
6567
+ mySyncNode.node.deleteTimeStamp = 1;
6568
+ mySyncNode.node.lastHeartBeat = 0;
6569
+ db._syncNodes.put(mySyncNode.node);
6570
+ mySyncNode.node = null;
6571
+ }
6572
+ if (pollHandle)
6573
+ clearTimeout(pollHandle);
6574
+ pollHandle = null;
6575
+ if (heartbeatHandle)
6576
+ clearTimeout(heartbeatHandle);
6577
+ heartbeatHandle = null;
6578
+ return origClose.apply(this, arguments);
6579
+ };
6580
+ });
6581
+ db.delete = override(db.delete, function(origDelete) {
6582
+ return function() {
6583
+ return origDelete.apply(this, arguments).then(function(result) {
6584
+ Observable.latestRevision[db.name] = 0;
6585
+ return result;
6586
+ });
6587
+ };
6588
+ });
6589
+ db.on("ready", function startObserving() {
6590
+ if (db.dynamicallyOpened())
6591
+ return db;
6592
+ return db.table("_changes").orderBy("rev").last(function(lastChange) {
6593
+ var latestRevision = lastChange ? lastChange.rev : 0;
6594
+ mySyncNode.node = new SyncNode({
6595
+ myRevision: latestRevision,
6596
+ type: "local",
6597
+ lastHeartBeat: Date.now(),
6598
+ deleteTimeStamp: null,
6599
+ isMaster: 0
6600
+ });
6601
+ if (Observable.latestRevision[db.name] < latestRevision) {
6602
+ Observable.latestRevision[db.name] = latestRevision;
6603
+ import_wrapper_default.ignoreTransaction(function() {
6604
+ Observable.on.latestRevisionIncremented.fire(latestRevision);
6605
+ });
6606
+ }
6607
+ return db._syncNodes.put(mySyncNode.node).then(import_wrapper_default.ignoreTransaction(function() {
6608
+ var mySyncNodeShouldBecomeMaster = 1;
6609
+ return db._syncNodes.orderBy("isMaster").reverse().modify(function(existingNode) {
6610
+ if (existingNode.isMaster) {
6611
+ if (existingNode.lastHeartBeat < Date.now() - NODE_TIMEOUT) {
6612
+ existingNode.isMaster = 0;
6613
+ } else {
6614
+ mySyncNodeShouldBecomeMaster = 0;
6615
+ }
6616
+ }
6617
+ if (!mySyncNode.node)
6618
+ return;
6619
+ if (existingNode.id === mySyncNode.node.id) {
6620
+ existingNode.isMaster = mySyncNode.node.isMaster = mySyncNodeShouldBecomeMaster;
6621
+ }
6622
+ });
6623
+ })).then(function() {
6624
+ Observable.on("latestRevisionIncremented", onLatestRevisionIncremented);
6625
+ Observable.on("beforeunload", onBeforeUnload);
6626
+ Observable.on("suicideNurseCall", onSuicide);
6627
+ Observable.on("intercomm", onIntercomm);
6628
+ pollHandle = setTimeout(poll, LOCAL_POLL);
6629
+ heartbeatHandle = setTimeout(heartbeat, HEARTBEAT_INTERVAL);
6630
+ }).then(function() {
6631
+ cleanup();
6632
+ });
6633
+ });
6634
+ }, true);
6635
+ var handledRevision = 0;
6636
+ function onLatestRevisionIncremented(dbname, latestRevision) {
6637
+ if (dbname === db.name) {
6638
+ if (handledRevision >= latestRevision)
6639
+ return;
6640
+ handledRevision = latestRevision;
6641
+ import_wrapper_default.vip(function() {
6642
+ readChanges().catch("DatabaseClosedError", function() {
6643
+ });
6644
+ });
6645
+ }
6646
+ }
6647
+ function readChanges(latestRevision, recursion, wasPartial) {
6648
+ if (!recursion && readChanges.ongoingOperation) {
6649
+ return readChanges.ongoingOperation;
6650
+ }
6651
+ var partial = false;
6652
+ var ourSyncNode = mySyncNode.node;
6653
+ if (!ourSyncNode) {
6654
+ return Promise$1.reject(new import_wrapper_default.DatabaseClosedError());
6655
+ }
6656
+ var LIMIT = 1e3;
6657
+ var promise = db._changes.where("rev").above(ourSyncNode.myRevision).limit(LIMIT).toArray(function(changes) {
6658
+ if (changes.length > 0) {
6659
+ var lastChange = changes[changes.length - 1];
6660
+ partial = changes.length === LIMIT;
6661
+ db.on("changes").fire(changes, partial);
6662
+ ourSyncNode.myRevision = lastChange.rev;
6663
+ } else if (wasPartial) {
6664
+ db.on("changes").fire([], false);
6665
+ }
6666
+ var ourNodeStillExists = false;
6667
+ return db._syncNodes.where(":id").equals(ourSyncNode.id).modify(function(syncNode) {
6668
+ ourNodeStillExists = true;
6669
+ syncNode.lastHeartBeat = Date.now();
6670
+ syncNode.deleteTimeStamp = null;
6671
+ syncNode.myRevision = Math.max(syncNode.myRevision, ourSyncNode.myRevision);
6672
+ }).then(function() {
6673
+ return ourNodeStillExists;
6674
+ });
6675
+ }).then(function(ourNodeStillExists) {
6676
+ if (!ourNodeStillExists) {
6677
+ if (browserIsShuttingDown) {
6678
+ throw new Error("Browser is shutting down");
6679
+ } else {
6680
+ db.close();
6681
+ console.error("Out of sync");
6682
+ if (global2.location)
6683
+ global2.location.reload(true);
6684
+ throw new Error("Out of sync");
6685
+ }
6686
+ }
6687
+ if (partial || Observable.latestRevision[db.name] > ourSyncNode.myRevision) {
6688
+ return readChanges(Observable.latestRevision[db.name], (recursion || 0) + 1, partial);
6689
+ }
6690
+ }).finally(function() {
6691
+ delete readChanges.ongoingOperation;
6692
+ });
6693
+ if (!recursion) {
6694
+ readChanges.ongoingOperation = promise;
6695
+ }
6696
+ return promise;
6697
+ }
6698
+ function heartbeat() {
6699
+ heartbeatHandle = null;
6700
+ var currentInstance = mySyncNode.node && mySyncNode.node.id;
6701
+ if (!currentInstance)
6702
+ return;
6703
+ db.transaction("rw!", db._syncNodes, function() {
6704
+ db._syncNodes.where({ id: currentInstance }).first(function(ourSyncNode) {
6705
+ if (!ourSyncNode) {
6706
+ if (db.isOpen())
6707
+ db.close();
6708
+ return;
6709
+ }
6710
+ ourSyncNode.lastHeartBeat = Date.now();
6711
+ ourSyncNode.deleteTimeStamp = null;
6712
+ return db._syncNodes.put(ourSyncNode);
6713
+ });
6714
+ }).catch("DatabaseClosedError", function() {
6715
+ }).finally(function() {
6716
+ if (mySyncNode.node && mySyncNode.node.id === currentInstance && db.isOpen()) {
6717
+ heartbeatHandle = setTimeout(heartbeat, HEARTBEAT_INTERVAL);
6718
+ }
6719
+ });
6720
+ }
6721
+ function poll() {
6722
+ pollHandle = null;
6723
+ var currentInstance = mySyncNode.node && mySyncNode.node.id;
6724
+ if (!currentInstance)
6725
+ return;
6726
+ import_wrapper_default.vip(function() {
6727
+ readChanges(Observable.latestRevision[db.name]).then(cleanup).then(consumeIntercommMessages).catch("DatabaseClosedError", function() {
6728
+ }).finally(function() {
6729
+ if (mySyncNode.node && mySyncNode.node.id === currentInstance && db.isOpen()) {
6730
+ pollHandle = setTimeout(poll, LOCAL_POLL);
6731
+ }
6732
+ });
6733
+ });
6734
+ }
6735
+ function cleanup() {
6736
+ var ourSyncNode = mySyncNode.node;
6737
+ if (!ourSyncNode)
6738
+ return Promise$1.reject(new import_wrapper_default.DatabaseClosedError());
6739
+ return db.transaction("rw", "_syncNodes", "_changes", "_intercomm", function() {
6740
+ var weBecameMaster = false;
6741
+ db._syncNodes.where("lastHeartBeat").below(Date.now() - NODE_TIMEOUT).filter(function(node) {
6742
+ return node.type === "local";
6743
+ }).modify(function(node) {
6744
+ if (node.deleteTimeStamp && node.deleteTimeStamp < Date.now()) {
6745
+ delete this.value;
6746
+ if (localStorage) {
6747
+ localStorage.removeItem("Dexie.Observable/deadnode:" + node.id + "/" + db.name);
6748
+ }
6749
+ if (node.isMaster) {
6750
+ db._syncNodes.update(ourSyncNode, { isMaster: 1 });
6751
+ weBecameMaster = true;
6752
+ }
6753
+ db._intercomm.where({ destinationNode: node.id }).modify(function(msg) {
6754
+ if (msg.wantReply)
6755
+ msg.destinationNode = ourSyncNode.id;
6756
+ else
6757
+ delete this.value;
6758
+ });
6759
+ } else if (!node.deleteTimeStamp) {
6760
+ node.deleteTimeStamp = Date.now() + HIBERNATE_GRACE_PERIOD;
6761
+ }
6762
+ }).then(function() {
6763
+ Observable.deleteOldChanges(db);
6764
+ return db.on("cleanup").fire(weBecameMaster);
6765
+ });
6766
+ });
6767
+ }
6768
+ function onBeforeUnload() {
6769
+ if (!mySyncNode.node)
6770
+ return;
6771
+ browserIsShuttingDown = true;
6772
+ mySyncNode.node.deleteTimeStamp = 1;
6773
+ mySyncNode.node.lastHeartBeat = 0;
6774
+ db._syncNodes.put(mySyncNode.node);
6775
+ Observable.wereTheOneDying = true;
6776
+ if (localStorage) {
6777
+ localStorage.setItem("Dexie.Observable/deadnode:" + mySyncNode.node.id.toString() + "/" + db.name, "dead");
6778
+ }
6779
+ }
6780
+ function onSuicide(dbname, nodeID) {
6781
+ if (dbname === db.name && !Observable.wereTheOneDying) {
6782
+ import_wrapper_default.vip(function() {
6783
+ db._syncNodes.update(nodeID, { deleteTimeStamp: 1, lastHeartBeat: 0 }).then(cleanup);
6784
+ });
6785
+ }
6786
+ }
6787
+ }
6788
+ Observable.version = "{version}";
6789
+ Observable.latestRevision = {};
6790
+ Observable.on = import_wrapper_default.Events(null, "latestRevisionIncremented", "suicideNurseCall", "intercomm", "beforeunload");
6791
+ Observable.createUUID = createUUID;
6792
+ Observable.deleteOldChanges = deleteOldChanges;
6793
+ Observable._onStorage = initOnStorage(Observable);
6794
+ Observable._onBeforeUnload = function() {
6795
+ Observable.on.beforeunload.fire();
6796
+ };
6797
+ try {
6798
+ Observable.localStorageImpl = global2.localStorage;
6799
+ } catch (ex) {
6800
+ }
6801
+ if (global2 === null || global2 === void 0 ? void 0 : global2.addEventListener) {
6802
+ global2.addEventListener("storage", Observable._onStorage);
6803
+ global2.addEventListener("beforeunload", Observable._onBeforeUnload);
6804
+ }
6805
+ if (import_wrapper_default.Observable) {
6806
+ if (import_wrapper_default.Observable.version !== "{version}") {
6807
+ throw new Error("Mixed versions of dexie-observable");
6808
+ }
6809
+ } else {
6810
+ import_wrapper_default.Observable = Observable;
6811
+ import_wrapper_default.addons.push(Observable);
6812
+ }
6813
+ var Dexie_Observable = import_wrapper_default.Observable;
6814
+
6815
+ // ../../node_modules/dexie-syncable/dist/dexie-syncable.es.js
6816
+ var Promise$3 = import_wrapper_default.Promise;
6817
+ function initSyncableConnect(db, connect) {
6818
+ return function syncableConnect(protocolInstance, protocolName, url, options) {
6819
+ if (db.isOpen()) {
6820
+ if (!db._localSyncNode)
6821
+ throw new Error("Precondition failed: local sync node is missing. Make sure Dexie.Observable is active!");
6822
+ if (db._localSyncNode.isMaster) {
6823
+ return connect(protocolInstance, protocolName, url, options, db._localSyncNode.id);
6824
+ } else {
6825
+ return db.table("_syncNodes").where("isMaster").above(0).first(function(masterNode) {
6826
+ return db.observable.sendMessage("connect", {
6827
+ protocolName,
6828
+ url,
6829
+ options
6830
+ }, masterNode.id, { wantReply: true });
6831
+ });
6832
+ }
6833
+ } else if (db.hasBeenClosed()) {
6834
+ return Promise$3.reject(new import_wrapper_default.DatabaseClosedError());
6835
+ } else if (db.hasFailed()) {
6836
+ return Promise$3.reject(new import_wrapper_default.InvalidStateError("Dexie.Syncable: Cannot connect. Database has failed to open"));
6837
+ } else {
6838
+ var promise = new Promise$3(function(resolve, reject) {
6839
+ db.on("ready", function() {
6840
+ return db._syncNodes.get({ url }, function(node) {
6841
+ var connectPromise = db.syncable.connect(protocolName, url, options);
6842
+ connectPromise.then(resolve, reject);
6843
+ if (node && node.appliedRemoteRevision) {
6844
+ return;
6845
+ }
6846
+ return connectPromise;
6847
+ });
6848
+ });
6849
+ db.open().catch(function(ex) {
6850
+ reject(new import_wrapper_default.InvalidStateError("Dexie.Syncable: Couldn't connect. Database failed to open", ex));
6851
+ });
6852
+ });
6853
+ return promise;
6854
+ }
6855
+ };
6856
+ }
6857
+ function initPersistedContext(node) {
6858
+ return (
6859
+ /** @class */
6860
+ function() {
6861
+ function PersistedContext(nodeID, otherProps) {
6862
+ this.nodeID = nodeID;
6863
+ if (otherProps)
6864
+ import_wrapper_default.extend(this, otherProps);
6865
+ }
6866
+ PersistedContext.prototype.save = function() {
6867
+ return import_wrapper_default.vip(function() {
6868
+ return node.save();
6869
+ });
6870
+ };
6871
+ return PersistedContext;
6872
+ }()
6873
+ );
6874
+ }
6875
+ function initGetOrCreateSyncNode(db, protocolName, url) {
6876
+ return function getOrCreateSyncNode(options) {
6877
+ return db.transaction("rw", db._syncNodes, db._changes, function() {
6878
+ if (!url)
6879
+ throw new Error("Url cannot be empty");
6880
+ return db._syncNodes.where("url").equalsIgnoreCase(url).first(function(node) {
6881
+ if (node) {
6882
+ var PersistedContext = initPersistedContext(node);
6883
+ node.syncContext = new PersistedContext(node.id, node.syncContext);
6884
+ node.syncProtocol = protocolName;
6885
+ node.syncOptions = options;
6886
+ db._syncNodes.put(node);
6887
+ } else {
6888
+ node = new db.observable.SyncNode();
6889
+ node.myRevision = -1;
6890
+ node.appliedRemoteRevision = null;
6891
+ node.remoteBaseRevisions = [];
6892
+ node.type = "remote";
6893
+ node.syncProtocol = protocolName;
6894
+ node.url = url;
6895
+ node.syncOptions = options;
6896
+ node.lastHeartBeat = Date.now();
6897
+ node.dbUploadState = null;
6898
+ var PersistedContext_1 = initPersistedContext(node);
6899
+ import_wrapper_default.Promise.resolve(function() {
6900
+ if (options.initialUpload === false)
6901
+ return db._changes.toCollection().lastKey(function(currentRevision) {
6902
+ node.myRevision = currentRevision;
6903
+ });
6904
+ }()).then(function() {
6905
+ db._syncNodes.add(node).then(function(nodeID) {
6906
+ node.syncContext = new PersistedContext_1(nodeID);
6907
+ db._syncNodes.put(node);
6908
+ });
6909
+ });
6910
+ }
6911
+ return node;
6912
+ });
6913
+ });
6914
+ };
6915
+ }
6916
+ function initEnqueue(db) {
6917
+ return function enqueue(context, fn, instanceID) {
6918
+ function _enqueue() {
6919
+ if (!context.ongoingOperation) {
6920
+ context.ongoingOperation = import_wrapper_default.ignoreTransaction(function() {
6921
+ return import_wrapper_default.vip(function() {
6922
+ return fn();
6923
+ });
6924
+ }).finally(function() {
6925
+ delete context.ongoingOperation;
6926
+ });
6927
+ } else {
6928
+ context.ongoingOperation = context.ongoingOperation.then(function() {
6929
+ return enqueue(context, fn, instanceID);
6930
+ });
6931
+ }
6932
+ return context.ongoingOperation;
6933
+ }
6934
+ if (!instanceID) {
6935
+ if (db.isOpen()) {
6936
+ return _enqueue();
6937
+ } else {
6938
+ return import_wrapper_default.Promise.reject(new import_wrapper_default.DatabaseClosedError());
6939
+ }
6940
+ } else if (db._localSyncNode && instanceID === db._localSyncNode.id) {
6941
+ return _enqueue();
6942
+ } else {
6943
+ return import_wrapper_default.Promise.reject(new import_wrapper_default.DatabaseClosedError());
6944
+ }
6945
+ };
6946
+ }
6947
+ function initSaveToUncommittedChanges(db, node) {
6948
+ return function saveToUncommittedChanges(changes, remoteRevision) {
6949
+ return db.transaction("rw!", db._uncommittedChanges, function() {
6950
+ return db._uncommittedChanges.bulkAdd(changes.map(function(change) {
6951
+ var changeWithNodeId = {
6952
+ node: node.id,
6953
+ type: change.type,
6954
+ table: change.table,
6955
+ key: change.key
6956
+ };
6957
+ if (change.obj)
6958
+ changeWithNodeId.obj = change.obj;
6959
+ if (change.mods)
6960
+ changeWithNodeId.mods = change.mods;
6961
+ return changeWithNodeId;
6962
+ }));
6963
+ }).then(function() {
6964
+ node.appliedRemoteRevision = remoteRevision;
6965
+ return node.save();
6966
+ });
6967
+ };
6968
+ }
6969
+ var CREATE2 = 1;
6970
+ var UPDATE2 = 2;
6971
+ var DELETE2 = 3;
6972
+ function bulkUpdate(table, changes) {
6973
+ var keys = changes.map(function(c) {
6974
+ return c.key;
6975
+ });
6976
+ var map = {};
6977
+ return table.where(":id").anyOf(keys).raw().each(function(obj, cursor) {
6978
+ map[cursor.primaryKey + ""] = obj;
6979
+ }).then(function() {
6980
+ var updatesThatApply = changes.filter(function(c) {
6981
+ return map.hasOwnProperty(c.key + "");
6982
+ });
6983
+ var objsToPut = updatesThatApply.map(function(c) {
6984
+ var curr = map[c.key + ""];
6985
+ Object.keys(c.mods).forEach(function(keyPath) {
6986
+ import_wrapper_default.setByKeyPath(curr, keyPath, c.mods[keyPath]);
6987
+ });
6988
+ return curr;
6989
+ });
6990
+ return table.bulkPut(objsToPut);
6991
+ });
6992
+ }
6993
+ function initApplyChanges(db) {
6994
+ return function applyChanges(changes) {
6995
+ var collectedChanges = {};
6996
+ changes.forEach(function(change) {
6997
+ var _a;
6998
+ if (!collectedChanges.hasOwnProperty(change.table)) {
6999
+ collectedChanges[change.table] = (_a = {}, _a[CREATE2] = [], _a[DELETE2] = [], _a[UPDATE2] = [], _a);
7000
+ }
7001
+ collectedChanges[change.table][change.type].push(change);
7002
+ });
7003
+ var table_names = Object.keys(collectedChanges);
7004
+ var tables = table_names.map(function(table) {
7005
+ return db.table(table);
7006
+ });
7007
+ return db.transaction("rw", tables, function() {
7008
+ table_names.forEach(function(table_name) {
7009
+ var table = db.table(table_name);
7010
+ var specifyKeys = !table.schema.primKey.keyPath;
7011
+ var createChangesToApply = collectedChanges[table_name][CREATE2];
7012
+ var deleteChangesToApply = collectedChanges[table_name][DELETE2];
7013
+ var updateChangesToApply = collectedChanges[table_name][UPDATE2];
7014
+ if (createChangesToApply.length > 0)
7015
+ table.bulkPut(createChangesToApply.map(function(c) {
7016
+ return c.obj;
7017
+ }), specifyKeys ? createChangesToApply.map(function(c) {
7018
+ return c.key;
7019
+ }) : void 0);
7020
+ if (updateChangesToApply.length > 0)
7021
+ bulkUpdate(table, updateChangesToApply);
7022
+ if (deleteChangesToApply.length > 0)
7023
+ table.bulkDelete(deleteChangesToApply.map(function(c) {
7024
+ return c.key;
7025
+ }));
7026
+ });
7027
+ });
7028
+ };
7029
+ }
7030
+ function initFinallyCommitAllChanges(db, node) {
7031
+ var applyChanges = initApplyChanges(db);
7032
+ return function finallyCommitAllChanges(changes, remoteRevision) {
7033
+ var tablesToIncludeInTrans = db.tables.filter(function(table) {
7034
+ return table.name === "_changes" || table.name === "_uncommittedChanges" || table.schema.observable;
7035
+ });
7036
+ return db.transaction("rw!", tablesToIncludeInTrans, function() {
7037
+ var trans = import_wrapper_default.currentTransaction;
7038
+ var localRevisionBeforeChanges = 0;
7039
+ return db._changes.orderBy("rev").last(function(lastChange) {
7040
+ localRevisionBeforeChanges = lastChange && lastChange.rev || 0;
7041
+ }).then(function() {
7042
+ trans.source = node.id;
7043
+ return db._uncommittedChanges.where("node").equals(node.id).toArray();
7044
+ }).then(function(uncommittedChanges) {
7045
+ return applyChanges(uncommittedChanges);
7046
+ }).then(function() {
7047
+ return db._uncommittedChanges.where("node").equals(node.id).delete();
7048
+ }).then(function() {
7049
+ return applyChanges(changes);
7050
+ }).then(function() {
7051
+ return db._changes.orderBy("rev").last();
7052
+ }).then(function(lastChange) {
7053
+ var currentLocalRevision = lastChange && lastChange.rev || 0;
7054
+ node.appliedRemoteRevision = remoteRevision;
7055
+ node.remoteBaseRevisions.push({ remote: remoteRevision, local: currentLocalRevision });
7056
+ if (node.myRevision === localRevisionBeforeChanges) {
7057
+ node.myRevision = currentLocalRevision;
7058
+ }
7059
+ if (node.remoteBaseRevisions.length > 1) {
7060
+ for (var i = node.remoteBaseRevisions.length - 1; i > 0; --i) {
7061
+ if (node.myRevision >= node.remoteBaseRevisions[i].local) {
7062
+ node.remoteBaseRevisions.splice(0, i);
7063
+ break;
7064
+ }
7065
+ }
7066
+ }
7067
+ node.save().catch(function(err) {
7068
+ console.warn("Dexie.Syncable: Unable to save SyncNode after applying remote changes: " + (err.stack || err));
7069
+ });
7070
+ });
7071
+ });
7072
+ };
7073
+ }
7074
+ function getBaseRevisionAndMaxClientRevision(node) {
7075
+ if (node.remoteBaseRevisions.length === 0)
7076
+ return {
7077
+ // No remoteBaseRevisions have arrived yet. No limit on clientRevision and provide null as remoteBaseRevision:
7078
+ maxClientRevision: Infinity,
7079
+ remoteBaseRevision: null
7080
+ };
7081
+ for (var i = node.remoteBaseRevisions.length - 1; i >= 0; --i) {
7082
+ if (node.myRevision >= node.remoteBaseRevisions[i].local) {
7083
+ return {
7084
+ maxClientRevision: i === node.remoteBaseRevisions.length - 1 ? Infinity : node.remoteBaseRevisions[i + 1].local,
7085
+ remoteBaseRevision: node.remoteBaseRevisions[i].remote
7086
+ };
7087
+ }
7088
+ }
7089
+ return {
7090
+ maxClientRevision: node.remoteBaseRevisions[0].local,
7091
+ remoteBaseRevision: null
7092
+ };
7093
+ }
7094
+ function combineCreateAndUpdate(prevChange, nextChange) {
7095
+ var clonedChange = import_wrapper_default.deepClone(prevChange);
7096
+ Object.keys(nextChange.mods).forEach(function(keyPath) {
7097
+ import_wrapper_default.setByKeyPath(clonedChange.obj, keyPath, nextChange.mods[keyPath]);
7098
+ });
7099
+ return clonedChange;
7100
+ }
7101
+ function combineUpdateAndUpdate(prevChange, nextChange) {
7102
+ var clonedChange = import_wrapper_default.deepClone(prevChange);
7103
+ Object.keys(nextChange.mods).forEach(function(keyPath) {
7104
+ var hadParentPath = false;
7105
+ Object.keys(prevChange.mods).filter(function(parentPath) {
7106
+ return keyPath.indexOf(parentPath + ".") === 0;
7107
+ }).forEach(function(parentPath) {
7108
+ import_wrapper_default.setByKeyPath(clonedChange.mods[parentPath], keyPath.substr(parentPath.length + 1), nextChange.mods[keyPath]);
7109
+ hadParentPath = true;
7110
+ });
7111
+ if (!hadParentPath) {
7112
+ clonedChange.mods[keyPath] = nextChange.mods[keyPath];
7113
+ }
7114
+ Object.keys(prevChange.mods).filter(function(subPath) {
7115
+ return subPath.indexOf(keyPath + ".") === 0;
7116
+ }).forEach(function(subPath) {
7117
+ delete clonedChange.mods[subPath];
7118
+ });
7119
+ });
7120
+ return clonedChange;
7121
+ }
7122
+ function mergeChange(prevChange, nextChange) {
7123
+ switch (prevChange.type) {
7124
+ case CREATE2:
7125
+ switch (nextChange.type) {
7126
+ case CREATE2:
7127
+ return nextChange;
7128
+ case UPDATE2:
7129
+ return combineCreateAndUpdate(prevChange, nextChange);
7130
+ case DELETE2:
7131
+ return nextChange;
7132
+ }
7133
+ break;
7134
+ case UPDATE2:
7135
+ switch (nextChange.type) {
7136
+ case CREATE2:
7137
+ return nextChange;
7138
+ case UPDATE2:
7139
+ return combineUpdateAndUpdate(prevChange, nextChange);
7140
+ case DELETE2:
7141
+ return nextChange;
7142
+ }
7143
+ break;
7144
+ case DELETE2:
7145
+ switch (nextChange.type) {
7146
+ case CREATE2:
7147
+ return nextChange;
7148
+ case UPDATE2:
7149
+ return prevChange;
7150
+ case DELETE2:
7151
+ return prevChange;
7152
+ }
7153
+ break;
7154
+ }
7155
+ }
7156
+ function initGetChangesSinceRevision(db, node, hasMoreToGive) {
7157
+ return function getChangesSinceRevision(revision, maxChanges, maxRevision, cb) {
7158
+ var changeSet = {};
7159
+ var numChanges = 0;
7160
+ var partial = false;
7161
+ var ignoreSource = node.id;
7162
+ var nextRevision = revision;
7163
+ return db.transaction("r", db._changes, function() {
7164
+ var query = db._changes.where("rev").between(revision, maxRevision, false, true);
7165
+ return query.until(function() {
7166
+ if (numChanges === maxChanges) {
7167
+ partial = true;
7168
+ return true;
7169
+ }
7170
+ }).each(function(change) {
7171
+ nextRevision = change.rev;
7172
+ if (change.source === ignoreSource)
7173
+ return;
7174
+ var changeToSend = {
7175
+ type: change.type,
7176
+ table: change.table,
7177
+ key: change.key
7178
+ };
7179
+ if (change.type === CREATE2)
7180
+ changeToSend.obj = change.obj;
7181
+ else if (change.type === UPDATE2)
7182
+ changeToSend.mods = change.mods;
7183
+ var id = change.table + ":" + change.key;
7184
+ var prevChange = changeSet[id];
7185
+ if (!prevChange) {
7186
+ changeSet[id] = changeToSend;
7187
+ ++numChanges;
7188
+ } else {
7189
+ var nextChange = changeToSend;
7190
+ var mergedChange = mergeChange(prevChange, nextChange);
7191
+ changeSet[id] = mergedChange;
7192
+ }
7193
+ });
7194
+ }).then(function() {
7195
+ var changes = Object.keys(changeSet).map(function(key) {
7196
+ return changeSet[key];
7197
+ });
7198
+ hasMoreToGive.hasMoreToGive = partial;
7199
+ return cb(changes, partial, { myRevision: nextRevision });
7200
+ });
7201
+ };
7202
+ }
7203
+ function initGetTableObjectsAsChanges(db, node, MAX_CHANGES_PER_CHUNK, getChangesSinceRevision, hasMoreToGive, cb) {
7204
+ return function getTableObjectsAsChanges(state, changes, collection) {
7205
+ var limitReached = false;
7206
+ return collection.until(function() {
7207
+ if (changes.length === MAX_CHANGES_PER_CHUNK) {
7208
+ limitReached = true;
7209
+ return true;
7210
+ }
7211
+ }).each(function(item, cursor) {
7212
+ changes.push({
7213
+ type: CREATE2,
7214
+ table: state.currentTable,
7215
+ key: cursor.key,
7216
+ obj: cursor.value
7217
+ });
7218
+ state.currentKey = cursor.key;
7219
+ }).then(function() {
7220
+ if (limitReached) {
7221
+ hasMoreToGive.hasMoreToGive = true;
7222
+ return cb(changes, null, true, { dbUploadState: state });
7223
+ } else {
7224
+ if (state.tablesToUpload.length === 0) {
7225
+ var brmcr = getBaseRevisionAndMaxClientRevision(node);
7226
+ return getChangesSinceRevision(state.localBaseRevision, MAX_CHANGES_PER_CHUNK - changes.length, brmcr.maxClientRevision, function(additionalChanges, partial, nodeModificationsOnAck) {
7227
+ changes = changes.concat(additionalChanges);
7228
+ nodeModificationsOnAck.dbUploadState = null;
7229
+ return cb(changes, brmcr.remoteBaseRevision, partial, nodeModificationsOnAck);
7230
+ });
7231
+ } else {
7232
+ state.currentTable = state.tablesToUpload.shift();
7233
+ return getTableObjectsAsChanges(state, changes, db.table(state.currentTable).orderBy(":id"));
7234
+ }
7235
+ }
7236
+ });
7237
+ };
7238
+ }
7239
+ function initGetLocalChangesForNode(db, hasMoreToGive, partialsThreshold) {
7240
+ var MAX_CHANGES_PER_CHUNK = partialsThreshold;
7241
+ return function getLocalChangesForNode(node, cb) {
7242
+ var getChangesSinceRevision = initGetChangesSinceRevision(db, node, hasMoreToGive);
7243
+ var getTableObjectsAsChanges = initGetTableObjectsAsChanges(db, node, MAX_CHANGES_PER_CHUNK, getChangesSinceRevision, hasMoreToGive, cb);
7244
+ if (node.myRevision >= 0) {
7245
+ var brmcr = getBaseRevisionAndMaxClientRevision(node);
7246
+ return getChangesSinceRevision(node.myRevision, MAX_CHANGES_PER_CHUNK, brmcr.maxClientRevision, function(changes, partial, nodeModificationsOnAck) {
7247
+ return cb(changes, brmcr.remoteBaseRevision, partial, nodeModificationsOnAck);
7248
+ });
7249
+ } else {
7250
+ if (node.dbUploadState === null) {
7251
+ var tablesToUpload = db.tables.filter(function(table) {
7252
+ return table.schema.observable;
7253
+ }).map(function(table) {
7254
+ return table.name;
7255
+ });
7256
+ if (tablesToUpload.length === 0)
7257
+ return import_wrapper_default.Promise.resolve(cb([], null, false, {}));
7258
+ var dbUploadState = {
7259
+ tablesToUpload,
7260
+ currentTable: tablesToUpload.shift(),
7261
+ currentKey: null
7262
+ };
7263
+ return db._changes.orderBy("rev").last(function(lastChange) {
7264
+ dbUploadState.localBaseRevision = lastChange && lastChange.rev || 0;
7265
+ var collection2 = db.table(dbUploadState.currentTable).orderBy(":id");
7266
+ return getTableObjectsAsChanges(dbUploadState, [], collection2);
7267
+ });
7268
+ } else if (node.dbUploadState.currentKey) {
7269
+ var collection = db.table(node.dbUploadState.currentTable).where(":id").above(node.dbUploadState.currentKey);
7270
+ return getTableObjectsAsChanges(import_wrapper_default.deepClone(node.dbUploadState), [], collection);
7271
+ } else {
7272
+ var collection = db.table(dbUploadState.currentTable).orderBy(":id");
7273
+ return getTableObjectsAsChanges(import_wrapper_default.deepClone(node.dbUploadState), [], collection);
7274
+ }
7275
+ }
7276
+ };
7277
+ }
7278
+ var Statuses = {
7279
+ ERROR: -1,
7280
+ OFFLINE: 0,
7281
+ CONNECTING: 1,
7282
+ ONLINE: 2,
7283
+ SYNCING: 3,
7284
+ ERROR_WILL_RETRY: 4
7285
+ // An error occurred such as net down but the sync provider will retry to connect.
7286
+ };
7287
+ var StatusTexts = {
7288
+ "-1": "ERROR",
7289
+ "0": "OFFLINE",
7290
+ "1": "CONNECTING",
7291
+ "2": "ONLINE",
7292
+ "3": "SYNCING",
7293
+ "4": "ERROR_WILL_RETRY"
7294
+ };
7295
+ var Promise$22 = import_wrapper_default.Promise;
7296
+ function initConnectProtocol(db, protocolInstance, dbAliveID, options, rejectConnectPromise) {
7297
+ var enqueue = initEnqueue(db);
7298
+ var hasMoreToGive = { hasMoreToGive: true };
7299
+ function stillAlive() {
7300
+ return db._localSyncNode && db._localSyncNode.id === dbAliveID;
7301
+ }
7302
+ return function connectProtocol(node, activePeer) {
7303
+ var getLocalChangesForNode = initGetLocalChangesForNode(db, hasMoreToGive, protocolInstance.partialsThreshold);
7304
+ var url = activePeer.url;
7305
+ function changeStatusTo(newStatus) {
7306
+ if (node.status !== newStatus) {
7307
+ node.status = newStatus;
7308
+ node.save().then(function() {
7309
+ db.syncable.on.statusChanged.fire(newStatus, url);
7310
+ db.observable.broadcastMessage("syncStatusChanged", { newStatus, url }, false);
7311
+ }).catch("DatabaseClosedError", function() {
7312
+ });
7313
+ }
7314
+ }
7315
+ activePeer.on("disconnect", function(newStatus) {
7316
+ if (!isNaN(newStatus))
7317
+ changeStatusTo(newStatus);
7318
+ });
7319
+ var connectedContinuation;
7320
+ changeStatusTo(Statuses.CONNECTING);
7321
+ return doSync();
7322
+ function doSync() {
7323
+ return enqueue(doSync, function() {
7324
+ return getLocalChangesForNode_autoAckIfEmpty(node, sendChangesToProvider);
7325
+ }, dbAliveID);
7326
+ }
7327
+ function sendChangesToProvider(changes, remoteBaseRevision, partial, nodeModificationsOnAck) {
7328
+ var finalSyncPromise = new Promise$22(function(resolve, reject) {
7329
+ rejectConnectPromise.p = function(err) {
7330
+ reject(err);
7331
+ };
7332
+ import_wrapper_default.asap(function() {
7333
+ try {
7334
+ protocolInstance.sync(node.syncContext, url, options, remoteBaseRevision, node.appliedRemoteRevision, changes, partial, applyRemoteChanges, onChangesAccepted, function(continuation) {
7335
+ resolve(continuation);
7336
+ }, onError);
7337
+ } catch (ex) {
7338
+ onError(ex, Infinity);
7339
+ }
7340
+ function onError(error, again) {
7341
+ reject(error);
7342
+ if (stillAlive()) {
7343
+ if (!isNaN(again) && again < Infinity) {
7344
+ setTimeout(function() {
7345
+ if (stillAlive()) {
7346
+ changeStatusTo(Statuses.SYNCING);
7347
+ doSync().catch("DatabaseClosedError", abortTheProvider);
7348
+ }
7349
+ }, again);
7350
+ changeStatusTo(Statuses.ERROR_WILL_RETRY);
7351
+ if (connectedContinuation && connectedContinuation.disconnect)
7352
+ connectedContinuation.disconnect();
7353
+ connectedContinuation = null;
7354
+ } else {
7355
+ abortTheProvider(error);
7356
+ }
7357
+ }
7358
+ }
7359
+ });
7360
+ });
7361
+ return finalSyncPromise.then(function() {
7362
+ return void 0;
7363
+ }).finally(function() {
7364
+ rejectConnectPromise.p = null;
7365
+ });
7366
+ function onChangesAccepted() {
7367
+ Object.keys(nodeModificationsOnAck).forEach(function(keyPath) {
7368
+ import_wrapper_default.setByKeyPath(node, keyPath, nodeModificationsOnAck[keyPath]);
7369
+ });
7370
+ finalSyncPromise.then(continueSendingChanges);
7371
+ return node.save();
7372
+ }
7373
+ }
7374
+ function abortTheProvider(error) {
7375
+ activePeer.disconnect(Statuses.ERROR, error);
7376
+ }
7377
+ function getLocalChangesForNode_autoAckIfEmpty(node2, cb) {
7378
+ return getLocalChangesForNode(node2, function autoAck(changes, remoteBaseRevision, partial, nodeModificationsOnAck) {
7379
+ if (changes.length === 0 && "myRevision" in nodeModificationsOnAck && nodeModificationsOnAck.myRevision !== node2.myRevision) {
7380
+ Object.keys(nodeModificationsOnAck).forEach(function(keyPath) {
7381
+ import_wrapper_default.setByKeyPath(node2, keyPath, nodeModificationsOnAck[keyPath]);
7382
+ });
7383
+ node2.save().catch("DatabaseClosedError", function() {
7384
+ });
7385
+ return getLocalChangesForNode(node2, autoAck);
7386
+ } else {
7387
+ return cb(changes, remoteBaseRevision, partial, nodeModificationsOnAck);
7388
+ }
7389
+ });
7390
+ }
7391
+ function applyRemoteChanges(remoteChanges, remoteRevision, partial) {
7392
+ var saveToUncommittedChanges = initSaveToUncommittedChanges(db, node);
7393
+ var finallyCommitAllChanges = initFinallyCommitAllChanges(db, node);
7394
+ return enqueue(applyRemoteChanges, function() {
7395
+ if (!stillAlive())
7396
+ return Promise$22.reject(new import_wrapper_default.DatabaseClosedError());
7397
+ return (partial ? saveToUncommittedChanges(remoteChanges, remoteRevision) : finallyCommitAllChanges(remoteChanges, remoteRevision)).catch(function(error) {
7398
+ abortTheProvider(error);
7399
+ return Promise$22.reject(error);
7400
+ });
7401
+ }, dbAliveID);
7402
+ }
7403
+ function continueSendingChanges(continuation) {
7404
+ if (!stillAlive()) {
7405
+ if (continuation.disconnect)
7406
+ continuation.disconnect();
7407
+ return;
7408
+ }
7409
+ connectedContinuation = continuation;
7410
+ activePeer.on("disconnect", function() {
7411
+ if (connectedContinuation) {
7412
+ if (connectedContinuation.react) {
7413
+ try {
7414
+ connectedContinuation.disconnect();
7415
+ } catch (e) {
7416
+ }
7417
+ }
7418
+ connectedContinuation = null;
7419
+ }
7420
+ });
7421
+ if (continuation.react) {
7422
+ continueUsingReactPattern(continuation);
7423
+ } else {
7424
+ continueUsingPollPattern();
7425
+ }
7426
+ }
7427
+ function continueUsingReactPattern(continuation) {
7428
+ var changesWaiting, isWaitingForServer;
7429
+ function onChanges() {
7430
+ if (connectedContinuation) {
7431
+ changeStatusTo(Statuses.SYNCING);
7432
+ if (isWaitingForServer)
7433
+ changesWaiting = true;
7434
+ else {
7435
+ reactToChanges();
7436
+ }
7437
+ }
7438
+ }
7439
+ db.on("changes", onChanges);
7440
+ activePeer.on("disconnect", function() {
7441
+ db.on.changes.unsubscribe(onChanges);
7442
+ });
7443
+ function reactToChanges() {
7444
+ if (!connectedContinuation)
7445
+ return;
7446
+ changesWaiting = false;
7447
+ isWaitingForServer = true;
7448
+ getLocalChangesForNode_autoAckIfEmpty(node, function(changes, remoteBaseRevision, partial, nodeModificationsOnAck) {
7449
+ if (!connectedContinuation)
7450
+ return;
7451
+ if (changes.length > 0) {
7452
+ continuation.react(changes, remoteBaseRevision, partial, function onChangesAccepted() {
7453
+ Object.keys(nodeModificationsOnAck).forEach(function(keyPath) {
7454
+ import_wrapper_default.setByKeyPath(node, keyPath, nodeModificationsOnAck[keyPath]);
7455
+ });
7456
+ node.save().catch("DatabaseClosedError", function() {
7457
+ });
7458
+ reactToChanges();
7459
+ });
7460
+ } else {
7461
+ isWaitingForServer = false;
7462
+ if (changesWaiting) {
7463
+ reactToChanges();
7464
+ } else {
7465
+ changeStatusTo(Statuses.ONLINE);
7466
+ }
7467
+ }
7468
+ }).catch(function(ex) {
7469
+ console.error("Got ".concat(ex.message, " caught by reactToChanges"));
7470
+ abortTheProvider(ex);
7471
+ });
7472
+ }
7473
+ reactToChanges();
7474
+ }
7475
+ function continueUsingPollPattern() {
7476
+ function syncAgain() {
7477
+ getLocalChangesForNode_autoAckIfEmpty(node, function(changes, remoteBaseRevision, partial, nodeModificationsOnAck) {
7478
+ protocolInstance.sync(node.syncContext, url, options, remoteBaseRevision, node.appliedRemoteRevision, changes, partial, applyRemoteChanges, onChangesAccepted, onSuccess, onError);
7479
+ function onChangesAccepted() {
7480
+ Object.keys(nodeModificationsOnAck).forEach(function(keyPath) {
7481
+ import_wrapper_default.setByKeyPath(node, keyPath, nodeModificationsOnAck[keyPath]);
7482
+ });
7483
+ node.save().catch("DatabaseClosedError", function() {
7484
+ });
7485
+ }
7486
+ function onSuccess(continuation) {
7487
+ if (!connectedContinuation) {
7488
+ return;
7489
+ }
7490
+ connectedContinuation = continuation;
7491
+ if (partial) {
7492
+ syncAgain();
7493
+ } else {
7494
+ if (!isNaN(continuation.again) && continuation.again < Infinity) {
7495
+ changeStatusTo(Statuses.ONLINE);
7496
+ setTimeout(function() {
7497
+ if (connectedContinuation) {
7498
+ changeStatusTo(Statuses.SYNCING);
7499
+ syncAgain();
7500
+ }
7501
+ }, continuation.again);
7502
+ } else {
7503
+ activePeer.disconnect(Statuses.OFFLINE);
7504
+ }
7505
+ }
7506
+ }
7507
+ function onError(error, again) {
7508
+ if (!isNaN(again) && again < Infinity) {
7509
+ if (connectedContinuation) {
7510
+ setTimeout(function() {
7511
+ if (connectedContinuation) {
7512
+ changeStatusTo(Statuses.SYNCING);
7513
+ syncAgain();
7514
+ }
7515
+ }, again);
7516
+ changeStatusTo(Statuses.ERROR_WILL_RETRY);
7517
+ }
7518
+ } else {
7519
+ abortTheProvider(error);
7520
+ }
7521
+ }
7522
+ }).catch(abortTheProvider);
7523
+ }
7524
+ if (hasMoreToGive.hasMoreToGive) {
7525
+ syncAgain();
7526
+ } else if (connectedContinuation && !isNaN(connectedContinuation.again) && connectedContinuation.again < Infinity) {
7527
+ changeStatusTo(Statuses.ONLINE);
7528
+ setTimeout(function() {
7529
+ if (connectedContinuation) {
7530
+ changeStatusTo(Statuses.SYNCING);
7531
+ syncAgain();
7532
+ }
7533
+ }, connectedContinuation.again);
7534
+ } else {
7535
+ activePeer.disconnect(Statuses.OFFLINE);
7536
+ }
7537
+ }
7538
+ };
7539
+ }
7540
+ function initConnectFn(db, activePeers) {
7541
+ return function connect(protocolInstance, protocolName, url, options, dbAliveID) {
7542
+ var existingPeer = activePeers.filter(function(peer) {
7543
+ return peer.url === url;
7544
+ });
7545
+ if (existingPeer.length > 0) {
7546
+ var activePeer = existingPeer[0];
7547
+ var diffObject = {};
7548
+ import_wrapper_default.getObjectDiff(activePeer.syncOptions, options, diffObject);
7549
+ if (Object.keys(diffObject).length !== 0) {
7550
+ return db.syncable.disconnect(url).then(function() {
7551
+ return execConnect();
7552
+ });
7553
+ } else {
7554
+ return existingPeer[0].connectPromise;
7555
+ }
7556
+ }
7557
+ function execConnect() {
7558
+ var rejectConnectPromise = { p: null };
7559
+ var connectProtocol = initConnectProtocol(db, protocolInstance, dbAliveID, options, rejectConnectPromise);
7560
+ var getOrCreateSyncNode = initGetOrCreateSyncNode(db, protocolName, url);
7561
+ var connectPromise = getOrCreateSyncNode(options).then(function(node) {
7562
+ return connectProtocol(node, activePeer2);
7563
+ });
7564
+ var disconnected = false;
7565
+ var activePeer2 = {
7566
+ url,
7567
+ status: Statuses.OFFLINE,
7568
+ connectPromise,
7569
+ syncOptions: options,
7570
+ on: import_wrapper_default.Events(null, "disconnect"),
7571
+ disconnect: function(newStatus, error) {
7572
+ var pos = activePeers.indexOf(activePeer2);
7573
+ if (pos >= 0)
7574
+ activePeers.splice(pos, 1);
7575
+ if (error && rejectConnectPromise.p)
7576
+ rejectConnectPromise.p(error);
7577
+ if (!disconnected) {
7578
+ activePeer2.on.disconnect.fire(newStatus, error);
7579
+ }
7580
+ disconnected = true;
7581
+ }
7582
+ };
7583
+ activePeers.push(activePeer2);
7584
+ return connectPromise;
7585
+ }
7586
+ return execConnect();
7587
+ };
7588
+ }
7589
+ var override2 = import_wrapper_default.override;
7590
+ var Promise$12 = import_wrapper_default.Promise;
7591
+ var Observable2 = import_wrapper_default.Observable;
7592
+ function Syncable(db) {
7593
+ if (!/^(3|4)\./.test(import_wrapper_default.version))
7594
+ throw new Error("Missing dexie version 3.x or 4.x");
7595
+ if (!db.observable || db.observable.version !== "{version}" && !/^(3|4)\./.test(db.observable.version))
7596
+ throw new Error("Missing dexie-observable version 3.x or 4.x");
7597
+ if (db.syncable) {
7598
+ if (db.syncable.version !== "{version}")
7599
+ throw new Error("Mixed versions of dexie-syncable");
7600
+ return;
7601
+ }
7602
+ var activePeers = [];
7603
+ var connectFn = initConnectFn(db, activePeers);
7604
+ var syncableConnect = initSyncableConnect(db, connectFn);
7605
+ db.on("message", function(msg) {
7606
+ import_wrapper_default.vip(function() {
7607
+ if (msg.type === "connect") {
7608
+ db.syncable.connect(msg.message.protocolName, msg.message.url, msg.message.options).then(msg.resolve, msg.reject);
7609
+ } else if (msg.type === "disconnect") {
7610
+ db.syncable.disconnect(msg.message.url).then(msg.resolve, msg.reject);
7611
+ } else if (msg.type === "syncStatusChanged") {
7612
+ db.syncable.on.statusChanged.fire(msg.message.newStatus, msg.message.url);
7613
+ }
7614
+ });
7615
+ });
7616
+ db.on("cleanup", function(weBecameMaster) {
7617
+ if (weBecameMaster) {
7618
+ import_wrapper_default.ignoreTransaction(function() {
7619
+ return import_wrapper_default.vip(function() {
7620
+ return db._syncNodes.where({ type: "remote" }).filter(function(node) {
7621
+ return node.status !== Statuses.OFFLINE;
7622
+ }).toArray(function(connectedRemoteNodes) {
7623
+ return Promise$12.all(connectedRemoteNodes.map(function(node) {
7624
+ return db.syncable.connect(node.syncProtocol, node.url, node.syncOptions).catch(function(e) {
7625
+ console.warn("Dexie.Syncable: Could not connect to ".concat(node.url, ". ").concat(e.stack || e));
7626
+ });
7627
+ }));
7628
+ });
7629
+ });
7630
+ }).catch("DatabaseClosedError", function() {
7631
+ });
7632
+ }
7633
+ });
7634
+ db.on("ready", function onReady() {
7635
+ if (db._localSyncNode && db._localSyncNode.isMaster) {
7636
+ db._syncNodes.where("type").equals("remote").and(function(node) {
7637
+ return node.status !== Statuses.OFFLINE;
7638
+ }).toArray(function(connectedRemoteNodes) {
7639
+ connectedRemoteNodes.forEach(
7640
+ function(node) {
7641
+ return db.syncable.connect(node.syncProtocol, node.url, node.syncOptions).catch(function() {
7642
+ });
7643
+ }
7644
+ // A failure will be triggered in on('statusChanged'). We can ignore.
7645
+ );
7646
+ }).catch("DatabaseClosedError", function() {
7647
+ });
7648
+ }
7649
+ }, true);
7650
+ db.syncable = {
7651
+ version: "{version}"
7652
+ };
7653
+ db.syncable.getStatus = function(url, cb) {
7654
+ if (db.isOpen()) {
7655
+ return import_wrapper_default.vip(function() {
7656
+ return db._syncNodes.where("url").equals(url).first(function(node) {
7657
+ return node ? node.status : Statuses.OFFLINE;
7658
+ });
7659
+ }).then(cb);
7660
+ } else {
7661
+ return Promise$12.resolve(Syncable.Statuses.OFFLINE).then(cb);
7662
+ }
7663
+ };
7664
+ db.syncable.getOptions = function(url, cb) {
7665
+ return db.transaction("r?", db._syncNodes, function() {
7666
+ return db._syncNodes.where("url").equals(url).first(function(node) {
7667
+ return node.syncOptions;
7668
+ }).then(cb);
7669
+ });
7670
+ };
7671
+ db.syncable.list = function() {
7672
+ return db.transaction("r?", db._syncNodes, function() {
7673
+ return db._syncNodes.where("type").equals("remote").toArray(function(a) {
7674
+ return a.map(function(node) {
7675
+ return node.url;
7676
+ });
7677
+ });
7678
+ });
7679
+ };
7680
+ db.syncable.on = import_wrapper_default.Events(db, { statusChanged: "asap" });
7681
+ db.syncable.disconnect = function(url) {
7682
+ return import_wrapper_default.ignoreTransaction(function() {
7683
+ return Promise$12.resolve().then(function() {
7684
+ if (db._localSyncNode && db._localSyncNode.isMaster) {
7685
+ return Promise$12.all(activePeers.filter(function(peer) {
7686
+ return peer.url === url;
7687
+ }).map(function(peer) {
7688
+ return peer.disconnect(Statuses.OFFLINE);
7689
+ }));
7690
+ } else {
7691
+ return db._syncNodes.where("isMaster").above(0).first(function(masterNode) {
7692
+ return db.observable.sendMessage("disconnect", { url }, masterNode.id, { wantReply: true });
7693
+ });
7694
+ }
7695
+ }).then(function() {
7696
+ return db._syncNodes.where("url").equals(url).modify(function(node) {
7697
+ node.status = Statuses.OFFLINE;
7698
+ });
7699
+ });
7700
+ });
7701
+ };
7702
+ db.syncable.connect = function(protocolName, url, options) {
7703
+ options = options || {};
7704
+ var protocolInstance = Syncable.registeredProtocols[protocolName];
7705
+ if (protocolInstance) {
7706
+ return syncableConnect(protocolInstance, protocolName, url, options);
7707
+ } else {
7708
+ return Promise$12.reject(new Error("ISyncProtocol '" + protocolName + "' is not registered in Dexie.Syncable.registerSyncProtocol()"));
7709
+ }
7710
+ };
7711
+ db.syncable.delete = function(url) {
7712
+ return db.syncable.disconnect(url).then(function() {
7713
+ return db.transaction("rw!", db._syncNodes, db._changes, db._uncommittedChanges, function() {
7714
+ var nodeIDsToDelete;
7715
+ return db._syncNodes.where("url").equals(url).toArray(function(nodes) {
7716
+ return nodes.map(function(node) {
7717
+ return node.id;
7718
+ });
7719
+ }).then(function(nodeIDs) {
7720
+ nodeIDsToDelete = nodeIDs;
7721
+ return db._syncNodes.where("id").anyOf(nodeIDs).delete();
7722
+ }).then(function() {
7723
+ return db._uncommittedChanges.where("node").anyOf(nodeIDsToDelete).delete();
7724
+ });
7725
+ }).then(function() {
7726
+ Observable2.deleteOldChanges(db);
7727
+ });
7728
+ });
7729
+ };
7730
+ db.syncable.unsyncedChanges = function(url) {
7731
+ return db._syncNodes.where("url").equals(url).first(function(node) {
7732
+ return db._changes.where("rev").above(node.myRevision).toArray();
7733
+ });
7734
+ };
7735
+ db.close = override2(db.close, function(origClose) {
7736
+ return function() {
7737
+ activePeers.forEach(function(peer) {
7738
+ peer.disconnect();
7739
+ });
7740
+ return origClose.apply(this, arguments);
7741
+ };
7742
+ });
7743
+ Object.defineProperty(db.observable.SyncNode.prototype, "save", {
7744
+ enumerable: false,
7745
+ configurable: true,
7746
+ writable: true,
7747
+ value: function() {
7748
+ var _this = this;
7749
+ return db.transaction("rw?", db._syncNodes, function() {
7750
+ return db._syncNodes.put(_this);
7751
+ });
7752
+ }
7753
+ });
7754
+ }
7755
+ Syncable.version = "{version}";
7756
+ Syncable.Statuses = Statuses;
7757
+ Syncable.StatusTexts = StatusTexts;
7758
+ Syncable.registeredProtocols = {};
7759
+ Syncable.registerSyncProtocol = function(name, protocolInstance) {
7760
+ var partialsThreshold = protocolInstance.partialsThreshold;
7761
+ if (typeof partialsThreshold === "number") {
7762
+ if (isNaN(partialsThreshold) || partialsThreshold < 0) {
7763
+ throw new Error("The given number for the threshold is not supported");
7764
+ }
7765
+ } else {
7766
+ protocolInstance.partialsThreshold = Infinity;
7767
+ }
7768
+ Syncable.registeredProtocols[name] = protocolInstance;
7769
+ };
7770
+ if (import_wrapper_default.Syncable) {
7771
+ if (import_wrapper_default.Syncable.version !== "{version}") {
7772
+ throw new Error("Mixed versions of dexie-syncable");
7773
+ }
7774
+ } else {
7775
+ import_wrapper_default.Syncable = Syncable;
7776
+ import_wrapper_default.addons.push(Syncable);
7777
+ }
7778
+ var Dexie_Syncable = import_wrapper_default.Syncable;
7779
+
7780
+ // ../sync/src/syncProtocol.js
7781
+ var syncProtocol = function() {
7782
+ console.log("Initializing syncProtocol");
7783
+ var RECONNECT_DELAY = 5e3;
7784
+ Dexie.Syncable.registerSyncProtocol("websocket", {
7785
+ sync: function(context, url, options, baseRevision, syncedRevision, changes, partial, applyRemoteChanges, onChangesAccepted, onSuccess, onError) {
7786
+ var requestId = 0;
7787
+ var acceptCallbacks = {};
7788
+ var ws = new WebSocket(url);
7789
+ function sendChanges(changes2, baseRevision2, partial2, onChangesAccepted2) {
7790
+ console.log("sendChanges", changes2.length, baseRevision2);
7791
+ ++requestId;
7792
+ acceptCallbacks[requestId.toString()] = onChangesAccepted2;
7793
+ ws.send(
7794
+ JSON.stringify({
7795
+ type: "changes",
7796
+ changes: changes2,
7797
+ partial: partial2,
7798
+ baseRevision: baseRevision2,
7799
+ requestId
7800
+ })
7801
+ );
7802
+ }
7803
+ ws.onopen = function(event) {
7804
+ console.log("Opening socket - sending clientIdentity", context.clientIdentity);
7805
+ ws.send(
7806
+ JSON.stringify({
7807
+ type: "clientIdentity",
7808
+ clientIdentity: context.clientIdentity || null,
7809
+ authToken: options.authToken
7810
+ })
7811
+ );
7812
+ };
7813
+ ws.onerror = function(event) {
7814
+ ws.close();
7815
+ console.log("ws.onerror", event);
7816
+ onError(event?.message, RECONNECT_DELAY);
7817
+ };
7818
+ ws.onclose = function(event) {
7819
+ onError("Socket closed: " + event.reason, RECONNECT_DELAY);
7820
+ };
7821
+ var isFirstRound = true;
7822
+ ws.onmessage = function(event) {
7823
+ try {
7824
+ var requestFromServer = JSON.parse(event.data);
7825
+ console.log("requestFromServer", requestFromServer, { acceptCallback, isFirstRound });
7826
+ if (requestFromServer.type == "clientIdentity") {
7827
+ context.clientIdentity = requestFromServer.clientIdentity;
7828
+ context.save();
7829
+ sendChanges(changes, baseRevision, partial, onChangesAccepted);
7830
+ ws.send(
7831
+ JSON.stringify({
7832
+ type: "subscribe",
7833
+ syncedRevision
7834
+ })
7835
+ );
7836
+ } else if (requestFromServer.type == "error") {
7837
+ } else if (requestFromServer.type == "changes") {
7838
+ applyRemoteChanges(
7839
+ requestFromServer.changes,
7840
+ requestFromServer.currentRevision,
7841
+ requestFromServer.partial
7842
+ );
7843
+ if (isFirstRound && !requestFromServer.partial) {
7844
+ onSuccess({
7845
+ // Specify a react function that will react on additional client changes
7846
+ react: function(changes2, baseRevision2, partial2, onChangesAccepted2) {
7847
+ sendChanges(
7848
+ changes2,
7849
+ baseRevision2,
7850
+ partial2,
7851
+ onChangesAccepted2
7852
+ );
7853
+ },
7854
+ // Specify a disconnect function that will close our socket so that we dont continue to monitor changes.
7855
+ disconnect: function() {
7856
+ ws.close();
7857
+ }
7858
+ });
7859
+ isFirstRound = false;
7860
+ }
7861
+ } else if (requestFromServer.type == "ack") {
7862
+ var requestId2 = requestFromServer.requestId;
7863
+ var acceptCallback = acceptCallbacks[requestId2.toString()];
7864
+ acceptCallback();
7865
+ delete acceptCallbacks[requestId2.toString()];
7866
+ } else if (requestFromServer.type == "error") {
7867
+ var requestId2 = requestFromServer.requestId;
7868
+ ws.close();
7869
+ onError(requestFromServer.message, Infinity);
7870
+ } else {
7871
+ console.log("unknown message", requestFromServer);
7872
+ ws.close();
7873
+ onError("unknown message", Infinity);
7874
+ }
7875
+ } catch (e) {
7876
+ ws.close();
7877
+ onError(e, Infinity);
7878
+ }
7879
+ };
7880
+ }
7881
+ });
7882
+ };
7883
+
7884
+ // ../sync/src/index.ts
7885
+ syncProtocol();
7886
+ var BasicSync = class extends Dexie {
7887
+ basic_schema;
7888
+ constructor(name, options) {
7889
+ super(name, options);
7890
+ this.basic_schema = options.schema;
7891
+ this.version(1).stores(this._convertSchemaToDxSchema(this.basic_schema));
7892
+ this.version(2).stores({});
7893
+ this.Collection.prototype.get = this.Collection.prototype.toArray;
7894
+ }
7895
+ async connect({ access_token }) {
7896
+ const WS_URL = "ws://localhost:3003/ws";
7897
+ await this.updateSyncNodes();
7898
+ console.log("Starting connection...");
7899
+ return this.syncable.connect("websocket", WS_URL, { authToken: access_token });
7900
+ }
7901
+ async updateSyncNodes() {
7902
+ try {
7903
+ const syncNodes = await this.table("_syncNodes").toArray();
7904
+ const localSyncNodes = syncNodes.filter((node) => node.type === "local");
7905
+ console.log("Local sync nodes:", localSyncNodes);
7906
+ if (localSyncNodes.length > 1) {
7907
+ const largestNodeId = Math.max(...localSyncNodes.map((node) => node.id));
7908
+ const largestNode = localSyncNodes.find((node) => node.id === largestNodeId);
7909
+ if (largestNode && largestNode.isMaster === 1) {
7910
+ console.log("Largest node is already the master. No changes needed.");
7911
+ return;
7912
+ }
7913
+ console.log("Largest node id:", largestNodeId);
7914
+ console.error("HEISENBUG: More than one local sync node found.");
7915
+ for (const node of localSyncNodes) {
7916
+ console.log(`Local sync node keys:`, node.id, node.isMaster);
7917
+ await this.table("_syncNodes").update(node.id, { isMaster: node.id === largestNodeId ? 1 : 0 });
7918
+ console.log(`HEISENBUG: Setting ${node.id} to ${node.id === largestNodeId ? "master" : "0"}`);
7919
+ }
7920
+ await new Promise((resolve) => setTimeout(resolve, 2e3));
7921
+ }
7922
+ console.log("Sync nodes updated");
7923
+ } catch (error) {
7924
+ console.error("Error updating _syncNodes table:", error);
7925
+ }
7926
+ }
7927
+ handleStatusChange(fn) {
7928
+ this.syncable.on("statusChanged", fn);
7929
+ }
7930
+ _convertSchemaToDxSchema(schema) {
7931
+ const stores = Object.entries(schema.tables).map(([key, table]) => {
7932
+ const indexedFields = Object.entries(table.fields).filter(([key2, field]) => field.indexed).map(([key2, field]) => `,${key2}`).join("");
7933
+ return {
7934
+ [key]: "id" + indexedFields
7935
+ };
7936
+ });
7937
+ return Object.assign({}, ...stores);
7938
+ }
7939
+ debugeroo() {
7940
+ return this.syncable;
7941
+ }
7942
+ collection(name) {
7943
+ return {
7944
+ /**
7945
+ * Returns the underlying Dexie table
7946
+ * @type {Dexie.Table}
7947
+ */
7948
+ ref: this.table(name),
7949
+ // --- WRITE ---- //
7950
+ add: (data) => {
7951
+ console.log("Adding data to", name, data);
7952
+ return this.table(name).add({
7953
+ id: v7_default(),
7954
+ ...data
7955
+ });
7956
+ },
7957
+ put: (data) => {
7958
+ return this.table(name).put({
7959
+ id: v7_default(),
7960
+ ...data
7961
+ });
7962
+ },
7963
+ update: (id, data) => {
7964
+ return this.table(name).update(id, data);
7965
+ },
7966
+ delete: (id) => {
7967
+ return this.table(name).delete(id);
7968
+ },
7969
+ // --- READ ---- //
7970
+ get: (id) => {
7971
+ return this.table(name).get(id);
7972
+ },
7973
+ getAll: () => {
7974
+ return this.table(name).toArray();
7975
+ },
7976
+ // --- QUERY ---- //
7977
+ // TODO: lots to do here. simplifing creating querie, filtering/ordering/limit, and execute
7978
+ query: () => this.table(name),
7979
+ filter: (fn) => this.table(name).filter(fn).toArray()
7980
+ };
7981
+ }
7982
+ };
5961
7983
 
5962
7984
  // src/db.ts
5963
7985
  var baseUrl = "https://api.basic.tech";
@@ -5970,7 +7992,7 @@ async function get({ projectId, accountId, tableName, token }) {
5970
7992
  });
5971
7993
  return response.json();
5972
7994
  }
5973
- async function add({ projectId, accountId, tableName, value, token }) {
7995
+ async function add2({ projectId, accountId, tableName, value, token }) {
5974
7996
  const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}`;
5975
7997
  const response = await fetch(url, {
5976
7998
  method: "POST",
@@ -6050,7 +8072,7 @@ function BasicProvider({ children, project_id, schema }) {
6050
8072
  const syncRef = (0, import_react.useRef)(null);
6051
8073
  (0, import_react.useEffect)(() => {
6052
8074
  if (!syncRef.current) {
6053
- syncRef.current = new import_sync.BasicSync("basicdb", { schema });
8075
+ syncRef.current = new BasicSync("basicdb", { schema });
6054
8076
  syncRef.current.handleStatusChange((status, url) => {
6055
8077
  setDbStatus(getSyncStatus(status));
6056
8078
  });
@@ -6211,7 +8233,7 @@ function BasicProvider({ children, project_id, schema }) {
6211
8233
  add: async (value) => {
6212
8234
  checkSignIn();
6213
8235
  const tok = await getToken();
6214
- return add({ projectId: project_id, accountId: user.id, tableName, value, token: tok });
8236
+ return add2({ projectId: project_id, accountId: user.id, tableName, value, token: tok });
6215
8237
  },
6216
8238
  update: async (id, value) => {
6217
8239
  checkSignIn();
@@ -6242,27 +8264,6 @@ function useBasic() {
6242
8264
  return (0, import_react.useContext)(BasicContext);
6243
8265
  }
6244
8266
 
6245
- // ../../node_modules/dexie/import-wrapper.mjs
6246
- var import_dexie = __toESM(require_dexie(), 1);
6247
- var DexieSymbol = Symbol.for("Dexie");
6248
- var Dexie = globalThis[DexieSymbol] || (globalThis[DexieSymbol] = import_dexie.default);
6249
- if (import_dexie.default.semVer !== Dexie.semVer) {
6250
- throw new Error(`Two different versions of Dexie loaded in the same app: ${import_dexie.default.semVer} and ${Dexie.semVer}`);
6251
- }
6252
- var {
6253
- liveQuery,
6254
- mergeRanges,
6255
- rangesOverlap,
6256
- RangeSet,
6257
- cmp,
6258
- Entity,
6259
- PropModSymbol,
6260
- PropModification,
6261
- replacePrefix,
6262
- add: add2,
6263
- remove
6264
- } = Dexie;
6265
-
6266
8267
  // ../../node_modules/dexie-react-hooks/dist/dexie-react-hooks.mjs
6267
8268
  var import_react2 = __toESM(require("react"), 1);
6268
8269
  function useObservable(observableFactory, arg2, arg3) {