@camstack/addon-matter-broker 0.2.56 → 0.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
@@ -10541,6 +10541,89 @@ var LocationStatSchema = object({
10541
10541
  fileCount: number(),
10542
10542
  present: boolean()
10543
10543
  });
10544
+ /** Lifecycle of a backup run. Terminal states: succeeded / failed / cancelled. */
10545
+ var BackupRunStateSchema = _enum([
10546
+ "queued",
10547
+ "running",
10548
+ "succeeded",
10549
+ "failed",
10550
+ "cancelled"
10551
+ ]);
10552
+ /**
10553
+ * Where a running backup currently is. `queued` before it starts,
10554
+ * `building` while the tar.gz is being staged, `uploading` during the
10555
+ * per-destination fan-out, `done` once terminal.
10556
+ */
10557
+ var BackupRunPhaseSchema = _enum([
10558
+ "queued",
10559
+ "building",
10560
+ "uploading",
10561
+ "done"
10562
+ ]);
10563
+ /**
10564
+ * Observable state of one backup run — readable WHILE it runs via
10565
+ * `backup.listRuns`. This is what makes the execution queue and
10566
+ * `backup.cancel` usable: the 2026-09-04 incident (two concurrent
10567
+ * multi-GB builds, staging 5.1 GB → 18 GB, load 62) was only
10568
+ * diagnosable with `du` because nothing reported that runs existed or
10569
+ * how large the staged archive had grown.
10570
+ */
10571
+ var BackupRunSchema = object({
10572
+ /** Stable run id — the handle `backup.cancel` takes. */
10573
+ id: string$2(),
10574
+ state: BackupRunStateSchema,
10575
+ phase: BackupRunPhaseSchema,
10576
+ /**
10577
+ * Resolved destination location ids. Empty while queued (targets are
10578
+ * resolved when the run starts, against the then-current policies).
10579
+ */
10580
+ destinationIds: array(string$2()).readonly(),
10581
+ label: string$2().optional(),
10582
+ /** ms-epoch when the run was submitted (trigger call / schedule fire). */
10583
+ requestedAt: number(),
10584
+ /** ms-epoch when the run left the queue and started building. */
10585
+ startedAt: number().optional(),
10586
+ /** ms-epoch when the run reached a terminal state. */
10587
+ finishedAt: number().optional(),
10588
+ /** Compressed bytes of the staging archive written so far. */
10589
+ stagedBytes: number(),
10590
+ /** Final staged archive size, once the build phase completes. */
10591
+ archiveSizeBytes: number().optional(),
10592
+ /** Bytes pushed to the destination currently uploading. */
10593
+ uploadedBytes: number(),
10594
+ /** Destinations where the archive fully landed (uploaded + indexed). */
10595
+ completedDestinationIds: array(string$2()).readonly(),
10596
+ /** Destinations that failed during the fan-out. */
10597
+ failedDestinationIds: array(string$2()).readonly(),
10598
+ /** Failure message when `state === 'failed'`. */
10599
+ error: string$2().optional(),
10600
+ /**
10601
+ * 1-based place in the execution queue — 1 = runs next. Present only
10602
+ * while `state === 'queued'`. Stamped by the orchestrator from the
10603
+ * queue's OWN pending order, never derived from timestamps, so the
10604
+ * UI cannot show an order the executor will not honour.
10605
+ */
10606
+ queuePosition: number().int().min(1).optional()
10607
+ });
10608
+ /**
10609
+ * Result of `backup.trigger`. The call still resolves when the run
10610
+ * terminates (compat with schedule-driven runs and the admin UI), but
10611
+ * it now names the run and says whether it had to WAIT: a trigger that
10612
+ * arrives while another run is in flight is enqueued (or joined onto
10613
+ * an identical already-queued run), never started concurrently.
10614
+ */
10615
+ var BackupTriggerResultSchema = object({
10616
+ /** The run this trigger mapped to — poll it via `listRuns`, stop it via `cancel`. */
10617
+ runId: string$2(),
10618
+ /** True when the run waited behind an in-flight run instead of starting immediately. */
10619
+ queued: boolean(),
10620
+ /** True when this trigger was coalesced onto an identical already-queued run. */
10621
+ joined: boolean(),
10622
+ /** True when the run was cancelled before completing every destination. */
10623
+ cancelled: boolean(),
10624
+ /** One entry per destination the archive landed at (partial on cancel). */
10625
+ entries: array(BackupEntrySchema).readonly()
10626
+ });
10544
10627
  /**
10545
10628
  * A backup schedule — the N:M "entry" that binds one cron cadence to a
10546
10629
  * SET of destination locations. Supersedes the per-location cron on
@@ -10588,7 +10671,10 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
10588
10671
  * retention (manual runs).
10589
10672
  */
10590
10673
  retentionCount: number().int().min(1).max(1e3).optional()
10591
- }).optional(), array(BackupEntrySchema).readonly(), {
10674
+ }).optional(), BackupTriggerResultSchema, {
10675
+ kind: "mutation",
10676
+ auth: "admin"
10677
+ }), method(_void(), array(BackupRunSchema).readonly(), { auth: "admin" }), method(object({ runId: string$2() }), object({ cancelled: boolean() }), {
10592
10678
  kind: "mutation",
10593
10679
  auth: "admin"
10594
10680
  }), method(_void(), array(BackupEntrySchema).readonly(), { auth: "admin" }), method(_void(), array(LocationStatSchema).readonly(), { auth: "admin" }), method(object({
@@ -11354,6 +11440,14 @@ method(object({
11354
11440
  }), object({ success: literal(true) }), {
11355
11441
  kind: "mutation",
11356
11442
  auth: "admin"
11443
+ }), method(object({ deviceId: number().int().nonnegative() }), object({
11444
+ derivedStreamsDeleted: array(string$2()).readonly(),
11445
+ assignmentsPurged: boolean(),
11446
+ probeSnapshotsDropped: number().int().nonnegative(),
11447
+ rtspTokenRowsDeleted: number().int().nonnegative()
11448
+ }), {
11449
+ kind: "mutation",
11450
+ auth: "admin"
11357
11451
  }), method(object({
11358
11452
  deviceId: number(),
11359
11453
  /** Absent = the LOWEST assigned profile — a notification attachment is
@@ -19263,7 +19357,20 @@ var RecentTracksQueryInput = object({
19263
19357
  projection: TrackProjectionSchema.optional(),
19264
19358
  /** Include stationary-promoted rows (parked objects). Default false: the
19265
19359
  * feed lists passages; parking records live on the stationary registry. */
19266
- includeStationary: boolean().optional()
19360
+ includeStationary: boolean().optional(),
19361
+ /**
19362
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
19363
+ *
19364
+ * The same filter `listTracks` takes, because the timeline's class chips must
19365
+ * mean the same thing whether the scope is one camera or twelve. Until this
19366
+ * existed the scoped feed downloaded a page and narrowed it on the phone
19367
+ * while the single-camera path narrowed the read — one filter, two costs.
19368
+ *
19369
+ * A SUPERSET prefilter on `classes[]`, like its single-camera twin: rows
19370
+ * whose class list is unreadable are kept, and the client's rule stays the
19371
+ * exact one.
19372
+ */
19373
+ classes: array(string$2()).optional()
19267
19374
  });
19268
19375
  var RecentTracksPageSchema = object({
19269
19376
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -23433,8 +23540,22 @@ var automationControlCapability = {
23433
23540
  * threshold.
23434
23541
  */
23435
23542
  var BatteryStatusSchema = object({
23436
- /** 0..100 inclusive. Firmware-reported. */
23437
- percentage: number().min(0).max(100),
23543
+ /**
23544
+ * 0..100 inclusive, firmware-reported. **`null` means NOT YET KNOWN** — the
23545
+ * provider has registered the capability but no reading has landed.
23546
+ *
23547
+ * It is nullable because it was not, and the only value a provider could
23548
+ * seed with was `0`. A battery camera behind an NVR therefore announced
23549
+ * itself at 0% on every start and corrected itself a moment later, which is
23550
+ * indistinguishable from a real flat battery: it fires the low-battery alert
23551
+ * every time the hub restarts. Unknown is not empty (D315), and on a battery
23552
+ * reading the difference is an alarm.
23553
+ *
23554
+ * `vacuum-control` and `lawn-mower-control` already model it this way.
23555
+ * Consumers must SKIP a null rather than coerce it — `battery-band` already
23556
+ * declines to band a non-finite reading, which is the correct shape.
23557
+ */
23558
+ percentage: number().min(0).max(100).nullable(),
23438
23559
  /**
23439
23560
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23440
23561
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -33212,6 +33333,12 @@ Object.freeze({
33212
33333
  addonId: null,
33213
33334
  access: "create"
33214
33335
  },
33336
+ "backup.cancel": {
33337
+ capName: "backup",
33338
+ capScope: "system",
33339
+ addonId: null,
33340
+ access: "create"
33341
+ },
33215
33342
  "backup.delete": {
33216
33343
  capName: "backup",
33217
33344
  capScope: "system",
@@ -33254,6 +33381,12 @@ Object.freeze({
33254
33381
  addonId: null,
33255
33382
  access: "view"
33256
33383
  },
33384
+ "backup.listRuns": {
33385
+ capName: "backup",
33386
+ capScope: "system",
33387
+ addonId: null,
33388
+ access: "view"
33389
+ },
33257
33390
  "backup.listSchedules": {
33258
33391
  capName: "backup",
33259
33392
  capScope: "system",
@@ -37820,6 +37953,12 @@ Object.freeze({
37820
37953
  addonId: null,
37821
37954
  access: "create"
37822
37955
  },
37956
+ "streamBroker.forgetDeviceHardware": {
37957
+ capName: "stream-broker",
37958
+ capScope: "system",
37959
+ addonId: null,
37960
+ access: "delete"
37961
+ },
37823
37962
  "streamBroker.getAllRtspEntries": {
37824
37963
  capName: "stream-broker",
37825
37964
  capScope: "system",
@@ -40278,6 +40417,11 @@ Object.freeze({
40278
40417
  form: "single",
40279
40418
  optional: false
40280
40419
  }],
40420
+ "streamBroker.forgetDeviceHardware": [{
40421
+ name: "deviceId",
40422
+ form: "single",
40423
+ optional: false
40424
+ }],
40281
40425
  "streamBroker.getDeviceAudioMute": [{
40282
40426
  name: "deviceId",
40283
40427
  form: "single",
package/dist/addon.mjs CHANGED
@@ -10539,6 +10539,89 @@ var LocationStatSchema = object({
10539
10539
  fileCount: number(),
10540
10540
  present: boolean()
10541
10541
  });
10542
+ /** Lifecycle of a backup run. Terminal states: succeeded / failed / cancelled. */
10543
+ var BackupRunStateSchema = _enum([
10544
+ "queued",
10545
+ "running",
10546
+ "succeeded",
10547
+ "failed",
10548
+ "cancelled"
10549
+ ]);
10550
+ /**
10551
+ * Where a running backup currently is. `queued` before it starts,
10552
+ * `building` while the tar.gz is being staged, `uploading` during the
10553
+ * per-destination fan-out, `done` once terminal.
10554
+ */
10555
+ var BackupRunPhaseSchema = _enum([
10556
+ "queued",
10557
+ "building",
10558
+ "uploading",
10559
+ "done"
10560
+ ]);
10561
+ /**
10562
+ * Observable state of one backup run — readable WHILE it runs via
10563
+ * `backup.listRuns`. This is what makes the execution queue and
10564
+ * `backup.cancel` usable: the 2026-09-04 incident (two concurrent
10565
+ * multi-GB builds, staging 5.1 GB → 18 GB, load 62) was only
10566
+ * diagnosable with `du` because nothing reported that runs existed or
10567
+ * how large the staged archive had grown.
10568
+ */
10569
+ var BackupRunSchema = object({
10570
+ /** Stable run id — the handle `backup.cancel` takes. */
10571
+ id: string$2(),
10572
+ state: BackupRunStateSchema,
10573
+ phase: BackupRunPhaseSchema,
10574
+ /**
10575
+ * Resolved destination location ids. Empty while queued (targets are
10576
+ * resolved when the run starts, against the then-current policies).
10577
+ */
10578
+ destinationIds: array(string$2()).readonly(),
10579
+ label: string$2().optional(),
10580
+ /** ms-epoch when the run was submitted (trigger call / schedule fire). */
10581
+ requestedAt: number(),
10582
+ /** ms-epoch when the run left the queue and started building. */
10583
+ startedAt: number().optional(),
10584
+ /** ms-epoch when the run reached a terminal state. */
10585
+ finishedAt: number().optional(),
10586
+ /** Compressed bytes of the staging archive written so far. */
10587
+ stagedBytes: number(),
10588
+ /** Final staged archive size, once the build phase completes. */
10589
+ archiveSizeBytes: number().optional(),
10590
+ /** Bytes pushed to the destination currently uploading. */
10591
+ uploadedBytes: number(),
10592
+ /** Destinations where the archive fully landed (uploaded + indexed). */
10593
+ completedDestinationIds: array(string$2()).readonly(),
10594
+ /** Destinations that failed during the fan-out. */
10595
+ failedDestinationIds: array(string$2()).readonly(),
10596
+ /** Failure message when `state === 'failed'`. */
10597
+ error: string$2().optional(),
10598
+ /**
10599
+ * 1-based place in the execution queue — 1 = runs next. Present only
10600
+ * while `state === 'queued'`. Stamped by the orchestrator from the
10601
+ * queue's OWN pending order, never derived from timestamps, so the
10602
+ * UI cannot show an order the executor will not honour.
10603
+ */
10604
+ queuePosition: number().int().min(1).optional()
10605
+ });
10606
+ /**
10607
+ * Result of `backup.trigger`. The call still resolves when the run
10608
+ * terminates (compat with schedule-driven runs and the admin UI), but
10609
+ * it now names the run and says whether it had to WAIT: a trigger that
10610
+ * arrives while another run is in flight is enqueued (or joined onto
10611
+ * an identical already-queued run), never started concurrently.
10612
+ */
10613
+ var BackupTriggerResultSchema = object({
10614
+ /** The run this trigger mapped to — poll it via `listRuns`, stop it via `cancel`. */
10615
+ runId: string$2(),
10616
+ /** True when the run waited behind an in-flight run instead of starting immediately. */
10617
+ queued: boolean(),
10618
+ /** True when this trigger was coalesced onto an identical already-queued run. */
10619
+ joined: boolean(),
10620
+ /** True when the run was cancelled before completing every destination. */
10621
+ cancelled: boolean(),
10622
+ /** One entry per destination the archive landed at (partial on cancel). */
10623
+ entries: array(BackupEntrySchema).readonly()
10624
+ });
10542
10625
  /**
10543
10626
  * A backup schedule — the N:M "entry" that binds one cron cadence to a
10544
10627
  * SET of destination locations. Supersedes the per-location cron on
@@ -10586,7 +10669,10 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
10586
10669
  * retention (manual runs).
10587
10670
  */
10588
10671
  retentionCount: number().int().min(1).max(1e3).optional()
10589
- }).optional(), array(BackupEntrySchema).readonly(), {
10672
+ }).optional(), BackupTriggerResultSchema, {
10673
+ kind: "mutation",
10674
+ auth: "admin"
10675
+ }), method(_void(), array(BackupRunSchema).readonly(), { auth: "admin" }), method(object({ runId: string$2() }), object({ cancelled: boolean() }), {
10590
10676
  kind: "mutation",
10591
10677
  auth: "admin"
10592
10678
  }), method(_void(), array(BackupEntrySchema).readonly(), { auth: "admin" }), method(_void(), array(LocationStatSchema).readonly(), { auth: "admin" }), method(object({
@@ -11352,6 +11438,14 @@ method(object({
11352
11438
  }), object({ success: literal(true) }), {
11353
11439
  kind: "mutation",
11354
11440
  auth: "admin"
11441
+ }), method(object({ deviceId: number().int().nonnegative() }), object({
11442
+ derivedStreamsDeleted: array(string$2()).readonly(),
11443
+ assignmentsPurged: boolean(),
11444
+ probeSnapshotsDropped: number().int().nonnegative(),
11445
+ rtspTokenRowsDeleted: number().int().nonnegative()
11446
+ }), {
11447
+ kind: "mutation",
11448
+ auth: "admin"
11355
11449
  }), method(object({
11356
11450
  deviceId: number(),
11357
11451
  /** Absent = the LOWEST assigned profile — a notification attachment is
@@ -19261,7 +19355,20 @@ var RecentTracksQueryInput = object({
19261
19355
  projection: TrackProjectionSchema.optional(),
19262
19356
  /** Include stationary-promoted rows (parked objects). Default false: the
19263
19357
  * feed lists passages; parking records live on the stationary registry. */
19264
- includeStationary: boolean().optional()
19358
+ includeStationary: boolean().optional(),
19359
+ /**
19360
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
19361
+ *
19362
+ * The same filter `listTracks` takes, because the timeline's class chips must
19363
+ * mean the same thing whether the scope is one camera or twelve. Until this
19364
+ * existed the scoped feed downloaded a page and narrowed it on the phone
19365
+ * while the single-camera path narrowed the read — one filter, two costs.
19366
+ *
19367
+ * A SUPERSET prefilter on `classes[]`, like its single-camera twin: rows
19368
+ * whose class list is unreadable are kept, and the client's rule stays the
19369
+ * exact one.
19370
+ */
19371
+ classes: array(string$2()).optional()
19265
19372
  });
19266
19373
  var RecentTracksPageSchema = object({
19267
19374
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -23431,8 +23538,22 @@ var automationControlCapability = {
23431
23538
  * threshold.
23432
23539
  */
23433
23540
  var BatteryStatusSchema = object({
23434
- /** 0..100 inclusive. Firmware-reported. */
23435
- percentage: number().min(0).max(100),
23541
+ /**
23542
+ * 0..100 inclusive, firmware-reported. **`null` means NOT YET KNOWN** — the
23543
+ * provider has registered the capability but no reading has landed.
23544
+ *
23545
+ * It is nullable because it was not, and the only value a provider could
23546
+ * seed with was `0`. A battery camera behind an NVR therefore announced
23547
+ * itself at 0% on every start and corrected itself a moment later, which is
23548
+ * indistinguishable from a real flat battery: it fires the low-battery alert
23549
+ * every time the hub restarts. Unknown is not empty (D315), and on a battery
23550
+ * reading the difference is an alarm.
23551
+ *
23552
+ * `vacuum-control` and `lawn-mower-control` already model it this way.
23553
+ * Consumers must SKIP a null rather than coerce it — `battery-band` already
23554
+ * declines to band a non-finite reading, which is the correct shape.
23555
+ */
23556
+ percentage: number().min(0).max(100).nullable(),
23436
23557
  /**
23437
23558
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23438
23559
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -33210,6 +33331,12 @@ Object.freeze({
33210
33331
  addonId: null,
33211
33332
  access: "create"
33212
33333
  },
33334
+ "backup.cancel": {
33335
+ capName: "backup",
33336
+ capScope: "system",
33337
+ addonId: null,
33338
+ access: "create"
33339
+ },
33213
33340
  "backup.delete": {
33214
33341
  capName: "backup",
33215
33342
  capScope: "system",
@@ -33252,6 +33379,12 @@ Object.freeze({
33252
33379
  addonId: null,
33253
33380
  access: "view"
33254
33381
  },
33382
+ "backup.listRuns": {
33383
+ capName: "backup",
33384
+ capScope: "system",
33385
+ addonId: null,
33386
+ access: "view"
33387
+ },
33255
33388
  "backup.listSchedules": {
33256
33389
  capName: "backup",
33257
33390
  capScope: "system",
@@ -37818,6 +37951,12 @@ Object.freeze({
37818
37951
  addonId: null,
37819
37952
  access: "create"
37820
37953
  },
37954
+ "streamBroker.forgetDeviceHardware": {
37955
+ capName: "stream-broker",
37956
+ capScope: "system",
37957
+ addonId: null,
37958
+ access: "delete"
37959
+ },
37821
37960
  "streamBroker.getAllRtspEntries": {
37822
37961
  capName: "stream-broker",
37823
37962
  capScope: "system",
@@ -40276,6 +40415,11 @@ Object.freeze({
40276
40415
  form: "single",
40277
40416
  optional: false
40278
40417
  }],
40418
+ "streamBroker.forgetDeviceHardware": [{
40419
+ name: "deviceId",
40420
+ form: "single",
40421
+ optional: false
40422
+ }],
40279
40423
  "streamBroker.getDeviceAudioMute": [{
40280
40424
  name: "deviceId",
40281
40425
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-matter-broker",
3
- "version": "0.2.56",
3
+ "version": "0.2.58",
4
4
  "description": "Matter broker addon for CamStack — owns a Matter fabric (commissioning + the long-lived controller) via the matter.js controller and brokers commissioned Matter nodes into CamStack",
5
5
  "keywords": [
6
6
  "camstack",