@converse/skeletor 3.0.1 → 3.1.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/skeletor.js CHANGED
@@ -5,7 +5,7 @@
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
7
  /** Used for built-in method references. */
8
- var objectProto$l = Object.prototype;
8
+ var objectProto$m = Object.prototype;
9
9
 
10
10
  /**
11
11
  * Checks if `value` is likely a prototype object.
@@ -16,7 +16,7 @@
16
16
  */
17
17
  function isPrototype(value) {
18
18
  var Ctor = value && value.constructor,
19
- proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$l;
19
+ proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$m;
20
20
 
21
21
  return value === proto;
22
22
  }
@@ -39,10 +39,10 @@
39
39
  var nativeKeys = overArg(Object.keys, Object);
40
40
 
41
41
  /** Used for built-in method references. */
42
- var objectProto$k = Object.prototype;
42
+ var objectProto$l = Object.prototype;
43
43
 
44
44
  /** Used to check objects for own properties. */
45
- var hasOwnProperty$h = objectProto$k.hasOwnProperty;
45
+ var hasOwnProperty$i = objectProto$l.hasOwnProperty;
46
46
 
47
47
  /**
48
48
  * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
@@ -57,7 +57,7 @@
57
57
  }
58
58
  var result = [];
59
59
  for (var key in Object(object)) {
60
- if (hasOwnProperty$h.call(object, key) && key != 'constructor') {
60
+ if (hasOwnProperty$i.call(object, key) && key != 'constructor') {
61
61
  result.push(key);
62
62
  }
63
63
  }
@@ -77,17 +77,17 @@
77
77
  var Symbol$1 = root$1.Symbol;
78
78
 
79
79
  /** Used for built-in method references. */
80
- var objectProto$j = Object.prototype;
80
+ var objectProto$k = Object.prototype;
81
81
 
82
82
  /** Used to check objects for own properties. */
83
- var hasOwnProperty$g = objectProto$j.hasOwnProperty;
83
+ var hasOwnProperty$h = objectProto$k.hasOwnProperty;
84
84
 
85
85
  /**
86
86
  * Used to resolve the
87
87
  * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
88
88
  * of values.
89
89
  */
90
- var nativeObjectToString$2 = objectProto$j.toString;
90
+ var nativeObjectToString$2 = objectProto$k.toString;
91
91
 
92
92
  /** Built-in value references. */
93
93
  var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;
@@ -100,7 +100,7 @@
100
100
  * @returns {string} Returns the raw `toStringTag`.
101
101
  */
102
102
  function getRawTag(value) {
103
- var isOwn = hasOwnProperty$g.call(value, symToStringTag$1),
103
+ var isOwn = hasOwnProperty$h.call(value, symToStringTag$1),
104
104
  tag = value[symToStringTag$1];
105
105
 
106
106
  try {
@@ -120,14 +120,14 @@
120
120
  }
121
121
 
122
122
  /** Used for built-in method references. */
123
- var objectProto$i = Object.prototype;
123
+ var objectProto$j = Object.prototype;
124
124
 
125
125
  /**
126
126
  * Used to resolve the
127
127
  * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
128
128
  * of values.
129
129
  */
130
- var nativeObjectToString$1 = objectProto$i.toString;
130
+ var nativeObjectToString$1 = objectProto$j.toString;
131
131
 
132
132
  /**
133
133
  * Converts `value` to a string using `Object.prototype.toString`.
@@ -282,17 +282,17 @@
282
282
 
283
283
  /** Used for built-in method references. */
284
284
  var funcProto$1 = Function.prototype,
285
- objectProto$h = Object.prototype;
285
+ objectProto$i = Object.prototype;
286
286
 
287
287
  /** Used to resolve the decompiled source of functions. */
288
288
  var funcToString$1 = funcProto$1.toString;
289
289
 
290
290
  /** Used to check objects for own properties. */
291
- var hasOwnProperty$f = objectProto$h.hasOwnProperty;
291
+ var hasOwnProperty$g = objectProto$i.hasOwnProperty;
292
292
 
293
293
  /** Used to detect if a method is native. */
294
294
  var reIsNative = RegExp('^' +
295
- funcToString$1.call(hasOwnProperty$f).replace(reRegExpChar, '\\$&')
295
+ funcToString$1.call(hasOwnProperty$g).replace(reRegExpChar, '\\$&')
296
296
  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
297
297
  );
298
298
 
@@ -341,16 +341,16 @@
341
341
  var DataView = getNative(root$1, 'DataView');
342
342
 
343
343
  /* Built-in method references that are verified to be native. */
344
- var Map = getNative(root$1, 'Map');
344
+ var Map$1 = getNative(root$1, 'Map');
345
345
 
346
346
  /* Built-in method references that are verified to be native. */
347
347
  var Promise$1 = getNative(root$1, 'Promise');
348
348
 
349
349
  /* Built-in method references that are verified to be native. */
350
- var Set = getNative(root$1, 'Set');
350
+ var Set$1 = getNative(root$1, 'Set');
351
351
 
352
352
  /* Built-in method references that are verified to be native. */
353
- var WeakMap = getNative(root$1, 'WeakMap');
353
+ var WeakMap$1 = getNative(root$1, 'WeakMap');
354
354
 
355
355
  /** `Object#toString` result references. */
356
356
  var mapTag$6 = '[object Map]',
@@ -363,10 +363,10 @@
363
363
 
364
364
  /** Used to detect maps, sets, and weakmaps. */
365
365
  var dataViewCtorString = toSource(DataView),
366
- mapCtorString = toSource(Map),
366
+ mapCtorString = toSource(Map$1),
367
367
  promiseCtorString = toSource(Promise$1),
368
- setCtorString = toSource(Set),
369
- weakMapCtorString = toSource(WeakMap);
368
+ setCtorString = toSource(Set$1),
369
+ weakMapCtorString = toSource(WeakMap$1);
370
370
 
371
371
  /**
372
372
  * Gets the `toStringTag` of `value`.
@@ -379,10 +379,10 @@
379
379
 
380
380
  // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
381
381
  if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$4) ||
382
- (Map && getTag(new Map) != mapTag$6) ||
382
+ (Map$1 && getTag(new Map$1) != mapTag$6) ||
383
383
  (Promise$1 && getTag(Promise$1.resolve()) != promiseTag) ||
384
- (Set && getTag(new Set) != setTag$6) ||
385
- (WeakMap && getTag(new WeakMap) != weakMapTag$2)) {
384
+ (Set$1 && getTag(new Set$1) != setTag$6) ||
385
+ (WeakMap$1 && getTag(new WeakMap$1) != weakMapTag$2)) {
386
386
  getTag = function(value) {
387
387
  var result = baseGetTag(value),
388
388
  Ctor = result == objectTag$4 ? value.constructor : undefined,
@@ -444,13 +444,13 @@
444
444
  }
445
445
 
446
446
  /** Used for built-in method references. */
447
- var objectProto$g = Object.prototype;
447
+ var objectProto$h = Object.prototype;
448
448
 
449
449
  /** Used to check objects for own properties. */
450
- var hasOwnProperty$e = objectProto$g.hasOwnProperty;
450
+ var hasOwnProperty$f = objectProto$h.hasOwnProperty;
451
451
 
452
452
  /** Built-in value references. */
453
- var propertyIsEnumerable$1 = objectProto$g.propertyIsEnumerable;
453
+ var propertyIsEnumerable$1 = objectProto$h.propertyIsEnumerable;
454
454
 
455
455
  /**
456
456
  * Checks if `value` is likely an `arguments` object.
@@ -471,7 +471,7 @@
471
471
  * // => false
472
472
  */
473
473
  var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
474
- return isObjectLike(value) && hasOwnProperty$e.call(value, 'callee') &&
474
+ return isObjectLike(value) && hasOwnProperty$f.call(value, 'callee') &&
475
475
  !propertyIsEnumerable$1.call(value, 'callee');
476
476
  };
477
477
 
@@ -736,10 +736,10 @@
736
736
  setTag$4 = '[object Set]';
737
737
 
738
738
  /** Used for built-in method references. */
739
- var objectProto$f = Object.prototype;
739
+ var objectProto$g = Object.prototype;
740
740
 
741
741
  /** Used to check objects for own properties. */
742
- var hasOwnProperty$d = objectProto$f.hasOwnProperty;
742
+ var hasOwnProperty$e = objectProto$g.hasOwnProperty;
743
743
 
744
744
  /**
745
745
  * Checks if `value` is an empty object, collection, map, or set.
@@ -791,7 +791,7 @@
791
791
  return !baseKeys(value).length;
792
792
  }
793
793
  for (var key in value) {
794
- if (hasOwnProperty$d.call(value, key)) {
794
+ if (hasOwnProperty$e.call(value, key)) {
795
795
  return false;
796
796
  }
797
797
  }
@@ -842,10 +842,10 @@
842
842
  }
843
843
 
844
844
  /** Used for built-in method references. */
845
- var objectProto$e = Object.prototype;
845
+ var objectProto$f = Object.prototype;
846
846
 
847
847
  /** Used to check objects for own properties. */
848
- var hasOwnProperty$c = objectProto$e.hasOwnProperty;
848
+ var hasOwnProperty$d = objectProto$f.hasOwnProperty;
849
849
 
850
850
  /**
851
851
  * Creates an array of the enumerable property names of the array-like `value`.
@@ -865,7 +865,7 @@
865
865
  length = result.length;
866
866
 
867
867
  for (var key in value) {
868
- if ((inherited || hasOwnProperty$c.call(value, key)) &&
868
+ if ((inherited || hasOwnProperty$d.call(value, key)) &&
869
869
  !(skipIndexes && (
870
870
  // Safari 9 has enumerable `arguments.length` in strict mode.
871
871
  key == 'length' ||
@@ -1008,7 +1008,7 @@
1008
1008
  * _.toString([1, 2, 3]);
1009
1009
  * // => '1,2,3'
1010
1010
  */
1011
- function toString$2(value) {
1011
+ function toString$1(value) {
1012
1012
  return value == null ? '' : baseToString(value);
1013
1013
  }
1014
1014
 
@@ -1034,7 +1034,7 @@
1034
1034
  */
1035
1035
  function uniqueId(prefix) {
1036
1036
  var id = ++idCounter;
1037
- return toString$2(prefix) + id;
1037
+ return toString$1(prefix) + id;
1038
1038
  }
1039
1039
 
1040
1040
  /** Used to match a single whitespace character. */
@@ -1630,6 +1630,14 @@
1630
1630
  eventsApi(triggerApi, this._events, name, undefined, args);
1631
1631
  return this;
1632
1632
  }
1633
+ /**
1634
+ * Subscribe to an event. Returns an unsubscribe function.
1635
+ * Compatible with `useSyncExternalStore` and other store-style APIs.
1636
+ */
1637
+ subscribe(event, callback, context) {
1638
+ this.on(event, callback, context);
1639
+ return () => this.off(event, callback, context);
1640
+ }
1633
1641
  };
1634
1642
  }
1635
1643
  /**
@@ -1637,7 +1645,7 @@
1637
1645
  */
1638
1646
  const EventEmitterObject = EventEmitter(Object);
1639
1647
 
1640
- /*! *****************************************************************************
1648
+ /******************************************************************************
1641
1649
  Copyright (c) Microsoft Corporation.
1642
1650
 
1643
1651
  Permission to use, copy, modify, and/or distribute this software for any
@@ -1651,7 +1659,7 @@
1651
1659
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1652
1660
  PERFORMANCE OF THIS SOFTWARE.
1653
1661
  ***************************************************************************** */
1654
- /* global Reflect, Promise */
1662
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
1655
1663
 
1656
1664
 
1657
1665
  function __values(o) {
@@ -1664,7 +1672,25 @@
1664
1672
  }
1665
1673
  };
1666
1674
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
1667
- }
1675
+ }
1676
+
1677
+ function __classPrivateFieldGet(receiver, state, kind, f) {
1678
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
1679
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
1680
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
1681
+ }
1682
+
1683
+ function __classPrivateFieldSet(receiver, state, value, kind, f) {
1684
+ if (kind === "m") throw new TypeError("Private method is not writable");
1685
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
1686
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
1687
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
1688
+ }
1689
+
1690
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1691
+ var e = new Error(message);
1692
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1693
+ };
1668
1694
 
1669
1695
  /*!
1670
1696
  MIT License
@@ -1703,7 +1729,7 @@
1703
1729
  * @param parts
1704
1730
  * @param properties
1705
1731
  */
1706
- function createBlob$1(parts, properties) {
1732
+ function createBlob(parts, properties) {
1707
1733
  /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
1708
1734
  parts = parts || [];
1709
1735
  properties = properties || {};
@@ -1727,12 +1753,12 @@
1727
1753
  }
1728
1754
  }
1729
1755
 
1730
- var BLOB_TYPE_PREFIX_REGEX$1 = /^~~local_forage_type~([^~]+)~/;
1731
- var SERIALIZED_MARKER_LENGTH$1 = "__lfsc__:" /* SERIALIZED_MARKER */.length;
1732
- var TYPE_SERIALIZED_MARKER_LENGTH$1 = SERIALIZED_MARKER_LENGTH$1 + "arbf" /* TYPE_ARRAYBUFFER */.length;
1756
+ var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;
1757
+ var SERIALIZED_MARKER_LENGTH = "__lfsc__:" /* SERIALIZED_MARKER */.length;
1758
+ var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + "arbf" /* TYPE_ARRAYBUFFER */.length;
1733
1759
  //tslint:disable:no-magic-numbers no-bitwise prefer-switch no-unbound-method
1734
- var toString$1 = Object.prototype.toString;
1735
- function stringToBuffer$1(serializedString) {
1760
+ var toString = Object.prototype.toString;
1761
+ function stringToBuffer(serializedString) {
1736
1762
  // Fill the string into a ArrayBuffer.
1737
1763
  var bufferLength = serializedString.length * 0.75;
1738
1764
  var len = serializedString.length;
@@ -1759,7 +1785,7 @@
1759
1785
  * Converts a buffer to a string to store, serialized, in the backend
1760
1786
  * storage library.
1761
1787
  */
1762
- function bufferToString$1(buffer) {
1788
+ function bufferToString(buffer) {
1763
1789
  // base64-arraybuffer
1764
1790
  var bytes = new Uint8Array(buffer);
1765
1791
  var base64String = '';
@@ -1786,15 +1812,15 @@
1786
1812
  * @param value
1787
1813
  * @param callback
1788
1814
  */
1789
- function serialize$2(value, callback) {
1815
+ function serialize$1(value, callback) {
1790
1816
  var valueType = '';
1791
1817
  if (value) {
1792
- valueType = toString$1.call(value);
1818
+ valueType = toString.call(value);
1793
1819
  }
1794
1820
  // Cannot use `value instanceof ArrayBuffer` or such here, as these
1795
1821
  // checks fail when running the tests using casper.js...
1796
1822
  if (value && (valueType === '[object ArrayBuffer]' ||
1797
- (value.buffer && toString$1.call(value.buffer) === '[object ArrayBuffer]'))) {
1823
+ (value.buffer && toString.call(value.buffer) === '[object ArrayBuffer]'))) {
1798
1824
  // Convert binary arrays to a string and prefix the string with
1799
1825
  // a special marker.
1800
1826
  var buffer = void 0;
@@ -1836,7 +1862,7 @@
1836
1862
  callback(new Error('Failed to get type for BinaryArray'));
1837
1863
  }
1838
1864
  }
1839
- callback(marker + bufferToString$1(buffer));
1865
+ callback(marker + bufferToString(buffer));
1840
1866
  }
1841
1867
  else if (valueType === '[object Blob]') {
1842
1868
  // Convert the blob to a binaryArray and then to a string.
@@ -1844,7 +1870,7 @@
1844
1870
  fileReader.onload = function () {
1845
1871
  // Backwards-compatible prefix for the blob type.
1846
1872
  //tslint:disable-next-line:restrict-plus-operands
1847
- var str = "~~local_forage_type~" /* BLOB_TYPE_PREFIX */ + value.type + "~" + bufferToString$1(this.result);
1873
+ var str = "~~local_forage_type~" /* BLOB_TYPE_PREFIX */ + value.type + "~" + bufferToString(this.result);
1848
1874
  callback("__lfsc__:" /* SERIALIZED_MARKER */ + "blob" /* TYPE_BLOB */ + str);
1849
1875
  };
1850
1876
  fileReader.readAsArrayBuffer(value);
@@ -1870,34 +1896,34 @@
1870
1896
  * some kind of arraybuffer/binary data/typed array out of the string.
1871
1897
  * @param value
1872
1898
  */
1873
- function deserialize$2(value) {
1899
+ function deserialize$1(value) {
1874
1900
  // If we haven't marked this string as being specially serialized (i.e.
1875
1901
  // something other than serialized JSON), we can just return it and be
1876
1902
  // done with it.
1877
- if (value.substring(0, SERIALIZED_MARKER_LENGTH$1) !== "__lfsc__:" /* SERIALIZED_MARKER */) {
1903
+ if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== "__lfsc__:" /* SERIALIZED_MARKER */) {
1878
1904
  return JSON.parse(value);
1879
1905
  }
1880
1906
  // The following code deals with deserializing some kind of Blob or
1881
1907
  // TypedArray. First we separate out the type of data we're dealing
1882
1908
  // with from the data itself.
1883
- var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH$1);
1884
- var type = value.substring(SERIALIZED_MARKER_LENGTH$1, TYPE_SERIALIZED_MARKER_LENGTH$1);
1909
+ var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);
1910
+ var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);
1885
1911
  var blobType;
1886
1912
  // Backwards-compatible blob type serialization strategy.
1887
1913
  // DBs created with older versions of localForage will simply not have the blob type.
1888
- if (type === "blob" /* TYPE_BLOB */ && BLOB_TYPE_PREFIX_REGEX$1.test(serializedString)) {
1889
- var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX$1);
1914
+ if (type === "blob" /* TYPE_BLOB */ && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {
1915
+ var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);
1890
1916
  blobType = matcher[1];
1891
1917
  serializedString = serializedString.substring(matcher[0].length);
1892
1918
  }
1893
- var buffer = stringToBuffer$1(serializedString);
1919
+ var buffer = stringToBuffer(serializedString);
1894
1920
  // Return the right type based on the code/type set during
1895
1921
  // serialization.
1896
1922
  switch (type) {
1897
1923
  case "arbf" /* TYPE_ARRAYBUFFER */:
1898
1924
  return buffer;
1899
1925
  case "blob" /* TYPE_BLOB */:
1900
- return createBlob$1([buffer], { type: blobType });
1926
+ return createBlob([buffer], { type: blobType });
1901
1927
  case "si08" /* TYPE_INT8ARRAY */:
1902
1928
  return new Int8Array(buffer);
1903
1929
  case "ui08" /* TYPE_UINT8ARRAY */:
@@ -1951,7 +1977,7 @@
1951
1977
  return (options.name || defaultConfig.name) + "/" + (options.storeName || defaultConfig.storeName) + "/";
1952
1978
  }
1953
1979
 
1954
- function executeCallback$2(promise, callback) {
1980
+ function executeCallback$1(promise, callback) {
1955
1981
  if (callback) {
1956
1982
  promise.then(function (result) {
1957
1983
  callback(null, result);
@@ -2004,10 +2030,10 @@
2004
2030
  }
2005
2031
 
2006
2032
  var serialiser = {
2007
- bufferToString: bufferToString$1,
2008
- deserialize: deserialize$2,
2009
- serialize: serialize$2,
2010
- stringToBuffer: stringToBuffer$1
2033
+ bufferToString: bufferToString,
2034
+ deserialize: deserialize$1,
2035
+ serialize: serialize$1,
2036
+ stringToBuffer: stringToBuffer
2011
2037
  };
2012
2038
 
2013
2039
  /*!
@@ -2092,7 +2118,7 @@
2092
2118
  var promise = this.ready().then(function () {
2093
2119
  _this._dbInfo.mStore.clear();
2094
2120
  });
2095
- executeCallback$2(promise, callback);
2121
+ executeCallback$1(promise, callback);
2096
2122
  return promise;
2097
2123
  }
2098
2124
 
@@ -2101,7 +2127,7 @@
2101
2127
  var outPromise = promise.then(function (keyPrefix) {
2102
2128
  Store.resolve(keyPrefix).drop();
2103
2129
  });
2104
- executeCallback$2(outPromise, callback);
2130
+ executeCallback$1(outPromise, callback);
2105
2131
  return promise;
2106
2132
  }
2107
2133
 
@@ -2113,7 +2139,7 @@
2113
2139
  // Deserialise if the result is not null or undefined
2114
2140
  return result == null ? null : _this._dbInfo.serializer.deserialize(result); //tslint:disable-line:triple-equals
2115
2141
  });
2116
- executeCallback$2(promise, callback);
2142
+ executeCallback$1(promise, callback);
2117
2143
  return promise;
2118
2144
  }
2119
2145
 
@@ -2137,7 +2163,7 @@
2137
2163
  }
2138
2164
  }
2139
2165
  });
2140
- executeCallback$2(promise, callback);
2166
+ executeCallback$1(promise, callback);
2141
2167
  return promise;
2142
2168
  }
2143
2169
 
@@ -2156,7 +2182,7 @@
2156
2182
  }
2157
2183
  return result;
2158
2184
  });
2159
- executeCallback$2(promise, callback);
2185
+ executeCallback$1(promise, callback);
2160
2186
  return promise;
2161
2187
  }
2162
2188
 
@@ -2165,13 +2191,13 @@
2165
2191
  var promise = this.ready().then(function () {
2166
2192
  return _this._dbInfo.mStore.keys();
2167
2193
  });
2168
- executeCallback$2(promise, callback);
2194
+ executeCallback$1(promise, callback);
2169
2195
  return promise;
2170
2196
  }
2171
2197
 
2172
2198
  function length$1(callback) {
2173
2199
  var promise = this.keys().then(function (keys$) { return keys$.length; });
2174
- executeCallback$2(promise, callback);
2200
+ executeCallback$1(promise, callback);
2175
2201
  return promise;
2176
2202
  }
2177
2203
 
@@ -2181,7 +2207,7 @@
2181
2207
  var promise = this.ready().then(function () {
2182
2208
  _this._dbInfo.mStore.rm(key$);
2183
2209
  });
2184
- executeCallback$2(promise, callback);
2210
+ executeCallback$1(promise, callback);
2185
2211
  return promise;
2186
2212
  }
2187
2213
 
@@ -2211,7 +2237,7 @@
2211
2237
  });
2212
2238
  });
2213
2239
  });
2214
- executeCallback$2(promise, callback);
2240
+ executeCallback$1(promise, callback);
2215
2241
  return promise;
2216
2242
  }
2217
2243
 
@@ -2498,10 +2524,10 @@
2498
2524
  var HASH_UNDEFINED$2 = '__lodash_hash_undefined__';
2499
2525
 
2500
2526
  /** Used for built-in method references. */
2501
- var objectProto$d = Object.prototype;
2527
+ var objectProto$e = Object.prototype;
2502
2528
 
2503
2529
  /** Used to check objects for own properties. */
2504
- var hasOwnProperty$b = objectProto$d.hasOwnProperty;
2530
+ var hasOwnProperty$c = objectProto$e.hasOwnProperty;
2505
2531
 
2506
2532
  /**
2507
2533
  * Gets the hash value for `key`.
@@ -2518,14 +2544,14 @@
2518
2544
  var result = data[key];
2519
2545
  return result === HASH_UNDEFINED$2 ? undefined : result;
2520
2546
  }
2521
- return hasOwnProperty$b.call(data, key) ? data[key] : undefined;
2547
+ return hasOwnProperty$c.call(data, key) ? data[key] : undefined;
2522
2548
  }
2523
2549
 
2524
2550
  /** Used for built-in method references. */
2525
- var objectProto$c = Object.prototype;
2551
+ var objectProto$d = Object.prototype;
2526
2552
 
2527
2553
  /** Used to check objects for own properties. */
2528
- var hasOwnProperty$a = objectProto$c.hasOwnProperty;
2554
+ var hasOwnProperty$b = objectProto$d.hasOwnProperty;
2529
2555
 
2530
2556
  /**
2531
2557
  * Checks if a hash value for `key` exists.
@@ -2538,7 +2564,7 @@
2538
2564
  */
2539
2565
  function hashHas(key) {
2540
2566
  var data = this.__data__;
2541
- return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$a.call(data, key);
2567
+ return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$b.call(data, key);
2542
2568
  }
2543
2569
 
2544
2570
  /** Used to stand-in for `undefined` hash values. */
@@ -2597,7 +2623,7 @@
2597
2623
  this.size = 0;
2598
2624
  this.__data__ = {
2599
2625
  'hash': new Hash,
2600
- 'map': new (Map || ListCache),
2626
+ 'map': new (Map$1 || ListCache),
2601
2627
  'string': new Hash
2602
2628
  };
2603
2629
  }
@@ -2733,7 +2759,7 @@
2733
2759
  var data = this.__data__;
2734
2760
  if (data instanceof ListCache) {
2735
2761
  var pairs = data.__data__;
2736
- if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
2762
+ if (!Map$1 || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
2737
2763
  pairs.push([key, value]);
2738
2764
  this.size = ++data.size;
2739
2765
  return this;
@@ -2816,10 +2842,10 @@
2816
2842
  }
2817
2843
 
2818
2844
  /** Used for built-in method references. */
2819
- var objectProto$b = Object.prototype;
2845
+ var objectProto$c = Object.prototype;
2820
2846
 
2821
2847
  /** Used to check objects for own properties. */
2822
- var hasOwnProperty$9 = objectProto$b.hasOwnProperty;
2848
+ var hasOwnProperty$a = objectProto$c.hasOwnProperty;
2823
2849
 
2824
2850
  /**
2825
2851
  * Assigns `value` to `key` of `object` if the existing value is not equivalent
@@ -2833,7 +2859,7 @@
2833
2859
  */
2834
2860
  function assignValue(object, key, value) {
2835
2861
  var objValue = object[key];
2836
- if (!(hasOwnProperty$9.call(object, key) && eq(objValue, value)) ||
2862
+ if (!(hasOwnProperty$a.call(object, key) && eq(objValue, value)) ||
2837
2863
  (value === undefined && !(key in object))) {
2838
2864
  baseAssignValue(object, key, value);
2839
2865
  }
@@ -2906,10 +2932,10 @@
2906
2932
  }
2907
2933
 
2908
2934
  /** Used for built-in method references. */
2909
- var objectProto$a = Object.prototype;
2935
+ var objectProto$b = Object.prototype;
2910
2936
 
2911
2937
  /** Used to check objects for own properties. */
2912
- var hasOwnProperty$8 = objectProto$a.hasOwnProperty;
2938
+ var hasOwnProperty$9 = objectProto$b.hasOwnProperty;
2913
2939
 
2914
2940
  /**
2915
2941
  * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
@@ -2926,7 +2952,7 @@
2926
2952
  result = [];
2927
2953
 
2928
2954
  for (var key in object) {
2929
- if (!(key == 'constructor' && (isProto || !hasOwnProperty$8.call(object, key)))) {
2955
+ if (!(key == 'constructor' && (isProto || !hasOwnProperty$9.call(object, key)))) {
2930
2956
  result.push(key);
2931
2957
  }
2932
2958
  }
@@ -3071,10 +3097,10 @@
3071
3097
  }
3072
3098
 
3073
3099
  /** Used for built-in method references. */
3074
- var objectProto$9 = Object.prototype;
3100
+ var objectProto$a = Object.prototype;
3075
3101
 
3076
3102
  /** Built-in value references. */
3077
- var propertyIsEnumerable = objectProto$9.propertyIsEnumerable;
3103
+ var propertyIsEnumerable = objectProto$a.propertyIsEnumerable;
3078
3104
 
3079
3105
  /* Built-in method references for those with the same name as other `lodash` methods. */
3080
3106
  var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
@@ -3201,10 +3227,10 @@
3201
3227
  }
3202
3228
 
3203
3229
  /** Used for built-in method references. */
3204
- var objectProto$8 = Object.prototype;
3230
+ var objectProto$9 = Object.prototype;
3205
3231
 
3206
3232
  /** Used to check objects for own properties. */
3207
- var hasOwnProperty$7 = objectProto$8.hasOwnProperty;
3233
+ var hasOwnProperty$8 = objectProto$9.hasOwnProperty;
3208
3234
 
3209
3235
  /**
3210
3236
  * Initializes an array clone.
@@ -3218,7 +3244,7 @@
3218
3244
  result = new array.constructor(length);
3219
3245
 
3220
3246
  // Add properties assigned by `RegExp#exec`.
3221
- if (length && typeof array[0] == 'string' && hasOwnProperty$7.call(array, 'index')) {
3247
+ if (length && typeof array[0] == 'string' && hasOwnProperty$8.call(array, 'index')) {
3222
3248
  result.index = array.index;
3223
3249
  result.input = array.input;
3224
3250
  }
@@ -6598,13 +6624,13 @@
6598
6624
 
6599
6625
  /** Used for built-in method references. */
6600
6626
  var funcProto = Function.prototype,
6601
- objectProto$7 = Object.prototype;
6627
+ objectProto$8 = Object.prototype;
6602
6628
 
6603
6629
  /** Used to resolve the decompiled source of functions. */
6604
6630
  var funcToString = funcProto.toString;
6605
6631
 
6606
6632
  /** Used to check objects for own properties. */
6607
- var hasOwnProperty$6 = objectProto$7.hasOwnProperty;
6633
+ var hasOwnProperty$7 = objectProto$8.hasOwnProperty;
6608
6634
 
6609
6635
  /** Used to infer the `Object` constructor. */
6610
6636
  var objectCtorString = funcToString.call(Object);
@@ -6645,7 +6671,7 @@
6645
6671
  if (proto === null) {
6646
6672
  return true;
6647
6673
  }
6648
- var Ctor = hasOwnProperty$6.call(proto, 'constructor') && proto.constructor;
6674
+ var Ctor = hasOwnProperty$7.call(proto, 'constructor') && proto.constructor;
6649
6675
  return typeof Ctor == 'function' && Ctor instanceof Ctor &&
6650
6676
  funcToString.call(Ctor) == objectCtorString;
6651
6677
  }
@@ -7377,310 +7403,43 @@
7377
7403
  return debounced;
7378
7404
  }
7379
7405
 
7380
- function executeCallback$1(promise, callback) {
7406
+ function chainCallback(promise, callback) {
7381
7407
  if (callback) {
7382
- promise.then(
7383
- function(result) {
7384
- callback(null, result);
7385
- },
7386
- function(error) {
7387
- callback(error);
7388
- }
7389
- );
7408
+ promise.then((result) => callback(null, result), (err) => callback(err));
7390
7409
  }
7391
7410
  }
7392
-
7393
- function getCallback() {
7394
- if (
7395
- arguments.length &&
7396
- typeof arguments[arguments.length - 1] === 'function'
7397
- ) {
7398
- return arguments[arguments.length - 1];
7411
+ function getCallback(...args) {
7412
+ if (args.length && typeof args[args.length - 1] === 'function') {
7413
+ return args[args.length - 1];
7399
7414
  }
7400
7415
  }
7401
-
7402
7416
  function normalizeKey(key) {
7403
- // Cast the key to a string, as that's all we can set as a key.
7404
7417
  if (typeof key !== 'string') {
7405
7418
  console.warn(`${key} used as a key, but it is not a string.`);
7406
7419
  key = String(key);
7407
7420
  }
7408
-
7409
7421
  return key;
7410
7422
  }
7411
-
7412
- // Abstracts constructing a Blob object, so it also works in older
7413
- // browsers that don't support the native Blob constructor. (i.e.
7414
- // old QtWebKit versions, at least).
7415
- // Abstracts constructing a Blob object, so it also works in older
7416
- // browsers that don't support the native Blob constructor. (i.e.
7417
- // old QtWebKit versions, at least).
7418
- function createBlob(parts, properties) {
7419
- /* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
7420
- parts = parts || [];
7421
- properties = properties || {};
7422
- try {
7423
- return new Blob(parts, properties);
7424
- } catch (e) {
7425
- if (e.name !== 'TypeError') {
7426
- throw e;
7427
- }
7428
- var Builder =
7429
- typeof BlobBuilder !== 'undefined'
7430
- ? BlobBuilder
7431
- : typeof MSBlobBuilder !== 'undefined'
7432
- ? MSBlobBuilder
7433
- : typeof MozBlobBuilder !== 'undefined'
7434
- ? MozBlobBuilder
7435
- : WebKitBlobBuilder;
7436
- var builder = new Builder();
7437
- for (var i = 0; i < parts.length; i += 1) {
7438
- builder.append(parts[i]);
7423
+ function serializeSync(value) {
7424
+ return JSON.stringify(value, (_key, val) => {
7425
+ if (val instanceof Date) {
7426
+ return val.toISOString();
7439
7427
  }
7440
- return builder.getBlob(properties.type);
7441
- }
7442
- }
7443
-
7444
- /* eslint-disable no-bitwise */
7445
-
7446
- // Sadly, the best way to save binary data in WebSQL/localStorage is serializing
7447
- // it to Base64, so this is how we store it to prevent very strange errors with less
7448
- // verbose ways of binary <-> string data storage.
7449
- var BASE_CHARS =
7450
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
7451
-
7452
- var BLOB_TYPE_PREFIX = '~~local_forage_type~';
7453
- var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;
7454
-
7455
- var SERIALIZED_MARKER = '__lfsc__:';
7456
- var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;
7457
-
7458
- // OMG the serializations!
7459
- var TYPE_ARRAYBUFFER = 'arbf';
7460
- var TYPE_BLOB = 'blob';
7461
- var TYPE_INT8ARRAY = 'si08';
7462
- var TYPE_UINT8ARRAY = 'ui08';
7463
- var TYPE_UINT8CLAMPEDARRAY = 'uic8';
7464
- var TYPE_INT16ARRAY = 'si16';
7465
- var TYPE_INT32ARRAY = 'si32';
7466
- var TYPE_UINT16ARRAY = 'ur16';
7467
- var TYPE_UINT32ARRAY = 'ui32';
7468
- var TYPE_FLOAT32ARRAY = 'fl32';
7469
- var TYPE_FLOAT64ARRAY = 'fl64';
7470
- var TYPE_SERIALIZED_MARKER_LENGTH =
7471
- SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;
7472
-
7473
- var toString = Object.prototype.toString;
7474
-
7475
- function stringToBuffer(serializedString) {
7476
- // Fill the string into a ArrayBuffer.
7477
- var bufferLength = serializedString.length * 0.75;
7478
- var len = serializedString.length;
7479
- var i;
7480
- var p = 0;
7481
- var encoded1, encoded2, encoded3, encoded4;
7482
-
7483
- if (serializedString[serializedString.length - 1] === '=') {
7484
- bufferLength--;
7485
- if (serializedString[serializedString.length - 2] === '=') {
7486
- bufferLength--;
7487
- }
7488
- }
7489
-
7490
- var buffer = new ArrayBuffer(bufferLength);
7491
- var bytes = new Uint8Array(buffer);
7492
-
7493
- for (i = 0; i < len; i += 4) {
7494
- encoded1 = BASE_CHARS.indexOf(serializedString[i]);
7495
- encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);
7496
- encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);
7497
- encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);
7498
-
7499
- /*jslint bitwise: true */
7500
- bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
7501
- bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
7502
- bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
7503
- }
7504
- return buffer;
7505
- }
7506
-
7507
- // Converts a buffer to a string to store, serialized, in the backend
7508
- // storage library.
7509
- function bufferToString(buffer) {
7510
- // base64-arraybuffer
7511
- var bytes = new Uint8Array(buffer);
7512
- var base64String = '';
7513
- var i;
7514
-
7515
- for (i = 0; i < bytes.length; i += 3) {
7516
- /*jslint bitwise: true */
7517
- base64String += BASE_CHARS[bytes[i] >> 2];
7518
- base64String += BASE_CHARS[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
7519
- base64String +=
7520
- BASE_CHARS[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
7521
- base64String += BASE_CHARS[bytes[i + 2] & 63];
7522
- }
7523
-
7524
- if (bytes.length % 3 === 2) {
7525
- base64String = base64String.substring(0, base64String.length - 1) + '=';
7526
- } else if (bytes.length % 3 === 1) {
7527
- base64String =
7528
- base64String.substring(0, base64String.length - 2) + '==';
7529
- }
7530
-
7531
- return base64String;
7428
+ return val;
7429
+ });
7532
7430
  }
7533
-
7534
- // Serialize a value, afterwards executing a callback (which usually
7535
- // instructs the `setItem()` callback/promise to be executed). This is how
7536
- // we store binary data with localStorage.
7537
- function serialize$1(value, callback) {
7538
- var valueType = '';
7539
- if (value) {
7540
- valueType = toString.call(value);
7431
+ function serialize(value, callback) {
7432
+ try {
7433
+ callback(serializeSync(value), null);
7541
7434
  }
7542
-
7543
- // Cannot use `value instanceof ArrayBuffer` or such here, as these
7544
- // checks fail when running the tests using casper.js...
7545
- //
7546
- // TODO: See why those tests fail and use a better solution.
7547
- if (
7548
- value &&
7549
- (valueType === '[object ArrayBuffer]' ||
7550
- (value.buffer &&
7551
- toString.call(value.buffer) === '[object ArrayBuffer]'))
7552
- ) {
7553
- // Convert binary arrays to a string and prefix the string with
7554
- // a special marker.
7555
- var buffer;
7556
- var marker = SERIALIZED_MARKER;
7557
-
7558
- if (value instanceof ArrayBuffer) {
7559
- buffer = value;
7560
- marker += TYPE_ARRAYBUFFER;
7561
- } else {
7562
- buffer = value.buffer;
7563
-
7564
- if (valueType === '[object Int8Array]') {
7565
- marker += TYPE_INT8ARRAY;
7566
- } else if (valueType === '[object Uint8Array]') {
7567
- marker += TYPE_UINT8ARRAY;
7568
- } else if (valueType === '[object Uint8ClampedArray]') {
7569
- marker += TYPE_UINT8CLAMPEDARRAY;
7570
- } else if (valueType === '[object Int16Array]') {
7571
- marker += TYPE_INT16ARRAY;
7572
- } else if (valueType === '[object Uint16Array]') {
7573
- marker += TYPE_UINT16ARRAY;
7574
- } else if (valueType === '[object Int32Array]') {
7575
- marker += TYPE_INT32ARRAY;
7576
- } else if (valueType === '[object Uint32Array]') {
7577
- marker += TYPE_UINT32ARRAY;
7578
- } else if (valueType === '[object Float32Array]') {
7579
- marker += TYPE_FLOAT32ARRAY;
7580
- } else if (valueType === '[object Float64Array]') {
7581
- marker += TYPE_FLOAT64ARRAY;
7582
- } else {
7583
- callback(new Error('Failed to get type for BinaryArray'));
7584
- }
7585
- }
7586
-
7587
- callback(marker + bufferToString(buffer));
7588
- } else if (valueType === '[object Blob]') {
7589
- // Conver the blob to a binaryArray and then to a string.
7590
- var fileReader = new FileReader();
7591
-
7592
- fileReader.onload = function() {
7593
- // Backwards-compatible prefix for the blob type.
7594
- var str =
7595
- BLOB_TYPE_PREFIX +
7596
- value.type +
7597
- '~' +
7598
- bufferToString(this.result);
7599
-
7600
- callback(SERIALIZED_MARKER + TYPE_BLOB + str);
7601
- };
7602
-
7603
- fileReader.readAsArrayBuffer(value);
7604
- } else {
7605
- try {
7606
- callback(JSON.stringify(value));
7607
- } catch (e) {
7608
- console.error("Couldn't convert value into a JSON string: ", value);
7609
-
7610
- callback(null, e);
7611
- }
7435
+ catch (e) {
7436
+ callback('', e);
7612
7437
  }
7613
7438
  }
7614
-
7615
- // Deserialize data we've inserted into a value column/field. We place
7616
- // special markers into our strings to mark them as encoded; this isn't
7617
- // as nice as a meta field, but it's the only sane thing we can do whilst
7618
- // keeping localStorage support intact.
7619
- //
7620
- // Oftentimes this will just deserialize JSON content, but if we have a
7621
- // special marker (SERIALIZED_MARKER, defined above), we will extract
7622
- // some kind of arraybuffer/binary data/typed array out of the string.
7623
- function deserialize$1(value) {
7624
- // If we haven't marked this string as being specially serialized (i.e.
7625
- // something other than serialized JSON), we can just return it and be
7626
- // done with it.
7627
- if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {
7628
- return JSON.parse(value);
7629
- }
7630
-
7631
- // The following code deals with deserializing some kind of Blob or
7632
- // TypedArray. First we separate out the type of data we're dealing
7633
- // with from the data itself.
7634
- var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);
7635
- var type = value.substring(
7636
- SERIALIZED_MARKER_LENGTH,
7637
- TYPE_SERIALIZED_MARKER_LENGTH
7638
- );
7639
-
7640
- var blobType;
7641
- // Backwards-compatible blob type serialization strategy.
7642
- // DBs created with older versions of localForage will simply not have the blob type.
7643
- if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {
7644
- var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);
7645
- blobType = matcher[1];
7646
- serializedString = serializedString.substring(matcher[0].length);
7647
- }
7648
- var buffer = stringToBuffer(serializedString);
7649
-
7650
- // Return the right type based on the code/type set during
7651
- // serialization.
7652
- switch (type) {
7653
- case TYPE_ARRAYBUFFER:
7654
- return buffer;
7655
- case TYPE_BLOB:
7656
- return createBlob([buffer], { type: blobType });
7657
- case TYPE_INT8ARRAY:
7658
- return new Int8Array(buffer);
7659
- case TYPE_UINT8ARRAY:
7660
- return new Uint8Array(buffer);
7661
- case TYPE_UINT8CLAMPEDARRAY:
7662
- return new Uint8ClampedArray(buffer);
7663
- case TYPE_INT16ARRAY:
7664
- return new Int16Array(buffer);
7665
- case TYPE_UINT16ARRAY:
7666
- return new Uint16Array(buffer);
7667
- case TYPE_INT32ARRAY:
7668
- return new Int32Array(buffer);
7669
- case TYPE_UINT32ARRAY:
7670
- return new Uint32Array(buffer);
7671
- case TYPE_FLOAT32ARRAY:
7672
- return new Float32Array(buffer);
7673
- case TYPE_FLOAT64ARRAY:
7674
- return new Float64Array(buffer);
7675
- default:
7676
- throw new Error('Unkown type: ' + type);
7677
- }
7439
+ function deserialize(value) {
7440
+ return JSON.parse(value);
7678
7441
  }
7679
7442
 
7680
- var localforageSerializer = {
7681
- serialize: serialize$1,
7682
- deserialize: deserialize$1};
7683
-
7684
7443
  // Copyright 2014 Mozilla
7685
7444
  // Copyright 2015 Thodoris Greasidis
7686
7445
  // Copyright 2018-2025 JC Brand
@@ -7696,8 +7455,6 @@
7696
7455
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7697
7456
  // See the License for the specific language governing permissions and
7698
7457
  // limitations under the License.
7699
- const serialize = localforageSerializer['serialize'];
7700
- const deserialize = localforageSerializer['deserialize'];
7701
7458
  function isSessionStorageValid() {
7702
7459
  try {
7703
7460
  if (sessionStorage && 'setItem' in sessionStorage) {
@@ -7743,7 +7500,7 @@
7743
7500
  }
7744
7501
  }
7745
7502
  });
7746
- executeCallback$1(promise, callback);
7503
+ chainCallback(promise, callback);
7747
7504
  return promise;
7748
7505
  }
7749
7506
  function getItem(key, callback) {
@@ -7759,7 +7516,7 @@
7759
7516
  }
7760
7517
  return null;
7761
7518
  });
7762
- executeCallback$1(promise, callback);
7519
+ chainCallback(promise, callback);
7763
7520
  return promise;
7764
7521
  }
7765
7522
  function iterate(iterator, callback) {
@@ -7787,7 +7544,7 @@
7787
7544
  }
7788
7545
  return;
7789
7546
  });
7790
- executeCallback$1(promise, callback);
7547
+ chainCallback(promise, callback);
7791
7548
  return promise;
7792
7549
  }
7793
7550
  // Same as sessionStorage's key() method, except takes a callback.
@@ -7807,7 +7564,7 @@
7807
7564
  }
7808
7565
  return result;
7809
7566
  });
7810
- executeCallback$1(promise, callback);
7567
+ chainCallback(promise, callback);
7811
7568
  return promise;
7812
7569
  }
7813
7570
  function keys(callback) {
@@ -7823,7 +7580,7 @@
7823
7580
  }
7824
7581
  return keys;
7825
7582
  });
7826
- executeCallback$1(promise, callback);
7583
+ chainCallback(promise, callback);
7827
7584
  return promise;
7828
7585
  }
7829
7586
  // Supply the number of keys in the datastore to the callback function.
@@ -7832,7 +7589,7 @@
7832
7589
  const promise = self.keys().then(function (keys) {
7833
7590
  return keys.length;
7834
7591
  });
7835
- executeCallback$1(promise, callback);
7592
+ chainCallback(promise, callback);
7836
7593
  return promise;
7837
7594
  }
7838
7595
  function removeItem(key, callback) {
@@ -7840,7 +7597,7 @@
7840
7597
  const promise = this.ready().then(function () {
7841
7598
  sessionStorage.removeItem(dbInfo.keyPrefix + key);
7842
7599
  });
7843
- executeCallback$1(promise, callback);
7600
+ chainCallback(promise, callback);
7844
7601
  return promise;
7845
7602
  }
7846
7603
  async function setItem(key, value, callback) {
@@ -7852,27 +7609,27 @@
7852
7609
  dbInfo.serializer.serialize(value, (serializedValue, error) => {
7853
7610
  if (error) {
7854
7611
  reject(error);
7855
- executeCallback$1(Promise.reject(error), callback);
7612
+ chainCallback(Promise.reject(error), callback);
7856
7613
  return;
7857
7614
  }
7858
7615
  try {
7859
7616
  sessionStorage.setItem(dbInfo.keyPrefix + key, serializedValue);
7860
7617
  resolve(originalValue);
7861
- executeCallback$1(Promise.resolve(originalValue), callback);
7618
+ chainCallback(Promise.resolve(originalValue), callback);
7862
7619
  }
7863
7620
  catch (e) {
7864
7621
  if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {
7865
7622
  console.error('Your sessionStorage capacity is used up.');
7866
7623
  }
7867
7624
  reject(e);
7868
- executeCallback$1(Promise.reject(e), callback);
7625
+ chainCallback(Promise.reject(e), callback);
7869
7626
  }
7870
7627
  });
7871
7628
  });
7872
7629
  }
7873
- function dropInstance(options, callback) {
7874
- callback = getCallback.apply(this, arguments);
7875
- options = (typeof options !== 'function' && options) || {};
7630
+ function dropInstance(...args) {
7631
+ const callback = getCallback(...args);
7632
+ let options = (typeof args[0] !== 'function' && args[0]) || {};
7876
7633
  if (!options.name) {
7877
7634
  const currentConfig = this.config();
7878
7635
  options.name = options.name || currentConfig.name;
@@ -7900,7 +7657,7 @@
7900
7657
  }
7901
7658
  });
7902
7659
  }
7903
- executeCallback$1(promise, callback);
7660
+ chainCallback(promise, callback);
7904
7661
  return promise;
7905
7662
  }
7906
7663
  const sessionStorageWrapper = {
@@ -8379,10 +8136,10 @@
8379
8136
  extendPrototype(localForage);
8380
8137
 
8381
8138
  /** Used for built-in method references. */
8382
- var objectProto$6 = Object.prototype;
8139
+ var objectProto$7 = Object.prototype;
8383
8140
 
8384
8141
  /** Used to check objects for own properties. */
8385
- var hasOwnProperty$5 = objectProto$6.hasOwnProperty;
8142
+ var hasOwnProperty$6 = objectProto$7.hasOwnProperty;
8386
8143
 
8387
8144
  /**
8388
8145
  * The base implementation of `_.has` without support for deep paths.
@@ -8393,7 +8150,7 @@
8393
8150
  * @returns {boolean} Returns `true` if `key` exists, else `false`.
8394
8151
  */
8395
8152
  function baseHas(object, key) {
8396
- return object != null && hasOwnProperty$5.call(object, key);
8153
+ return object != null && hasOwnProperty$6.call(object, key);
8397
8154
  }
8398
8155
 
8399
8156
  /** Used to match property names within property paths. */
@@ -8550,7 +8307,7 @@
8550
8307
  if (isArray(value)) {
8551
8308
  return value;
8552
8309
  }
8553
- return isKey(value, object) ? [value] : stringToPath(toString$2(value));
8310
+ return isKey(value, object) ? [value] : stringToPath(toString$1(value));
8554
8311
  }
8555
8312
 
8556
8313
  /**
@@ -8704,16 +8461,18 @@
8704
8461
  wrapper.reject = reject;
8705
8462
  });
8706
8463
  Object.assign(promise, wrapper);
8707
- promise.then(function (v) {
8464
+ // This `then` only mirrors settlement into the state flags. It must NOT
8465
+ // rethrow on rejection: the derived promise is discarded, so rethrowing would
8466
+ // surface as an unhandled rejection whenever the promise is rejected. The real
8467
+ // consumer still awaits `promise` itself, which rejects normally.
8468
+ promise.then(function () {
8708
8469
  promise.isResolved = true;
8709
8470
  promise.isPending = false;
8710
8471
  promise.isRejected = false;
8711
- return v;
8712
- }, function (e) {
8472
+ }, function () {
8713
8473
  promise.isResolved = false;
8714
8474
  promise.isPending = false;
8715
8475
  promise.isRejected = true;
8716
- throw e;
8717
8476
  });
8718
8477
  return promise;
8719
8478
  }
@@ -8721,13 +8480,16 @@
8721
8480
  function urlError() {
8722
8481
  throw new Error('A "url" property or function must be specified');
8723
8482
  }
8724
- // Wrap an optional error callback with a fallback error event.
8725
- function wrapError(model, options) {
8483
+ // Wrap an optional error callback with a fallback error event. When a
8484
+ // `promise` is supplied (the `{ promise: true }` fetch/save path), the error is
8485
+ // also forwarded to `promise.reject` so the returned promise settles on failure.
8486
+ function wrapError(model, options, promise) {
8726
8487
  const error = options.error;
8727
8488
  options.error = function (resp) {
8728
8489
  if (error)
8729
8490
  error.call(options.context, model, resp, options);
8730
8491
  model.trigger('error', model, resp, options);
8492
+ promise && promise.reject && promise.reject(resp);
8731
8493
  };
8732
8494
  }
8733
8495
  // Map from CRUD to HTTP for our default `sync` implementation.
@@ -8738,8 +8500,44 @@
8738
8500
  delete: 'DELETE',
8739
8501
  read: 'GET',
8740
8502
  };
8503
+ // Tracks the classes we've already warned about, so the `browserStorage`
8504
+ // deprecation notice is logged at most once per class rather than once per
8505
+ // instance (a collection can resolve storage once per contained model).
8506
+ const warnedBrowserStorage = new WeakSet();
8507
+ /**
8508
+ * Emit a one-time-per-class deprecation warning nudging downstream code from
8509
+ * the `browserStorage` alias to the canonical `storage` accessor.
8510
+ */
8511
+ function warnBrowserStorageDeprecation(obj) {
8512
+ const ctor = obj?.constructor;
8513
+ if (!ctor || warnedBrowserStorage.has(ctor))
8514
+ return;
8515
+ warnedBrowserStorage.add(ctor);
8516
+ const name = ctor.name;
8517
+ console.warn(`Skeletor: \`browserStorage\` is deprecated and will be removed in a future major version; ` +
8518
+ `use \`storage\` instead${name ? ` (on \`${name}\`)` : ''}.`);
8519
+ }
8520
+ /**
8521
+ * Return the PersistentStorage instance configured on `obj`, checking both
8522
+ * the canonical `storage` accessor and the deprecated `browserStorage` alias
8523
+ * so that subclasses that still override `get browserStorage()` continue to work.
8524
+ * @public
8525
+ */
8526
+ function getStorage(obj) {
8527
+ if (!obj)
8528
+ return undefined;
8529
+ const storage = result(obj, 'storage');
8530
+ if (storage != null)
8531
+ return storage;
8532
+ // Fall back to the deprecated alias; warn only when it actually supplies the
8533
+ // store, so storage-less models/collections don't trip the notice.
8534
+ const legacy = result(obj, 'browserStorage');
8535
+ if (legacy != null)
8536
+ warnBrowserStorageDeprecation(obj);
8537
+ return legacy;
8538
+ }
8741
8539
  function getSyncMethod(model) {
8742
- const store = result(model, 'browserStorage') || result(model.collection, 'browserStorage');
8540
+ const store = getStorage(model) || getStorage(model.collection);
8743
8541
  return store ? store.sync() : sync;
8744
8542
  }
8745
8543
  /**
@@ -8789,15 +8587,56 @@
8789
8587
  localForage.defineDriver(memoryDriver);
8790
8588
  localforageSetitemsExports.extendPrototype(localForage);
8791
8589
  extendPrototype(localForage);
8590
+ // Every storage instance is registered with a WeakRef so that flushAll() can
8591
+ // reach pending writes without keeping instances alive. There's no leak and no
8592
+ // lifecycle hook to maintain: an instance is collected once its owning model or
8593
+ // collection is gone, at which point nothing is writing through it anyway.
8594
+ // Models with a pending debounced save stay reachable via the autosync `pending`
8595
+ // map until the timer fires, so flushAll() always reaches in-flight writes.
8596
+ const weakInstances = new Set();
8597
+ // Tracks which instances already have a WeakRef in `weakInstances`, so repeated
8598
+ // `storage =` assignments (or a store shared across models) don't register the
8599
+ // same instance twice and make flushAll() flush it more than once.
8600
+ const registered = new WeakSet();
8792
8601
  /**
8793
8602
  * @public
8794
8603
  */
8795
- class BrowserStorage {
8604
+ class PersistentStorage {
8605
+ /** Register a storage instance with a weak reference. @public */
8606
+ static register(instance) {
8607
+ if (registered.has(instance))
8608
+ return;
8609
+ registered.add(instance);
8610
+ weakInstances.add(new WeakRef(instance));
8611
+ }
8612
+ /**
8613
+ * Flush the debounced write buffer of every registered PersistentStorage
8614
+ * instance. Called automatically on pagehide/visibilitychange when autoSync
8615
+ * is in use; can also be called manually.
8616
+ * @public
8617
+ */
8618
+ static flushAll() {
8619
+ for (const ref of weakInstances) {
8620
+ const instance = ref.deref();
8621
+ if (!instance) {
8622
+ weakInstances.delete(ref);
8623
+ }
8624
+ else {
8625
+ instance.flush();
8626
+ }
8627
+ }
8628
+ }
8796
8629
  constructor(id, type, batchedWrites = false) {
8797
- if (type === 'local' && !window.localStorage) {
8630
+ // Set once `storeInitialized` resolves. Lets `sync()` skip awaiting it on the
8631
+ // hot path so a save buffers/issues its write *synchronously*, which is what
8632
+ // makes the synchronous unload flush (`flushPending` -> `flushAll`) able to
8633
+ // push a pending write out before the page is torn down.
8634
+ this.storeReady = false;
8635
+ this.name = id;
8636
+ if (type === 'local' && typeof window !== 'undefined' && !window.localStorage) {
8798
8637
  throw new Error('Skeletor.storage: Environment does not support localStorage.');
8799
8638
  }
8800
- else if (type === 'session' && !window.sessionStorage) {
8639
+ else if (type === 'session' && typeof window !== 'undefined' && !window.sessionStorage) {
8801
8640
  throw new Error('Skeletor.storage: Environment does not support sessionStorage.');
8802
8641
  }
8803
8642
  if (isString(type)) {
@@ -8812,10 +8651,13 @@
8812
8651
  }
8813
8652
  this.storeInitialized = Promise.resolve();
8814
8653
  }
8815
- this.name = id;
8654
+ // Flip the synchronous-readiness flag once init settles. Callers that await
8655
+ // `storeInitialized` directly still see any rejection; this branch only
8656
+ // exists to set the flag and must not raise an unhandled rejection.
8657
+ this.storeInitialized.then(() => (this.storeReady = true)).catch(() => { });
8816
8658
  }
8817
8659
  /**
8818
- * @param type - The storage type: 'local', 'session', 'indexed', or 'in_memory'
8660
+ * @param type - The storage type: 'local', 'session', 'indexed', 'node', or 'in_memory'
8819
8661
  * @param batchedWrites - Whether to enable batched writes
8820
8662
  */
8821
8663
  async initStore(type, batchedWrites) {
@@ -8828,6 +8670,20 @@
8828
8670
  else if (type === 'in_memory') {
8829
8671
  await localForage.config({ 'driver': IN_MEMORY });
8830
8672
  }
8673
+ else if (type === 'node') {
8674
+ const NodeSQLiteStorage = PersistentStorage.nodeStorage;
8675
+ if (!NodeSQLiteStorage) {
8676
+ throw new Error("Skeletor.storage: the 'node' storage type is only available in Node.js builds. " +
8677
+ "Import from '@converse/skeletor/node' instead of '@converse/skeletor'.");
8678
+ }
8679
+ this.store = new NodeSQLiteStorage(this.name);
8680
+ if (batchedWrites) {
8681
+ this.store.debouncedSetItems = mergebounce((items) => this.store.setItems(items), 50, {
8682
+ 'promise': true,
8683
+ });
8684
+ }
8685
+ return;
8686
+ }
8831
8687
  else if (type !== 'indexed') {
8832
8688
  throw new Error('Skeletor.storage: No storage type was specified');
8833
8689
  }
@@ -8844,6 +8700,7 @@
8844
8700
  }
8845
8701
  }
8846
8702
  async clear() {
8703
+ await this.storeInitialized;
8847
8704
  await this.store.removeItem(this.name).catch((e) => console.error(e));
8848
8705
  const re = new RegExp(`^${this.name}-`);
8849
8706
  const keys = await this.store.keys();
@@ -8858,12 +8715,16 @@
8858
8715
  // We get the collection (and if necessary the model attribute.
8859
8716
  // Waiting for storeInitialized will cause another iteration of
8860
8717
  // the event loop, after which the collection reference will
8861
- // be removed from the model.
8862
- const collection = model.collection;
8718
+ // be removed from the model. `options.collection` lets a deferred
8719
+ // delete (sequenced behind an in-flight auto-save by Model.destroy)
8720
+ // supply the collection captured before its optimistic removal.
8721
+ const collection = options.collection ?? model.collection;
8863
8722
  if (['patch', 'update'].includes(method)) {
8864
8723
  new_attributes = cloneDeep(model.attributes);
8865
8724
  }
8866
- await that.storeInitialized;
8725
+ // Skip `await` if not necessary to allow for sync flushing
8726
+ if (!that.storeReady)
8727
+ await that.storeInitialized;
8867
8728
  try {
8868
8729
  const original_attributes = model.attributes;
8869
8730
  switch (method) {
@@ -9018,8 +8879,12 @@
9018
8879
  return this.name + '-' + id;
9019
8880
  }
9020
8881
  }
9021
- BrowserStorage.sessionStorageInitialized = localForage.defineDriver(sessionStorageWrapper);
9022
- BrowserStorage.localForage = localForage;
8882
+ // The Node.js SQLite storage driver. Left null in browser builds so the
8883
+ // node-only driver (and its `node:sqlite` import) never enters the browser
8884
+ // bundle; the `@converse/skeletor/node` entry sets it.
8885
+ PersistentStorage.nodeStorage = null;
8886
+ PersistentStorage.sessionStorageInitialized = localForage.defineDriver(sessionStorageWrapper);
8887
+ PersistentStorage.localForage = localForage;
9023
8888
 
9024
8889
  /** Used to compose bitmasks for cloning. */
9025
8890
  var CLONE_SYMBOLS_FLAG$1 = 4;
@@ -9169,7 +9034,7 @@
9169
9034
  * @name has
9170
9035
  * @memberOf SetCache
9171
9036
  * @param {*} value The value to search for.
9172
- * @returns {number} Returns `true` if `value` is found, else `false`.
9037
+ * @returns {boolean} Returns `true` if `value` is found, else `false`.
9173
9038
  */
9174
9039
  function setCacheHas(value) {
9175
9040
  return this.__data__.has(value);
@@ -9452,10 +9317,10 @@
9452
9317
  var COMPARE_PARTIAL_FLAG$3 = 1;
9453
9318
 
9454
9319
  /** Used for built-in method references. */
9455
- var objectProto$5 = Object.prototype;
9320
+ var objectProto$6 = Object.prototype;
9456
9321
 
9457
9322
  /** Used to check objects for own properties. */
9458
- var hasOwnProperty$4 = objectProto$5.hasOwnProperty;
9323
+ var hasOwnProperty$5 = objectProto$6.hasOwnProperty;
9459
9324
 
9460
9325
  /**
9461
9326
  * A specialized version of `baseIsEqualDeep` for objects with support for
@@ -9483,7 +9348,7 @@
9483
9348
  var index = objLength;
9484
9349
  while (index--) {
9485
9350
  var key = objProps[index];
9486
- if (!(isPartial ? key in other : hasOwnProperty$4.call(other, key))) {
9351
+ if (!(isPartial ? key in other : hasOwnProperty$5.call(other, key))) {
9487
9352
  return false;
9488
9353
  }
9489
9354
  }
@@ -9544,10 +9409,10 @@
9544
9409
  objectTag = '[object Object]';
9545
9410
 
9546
9411
  /** Used for built-in method references. */
9547
- var objectProto$4 = Object.prototype;
9412
+ var objectProto$5 = Object.prototype;
9548
9413
 
9549
9414
  /** Used to check objects for own properties. */
9550
- var hasOwnProperty$3 = objectProto$4.hasOwnProperty;
9415
+ var hasOwnProperty$4 = objectProto$5.hasOwnProperty;
9551
9416
 
9552
9417
  /**
9553
9418
  * A specialized version of `baseIsEqual` for arrays and objects which performs
@@ -9590,8 +9455,8 @@
9590
9455
  : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
9591
9456
  }
9592
9457
  if (!(bitmask & COMPARE_PARTIAL_FLAG$2)) {
9593
- var objIsWrapped = objIsObj && hasOwnProperty$3.call(object, '__wrapped__'),
9594
- othIsWrapped = othIsObj && hasOwnProperty$3.call(other, '__wrapped__');
9458
+ var objIsWrapped = objIsObj && hasOwnProperty$4.call(object, '__wrapped__'),
9459
+ othIsWrapped = othIsObj && hasOwnProperty$4.call(other, '__wrapped__');
9595
9460
 
9596
9461
  if (objIsWrapped || othIsWrapped) {
9597
9462
  var objUnwrapped = objIsWrapped ? object.value() : object,
@@ -9965,10 +9830,10 @@
9965
9830
  }
9966
9831
 
9967
9832
  /** Used for built-in method references. */
9968
- var objectProto$3 = Object.prototype;
9833
+ var objectProto$4 = Object.prototype;
9969
9834
 
9970
9835
  /** Used to check objects for own properties. */
9971
- var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
9836
+ var hasOwnProperty$3 = objectProto$4.hasOwnProperty;
9972
9837
 
9973
9838
  /**
9974
9839
  * Creates an object composed of keys generated from the results of running
@@ -9993,7 +9858,7 @@
9993
9858
  * // => { '3': 2, '5': 1 }
9994
9859
  */
9995
9860
  var countBy = createAggregator(function(result, value, key) {
9996
- if (hasOwnProperty$2.call(result, key)) {
9861
+ if (hasOwnProperty$3.call(result, key)) {
9997
9862
  ++result[key];
9998
9863
  } else {
9999
9864
  baseAssignValue(result, key, 1);
@@ -10001,10 +9866,10 @@
10001
9866
  });
10002
9867
 
10003
9868
  /** Used for built-in method references. */
10004
- var objectProto$2 = Object.prototype;
9869
+ var objectProto$3 = Object.prototype;
10005
9870
 
10006
9871
  /** Used to check objects for own properties. */
10007
- var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
9872
+ var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
10008
9873
 
10009
9874
  /**
10010
9875
  * Creates an object composed of keys generated from the results of running
@@ -10030,7 +9895,7 @@
10030
9895
  * // => { '3': ['one', 'two'], '5': ['three'] }
10031
9896
  */
10032
9897
  var groupBy = createAggregator(function(result, value, key) {
10033
- if (hasOwnProperty$1.call(result, key)) {
9898
+ if (hasOwnProperty$2.call(result, key)) {
10034
9899
  result[key].push(value);
10035
9900
  } else {
10036
9901
  baseAssignValue(result, key, [value]);
@@ -10247,7 +10112,7 @@
10247
10112
  if (isArray(iteratee)) {
10248
10113
  return function(value) {
10249
10114
  return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
10250
- }
10115
+ };
10251
10116
  }
10252
10117
  return iteratee;
10253
10118
  });
@@ -10312,11 +10177,130 @@
10312
10177
  return baseOrderBy(collection, baseFlatten(iteratees), []);
10313
10178
  });
10314
10179
 
10180
+ const pending = new Map();
10181
+ const inFlight = new Set();
10182
+ // Per-object view of `inFlight`, so a caller (notably `Model.destroy`) can
10183
+ // await the saves for a single object without blocking on unrelated writes.
10184
+ const inFlightByObj = new Map();
10185
+ let unloadListenerAttached = false;
10186
+ /**
10187
+ * Execute a save `run` now and track the resulting promise as in-flight until
10188
+ * it settles, both globally (`inFlight`) and per object (`inFlightByObj`), so
10189
+ * `flushPending({ wait: true })` can await every save and `Model.destroy` can
10190
+ * await just its own.
10191
+ *
10192
+ * @internal
10193
+ * @param obj - The owning model/collection (or `null` when the save isn't tied to one).
10194
+ * A rejection is logged and re-surfaced on `obj`'s `error` event.
10195
+ * Called when a debounce timer fires or a flush forces it.
10196
+ */
10197
+ function fireRun(obj, run) {
10198
+ const p = Promise.resolve(run()).catch((e) => {
10199
+ console.error('Skeletor autoSync save error:', e);
10200
+ // Surface failures that bypassed `options.error` on the model's `error` event,
10201
+ // the same channel storage-layer failures already use. Storage saves route
10202
+ // errors through `options.error` and then resolve, so they never reach this
10203
+ // catch and won't double-emit.
10204
+ obj?.trigger?.('error', obj, e);
10205
+ });
10206
+ inFlight.add(p);
10207
+ let perObj;
10208
+ if (obj) {
10209
+ perObj = inFlightByObj.get(obj);
10210
+ if (!perObj) {
10211
+ perObj = new Set();
10212
+ inFlightByObj.set(obj, perObj);
10213
+ }
10214
+ perObj.add(p);
10215
+ }
10216
+ p.finally(() => {
10217
+ inFlight.delete(p);
10218
+ if (perObj) {
10219
+ perObj.delete(p);
10220
+ if (perObj.size === 0)
10221
+ inFlightByObj.delete(obj);
10222
+ }
10223
+ });
10224
+ }
10225
+ /**
10226
+ * Schedule a debounced auto-save for `obj`. Replaces any pending schedule
10227
+ * for the same object.
10228
+ * @internal
10229
+ */
10230
+ function scheduleAutoSave(obj, run, delay) {
10231
+ const existing = pending.get(obj);
10232
+ if (existing)
10233
+ clearTimeout(existing.timerId);
10234
+ const timerId = setTimeout(() => {
10235
+ pending.delete(obj);
10236
+ fireRun(obj, run);
10237
+ }, delay);
10238
+ pending.set(obj, { timerId, run });
10239
+ }
10240
+ /**
10241
+ * Cancel any pending auto-save for `obj`.
10242
+ *
10243
+ * This only stops a *pending* (not-yet-fired) debounce timer. A save whose
10244
+ * timer has already fired is in flight and beyond cancellation — sequence
10245
+ * against it with {@link awaitInFlightSaves} instead.
10246
+ * @internal
10247
+ */
10248
+ function cancelAutoSave(obj) {
10249
+ const existing = pending.get(obj);
10250
+ if (existing) {
10251
+ clearTimeout(existing.timerId);
10252
+ pending.delete(obj);
10253
+ }
10254
+ }
10255
+ /**
10256
+ * Return a promise that settles once every in-flight auto-save for `obj` has
10257
+ * completed, or `null` when none are in flight. `Model.destroy` uses this to
10258
+ * sequence its delete after a save that has already fired, so a late write
10259
+ * cannot land after the delete and resurrect the record.
10260
+ * @internal
10261
+ */
10262
+ function awaitInFlightSaves(obj) {
10263
+ const set = inFlightByObj.get(obj);
10264
+ if (!set || set.size === 0)
10265
+ return null;
10266
+ return Promise.all([...set]).then(() => undefined);
10267
+ }
10268
+ function flushPending({ storage, wait = false, } = {}) {
10269
+ for (const [obj, { timerId, run }] of pending.entries()) {
10270
+ clearTimeout(timerId);
10271
+ fireRun(obj, run);
10272
+ }
10273
+ pending.clear();
10274
+ if (storage)
10275
+ storage.flushAll();
10276
+ if (wait)
10277
+ return Promise.all([...inFlight]).then(() => undefined);
10278
+ }
10279
+ /**
10280
+ * Lazily attach pagehide/visibilitychange listeners in browser environments
10281
+ * to flush pending writes when the page is hidden/unloading. This is a
10282
+ * best-effort durability measure: the flush initiates writes synchronously but
10283
+ * cannot guarantee an asynchronous backend finishes persisting them before the
10284
+ * page goes away. Called at most once.
10285
+ * @internal
10286
+ */
10287
+ function ensureUnloadListener(storage) {
10288
+ if (unloadListenerAttached || typeof window === 'undefined')
10289
+ return;
10290
+ unloadListenerAttached = true;
10291
+ const flush = () => flushPending({ storage });
10292
+ window.addEventListener('pagehide', flush);
10293
+ window.addEventListener('visibilitychange', () => {
10294
+ if (document.visibilityState === 'hidden')
10295
+ flush();
10296
+ });
10297
+ }
10298
+
10315
10299
  /** Used for built-in method references. */
10316
- var objectProto$1 = Object.prototype;
10300
+ var objectProto$2 = Object.prototype;
10317
10301
 
10318
10302
  /** Used to check objects for own properties. */
10319
- var hasOwnProperty = objectProto$1.hasOwnProperty;
10303
+ var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
10320
10304
 
10321
10305
  /**
10322
10306
  * Assigns own and inherited enumerable string keyed properties of source
@@ -10361,7 +10345,7 @@
10361
10345
  var value = object[key];
10362
10346
 
10363
10347
  if (value === undefined ||
10364
- (eq(value, objectProto$1[key]) && !hasOwnProperty.call(object, key))) {
10348
+ (eq(value, objectProto$2[key]) && !hasOwnProperty$1.call(object, key))) {
10365
10349
  object[key] = source[key];
10366
10350
  }
10367
10351
  }
@@ -10445,14 +10429,14 @@
10445
10429
  }
10446
10430
 
10447
10431
  /** Used for built-in method references. */
10448
- var objectProto = Object.prototype;
10432
+ var objectProto$1 = Object.prototype;
10449
10433
 
10450
10434
  /**
10451
10435
  * Used to resolve the
10452
10436
  * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
10453
10437
  * of values.
10454
10438
  */
10455
- var nativeObjectToString = objectProto.toString;
10439
+ var nativeObjectToString = objectProto$1.toString;
10456
10440
 
10457
10441
  /**
10458
10442
  * Creates an object composed of the inverted keys and values of `object`.
@@ -10623,6 +10607,12 @@
10623
10607
  return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
10624
10608
  }
10625
10609
 
10610
+ /** Used for built-in method references. */
10611
+ var objectProto = Object.prototype;
10612
+
10613
+ /** Used to check objects for own properties. */
10614
+ var hasOwnProperty = objectProto.hasOwnProperty;
10615
+
10626
10616
  /**
10627
10617
  * The base implementation of `_.unset`.
10628
10618
  *
@@ -10633,8 +10623,34 @@
10633
10623
  */
10634
10624
  function baseUnset(object, path) {
10635
10625
  path = castPath(path, object);
10636
- object = parent(object, path);
10637
- return object == null || delete object[toKey(last(path))];
10626
+
10627
+ // Prevent prototype pollution:
10628
+ // https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
10629
+ // https://github.com/lodash/lodash/security/advisories/GHSA-f23m-r3pf-42rh
10630
+ var index = -1,
10631
+ length = path.length;
10632
+
10633
+ if (!length) {
10634
+ return true;
10635
+ }
10636
+
10637
+ while (++index < length) {
10638
+ var key = toKey(path[index]);
10639
+
10640
+ // Always block "__proto__" anywhere in the path if it's not expected
10641
+ if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
10642
+ return false;
10643
+ }
10644
+
10645
+ // Block constructor/prototype as non-terminal traversal keys to prevent
10646
+ // escaping the object graph into built-in constructors and prototypes.
10647
+ if ((key === 'constructor' || key === 'prototype') && index < length - 1) {
10648
+ return false;
10649
+ }
10650
+ }
10651
+
10652
+ var obj = parent(object, path);
10653
+ return obj == null || delete obj[toKey(last(path))];
10638
10654
  }
10639
10655
 
10640
10656
  /**
@@ -10832,6 +10848,7 @@
10832
10848
  return object == null ? {} : basePick(object, paths);
10833
10849
  });
10834
10850
 
10851
+ var _Model_instances, _Model_computedCache, _Model_computedDefs, _Model_state, _Model_hydrate, _Model_doAutoSave, _Model_updateComputed, _Model_initComputed;
10835
10852
  /**
10836
10853
  * @public
10837
10854
  * **Models** are the basic data object in the framework --
@@ -10846,6 +10863,10 @@
10846
10863
  */
10847
10864
  constructor(attributes, options) {
10848
10865
  super();
10866
+ _Model_instances.add(this);
10867
+ _Model_computedCache.set(this, void 0);
10868
+ _Model_computedDefs.set(this, void 0);
10869
+ _Model_state.set(this, 'constructing');
10849
10870
  this._changing = false;
10850
10871
  this._pending = false;
10851
10872
  this._url = '';
@@ -10863,15 +10884,74 @@
10863
10884
  const default_attrs = result(this, 'defaults');
10864
10885
  attrs = defaults(Object.assign({}, default_attrs, attrs), default_attrs);
10865
10886
  this.set(attrs, options);
10887
+ __classPrivateFieldGet(this, _Model_instances, "m", _Model_initComputed).call(this);
10888
+ this.attrs = new Proxy(this.attributes, {
10889
+ get: (_target, key) => {
10890
+ if (typeof key !== 'symbol' && __classPrivateFieldGet(this, _Model_computedCache, "f") && key in __classPrivateFieldGet(this, _Model_computedCache, "f")) {
10891
+ return __classPrivateFieldGet(this, _Model_computedCache, "f")[key];
10892
+ }
10893
+ return this.attributes[key];
10894
+ },
10895
+ set: (_target, key, value) => {
10896
+ this.set(key, value);
10897
+ return true;
10898
+ },
10899
+ });
10866
10900
  this.initialize.apply(this, arguments);
10867
10901
  // Reset changed after initial set
10868
10902
  this.changed = {};
10903
+ // When autoSync is on, `initialized` is always a Promise so callers can
10904
+ // uniformly `await model.initialized`. It only hydrates from storage when
10905
+ // there's something to load (storage configured and the model isn't new);
10906
+ // otherwise it's already ready and resolves immediately.
10907
+ if (this.autoSync) {
10908
+ if (getStorage(this) && !this.isNew()) {
10909
+ __classPrivateFieldSet(this, _Model_state, 'hydrating', "f");
10910
+ this.initialized = __classPrivateFieldGet(this, _Model_instances, "m", _Model_hydrate).call(this);
10911
+ }
10912
+ else {
10913
+ __classPrivateFieldSet(this, _Model_state, 'ready', "f");
10914
+ this.initialized = Promise.resolve();
10915
+ }
10916
+ }
10917
+ else {
10918
+ __classPrivateFieldSet(this, _Model_state, 'ready', "f");
10919
+ }
10920
+ }
10921
+ /**
10922
+ * The canonical storage accessor. Set to a `PersistentStorage` instance
10923
+ * to enable local persistence for this model.
10924
+ */
10925
+ get storage() {
10926
+ return this._storage;
10869
10927
  }
10870
- set browserStorage(storage) {
10871
- this._browserStorage = storage;
10928
+ set storage(s) {
10929
+ this._storage = s;
10930
+ PersistentStorage.register(s);
10872
10931
  }
10932
+ /**
10933
+ * @deprecated Use `storage` instead.
10934
+ */
10873
10935
  get browserStorage() {
10874
- return this._browserStorage;
10936
+ return this._storage;
10937
+ }
10938
+ set browserStorage(s) {
10939
+ warnBrowserStorageDeprecation(this);
10940
+ this.storage = s;
10941
+ }
10942
+ /**
10943
+ * Override to enable automatic persistence. When true, any `set()` call
10944
+ * that changes attributes will schedule a debounced save to `storage`, and
10945
+ * the model will auto-hydrate from storage on construction.
10946
+ */
10947
+ get autoSync() {
10948
+ return false;
10949
+ }
10950
+ /**
10951
+ * Debounce delay (ms) for auto-save writes. Override to tune.
10952
+ */
10953
+ get autoSyncDelay() {
10954
+ return 100;
10875
10955
  }
10876
10956
  /**
10877
10957
  * The default name for the JSON `id` attribute is `"id"`. MongoDB and
@@ -10907,6 +10987,17 @@
10907
10987
  defaults() {
10908
10988
  return {};
10909
10989
  }
10990
+ /**
10991
+ * Declare computed properties. Override in subclasses to define properties
10992
+ * that derive their value from other attributes. Each entry specifies the
10993
+ * attribute keys it depends on (`deps`) and a function (`fn`) that receives
10994
+ * the model and returns the computed value. The value is cached and
10995
+ * recalculated automatically when any dep changes, firing a `change:key`
10996
+ * event.
10997
+ */
10998
+ get computed() {
10999
+ return {};
11000
+ }
10910
11001
  /**
10911
11002
  * Return a copy of the model's `attributes` object.
10912
11003
  */
@@ -10920,9 +11011,12 @@
10920
11011
  return getSyncMethod(model)(method, model, options);
10921
11012
  }
10922
11013
  /**
10923
- * Get the value of an attribute.
11014
+ * Get the value of an attribute, or a computed property.
10924
11015
  */
10925
11016
  get(attr) {
11017
+ if (__classPrivateFieldGet(this, _Model_computedCache, "f") && attr in __classPrivateFieldGet(this, _Model_computedCache, "f")) {
11018
+ return __classPrivateFieldGet(this, _Model_computedCache, "f")[attr];
11019
+ }
10926
11020
  return this.attributes[attr];
10927
11021
  }
10928
11022
  keys() {
@@ -10987,6 +11081,11 @@
10987
11081
  attrs[key] = val;
10988
11082
  }
10989
11083
  options = options || {};
11084
+ // Guard must come after arg normalization: when called as set(obj, opts),
11085
+ // fromStorage lives in `val` (second arg), not `options` (third arg).
11086
+ if (this.autoSync && __classPrivateFieldGet(this, _Model_state, "f") === 'hydrating' && !options.fromStorage) {
11087
+ throw new Error(`Skeletor: set() called on an autoSync model before initialized resolved. Await model.initialized first.`);
11088
+ }
10990
11089
  // Run validation.
10991
11090
  if (!this._validate(attrs, options))
10992
11091
  return null;
@@ -11027,6 +11126,14 @@
11027
11126
  this.trigger('change:' + changes[i], this, current[changes[i]], options);
11028
11127
  }
11029
11128
  }
11129
+ // Recalculate computed properties whose deps changed.
11130
+ if (changes.length && __classPrivateFieldGet(this, _Model_computedDefs, "f")) {
11131
+ for (const [key, def] of Object.entries(__classPrivateFieldGet(this, _Model_computedDefs, "f"))) {
11132
+ if (def.deps.some((dep) => changes.includes(dep))) {
11133
+ __classPrivateFieldGet(this, _Model_instances, "m", _Model_updateComputed).call(this, key, def, silent, options);
11134
+ }
11135
+ }
11136
+ }
11030
11137
  if (changing)
11031
11138
  return this;
11032
11139
  if (!silent) {
@@ -11040,6 +11147,17 @@
11040
11147
  }
11041
11148
  this._pending = false;
11042
11149
  this._changing = false;
11150
+ // Auto-save: schedule a debounced write when autoSync is on and there
11151
+ // were actual changes that originated from application code (not a
11152
+ // storage read or an explicit noAutoSave call).
11153
+ if (__classPrivateFieldGet(this, _Model_state, "f") === 'ready' &&
11154
+ this.autoSync &&
11155
+ getStorage(this) &&
11156
+ changes.length &&
11157
+ !options.fromStorage &&
11158
+ !options.noAutoSave) {
11159
+ scheduleAutoSave(this, () => __classPrivateFieldGet(this, _Model_instances, "m", _Model_doAutoSave).call(this), this.autoSyncDelay);
11160
+ }
11043
11161
  return this;
11044
11162
  }
11045
11163
  /**
@@ -11114,16 +11232,48 @@
11114
11232
  fetch(options = {}) {
11115
11233
  options = Object.assign({ parse: true }, options);
11116
11234
  const success = options.success;
11235
+ const promise = options.promise ? getResolveablePromise() : undefined;
11236
+ // Tracks whether sync invoked one of the callbacks. A sync may instead
11237
+ // settle its returned promise; the `.then`/`.catch` below bridges that to
11238
+ // the callbacks so the fetch promise never hangs. The flag is set
11239
+ // synchronously inside each callback (before sync's promise resolves), so
11240
+ // it's reliable by the time those handlers run.
11241
+ let settled = false;
11117
11242
  options.success = (resp) => {
11243
+ settled = true;
11118
11244
  const serverAttrs = options.parse ? this.parse(resp, options) : resp;
11119
- if (!this.set(serverAttrs, options))
11245
+ // fromStorage prevents the set() from triggering auto-save on reads
11246
+ if (!this.set(serverAttrs, Object.assign({}, options, { fromStorage: true })))
11120
11247
  return false;
11121
11248
  if (success)
11122
11249
  success.call(options.context, this, resp, options);
11123
11250
  this.trigger('sync', this, resp, options);
11251
+ promise && promise.resolve(resp);
11124
11252
  };
11125
- wrapError(this, options);
11126
- return this.sync('read', this, options);
11253
+ wrapError(this, options, promise);
11254
+ if (promise) {
11255
+ const onError = options.error;
11256
+ options.error = (resp) => {
11257
+ settled = true;
11258
+ onError(resp);
11259
+ };
11260
+ }
11261
+ const result = this.sync('read', this, options);
11262
+ if (promise) {
11263
+ Promise.resolve(result).then(
11264
+ // A sync that resolves its promise without invoking options.success:
11265
+ // treat the resolved value as the response, so the model is still
11266
+ // merged and the promise settles instead of hanging.
11267
+ (value) => {
11268
+ if (!settled)
11269
+ options.success(value);
11270
+ },
11271
+ // A sync that rejects instead of invoking options.error; settling
11272
+ // twice is a harmless no-op.
11273
+ (e) => promise.reject(e));
11274
+ return promise;
11275
+ }
11276
+ return result;
11127
11277
  }
11128
11278
  /**
11129
11279
  * Set a hash of model attributes, and sync the model to the server.
@@ -11200,6 +11350,7 @@
11200
11350
  * If `wait: true` is passed, waits for the server to respond before removal.
11201
11351
  */
11202
11352
  destroy(options) {
11353
+ cancelAutoSave(this);
11203
11354
  options = options ? clone(options) : {};
11204
11355
  const success = options.success;
11205
11356
  const wait = options.wait;
@@ -11215,13 +11366,25 @@
11215
11366
  if (!this.isNew())
11216
11367
  this.trigger('sync', this, resp, options);
11217
11368
  };
11369
+ // A debounced auto-save may already have fired and be in flight.
11370
+ // cancelAutoSave() above only stops a *pending* timer, so sequence the
11371
+ // delete after any in-flight save; otherwise the late write could land
11372
+ // after the delete and resurrect the record. Capture the collection now,
11373
+ // the optimistic in-memory removal below nulls `model.collection` before
11374
+ // the deferred sync runs, but the storage layer still needs it to drop
11375
+ // this id from the collection's persisted index.
11376
+ const inFlightSave = awaitInFlightSaves(this);
11377
+ if (inFlightSave && this.collection)
11378
+ options.collection = this.collection;
11218
11379
  let xhr = false;
11219
11380
  if (this.isNew()) {
11220
11381
  defer(options.success);
11221
11382
  }
11222
11383
  else {
11223
11384
  wrapError(this, options);
11224
- xhr = this.sync('delete', this, options);
11385
+ xhr = inFlightSave
11386
+ ? inFlightSave.then(() => this.sync('delete', this, options))
11387
+ : this.sync('delete', this, options);
11225
11388
  }
11226
11389
  if (!wait)
11227
11390
  destroy();
@@ -11269,6 +11432,14 @@
11269
11432
  isValid(options) {
11270
11433
  return this._validate({}, Object.assign({}, options, { validate: true }));
11271
11434
  }
11435
+ subscribe(eventOrCallback, callback, context) {
11436
+ if (typeof eventOrCallback === 'function') {
11437
+ const cb = (model) => eventOrCallback(model, this.changed);
11438
+ this.on('change', cb);
11439
+ return () => this.off('change', cb);
11440
+ }
11441
+ return super.subscribe(eventOrCallback, callback, context);
11442
+ }
11272
11443
  /**
11273
11444
  * Run validation against the next complete set of model attributes,
11274
11445
  * returning `true` if all is well. Otherwise, fire an `"invalid"` event.
@@ -11284,8 +11455,43 @@
11284
11455
  return false;
11285
11456
  }
11286
11457
  }
11458
+ _Model_computedCache = new WeakMap(), _Model_computedDefs = new WeakMap(), _Model_state = new WeakMap(), _Model_instances = new WeakSet(), _Model_hydrate = async function _Model_hydrate() {
11459
+ ensureUnloadListener(PersistentStorage);
11460
+ try {
11461
+ await this.fetch({ fromStorage: true, promise: true });
11462
+ }
11463
+ catch (e) {
11464
+ // 'Record Not Found' is a normal first-run state (nothing stored yet);
11465
+ // keep the initial attributes and resolve. Re-throw anything else.
11466
+ if (e !== 'Record Not Found')
11467
+ throw e;
11468
+ }
11469
+ finally {
11470
+ __classPrivateFieldSet(this, _Model_state, 'ready', "f");
11471
+ }
11472
+ }, _Model_doAutoSave = function _Model_doAutoSave() {
11473
+ return this.save(null, { noAutoSave: true });
11474
+ }, _Model_updateComputed = function _Model_updateComputed(key, def, silent, options) {
11475
+ const newVal = def.fn(this);
11476
+ if (!isEqual(__classPrivateFieldGet(this, _Model_computedCache, "f")[key], newVal)) {
11477
+ __classPrivateFieldGet(this, _Model_computedCache, "f")[key] = newVal;
11478
+ if (!silent) {
11479
+ this.changed[key] = newVal;
11480
+ this.trigger('change:' + key, this, newVal, options);
11481
+ }
11482
+ }
11483
+ }, _Model_initComputed = function _Model_initComputed() {
11484
+ const defs = result(this, 'computed');
11485
+ if (!defs || isEmpty(defs))
11486
+ return;
11487
+ __classPrivateFieldSet(this, _Model_computedDefs, defs, "f");
11488
+ __classPrivateFieldSet(this, _Model_computedCache, {}, "f");
11489
+ for (const [key, def] of Object.entries(defs)) {
11490
+ __classPrivateFieldGet(this, _Model_computedCache, "f")[key] = def.fn(this);
11491
+ }
11492
+ };
11287
11493
 
11288
- var _a;
11494
+ var _Collection_instances, _Collection_hydrate, _a;
11289
11495
  // Default options for `Collection#set`.
11290
11496
  const setOptions = { add: true, remove: true, merge: true };
11291
11497
  const addOptions = { add: true, remove: false };
@@ -11306,6 +11512,7 @@
11306
11512
  */
11307
11513
  constructor(models, options) {
11308
11514
  super();
11515
+ _Collection_instances.add(this);
11309
11516
  this._url = '';
11310
11517
  /**
11311
11518
  * @public
@@ -11323,6 +11530,12 @@
11323
11530
  if (models)
11324
11531
  this.reset(models, Object.assign({ silent: true }, options));
11325
11532
  this[Symbol.iterator] = this.values;
11533
+ // When autoSync is on, `initialized` is always a Promise so callers can
11534
+ // uniformly `await collection.initialized`; it resolves immediately when
11535
+ // there's no storage to hydrate from.
11536
+ if (this.autoSync) {
11537
+ this.initialized = getStorage(this) ? __classPrivateFieldGet(this, _Collection_instances, "m", _Collection_hydrate).call(this) : Promise.resolve();
11538
+ }
11326
11539
  }
11327
11540
  get comparator() {
11328
11541
  return this._comparator;
@@ -11330,11 +11543,40 @@
11330
11543
  set comparator(c) {
11331
11544
  this._comparator = c;
11332
11545
  }
11333
- set browserStorage(storage) {
11334
- this._browserStorage = storage;
11546
+ /**
11547
+ * The canonical storage accessor. Set to a `PersistentStorage` instance
11548
+ * to enable local persistence for this collection.
11549
+ */
11550
+ get storage() {
11551
+ return this._storage;
11552
+ }
11553
+ set storage(s) {
11554
+ this._storage = s;
11555
+ PersistentStorage.register(s);
11335
11556
  }
11557
+ /**
11558
+ * @deprecated Use `storage` instead.
11559
+ */
11336
11560
  get browserStorage() {
11337
- return this._browserStorage;
11561
+ return this._storage;
11562
+ }
11563
+ set browserStorage(s) {
11564
+ warnBrowserStorageDeprecation(this);
11565
+ this.storage = s;
11566
+ }
11567
+ /**
11568
+ * Override to return `true` to automatically load the collection from
11569
+ * storage on construction. Await `initialized` to know when hydration
11570
+ * is complete.
11571
+ *
11572
+ * Note: collection `autoSync` is hydrate-only. Unlike `Model`, it does
11573
+ * **not** schedule auto-saves when the collection changes (`add`/`remove`/
11574
+ * `reset`). Persisting members is each model's responsibility — enable
11575
+ * `autoSync` on the contained model class and every model writes its own
11576
+ * record. A collection-level write would be redundant with that.
11577
+ */
11578
+ get autoSync() {
11579
+ return false;
11338
11580
  }
11339
11581
  /**
11340
11582
  * The default model for a collection is just a **Model**.
@@ -11529,7 +11771,7 @@
11529
11771
  }));
11530
11772
  });
11531
11773
  }));
11532
- await this.browserStorage?.clear();
11774
+ await getStorage(this)?.clear();
11533
11775
  this.reset();
11534
11776
  }
11535
11777
  /**
@@ -11767,17 +12009,47 @@
11767
12009
  const success = options.success;
11768
12010
  // eslint-disable-next-line @typescript-eslint/no-this-alias
11769
12011
  const collection = this;
11770
- const promise = options.promise && getResolveablePromise();
12012
+ const promise = options.promise ? getResolveablePromise() : undefined;
12013
+ // Tracks whether sync invoked one of the callbacks. A sync may instead
12014
+ // settle its returned promise; the `.then`/`.catch` below bridges that to
12015
+ // the callbacks so the fetch promise never hangs. The flag is set
12016
+ // synchronously inside each callback (before sync's promise resolves), so
12017
+ // it's reliable by the time those handlers run.
12018
+ let settled = false;
11771
12019
  options.success = function (resp) {
12020
+ settled = true;
11772
12021
  const method = options.reset ? 'reset' : 'set';
11773
- collection[method](resp, options);
12022
+ // fromStorage prevents individual model set() calls from triggering auto-save on reads
12023
+ collection[method](resp, Object.assign({}, options, { fromStorage: true }));
11774
12024
  if (success)
11775
12025
  success.call(options.context, collection, resp, options);
11776
12026
  promise && promise.resolve();
11777
12027
  collection.trigger('sync', collection, resp, options);
11778
12028
  };
11779
- wrapError(this, options);
11780
- return promise ? promise : this.sync('read', this, options);
12029
+ wrapError(this, options, promise);
12030
+ if (promise) {
12031
+ const onError = options.error;
12032
+ options.error = (resp) => {
12033
+ settled = true;
12034
+ onError(resp);
12035
+ };
12036
+ }
12037
+ const result = this.sync('read', this, options);
12038
+ if (promise) {
12039
+ Promise.resolve(result).then(
12040
+ // A sync that resolves its promise without invoking options.success:
12041
+ // treat the resolved value as the response, so the collection is still
12042
+ // populated and the promise settles instead of hanging.
12043
+ (value) => {
12044
+ if (!settled)
12045
+ options.success(value);
12046
+ },
12047
+ // A sync that rejects instead of invoking options.error; settling
12048
+ // twice is a harmless no-op.
12049
+ (e) => promise.reject(e));
12050
+ return promise;
12051
+ }
12052
+ return result;
11781
12053
  }
11782
12054
  /**
11783
12055
  * Create a new instance of a model in this collection. Add the model to the
@@ -11821,6 +12093,14 @@
11821
12093
  return preparedModel;
11822
12094
  }
11823
12095
  }
12096
+ subscribe(eventOrCallback, callback, context) {
12097
+ if (typeof eventOrCallback === 'function') {
12098
+ const cb = () => eventOrCallback(this);
12099
+ this.on('update reset sort', cb);
12100
+ return () => this.off('update reset sort', cb);
12101
+ }
12102
+ return super.subscribe(eventOrCallback, callback, context);
12103
+ }
11824
12104
  /**
11825
12105
  * **parse** converts a response into a list of models to be added to the
11826
12106
  * collection. The default implementation is just to pass it through.
@@ -11958,7 +12238,12 @@
11958
12238
  this.trigger.apply(this, arguments);
11959
12239
  }
11960
12240
  }
11961
- _a = Symbol.iterator;
12241
+ _Collection_instances = new WeakSet(), _Collection_hydrate = async function _Collection_hydrate() {
12242
+ ensureUnloadListener(PersistentStorage);
12243
+ // findAll() returns [] for an empty store, so a first-run collection
12244
+ // resolves rather than erroring the way a model fetch-by-id would.
12245
+ await this.fetch({ fromStorage: true, promise: true });
12246
+ }, _a = Symbol.iterator;
11962
12247
  // This "enum" defines the three possible kinds of values which can be emitted
11963
12248
  // by a CollectionIterator that correspond to the values(), keys() and entries()
11964
12249
  // methods on Collection, respectively.
@@ -12047,12 +12332,19 @@
12047
12332
  }
12048
12333
  skeletor.noConflict = noConflict;
12049
12334
  root.Skeletor = skeletor;
12335
+ /**
12336
+ * @deprecated Use `PersistentStorage` instead.
12337
+ * @public
12338
+ */
12339
+ const BrowserStorage = PersistentStorage;
12050
12340
 
12051
12341
  exports.BrowserStorage = BrowserStorage;
12052
12342
  exports.Collection = Collection;
12053
12343
  exports.EventEmitter = EventEmitter;
12054
12344
  exports.Model = Model;
12345
+ exports.PersistentStorage = PersistentStorage;
12055
12346
  exports.default = skeletor;
12347
+ exports.getStorage = getStorage;
12056
12348
  exports.noConflict = noConflict;
12057
12349
  exports.sync = sync;
12058
12350