@camstack/addon-provider-unifi 0.2.51 → 0.2.52

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
@@ -19191,6 +19191,34 @@ var KeyEventsForDeviceSchema = object({
19191
19191
  deviceId: number(),
19192
19192
  events: array(KeyEventSchema).readonly()
19193
19193
  });
19194
+ /** One non-empty bucket of the timeline histogram. */
19195
+ var EventDensityBucketSchema = object({
19196
+ bucketStart: number(),
19197
+ motion: number().int(),
19198
+ object: number().int(),
19199
+ audio: number().int()
19200
+ });
19201
+ /**
19202
+ * One camera's row in a `getEventDensityBatch` answer.
19203
+ *
19204
+ * TWO facts, and the timeline draws them differently:
19205
+ *
19206
+ * - `read: 'read'` — the histogram for this camera. `buckets: []` is a real
19207
+ * claim: read, and nothing happened in the window.
19208
+ * - `read: 'unreadable'` — nobody could answer for this camera. `buckets` is
19209
+ * empty and that emptiness means NOTHING; the timeline must render unknown,
19210
+ * not quiet.
19211
+ *
19212
+ * Fanned out per camera the difference was free — one query rejected while the
19213
+ * others resolved — and collapsing to a batch is the exact moment it is lost
19214
+ * silently. Every requested id gets a row: a caller that asked for twelve and
19215
+ * got eleven cannot tell which one is missing, or that any is.
19216
+ */
19217
+ var EventDensityForDeviceSchema = object({
19218
+ deviceId: number(),
19219
+ read: _enum(["read", "unreadable"]),
19220
+ buckets: array(EventDensityBucketSchema).readonly()
19221
+ });
19194
19222
  object({
19195
19223
  trackId: string(),
19196
19224
  className: string(),
@@ -19501,12 +19529,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19501
19529
  since: number(),
19502
19530
  until: number(),
19503
19531
  bucketMs: number().int().positive()
19504
- }), array(object({
19505
- bucketStart: number(),
19506
- motion: number().int(),
19507
- object: number().int(),
19508
- audio: number().int()
19509
- })).readonly()), method(object({
19532
+ }), array(EventDensityBucketSchema).readonly()), method(object({
19533
+ deviceIds: array(number()).min(1).max(200),
19534
+ since: number(),
19535
+ until: number(),
19536
+ bucketMs: number().int().positive()
19537
+ }), array(EventDensityForDeviceSchema).readonly()), method(object({
19510
19538
  deviceId: number(),
19511
19539
  cutoffMs: number()
19512
19540
  }), object({
@@ -28548,6 +28576,39 @@ var RecordingDaysSchema = object({
28548
28576
  /** Local-midnight epochs (UTC ms) of days that have ≥1 recorded segment. */
28549
28577
  days: array(number())
28550
28578
  });
28579
+ /**
28580
+ * One camera's row in a `getAvailabilityBatch` answer.
28581
+ *
28582
+ * `ranges` is EXACTLY what `getAvailability` returns for that camera — the
28583
+ * batch collapses the transport, not the work — plus the one thing the singular
28584
+ * method never had to say:
28585
+ *
28586
+ * - `read: 'read'` — answered. `ranges: []` means "read, and this camera has
28587
+ * no footage in the window", which is a real claim.
28588
+ * - `read: 'unreadable'` — the recorder could not answer for this camera (its
28589
+ * calendar rung threw, its location is unmounted). `ranges` is empty and
28590
+ * that emptiness means NOTHING.
28591
+ *
28592
+ * A timeline that renders the second as the first tells an operator there is no
28593
+ * footage when the truth is that nobody looked.
28594
+ */
28595
+ var RecordingAvailabilityForDeviceSchema = object({
28596
+ deviceId: number(),
28597
+ read: _enum(["read", "unreadable"]),
28598
+ ranges: array(RecordingRangeSchema).readonly()
28599
+ });
28600
+ /**
28601
+ * One camera's row in a `getDaysWithRecordingsBatch` answer. Same rule as
28602
+ * {@link RecordingAvailabilityForDeviceSchema}: `days: []` on a `'read'` row is
28603
+ * "no footage in this month", `read: 'unreadable'` is "nobody could look", and
28604
+ * the date-picker's day dots must not spell them the same.
28605
+ */
28606
+ var RecordingDaysForDeviceSchema = object({
28607
+ deviceId: number(),
28608
+ read: _enum(["read", "unreadable"]),
28609
+ /** Local-midnight epochs (UTC ms) of days that have ≥1 recorded segment. */
28610
+ days: array(number()).readonly()
28611
+ });
28551
28612
  var RecordingManifestSchema = object({
28552
28613
  deviceId: number(),
28553
28614
  /** Local filesystem path to the master playlist; null when no recording exists for the requested range. */
@@ -28782,6 +28843,13 @@ method(object({
28782
28843
  }), RecordingAvailabilitySchema, {
28783
28844
  kind: "query",
28784
28845
  auth: "protected"
28846
+ }), method(object({
28847
+ deviceIds: array(number()).min(1).max(200),
28848
+ fromMs: number(),
28849
+ toMs: number()
28850
+ }), array(RecordingAvailabilityForDeviceSchema).readonly(), {
28851
+ kind: "query",
28852
+ auth: "protected"
28785
28853
  }), method(object({
28786
28854
  deviceId: number(),
28787
28855
  fromMs: number(),
@@ -28790,6 +28858,14 @@ method(object({
28790
28858
  }), RecordingDaysSchema, {
28791
28859
  kind: "query",
28792
28860
  auth: "protected"
28861
+ }), method(object({
28862
+ deviceIds: array(number()).min(1).max(200),
28863
+ fromMs: number(),
28864
+ toMs: number(),
28865
+ tzOffsetMinutes: number()
28866
+ }), array(RecordingDaysForDeviceSchema).readonly(), {
28867
+ kind: "query",
28868
+ auth: "protected"
28793
28869
  }), method(object({
28794
28870
  deviceId: number(),
28795
28871
  fromMs: number(),
@@ -35686,6 +35762,12 @@ Object.freeze({
35686
35762
  addonId: null,
35687
35763
  access: "view"
35688
35764
  },
35765
+ "pipelineAnalytics.getEventDensityBatch": {
35766
+ capName: "pipeline-analytics",
35767
+ capScope: "device",
35768
+ addonId: null,
35769
+ access: "view"
35770
+ },
35689
35771
  "pipelineAnalytics.getEventMedia": {
35690
35772
  capName: "pipeline-analytics",
35691
35773
  capScope: "device",
@@ -36808,12 +36890,24 @@ Object.freeze({
36808
36890
  addonId: null,
36809
36891
  access: "view"
36810
36892
  },
36893
+ "recording.getAvailabilityBatch": {
36894
+ capName: "recording",
36895
+ capScope: "system",
36896
+ addonId: null,
36897
+ access: "view"
36898
+ },
36811
36899
  "recording.getDaysWithRecordings": {
36812
36900
  capName: "recording",
36813
36901
  capScope: "system",
36814
36902
  addonId: null,
36815
36903
  access: "view"
36816
36904
  },
36905
+ "recording.getDaysWithRecordingsBatch": {
36906
+ capName: "recording",
36907
+ capScope: "system",
36908
+ addonId: null,
36909
+ access: "view"
36910
+ },
36817
36911
  "recording.getDeviceConfig": {
36818
36912
  capName: "recording",
36819
36913
  capScope: "system",
@@ -39418,6 +39512,11 @@ Object.freeze({
39418
39512
  form: "single",
39419
39513
  optional: false
39420
39514
  }],
39515
+ "pipelineAnalytics.getEventDensityBatch": [{
39516
+ name: "deviceIds",
39517
+ form: "array",
39518
+ optional: false
39519
+ }],
39421
39520
  "pipelineAnalytics.getEventMedia": [{
39422
39521
  name: "deviceId",
39423
39522
  form: "single",
@@ -39833,11 +39932,21 @@ Object.freeze({
39833
39932
  form: "single",
39834
39933
  optional: false
39835
39934
  }],
39935
+ "recording.getAvailabilityBatch": [{
39936
+ name: "deviceIds",
39937
+ form: "array",
39938
+ optional: false
39939
+ }],
39836
39940
  "recording.getDaysWithRecordings": [{
39837
39941
  name: "deviceId",
39838
39942
  form: "single",
39839
39943
  optional: false
39840
39944
  }],
39945
+ "recording.getDaysWithRecordingsBatch": [{
39946
+ name: "deviceIds",
39947
+ form: "array",
39948
+ optional: false
39949
+ }],
39841
39950
  "recording.getDeviceConfig": [{
39842
39951
  name: "deviceId",
39843
39952
  form: "single",
package/dist/addon.mjs CHANGED
@@ -19190,6 +19190,34 @@ var KeyEventsForDeviceSchema = object({
19190
19190
  deviceId: number(),
19191
19191
  events: array(KeyEventSchema).readonly()
19192
19192
  });
19193
+ /** One non-empty bucket of the timeline histogram. */
19194
+ var EventDensityBucketSchema = object({
19195
+ bucketStart: number(),
19196
+ motion: number().int(),
19197
+ object: number().int(),
19198
+ audio: number().int()
19199
+ });
19200
+ /**
19201
+ * One camera's row in a `getEventDensityBatch` answer.
19202
+ *
19203
+ * TWO facts, and the timeline draws them differently:
19204
+ *
19205
+ * - `read: 'read'` — the histogram for this camera. `buckets: []` is a real
19206
+ * claim: read, and nothing happened in the window.
19207
+ * - `read: 'unreadable'` — nobody could answer for this camera. `buckets` is
19208
+ * empty and that emptiness means NOTHING; the timeline must render unknown,
19209
+ * not quiet.
19210
+ *
19211
+ * Fanned out per camera the difference was free — one query rejected while the
19212
+ * others resolved — and collapsing to a batch is the exact moment it is lost
19213
+ * silently. Every requested id gets a row: a caller that asked for twelve and
19214
+ * got eleven cannot tell which one is missing, or that any is.
19215
+ */
19216
+ var EventDensityForDeviceSchema = object({
19217
+ deviceId: number(),
19218
+ read: _enum(["read", "unreadable"]),
19219
+ buckets: array(EventDensityBucketSchema).readonly()
19220
+ });
19193
19221
  object({
19194
19222
  trackId: string(),
19195
19223
  className: string(),
@@ -19500,12 +19528,12 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19500
19528
  since: number(),
19501
19529
  until: number(),
19502
19530
  bucketMs: number().int().positive()
19503
- }), array(object({
19504
- bucketStart: number(),
19505
- motion: number().int(),
19506
- object: number().int(),
19507
- audio: number().int()
19508
- })).readonly()), method(object({
19531
+ }), array(EventDensityBucketSchema).readonly()), method(object({
19532
+ deviceIds: array(number()).min(1).max(200),
19533
+ since: number(),
19534
+ until: number(),
19535
+ bucketMs: number().int().positive()
19536
+ }), array(EventDensityForDeviceSchema).readonly()), method(object({
19509
19537
  deviceId: number(),
19510
19538
  cutoffMs: number()
19511
19539
  }), object({
@@ -28547,6 +28575,39 @@ var RecordingDaysSchema = object({
28547
28575
  /** Local-midnight epochs (UTC ms) of days that have ≥1 recorded segment. */
28548
28576
  days: array(number())
28549
28577
  });
28578
+ /**
28579
+ * One camera's row in a `getAvailabilityBatch` answer.
28580
+ *
28581
+ * `ranges` is EXACTLY what `getAvailability` returns for that camera — the
28582
+ * batch collapses the transport, not the work — plus the one thing the singular
28583
+ * method never had to say:
28584
+ *
28585
+ * - `read: 'read'` — answered. `ranges: []` means "read, and this camera has
28586
+ * no footage in the window", which is a real claim.
28587
+ * - `read: 'unreadable'` — the recorder could not answer for this camera (its
28588
+ * calendar rung threw, its location is unmounted). `ranges` is empty and
28589
+ * that emptiness means NOTHING.
28590
+ *
28591
+ * A timeline that renders the second as the first tells an operator there is no
28592
+ * footage when the truth is that nobody looked.
28593
+ */
28594
+ var RecordingAvailabilityForDeviceSchema = object({
28595
+ deviceId: number(),
28596
+ read: _enum(["read", "unreadable"]),
28597
+ ranges: array(RecordingRangeSchema).readonly()
28598
+ });
28599
+ /**
28600
+ * One camera's row in a `getDaysWithRecordingsBatch` answer. Same rule as
28601
+ * {@link RecordingAvailabilityForDeviceSchema}: `days: []` on a `'read'` row is
28602
+ * "no footage in this month", `read: 'unreadable'` is "nobody could look", and
28603
+ * the date-picker's day dots must not spell them the same.
28604
+ */
28605
+ var RecordingDaysForDeviceSchema = object({
28606
+ deviceId: number(),
28607
+ read: _enum(["read", "unreadable"]),
28608
+ /** Local-midnight epochs (UTC ms) of days that have ≥1 recorded segment. */
28609
+ days: array(number()).readonly()
28610
+ });
28550
28611
  var RecordingManifestSchema = object({
28551
28612
  deviceId: number(),
28552
28613
  /** Local filesystem path to the master playlist; null when no recording exists for the requested range. */
@@ -28781,6 +28842,13 @@ method(object({
28781
28842
  }), RecordingAvailabilitySchema, {
28782
28843
  kind: "query",
28783
28844
  auth: "protected"
28845
+ }), method(object({
28846
+ deviceIds: array(number()).min(1).max(200),
28847
+ fromMs: number(),
28848
+ toMs: number()
28849
+ }), array(RecordingAvailabilityForDeviceSchema).readonly(), {
28850
+ kind: "query",
28851
+ auth: "protected"
28784
28852
  }), method(object({
28785
28853
  deviceId: number(),
28786
28854
  fromMs: number(),
@@ -28789,6 +28857,14 @@ method(object({
28789
28857
  }), RecordingDaysSchema, {
28790
28858
  kind: "query",
28791
28859
  auth: "protected"
28860
+ }), method(object({
28861
+ deviceIds: array(number()).min(1).max(200),
28862
+ fromMs: number(),
28863
+ toMs: number(),
28864
+ tzOffsetMinutes: number()
28865
+ }), array(RecordingDaysForDeviceSchema).readonly(), {
28866
+ kind: "query",
28867
+ auth: "protected"
28792
28868
  }), method(object({
28793
28869
  deviceId: number(),
28794
28870
  fromMs: number(),
@@ -35685,6 +35761,12 @@ Object.freeze({
35685
35761
  addonId: null,
35686
35762
  access: "view"
35687
35763
  },
35764
+ "pipelineAnalytics.getEventDensityBatch": {
35765
+ capName: "pipeline-analytics",
35766
+ capScope: "device",
35767
+ addonId: null,
35768
+ access: "view"
35769
+ },
35688
35770
  "pipelineAnalytics.getEventMedia": {
35689
35771
  capName: "pipeline-analytics",
35690
35772
  capScope: "device",
@@ -36807,12 +36889,24 @@ Object.freeze({
36807
36889
  addonId: null,
36808
36890
  access: "view"
36809
36891
  },
36892
+ "recording.getAvailabilityBatch": {
36893
+ capName: "recording",
36894
+ capScope: "system",
36895
+ addonId: null,
36896
+ access: "view"
36897
+ },
36810
36898
  "recording.getDaysWithRecordings": {
36811
36899
  capName: "recording",
36812
36900
  capScope: "system",
36813
36901
  addonId: null,
36814
36902
  access: "view"
36815
36903
  },
36904
+ "recording.getDaysWithRecordingsBatch": {
36905
+ capName: "recording",
36906
+ capScope: "system",
36907
+ addonId: null,
36908
+ access: "view"
36909
+ },
36816
36910
  "recording.getDeviceConfig": {
36817
36911
  capName: "recording",
36818
36912
  capScope: "system",
@@ -39417,6 +39511,11 @@ Object.freeze({
39417
39511
  form: "single",
39418
39512
  optional: false
39419
39513
  }],
39514
+ "pipelineAnalytics.getEventDensityBatch": [{
39515
+ name: "deviceIds",
39516
+ form: "array",
39517
+ optional: false
39518
+ }],
39420
39519
  "pipelineAnalytics.getEventMedia": [{
39421
39520
  name: "deviceId",
39422
39521
  form: "single",
@@ -39832,11 +39931,21 @@ Object.freeze({
39832
39931
  form: "single",
39833
39932
  optional: false
39834
39933
  }],
39934
+ "recording.getAvailabilityBatch": [{
39935
+ name: "deviceIds",
39936
+ form: "array",
39937
+ optional: false
39938
+ }],
39835
39939
  "recording.getDaysWithRecordings": [{
39836
39940
  name: "deviceId",
39837
39941
  form: "single",
39838
39942
  optional: false
39839
39943
  }],
39944
+ "recording.getDaysWithRecordingsBatch": [{
39945
+ name: "deviceIds",
39946
+ form: "array",
39947
+ optional: false
39948
+ }],
39840
39949
  "recording.getDeviceConfig": [{
39841
39950
  name: "deviceId",
39842
39951
  form: "single",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-unifi",
3
- "version": "0.2.51",
3
+ "version": "0.2.52",
4
4
  "description": "UniFi Network controller device-provider addon for CamStack — local-controller infra switches/APs (as containers) + network-client presence. NO cameras/Protect.",
5
5
  "keywords": [
6
6
  "camstack",