@converse/skeletor 4.0.0 → 4.0.2
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/CHANGES.md +19 -0
- package/dist/skeletor.d.ts +925 -953
- package/dist/skeletor.esm.js +79 -91
- package/dist/skeletor.esm.js.map +1 -1
- package/dist/skeletor.js +79 -91
- package/dist/skeletor.js.map +1 -1
- package/dist/skeletor.min.js +5 -5
- package/dist/skeletor.node.d.ts +950 -978
- package/dist/skeletor.node.js +79 -91
- package/dist/skeletor.node.mjs +79 -91
- package/package.json +9 -19
- package/src/collection.ts +35 -34
- package/src/model.ts +85 -52
- package/src/types.ts +5 -6
package/dist/skeletor.esm.js
CHANGED
|
@@ -1668,19 +1668,6 @@ function __values(o) {
|
|
|
1668
1668
|
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
1669
1669
|
}
|
|
1670
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
1671
|
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1685
1672
|
var e = new Error(message);
|
|
1686
1673
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
@@ -11008,7 +10995,47 @@ var pick = flatRest(function(object, paths) {
|
|
|
11008
10995
|
return object == null ? {} : basePick(object, paths);
|
|
11009
10996
|
});
|
|
11010
10997
|
|
|
11011
|
-
|
|
10998
|
+
const INTERNALS = new WeakMap();
|
|
10999
|
+
function internals(model) {
|
|
11000
|
+
let priv = INTERNALS.get(model);
|
|
11001
|
+
if (!priv) {
|
|
11002
|
+
priv = { state: 'constructing' };
|
|
11003
|
+
INTERNALS.set(model, priv);
|
|
11004
|
+
}
|
|
11005
|
+
return priv;
|
|
11006
|
+
}
|
|
11007
|
+
/** Load the model from storage, marking it ready whether or not the read succeeds. */
|
|
11008
|
+
async function hydrate$1(model, priv) {
|
|
11009
|
+
ensureUnloadListener(PersistentStorage);
|
|
11010
|
+
try {
|
|
11011
|
+
await model.fetch({ fromStorage: true, promise: true });
|
|
11012
|
+
}
|
|
11013
|
+
finally {
|
|
11014
|
+
priv.state = 'ready';
|
|
11015
|
+
}
|
|
11016
|
+
}
|
|
11017
|
+
/** Evaluate the model's declared computed properties once, seeding the cache. */
|
|
11018
|
+
function initComputed(model, priv) {
|
|
11019
|
+
const defs = result(model, 'computed');
|
|
11020
|
+
if (!defs || isEmpty(defs))
|
|
11021
|
+
return;
|
|
11022
|
+
priv.computedDefs = defs;
|
|
11023
|
+
priv.computedCache = {};
|
|
11024
|
+
for (const [key, def] of Object.entries(defs)) {
|
|
11025
|
+
priv.computedCache[key] = def.fn(model);
|
|
11026
|
+
}
|
|
11027
|
+
}
|
|
11028
|
+
/** Recompute one computed property, firing `change:key` when its value changed. */
|
|
11029
|
+
function updateComputed(model, priv, key, def, silent, options) {
|
|
11030
|
+
const newVal = def.fn(model);
|
|
11031
|
+
if (!isEqual(priv.computedCache[key], newVal)) {
|
|
11032
|
+
priv.computedCache[key] = newVal;
|
|
11033
|
+
if (!silent) {
|
|
11034
|
+
model.changed[key] = newVal;
|
|
11035
|
+
model.trigger('change:' + key, model, newVal, options);
|
|
11036
|
+
}
|
|
11037
|
+
}
|
|
11038
|
+
}
|
|
11012
11039
|
/**
|
|
11013
11040
|
* @public
|
|
11014
11041
|
* **Models** are the basic data object in the framework --
|
|
@@ -11023,15 +11050,12 @@ class Model extends EventEmitterObject {
|
|
|
11023
11050
|
*/
|
|
11024
11051
|
constructor(attributes, options) {
|
|
11025
11052
|
super();
|
|
11026
|
-
_Model_instances.add(this);
|
|
11027
|
-
_Model_computedCache.set(this, void 0);
|
|
11028
|
-
_Model_computedDefs.set(this, void 0);
|
|
11029
|
-
_Model_state.set(this, 'constructing');
|
|
11030
11053
|
this._changing = false;
|
|
11031
11054
|
this._pending = false;
|
|
11032
11055
|
this._url = '';
|
|
11033
11056
|
this.changed = {};
|
|
11034
11057
|
this.validationError = null;
|
|
11058
|
+
const priv = internals(this);
|
|
11035
11059
|
let attrs = attributes || {};
|
|
11036
11060
|
options = options || {};
|
|
11037
11061
|
this.preinitialize.apply(this, arguments);
|
|
@@ -11044,11 +11068,12 @@ class Model extends EventEmitterObject {
|
|
|
11044
11068
|
const default_attrs = result(this, 'defaults');
|
|
11045
11069
|
attrs = defaults(Object.assign({}, default_attrs, attrs), default_attrs);
|
|
11046
11070
|
this.set(attrs, options);
|
|
11047
|
-
|
|
11071
|
+
initComputed(this, priv);
|
|
11048
11072
|
this.attrs = new Proxy(this.attributes, {
|
|
11049
11073
|
get: (_target, key) => {
|
|
11050
|
-
|
|
11051
|
-
|
|
11074
|
+
const cache = priv.computedCache;
|
|
11075
|
+
if (typeof key !== 'symbol' && cache && key in cache) {
|
|
11076
|
+
return cache[key];
|
|
11052
11077
|
}
|
|
11053
11078
|
return this.attributes[key];
|
|
11054
11079
|
},
|
|
@@ -11066,16 +11091,16 @@ class Model extends EventEmitterObject {
|
|
|
11066
11091
|
// otherwise it's already ready and resolves immediately.
|
|
11067
11092
|
if (this.autoSync) {
|
|
11068
11093
|
if (getStorage(this) && !this.isNew()) {
|
|
11069
|
-
|
|
11070
|
-
this.hydrated =
|
|
11094
|
+
priv.state = 'hydrating';
|
|
11095
|
+
this.hydrated = hydrate$1(this, priv);
|
|
11071
11096
|
}
|
|
11072
11097
|
else {
|
|
11073
|
-
|
|
11098
|
+
priv.state = 'ready';
|
|
11074
11099
|
this.hydrated = Promise.resolve();
|
|
11075
11100
|
}
|
|
11076
11101
|
}
|
|
11077
11102
|
else {
|
|
11078
|
-
|
|
11103
|
+
priv.state = 'ready';
|
|
11079
11104
|
}
|
|
11080
11105
|
}
|
|
11081
11106
|
/**
|
|
@@ -11174,8 +11199,9 @@ class Model extends EventEmitterObject {
|
|
|
11174
11199
|
* Get the value of an attribute, or a computed property.
|
|
11175
11200
|
*/
|
|
11176
11201
|
get(attr) {
|
|
11177
|
-
|
|
11178
|
-
|
|
11202
|
+
const cache = internals(this).computedCache;
|
|
11203
|
+
if (cache && attr in cache) {
|
|
11204
|
+
return cache[attr];
|
|
11179
11205
|
}
|
|
11180
11206
|
return this.attributes[attr];
|
|
11181
11207
|
}
|
|
@@ -11251,9 +11277,10 @@ class Model extends EventEmitterObject {
|
|
|
11251
11277
|
attrs[key] = val;
|
|
11252
11278
|
}
|
|
11253
11279
|
options = options || {};
|
|
11280
|
+
const priv = internals(this);
|
|
11254
11281
|
// Guard must come after arg normalization: when called as set(obj, opts),
|
|
11255
11282
|
// fromStorage lives in `val` (second arg), not `options` (third arg).
|
|
11256
|
-
if (this.autoSync &&
|
|
11283
|
+
if (this.autoSync && priv.state === 'hydrating' && !options.fromStorage) {
|
|
11257
11284
|
throw new Error(`Skeletor: set() called on an autoSync model before hydration resolved. Await model.hydrated first.`);
|
|
11258
11285
|
}
|
|
11259
11286
|
// Run validation.
|
|
@@ -11297,10 +11324,10 @@ class Model extends EventEmitterObject {
|
|
|
11297
11324
|
}
|
|
11298
11325
|
}
|
|
11299
11326
|
// Recalculate computed properties whose deps changed.
|
|
11300
|
-
if (changes.length &&
|
|
11301
|
-
for (const [key, def] of Object.entries(
|
|
11327
|
+
if (changes.length && priv.computedDefs) {
|
|
11328
|
+
for (const [key, def] of Object.entries(priv.computedDefs)) {
|
|
11302
11329
|
if (def.deps.some((dep) => changes.includes(dep))) {
|
|
11303
|
-
|
|
11330
|
+
updateComputed(this, priv, key, def, silent, options);
|
|
11304
11331
|
}
|
|
11305
11332
|
}
|
|
11306
11333
|
}
|
|
@@ -11320,13 +11347,13 @@ class Model extends EventEmitterObject {
|
|
|
11320
11347
|
// Auto-save: schedule a debounced write when autoSync is on and there
|
|
11321
11348
|
// were actual changes that originated from application code (not a
|
|
11322
11349
|
// storage read or an explicit noAutoSave call).
|
|
11323
|
-
if (
|
|
11350
|
+
if (priv.state === 'ready' &&
|
|
11324
11351
|
this.autoSync &&
|
|
11325
11352
|
getStorage(this) &&
|
|
11326
11353
|
changes.length &&
|
|
11327
11354
|
!options.fromStorage &&
|
|
11328
11355
|
!options.noAutoSave) {
|
|
11329
|
-
scheduleAutoSave(this, () =>
|
|
11356
|
+
scheduleAutoSave(this, () => this.save(null, { noAutoSave: true }), this.autoSyncDelay);
|
|
11330
11357
|
}
|
|
11331
11358
|
return this;
|
|
11332
11359
|
}
|
|
@@ -11607,37 +11634,8 @@ class Model extends EventEmitterObject {
|
|
|
11607
11634
|
return false;
|
|
11608
11635
|
}
|
|
11609
11636
|
}
|
|
11610
|
-
_Model_computedCache = new WeakMap(), _Model_computedDefs = new WeakMap(), _Model_state = new WeakMap(), _Model_instances = new WeakSet(), _Model_hydrate = async function _Model_hydrate() {
|
|
11611
|
-
ensureUnloadListener(PersistentStorage);
|
|
11612
|
-
try {
|
|
11613
|
-
await this.fetch({ fromStorage: true, promise: true });
|
|
11614
|
-
}
|
|
11615
|
-
finally {
|
|
11616
|
-
__classPrivateFieldSet(this, _Model_state, 'ready', "f");
|
|
11617
|
-
}
|
|
11618
|
-
}, _Model_doAutoSave = function _Model_doAutoSave() {
|
|
11619
|
-
return this.save(null, { noAutoSave: true });
|
|
11620
|
-
}, _Model_updateComputed = function _Model_updateComputed(key, def, silent, options) {
|
|
11621
|
-
const newVal = def.fn(this);
|
|
11622
|
-
if (!isEqual(__classPrivateFieldGet(this, _Model_computedCache, "f")[key], newVal)) {
|
|
11623
|
-
__classPrivateFieldGet(this, _Model_computedCache, "f")[key] = newVal;
|
|
11624
|
-
if (!silent) {
|
|
11625
|
-
this.changed[key] = newVal;
|
|
11626
|
-
this.trigger('change:' + key, this, newVal, options);
|
|
11627
|
-
}
|
|
11628
|
-
}
|
|
11629
|
-
}, _Model_initComputed = function _Model_initComputed() {
|
|
11630
|
-
const defs = result(this, 'computed');
|
|
11631
|
-
if (!defs || isEmpty(defs))
|
|
11632
|
-
return;
|
|
11633
|
-
__classPrivateFieldSet(this, _Model_computedDefs, defs, "f");
|
|
11634
|
-
__classPrivateFieldSet(this, _Model_computedCache, {}, "f");
|
|
11635
|
-
for (const [key, def] of Object.entries(defs)) {
|
|
11636
|
-
__classPrivateFieldGet(this, _Model_computedCache, "f")[key] = def.fn(this);
|
|
11637
|
-
}
|
|
11638
|
-
};
|
|
11639
11637
|
|
|
11640
|
-
var
|
|
11638
|
+
var _a;
|
|
11641
11639
|
// Default options for `Collection#set`.
|
|
11642
11640
|
const setOptions = { add: true, remove: true, merge: true };
|
|
11643
11641
|
const addOptions = { add: true, remove: false };
|
|
@@ -11658,6 +11656,18 @@ function toModelPredicate(pred) {
|
|
|
11658
11656
|
const matcher = matches(pred);
|
|
11659
11657
|
return (m) => matcher(m.attributes);
|
|
11660
11658
|
}
|
|
11659
|
+
/**
|
|
11660
|
+
* Load the collection's members from storage. A module-level function rather
|
|
11661
|
+
* than a `#private` method so the published declarations carry no private
|
|
11662
|
+
* members, which TypeScript 6 rejects in anonymously extended classes (TS4094).
|
|
11663
|
+
*/
|
|
11664
|
+
async function hydrate(collection) {
|
|
11665
|
+
ensureUnloadListener(PersistentStorage);
|
|
11666
|
+
// An empty store is a normal first-run state: findAll() returns [] and a
|
|
11667
|
+
// missing model record resolves to null, so hydration resolves rather
|
|
11668
|
+
// than rejecting.
|
|
11669
|
+
await collection.fetch({ fromStorage: true, promise: true });
|
|
11670
|
+
}
|
|
11661
11671
|
/**
|
|
11662
11672
|
* @public
|
|
11663
11673
|
* If models tend to represent a single row of data, a Collection is
|
|
@@ -11667,6 +11677,7 @@ function toModelPredicate(pred) {
|
|
|
11667
11677
|
* belonging to this particular author, and so on. Collections maintain
|
|
11668
11678
|
* indexes of their models, both in order, and for lookup by `id`.
|
|
11669
11679
|
*/
|
|
11680
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging -- see the interface above
|
|
11670
11681
|
class Collection extends EventEmitterObject {
|
|
11671
11682
|
/**
|
|
11672
11683
|
* Create a new **Collection**, perhaps to contain a specific type of `model`.
|
|
@@ -11675,7 +11686,6 @@ class Collection extends EventEmitterObject {
|
|
|
11675
11686
|
*/
|
|
11676
11687
|
constructor(models, options) {
|
|
11677
11688
|
super();
|
|
11678
|
-
_Collection_instances.add(this);
|
|
11679
11689
|
this._url = '';
|
|
11680
11690
|
/**
|
|
11681
11691
|
* @public
|
|
@@ -11685,7 +11695,7 @@ class Collection extends EventEmitterObject {
|
|
|
11685
11695
|
options = options || {};
|
|
11686
11696
|
this.preinitialize.apply(this, arguments);
|
|
11687
11697
|
if (options.model)
|
|
11688
|
-
this.
|
|
11698
|
+
this.model = options.model;
|
|
11689
11699
|
if (options.comparator !== undefined)
|
|
11690
11700
|
this.comparator = options.comparator;
|
|
11691
11701
|
this._reset();
|
|
@@ -11697,15 +11707,9 @@ class Collection extends EventEmitterObject {
|
|
|
11697
11707
|
// uniformly `await collection.hydrated`; it resolves immediately when
|
|
11698
11708
|
// there's no storage to hydrate from.
|
|
11699
11709
|
if (this.autoSync) {
|
|
11700
|
-
this.hydrated = getStorage(this) ?
|
|
11710
|
+
this.hydrated = getStorage(this) ? hydrate(this) : Promise.resolve();
|
|
11701
11711
|
}
|
|
11702
11712
|
}
|
|
11703
|
-
get comparator() {
|
|
11704
|
-
return this._comparator;
|
|
11705
|
-
}
|
|
11706
|
-
set comparator(c) {
|
|
11707
|
-
this._comparator = c;
|
|
11708
|
-
}
|
|
11709
11713
|
/**
|
|
11710
11714
|
* The canonical storage accessor. Set to a `PersistentStorage` instance
|
|
11711
11715
|
* to enable local persistence for this collection.
|
|
@@ -11741,16 +11745,6 @@ class Collection extends EventEmitterObject {
|
|
|
11741
11745
|
get autoSync() {
|
|
11742
11746
|
return false;
|
|
11743
11747
|
}
|
|
11744
|
-
/**
|
|
11745
|
-
* The default model for a collection is just a **Model**.
|
|
11746
|
-
* This should be overridden in most cases.
|
|
11747
|
-
*/
|
|
11748
|
-
get model() {
|
|
11749
|
-
return this._model ?? Model;
|
|
11750
|
-
}
|
|
11751
|
-
set model(model) {
|
|
11752
|
-
this._model = model;
|
|
11753
|
-
}
|
|
11754
11748
|
get length() {
|
|
11755
11749
|
return this.models.length;
|
|
11756
11750
|
}
|
|
@@ -12254,7 +12248,7 @@ class Collection extends EventEmitterObject {
|
|
|
12254
12248
|
* Define how to uniquely identify models in the collection.
|
|
12255
12249
|
*/
|
|
12256
12250
|
modelId(attrs) {
|
|
12257
|
-
return attrs[this.model.prototype?.idAttribute || 'id'];
|
|
12251
|
+
return attrs[(this.model ?? Model).prototype?.idAttribute || 'id'];
|
|
12258
12252
|
}
|
|
12259
12253
|
/** Get an iterator of all models in this collection. */
|
|
12260
12254
|
values() {
|
|
@@ -12277,7 +12271,7 @@ class Collection extends EventEmitterObject {
|
|
|
12277
12271
|
this._byId = {};
|
|
12278
12272
|
}
|
|
12279
12273
|
createModel(attrs, options) {
|
|
12280
|
-
const Klass = this.model;
|
|
12274
|
+
const Klass = this.model ?? Model;
|
|
12281
12275
|
return new Klass(attrs, options);
|
|
12282
12276
|
}
|
|
12283
12277
|
/**
|
|
@@ -12380,13 +12374,7 @@ class Collection extends EventEmitterObject {
|
|
|
12380
12374
|
this.trigger.apply(this, arguments);
|
|
12381
12375
|
}
|
|
12382
12376
|
}
|
|
12383
|
-
|
|
12384
|
-
ensureUnloadListener(PersistentStorage);
|
|
12385
|
-
// An empty store is a normal first-run state: findAll() returns [] and a
|
|
12386
|
-
// missing model record resolves to null, so hydration resolves rather
|
|
12387
|
-
// than rejecting.
|
|
12388
|
-
await this.fetch({ fromStorage: true, promise: true });
|
|
12389
|
-
}, _a = Symbol.iterator;
|
|
12377
|
+
_a = Symbol.iterator;
|
|
12390
12378
|
// This "enum" defines the three possible kinds of values which can be emitted
|
|
12391
12379
|
// by a CollectionIterator that correspond to the values(), keys() and entries()
|
|
12392
12380
|
// methods on Collection, respectively.
|