@camstack/addon-provider-wyze 0.2.61 → 0.2.63

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
@@ -10559,6 +10559,89 @@ var LocationStatSchema = object({
10559
10559
  fileCount: number(),
10560
10560
  present: boolean()
10561
10561
  });
10562
+ /** Lifecycle of a backup run. Terminal states: succeeded / failed / cancelled. */
10563
+ var BackupRunStateSchema = _enum([
10564
+ "queued",
10565
+ "running",
10566
+ "succeeded",
10567
+ "failed",
10568
+ "cancelled"
10569
+ ]);
10570
+ /**
10571
+ * Where a running backup currently is. `queued` before it starts,
10572
+ * `building` while the tar.gz is being staged, `uploading` during the
10573
+ * per-destination fan-out, `done` once terminal.
10574
+ */
10575
+ var BackupRunPhaseSchema = _enum([
10576
+ "queued",
10577
+ "building",
10578
+ "uploading",
10579
+ "done"
10580
+ ]);
10581
+ /**
10582
+ * Observable state of one backup run — readable WHILE it runs via
10583
+ * `backup.listRuns`. This is what makes the execution queue and
10584
+ * `backup.cancel` usable: the 2026-09-04 incident (two concurrent
10585
+ * multi-GB builds, staging 5.1 GB → 18 GB, load 62) was only
10586
+ * diagnosable with `du` because nothing reported that runs existed or
10587
+ * how large the staged archive had grown.
10588
+ */
10589
+ var BackupRunSchema = object({
10590
+ /** Stable run id — the handle `backup.cancel` takes. */
10591
+ id: string(),
10592
+ state: BackupRunStateSchema,
10593
+ phase: BackupRunPhaseSchema,
10594
+ /**
10595
+ * Resolved destination location ids. Empty while queued (targets are
10596
+ * resolved when the run starts, against the then-current policies).
10597
+ */
10598
+ destinationIds: array(string()).readonly(),
10599
+ label: string().optional(),
10600
+ /** ms-epoch when the run was submitted (trigger call / schedule fire). */
10601
+ requestedAt: number(),
10602
+ /** ms-epoch when the run left the queue and started building. */
10603
+ startedAt: number().optional(),
10604
+ /** ms-epoch when the run reached a terminal state. */
10605
+ finishedAt: number().optional(),
10606
+ /** Compressed bytes of the staging archive written so far. */
10607
+ stagedBytes: number(),
10608
+ /** Final staged archive size, once the build phase completes. */
10609
+ archiveSizeBytes: number().optional(),
10610
+ /** Bytes pushed to the destination currently uploading. */
10611
+ uploadedBytes: number(),
10612
+ /** Destinations where the archive fully landed (uploaded + indexed). */
10613
+ completedDestinationIds: array(string()).readonly(),
10614
+ /** Destinations that failed during the fan-out. */
10615
+ failedDestinationIds: array(string()).readonly(),
10616
+ /** Failure message when `state === 'failed'`. */
10617
+ error: string().optional(),
10618
+ /**
10619
+ * 1-based place in the execution queue — 1 = runs next. Present only
10620
+ * while `state === 'queued'`. Stamped by the orchestrator from the
10621
+ * queue's OWN pending order, never derived from timestamps, so the
10622
+ * UI cannot show an order the executor will not honour.
10623
+ */
10624
+ queuePosition: number().int().min(1).optional()
10625
+ });
10626
+ /**
10627
+ * Result of `backup.trigger`. The call still resolves when the run
10628
+ * terminates (compat with schedule-driven runs and the admin UI), but
10629
+ * it now names the run and says whether it had to WAIT: a trigger that
10630
+ * arrives while another run is in flight is enqueued (or joined onto
10631
+ * an identical already-queued run), never started concurrently.
10632
+ */
10633
+ var BackupTriggerResultSchema = object({
10634
+ /** The run this trigger mapped to — poll it via `listRuns`, stop it via `cancel`. */
10635
+ runId: string(),
10636
+ /** True when the run waited behind an in-flight run instead of starting immediately. */
10637
+ queued: boolean(),
10638
+ /** True when this trigger was coalesced onto an identical already-queued run. */
10639
+ joined: boolean(),
10640
+ /** True when the run was cancelled before completing every destination. */
10641
+ cancelled: boolean(),
10642
+ /** One entry per destination the archive landed at (partial on cancel). */
10643
+ entries: array(BackupEntrySchema).readonly()
10644
+ });
10562
10645
  /**
10563
10646
  * A backup schedule — the N:M "entry" that binds one cron cadence to a
10564
10647
  * SET of destination locations. Supersedes the per-location cron on
@@ -10606,7 +10689,10 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
10606
10689
  * retention (manual runs).
10607
10690
  */
10608
10691
  retentionCount: number().int().min(1).max(1e3).optional()
10609
- }).optional(), array(BackupEntrySchema).readonly(), {
10692
+ }).optional(), BackupTriggerResultSchema, {
10693
+ kind: "mutation",
10694
+ auth: "admin"
10695
+ }), method(_void(), array(BackupRunSchema).readonly(), { auth: "admin" }), method(object({ runId: string() }), object({ cancelled: boolean() }), {
10610
10696
  kind: "mutation",
10611
10697
  auth: "admin"
10612
10698
  }), method(_void(), array(BackupEntrySchema).readonly(), { auth: "admin" }), method(_void(), array(LocationStatSchema).readonly(), { auth: "admin" }), method(object({
@@ -11323,6 +11409,14 @@ method(object({
11323
11409
  }), object({ success: literal(true) }), {
11324
11410
  kind: "mutation",
11325
11411
  auth: "admin"
11412
+ }), method(object({ deviceId: number().int().nonnegative() }), object({
11413
+ derivedStreamsDeleted: array(string()).readonly(),
11414
+ assignmentsPurged: boolean(),
11415
+ probeSnapshotsDropped: number().int().nonnegative(),
11416
+ rtspTokenRowsDeleted: number().int().nonnegative()
11417
+ }), {
11418
+ kind: "mutation",
11419
+ auth: "admin"
11326
11420
  }), method(object({
11327
11421
  deviceId: number(),
11328
11422
  /** Absent = the LOWEST assigned profile — a notification attachment is
@@ -19232,7 +19326,20 @@ var RecentTracksQueryInput = object({
19232
19326
  projection: TrackProjectionSchema.optional(),
19233
19327
  /** Include stationary-promoted rows (parked objects). Default false: the
19234
19328
  * feed lists passages; parking records live on the stationary registry. */
19235
- includeStationary: boolean().optional()
19329
+ includeStationary: boolean().optional(),
19330
+ /**
19331
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
19332
+ *
19333
+ * The same filter `listTracks` takes, because the timeline's class chips must
19334
+ * mean the same thing whether the scope is one camera or twelve. Until this
19335
+ * existed the scoped feed downloaded a page and narrowed it on the phone
19336
+ * while the single-camera path narrowed the read — one filter, two costs.
19337
+ *
19338
+ * A SUPERSET prefilter on `classes[]`, like its single-camera twin: rows
19339
+ * whose class list is unreadable are kept, and the client's rule stays the
19340
+ * exact one.
19341
+ */
19342
+ classes: array(string()).optional()
19236
19343
  });
19237
19344
  var RecentTracksPageSchema = object({
19238
19345
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -23506,8 +23613,22 @@ var automationControlCapability = {
23506
23613
  * threshold.
23507
23614
  */
23508
23615
  var BatteryStatusSchema = object({
23509
- /** 0..100 inclusive. Firmware-reported. */
23510
- percentage: number().min(0).max(100),
23616
+ /**
23617
+ * 0..100 inclusive, firmware-reported. **`null` means NOT YET KNOWN** — the
23618
+ * provider has registered the capability but no reading has landed.
23619
+ *
23620
+ * It is nullable because it was not, and the only value a provider could
23621
+ * seed with was `0`. A battery camera behind an NVR therefore announced
23622
+ * itself at 0% on every start and corrected itself a moment later, which is
23623
+ * indistinguishable from a real flat battery: it fires the low-battery alert
23624
+ * every time the hub restarts. Unknown is not empty (D315), and on a battery
23625
+ * reading the difference is an alarm.
23626
+ *
23627
+ * `vacuum-control` and `lawn-mower-control` already model it this way.
23628
+ * Consumers must SKIP a null rather than coerce it — `battery-band` already
23629
+ * declines to band a non-finite reading, which is the correct shape.
23630
+ */
23631
+ percentage: number().min(0).max(100).nullable(),
23511
23632
  /**
23512
23633
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23513
23634
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -33276,6 +33397,12 @@ Object.freeze({
33276
33397
  addonId: null,
33277
33398
  access: "create"
33278
33399
  },
33400
+ "backup.cancel": {
33401
+ capName: "backup",
33402
+ capScope: "system",
33403
+ addonId: null,
33404
+ access: "create"
33405
+ },
33279
33406
  "backup.delete": {
33280
33407
  capName: "backup",
33281
33408
  capScope: "system",
@@ -33318,6 +33445,12 @@ Object.freeze({
33318
33445
  addonId: null,
33319
33446
  access: "view"
33320
33447
  },
33448
+ "backup.listRuns": {
33449
+ capName: "backup",
33450
+ capScope: "system",
33451
+ addonId: null,
33452
+ access: "view"
33453
+ },
33321
33454
  "backup.listSchedules": {
33322
33455
  capName: "backup",
33323
33456
  capScope: "system",
@@ -37884,6 +38017,12 @@ Object.freeze({
37884
38017
  addonId: null,
37885
38018
  access: "create"
37886
38019
  },
38020
+ "streamBroker.forgetDeviceHardware": {
38021
+ capName: "stream-broker",
38022
+ capScope: "system",
38023
+ addonId: null,
38024
+ access: "delete"
38025
+ },
37887
38026
  "streamBroker.getAllRtspEntries": {
37888
38027
  capName: "stream-broker",
37889
38028
  capScope: "system",
@@ -40342,6 +40481,11 @@ Object.freeze({
40342
40481
  form: "single",
40343
40482
  optional: false
40344
40483
  }],
40484
+ "streamBroker.forgetDeviceHardware": [{
40485
+ name: "deviceId",
40486
+ form: "single",
40487
+ optional: false
40488
+ }],
40345
40489
  "streamBroker.getDeviceAudioMute": [{
40346
40490
  name: "deviceId",
40347
40491
  form: "single",
package/dist/addon.mjs CHANGED
@@ -10538,6 +10538,89 @@ var LocationStatSchema = object({
10538
10538
  fileCount: number(),
10539
10539
  present: boolean()
10540
10540
  });
10541
+ /** Lifecycle of a backup run. Terminal states: succeeded / failed / cancelled. */
10542
+ var BackupRunStateSchema = _enum([
10543
+ "queued",
10544
+ "running",
10545
+ "succeeded",
10546
+ "failed",
10547
+ "cancelled"
10548
+ ]);
10549
+ /**
10550
+ * Where a running backup currently is. `queued` before it starts,
10551
+ * `building` while the tar.gz is being staged, `uploading` during the
10552
+ * per-destination fan-out, `done` once terminal.
10553
+ */
10554
+ var BackupRunPhaseSchema = _enum([
10555
+ "queued",
10556
+ "building",
10557
+ "uploading",
10558
+ "done"
10559
+ ]);
10560
+ /**
10561
+ * Observable state of one backup run — readable WHILE it runs via
10562
+ * `backup.listRuns`. This is what makes the execution queue and
10563
+ * `backup.cancel` usable: the 2026-09-04 incident (two concurrent
10564
+ * multi-GB builds, staging 5.1 GB → 18 GB, load 62) was only
10565
+ * diagnosable with `du` because nothing reported that runs existed or
10566
+ * how large the staged archive had grown.
10567
+ */
10568
+ var BackupRunSchema = object({
10569
+ /** Stable run id — the handle `backup.cancel` takes. */
10570
+ id: string(),
10571
+ state: BackupRunStateSchema,
10572
+ phase: BackupRunPhaseSchema,
10573
+ /**
10574
+ * Resolved destination location ids. Empty while queued (targets are
10575
+ * resolved when the run starts, against the then-current policies).
10576
+ */
10577
+ destinationIds: array(string()).readonly(),
10578
+ label: string().optional(),
10579
+ /** ms-epoch when the run was submitted (trigger call / schedule fire). */
10580
+ requestedAt: number(),
10581
+ /** ms-epoch when the run left the queue and started building. */
10582
+ startedAt: number().optional(),
10583
+ /** ms-epoch when the run reached a terminal state. */
10584
+ finishedAt: number().optional(),
10585
+ /** Compressed bytes of the staging archive written so far. */
10586
+ stagedBytes: number(),
10587
+ /** Final staged archive size, once the build phase completes. */
10588
+ archiveSizeBytes: number().optional(),
10589
+ /** Bytes pushed to the destination currently uploading. */
10590
+ uploadedBytes: number(),
10591
+ /** Destinations where the archive fully landed (uploaded + indexed). */
10592
+ completedDestinationIds: array(string()).readonly(),
10593
+ /** Destinations that failed during the fan-out. */
10594
+ failedDestinationIds: array(string()).readonly(),
10595
+ /** Failure message when `state === 'failed'`. */
10596
+ error: string().optional(),
10597
+ /**
10598
+ * 1-based place in the execution queue — 1 = runs next. Present only
10599
+ * while `state === 'queued'`. Stamped by the orchestrator from the
10600
+ * queue's OWN pending order, never derived from timestamps, so the
10601
+ * UI cannot show an order the executor will not honour.
10602
+ */
10603
+ queuePosition: number().int().min(1).optional()
10604
+ });
10605
+ /**
10606
+ * Result of `backup.trigger`. The call still resolves when the run
10607
+ * terminates (compat with schedule-driven runs and the admin UI), but
10608
+ * it now names the run and says whether it had to WAIT: a trigger that
10609
+ * arrives while another run is in flight is enqueued (or joined onto
10610
+ * an identical already-queued run), never started concurrently.
10611
+ */
10612
+ var BackupTriggerResultSchema = object({
10613
+ /** The run this trigger mapped to — poll it via `listRuns`, stop it via `cancel`. */
10614
+ runId: string(),
10615
+ /** True when the run waited behind an in-flight run instead of starting immediately. */
10616
+ queued: boolean(),
10617
+ /** True when this trigger was coalesced onto an identical already-queued run. */
10618
+ joined: boolean(),
10619
+ /** True when the run was cancelled before completing every destination. */
10620
+ cancelled: boolean(),
10621
+ /** One entry per destination the archive landed at (partial on cancel). */
10622
+ entries: array(BackupEntrySchema).readonly()
10623
+ });
10541
10624
  /**
10542
10625
  * A backup schedule — the N:M "entry" that binds one cron cadence to a
10543
10626
  * SET of destination locations. Supersedes the per-location cron on
@@ -10585,7 +10668,10 @@ method(_void(), array(BackupDestinationInfoSchema).readonly(), { auth: "admin" }
10585
10668
  * retention (manual runs).
10586
10669
  */
10587
10670
  retentionCount: number().int().min(1).max(1e3).optional()
10588
- }).optional(), array(BackupEntrySchema).readonly(), {
10671
+ }).optional(), BackupTriggerResultSchema, {
10672
+ kind: "mutation",
10673
+ auth: "admin"
10674
+ }), method(_void(), array(BackupRunSchema).readonly(), { auth: "admin" }), method(object({ runId: string() }), object({ cancelled: boolean() }), {
10589
10675
  kind: "mutation",
10590
10676
  auth: "admin"
10591
10677
  }), method(_void(), array(BackupEntrySchema).readonly(), { auth: "admin" }), method(_void(), array(LocationStatSchema).readonly(), { auth: "admin" }), method(object({
@@ -11302,6 +11388,14 @@ method(object({
11302
11388
  }), object({ success: literal(true) }), {
11303
11389
  kind: "mutation",
11304
11390
  auth: "admin"
11391
+ }), method(object({ deviceId: number().int().nonnegative() }), object({
11392
+ derivedStreamsDeleted: array(string()).readonly(),
11393
+ assignmentsPurged: boolean(),
11394
+ probeSnapshotsDropped: number().int().nonnegative(),
11395
+ rtspTokenRowsDeleted: number().int().nonnegative()
11396
+ }), {
11397
+ kind: "mutation",
11398
+ auth: "admin"
11305
11399
  }), method(object({
11306
11400
  deviceId: number(),
11307
11401
  /** Absent = the LOWEST assigned profile — a notification attachment is
@@ -19211,7 +19305,20 @@ var RecentTracksQueryInput = object({
19211
19305
  projection: TrackProjectionSchema.optional(),
19212
19306
  /** Include stationary-promoted rows (parked objects). Default false: the
19213
19307
  * feed lists passages; parking records live on the stationary registry. */
19214
- includeStationary: boolean().optional()
19308
+ includeStationary: boolean().optional(),
19309
+ /**
19310
+ * Restrict to these track classes. ABSENT or EMPTY means no filter.
19311
+ *
19312
+ * The same filter `listTracks` takes, because the timeline's class chips must
19313
+ * mean the same thing whether the scope is one camera or twelve. Until this
19314
+ * existed the scoped feed downloaded a page and narrowed it on the phone
19315
+ * while the single-camera path narrowed the read — one filter, two costs.
19316
+ *
19317
+ * A SUPERSET prefilter on `classes[]`, like its single-camera twin: rows
19318
+ * whose class list is unreadable are kept, and the client's rule stays the
19319
+ * exact one.
19320
+ */
19321
+ classes: array(string()).optional()
19215
19322
  });
19216
19323
  var RecentTracksPageSchema = object({
19217
19324
  /** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
@@ -23485,8 +23592,22 @@ var automationControlCapability = {
23485
23592
  * threshold.
23486
23593
  */
23487
23594
  var BatteryStatusSchema = object({
23488
- /** 0..100 inclusive. Firmware-reported. */
23489
- percentage: number().min(0).max(100),
23595
+ /**
23596
+ * 0..100 inclusive, firmware-reported. **`null` means NOT YET KNOWN** — the
23597
+ * provider has registered the capability but no reading has landed.
23598
+ *
23599
+ * It is nullable because it was not, and the only value a provider could
23600
+ * seed with was `0`. A battery camera behind an NVR therefore announced
23601
+ * itself at 0% on every start and corrected itself a moment later, which is
23602
+ * indistinguishable from a real flat battery: it fires the low-battery alert
23603
+ * every time the hub restarts. Unknown is not empty (D315), and on a battery
23604
+ * reading the difference is an alarm.
23605
+ *
23606
+ * `vacuum-control` and `lawn-mower-control` already model it this way.
23607
+ * Consumers must SKIP a null rather than coerce it — `battery-band` already
23608
+ * declines to band a non-finite reading, which is the correct shape.
23609
+ */
23610
+ percentage: number().min(0).max(100).nullable(),
23490
23611
  /**
23491
23612
  * Charging source. `'dc'` covers wall/USB adapters; `'solar'` is
23492
23613
  * Reolink-specific for the Solar Panel 2 accessory (will become
@@ -33255,6 +33376,12 @@ Object.freeze({
33255
33376
  addonId: null,
33256
33377
  access: "create"
33257
33378
  },
33379
+ "backup.cancel": {
33380
+ capName: "backup",
33381
+ capScope: "system",
33382
+ addonId: null,
33383
+ access: "create"
33384
+ },
33258
33385
  "backup.delete": {
33259
33386
  capName: "backup",
33260
33387
  capScope: "system",
@@ -33297,6 +33424,12 @@ Object.freeze({
33297
33424
  addonId: null,
33298
33425
  access: "view"
33299
33426
  },
33427
+ "backup.listRuns": {
33428
+ capName: "backup",
33429
+ capScope: "system",
33430
+ addonId: null,
33431
+ access: "view"
33432
+ },
33300
33433
  "backup.listSchedules": {
33301
33434
  capName: "backup",
33302
33435
  capScope: "system",
@@ -37863,6 +37996,12 @@ Object.freeze({
37863
37996
  addonId: null,
37864
37997
  access: "create"
37865
37998
  },
37999
+ "streamBroker.forgetDeviceHardware": {
38000
+ capName: "stream-broker",
38001
+ capScope: "system",
38002
+ addonId: null,
38003
+ access: "delete"
38004
+ },
37866
38005
  "streamBroker.getAllRtspEntries": {
37867
38006
  capName: "stream-broker",
37868
38007
  capScope: "system",
@@ -40321,6 +40460,11 @@ Object.freeze({
40321
40460
  form: "single",
40322
40461
  optional: false
40323
40462
  }],
40463
+ "streamBroker.forgetDeviceHardware": [{
40464
+ name: "deviceId",
40465
+ form: "single",
40466
+ optional: false
40467
+ }],
40324
40468
  "streamBroker.getDeviceAudioMute": [{
40325
40469
  name: "deviceId",
40326
40470
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-wyze",
3
- "version": "0.2.61",
3
+ "version": "0.2.63",
4
4
  "description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
5
5
  "keywords": [
6
6
  "camstack",