@converse/skeletor 3.0.1 → 3.1.0
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/README.md +330 -38
- package/dist/skeletor.d.ts +193 -56
- package/dist/skeletor.esm.js +739 -457
- package/dist/skeletor.esm.js.map +1 -1
- package/dist/skeletor.js +740 -456
- package/dist/skeletor.js.map +1 -1
- package/dist/skeletor.min.js +6 -19
- package/dist/skeletor.node.js +12494 -0
- package/dist/skeletor.node.mjs +12481 -0
- package/package.json +24 -7
- package/src/autosync.ts +156 -0
- package/src/collection.ts +140 -35
- package/src/drivers/helpers.ts +61 -0
- package/src/drivers/nodeSQLiteStorage.ts +162 -0
- package/src/drivers/sessionStorage.ts +16 -22
- package/src/drivers/types.ts +25 -0
- package/src/eventemitter.ts +9 -0
- package/src/helpers.ts +57 -10
- package/src/index.node.ts +8 -0
- package/src/index.ts +11 -3
- package/src/model.ts +254 -13
- package/src/storage.ts +78 -38
- package/src/types.ts +34 -9
- package/src/utils/events.ts +6 -6
package/dist/skeletor.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Used for built-in method references. */
|
|
2
|
-
var objectProto$
|
|
2
|
+
var objectProto$m = Object.prototype;
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Checks if `value` is likely a prototype object.
|
|
@@ -10,7 +10,7 @@ var objectProto$l = Object.prototype;
|
|
|
10
10
|
*/
|
|
11
11
|
function isPrototype(value) {
|
|
12
12
|
var Ctor = value && value.constructor,
|
|
13
|
-
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$
|
|
13
|
+
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$m;
|
|
14
14
|
|
|
15
15
|
return value === proto;
|
|
16
16
|
}
|
|
@@ -33,10 +33,10 @@ function overArg(func, transform) {
|
|
|
33
33
|
var nativeKeys = overArg(Object.keys, Object);
|
|
34
34
|
|
|
35
35
|
/** Used for built-in method references. */
|
|
36
|
-
var objectProto$
|
|
36
|
+
var objectProto$l = Object.prototype;
|
|
37
37
|
|
|
38
38
|
/** Used to check objects for own properties. */
|
|
39
|
-
var hasOwnProperty$
|
|
39
|
+
var hasOwnProperty$i = objectProto$l.hasOwnProperty;
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
|
|
@@ -51,7 +51,7 @@ function baseKeys(object) {
|
|
|
51
51
|
}
|
|
52
52
|
var result = [];
|
|
53
53
|
for (var key in Object(object)) {
|
|
54
|
-
if (hasOwnProperty$
|
|
54
|
+
if (hasOwnProperty$i.call(object, key) && key != 'constructor') {
|
|
55
55
|
result.push(key);
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -71,17 +71,17 @@ var root$1 = freeGlobal || freeSelf || Function('return this')();
|
|
|
71
71
|
var Symbol$1 = root$1.Symbol;
|
|
72
72
|
|
|
73
73
|
/** Used for built-in method references. */
|
|
74
|
-
var objectProto$
|
|
74
|
+
var objectProto$k = Object.prototype;
|
|
75
75
|
|
|
76
76
|
/** Used to check objects for own properties. */
|
|
77
|
-
var hasOwnProperty$
|
|
77
|
+
var hasOwnProperty$h = objectProto$k.hasOwnProperty;
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
80
|
* Used to resolve the
|
|
81
81
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
82
82
|
* of values.
|
|
83
83
|
*/
|
|
84
|
-
var nativeObjectToString$2 = objectProto$
|
|
84
|
+
var nativeObjectToString$2 = objectProto$k.toString;
|
|
85
85
|
|
|
86
86
|
/** Built-in value references. */
|
|
87
87
|
var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;
|
|
@@ -94,7 +94,7 @@ var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;
|
|
|
94
94
|
* @returns {string} Returns the raw `toStringTag`.
|
|
95
95
|
*/
|
|
96
96
|
function getRawTag(value) {
|
|
97
|
-
var isOwn = hasOwnProperty$
|
|
97
|
+
var isOwn = hasOwnProperty$h.call(value, symToStringTag$1),
|
|
98
98
|
tag = value[symToStringTag$1];
|
|
99
99
|
|
|
100
100
|
try {
|
|
@@ -114,14 +114,14 @@ function getRawTag(value) {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/** Used for built-in method references. */
|
|
117
|
-
var objectProto$
|
|
117
|
+
var objectProto$j = Object.prototype;
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
120
|
* Used to resolve the
|
|
121
121
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
122
122
|
* of values.
|
|
123
123
|
*/
|
|
124
|
-
var nativeObjectToString$1 = objectProto$
|
|
124
|
+
var nativeObjectToString$1 = objectProto$j.toString;
|
|
125
125
|
|
|
126
126
|
/**
|
|
127
127
|
* Converts `value` to a string using `Object.prototype.toString`.
|
|
@@ -276,17 +276,17 @@ var reIsHostCtor = /^\[object .+?Constructor\]$/;
|
|
|
276
276
|
|
|
277
277
|
/** Used for built-in method references. */
|
|
278
278
|
var funcProto$1 = Function.prototype,
|
|
279
|
-
objectProto$
|
|
279
|
+
objectProto$i = Object.prototype;
|
|
280
280
|
|
|
281
281
|
/** Used to resolve the decompiled source of functions. */
|
|
282
282
|
var funcToString$1 = funcProto$1.toString;
|
|
283
283
|
|
|
284
284
|
/** Used to check objects for own properties. */
|
|
285
|
-
var hasOwnProperty$
|
|
285
|
+
var hasOwnProperty$g = objectProto$i.hasOwnProperty;
|
|
286
286
|
|
|
287
287
|
/** Used to detect if a method is native. */
|
|
288
288
|
var reIsNative = RegExp('^' +
|
|
289
|
-
funcToString$1.call(hasOwnProperty$
|
|
289
|
+
funcToString$1.call(hasOwnProperty$g).replace(reRegExpChar, '\\$&')
|
|
290
290
|
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
|
|
291
291
|
);
|
|
292
292
|
|
|
@@ -335,16 +335,16 @@ function getNative(object, key) {
|
|
|
335
335
|
var DataView = getNative(root$1, 'DataView');
|
|
336
336
|
|
|
337
337
|
/* Built-in method references that are verified to be native. */
|
|
338
|
-
var Map = getNative(root$1, 'Map');
|
|
338
|
+
var Map$1 = getNative(root$1, 'Map');
|
|
339
339
|
|
|
340
340
|
/* Built-in method references that are verified to be native. */
|
|
341
341
|
var Promise$1 = getNative(root$1, 'Promise');
|
|
342
342
|
|
|
343
343
|
/* Built-in method references that are verified to be native. */
|
|
344
|
-
var Set = getNative(root$1, 'Set');
|
|
344
|
+
var Set$1 = getNative(root$1, 'Set');
|
|
345
345
|
|
|
346
346
|
/* Built-in method references that are verified to be native. */
|
|
347
|
-
var WeakMap = getNative(root$1, 'WeakMap');
|
|
347
|
+
var WeakMap$1 = getNative(root$1, 'WeakMap');
|
|
348
348
|
|
|
349
349
|
/** `Object#toString` result references. */
|
|
350
350
|
var mapTag$6 = '[object Map]',
|
|
@@ -357,10 +357,10 @@ var dataViewTag$4 = '[object DataView]';
|
|
|
357
357
|
|
|
358
358
|
/** Used to detect maps, sets, and weakmaps. */
|
|
359
359
|
var dataViewCtorString = toSource(DataView),
|
|
360
|
-
mapCtorString = toSource(Map),
|
|
360
|
+
mapCtorString = toSource(Map$1),
|
|
361
361
|
promiseCtorString = toSource(Promise$1),
|
|
362
|
-
setCtorString = toSource(Set),
|
|
363
|
-
weakMapCtorString = toSource(WeakMap);
|
|
362
|
+
setCtorString = toSource(Set$1),
|
|
363
|
+
weakMapCtorString = toSource(WeakMap$1);
|
|
364
364
|
|
|
365
365
|
/**
|
|
366
366
|
* Gets the `toStringTag` of `value`.
|
|
@@ -373,10 +373,10 @@ var getTag = baseGetTag;
|
|
|
373
373
|
|
|
374
374
|
// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
|
|
375
375
|
if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$4) ||
|
|
376
|
-
(Map && getTag(new Map) != mapTag$6) ||
|
|
376
|
+
(Map$1 && getTag(new Map$1) != mapTag$6) ||
|
|
377
377
|
(Promise$1 && getTag(Promise$1.resolve()) != promiseTag) ||
|
|
378
|
-
(Set && getTag(new Set) != setTag$6) ||
|
|
379
|
-
(WeakMap && getTag(new WeakMap) != weakMapTag$2)) {
|
|
378
|
+
(Set$1 && getTag(new Set$1) != setTag$6) ||
|
|
379
|
+
(WeakMap$1 && getTag(new WeakMap$1) != weakMapTag$2)) {
|
|
380
380
|
getTag = function(value) {
|
|
381
381
|
var result = baseGetTag(value),
|
|
382
382
|
Ctor = result == objectTag$4 ? value.constructor : undefined,
|
|
@@ -438,13 +438,13 @@ function baseIsArguments(value) {
|
|
|
438
438
|
}
|
|
439
439
|
|
|
440
440
|
/** Used for built-in method references. */
|
|
441
|
-
var objectProto$
|
|
441
|
+
var objectProto$h = Object.prototype;
|
|
442
442
|
|
|
443
443
|
/** Used to check objects for own properties. */
|
|
444
|
-
var hasOwnProperty$
|
|
444
|
+
var hasOwnProperty$f = objectProto$h.hasOwnProperty;
|
|
445
445
|
|
|
446
446
|
/** Built-in value references. */
|
|
447
|
-
var propertyIsEnumerable$1 = objectProto$
|
|
447
|
+
var propertyIsEnumerable$1 = objectProto$h.propertyIsEnumerable;
|
|
448
448
|
|
|
449
449
|
/**
|
|
450
450
|
* Checks if `value` is likely an `arguments` object.
|
|
@@ -465,7 +465,7 @@ var propertyIsEnumerable$1 = objectProto$g.propertyIsEnumerable;
|
|
|
465
465
|
* // => false
|
|
466
466
|
*/
|
|
467
467
|
var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
|
|
468
|
-
return isObjectLike(value) && hasOwnProperty$
|
|
468
|
+
return isObjectLike(value) && hasOwnProperty$f.call(value, 'callee') &&
|
|
469
469
|
!propertyIsEnumerable$1.call(value, 'callee');
|
|
470
470
|
};
|
|
471
471
|
|
|
@@ -730,10 +730,10 @@ var mapTag$4 = '[object Map]',
|
|
|
730
730
|
setTag$4 = '[object Set]';
|
|
731
731
|
|
|
732
732
|
/** Used for built-in method references. */
|
|
733
|
-
var objectProto$
|
|
733
|
+
var objectProto$g = Object.prototype;
|
|
734
734
|
|
|
735
735
|
/** Used to check objects for own properties. */
|
|
736
|
-
var hasOwnProperty$
|
|
736
|
+
var hasOwnProperty$e = objectProto$g.hasOwnProperty;
|
|
737
737
|
|
|
738
738
|
/**
|
|
739
739
|
* Checks if `value` is an empty object, collection, map, or set.
|
|
@@ -785,7 +785,7 @@ function isEmpty(value) {
|
|
|
785
785
|
return !baseKeys(value).length;
|
|
786
786
|
}
|
|
787
787
|
for (var key in value) {
|
|
788
|
-
if (hasOwnProperty$
|
|
788
|
+
if (hasOwnProperty$e.call(value, key)) {
|
|
789
789
|
return false;
|
|
790
790
|
}
|
|
791
791
|
}
|
|
@@ -836,10 +836,10 @@ function isIndex(value, length) {
|
|
|
836
836
|
}
|
|
837
837
|
|
|
838
838
|
/** Used for built-in method references. */
|
|
839
|
-
var objectProto$
|
|
839
|
+
var objectProto$f = Object.prototype;
|
|
840
840
|
|
|
841
841
|
/** Used to check objects for own properties. */
|
|
842
|
-
var hasOwnProperty$
|
|
842
|
+
var hasOwnProperty$d = objectProto$f.hasOwnProperty;
|
|
843
843
|
|
|
844
844
|
/**
|
|
845
845
|
* Creates an array of the enumerable property names of the array-like `value`.
|
|
@@ -859,7 +859,7 @@ function arrayLikeKeys(value, inherited) {
|
|
|
859
859
|
length = result.length;
|
|
860
860
|
|
|
861
861
|
for (var key in value) {
|
|
862
|
-
if ((inherited || hasOwnProperty$
|
|
862
|
+
if ((inherited || hasOwnProperty$d.call(value, key)) &&
|
|
863
863
|
!(skipIndexes && (
|
|
864
864
|
// Safari 9 has enumerable `arguments.length` in strict mode.
|
|
865
865
|
key == 'length' ||
|
|
@@ -1002,7 +1002,7 @@ function baseToString(value) {
|
|
|
1002
1002
|
* _.toString([1, 2, 3]);
|
|
1003
1003
|
* // => '1,2,3'
|
|
1004
1004
|
*/
|
|
1005
|
-
function toString$
|
|
1005
|
+
function toString$1(value) {
|
|
1006
1006
|
return value == null ? '' : baseToString(value);
|
|
1007
1007
|
}
|
|
1008
1008
|
|
|
@@ -1028,7 +1028,7 @@ var idCounter = 0;
|
|
|
1028
1028
|
*/
|
|
1029
1029
|
function uniqueId(prefix) {
|
|
1030
1030
|
var id = ++idCounter;
|
|
1031
|
-
return toString$
|
|
1031
|
+
return toString$1(prefix) + id;
|
|
1032
1032
|
}
|
|
1033
1033
|
|
|
1034
1034
|
/** Used to match a single whitespace character. */
|
|
@@ -1624,6 +1624,14 @@ function EventEmitter(Base) {
|
|
|
1624
1624
|
eventsApi(triggerApi, this._events, name, undefined, args);
|
|
1625
1625
|
return this;
|
|
1626
1626
|
}
|
|
1627
|
+
/**
|
|
1628
|
+
* Subscribe to an event. Returns an unsubscribe function.
|
|
1629
|
+
* Compatible with `useSyncExternalStore` and other store-style APIs.
|
|
1630
|
+
*/
|
|
1631
|
+
subscribe(event, callback, context) {
|
|
1632
|
+
this.on(event, callback, context);
|
|
1633
|
+
return () => this.off(event, callback, context);
|
|
1634
|
+
}
|
|
1627
1635
|
};
|
|
1628
1636
|
}
|
|
1629
1637
|
/**
|
|
@@ -1631,7 +1639,7 @@ function EventEmitter(Base) {
|
|
|
1631
1639
|
*/
|
|
1632
1640
|
const EventEmitterObject = EventEmitter(Object);
|
|
1633
1641
|
|
|
1634
|
-
|
|
1642
|
+
/******************************************************************************
|
|
1635
1643
|
Copyright (c) Microsoft Corporation.
|
|
1636
1644
|
|
|
1637
1645
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
@@ -1645,7 +1653,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
1645
1653
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1646
1654
|
PERFORMANCE OF THIS SOFTWARE.
|
|
1647
1655
|
***************************************************************************** */
|
|
1648
|
-
/* global Reflect, Promise */
|
|
1656
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
1649
1657
|
|
|
1650
1658
|
|
|
1651
1659
|
function __values(o) {
|
|
@@ -1658,7 +1666,25 @@ function __values(o) {
|
|
|
1658
1666
|
}
|
|
1659
1667
|
};
|
|
1660
1668
|
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
1661
|
-
}
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
function __classPrivateFieldGet(receiver, state, kind, f) {
|
|
1672
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
1673
|
+
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");
|
|
1674
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
function __classPrivateFieldSet(receiver, state, value, kind, f) {
|
|
1678
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
1679
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
1680
|
+
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");
|
|
1681
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1685
|
+
var e = new Error(message);
|
|
1686
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1687
|
+
};
|
|
1662
1688
|
|
|
1663
1689
|
/*!
|
|
1664
1690
|
MIT License
|
|
@@ -1697,7 +1723,7 @@ SOFTWARE.
|
|
|
1697
1723
|
* @param parts
|
|
1698
1724
|
* @param properties
|
|
1699
1725
|
*/
|
|
1700
|
-
function createBlob
|
|
1726
|
+
function createBlob(parts, properties) {
|
|
1701
1727
|
/* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
|
|
1702
1728
|
parts = parts || [];
|
|
1703
1729
|
properties = properties || {};
|
|
@@ -1721,12 +1747,12 @@ function createBlob$1(parts, properties) {
|
|
|
1721
1747
|
}
|
|
1722
1748
|
}
|
|
1723
1749
|
|
|
1724
|
-
var BLOB_TYPE_PREFIX_REGEX
|
|
1725
|
-
var SERIALIZED_MARKER_LENGTH
|
|
1726
|
-
var TYPE_SERIALIZED_MARKER_LENGTH
|
|
1750
|
+
var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;
|
|
1751
|
+
var SERIALIZED_MARKER_LENGTH = "__lfsc__:" /* SERIALIZED_MARKER */.length;
|
|
1752
|
+
var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + "arbf" /* TYPE_ARRAYBUFFER */.length;
|
|
1727
1753
|
//tslint:disable:no-magic-numbers no-bitwise prefer-switch no-unbound-method
|
|
1728
|
-
var toString
|
|
1729
|
-
function stringToBuffer
|
|
1754
|
+
var toString = Object.prototype.toString;
|
|
1755
|
+
function stringToBuffer(serializedString) {
|
|
1730
1756
|
// Fill the string into a ArrayBuffer.
|
|
1731
1757
|
var bufferLength = serializedString.length * 0.75;
|
|
1732
1758
|
var len = serializedString.length;
|
|
@@ -1753,7 +1779,7 @@ function stringToBuffer$1(serializedString) {
|
|
|
1753
1779
|
* Converts a buffer to a string to store, serialized, in the backend
|
|
1754
1780
|
* storage library.
|
|
1755
1781
|
*/
|
|
1756
|
-
function bufferToString
|
|
1782
|
+
function bufferToString(buffer) {
|
|
1757
1783
|
// base64-arraybuffer
|
|
1758
1784
|
var bytes = new Uint8Array(buffer);
|
|
1759
1785
|
var base64String = '';
|
|
@@ -1780,15 +1806,15 @@ function bufferToString$1(buffer) {
|
|
|
1780
1806
|
* @param value
|
|
1781
1807
|
* @param callback
|
|
1782
1808
|
*/
|
|
1783
|
-
function serialize$
|
|
1809
|
+
function serialize$1(value, callback) {
|
|
1784
1810
|
var valueType = '';
|
|
1785
1811
|
if (value) {
|
|
1786
|
-
valueType = toString
|
|
1812
|
+
valueType = toString.call(value);
|
|
1787
1813
|
}
|
|
1788
1814
|
// Cannot use `value instanceof ArrayBuffer` or such here, as these
|
|
1789
1815
|
// checks fail when running the tests using casper.js...
|
|
1790
1816
|
if (value && (valueType === '[object ArrayBuffer]' ||
|
|
1791
|
-
(value.buffer && toString
|
|
1817
|
+
(value.buffer && toString.call(value.buffer) === '[object ArrayBuffer]'))) {
|
|
1792
1818
|
// Convert binary arrays to a string and prefix the string with
|
|
1793
1819
|
// a special marker.
|
|
1794
1820
|
var buffer = void 0;
|
|
@@ -1830,7 +1856,7 @@ function serialize$2(value, callback) {
|
|
|
1830
1856
|
callback(new Error('Failed to get type for BinaryArray'));
|
|
1831
1857
|
}
|
|
1832
1858
|
}
|
|
1833
|
-
callback(marker + bufferToString
|
|
1859
|
+
callback(marker + bufferToString(buffer));
|
|
1834
1860
|
}
|
|
1835
1861
|
else if (valueType === '[object Blob]') {
|
|
1836
1862
|
// Convert the blob to a binaryArray and then to a string.
|
|
@@ -1838,7 +1864,7 @@ function serialize$2(value, callback) {
|
|
|
1838
1864
|
fileReader.onload = function () {
|
|
1839
1865
|
// Backwards-compatible prefix for the blob type.
|
|
1840
1866
|
//tslint:disable-next-line:restrict-plus-operands
|
|
1841
|
-
var str = "~~local_forage_type~" /* BLOB_TYPE_PREFIX */ + value.type + "~" + bufferToString
|
|
1867
|
+
var str = "~~local_forage_type~" /* BLOB_TYPE_PREFIX */ + value.type + "~" + bufferToString(this.result);
|
|
1842
1868
|
callback("__lfsc__:" /* SERIALIZED_MARKER */ + "blob" /* TYPE_BLOB */ + str);
|
|
1843
1869
|
};
|
|
1844
1870
|
fileReader.readAsArrayBuffer(value);
|
|
@@ -1864,34 +1890,34 @@ function serialize$2(value, callback) {
|
|
|
1864
1890
|
* some kind of arraybuffer/binary data/typed array out of the string.
|
|
1865
1891
|
* @param value
|
|
1866
1892
|
*/
|
|
1867
|
-
function deserialize$
|
|
1893
|
+
function deserialize$1(value) {
|
|
1868
1894
|
// If we haven't marked this string as being specially serialized (i.e.
|
|
1869
1895
|
// something other than serialized JSON), we can just return it and be
|
|
1870
1896
|
// done with it.
|
|
1871
|
-
if (value.substring(0, SERIALIZED_MARKER_LENGTH
|
|
1897
|
+
if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== "__lfsc__:" /* SERIALIZED_MARKER */) {
|
|
1872
1898
|
return JSON.parse(value);
|
|
1873
1899
|
}
|
|
1874
1900
|
// The following code deals with deserializing some kind of Blob or
|
|
1875
1901
|
// TypedArray. First we separate out the type of data we're dealing
|
|
1876
1902
|
// with from the data itself.
|
|
1877
|
-
var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH
|
|
1878
|
-
var type = value.substring(SERIALIZED_MARKER_LENGTH
|
|
1903
|
+
var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);
|
|
1904
|
+
var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH);
|
|
1879
1905
|
var blobType;
|
|
1880
1906
|
// Backwards-compatible blob type serialization strategy.
|
|
1881
1907
|
// DBs created with older versions of localForage will simply not have the blob type.
|
|
1882
|
-
if (type === "blob" /* TYPE_BLOB */ && BLOB_TYPE_PREFIX_REGEX
|
|
1883
|
-
var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX
|
|
1908
|
+
if (type === "blob" /* TYPE_BLOB */ && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {
|
|
1909
|
+
var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);
|
|
1884
1910
|
blobType = matcher[1];
|
|
1885
1911
|
serializedString = serializedString.substring(matcher[0].length);
|
|
1886
1912
|
}
|
|
1887
|
-
var buffer = stringToBuffer
|
|
1913
|
+
var buffer = stringToBuffer(serializedString);
|
|
1888
1914
|
// Return the right type based on the code/type set during
|
|
1889
1915
|
// serialization.
|
|
1890
1916
|
switch (type) {
|
|
1891
1917
|
case "arbf" /* TYPE_ARRAYBUFFER */:
|
|
1892
1918
|
return buffer;
|
|
1893
1919
|
case "blob" /* TYPE_BLOB */:
|
|
1894
|
-
return createBlob
|
|
1920
|
+
return createBlob([buffer], { type: blobType });
|
|
1895
1921
|
case "si08" /* TYPE_INT8ARRAY */:
|
|
1896
1922
|
return new Int8Array(buffer);
|
|
1897
1923
|
case "ui08" /* TYPE_UINT8ARRAY */:
|
|
@@ -1945,7 +1971,7 @@ function getKeyPrefix(options, defaultConfig) {
|
|
|
1945
1971
|
return (options.name || defaultConfig.name) + "/" + (options.storeName || defaultConfig.storeName) + "/";
|
|
1946
1972
|
}
|
|
1947
1973
|
|
|
1948
|
-
function executeCallback$
|
|
1974
|
+
function executeCallback$1(promise, callback) {
|
|
1949
1975
|
if (callback) {
|
|
1950
1976
|
promise.then(function (result) {
|
|
1951
1977
|
callback(null, result);
|
|
@@ -1998,10 +2024,10 @@ function normaliseKey(key) {
|
|
|
1998
2024
|
}
|
|
1999
2025
|
|
|
2000
2026
|
var serialiser = {
|
|
2001
|
-
bufferToString: bufferToString
|
|
2002
|
-
deserialize: deserialize$
|
|
2003
|
-
serialize: serialize$
|
|
2004
|
-
stringToBuffer: stringToBuffer
|
|
2027
|
+
bufferToString: bufferToString,
|
|
2028
|
+
deserialize: deserialize$1,
|
|
2029
|
+
serialize: serialize$1,
|
|
2030
|
+
stringToBuffer: stringToBuffer
|
|
2005
2031
|
};
|
|
2006
2032
|
|
|
2007
2033
|
/*!
|
|
@@ -2086,7 +2112,7 @@ function clear$1(callback) {
|
|
|
2086
2112
|
var promise = this.ready().then(function () {
|
|
2087
2113
|
_this._dbInfo.mStore.clear();
|
|
2088
2114
|
});
|
|
2089
|
-
executeCallback$
|
|
2115
|
+
executeCallback$1(promise, callback);
|
|
2090
2116
|
return promise;
|
|
2091
2117
|
}
|
|
2092
2118
|
|
|
@@ -2095,7 +2121,7 @@ function dropInstance$1(_options, _cb) {
|
|
|
2095
2121
|
var outPromise = promise.then(function (keyPrefix) {
|
|
2096
2122
|
Store.resolve(keyPrefix).drop();
|
|
2097
2123
|
});
|
|
2098
|
-
executeCallback$
|
|
2124
|
+
executeCallback$1(outPromise, callback);
|
|
2099
2125
|
return promise;
|
|
2100
2126
|
}
|
|
2101
2127
|
|
|
@@ -2107,7 +2133,7 @@ function getItem$1(key$, callback) {
|
|
|
2107
2133
|
// Deserialise if the result is not null or undefined
|
|
2108
2134
|
return result == null ? null : _this._dbInfo.serializer.deserialize(result); //tslint:disable-line:triple-equals
|
|
2109
2135
|
});
|
|
2110
|
-
executeCallback$
|
|
2136
|
+
executeCallback$1(promise, callback);
|
|
2111
2137
|
return promise;
|
|
2112
2138
|
}
|
|
2113
2139
|
|
|
@@ -2131,7 +2157,7 @@ function iterate$1(iterator, callback) {
|
|
|
2131
2157
|
}
|
|
2132
2158
|
}
|
|
2133
2159
|
});
|
|
2134
|
-
executeCallback$
|
|
2160
|
+
executeCallback$1(promise, callback);
|
|
2135
2161
|
return promise;
|
|
2136
2162
|
}
|
|
2137
2163
|
|
|
@@ -2150,7 +2176,7 @@ function key$1(idx, callback) {
|
|
|
2150
2176
|
}
|
|
2151
2177
|
return result;
|
|
2152
2178
|
});
|
|
2153
|
-
executeCallback$
|
|
2179
|
+
executeCallback$1(promise, callback);
|
|
2154
2180
|
return promise;
|
|
2155
2181
|
}
|
|
2156
2182
|
|
|
@@ -2159,13 +2185,13 @@ function keys$1(callback) {
|
|
|
2159
2185
|
var promise = this.ready().then(function () {
|
|
2160
2186
|
return _this._dbInfo.mStore.keys();
|
|
2161
2187
|
});
|
|
2162
|
-
executeCallback$
|
|
2188
|
+
executeCallback$1(promise, callback);
|
|
2163
2189
|
return promise;
|
|
2164
2190
|
}
|
|
2165
2191
|
|
|
2166
2192
|
function length$1(callback) {
|
|
2167
2193
|
var promise = this.keys().then(function (keys$) { return keys$.length; });
|
|
2168
|
-
executeCallback$
|
|
2194
|
+
executeCallback$1(promise, callback);
|
|
2169
2195
|
return promise;
|
|
2170
2196
|
}
|
|
2171
2197
|
|
|
@@ -2175,7 +2201,7 @@ function removeItem$1(key$, callback) {
|
|
|
2175
2201
|
var promise = this.ready().then(function () {
|
|
2176
2202
|
_this._dbInfo.mStore.rm(key$);
|
|
2177
2203
|
});
|
|
2178
|
-
executeCallback$
|
|
2204
|
+
executeCallback$1(promise, callback);
|
|
2179
2205
|
return promise;
|
|
2180
2206
|
}
|
|
2181
2207
|
|
|
@@ -2205,7 +2231,7 @@ function setItem$1(key$, value, callback) {
|
|
|
2205
2231
|
});
|
|
2206
2232
|
});
|
|
2207
2233
|
});
|
|
2208
|
-
executeCallback$
|
|
2234
|
+
executeCallback$1(promise, callback);
|
|
2209
2235
|
return promise;
|
|
2210
2236
|
}
|
|
2211
2237
|
|
|
@@ -2492,10 +2518,10 @@ function hashDelete(key) {
|
|
|
2492
2518
|
var HASH_UNDEFINED$2 = '__lodash_hash_undefined__';
|
|
2493
2519
|
|
|
2494
2520
|
/** Used for built-in method references. */
|
|
2495
|
-
var objectProto$
|
|
2521
|
+
var objectProto$e = Object.prototype;
|
|
2496
2522
|
|
|
2497
2523
|
/** Used to check objects for own properties. */
|
|
2498
|
-
var hasOwnProperty$
|
|
2524
|
+
var hasOwnProperty$c = objectProto$e.hasOwnProperty;
|
|
2499
2525
|
|
|
2500
2526
|
/**
|
|
2501
2527
|
* Gets the hash value for `key`.
|
|
@@ -2512,14 +2538,14 @@ function hashGet(key) {
|
|
|
2512
2538
|
var result = data[key];
|
|
2513
2539
|
return result === HASH_UNDEFINED$2 ? undefined : result;
|
|
2514
2540
|
}
|
|
2515
|
-
return hasOwnProperty$
|
|
2541
|
+
return hasOwnProperty$c.call(data, key) ? data[key] : undefined;
|
|
2516
2542
|
}
|
|
2517
2543
|
|
|
2518
2544
|
/** Used for built-in method references. */
|
|
2519
|
-
var objectProto$
|
|
2545
|
+
var objectProto$d = Object.prototype;
|
|
2520
2546
|
|
|
2521
2547
|
/** Used to check objects for own properties. */
|
|
2522
|
-
var hasOwnProperty$
|
|
2548
|
+
var hasOwnProperty$b = objectProto$d.hasOwnProperty;
|
|
2523
2549
|
|
|
2524
2550
|
/**
|
|
2525
2551
|
* Checks if a hash value for `key` exists.
|
|
@@ -2532,7 +2558,7 @@ var hasOwnProperty$a = objectProto$c.hasOwnProperty;
|
|
|
2532
2558
|
*/
|
|
2533
2559
|
function hashHas(key) {
|
|
2534
2560
|
var data = this.__data__;
|
|
2535
|
-
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$
|
|
2561
|
+
return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$b.call(data, key);
|
|
2536
2562
|
}
|
|
2537
2563
|
|
|
2538
2564
|
/** Used to stand-in for `undefined` hash values. */
|
|
@@ -2591,7 +2617,7 @@ function mapCacheClear() {
|
|
|
2591
2617
|
this.size = 0;
|
|
2592
2618
|
this.__data__ = {
|
|
2593
2619
|
'hash': new Hash,
|
|
2594
|
-
'map': new (Map || ListCache),
|
|
2620
|
+
'map': new (Map$1 || ListCache),
|
|
2595
2621
|
'string': new Hash
|
|
2596
2622
|
};
|
|
2597
2623
|
}
|
|
@@ -2727,7 +2753,7 @@ function stackSet(key, value) {
|
|
|
2727
2753
|
var data = this.__data__;
|
|
2728
2754
|
if (data instanceof ListCache) {
|
|
2729
2755
|
var pairs = data.__data__;
|
|
2730
|
-
if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
|
|
2756
|
+
if (!Map$1 || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
|
|
2731
2757
|
pairs.push([key, value]);
|
|
2732
2758
|
this.size = ++data.size;
|
|
2733
2759
|
return this;
|
|
@@ -2810,10 +2836,10 @@ function baseAssignValue(object, key, value) {
|
|
|
2810
2836
|
}
|
|
2811
2837
|
|
|
2812
2838
|
/** Used for built-in method references. */
|
|
2813
|
-
var objectProto$
|
|
2839
|
+
var objectProto$c = Object.prototype;
|
|
2814
2840
|
|
|
2815
2841
|
/** Used to check objects for own properties. */
|
|
2816
|
-
var hasOwnProperty$
|
|
2842
|
+
var hasOwnProperty$a = objectProto$c.hasOwnProperty;
|
|
2817
2843
|
|
|
2818
2844
|
/**
|
|
2819
2845
|
* Assigns `value` to `key` of `object` if the existing value is not equivalent
|
|
@@ -2827,7 +2853,7 @@ var hasOwnProperty$9 = objectProto$b.hasOwnProperty;
|
|
|
2827
2853
|
*/
|
|
2828
2854
|
function assignValue(object, key, value) {
|
|
2829
2855
|
var objValue = object[key];
|
|
2830
|
-
if (!(hasOwnProperty$
|
|
2856
|
+
if (!(hasOwnProperty$a.call(object, key) && eq(objValue, value)) ||
|
|
2831
2857
|
(value === undefined && !(key in object))) {
|
|
2832
2858
|
baseAssignValue(object, key, value);
|
|
2833
2859
|
}
|
|
@@ -2900,10 +2926,10 @@ function nativeKeysIn(object) {
|
|
|
2900
2926
|
}
|
|
2901
2927
|
|
|
2902
2928
|
/** Used for built-in method references. */
|
|
2903
|
-
var objectProto$
|
|
2929
|
+
var objectProto$b = Object.prototype;
|
|
2904
2930
|
|
|
2905
2931
|
/** Used to check objects for own properties. */
|
|
2906
|
-
var hasOwnProperty$
|
|
2932
|
+
var hasOwnProperty$9 = objectProto$b.hasOwnProperty;
|
|
2907
2933
|
|
|
2908
2934
|
/**
|
|
2909
2935
|
* The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
|
|
@@ -2920,7 +2946,7 @@ function baseKeysIn(object) {
|
|
|
2920
2946
|
result = [];
|
|
2921
2947
|
|
|
2922
2948
|
for (var key in object) {
|
|
2923
|
-
if (!(key == 'constructor' && (isProto || !hasOwnProperty$
|
|
2949
|
+
if (!(key == 'constructor' && (isProto || !hasOwnProperty$9.call(object, key)))) {
|
|
2924
2950
|
result.push(key);
|
|
2925
2951
|
}
|
|
2926
2952
|
}
|
|
@@ -3065,10 +3091,10 @@ function stubArray() {
|
|
|
3065
3091
|
}
|
|
3066
3092
|
|
|
3067
3093
|
/** Used for built-in method references. */
|
|
3068
|
-
var objectProto$
|
|
3094
|
+
var objectProto$a = Object.prototype;
|
|
3069
3095
|
|
|
3070
3096
|
/** Built-in value references. */
|
|
3071
|
-
var propertyIsEnumerable = objectProto$
|
|
3097
|
+
var propertyIsEnumerable = objectProto$a.propertyIsEnumerable;
|
|
3072
3098
|
|
|
3073
3099
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
3074
3100
|
var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
|
|
@@ -3195,10 +3221,10 @@ function getAllKeysIn(object) {
|
|
|
3195
3221
|
}
|
|
3196
3222
|
|
|
3197
3223
|
/** Used for built-in method references. */
|
|
3198
|
-
var objectProto$
|
|
3224
|
+
var objectProto$9 = Object.prototype;
|
|
3199
3225
|
|
|
3200
3226
|
/** Used to check objects for own properties. */
|
|
3201
|
-
var hasOwnProperty$
|
|
3227
|
+
var hasOwnProperty$8 = objectProto$9.hasOwnProperty;
|
|
3202
3228
|
|
|
3203
3229
|
/**
|
|
3204
3230
|
* Initializes an array clone.
|
|
@@ -3212,7 +3238,7 @@ function initCloneArray(array) {
|
|
|
3212
3238
|
result = new array.constructor(length);
|
|
3213
3239
|
|
|
3214
3240
|
// Add properties assigned by `RegExp#exec`.
|
|
3215
|
-
if (length && typeof array[0] == 'string' && hasOwnProperty$
|
|
3241
|
+
if (length && typeof array[0] == 'string' && hasOwnProperty$8.call(array, 'index')) {
|
|
3216
3242
|
result.index = array.index;
|
|
3217
3243
|
result.input = array.input;
|
|
3218
3244
|
}
|
|
@@ -6592,13 +6618,13 @@ var objectTag$1 = '[object Object]';
|
|
|
6592
6618
|
|
|
6593
6619
|
/** Used for built-in method references. */
|
|
6594
6620
|
var funcProto = Function.prototype,
|
|
6595
|
-
objectProto$
|
|
6621
|
+
objectProto$8 = Object.prototype;
|
|
6596
6622
|
|
|
6597
6623
|
/** Used to resolve the decompiled source of functions. */
|
|
6598
6624
|
var funcToString = funcProto.toString;
|
|
6599
6625
|
|
|
6600
6626
|
/** Used to check objects for own properties. */
|
|
6601
|
-
var hasOwnProperty$
|
|
6627
|
+
var hasOwnProperty$7 = objectProto$8.hasOwnProperty;
|
|
6602
6628
|
|
|
6603
6629
|
/** Used to infer the `Object` constructor. */
|
|
6604
6630
|
var objectCtorString = funcToString.call(Object);
|
|
@@ -6639,7 +6665,7 @@ function isPlainObject(value) {
|
|
|
6639
6665
|
if (proto === null) {
|
|
6640
6666
|
return true;
|
|
6641
6667
|
}
|
|
6642
|
-
var Ctor = hasOwnProperty$
|
|
6668
|
+
var Ctor = hasOwnProperty$7.call(proto, 'constructor') && proto.constructor;
|
|
6643
6669
|
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
|
|
6644
6670
|
funcToString.call(Ctor) == objectCtorString;
|
|
6645
6671
|
}
|
|
@@ -7371,310 +7397,43 @@ function mergebounce(func, wait, options={}) {
|
|
|
7371
7397
|
return debounced;
|
|
7372
7398
|
}
|
|
7373
7399
|
|
|
7374
|
-
function
|
|
7400
|
+
function chainCallback(promise, callback) {
|
|
7375
7401
|
if (callback) {
|
|
7376
|
-
promise.then(
|
|
7377
|
-
function(result) {
|
|
7378
|
-
callback(null, result);
|
|
7379
|
-
},
|
|
7380
|
-
function(error) {
|
|
7381
|
-
callback(error);
|
|
7382
|
-
}
|
|
7383
|
-
);
|
|
7402
|
+
promise.then((result) => callback(null, result), (err) => callback(err));
|
|
7384
7403
|
}
|
|
7385
7404
|
}
|
|
7386
|
-
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
arguments.length &&
|
|
7390
|
-
typeof arguments[arguments.length - 1] === 'function'
|
|
7391
|
-
) {
|
|
7392
|
-
return arguments[arguments.length - 1];
|
|
7405
|
+
function getCallback(...args) {
|
|
7406
|
+
if (args.length && typeof args[args.length - 1] === 'function') {
|
|
7407
|
+
return args[args.length - 1];
|
|
7393
7408
|
}
|
|
7394
7409
|
}
|
|
7395
|
-
|
|
7396
7410
|
function normalizeKey(key) {
|
|
7397
|
-
// Cast the key to a string, as that's all we can set as a key.
|
|
7398
7411
|
if (typeof key !== 'string') {
|
|
7399
7412
|
console.warn(`${key} used as a key, but it is not a string.`);
|
|
7400
7413
|
key = String(key);
|
|
7401
7414
|
}
|
|
7402
|
-
|
|
7403
7415
|
return key;
|
|
7404
7416
|
}
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
// Abstracts constructing a Blob object, so it also works in older
|
|
7410
|
-
// browsers that don't support the native Blob constructor. (i.e.
|
|
7411
|
-
// old QtWebKit versions, at least).
|
|
7412
|
-
function createBlob(parts, properties) {
|
|
7413
|
-
/* global BlobBuilder,MSBlobBuilder,MozBlobBuilder,WebKitBlobBuilder */
|
|
7414
|
-
parts = parts || [];
|
|
7415
|
-
properties = properties || {};
|
|
7416
|
-
try {
|
|
7417
|
-
return new Blob(parts, properties);
|
|
7418
|
-
} catch (e) {
|
|
7419
|
-
if (e.name !== 'TypeError') {
|
|
7420
|
-
throw e;
|
|
7421
|
-
}
|
|
7422
|
-
var Builder =
|
|
7423
|
-
typeof BlobBuilder !== 'undefined'
|
|
7424
|
-
? BlobBuilder
|
|
7425
|
-
: typeof MSBlobBuilder !== 'undefined'
|
|
7426
|
-
? MSBlobBuilder
|
|
7427
|
-
: typeof MozBlobBuilder !== 'undefined'
|
|
7428
|
-
? MozBlobBuilder
|
|
7429
|
-
: WebKitBlobBuilder;
|
|
7430
|
-
var builder = new Builder();
|
|
7431
|
-
for (var i = 0; i < parts.length; i += 1) {
|
|
7432
|
-
builder.append(parts[i]);
|
|
7417
|
+
function serializeSync(value) {
|
|
7418
|
+
return JSON.stringify(value, (_key, val) => {
|
|
7419
|
+
if (val instanceof Date) {
|
|
7420
|
+
return val.toISOString();
|
|
7433
7421
|
}
|
|
7434
|
-
return
|
|
7435
|
-
}
|
|
7436
|
-
}
|
|
7437
|
-
|
|
7438
|
-
/* eslint-disable no-bitwise */
|
|
7439
|
-
|
|
7440
|
-
// Sadly, the best way to save binary data in WebSQL/localStorage is serializing
|
|
7441
|
-
// it to Base64, so this is how we store it to prevent very strange errors with less
|
|
7442
|
-
// verbose ways of binary <-> string data storage.
|
|
7443
|
-
var BASE_CHARS =
|
|
7444
|
-
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
7445
|
-
|
|
7446
|
-
var BLOB_TYPE_PREFIX = '~~local_forage_type~';
|
|
7447
|
-
var BLOB_TYPE_PREFIX_REGEX = /^~~local_forage_type~([^~]+)~/;
|
|
7448
|
-
|
|
7449
|
-
var SERIALIZED_MARKER = '__lfsc__:';
|
|
7450
|
-
var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length;
|
|
7451
|
-
|
|
7452
|
-
// OMG the serializations!
|
|
7453
|
-
var TYPE_ARRAYBUFFER = 'arbf';
|
|
7454
|
-
var TYPE_BLOB = 'blob';
|
|
7455
|
-
var TYPE_INT8ARRAY = 'si08';
|
|
7456
|
-
var TYPE_UINT8ARRAY = 'ui08';
|
|
7457
|
-
var TYPE_UINT8CLAMPEDARRAY = 'uic8';
|
|
7458
|
-
var TYPE_INT16ARRAY = 'si16';
|
|
7459
|
-
var TYPE_INT32ARRAY = 'si32';
|
|
7460
|
-
var TYPE_UINT16ARRAY = 'ur16';
|
|
7461
|
-
var TYPE_UINT32ARRAY = 'ui32';
|
|
7462
|
-
var TYPE_FLOAT32ARRAY = 'fl32';
|
|
7463
|
-
var TYPE_FLOAT64ARRAY = 'fl64';
|
|
7464
|
-
var TYPE_SERIALIZED_MARKER_LENGTH =
|
|
7465
|
-
SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length;
|
|
7466
|
-
|
|
7467
|
-
var toString = Object.prototype.toString;
|
|
7468
|
-
|
|
7469
|
-
function stringToBuffer(serializedString) {
|
|
7470
|
-
// Fill the string into a ArrayBuffer.
|
|
7471
|
-
var bufferLength = serializedString.length * 0.75;
|
|
7472
|
-
var len = serializedString.length;
|
|
7473
|
-
var i;
|
|
7474
|
-
var p = 0;
|
|
7475
|
-
var encoded1, encoded2, encoded3, encoded4;
|
|
7476
|
-
|
|
7477
|
-
if (serializedString[serializedString.length - 1] === '=') {
|
|
7478
|
-
bufferLength--;
|
|
7479
|
-
if (serializedString[serializedString.length - 2] === '=') {
|
|
7480
|
-
bufferLength--;
|
|
7481
|
-
}
|
|
7482
|
-
}
|
|
7483
|
-
|
|
7484
|
-
var buffer = new ArrayBuffer(bufferLength);
|
|
7485
|
-
var bytes = new Uint8Array(buffer);
|
|
7486
|
-
|
|
7487
|
-
for (i = 0; i < len; i += 4) {
|
|
7488
|
-
encoded1 = BASE_CHARS.indexOf(serializedString[i]);
|
|
7489
|
-
encoded2 = BASE_CHARS.indexOf(serializedString[i + 1]);
|
|
7490
|
-
encoded3 = BASE_CHARS.indexOf(serializedString[i + 2]);
|
|
7491
|
-
encoded4 = BASE_CHARS.indexOf(serializedString[i + 3]);
|
|
7492
|
-
|
|
7493
|
-
/*jslint bitwise: true */
|
|
7494
|
-
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
|
|
7495
|
-
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
|
|
7496
|
-
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
|
|
7497
|
-
}
|
|
7498
|
-
return buffer;
|
|
7422
|
+
return val;
|
|
7423
|
+
});
|
|
7499
7424
|
}
|
|
7500
|
-
|
|
7501
|
-
|
|
7502
|
-
|
|
7503
|
-
function bufferToString(buffer) {
|
|
7504
|
-
// base64-arraybuffer
|
|
7505
|
-
var bytes = new Uint8Array(buffer);
|
|
7506
|
-
var base64String = '';
|
|
7507
|
-
var i;
|
|
7508
|
-
|
|
7509
|
-
for (i = 0; i < bytes.length; i += 3) {
|
|
7510
|
-
/*jslint bitwise: true */
|
|
7511
|
-
base64String += BASE_CHARS[bytes[i] >> 2];
|
|
7512
|
-
base64String += BASE_CHARS[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
|
|
7513
|
-
base64String +=
|
|
7514
|
-
BASE_CHARS[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
|
|
7515
|
-
base64String += BASE_CHARS[bytes[i + 2] & 63];
|
|
7425
|
+
function serialize(value, callback) {
|
|
7426
|
+
try {
|
|
7427
|
+
callback(serializeSync(value), null);
|
|
7516
7428
|
}
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
base64String = base64String.substring(0, base64String.length - 1) + '=';
|
|
7520
|
-
} else if (bytes.length % 3 === 1) {
|
|
7521
|
-
base64String =
|
|
7522
|
-
base64String.substring(0, base64String.length - 2) + '==';
|
|
7429
|
+
catch (e) {
|
|
7430
|
+
callback('', e);
|
|
7523
7431
|
}
|
|
7524
|
-
|
|
7525
|
-
return base64String;
|
|
7526
7432
|
}
|
|
7527
|
-
|
|
7528
|
-
|
|
7529
|
-
// instructs the `setItem()` callback/promise to be executed). This is how
|
|
7530
|
-
// we store binary data with localStorage.
|
|
7531
|
-
function serialize$1(value, callback) {
|
|
7532
|
-
var valueType = '';
|
|
7533
|
-
if (value) {
|
|
7534
|
-
valueType = toString.call(value);
|
|
7535
|
-
}
|
|
7536
|
-
|
|
7537
|
-
// Cannot use `value instanceof ArrayBuffer` or such here, as these
|
|
7538
|
-
// checks fail when running the tests using casper.js...
|
|
7539
|
-
//
|
|
7540
|
-
// TODO: See why those tests fail and use a better solution.
|
|
7541
|
-
if (
|
|
7542
|
-
value &&
|
|
7543
|
-
(valueType === '[object ArrayBuffer]' ||
|
|
7544
|
-
(value.buffer &&
|
|
7545
|
-
toString.call(value.buffer) === '[object ArrayBuffer]'))
|
|
7546
|
-
) {
|
|
7547
|
-
// Convert binary arrays to a string and prefix the string with
|
|
7548
|
-
// a special marker.
|
|
7549
|
-
var buffer;
|
|
7550
|
-
var marker = SERIALIZED_MARKER;
|
|
7551
|
-
|
|
7552
|
-
if (value instanceof ArrayBuffer) {
|
|
7553
|
-
buffer = value;
|
|
7554
|
-
marker += TYPE_ARRAYBUFFER;
|
|
7555
|
-
} else {
|
|
7556
|
-
buffer = value.buffer;
|
|
7557
|
-
|
|
7558
|
-
if (valueType === '[object Int8Array]') {
|
|
7559
|
-
marker += TYPE_INT8ARRAY;
|
|
7560
|
-
} else if (valueType === '[object Uint8Array]') {
|
|
7561
|
-
marker += TYPE_UINT8ARRAY;
|
|
7562
|
-
} else if (valueType === '[object Uint8ClampedArray]') {
|
|
7563
|
-
marker += TYPE_UINT8CLAMPEDARRAY;
|
|
7564
|
-
} else if (valueType === '[object Int16Array]') {
|
|
7565
|
-
marker += TYPE_INT16ARRAY;
|
|
7566
|
-
} else if (valueType === '[object Uint16Array]') {
|
|
7567
|
-
marker += TYPE_UINT16ARRAY;
|
|
7568
|
-
} else if (valueType === '[object Int32Array]') {
|
|
7569
|
-
marker += TYPE_INT32ARRAY;
|
|
7570
|
-
} else if (valueType === '[object Uint32Array]') {
|
|
7571
|
-
marker += TYPE_UINT32ARRAY;
|
|
7572
|
-
} else if (valueType === '[object Float32Array]') {
|
|
7573
|
-
marker += TYPE_FLOAT32ARRAY;
|
|
7574
|
-
} else if (valueType === '[object Float64Array]') {
|
|
7575
|
-
marker += TYPE_FLOAT64ARRAY;
|
|
7576
|
-
} else {
|
|
7577
|
-
callback(new Error('Failed to get type for BinaryArray'));
|
|
7578
|
-
}
|
|
7579
|
-
}
|
|
7580
|
-
|
|
7581
|
-
callback(marker + bufferToString(buffer));
|
|
7582
|
-
} else if (valueType === '[object Blob]') {
|
|
7583
|
-
// Conver the blob to a binaryArray and then to a string.
|
|
7584
|
-
var fileReader = new FileReader();
|
|
7585
|
-
|
|
7586
|
-
fileReader.onload = function() {
|
|
7587
|
-
// Backwards-compatible prefix for the blob type.
|
|
7588
|
-
var str =
|
|
7589
|
-
BLOB_TYPE_PREFIX +
|
|
7590
|
-
value.type +
|
|
7591
|
-
'~' +
|
|
7592
|
-
bufferToString(this.result);
|
|
7593
|
-
|
|
7594
|
-
callback(SERIALIZED_MARKER + TYPE_BLOB + str);
|
|
7595
|
-
};
|
|
7596
|
-
|
|
7597
|
-
fileReader.readAsArrayBuffer(value);
|
|
7598
|
-
} else {
|
|
7599
|
-
try {
|
|
7600
|
-
callback(JSON.stringify(value));
|
|
7601
|
-
} catch (e) {
|
|
7602
|
-
console.error("Couldn't convert value into a JSON string: ", value);
|
|
7603
|
-
|
|
7604
|
-
callback(null, e);
|
|
7605
|
-
}
|
|
7606
|
-
}
|
|
7433
|
+
function deserialize(value) {
|
|
7434
|
+
return JSON.parse(value);
|
|
7607
7435
|
}
|
|
7608
7436
|
|
|
7609
|
-
// Deserialize data we've inserted into a value column/field. We place
|
|
7610
|
-
// special markers into our strings to mark them as encoded; this isn't
|
|
7611
|
-
// as nice as a meta field, but it's the only sane thing we can do whilst
|
|
7612
|
-
// keeping localStorage support intact.
|
|
7613
|
-
//
|
|
7614
|
-
// Oftentimes this will just deserialize JSON content, but if we have a
|
|
7615
|
-
// special marker (SERIALIZED_MARKER, defined above), we will extract
|
|
7616
|
-
// some kind of arraybuffer/binary data/typed array out of the string.
|
|
7617
|
-
function deserialize$1(value) {
|
|
7618
|
-
// If we haven't marked this string as being specially serialized (i.e.
|
|
7619
|
-
// something other than serialized JSON), we can just return it and be
|
|
7620
|
-
// done with it.
|
|
7621
|
-
if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) {
|
|
7622
|
-
return JSON.parse(value);
|
|
7623
|
-
}
|
|
7624
|
-
|
|
7625
|
-
// The following code deals with deserializing some kind of Blob or
|
|
7626
|
-
// TypedArray. First we separate out the type of data we're dealing
|
|
7627
|
-
// with from the data itself.
|
|
7628
|
-
var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH);
|
|
7629
|
-
var type = value.substring(
|
|
7630
|
-
SERIALIZED_MARKER_LENGTH,
|
|
7631
|
-
TYPE_SERIALIZED_MARKER_LENGTH
|
|
7632
|
-
);
|
|
7633
|
-
|
|
7634
|
-
var blobType;
|
|
7635
|
-
// Backwards-compatible blob type serialization strategy.
|
|
7636
|
-
// DBs created with older versions of localForage will simply not have the blob type.
|
|
7637
|
-
if (type === TYPE_BLOB && BLOB_TYPE_PREFIX_REGEX.test(serializedString)) {
|
|
7638
|
-
var matcher = serializedString.match(BLOB_TYPE_PREFIX_REGEX);
|
|
7639
|
-
blobType = matcher[1];
|
|
7640
|
-
serializedString = serializedString.substring(matcher[0].length);
|
|
7641
|
-
}
|
|
7642
|
-
var buffer = stringToBuffer(serializedString);
|
|
7643
|
-
|
|
7644
|
-
// Return the right type based on the code/type set during
|
|
7645
|
-
// serialization.
|
|
7646
|
-
switch (type) {
|
|
7647
|
-
case TYPE_ARRAYBUFFER:
|
|
7648
|
-
return buffer;
|
|
7649
|
-
case TYPE_BLOB:
|
|
7650
|
-
return createBlob([buffer], { type: blobType });
|
|
7651
|
-
case TYPE_INT8ARRAY:
|
|
7652
|
-
return new Int8Array(buffer);
|
|
7653
|
-
case TYPE_UINT8ARRAY:
|
|
7654
|
-
return new Uint8Array(buffer);
|
|
7655
|
-
case TYPE_UINT8CLAMPEDARRAY:
|
|
7656
|
-
return new Uint8ClampedArray(buffer);
|
|
7657
|
-
case TYPE_INT16ARRAY:
|
|
7658
|
-
return new Int16Array(buffer);
|
|
7659
|
-
case TYPE_UINT16ARRAY:
|
|
7660
|
-
return new Uint16Array(buffer);
|
|
7661
|
-
case TYPE_INT32ARRAY:
|
|
7662
|
-
return new Int32Array(buffer);
|
|
7663
|
-
case TYPE_UINT32ARRAY:
|
|
7664
|
-
return new Uint32Array(buffer);
|
|
7665
|
-
case TYPE_FLOAT32ARRAY:
|
|
7666
|
-
return new Float32Array(buffer);
|
|
7667
|
-
case TYPE_FLOAT64ARRAY:
|
|
7668
|
-
return new Float64Array(buffer);
|
|
7669
|
-
default:
|
|
7670
|
-
throw new Error('Unkown type: ' + type);
|
|
7671
|
-
}
|
|
7672
|
-
}
|
|
7673
|
-
|
|
7674
|
-
var localforageSerializer = {
|
|
7675
|
-
serialize: serialize$1,
|
|
7676
|
-
deserialize: deserialize$1};
|
|
7677
|
-
|
|
7678
7437
|
// Copyright 2014 Mozilla
|
|
7679
7438
|
// Copyright 2015 Thodoris Greasidis
|
|
7680
7439
|
// Copyright 2018-2025 JC Brand
|
|
@@ -7690,8 +7449,6 @@ var localforageSerializer = {
|
|
|
7690
7449
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
7691
7450
|
// See the License for the specific language governing permissions and
|
|
7692
7451
|
// limitations under the License.
|
|
7693
|
-
const serialize = localforageSerializer['serialize'];
|
|
7694
|
-
const deserialize = localforageSerializer['deserialize'];
|
|
7695
7452
|
function isSessionStorageValid() {
|
|
7696
7453
|
try {
|
|
7697
7454
|
if (sessionStorage && 'setItem' in sessionStorage) {
|
|
@@ -7737,7 +7494,7 @@ function clear(callback) {
|
|
|
7737
7494
|
}
|
|
7738
7495
|
}
|
|
7739
7496
|
});
|
|
7740
|
-
|
|
7497
|
+
chainCallback(promise, callback);
|
|
7741
7498
|
return promise;
|
|
7742
7499
|
}
|
|
7743
7500
|
function getItem(key, callback) {
|
|
@@ -7753,7 +7510,7 @@ function getItem(key, callback) {
|
|
|
7753
7510
|
}
|
|
7754
7511
|
return null;
|
|
7755
7512
|
});
|
|
7756
|
-
|
|
7513
|
+
chainCallback(promise, callback);
|
|
7757
7514
|
return promise;
|
|
7758
7515
|
}
|
|
7759
7516
|
function iterate(iterator, callback) {
|
|
@@ -7781,7 +7538,7 @@ function iterate(iterator, callback) {
|
|
|
7781
7538
|
}
|
|
7782
7539
|
return;
|
|
7783
7540
|
});
|
|
7784
|
-
|
|
7541
|
+
chainCallback(promise, callback);
|
|
7785
7542
|
return promise;
|
|
7786
7543
|
}
|
|
7787
7544
|
// Same as sessionStorage's key() method, except takes a callback.
|
|
@@ -7801,7 +7558,7 @@ function key(n, callback) {
|
|
|
7801
7558
|
}
|
|
7802
7559
|
return result;
|
|
7803
7560
|
});
|
|
7804
|
-
|
|
7561
|
+
chainCallback(promise, callback);
|
|
7805
7562
|
return promise;
|
|
7806
7563
|
}
|
|
7807
7564
|
function keys(callback) {
|
|
@@ -7817,7 +7574,7 @@ function keys(callback) {
|
|
|
7817
7574
|
}
|
|
7818
7575
|
return keys;
|
|
7819
7576
|
});
|
|
7820
|
-
|
|
7577
|
+
chainCallback(promise, callback);
|
|
7821
7578
|
return promise;
|
|
7822
7579
|
}
|
|
7823
7580
|
// Supply the number of keys in the datastore to the callback function.
|
|
@@ -7826,7 +7583,7 @@ function length(callback) {
|
|
|
7826
7583
|
const promise = self.keys().then(function (keys) {
|
|
7827
7584
|
return keys.length;
|
|
7828
7585
|
});
|
|
7829
|
-
|
|
7586
|
+
chainCallback(promise, callback);
|
|
7830
7587
|
return promise;
|
|
7831
7588
|
}
|
|
7832
7589
|
function removeItem(key, callback) {
|
|
@@ -7834,7 +7591,7 @@ function removeItem(key, callback) {
|
|
|
7834
7591
|
const promise = this.ready().then(function () {
|
|
7835
7592
|
sessionStorage.removeItem(dbInfo.keyPrefix + key);
|
|
7836
7593
|
});
|
|
7837
|
-
|
|
7594
|
+
chainCallback(promise, callback);
|
|
7838
7595
|
return promise;
|
|
7839
7596
|
}
|
|
7840
7597
|
async function setItem(key, value, callback) {
|
|
@@ -7846,27 +7603,27 @@ async function setItem(key, value, callback) {
|
|
|
7846
7603
|
dbInfo.serializer.serialize(value, (serializedValue, error) => {
|
|
7847
7604
|
if (error) {
|
|
7848
7605
|
reject(error);
|
|
7849
|
-
|
|
7606
|
+
chainCallback(Promise.reject(error), callback);
|
|
7850
7607
|
return;
|
|
7851
7608
|
}
|
|
7852
7609
|
try {
|
|
7853
7610
|
sessionStorage.setItem(dbInfo.keyPrefix + key, serializedValue);
|
|
7854
7611
|
resolve(originalValue);
|
|
7855
|
-
|
|
7612
|
+
chainCallback(Promise.resolve(originalValue), callback);
|
|
7856
7613
|
}
|
|
7857
7614
|
catch (e) {
|
|
7858
7615
|
if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {
|
|
7859
7616
|
console.error('Your sessionStorage capacity is used up.');
|
|
7860
7617
|
}
|
|
7861
7618
|
reject(e);
|
|
7862
|
-
|
|
7619
|
+
chainCallback(Promise.reject(e), callback);
|
|
7863
7620
|
}
|
|
7864
7621
|
});
|
|
7865
7622
|
});
|
|
7866
7623
|
}
|
|
7867
|
-
function dropInstance(
|
|
7868
|
-
callback = getCallback
|
|
7869
|
-
options = (typeof
|
|
7624
|
+
function dropInstance(...args) {
|
|
7625
|
+
const callback = getCallback(...args);
|
|
7626
|
+
let options = (typeof args[0] !== 'function' && args[0]) || {};
|
|
7870
7627
|
if (!options.name) {
|
|
7871
7628
|
const currentConfig = this.config();
|
|
7872
7629
|
options.name = options.name || currentConfig.name;
|
|
@@ -7894,7 +7651,7 @@ function dropInstance(options, callback) {
|
|
|
7894
7651
|
}
|
|
7895
7652
|
});
|
|
7896
7653
|
}
|
|
7897
|
-
|
|
7654
|
+
chainCallback(promise, callback);
|
|
7898
7655
|
return promise;
|
|
7899
7656
|
}
|
|
7900
7657
|
const sessionStorageWrapper = {
|
|
@@ -8373,10 +8130,10 @@ function extendPrototype(localforage$$1) {
|
|
|
8373
8130
|
extendPrototype(localForage);
|
|
8374
8131
|
|
|
8375
8132
|
/** Used for built-in method references. */
|
|
8376
|
-
var objectProto$
|
|
8133
|
+
var objectProto$7 = Object.prototype;
|
|
8377
8134
|
|
|
8378
8135
|
/** Used to check objects for own properties. */
|
|
8379
|
-
var hasOwnProperty$
|
|
8136
|
+
var hasOwnProperty$6 = objectProto$7.hasOwnProperty;
|
|
8380
8137
|
|
|
8381
8138
|
/**
|
|
8382
8139
|
* The base implementation of `_.has` without support for deep paths.
|
|
@@ -8387,7 +8144,7 @@ var hasOwnProperty$5 = objectProto$6.hasOwnProperty;
|
|
|
8387
8144
|
* @returns {boolean} Returns `true` if `key` exists, else `false`.
|
|
8388
8145
|
*/
|
|
8389
8146
|
function baseHas(object, key) {
|
|
8390
|
-
return object != null && hasOwnProperty$
|
|
8147
|
+
return object != null && hasOwnProperty$6.call(object, key);
|
|
8391
8148
|
}
|
|
8392
8149
|
|
|
8393
8150
|
/** Used to match property names within property paths. */
|
|
@@ -8544,7 +8301,7 @@ function castPath(value, object) {
|
|
|
8544
8301
|
if (isArray(value)) {
|
|
8545
8302
|
return value;
|
|
8546
8303
|
}
|
|
8547
|
-
return isKey(value, object) ? [value] : stringToPath(toString$
|
|
8304
|
+
return isKey(value, object) ? [value] : stringToPath(toString$1(value));
|
|
8548
8305
|
}
|
|
8549
8306
|
|
|
8550
8307
|
/**
|
|
@@ -8698,16 +8455,18 @@ function getResolveablePromise() {
|
|
|
8698
8455
|
wrapper.reject = reject;
|
|
8699
8456
|
});
|
|
8700
8457
|
Object.assign(promise, wrapper);
|
|
8701
|
-
|
|
8458
|
+
// This `then` only mirrors settlement into the state flags. It must NOT
|
|
8459
|
+
// rethrow on rejection: the derived promise is discarded, so rethrowing would
|
|
8460
|
+
// surface as an unhandled rejection whenever the promise is rejected. The real
|
|
8461
|
+
// consumer still awaits `promise` itself, which rejects normally.
|
|
8462
|
+
promise.then(function () {
|
|
8702
8463
|
promise.isResolved = true;
|
|
8703
8464
|
promise.isPending = false;
|
|
8704
8465
|
promise.isRejected = false;
|
|
8705
|
-
|
|
8706
|
-
}, function (e) {
|
|
8466
|
+
}, function () {
|
|
8707
8467
|
promise.isResolved = false;
|
|
8708
8468
|
promise.isPending = false;
|
|
8709
8469
|
promise.isRejected = true;
|
|
8710
|
-
throw e;
|
|
8711
8470
|
});
|
|
8712
8471
|
return promise;
|
|
8713
8472
|
}
|
|
@@ -8715,13 +8474,16 @@ function getResolveablePromise() {
|
|
|
8715
8474
|
function urlError() {
|
|
8716
8475
|
throw new Error('A "url" property or function must be specified');
|
|
8717
8476
|
}
|
|
8718
|
-
// Wrap an optional error callback with a fallback error event.
|
|
8719
|
-
|
|
8477
|
+
// Wrap an optional error callback with a fallback error event. When a
|
|
8478
|
+
// `promise` is supplied (the `{ promise: true }` fetch/save path), the error is
|
|
8479
|
+
// also forwarded to `promise.reject` so the returned promise settles on failure.
|
|
8480
|
+
function wrapError(model, options, promise) {
|
|
8720
8481
|
const error = options.error;
|
|
8721
8482
|
options.error = function (resp) {
|
|
8722
8483
|
if (error)
|
|
8723
8484
|
error.call(options.context, model, resp, options);
|
|
8724
8485
|
model.trigger('error', model, resp, options);
|
|
8486
|
+
promise && promise.reject && promise.reject(resp);
|
|
8725
8487
|
};
|
|
8726
8488
|
}
|
|
8727
8489
|
// Map from CRUD to HTTP for our default `sync` implementation.
|
|
@@ -8732,8 +8494,44 @@ const methodMap = {
|
|
|
8732
8494
|
delete: 'DELETE',
|
|
8733
8495
|
read: 'GET',
|
|
8734
8496
|
};
|
|
8497
|
+
// Tracks the classes we've already warned about, so the `browserStorage`
|
|
8498
|
+
// deprecation notice is logged at most once per class rather than once per
|
|
8499
|
+
// instance (a collection can resolve storage once per contained model).
|
|
8500
|
+
const warnedBrowserStorage = new WeakSet();
|
|
8501
|
+
/**
|
|
8502
|
+
* Emit a one-time-per-class deprecation warning nudging downstream code from
|
|
8503
|
+
* the `browserStorage` alias to the canonical `storage` accessor.
|
|
8504
|
+
*/
|
|
8505
|
+
function warnBrowserStorageDeprecation(obj) {
|
|
8506
|
+
const ctor = obj?.constructor;
|
|
8507
|
+
if (!ctor || warnedBrowserStorage.has(ctor))
|
|
8508
|
+
return;
|
|
8509
|
+
warnedBrowserStorage.add(ctor);
|
|
8510
|
+
const name = ctor.name;
|
|
8511
|
+
console.warn(`Skeletor: \`browserStorage\` is deprecated and will be removed in a future major version; ` +
|
|
8512
|
+
`use \`storage\` instead${name ? ` (on \`${name}\`)` : ''}.`);
|
|
8513
|
+
}
|
|
8514
|
+
/**
|
|
8515
|
+
* Return the PersistentStorage instance configured on `obj`, checking both
|
|
8516
|
+
* the canonical `storage` accessor and the deprecated `browserStorage` alias
|
|
8517
|
+
* so that subclasses that still override `get browserStorage()` continue to work.
|
|
8518
|
+
* @public
|
|
8519
|
+
*/
|
|
8520
|
+
function getStorage(obj) {
|
|
8521
|
+
if (!obj)
|
|
8522
|
+
return undefined;
|
|
8523
|
+
const storage = result(obj, 'storage');
|
|
8524
|
+
if (storage != null)
|
|
8525
|
+
return storage;
|
|
8526
|
+
// Fall back to the deprecated alias; warn only when it actually supplies the
|
|
8527
|
+
// store, so storage-less models/collections don't trip the notice.
|
|
8528
|
+
const legacy = result(obj, 'browserStorage');
|
|
8529
|
+
if (legacy != null)
|
|
8530
|
+
warnBrowserStorageDeprecation(obj);
|
|
8531
|
+
return legacy;
|
|
8532
|
+
}
|
|
8735
8533
|
function getSyncMethod(model) {
|
|
8736
|
-
const store =
|
|
8534
|
+
const store = getStorage(model) || getStorage(model.collection);
|
|
8737
8535
|
return store ? store.sync() : sync;
|
|
8738
8536
|
}
|
|
8739
8537
|
/**
|
|
@@ -8783,15 +8581,56 @@ const IN_MEMORY = _driver;
|
|
|
8783
8581
|
localForage.defineDriver(memoryDriver);
|
|
8784
8582
|
localforageSetitemsExports.extendPrototype(localForage);
|
|
8785
8583
|
extendPrototype(localForage);
|
|
8584
|
+
// Every storage instance is registered with a WeakRef so that flushAll() can
|
|
8585
|
+
// reach pending writes without keeping instances alive. There's no leak and no
|
|
8586
|
+
// lifecycle hook to maintain: an instance is collected once its owning model or
|
|
8587
|
+
// collection is gone, at which point nothing is writing through it anyway.
|
|
8588
|
+
// Models with a pending debounced save stay reachable via the autosync `pending`
|
|
8589
|
+
// map until the timer fires, so flushAll() always reaches in-flight writes.
|
|
8590
|
+
const weakInstances = new Set();
|
|
8591
|
+
// Tracks which instances already have a WeakRef in `weakInstances`, so repeated
|
|
8592
|
+
// `storage =` assignments (or a store shared across models) don't register the
|
|
8593
|
+
// same instance twice and make flushAll() flush it more than once.
|
|
8594
|
+
const registered = new WeakSet();
|
|
8786
8595
|
/**
|
|
8787
8596
|
* @public
|
|
8788
8597
|
*/
|
|
8789
|
-
class
|
|
8598
|
+
class PersistentStorage {
|
|
8599
|
+
/** Register a storage instance with a weak reference. @public */
|
|
8600
|
+
static register(instance) {
|
|
8601
|
+
if (registered.has(instance))
|
|
8602
|
+
return;
|
|
8603
|
+
registered.add(instance);
|
|
8604
|
+
weakInstances.add(new WeakRef(instance));
|
|
8605
|
+
}
|
|
8606
|
+
/**
|
|
8607
|
+
* Flush the debounced write buffer of every registered PersistentStorage
|
|
8608
|
+
* instance. Called automatically on pagehide/visibilitychange when autoSync
|
|
8609
|
+
* is in use; can also be called manually.
|
|
8610
|
+
* @public
|
|
8611
|
+
*/
|
|
8612
|
+
static flushAll() {
|
|
8613
|
+
for (const ref of weakInstances) {
|
|
8614
|
+
const instance = ref.deref();
|
|
8615
|
+
if (!instance) {
|
|
8616
|
+
weakInstances.delete(ref);
|
|
8617
|
+
}
|
|
8618
|
+
else {
|
|
8619
|
+
instance.flush();
|
|
8620
|
+
}
|
|
8621
|
+
}
|
|
8622
|
+
}
|
|
8790
8623
|
constructor(id, type, batchedWrites = false) {
|
|
8791
|
-
|
|
8624
|
+
// Set once `storeInitialized` resolves. Lets `sync()` skip awaiting it on the
|
|
8625
|
+
// hot path so a save buffers/issues its write *synchronously*, which is what
|
|
8626
|
+
// makes the synchronous unload flush (`flushPending` -> `flushAll`) able to
|
|
8627
|
+
// push a pending write out before the page is torn down.
|
|
8628
|
+
this.storeReady = false;
|
|
8629
|
+
this.name = id;
|
|
8630
|
+
if (type === 'local' && typeof window !== 'undefined' && !window.localStorage) {
|
|
8792
8631
|
throw new Error('Skeletor.storage: Environment does not support localStorage.');
|
|
8793
8632
|
}
|
|
8794
|
-
else if (type === 'session' && !window.sessionStorage) {
|
|
8633
|
+
else if (type === 'session' && typeof window !== 'undefined' && !window.sessionStorage) {
|
|
8795
8634
|
throw new Error('Skeletor.storage: Environment does not support sessionStorage.');
|
|
8796
8635
|
}
|
|
8797
8636
|
if (isString(type)) {
|
|
@@ -8806,10 +8645,13 @@ class BrowserStorage {
|
|
|
8806
8645
|
}
|
|
8807
8646
|
this.storeInitialized = Promise.resolve();
|
|
8808
8647
|
}
|
|
8809
|
-
|
|
8648
|
+
// Flip the synchronous-readiness flag once init settles. Callers that await
|
|
8649
|
+
// `storeInitialized` directly still see any rejection; this branch only
|
|
8650
|
+
// exists to set the flag and must not raise an unhandled rejection.
|
|
8651
|
+
this.storeInitialized.then(() => (this.storeReady = true)).catch(() => { });
|
|
8810
8652
|
}
|
|
8811
8653
|
/**
|
|
8812
|
-
* @param type - The storage type: 'local', 'session', 'indexed', or 'in_memory'
|
|
8654
|
+
* @param type - The storage type: 'local', 'session', 'indexed', 'node', or 'in_memory'
|
|
8813
8655
|
* @param batchedWrites - Whether to enable batched writes
|
|
8814
8656
|
*/
|
|
8815
8657
|
async initStore(type, batchedWrites) {
|
|
@@ -8822,6 +8664,16 @@ class BrowserStorage {
|
|
|
8822
8664
|
else if (type === 'in_memory') {
|
|
8823
8665
|
await localForage.config({ 'driver': IN_MEMORY });
|
|
8824
8666
|
}
|
|
8667
|
+
else if (type === 'node') {
|
|
8668
|
+
const { NodeSQLiteStorage } = await import('./drivers/nodeSQLiteStorage');
|
|
8669
|
+
this.store = new NodeSQLiteStorage(this.name);
|
|
8670
|
+
if (batchedWrites) {
|
|
8671
|
+
this.store.debouncedSetItems = mergebounce((items) => this.store.setItems(items), 50, {
|
|
8672
|
+
'promise': true,
|
|
8673
|
+
});
|
|
8674
|
+
}
|
|
8675
|
+
return;
|
|
8676
|
+
}
|
|
8825
8677
|
else if (type !== 'indexed') {
|
|
8826
8678
|
throw new Error('Skeletor.storage: No storage type was specified');
|
|
8827
8679
|
}
|
|
@@ -8838,6 +8690,7 @@ class BrowserStorage {
|
|
|
8838
8690
|
}
|
|
8839
8691
|
}
|
|
8840
8692
|
async clear() {
|
|
8693
|
+
await this.storeInitialized;
|
|
8841
8694
|
await this.store.removeItem(this.name).catch((e) => console.error(e));
|
|
8842
8695
|
const re = new RegExp(`^${this.name}-`);
|
|
8843
8696
|
const keys = await this.store.keys();
|
|
@@ -8852,12 +8705,16 @@ class BrowserStorage {
|
|
|
8852
8705
|
// We get the collection (and if necessary the model attribute.
|
|
8853
8706
|
// Waiting for storeInitialized will cause another iteration of
|
|
8854
8707
|
// the event loop, after which the collection reference will
|
|
8855
|
-
// be removed from the model.
|
|
8856
|
-
|
|
8708
|
+
// be removed from the model. `options.collection` lets a deferred
|
|
8709
|
+
// delete (sequenced behind an in-flight auto-save by Model.destroy)
|
|
8710
|
+
// supply the collection captured before its optimistic removal.
|
|
8711
|
+
const collection = options.collection ?? model.collection;
|
|
8857
8712
|
if (['patch', 'update'].includes(method)) {
|
|
8858
8713
|
new_attributes = cloneDeep(model.attributes);
|
|
8859
8714
|
}
|
|
8860
|
-
await
|
|
8715
|
+
// Skip `await` if not necessary to allow for sync flushing
|
|
8716
|
+
if (!that.storeReady)
|
|
8717
|
+
await that.storeInitialized;
|
|
8861
8718
|
try {
|
|
8862
8719
|
const original_attributes = model.attributes;
|
|
8863
8720
|
switch (method) {
|
|
@@ -9012,8 +8869,8 @@ class BrowserStorage {
|
|
|
9012
8869
|
return this.name + '-' + id;
|
|
9013
8870
|
}
|
|
9014
8871
|
}
|
|
9015
|
-
|
|
9016
|
-
|
|
8872
|
+
PersistentStorage.sessionStorageInitialized = localForage.defineDriver(sessionStorageWrapper);
|
|
8873
|
+
PersistentStorage.localForage = localForage;
|
|
9017
8874
|
|
|
9018
8875
|
/** Used to compose bitmasks for cloning. */
|
|
9019
8876
|
var CLONE_SYMBOLS_FLAG$1 = 4;
|
|
@@ -9163,7 +9020,7 @@ function setCacheAdd(value) {
|
|
|
9163
9020
|
* @name has
|
|
9164
9021
|
* @memberOf SetCache
|
|
9165
9022
|
* @param {*} value The value to search for.
|
|
9166
|
-
* @returns {
|
|
9023
|
+
* @returns {boolean} Returns `true` if `value` is found, else `false`.
|
|
9167
9024
|
*/
|
|
9168
9025
|
function setCacheHas(value) {
|
|
9169
9026
|
return this.__data__.has(value);
|
|
@@ -9446,10 +9303,10 @@ function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
|
|
|
9446
9303
|
var COMPARE_PARTIAL_FLAG$3 = 1;
|
|
9447
9304
|
|
|
9448
9305
|
/** Used for built-in method references. */
|
|
9449
|
-
var objectProto$
|
|
9306
|
+
var objectProto$6 = Object.prototype;
|
|
9450
9307
|
|
|
9451
9308
|
/** Used to check objects for own properties. */
|
|
9452
|
-
var hasOwnProperty$
|
|
9309
|
+
var hasOwnProperty$5 = objectProto$6.hasOwnProperty;
|
|
9453
9310
|
|
|
9454
9311
|
/**
|
|
9455
9312
|
* A specialized version of `baseIsEqualDeep` for objects with support for
|
|
@@ -9477,7 +9334,7 @@ function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
|
|
|
9477
9334
|
var index = objLength;
|
|
9478
9335
|
while (index--) {
|
|
9479
9336
|
var key = objProps[index];
|
|
9480
|
-
if (!(isPartial ? key in other : hasOwnProperty$
|
|
9337
|
+
if (!(isPartial ? key in other : hasOwnProperty$5.call(other, key))) {
|
|
9481
9338
|
return false;
|
|
9482
9339
|
}
|
|
9483
9340
|
}
|
|
@@ -9538,10 +9395,10 @@ var argsTag = '[object Arguments]',
|
|
|
9538
9395
|
objectTag = '[object Object]';
|
|
9539
9396
|
|
|
9540
9397
|
/** Used for built-in method references. */
|
|
9541
|
-
var objectProto$
|
|
9398
|
+
var objectProto$5 = Object.prototype;
|
|
9542
9399
|
|
|
9543
9400
|
/** Used to check objects for own properties. */
|
|
9544
|
-
var hasOwnProperty$
|
|
9401
|
+
var hasOwnProperty$4 = objectProto$5.hasOwnProperty;
|
|
9545
9402
|
|
|
9546
9403
|
/**
|
|
9547
9404
|
* A specialized version of `baseIsEqual` for arrays and objects which performs
|
|
@@ -9584,8 +9441,8 @@ function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
|
|
|
9584
9441
|
: equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
|
|
9585
9442
|
}
|
|
9586
9443
|
if (!(bitmask & COMPARE_PARTIAL_FLAG$2)) {
|
|
9587
|
-
var objIsWrapped = objIsObj && hasOwnProperty$
|
|
9588
|
-
othIsWrapped = othIsObj && hasOwnProperty$
|
|
9444
|
+
var objIsWrapped = objIsObj && hasOwnProperty$4.call(object, '__wrapped__'),
|
|
9445
|
+
othIsWrapped = othIsObj && hasOwnProperty$4.call(other, '__wrapped__');
|
|
9589
9446
|
|
|
9590
9447
|
if (objIsWrapped || othIsWrapped) {
|
|
9591
9448
|
var objUnwrapped = objIsWrapped ? object.value() : object,
|
|
@@ -9959,10 +9816,10 @@ function createAggregator(setter, initializer) {
|
|
|
9959
9816
|
}
|
|
9960
9817
|
|
|
9961
9818
|
/** Used for built-in method references. */
|
|
9962
|
-
var objectProto$
|
|
9819
|
+
var objectProto$4 = Object.prototype;
|
|
9963
9820
|
|
|
9964
9821
|
/** Used to check objects for own properties. */
|
|
9965
|
-
var hasOwnProperty$
|
|
9822
|
+
var hasOwnProperty$3 = objectProto$4.hasOwnProperty;
|
|
9966
9823
|
|
|
9967
9824
|
/**
|
|
9968
9825
|
* Creates an object composed of keys generated from the results of running
|
|
@@ -9987,7 +9844,7 @@ var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
|
|
|
9987
9844
|
* // => { '3': 2, '5': 1 }
|
|
9988
9845
|
*/
|
|
9989
9846
|
var countBy = createAggregator(function(result, value, key) {
|
|
9990
|
-
if (hasOwnProperty$
|
|
9847
|
+
if (hasOwnProperty$3.call(result, key)) {
|
|
9991
9848
|
++result[key];
|
|
9992
9849
|
} else {
|
|
9993
9850
|
baseAssignValue(result, key, 1);
|
|
@@ -9995,10 +9852,10 @@ var countBy = createAggregator(function(result, value, key) {
|
|
|
9995
9852
|
});
|
|
9996
9853
|
|
|
9997
9854
|
/** Used for built-in method references. */
|
|
9998
|
-
var objectProto$
|
|
9855
|
+
var objectProto$3 = Object.prototype;
|
|
9999
9856
|
|
|
10000
9857
|
/** Used to check objects for own properties. */
|
|
10001
|
-
var hasOwnProperty$
|
|
9858
|
+
var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
|
|
10002
9859
|
|
|
10003
9860
|
/**
|
|
10004
9861
|
* Creates an object composed of keys generated from the results of running
|
|
@@ -10024,7 +9881,7 @@ var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
|
|
|
10024
9881
|
* // => { '3': ['one', 'two'], '5': ['three'] }
|
|
10025
9882
|
*/
|
|
10026
9883
|
var groupBy = createAggregator(function(result, value, key) {
|
|
10027
|
-
if (hasOwnProperty$
|
|
9884
|
+
if (hasOwnProperty$2.call(result, key)) {
|
|
10028
9885
|
result[key].push(value);
|
|
10029
9886
|
} else {
|
|
10030
9887
|
baseAssignValue(result, key, [value]);
|
|
@@ -10241,7 +10098,7 @@ function baseOrderBy(collection, iteratees, orders) {
|
|
|
10241
10098
|
if (isArray(iteratee)) {
|
|
10242
10099
|
return function(value) {
|
|
10243
10100
|
return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
|
|
10244
|
-
}
|
|
10101
|
+
};
|
|
10245
10102
|
}
|
|
10246
10103
|
return iteratee;
|
|
10247
10104
|
});
|
|
@@ -10306,11 +10163,130 @@ var sortBy = baseRest(function(collection, iteratees) {
|
|
|
10306
10163
|
return baseOrderBy(collection, baseFlatten(iteratees), []);
|
|
10307
10164
|
});
|
|
10308
10165
|
|
|
10166
|
+
const pending = new Map();
|
|
10167
|
+
const inFlight = new Set();
|
|
10168
|
+
// Per-object view of `inFlight`, so a caller (notably `Model.destroy`) can
|
|
10169
|
+
// await the saves for a single object without blocking on unrelated writes.
|
|
10170
|
+
const inFlightByObj = new Map();
|
|
10171
|
+
let unloadListenerAttached = false;
|
|
10172
|
+
/**
|
|
10173
|
+
* Execute a save `run` now and track the resulting promise as in-flight until
|
|
10174
|
+
* it settles, both globally (`inFlight`) and per object (`inFlightByObj`), so
|
|
10175
|
+
* `flushPending({ wait: true })` can await every save and `Model.destroy` can
|
|
10176
|
+
* await just its own.
|
|
10177
|
+
*
|
|
10178
|
+
* @internal
|
|
10179
|
+
* @param obj - The owning model/collection (or `null` when the save isn't tied to one).
|
|
10180
|
+
* A rejection is logged and re-surfaced on `obj`'s `error` event.
|
|
10181
|
+
* Called when a debounce timer fires or a flush forces it.
|
|
10182
|
+
*/
|
|
10183
|
+
function fireRun(obj, run) {
|
|
10184
|
+
const p = Promise.resolve(run()).catch((e) => {
|
|
10185
|
+
console.error('Skeletor autoSync save error:', e);
|
|
10186
|
+
// Surface failures that bypassed `options.error` on the model's `error` event,
|
|
10187
|
+
// the same channel storage-layer failures already use. Storage saves route
|
|
10188
|
+
// errors through `options.error` and then resolve, so they never reach this
|
|
10189
|
+
// catch and won't double-emit.
|
|
10190
|
+
obj?.trigger?.('error', obj, e);
|
|
10191
|
+
});
|
|
10192
|
+
inFlight.add(p);
|
|
10193
|
+
let perObj;
|
|
10194
|
+
if (obj) {
|
|
10195
|
+
perObj = inFlightByObj.get(obj);
|
|
10196
|
+
if (!perObj) {
|
|
10197
|
+
perObj = new Set();
|
|
10198
|
+
inFlightByObj.set(obj, perObj);
|
|
10199
|
+
}
|
|
10200
|
+
perObj.add(p);
|
|
10201
|
+
}
|
|
10202
|
+
p.finally(() => {
|
|
10203
|
+
inFlight.delete(p);
|
|
10204
|
+
if (perObj) {
|
|
10205
|
+
perObj.delete(p);
|
|
10206
|
+
if (perObj.size === 0)
|
|
10207
|
+
inFlightByObj.delete(obj);
|
|
10208
|
+
}
|
|
10209
|
+
});
|
|
10210
|
+
}
|
|
10211
|
+
/**
|
|
10212
|
+
* Schedule a debounced auto-save for `obj`. Replaces any pending schedule
|
|
10213
|
+
* for the same object.
|
|
10214
|
+
* @internal
|
|
10215
|
+
*/
|
|
10216
|
+
function scheduleAutoSave(obj, run, delay) {
|
|
10217
|
+
const existing = pending.get(obj);
|
|
10218
|
+
if (existing)
|
|
10219
|
+
clearTimeout(existing.timerId);
|
|
10220
|
+
const timerId = setTimeout(() => {
|
|
10221
|
+
pending.delete(obj);
|
|
10222
|
+
fireRun(obj, run);
|
|
10223
|
+
}, delay);
|
|
10224
|
+
pending.set(obj, { timerId, run });
|
|
10225
|
+
}
|
|
10226
|
+
/**
|
|
10227
|
+
* Cancel any pending auto-save for `obj`.
|
|
10228
|
+
*
|
|
10229
|
+
* This only stops a *pending* (not-yet-fired) debounce timer. A save whose
|
|
10230
|
+
* timer has already fired is in flight and beyond cancellation — sequence
|
|
10231
|
+
* against it with {@link awaitInFlightSaves} instead.
|
|
10232
|
+
* @internal
|
|
10233
|
+
*/
|
|
10234
|
+
function cancelAutoSave(obj) {
|
|
10235
|
+
const existing = pending.get(obj);
|
|
10236
|
+
if (existing) {
|
|
10237
|
+
clearTimeout(existing.timerId);
|
|
10238
|
+
pending.delete(obj);
|
|
10239
|
+
}
|
|
10240
|
+
}
|
|
10241
|
+
/**
|
|
10242
|
+
* Return a promise that settles once every in-flight auto-save for `obj` has
|
|
10243
|
+
* completed, or `null` when none are in flight. `Model.destroy` uses this to
|
|
10244
|
+
* sequence its delete after a save that has already fired, so a late write
|
|
10245
|
+
* cannot land after the delete and resurrect the record.
|
|
10246
|
+
* @internal
|
|
10247
|
+
*/
|
|
10248
|
+
function awaitInFlightSaves(obj) {
|
|
10249
|
+
const set = inFlightByObj.get(obj);
|
|
10250
|
+
if (!set || set.size === 0)
|
|
10251
|
+
return null;
|
|
10252
|
+
return Promise.all([...set]).then(() => undefined);
|
|
10253
|
+
}
|
|
10254
|
+
function flushPending({ storage, wait = false, } = {}) {
|
|
10255
|
+
for (const [obj, { timerId, run }] of pending.entries()) {
|
|
10256
|
+
clearTimeout(timerId);
|
|
10257
|
+
fireRun(obj, run);
|
|
10258
|
+
}
|
|
10259
|
+
pending.clear();
|
|
10260
|
+
if (storage)
|
|
10261
|
+
storage.flushAll();
|
|
10262
|
+
if (wait)
|
|
10263
|
+
return Promise.all([...inFlight]).then(() => undefined);
|
|
10264
|
+
}
|
|
10265
|
+
/**
|
|
10266
|
+
* Lazily attach pagehide/visibilitychange listeners in browser environments
|
|
10267
|
+
* to flush pending writes when the page is hidden/unloading. This is a
|
|
10268
|
+
* best-effort durability measure: the flush initiates writes synchronously but
|
|
10269
|
+
* cannot guarantee an asynchronous backend finishes persisting them before the
|
|
10270
|
+
* page goes away. Called at most once.
|
|
10271
|
+
* @internal
|
|
10272
|
+
*/
|
|
10273
|
+
function ensureUnloadListener(storage) {
|
|
10274
|
+
if (unloadListenerAttached || typeof window === 'undefined')
|
|
10275
|
+
return;
|
|
10276
|
+
unloadListenerAttached = true;
|
|
10277
|
+
const flush = () => flushPending({ storage });
|
|
10278
|
+
window.addEventListener('pagehide', flush);
|
|
10279
|
+
window.addEventListener('visibilitychange', () => {
|
|
10280
|
+
if (document.visibilityState === 'hidden')
|
|
10281
|
+
flush();
|
|
10282
|
+
});
|
|
10283
|
+
}
|
|
10284
|
+
|
|
10309
10285
|
/** Used for built-in method references. */
|
|
10310
|
-
var objectProto$
|
|
10286
|
+
var objectProto$2 = Object.prototype;
|
|
10311
10287
|
|
|
10312
10288
|
/** Used to check objects for own properties. */
|
|
10313
|
-
var hasOwnProperty = objectProto$
|
|
10289
|
+
var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
|
|
10314
10290
|
|
|
10315
10291
|
/**
|
|
10316
10292
|
* Assigns own and inherited enumerable string keyed properties of source
|
|
@@ -10355,7 +10331,7 @@ var defaults = baseRest(function(object, sources) {
|
|
|
10355
10331
|
var value = object[key];
|
|
10356
10332
|
|
|
10357
10333
|
if (value === undefined ||
|
|
10358
|
-
(eq(value, objectProto$
|
|
10334
|
+
(eq(value, objectProto$2[key]) && !hasOwnProperty$1.call(object, key))) {
|
|
10359
10335
|
object[key] = source[key];
|
|
10360
10336
|
}
|
|
10361
10337
|
}
|
|
@@ -10439,14 +10415,14 @@ function createInverter(setter, toIteratee) {
|
|
|
10439
10415
|
}
|
|
10440
10416
|
|
|
10441
10417
|
/** Used for built-in method references. */
|
|
10442
|
-
var objectProto = Object.prototype;
|
|
10418
|
+
var objectProto$1 = Object.prototype;
|
|
10443
10419
|
|
|
10444
10420
|
/**
|
|
10445
10421
|
* Used to resolve the
|
|
10446
10422
|
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
10447
10423
|
* of values.
|
|
10448
10424
|
*/
|
|
10449
|
-
var nativeObjectToString = objectProto.toString;
|
|
10425
|
+
var nativeObjectToString = objectProto$1.toString;
|
|
10450
10426
|
|
|
10451
10427
|
/**
|
|
10452
10428
|
* Creates an object composed of the inverted keys and values of `object`.
|
|
@@ -10617,6 +10593,12 @@ function parent(object, path) {
|
|
|
10617
10593
|
return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
|
|
10618
10594
|
}
|
|
10619
10595
|
|
|
10596
|
+
/** Used for built-in method references. */
|
|
10597
|
+
var objectProto = Object.prototype;
|
|
10598
|
+
|
|
10599
|
+
/** Used to check objects for own properties. */
|
|
10600
|
+
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
10601
|
+
|
|
10620
10602
|
/**
|
|
10621
10603
|
* The base implementation of `_.unset`.
|
|
10622
10604
|
*
|
|
@@ -10627,8 +10609,34 @@ function parent(object, path) {
|
|
|
10627
10609
|
*/
|
|
10628
10610
|
function baseUnset(object, path) {
|
|
10629
10611
|
path = castPath(path, object);
|
|
10630
|
-
|
|
10631
|
-
|
|
10612
|
+
|
|
10613
|
+
// Prevent prototype pollution:
|
|
10614
|
+
// https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
|
|
10615
|
+
// https://github.com/lodash/lodash/security/advisories/GHSA-f23m-r3pf-42rh
|
|
10616
|
+
var index = -1,
|
|
10617
|
+
length = path.length;
|
|
10618
|
+
|
|
10619
|
+
if (!length) {
|
|
10620
|
+
return true;
|
|
10621
|
+
}
|
|
10622
|
+
|
|
10623
|
+
while (++index < length) {
|
|
10624
|
+
var key = toKey(path[index]);
|
|
10625
|
+
|
|
10626
|
+
// Always block "__proto__" anywhere in the path if it's not expected
|
|
10627
|
+
if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
|
|
10628
|
+
return false;
|
|
10629
|
+
}
|
|
10630
|
+
|
|
10631
|
+
// Block constructor/prototype as non-terminal traversal keys to prevent
|
|
10632
|
+
// escaping the object graph into built-in constructors and prototypes.
|
|
10633
|
+
if ((key === 'constructor' || key === 'prototype') && index < length - 1) {
|
|
10634
|
+
return false;
|
|
10635
|
+
}
|
|
10636
|
+
}
|
|
10637
|
+
|
|
10638
|
+
var obj = parent(object, path);
|
|
10639
|
+
return obj == null || delete obj[toKey(last(path))];
|
|
10632
10640
|
}
|
|
10633
10641
|
|
|
10634
10642
|
/**
|
|
@@ -10826,6 +10834,7 @@ var pick = flatRest(function(object, paths) {
|
|
|
10826
10834
|
return object == null ? {} : basePick(object, paths);
|
|
10827
10835
|
});
|
|
10828
10836
|
|
|
10837
|
+
var _Model_instances, _Model_computedCache, _Model_computedDefs, _Model_state, _Model_hydrate, _Model_doAutoSave, _Model_updateComputed, _Model_initComputed;
|
|
10829
10838
|
/**
|
|
10830
10839
|
* @public
|
|
10831
10840
|
* **Models** are the basic data object in the framework --
|
|
@@ -10840,6 +10849,10 @@ class Model extends EventEmitterObject {
|
|
|
10840
10849
|
*/
|
|
10841
10850
|
constructor(attributes, options) {
|
|
10842
10851
|
super();
|
|
10852
|
+
_Model_instances.add(this);
|
|
10853
|
+
_Model_computedCache.set(this, void 0);
|
|
10854
|
+
_Model_computedDefs.set(this, void 0);
|
|
10855
|
+
_Model_state.set(this, 'constructing');
|
|
10843
10856
|
this._changing = false;
|
|
10844
10857
|
this._pending = false;
|
|
10845
10858
|
this._url = '';
|
|
@@ -10857,15 +10870,74 @@ class Model extends EventEmitterObject {
|
|
|
10857
10870
|
const default_attrs = result(this, 'defaults');
|
|
10858
10871
|
attrs = defaults(Object.assign({}, default_attrs, attrs), default_attrs);
|
|
10859
10872
|
this.set(attrs, options);
|
|
10873
|
+
__classPrivateFieldGet(this, _Model_instances, "m", _Model_initComputed).call(this);
|
|
10874
|
+
this.attrs = new Proxy(this.attributes, {
|
|
10875
|
+
get: (_target, key) => {
|
|
10876
|
+
if (typeof key !== 'symbol' && __classPrivateFieldGet(this, _Model_computedCache, "f") && key in __classPrivateFieldGet(this, _Model_computedCache, "f")) {
|
|
10877
|
+
return __classPrivateFieldGet(this, _Model_computedCache, "f")[key];
|
|
10878
|
+
}
|
|
10879
|
+
return this.attributes[key];
|
|
10880
|
+
},
|
|
10881
|
+
set: (_target, key, value) => {
|
|
10882
|
+
this.set(key, value);
|
|
10883
|
+
return true;
|
|
10884
|
+
},
|
|
10885
|
+
});
|
|
10860
10886
|
this.initialize.apply(this, arguments);
|
|
10861
10887
|
// Reset changed after initial set
|
|
10862
10888
|
this.changed = {};
|
|
10889
|
+
// When autoSync is on, `initialized` is always a Promise so callers can
|
|
10890
|
+
// uniformly `await model.initialized`. It only hydrates from storage when
|
|
10891
|
+
// there's something to load (storage configured and the model isn't new);
|
|
10892
|
+
// otherwise it's already ready and resolves immediately.
|
|
10893
|
+
if (this.autoSync) {
|
|
10894
|
+
if (getStorage(this) && !this.isNew()) {
|
|
10895
|
+
__classPrivateFieldSet(this, _Model_state, 'hydrating', "f");
|
|
10896
|
+
this.initialized = __classPrivateFieldGet(this, _Model_instances, "m", _Model_hydrate).call(this);
|
|
10897
|
+
}
|
|
10898
|
+
else {
|
|
10899
|
+
__classPrivateFieldSet(this, _Model_state, 'ready', "f");
|
|
10900
|
+
this.initialized = Promise.resolve();
|
|
10901
|
+
}
|
|
10902
|
+
}
|
|
10903
|
+
else {
|
|
10904
|
+
__classPrivateFieldSet(this, _Model_state, 'ready', "f");
|
|
10905
|
+
}
|
|
10906
|
+
}
|
|
10907
|
+
/**
|
|
10908
|
+
* The canonical storage accessor. Set to a `PersistentStorage` instance
|
|
10909
|
+
* to enable local persistence for this model.
|
|
10910
|
+
*/
|
|
10911
|
+
get storage() {
|
|
10912
|
+
return this._storage;
|
|
10863
10913
|
}
|
|
10864
|
-
set
|
|
10865
|
-
this.
|
|
10914
|
+
set storage(s) {
|
|
10915
|
+
this._storage = s;
|
|
10916
|
+
PersistentStorage.register(s);
|
|
10866
10917
|
}
|
|
10918
|
+
/**
|
|
10919
|
+
* @deprecated Use `storage` instead.
|
|
10920
|
+
*/
|
|
10867
10921
|
get browserStorage() {
|
|
10868
|
-
return this.
|
|
10922
|
+
return this._storage;
|
|
10923
|
+
}
|
|
10924
|
+
set browserStorage(s) {
|
|
10925
|
+
warnBrowserStorageDeprecation(this);
|
|
10926
|
+
this.storage = s;
|
|
10927
|
+
}
|
|
10928
|
+
/**
|
|
10929
|
+
* Override to enable automatic persistence. When true, any `set()` call
|
|
10930
|
+
* that changes attributes will schedule a debounced save to `storage`, and
|
|
10931
|
+
* the model will auto-hydrate from storage on construction.
|
|
10932
|
+
*/
|
|
10933
|
+
get autoSync() {
|
|
10934
|
+
return false;
|
|
10935
|
+
}
|
|
10936
|
+
/**
|
|
10937
|
+
* Debounce delay (ms) for auto-save writes. Override to tune.
|
|
10938
|
+
*/
|
|
10939
|
+
get autoSyncDelay() {
|
|
10940
|
+
return 100;
|
|
10869
10941
|
}
|
|
10870
10942
|
/**
|
|
10871
10943
|
* The default name for the JSON `id` attribute is `"id"`. MongoDB and
|
|
@@ -10901,6 +10973,17 @@ class Model extends EventEmitterObject {
|
|
|
10901
10973
|
defaults() {
|
|
10902
10974
|
return {};
|
|
10903
10975
|
}
|
|
10976
|
+
/**
|
|
10977
|
+
* Declare computed properties. Override in subclasses to define properties
|
|
10978
|
+
* that derive their value from other attributes. Each entry specifies the
|
|
10979
|
+
* attribute keys it depends on (`deps`) and a function (`fn`) that receives
|
|
10980
|
+
* the model and returns the computed value. The value is cached and
|
|
10981
|
+
* recalculated automatically when any dep changes, firing a `change:key`
|
|
10982
|
+
* event.
|
|
10983
|
+
*/
|
|
10984
|
+
get computed() {
|
|
10985
|
+
return {};
|
|
10986
|
+
}
|
|
10904
10987
|
/**
|
|
10905
10988
|
* Return a copy of the model's `attributes` object.
|
|
10906
10989
|
*/
|
|
@@ -10914,9 +10997,12 @@ class Model extends EventEmitterObject {
|
|
|
10914
10997
|
return getSyncMethod(model)(method, model, options);
|
|
10915
10998
|
}
|
|
10916
10999
|
/**
|
|
10917
|
-
* Get the value of an attribute.
|
|
11000
|
+
* Get the value of an attribute, or a computed property.
|
|
10918
11001
|
*/
|
|
10919
11002
|
get(attr) {
|
|
11003
|
+
if (__classPrivateFieldGet(this, _Model_computedCache, "f") && attr in __classPrivateFieldGet(this, _Model_computedCache, "f")) {
|
|
11004
|
+
return __classPrivateFieldGet(this, _Model_computedCache, "f")[attr];
|
|
11005
|
+
}
|
|
10920
11006
|
return this.attributes[attr];
|
|
10921
11007
|
}
|
|
10922
11008
|
keys() {
|
|
@@ -10981,6 +11067,11 @@ class Model extends EventEmitterObject {
|
|
|
10981
11067
|
attrs[key] = val;
|
|
10982
11068
|
}
|
|
10983
11069
|
options = options || {};
|
|
11070
|
+
// Guard must come after arg normalization: when called as set(obj, opts),
|
|
11071
|
+
// fromStorage lives in `val` (second arg), not `options` (third arg).
|
|
11072
|
+
if (this.autoSync && __classPrivateFieldGet(this, _Model_state, "f") === 'hydrating' && !options.fromStorage) {
|
|
11073
|
+
throw new Error(`Skeletor: set() called on an autoSync model before initialized resolved. Await model.initialized first.`);
|
|
11074
|
+
}
|
|
10984
11075
|
// Run validation.
|
|
10985
11076
|
if (!this._validate(attrs, options))
|
|
10986
11077
|
return null;
|
|
@@ -11021,6 +11112,14 @@ class Model extends EventEmitterObject {
|
|
|
11021
11112
|
this.trigger('change:' + changes[i], this, current[changes[i]], options);
|
|
11022
11113
|
}
|
|
11023
11114
|
}
|
|
11115
|
+
// Recalculate computed properties whose deps changed.
|
|
11116
|
+
if (changes.length && __classPrivateFieldGet(this, _Model_computedDefs, "f")) {
|
|
11117
|
+
for (const [key, def] of Object.entries(__classPrivateFieldGet(this, _Model_computedDefs, "f"))) {
|
|
11118
|
+
if (def.deps.some((dep) => changes.includes(dep))) {
|
|
11119
|
+
__classPrivateFieldGet(this, _Model_instances, "m", _Model_updateComputed).call(this, key, def, silent, options);
|
|
11120
|
+
}
|
|
11121
|
+
}
|
|
11122
|
+
}
|
|
11024
11123
|
if (changing)
|
|
11025
11124
|
return this;
|
|
11026
11125
|
if (!silent) {
|
|
@@ -11034,6 +11133,17 @@ class Model extends EventEmitterObject {
|
|
|
11034
11133
|
}
|
|
11035
11134
|
this._pending = false;
|
|
11036
11135
|
this._changing = false;
|
|
11136
|
+
// Auto-save: schedule a debounced write when autoSync is on and there
|
|
11137
|
+
// were actual changes that originated from application code (not a
|
|
11138
|
+
// storage read or an explicit noAutoSave call).
|
|
11139
|
+
if (__classPrivateFieldGet(this, _Model_state, "f") === 'ready' &&
|
|
11140
|
+
this.autoSync &&
|
|
11141
|
+
getStorage(this) &&
|
|
11142
|
+
changes.length &&
|
|
11143
|
+
!options.fromStorage &&
|
|
11144
|
+
!options.noAutoSave) {
|
|
11145
|
+
scheduleAutoSave(this, () => __classPrivateFieldGet(this, _Model_instances, "m", _Model_doAutoSave).call(this), this.autoSyncDelay);
|
|
11146
|
+
}
|
|
11037
11147
|
return this;
|
|
11038
11148
|
}
|
|
11039
11149
|
/**
|
|
@@ -11108,16 +11218,48 @@ class Model extends EventEmitterObject {
|
|
|
11108
11218
|
fetch(options = {}) {
|
|
11109
11219
|
options = Object.assign({ parse: true }, options);
|
|
11110
11220
|
const success = options.success;
|
|
11221
|
+
const promise = options.promise ? getResolveablePromise() : undefined;
|
|
11222
|
+
// Tracks whether sync invoked one of the callbacks. A sync may instead
|
|
11223
|
+
// settle its returned promise; the `.then`/`.catch` below bridges that to
|
|
11224
|
+
// the callbacks so the fetch promise never hangs. The flag is set
|
|
11225
|
+
// synchronously inside each callback (before sync's promise resolves), so
|
|
11226
|
+
// it's reliable by the time those handlers run.
|
|
11227
|
+
let settled = false;
|
|
11111
11228
|
options.success = (resp) => {
|
|
11229
|
+
settled = true;
|
|
11112
11230
|
const serverAttrs = options.parse ? this.parse(resp, options) : resp;
|
|
11113
|
-
|
|
11231
|
+
// fromStorage prevents the set() from triggering auto-save on reads
|
|
11232
|
+
if (!this.set(serverAttrs, Object.assign({}, options, { fromStorage: true })))
|
|
11114
11233
|
return false;
|
|
11115
11234
|
if (success)
|
|
11116
11235
|
success.call(options.context, this, resp, options);
|
|
11117
11236
|
this.trigger('sync', this, resp, options);
|
|
11237
|
+
promise && promise.resolve(resp);
|
|
11118
11238
|
};
|
|
11119
|
-
wrapError(this, options);
|
|
11120
|
-
|
|
11239
|
+
wrapError(this, options, promise);
|
|
11240
|
+
if (promise) {
|
|
11241
|
+
const onError = options.error;
|
|
11242
|
+
options.error = (resp) => {
|
|
11243
|
+
settled = true;
|
|
11244
|
+
onError(resp);
|
|
11245
|
+
};
|
|
11246
|
+
}
|
|
11247
|
+
const result = this.sync('read', this, options);
|
|
11248
|
+
if (promise) {
|
|
11249
|
+
Promise.resolve(result).then(
|
|
11250
|
+
// A sync that resolves its promise without invoking options.success:
|
|
11251
|
+
// treat the resolved value as the response, so the model is still
|
|
11252
|
+
// merged and the promise settles instead of hanging.
|
|
11253
|
+
(value) => {
|
|
11254
|
+
if (!settled)
|
|
11255
|
+
options.success(value);
|
|
11256
|
+
},
|
|
11257
|
+
// A sync that rejects instead of invoking options.error; settling
|
|
11258
|
+
// twice is a harmless no-op.
|
|
11259
|
+
(e) => promise.reject(e));
|
|
11260
|
+
return promise;
|
|
11261
|
+
}
|
|
11262
|
+
return result;
|
|
11121
11263
|
}
|
|
11122
11264
|
/**
|
|
11123
11265
|
* Set a hash of model attributes, and sync the model to the server.
|
|
@@ -11194,6 +11336,7 @@ class Model extends EventEmitterObject {
|
|
|
11194
11336
|
* If `wait: true` is passed, waits for the server to respond before removal.
|
|
11195
11337
|
*/
|
|
11196
11338
|
destroy(options) {
|
|
11339
|
+
cancelAutoSave(this);
|
|
11197
11340
|
options = options ? clone(options) : {};
|
|
11198
11341
|
const success = options.success;
|
|
11199
11342
|
const wait = options.wait;
|
|
@@ -11209,13 +11352,25 @@ class Model extends EventEmitterObject {
|
|
|
11209
11352
|
if (!this.isNew())
|
|
11210
11353
|
this.trigger('sync', this, resp, options);
|
|
11211
11354
|
};
|
|
11355
|
+
// A debounced auto-save may already have fired and be in flight.
|
|
11356
|
+
// cancelAutoSave() above only stops a *pending* timer, so sequence the
|
|
11357
|
+
// delete after any in-flight save; otherwise the late write could land
|
|
11358
|
+
// after the delete and resurrect the record. Capture the collection now,
|
|
11359
|
+
// the optimistic in-memory removal below nulls `model.collection` before
|
|
11360
|
+
// the deferred sync runs, but the storage layer still needs it to drop
|
|
11361
|
+
// this id from the collection's persisted index.
|
|
11362
|
+
const inFlightSave = awaitInFlightSaves(this);
|
|
11363
|
+
if (inFlightSave && this.collection)
|
|
11364
|
+
options.collection = this.collection;
|
|
11212
11365
|
let xhr = false;
|
|
11213
11366
|
if (this.isNew()) {
|
|
11214
11367
|
defer(options.success);
|
|
11215
11368
|
}
|
|
11216
11369
|
else {
|
|
11217
11370
|
wrapError(this, options);
|
|
11218
|
-
xhr =
|
|
11371
|
+
xhr = inFlightSave
|
|
11372
|
+
? inFlightSave.then(() => this.sync('delete', this, options))
|
|
11373
|
+
: this.sync('delete', this, options);
|
|
11219
11374
|
}
|
|
11220
11375
|
if (!wait)
|
|
11221
11376
|
destroy();
|
|
@@ -11263,6 +11418,14 @@ class Model extends EventEmitterObject {
|
|
|
11263
11418
|
isValid(options) {
|
|
11264
11419
|
return this._validate({}, Object.assign({}, options, { validate: true }));
|
|
11265
11420
|
}
|
|
11421
|
+
subscribe(eventOrCallback, callback, context) {
|
|
11422
|
+
if (typeof eventOrCallback === 'function') {
|
|
11423
|
+
const cb = (model) => eventOrCallback(model, this.changed);
|
|
11424
|
+
this.on('change', cb);
|
|
11425
|
+
return () => this.off('change', cb);
|
|
11426
|
+
}
|
|
11427
|
+
return super.subscribe(eventOrCallback, callback, context);
|
|
11428
|
+
}
|
|
11266
11429
|
/**
|
|
11267
11430
|
* Run validation against the next complete set of model attributes,
|
|
11268
11431
|
* returning `true` if all is well. Otherwise, fire an `"invalid"` event.
|
|
@@ -11278,8 +11441,43 @@ class Model extends EventEmitterObject {
|
|
|
11278
11441
|
return false;
|
|
11279
11442
|
}
|
|
11280
11443
|
}
|
|
11444
|
+
_Model_computedCache = new WeakMap(), _Model_computedDefs = new WeakMap(), _Model_state = new WeakMap(), _Model_instances = new WeakSet(), _Model_hydrate = async function _Model_hydrate() {
|
|
11445
|
+
ensureUnloadListener(PersistentStorage);
|
|
11446
|
+
try {
|
|
11447
|
+
await this.fetch({ fromStorage: true, promise: true });
|
|
11448
|
+
}
|
|
11449
|
+
catch (e) {
|
|
11450
|
+
// 'Record Not Found' is a normal first-run state (nothing stored yet);
|
|
11451
|
+
// keep the initial attributes and resolve. Re-throw anything else.
|
|
11452
|
+
if (e !== 'Record Not Found')
|
|
11453
|
+
throw e;
|
|
11454
|
+
}
|
|
11455
|
+
finally {
|
|
11456
|
+
__classPrivateFieldSet(this, _Model_state, 'ready', "f");
|
|
11457
|
+
}
|
|
11458
|
+
}, _Model_doAutoSave = function _Model_doAutoSave() {
|
|
11459
|
+
return this.save(null, { noAutoSave: true });
|
|
11460
|
+
}, _Model_updateComputed = function _Model_updateComputed(key, def, silent, options) {
|
|
11461
|
+
const newVal = def.fn(this);
|
|
11462
|
+
if (!isEqual(__classPrivateFieldGet(this, _Model_computedCache, "f")[key], newVal)) {
|
|
11463
|
+
__classPrivateFieldGet(this, _Model_computedCache, "f")[key] = newVal;
|
|
11464
|
+
if (!silent) {
|
|
11465
|
+
this.changed[key] = newVal;
|
|
11466
|
+
this.trigger('change:' + key, this, newVal, options);
|
|
11467
|
+
}
|
|
11468
|
+
}
|
|
11469
|
+
}, _Model_initComputed = function _Model_initComputed() {
|
|
11470
|
+
const defs = result(this, 'computed');
|
|
11471
|
+
if (!defs || isEmpty(defs))
|
|
11472
|
+
return;
|
|
11473
|
+
__classPrivateFieldSet(this, _Model_computedDefs, defs, "f");
|
|
11474
|
+
__classPrivateFieldSet(this, _Model_computedCache, {}, "f");
|
|
11475
|
+
for (const [key, def] of Object.entries(defs)) {
|
|
11476
|
+
__classPrivateFieldGet(this, _Model_computedCache, "f")[key] = def.fn(this);
|
|
11477
|
+
}
|
|
11478
|
+
};
|
|
11281
11479
|
|
|
11282
|
-
var _a;
|
|
11480
|
+
var _Collection_instances, _Collection_hydrate, _a;
|
|
11283
11481
|
// Default options for `Collection#set`.
|
|
11284
11482
|
const setOptions = { add: true, remove: true, merge: true };
|
|
11285
11483
|
const addOptions = { add: true, remove: false };
|
|
@@ -11300,6 +11498,7 @@ class Collection extends EventEmitterObject {
|
|
|
11300
11498
|
*/
|
|
11301
11499
|
constructor(models, options) {
|
|
11302
11500
|
super();
|
|
11501
|
+
_Collection_instances.add(this);
|
|
11303
11502
|
this._url = '';
|
|
11304
11503
|
/**
|
|
11305
11504
|
* @public
|
|
@@ -11317,6 +11516,12 @@ class Collection extends EventEmitterObject {
|
|
|
11317
11516
|
if (models)
|
|
11318
11517
|
this.reset(models, Object.assign({ silent: true }, options));
|
|
11319
11518
|
this[Symbol.iterator] = this.values;
|
|
11519
|
+
// When autoSync is on, `initialized` is always a Promise so callers can
|
|
11520
|
+
// uniformly `await collection.initialized`; it resolves immediately when
|
|
11521
|
+
// there's no storage to hydrate from.
|
|
11522
|
+
if (this.autoSync) {
|
|
11523
|
+
this.initialized = getStorage(this) ? __classPrivateFieldGet(this, _Collection_instances, "m", _Collection_hydrate).call(this) : Promise.resolve();
|
|
11524
|
+
}
|
|
11320
11525
|
}
|
|
11321
11526
|
get comparator() {
|
|
11322
11527
|
return this._comparator;
|
|
@@ -11324,11 +11529,40 @@ class Collection extends EventEmitterObject {
|
|
|
11324
11529
|
set comparator(c) {
|
|
11325
11530
|
this._comparator = c;
|
|
11326
11531
|
}
|
|
11327
|
-
|
|
11328
|
-
|
|
11532
|
+
/**
|
|
11533
|
+
* The canonical storage accessor. Set to a `PersistentStorage` instance
|
|
11534
|
+
* to enable local persistence for this collection.
|
|
11535
|
+
*/
|
|
11536
|
+
get storage() {
|
|
11537
|
+
return this._storage;
|
|
11538
|
+
}
|
|
11539
|
+
set storage(s) {
|
|
11540
|
+
this._storage = s;
|
|
11541
|
+
PersistentStorage.register(s);
|
|
11329
11542
|
}
|
|
11543
|
+
/**
|
|
11544
|
+
* @deprecated Use `storage` instead.
|
|
11545
|
+
*/
|
|
11330
11546
|
get browserStorage() {
|
|
11331
|
-
return this.
|
|
11547
|
+
return this._storage;
|
|
11548
|
+
}
|
|
11549
|
+
set browserStorage(s) {
|
|
11550
|
+
warnBrowserStorageDeprecation(this);
|
|
11551
|
+
this.storage = s;
|
|
11552
|
+
}
|
|
11553
|
+
/**
|
|
11554
|
+
* Override to return `true` to automatically load the collection from
|
|
11555
|
+
* storage on construction. Await `initialized` to know when hydration
|
|
11556
|
+
* is complete.
|
|
11557
|
+
*
|
|
11558
|
+
* Note: collection `autoSync` is hydrate-only. Unlike `Model`, it does
|
|
11559
|
+
* **not** schedule auto-saves when the collection changes (`add`/`remove`/
|
|
11560
|
+
* `reset`). Persisting members is each model's responsibility — enable
|
|
11561
|
+
* `autoSync` on the contained model class and every model writes its own
|
|
11562
|
+
* record. A collection-level write would be redundant with that.
|
|
11563
|
+
*/
|
|
11564
|
+
get autoSync() {
|
|
11565
|
+
return false;
|
|
11332
11566
|
}
|
|
11333
11567
|
/**
|
|
11334
11568
|
* The default model for a collection is just a **Model**.
|
|
@@ -11523,7 +11757,7 @@ class Collection extends EventEmitterObject {
|
|
|
11523
11757
|
}));
|
|
11524
11758
|
});
|
|
11525
11759
|
}));
|
|
11526
|
-
await this
|
|
11760
|
+
await getStorage(this)?.clear();
|
|
11527
11761
|
this.reset();
|
|
11528
11762
|
}
|
|
11529
11763
|
/**
|
|
@@ -11761,17 +11995,47 @@ class Collection extends EventEmitterObject {
|
|
|
11761
11995
|
const success = options.success;
|
|
11762
11996
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
11763
11997
|
const collection = this;
|
|
11764
|
-
const promise = options.promise
|
|
11998
|
+
const promise = options.promise ? getResolveablePromise() : undefined;
|
|
11999
|
+
// Tracks whether sync invoked one of the callbacks. A sync may instead
|
|
12000
|
+
// settle its returned promise; the `.then`/`.catch` below bridges that to
|
|
12001
|
+
// the callbacks so the fetch promise never hangs. The flag is set
|
|
12002
|
+
// synchronously inside each callback (before sync's promise resolves), so
|
|
12003
|
+
// it's reliable by the time those handlers run.
|
|
12004
|
+
let settled = false;
|
|
11765
12005
|
options.success = function (resp) {
|
|
12006
|
+
settled = true;
|
|
11766
12007
|
const method = options.reset ? 'reset' : 'set';
|
|
11767
|
-
|
|
12008
|
+
// fromStorage prevents individual model set() calls from triggering auto-save on reads
|
|
12009
|
+
collection[method](resp, Object.assign({}, options, { fromStorage: true }));
|
|
11768
12010
|
if (success)
|
|
11769
12011
|
success.call(options.context, collection, resp, options);
|
|
11770
12012
|
promise && promise.resolve();
|
|
11771
12013
|
collection.trigger('sync', collection, resp, options);
|
|
11772
12014
|
};
|
|
11773
|
-
wrapError(this, options);
|
|
11774
|
-
|
|
12015
|
+
wrapError(this, options, promise);
|
|
12016
|
+
if (promise) {
|
|
12017
|
+
const onError = options.error;
|
|
12018
|
+
options.error = (resp) => {
|
|
12019
|
+
settled = true;
|
|
12020
|
+
onError(resp);
|
|
12021
|
+
};
|
|
12022
|
+
}
|
|
12023
|
+
const result = this.sync('read', this, options);
|
|
12024
|
+
if (promise) {
|
|
12025
|
+
Promise.resolve(result).then(
|
|
12026
|
+
// A sync that resolves its promise without invoking options.success:
|
|
12027
|
+
// treat the resolved value as the response, so the collection is still
|
|
12028
|
+
// populated and the promise settles instead of hanging.
|
|
12029
|
+
(value) => {
|
|
12030
|
+
if (!settled)
|
|
12031
|
+
options.success(value);
|
|
12032
|
+
},
|
|
12033
|
+
// A sync that rejects instead of invoking options.error; settling
|
|
12034
|
+
// twice is a harmless no-op.
|
|
12035
|
+
(e) => promise.reject(e));
|
|
12036
|
+
return promise;
|
|
12037
|
+
}
|
|
12038
|
+
return result;
|
|
11775
12039
|
}
|
|
11776
12040
|
/**
|
|
11777
12041
|
* Create a new instance of a model in this collection. Add the model to the
|
|
@@ -11815,6 +12079,14 @@ class Collection extends EventEmitterObject {
|
|
|
11815
12079
|
return preparedModel;
|
|
11816
12080
|
}
|
|
11817
12081
|
}
|
|
12082
|
+
subscribe(eventOrCallback, callback, context) {
|
|
12083
|
+
if (typeof eventOrCallback === 'function') {
|
|
12084
|
+
const cb = () => eventOrCallback(this);
|
|
12085
|
+
this.on('update reset sort', cb);
|
|
12086
|
+
return () => this.off('update reset sort', cb);
|
|
12087
|
+
}
|
|
12088
|
+
return super.subscribe(eventOrCallback, callback, context);
|
|
12089
|
+
}
|
|
11818
12090
|
/**
|
|
11819
12091
|
* **parse** converts a response into a list of models to be added to the
|
|
11820
12092
|
* collection. The default implementation is just to pass it through.
|
|
@@ -11952,7 +12224,12 @@ class Collection extends EventEmitterObject {
|
|
|
11952
12224
|
this.trigger.apply(this, arguments);
|
|
11953
12225
|
}
|
|
11954
12226
|
}
|
|
11955
|
-
|
|
12227
|
+
_Collection_instances = new WeakSet(), _Collection_hydrate = async function _Collection_hydrate() {
|
|
12228
|
+
ensureUnloadListener(PersistentStorage);
|
|
12229
|
+
// findAll() returns [] for an empty store, so a first-run collection
|
|
12230
|
+
// resolves rather than erroring the way a model fetch-by-id would.
|
|
12231
|
+
await this.fetch({ fromStorage: true, promise: true });
|
|
12232
|
+
}, _a = Symbol.iterator;
|
|
11956
12233
|
// This "enum" defines the three possible kinds of values which can be emitted
|
|
11957
12234
|
// by a CollectionIterator that correspond to the values(), keys() and entries()
|
|
11958
12235
|
// methods on Collection, respectively.
|
|
@@ -12041,6 +12318,11 @@ function noConflict() {
|
|
|
12041
12318
|
}
|
|
12042
12319
|
skeletor.noConflict = noConflict;
|
|
12043
12320
|
root.Skeletor = skeletor;
|
|
12321
|
+
/**
|
|
12322
|
+
* @deprecated Use `PersistentStorage` instead.
|
|
12323
|
+
* @public
|
|
12324
|
+
*/
|
|
12325
|
+
const BrowserStorage = PersistentStorage;
|
|
12044
12326
|
|
|
12045
|
-
export { BrowserStorage, Collection, EventEmitter, Model, skeletor as default, noConflict, sync };
|
|
12327
|
+
export { BrowserStorage, Collection, EventEmitter, Model, PersistentStorage, skeletor as default, getStorage, noConflict, sync };
|
|
12046
12328
|
//# sourceMappingURL=skeletor.esm.js.map
|