@camstack/addon-provider-onvif 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/addon.js CHANGED
@@ -10526,6 +10526,89 @@ var LocationStatSchema = object({
10526
10526
  fileCount: number(),
10527
10527
  present: boolean()
10528
10528
  });
10529
+ /** Lifecycle of a backup run. Terminal states: succeeded / failed / cancelled. */
10530
+ var BackupRunStateSchema = _enum([
10531
+ "queued",
10532
+ "running",
10533
+ "succeeded",
10534
+ "failed",
10535
+ "cancelled"
10536
+ ]);
10537
+ /**
10538
+ * Where a running backup currently is. `queued` before it starts,
10539
+ * `building` while the tar.gz is being staged, `uploading` during the
10540
+ * per-destination fan-out, `done` once terminal.
10541
+ */
10542
+ var BackupRunPhaseSchema = _enum([
10543
+ "queued",
10544
+ "building",
10545
+ "uploading",
10546
+ "done"
10547
+ ]);
10548
+ /**
10549
+ * Observable state of one backup run — readable WHILE it runs via
10550
+ * `backup.listRuns`. This is what makes the execution queue and
10551
+ * `backup.cancel` usable: the 2026-09-04 incident (two concurrent
10552
+ * multi-GB builds, staging 5.1 GB → 18 GB, load 62) was only
10553
+ * diagnosable with `du` because nothing reported that runs existed or
10554
+ * how large the staged archive had grown.
10555
+ */
10556
+ var BackupRunSchema = object({
10557
+ /** Stable run id — the handle `backup.cancel` takes. */
10558
+ id: string(),
10559
+ state: BackupRunStateSchema,
10560
+ phase: BackupRunPhaseSchema,
10561
+ /**
10562
+ * Resolved destination location ids. Empty while queued (targets are
10563
+ * resolved when the run starts, against the then-current policies).
10564
+ */
10565
+ destinationIds: array(string()).readonly(),
10566
+ label: string().optional(),
10567
+ /** ms-epoch when the run was submitted (trigger call / schedule fire). */
10568
+ requestedAt: number(),
10569
+ /** ms-epoch when the run left the queue and started building. */
10570
+ startedAt: number().optional(),
10571
+ /** ms-epoch when the run reached a terminal state. */
10572
+ finishedAt: number().optional(),
10573
+ /** Compressed bytes of the staging archive written so far. */
10574
+ stagedBytes: number(),
10575
+ /** Final staged archive size, once the build phase completes. */
10576
+ archiveSizeBytes: number().optional(),
10577
+ /** Bytes pushed to the destination currently uploading. */
10578
+ uploadedBytes: number(),
10579
+ /** Destinations where the archive fully landed (uploaded + indexed). */
10580
+ completedDestinationIds: array(string()).readonly(),
10581
+ /** Destinations that failed during the fan-out. */
10582
+ failedDestinationIds: array(string()).readonly(),
10583
+ /** Failure message when `state === 'failed'`. */
10584
+ error: string().optional(),
10585
+ /**
10586
+ * 1-based place in the execution queue — 1 = runs next. Present only
10587
+ * while `state === 'queued'`. Stamped by the orchestrator from the
10588
+ * queue's OWN pending order, never derived from timestamps, so the
10589
+ * UI cannot show an order the executor will not honour.
10590
+ */
10591
+ queuePosition: number().int().min(1).optional()
10592
+ });
10593
+ /**
10594
+ * Result of `backup.trigger`. The call still resolves when the run
10595
+ * terminates (compat with schedule-driven runs and the admin UI), but
10596
+ * it now names the run and says whether it had to WAIT: a trigger that
10597
+ * arrives while another run is in flight is enqueued (or joined onto
10598
+ * an identical already-queued run), never started concurrently.
10599
+ */
10600
+ var BackupTriggerResultSchema = object({
10601
+ /** The run this trigger mapped to — poll it via `listRuns`, stop it via `cancel`. */
10602
+ runId: string(),
10603
+ /** True when the run waited behind an in-flight run instead of starting immediately. */
10604
+ queued: boolean(),
10605
+ /** True when this trigger was coalesced onto an identical already-queued run. */
10606
+ joined: boolean(),
10607
+ /** True when the run was cancelled before completing every destination. */
10608
+ cancelled: boolean(),
10609
+ /** One entry per destination the archive landed at (partial on cancel). */
10610
+ entries: array(BackupEntrySchema).readonly()
10611
+ });
10529
10612
  /**
10530
10613
  * A backup schedule — the N:M "entry" that binds one cron cadence to a
10531
10614
  * SET of destination locations. Supersedes the per-location cron on
@@ -10573,7 +10656,10 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
10573
10656
  * retention (manual runs).
10574
10657
  */
10575
10658
  retentionCount: number().int().min(1).max(1e3).optional()
10576
- }).optional(), array(BackupEntrySchema).readonly(), {
10659
+ }).optional(), BackupTriggerResultSchema, {
10660
+ kind: "mutation",
10661
+ auth: "admin"
10662
+ }), method(_void(), array(BackupRunSchema).readonly(), { auth: "admin" }), method(object({ runId: string() }), object({ cancelled: boolean() }), {
10577
10663
  kind: "mutation",
10578
10664
  auth: "admin"
10579
10665
  }), method(_void(), array(BackupEntrySchema).readonly(), { auth: "admin" }), method(_void(), array(LocationStatSchema).readonly(), { auth: "admin" }), method(object({
@@ -11290,6 +11376,14 @@ method(object({
11290
11376
  }), object({ success: literal(true) }), {
11291
11377
  kind: "mutation",
11292
11378
  auth: "admin"
11379
+ }), method(object({ deviceId: number().int().nonnegative() }), object({
11380
+ derivedStreamsDeleted: array(string()).readonly(),
11381
+ assignmentsPurged: boolean(),
11382
+ probeSnapshotsDropped: number().int().nonnegative(),
11383
+ rtspTokenRowsDeleted: number().int().nonnegative()
11384
+ }), {
11385
+ kind: "mutation",
11386
+ auth: "admin"
11293
11387
  }), method(object({
11294
11388
  deviceId: number(),
11295
11389
  /** Absent = the LOWEST assigned profile — a notification attachment is
@@ -18895,7 +18989,20 @@ var RecentTracksQueryInput = object({
18895
18989
  projection: TrackProjectionSchema.optional(),
18896
18990
  /** Include stationary-promoted rows (parked objects). Default false: the
18897
18991
  * feed lists passages; parking records live on the stationary registry. */
18898
- includeStationary: boolean().optional()
18992
+ includeStationary: boolean().optional(),
18993
+ /**
18994
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
18995
+ *
18996
+ * The same filter `listTracks` takes, because the timeline's class chips must
18997
+ * mean the same thing whether the scope is one camera or twelve. Until this
18998
+ * existed the scoped feed downloaded a page and narrowed it on the phone
18999
+ * while the single-camera path narrowed the read — one filter, two costs.
19000
+ *
19001
+ * A SUPERSET prefilter on `classes[]`, like its single-camera twin: rows
19002
+ * whose class list is unreadable are kept, and the client's rule stays the
19003
+ * exact one.
19004
+ */
19005
+ classes: array(string()).optional()
18899
19006
  });
18900
19007
  var RecentTracksPageSchema = object({
18901
19008
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -23037,8 +23144,22 @@ DeviceType.Automation, method(object({ deviceId: number().int().nonnegative() })
23037
23144
  * threshold.
23038
23145
  */
23039
23146
  var BatteryStatusSchema = object({
23040
- /** 0..100 inclusive. Firmware-reported. */
23041
- percentage: number().min(0).max(100),
23147
+ /**
23148
+ * 0..100 inclusive, firmware-reported. **`null` means NOT YET KNOWN** — the
23149
+ * provider has registered the capability but no reading has landed.
23150
+ *
23151
+ * It is nullable because it was not, and the only value a provider could
23152
+ * seed with was `0`. A battery camera behind an NVR therefore announced
23153
+ * itself at 0% on every start and corrected itself a moment later, which is
23154
+ * indistinguishable from a real flat battery: it fires the low-battery alert
23155
+ * every time the hub restarts. Unknown is not empty (D315), and on a battery
23156
+ * reading the difference is an alarm.
23157
+ *
23158
+ * `vacuum-control` and `lawn-mower-control` already model it this way.
23159
+ * Consumers must SKIP a null rather than coerce it — `battery-band` already
23160
+ * declines to band a non-finite reading, which is the correct shape.
23161
+ */
23162
+ percentage: number().min(0).max(100).nullable(),
23042
23163
  /**
23043
23164
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23044
23165
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -29969,6 +30090,12 @@ Object.freeze({
29969
30090
  addonId: null,
29970
30091
  access: "create"
29971
30092
  },
30093
+ "backup.cancel": {
30094
+ capName: "backup",
30095
+ capScope: "system",
30096
+ addonId: null,
30097
+ access: "create"
30098
+ },
29972
30099
  "backup.delete": {
29973
30100
  capName: "backup",
29974
30101
  capScope: "system",
@@ -30011,6 +30138,12 @@ Object.freeze({
30011
30138
  addonId: null,
30012
30139
  access: "view"
30013
30140
  },
30141
+ "backup.listRuns": {
30142
+ capName: "backup",
30143
+ capScope: "system",
30144
+ addonId: null,
30145
+ access: "view"
30146
+ },
30014
30147
  "backup.listSchedules": {
30015
30148
  capName: "backup",
30016
30149
  capScope: "system",
@@ -34577,6 +34710,12 @@ Object.freeze({
34577
34710
  addonId: null,
34578
34711
  access: "create"
34579
34712
  },
34713
+ "streamBroker.forgetDeviceHardware": {
34714
+ capName: "stream-broker",
34715
+ capScope: "system",
34716
+ addonId: null,
34717
+ access: "delete"
34718
+ },
34580
34719
  "streamBroker.getAllRtspEntries": {
34581
34720
  capName: "stream-broker",
34582
34721
  capScope: "system",
@@ -37035,6 +37174,11 @@ Object.freeze({
37035
37174
  form: "single",
37036
37175
  optional: false
37037
37176
  }],
37177
+ "streamBroker.forgetDeviceHardware": [{
37178
+ name: "deviceId",
37179
+ form: "single",
37180
+ optional: false
37181
+ }],
37038
37182
  "streamBroker.getDeviceAudioMute": [{
37039
37183
  name: "deviceId",
37040
37184
  form: "single",
package/dist/addon.mjs CHANGED
@@ -10527,6 +10527,89 @@ var LocationStatSchema = object({
10527
10527
  fileCount: number(),
10528
10528
  present: boolean()
10529
10529
  });
10530
+ /** Lifecycle of a backup run. Terminal states: succeeded / failed / cancelled. */
10531
+ var BackupRunStateSchema = _enum([
10532
+ "queued",
10533
+ "running",
10534
+ "succeeded",
10535
+ "failed",
10536
+ "cancelled"
10537
+ ]);
10538
+ /**
10539
+ * Where a running backup currently is. `queued` before it starts,
10540
+ * `building` while the tar.gz is being staged, `uploading` during the
10541
+ * per-destination fan-out, `done` once terminal.
10542
+ */
10543
+ var BackupRunPhaseSchema = _enum([
10544
+ "queued",
10545
+ "building",
10546
+ "uploading",
10547
+ "done"
10548
+ ]);
10549
+ /**
10550
+ * Observable state of one backup run — readable WHILE it runs via
10551
+ * `backup.listRuns`. This is what makes the execution queue and
10552
+ * `backup.cancel` usable: the 2026-09-04 incident (two concurrent
10553
+ * multi-GB builds, staging 5.1 GB → 18 GB, load 62) was only
10554
+ * diagnosable with `du` because nothing reported that runs existed or
10555
+ * how large the staged archive had grown.
10556
+ */
10557
+ var BackupRunSchema = object({
10558
+ /** Stable run id — the handle `backup.cancel` takes. */
10559
+ id: string(),
10560
+ state: BackupRunStateSchema,
10561
+ phase: BackupRunPhaseSchema,
10562
+ /**
10563
+ * Resolved destination location ids. Empty while queued (targets are
10564
+ * resolved when the run starts, against the then-current policies).
10565
+ */
10566
+ destinationIds: array(string()).readonly(),
10567
+ label: string().optional(),
10568
+ /** ms-epoch when the run was submitted (trigger call / schedule fire). */
10569
+ requestedAt: number(),
10570
+ /** ms-epoch when the run left the queue and started building. */
10571
+ startedAt: number().optional(),
10572
+ /** ms-epoch when the run reached a terminal state. */
10573
+ finishedAt: number().optional(),
10574
+ /** Compressed bytes of the staging archive written so far. */
10575
+ stagedBytes: number(),
10576
+ /** Final staged archive size, once the build phase completes. */
10577
+ archiveSizeBytes: number().optional(),
10578
+ /** Bytes pushed to the destination currently uploading. */
10579
+ uploadedBytes: number(),
10580
+ /** Destinations where the archive fully landed (uploaded + indexed). */
10581
+ completedDestinationIds: array(string()).readonly(),
10582
+ /** Destinations that failed during the fan-out. */
10583
+ failedDestinationIds: array(string()).readonly(),
10584
+ /** Failure message when `state === 'failed'`. */
10585
+ error: string().optional(),
10586
+ /**
10587
+ * 1-based place in the execution queue — 1 = runs next. Present only
10588
+ * while `state === 'queued'`. Stamped by the orchestrator from the
10589
+ * queue's OWN pending order, never derived from timestamps, so the
10590
+ * UI cannot show an order the executor will not honour.
10591
+ */
10592
+ queuePosition: number().int().min(1).optional()
10593
+ });
10594
+ /**
10595
+ * Result of `backup.trigger`. The call still resolves when the run
10596
+ * terminates (compat with schedule-driven runs and the admin UI), but
10597
+ * it now names the run and says whether it had to WAIT: a trigger that
10598
+ * arrives while another run is in flight is enqueued (or joined onto
10599
+ * an identical already-queued run), never started concurrently.
10600
+ */
10601
+ var BackupTriggerResultSchema = object({
10602
+ /** The run this trigger mapped to — poll it via `listRuns`, stop it via `cancel`. */
10603
+ runId: string(),
10604
+ /** True when the run waited behind an in-flight run instead of starting immediately. */
10605
+ queued: boolean(),
10606
+ /** True when this trigger was coalesced onto an identical already-queued run. */
10607
+ joined: boolean(),
10608
+ /** True when the run was cancelled before completing every destination. */
10609
+ cancelled: boolean(),
10610
+ /** One entry per destination the archive landed at (partial on cancel). */
10611
+ entries: array(BackupEntrySchema).readonly()
10612
+ });
10530
10613
  /**
10531
10614
  * A backup schedule — the N:M "entry" that binds one cron cadence to a
10532
10615
  * SET of destination locations. Supersedes the per-location cron on
@@ -10574,7 +10657,10 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
10574
10657
  * retention (manual runs).
10575
10658
  */
10576
10659
  retentionCount: number().int().min(1).max(1e3).optional()
10577
- }).optional(), array(BackupEntrySchema).readonly(), {
10660
+ }).optional(), BackupTriggerResultSchema, {
10661
+ kind: "mutation",
10662
+ auth: "admin"
10663
+ }), method(_void(), array(BackupRunSchema).readonly(), { auth: "admin" }), method(object({ runId: string() }), object({ cancelled: boolean() }), {
10578
10664
  kind: "mutation",
10579
10665
  auth: "admin"
10580
10666
  }), method(_void(), array(BackupEntrySchema).readonly(), { auth: "admin" }), method(_void(), array(LocationStatSchema).readonly(), { auth: "admin" }), method(object({
@@ -11291,6 +11377,14 @@ method(object({
11291
11377
  }), object({ success: literal(true) }), {
11292
11378
  kind: "mutation",
11293
11379
  auth: "admin"
11380
+ }), method(object({ deviceId: number().int().nonnegative() }), object({
11381
+ derivedStreamsDeleted: array(string()).readonly(),
11382
+ assignmentsPurged: boolean(),
11383
+ probeSnapshotsDropped: number().int().nonnegative(),
11384
+ rtspTokenRowsDeleted: number().int().nonnegative()
11385
+ }), {
11386
+ kind: "mutation",
11387
+ auth: "admin"
11294
11388
  }), method(object({
11295
11389
  deviceId: number(),
11296
11390
  /** Absent = the LOWEST assigned profile — a notification attachment is
@@ -18896,7 +18990,20 @@ var RecentTracksQueryInput = object({
18896
18990
  projection: TrackProjectionSchema.optional(),
18897
18991
  /** Include stationary-promoted rows (parked objects). Default false: the
18898
18992
  * feed lists passages; parking records live on the stationary registry. */
18899
- includeStationary: boolean().optional()
18993
+ includeStationary: boolean().optional(),
18994
+ /**
18995
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
18996
+ *
18997
+ * The same filter `listTracks` takes, because the timeline's class chips must
18998
+ * mean the same thing whether the scope is one camera or twelve. Until this
18999
+ * existed the scoped feed downloaded a page and narrowed it on the phone
19000
+ * while the single-camera path narrowed the read — one filter, two costs.
19001
+ *
19002
+ * A SUPERSET prefilter on `classes[]`, like its single-camera twin: rows
19003
+ * whose class list is unreadable are kept, and the client's rule stays the
19004
+ * exact one.
19005
+ */
19006
+ classes: array(string()).optional()
18900
19007
  });
18901
19008
  var RecentTracksPageSchema = object({
18902
19009
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -23038,8 +23145,22 @@ DeviceType.Automation, method(object({ deviceId: number().int().nonnegative() })
23038
23145
  * threshold.
23039
23146
  */
23040
23147
  var BatteryStatusSchema = object({
23041
- /** 0..100 inclusive. Firmware-reported. */
23042
- percentage: number().min(0).max(100),
23148
+ /**
23149
+ * 0..100 inclusive, firmware-reported. **`null` means NOT YET KNOWN** — the
23150
+ * provider has registered the capability but no reading has landed.
23151
+ *
23152
+ * It is nullable because it was not, and the only value a provider could
23153
+ * seed with was `0`. A battery camera behind an NVR therefore announced
23154
+ * itself at 0% on every start and corrected itself a moment later, which is
23155
+ * indistinguishable from a real flat battery: it fires the low-battery alert
23156
+ * every time the hub restarts. Unknown is not empty (D315), and on a battery
23157
+ * reading the difference is an alarm.
23158
+ *
23159
+ * `vacuum-control` and `lawn-mower-control` already model it this way.
23160
+ * Consumers must SKIP a null rather than coerce it — `battery-band` already
23161
+ * declines to band a non-finite reading, which is the correct shape.
23162
+ */
23163
+ percentage: number().min(0).max(100).nullable(),
23043
23164
  /**
23044
23165
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23045
23166
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -29970,6 +30091,12 @@ Object.freeze({
29970
30091
  addonId: null,
29971
30092
  access: "create"
29972
30093
  },
30094
+ "backup.cancel": {
30095
+ capName: "backup",
30096
+ capScope: "system",
30097
+ addonId: null,
30098
+ access: "create"
30099
+ },
29973
30100
  "backup.delete": {
29974
30101
  capName: "backup",
29975
30102
  capScope: "system",
@@ -30012,6 +30139,12 @@ Object.freeze({
30012
30139
  addonId: null,
30013
30140
  access: "view"
30014
30141
  },
30142
+ "backup.listRuns": {
30143
+ capName: "backup",
30144
+ capScope: "system",
30145
+ addonId: null,
30146
+ access: "view"
30147
+ },
30015
30148
  "backup.listSchedules": {
30016
30149
  capName: "backup",
30017
30150
  capScope: "system",
@@ -34578,6 +34711,12 @@ Object.freeze({
34578
34711
  addonId: null,
34579
34712
  access: "create"
34580
34713
  },
34714
+ "streamBroker.forgetDeviceHardware": {
34715
+ capName: "stream-broker",
34716
+ capScope: "system",
34717
+ addonId: null,
34718
+ access: "delete"
34719
+ },
34581
34720
  "streamBroker.getAllRtspEntries": {
34582
34721
  capName: "stream-broker",
34583
34722
  capScope: "system",
@@ -37036,6 +37175,11 @@ Object.freeze({
37036
37175
  form: "single",
37037
37176
  optional: false
37038
37177
  }],
37178
+ "streamBroker.forgetDeviceHardware": [{
37179
+ name: "deviceId",
37180
+ form: "single",
37181
+ optional: false
37182
+ }],
37039
37183
  "streamBroker.getDeviceAudioMute": [{
37040
37184
  name: "deviceId",
37041
37185
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-onvif",
3
- "version": "1.2.56",
3
+ "version": "1.2.58",
4
4
  "description": "ONVIF camera device provider addon for CamStack",
5
5
  "keywords": [
6
6
  "camstack",