@camstack/addon-decoder-nodeav 1.2.56 → 1.2.58

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -18971,7 +18971,20 @@ var RecentTracksQueryInput = object({
18971
18971
  projection: TrackProjectionSchema.optional(),
18972
18972
  /** Include stationary-promoted rows (parked objects). Default false: the
18973
18973
  * feed lists passages; parking records live on the stationary registry. */
18974
- includeStationary: boolean().optional()
18974
+ includeStationary: boolean().optional(),
18975
+ /**
18976
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
18977
+ *
18978
+ * The same filter `listTracks` takes, because the timeline's class chips must
18979
+ * mean the same thing whether the scope is one camera or twelve. Until this
18980
+ * existed the scoped feed downloaded a page and narrowed it on the phone
18981
+ * while the single-camera path narrowed the read — one filter, two costs.
18982
+ *
18983
+ * A SUPERSET prefilter on `classes[]`, like its single-camera twin: rows
18984
+ * whose class list is unreadable are kept, and the client's rule stays the
18985
+ * exact one.
18986
+ */
18987
+ classes: array(string()).optional()
18975
18988
  });
18976
18989
  var RecentTracksPageSchema = object({
18977
18990
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -19358,7 +19371,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19358
19371
  /** Include stationary-promoted rows (parked objects handed to the
19359
19372
  * stationary registry). Default false: the timeline lists passages,
19360
19373
  * not parking records (operator decision, 2026-08-15). */
19361
- includeStationary: boolean().optional()
19374
+ includeStationary: boolean().optional(),
19375
+ /**
19376
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
19377
+ *
19378
+ * Added 2026-09-03: the timeline's class chips filtered in the CLIENT,
19379
+ * on a day of rows already downloaded. The zone filter had been moved
19380
+ * here for exactly that reason — and it is also what lets the rows come
19381
+ * back `slim` — but the class filter was left behind, so a narrow
19382
+ * selection was still a wide read followed by a wide discard.
19383
+ *
19384
+ * Empty is "show all", not "nothing matches": a chip row with nothing
19385
+ * selected is an operator who has not narrowed anything, and an empty
19386
+ * timeline would read as a camera that saw nothing.
19387
+ */
19388
+ classes: array(string()).optional()
19362
19389
  }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19363
19390
  kind: "mutation",
19364
19391
  auth: "admin"
@@ -22995,8 +23022,22 @@ DeviceType.Automation, method(object({ deviceId: number().int().nonnegative() })
22995
23022
  * threshold.
22996
23023
  */
22997
23024
  var BatteryStatusSchema = object({
22998
- /** 0..100 inclusive. Firmware-reported. */
22999
- percentage: number().min(0).max(100),
23025
+ /**
23026
+ * 0..100 inclusive, firmware-reported. **`null` means NOT YET KNOWN** — the
23027
+ * provider has registered the capability but no reading has landed.
23028
+ *
23029
+ * It is nullable because it was not, and the only value a provider could
23030
+ * seed with was `0`. A battery camera behind an NVR therefore announced
23031
+ * itself at 0% on every start and corrected itself a moment later, which is
23032
+ * indistinguishable from a real flat battery: it fires the low-battery alert
23033
+ * every time the hub restarts. Unknown is not empty (D315), and on a battery
23034
+ * reading the difference is an alarm.
23035
+ *
23036
+ * `vacuum-control` and `lawn-mower-control` already model it this way.
23037
+ * Consumers must SKIP a null rather than coerce it — `battery-band` already
23038
+ * declines to band a non-finite reading, which is the correct shape.
23039
+ */
23040
+ percentage: number().min(0).max(100).nullable(),
23000
23041
  /**
23001
23042
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23002
23043
  * Reolink-specific for the Solar Panel 2 accessory (will become
package/dist/index.mjs CHANGED
@@ -18967,7 +18967,20 @@ var RecentTracksQueryInput = object({
18967
18967
  projection: TrackProjectionSchema.optional(),
18968
18968
  /** Include stationary-promoted rows (parked objects). Default false: the
18969
18969
  * feed lists passages; parking records live on the stationary registry. */
18970
- includeStationary: boolean().optional()
18970
+ includeStationary: boolean().optional(),
18971
+ /**
18972
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
18973
+ *
18974
+ * The same filter `listTracks` takes, because the timeline's class chips must
18975
+ * mean the same thing whether the scope is one camera or twelve. Until this
18976
+ * existed the scoped feed downloaded a page and narrowed it on the phone
18977
+ * while the single-camera path narrowed the read — one filter, two costs.
18978
+ *
18979
+ * A SUPERSET prefilter on `classes[]`, like its single-camera twin: rows
18980
+ * whose class list is unreadable are kept, and the client's rule stays the
18981
+ * exact one.
18982
+ */
18983
+ classes: array(string()).optional()
18971
18984
  });
18972
18985
  var RecentTracksPageSchema = object({
18973
18986
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -19354,7 +19367,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19354
19367
  /** Include stationary-promoted rows (parked objects handed to the
19355
19368
  * stationary registry). Default false: the timeline lists passages,
19356
19369
  * not parking records (operator decision, 2026-08-15). */
19357
- includeStationary: boolean().optional()
19370
+ includeStationary: boolean().optional(),
19371
+ /**
19372
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
19373
+ *
19374
+ * Added 2026-09-03: the timeline's class chips filtered in the CLIENT,
19375
+ * on a day of rows already downloaded. The zone filter had been moved
19376
+ * here for exactly that reason — and it is also what lets the rows come
19377
+ * back `slim` — but the class filter was left behind, so a narrow
19378
+ * selection was still a wide read followed by a wide discard.
19379
+ *
19380
+ * Empty is "show all", not "nothing matches": a chip row with nothing
19381
+ * selected is an operator who has not narrowed anything, and an empty
19382
+ * timeline would read as a camera that saw nothing.
19383
+ */
19384
+ classes: array(string()).optional()
19358
19385
  }), array(TrackSchema).readonly()), method(RecentTracksQueryInput, RecentTracksPageSchema), method(object({ deviceId: number() }), _void(), {
19359
19386
  kind: "mutation",
19360
19387
  auth: "admin"
@@ -22991,8 +23018,22 @@ DeviceType.Automation, method(object({ deviceId: number().int().nonnegative() })
22991
23018
  * threshold.
22992
23019
  */
22993
23020
  var BatteryStatusSchema = object({
22994
- /** 0..100 inclusive. Firmware-reported. */
22995
- percentage: number().min(0).max(100),
23021
+ /**
23022
+ * 0..100 inclusive, firmware-reported. **`null` means NOT YET KNOWN** — the
23023
+ * provider has registered the capability but no reading has landed.
23024
+ *
23025
+ * It is nullable because it was not, and the only value a provider could
23026
+ * seed with was `0`. A battery camera behind an NVR therefore announced
23027
+ * itself at 0% on every start and corrected itself a moment later, which is
23028
+ * indistinguishable from a real flat battery: it fires the low-battery alert
23029
+ * every time the hub restarts. Unknown is not empty (D315), and on a battery
23030
+ * reading the difference is an alarm.
23031
+ *
23032
+ * `vacuum-control` and `lawn-mower-control` already model it this way.
23033
+ * Consumers must SKIP a null rather than coerce it — `battery-band` already
23034
+ * declines to band a non-finite reading, which is the correct shape.
23035
+ */
23036
+ percentage: number().min(0).max(100).nullable(),
22996
23037
  /**
22997
23038
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
22998
23039
  * Reolink-specific for the Solar Panel 2 accessory (will become
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-decoder-nodeav",
3
- "version": "1.2.56",
3
+ "version": "1.2.58",
4
4
  "description": "Standalone in-process node-av decoder addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",