@converse/skeletor 3.1.6 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGES.md CHANGED
@@ -1,5 +1,60 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.1 (2026-10-27)
4
+
5
+ - The declarations for `Model` and `Collection` no longer contain `#private` members, so mixins
6
+ over them (`class extends Base`) type-check under TypeScript 6 (TS4094). No runtime change.
7
+
8
+ ## 4.0.0 (2026-10-24)
9
+
10
+ - Attribute-object queries on a collection (`findWhere`, `where`, and `find`, `filter`, `some`,
11
+ `every`, `map`, `sortBy`, `countBy`, `groupBy`, `findIndex` and `findLastIndex` when given an
12
+ object) now build their lodash matcher once per scan instead of once per model visited. Each
13
+ per-model build deep-cloned the attributes object and walked its keys, which made `findWhere`
14
+ roughly 8 to 13 times slower than `find` with a hand-written predicate on a few thousand models.
15
+ Matching semantics are unchanged: still lodash's partial, deep comparison, so nested lookups
16
+ such as `where({ FORM_TYPE: { type: 'hidden' } })` keep working. One alignment: `find` and
17
+ `filter` given a string now read that attribute through `Model.get`, like the other query
18
+ methods already did, instead of resolving it as a lodash property path over the raw attributes.
19
+
20
+ - `Model.matches` no longer deep-clones its argument on every call (it uses lodash's `isMatch`)
21
+ and its signature now admits the predicate function it has always accepted at runtime. The
22
+ undocumented lodash string and `[key, value]` shorthand forms are no longer supported.
23
+
24
+ - Fix `Model.save({ promise: true })` hanging forever, and leaking an unhandled rejection, when
25
+ its `sync` settles the returned promise instead of invoking the `success`/`error` callbacks
26
+ (a rejecting custom `sync`, or a throwing `'sync'`/`'error'` listener). `save` now bridges that
27
+ promise to the one it hands back, the way `fetch` already did. `Collection.create({ promise: true })`,
28
+ which delegates to `save`, is fixed the same way.
29
+
30
+ - Fix `fetch({ promise: true })` on a Model or Collection settling early when a callback-style `sync`
31
+ returns a non-thenable (nothing, or an XHR) and invokes `success`/`error` later. The bridge from the
32
+ `sync` return value to the returned promise now only engages for a thenable, so such a `sync` settles
33
+ the promise through its callbacks. The same guard applies to `save({ promise: true })`.
34
+
35
+ - The `{ promise: true }` paths of `fetch` and `save` now share one bridge from the `sync` outcome
36
+ to the returned promise, with two behaviour changes: a `sync` that rejects its promise without
37
+ calling the callbacks now also runs the `error` callback and fires the `'error'` event, and a
38
+ `'sync'`/`'error'` listener (or `success`/`error` callback) that throws now rejects the promise
39
+ instead of leaving it pending with an unhandled rejection. `Collection.fetch` fires `'sync'` before
40
+ resolving, as `Model.fetch`/`save` already did, so a throwing listener rejects there too.
41
+
42
+ - Fix `save({ promise: true })` and `fetch({ promise: true, validate: true })` leaving the promise
43
+ pending when the attributes returned by `sync` fail validation. The promise now rejects with
44
+ `validationError`; the `'invalid'` event fires as before.
45
+
46
+ - `save({ promise: true })` now returns a promise rejected with `validationError`, instead of `false`,
47
+ when the attributes passed to it fail validation; `create({ promise: true })` likewise returns a
48
+ rejected promise instead of `null`. The callback forms still return `false`/`null`.
49
+
50
+ - The default HTTP `sync` now honours both the callback and the promise contracts. It never invoked
51
+ `success`/`error` (it passed them to `fetch()` as init options, which ignores them), sent an empty
52
+ body on GET (which the Fetch API rejects outright), and resolved with the raw `Response`, which the
53
+ promise bridge then merged into the model as attributes. It now sends `data` as query parameters on
54
+ GET and as a JSON body otherwise, passes a parsed 2xx JSON body (`null` when empty) to `success` and
55
+ resolves with it, and on a non-2xx response or a network failure calls `error` with, and rejects
56
+ with, the error: an `HTTPError` (new export, carrying `status` and `response`) for the former.
57
+
3
58
  ## 3.1.6 (2026-08-06)
4
59
 
5
60
  - The `'node'` store type can now be told where to put its database files, via the new