@camstack/addon-provider-rademacher 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
@@ -11512,6 +11512,89 @@ var LocationStatSchema = object({
11512
11512
  fileCount: number(),
11513
11513
  present: boolean()
11514
11514
  });
11515
+ /** Lifecycle of a backup run. Terminal states: succeeded / failed / cancelled. */
11516
+ var BackupRunStateSchema = _enum([
11517
+ "queued",
11518
+ "running",
11519
+ "succeeded",
11520
+ "failed",
11521
+ "cancelled"
11522
+ ]);
11523
+ /**
11524
+ * Where a running backup currently is. `queued` before it starts,
11525
+ * `building` while the tar.gz is being staged, `uploading` during the
11526
+ * per-destination fan-out, `done` once terminal.
11527
+ */
11528
+ var BackupRunPhaseSchema = _enum([
11529
+ "queued",
11530
+ "building",
11531
+ "uploading",
11532
+ "done"
11533
+ ]);
11534
+ /**
11535
+ * Observable state of one backup run — readable WHILE it runs via
11536
+ * `backup.listRuns`. This is what makes the execution queue and
11537
+ * `backup.cancel` usable: the 2026-09-04 incident (two concurrent
11538
+ * multi-GB builds, staging 5.1 GB → 18 GB, load 62) was only
11539
+ * diagnosable with `du` because nothing reported that runs existed or
11540
+ * how large the staged archive had grown.
11541
+ */
11542
+ var BackupRunSchema = object({
11543
+ /** Stable run id — the handle `backup.cancel` takes. */
11544
+ id: string(),
11545
+ state: BackupRunStateSchema,
11546
+ phase: BackupRunPhaseSchema,
11547
+ /**
11548
+ * Resolved destination location ids. Empty while queued (targets are
11549
+ * resolved when the run starts, against the then-current policies).
11550
+ */
11551
+ destinationIds: array(string()).readonly(),
11552
+ label: string().optional(),
11553
+ /** ms-epoch when the run was submitted (trigger call / schedule fire). */
11554
+ requestedAt: number(),
11555
+ /** ms-epoch when the run left the queue and started building. */
11556
+ startedAt: number().optional(),
11557
+ /** ms-epoch when the run reached a terminal state. */
11558
+ finishedAt: number().optional(),
11559
+ /** Compressed bytes of the staging archive written so far. */
11560
+ stagedBytes: number(),
11561
+ /** Final staged archive size, once the build phase completes. */
11562
+ archiveSizeBytes: number().optional(),
11563
+ /** Bytes pushed to the destination currently uploading. */
11564
+ uploadedBytes: number(),
11565
+ /** Destinations where the archive fully landed (uploaded + indexed). */
11566
+ completedDestinationIds: array(string()).readonly(),
11567
+ /** Destinations that failed during the fan-out. */
11568
+ failedDestinationIds: array(string()).readonly(),
11569
+ /** Failure message when `state === 'failed'`. */
11570
+ error: string().optional(),
11571
+ /**
11572
+ * 1-based place in the execution queue — 1 = runs next. Present only
11573
+ * while `state === 'queued'`. Stamped by the orchestrator from the
11574
+ * queue's OWN pending order, never derived from timestamps, so the
11575
+ * UI cannot show an order the executor will not honour.
11576
+ */
11577
+ queuePosition: number().int().min(1).optional()
11578
+ });
11579
+ /**
11580
+ * Result of `backup.trigger`. The call still resolves when the run
11581
+ * terminates (compat with schedule-driven runs and the admin UI), but
11582
+ * it now names the run and says whether it had to WAIT: a trigger that
11583
+ * arrives while another run is in flight is enqueued (or joined onto
11584
+ * an identical already-queued run), never started concurrently.
11585
+ */
11586
+ var BackupTriggerResultSchema = object({
11587
+ /** The run this trigger mapped to — poll it via `listRuns`, stop it via `cancel`. */
11588
+ runId: string(),
11589
+ /** True when the run waited behind an in-flight run instead of starting immediately. */
11590
+ queued: boolean(),
11591
+ /** True when this trigger was coalesced onto an identical already-queued run. */
11592
+ joined: boolean(),
11593
+ /** True when the run was cancelled before completing every destination. */
11594
+ cancelled: boolean(),
11595
+ /** One entry per destination the archive landed at (partial on cancel). */
11596
+ entries: array(BackupEntrySchema).readonly()
11597
+ });
11515
11598
  /**
11516
11599
  * A backup schedule — the N:M "entry" that binds one cron cadence to a
11517
11600
  * SET of destination locations. Supersedes the per-location cron on
@@ -11559,7 +11642,10 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
11559
11642
  * retention (manual runs).
11560
11643
  */
11561
11644
  retentionCount: number().int().min(1).max(1e3).optional()
11562
- }).optional(), array(BackupEntrySchema).readonly(), {
11645
+ }).optional(), BackupTriggerResultSchema, {
11646
+ kind: "mutation",
11647
+ auth: "admin"
11648
+ }), method(_void(), array(BackupRunSchema).readonly(), { auth: "admin" }), method(object({ runId: string() }), object({ cancelled: boolean() }), {
11563
11649
  kind: "mutation",
11564
11650
  auth: "admin"
11565
11651
  }), method(_void(), array(BackupEntrySchema).readonly(), { auth: "admin" }), method(_void(), array(LocationStatSchema).readonly(), { auth: "admin" }), method(object({
@@ -12276,6 +12362,14 @@ method(object({
12276
12362
  }), object({ success: literal(true) }), {
12277
12363
  kind: "mutation",
12278
12364
  auth: "admin"
12365
+ }), method(object({ deviceId: number().int().nonnegative() }), object({
12366
+ derivedStreamsDeleted: array(string()).readonly(),
12367
+ assignmentsPurged: boolean(),
12368
+ probeSnapshotsDropped: number().int().nonnegative(),
12369
+ rtspTokenRowsDeleted: number().int().nonnegative()
12370
+ }), {
12371
+ kind: "mutation",
12372
+ auth: "admin"
12279
12373
  }), method(object({
12280
12374
  deviceId: number(),
12281
12375
  /** Absent = the LOWEST assigned profile — a notification attachment is
@@ -20168,7 +20262,20 @@ var RecentTracksQueryInput = object({
20168
20262
  projection: TrackProjectionSchema.optional(),
20169
20263
  /** Include stationary-promoted rows (parked objects). Default false: the
20170
20264
  * feed lists passages; parking records live on the stationary registry. */
20171
- includeStationary: boolean().optional()
20265
+ includeStationary: boolean().optional(),
20266
+ /**
20267
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
20268
+ *
20269
+ * The same filter `listTracks` takes, because the timeline's class chips must
20270
+ * mean the same thing whether the scope is one camera or twelve. Until this
20271
+ * existed the scoped feed downloaded a page and narrowed it on the phone
20272
+ * while the single-camera path narrowed the read — one filter, two costs.
20273
+ *
20274
+ * A SUPERSET prefilter on `classes[]`, like its single-camera twin: rows
20275
+ * whose class list is unreadable are kept, and the client's rule stays the
20276
+ * exact one.
20277
+ */
20278
+ classes: array(string()).optional()
20172
20279
  });
20173
20280
  var RecentTracksPageSchema = object({
20174
20281
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -24338,8 +24445,22 @@ var automationControlCapability = {
24338
24445
  * threshold.
24339
24446
  */
24340
24447
  var BatteryStatusSchema = object({
24341
- /** 0..100 inclusive. Firmware-reported. */
24342
- percentage: number().min(0).max(100),
24448
+ /**
24449
+ * 0..100 inclusive, firmware-reported. **`null` means NOT YET KNOWN** — the
24450
+ * provider has registered the capability but no reading has landed.
24451
+ *
24452
+ * It is nullable because it was not, and the only value a provider could
24453
+ * seed with was `0`. A battery camera behind an NVR therefore announced
24454
+ * itself at 0% on every start and corrected itself a moment later, which is
24455
+ * indistinguishable from a real flat battery: it fires the low-battery alert
24456
+ * every time the hub restarts. Unknown is not empty (D315), and on a battery
24457
+ * reading the difference is an alarm.
24458
+ *
24459
+ * `vacuum-control` and `lawn-mower-control` already model it this way.
24460
+ * Consumers must SKIP a null rather than coerce it — `battery-band` already
24461
+ * declines to band a non-finite reading, which is the correct shape.
24462
+ */
24463
+ percentage: number().min(0).max(100).nullable(),
24343
24464
  /**
24344
24465
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
24345
24466
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -34100,6 +34221,12 @@ Object.freeze({
34100
34221
  addonId: null,
34101
34222
  access: "create"
34102
34223
  },
34224
+ "backup.cancel": {
34225
+ capName: "backup",
34226
+ capScope: "system",
34227
+ addonId: null,
34228
+ access: "create"
34229
+ },
34103
34230
  "backup.delete": {
34104
34231
  capName: "backup",
34105
34232
  capScope: "system",
@@ -34142,6 +34269,12 @@ Object.freeze({
34142
34269
  addonId: null,
34143
34270
  access: "view"
34144
34271
  },
34272
+ "backup.listRuns": {
34273
+ capName: "backup",
34274
+ capScope: "system",
34275
+ addonId: null,
34276
+ access: "view"
34277
+ },
34145
34278
  "backup.listSchedules": {
34146
34279
  capName: "backup",
34147
34280
  capScope: "system",
@@ -38708,6 +38841,12 @@ Object.freeze({
38708
38841
  addonId: null,
38709
38842
  access: "create"
38710
38843
  },
38844
+ "streamBroker.forgetDeviceHardware": {
38845
+ capName: "stream-broker",
38846
+ capScope: "system",
38847
+ addonId: null,
38848
+ access: "delete"
38849
+ },
38711
38850
  "streamBroker.getAllRtspEntries": {
38712
38851
  capName: "stream-broker",
38713
38852
  capScope: "system",
@@ -41166,6 +41305,11 @@ Object.freeze({
41166
41305
  form: "single",
41167
41306
  optional: false
41168
41307
  }],
41308
+ "streamBroker.forgetDeviceHardware": [{
41309
+ name: "deviceId",
41310
+ form: "single",
41311
+ optional: false
41312
+ }],
41169
41313
  "streamBroker.getDeviceAudioMute": [{
41170
41314
  name: "deviceId",
41171
41315
  form: "single",
package/dist/addon.mjs CHANGED
@@ -11511,6 +11511,89 @@ var LocationStatSchema = object({
11511
11511
  fileCount: number(),
11512
11512
  present: boolean()
11513
11513
  });
11514
+ /** Lifecycle of a backup run. Terminal states: succeeded / failed / cancelled. */
11515
+ var BackupRunStateSchema = _enum([
11516
+ "queued",
11517
+ "running",
11518
+ "succeeded",
11519
+ "failed",
11520
+ "cancelled"
11521
+ ]);
11522
+ /**
11523
+ * Where a running backup currently is. `queued` before it starts,
11524
+ * `building` while the tar.gz is being staged, `uploading` during the
11525
+ * per-destination fan-out, `done` once terminal.
11526
+ */
11527
+ var BackupRunPhaseSchema = _enum([
11528
+ "queued",
11529
+ "building",
11530
+ "uploading",
11531
+ "done"
11532
+ ]);
11533
+ /**
11534
+ * Observable state of one backup run — readable WHILE it runs via
11535
+ * `backup.listRuns`. This is what makes the execution queue and
11536
+ * `backup.cancel` usable: the 2026-09-04 incident (two concurrent
11537
+ * multi-GB builds, staging 5.1 GB → 18 GB, load 62) was only
11538
+ * diagnosable with `du` because nothing reported that runs existed or
11539
+ * how large the staged archive had grown.
11540
+ */
11541
+ var BackupRunSchema = object({
11542
+ /** Stable run id — the handle `backup.cancel` takes. */
11543
+ id: string(),
11544
+ state: BackupRunStateSchema,
11545
+ phase: BackupRunPhaseSchema,
11546
+ /**
11547
+ * Resolved destination location ids. Empty while queued (targets are
11548
+ * resolved when the run starts, against the then-current policies).
11549
+ */
11550
+ destinationIds: array(string()).readonly(),
11551
+ label: string().optional(),
11552
+ /** ms-epoch when the run was submitted (trigger call / schedule fire). */
11553
+ requestedAt: number(),
11554
+ /** ms-epoch when the run left the queue and started building. */
11555
+ startedAt: number().optional(),
11556
+ /** ms-epoch when the run reached a terminal state. */
11557
+ finishedAt: number().optional(),
11558
+ /** Compressed bytes of the staging archive written so far. */
11559
+ stagedBytes: number(),
11560
+ /** Final staged archive size, once the build phase completes. */
11561
+ archiveSizeBytes: number().optional(),
11562
+ /** Bytes pushed to the destination currently uploading. */
11563
+ uploadedBytes: number(),
11564
+ /** Destinations where the archive fully landed (uploaded + indexed). */
11565
+ completedDestinationIds: array(string()).readonly(),
11566
+ /** Destinations that failed during the fan-out. */
11567
+ failedDestinationIds: array(string()).readonly(),
11568
+ /** Failure message when `state === 'failed'`. */
11569
+ error: string().optional(),
11570
+ /**
11571
+ * 1-based place in the execution queue — 1 = runs next. Present only
11572
+ * while `state === 'queued'`. Stamped by the orchestrator from the
11573
+ * queue's OWN pending order, never derived from timestamps, so the
11574
+ * UI cannot show an order the executor will not honour.
11575
+ */
11576
+ queuePosition: number().int().min(1).optional()
11577
+ });
11578
+ /**
11579
+ * Result of `backup.trigger`. The call still resolves when the run
11580
+ * terminates (compat with schedule-driven runs and the admin UI), but
11581
+ * it now names the run and says whether it had to WAIT: a trigger that
11582
+ * arrives while another run is in flight is enqueued (or joined onto
11583
+ * an identical already-queued run), never started concurrently.
11584
+ */
11585
+ var BackupTriggerResultSchema = object({
11586
+ /** The run this trigger mapped to — poll it via `listRuns`, stop it via `cancel`. */
11587
+ runId: string(),
11588
+ /** True when the run waited behind an in-flight run instead of starting immediately. */
11589
+ queued: boolean(),
11590
+ /** True when this trigger was coalesced onto an identical already-queued run. */
11591
+ joined: boolean(),
11592
+ /** True when the run was cancelled before completing every destination. */
11593
+ cancelled: boolean(),
11594
+ /** One entry per destination the archive landed at (partial on cancel). */
11595
+ entries: array(BackupEntrySchema).readonly()
11596
+ });
11514
11597
  /**
11515
11598
  * A backup schedule — the N:M "entry" that binds one cron cadence to a
11516
11599
  * SET of destination locations. Supersedes the per-location cron on
@@ -11558,7 +11641,10 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
11558
11641
  * retention (manual runs).
11559
11642
  */
11560
11643
  retentionCount: number().int().min(1).max(1e3).optional()
11561
- }).optional(), array(BackupEntrySchema).readonly(), {
11644
+ }).optional(), BackupTriggerResultSchema, {
11645
+ kind: "mutation",
11646
+ auth: "admin"
11647
+ }), method(_void(), array(BackupRunSchema).readonly(), { auth: "admin" }), method(object({ runId: string() }), object({ cancelled: boolean() }), {
11562
11648
  kind: "mutation",
11563
11649
  auth: "admin"
11564
11650
  }), method(_void(), array(BackupEntrySchema).readonly(), { auth: "admin" }), method(_void(), array(LocationStatSchema).readonly(), { auth: "admin" }), method(object({
@@ -12275,6 +12361,14 @@ method(object({
12275
12361
  }), object({ success: literal(true) }), {
12276
12362
  kind: "mutation",
12277
12363
  auth: "admin"
12364
+ }), method(object({ deviceId: number().int().nonnegative() }), object({
12365
+ derivedStreamsDeleted: array(string()).readonly(),
12366
+ assignmentsPurged: boolean(),
12367
+ probeSnapshotsDropped: number().int().nonnegative(),
12368
+ rtspTokenRowsDeleted: number().int().nonnegative()
12369
+ }), {
12370
+ kind: "mutation",
12371
+ auth: "admin"
12278
12372
  }), method(object({
12279
12373
  deviceId: number(),
12280
12374
  /** Absent = the LOWEST assigned profile — a notification attachment is
@@ -20167,7 +20261,20 @@ var RecentTracksQueryInput = object({
20167
20261
  projection: TrackProjectionSchema.optional(),
20168
20262
  /** Include stationary-promoted rows (parked objects). Default false: the
20169
20263
  * feed lists passages; parking records live on the stationary registry. */
20170
- includeStationary: boolean().optional()
20264
+ includeStationary: boolean().optional(),
20265
+ /**
20266
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
20267
+ *
20268
+ * The same filter `listTracks` takes, because the timeline's class chips must
20269
+ * mean the same thing whether the scope is one camera or twelve. Until this
20270
+ * existed the scoped feed downloaded a page and narrowed it on the phone
20271
+ * while the single-camera path narrowed the read — one filter, two costs.
20272
+ *
20273
+ * A SUPERSET prefilter on `classes[]`, like its single-camera twin: rows
20274
+ * whose class list is unreadable are kept, and the client's rule stays the
20275
+ * exact one.
20276
+ */
20277
+ classes: array(string()).optional()
20171
20278
  });
20172
20279
  var RecentTracksPageSchema = object({
20173
20280
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -24337,8 +24444,22 @@ var automationControlCapability = {
24337
24444
  * threshold.
24338
24445
  */
24339
24446
  var BatteryStatusSchema = object({
24340
- /** 0..100 inclusive. Firmware-reported. */
24341
- percentage: number().min(0).max(100),
24447
+ /**
24448
+ * 0..100 inclusive, firmware-reported. **`null` means NOT YET KNOWN** — the
24449
+ * provider has registered the capability but no reading has landed.
24450
+ *
24451
+ * It is nullable because it was not, and the only value a provider could
24452
+ * seed with was `0`. A battery camera behind an NVR therefore announced
24453
+ * itself at 0% on every start and corrected itself a moment later, which is
24454
+ * indistinguishable from a real flat battery: it fires the low-battery alert
24455
+ * every time the hub restarts. Unknown is not empty (D315), and on a battery
24456
+ * reading the difference is an alarm.
24457
+ *
24458
+ * `vacuum-control` and `lawn-mower-control` already model it this way.
24459
+ * Consumers must SKIP a null rather than coerce it — `battery-band` already
24460
+ * declines to band a non-finite reading, which is the correct shape.
24461
+ */
24462
+ percentage: number().min(0).max(100).nullable(),
24342
24463
  /**
24343
24464
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
24344
24465
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -34099,6 +34220,12 @@ Object.freeze({
34099
34220
  addonId: null,
34100
34221
  access: "create"
34101
34222
  },
34223
+ "backup.cancel": {
34224
+ capName: "backup",
34225
+ capScope: "system",
34226
+ addonId: null,
34227
+ access: "create"
34228
+ },
34102
34229
  "backup.delete": {
34103
34230
  capName: "backup",
34104
34231
  capScope: "system",
@@ -34141,6 +34268,12 @@ Object.freeze({
34141
34268
  addonId: null,
34142
34269
  access: "view"
34143
34270
  },
34271
+ "backup.listRuns": {
34272
+ capName: "backup",
34273
+ capScope: "system",
34274
+ addonId: null,
34275
+ access: "view"
34276
+ },
34144
34277
  "backup.listSchedules": {
34145
34278
  capName: "backup",
34146
34279
  capScope: "system",
@@ -38707,6 +38840,12 @@ Object.freeze({
38707
38840
  addonId: null,
38708
38841
  access: "create"
38709
38842
  },
38843
+ "streamBroker.forgetDeviceHardware": {
38844
+ capName: "stream-broker",
38845
+ capScope: "system",
38846
+ addonId: null,
38847
+ access: "delete"
38848
+ },
38710
38849
  "streamBroker.getAllRtspEntries": {
38711
38850
  capName: "stream-broker",
38712
38851
  capScope: "system",
@@ -41165,6 +41304,11 @@ Object.freeze({
41165
41304
  form: "single",
41166
41305
  optional: false
41167
41306
  }],
41307
+ "streamBroker.forgetDeviceHardware": [{
41308
+ name: "deviceId",
41309
+ form: "single",
41310
+ optional: false
41311
+ }],
41168
41312
  "streamBroker.getDeviceAudioMute": [{
41169
41313
  name: "deviceId",
41170
41314
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-rademacher",
3
- "version": "0.2.56",
3
+ "version": "0.2.58",
4
4
  "description": "Rademacher HomePilot device-provider addon for CamStack — wraps the @apocaliss92/noderademacher local-hub client (roller shutters over the cover cap)",
5
5
  "keywords": [
6
6
  "camstack",