@camstack/addon-provider-hikvision 1.1.27 → 1.1.28

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
@@ -7514,6 +7514,62 @@ var RecordingConfigSchema = object({
7514
7514
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7515
7515
  });
7516
7516
  /**
7517
+ * Ops-log — the durable, append-only operations audit shared by the
7518
+ * recordings and events management surfaces.
7519
+ *
7520
+ * ONE row shape is reused for both domains so a single "Activity" view can
7521
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7522
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7523
+ * management operation, WHY it ran (reason), and its measurable effect
7524
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7525
+ * never fail the operation it records.
7526
+ */
7527
+ /** Which management domain the operation belongs to. */
7528
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7529
+ /** The kind of management operation performed. */
7530
+ var OpsLogOpSchema = _enum([
7531
+ "prune",
7532
+ "manual-delete",
7533
+ "rescan",
7534
+ "retention-run"
7535
+ ]);
7536
+ /** Why the operation ran. */
7537
+ var OpsLogReasonSchema = _enum([
7538
+ "retention",
7539
+ "quota",
7540
+ "manual",
7541
+ "operator"
7542
+ ]);
7543
+ /** One audit row, shared verbatim by both domains. */
7544
+ var OpsLogEntrySchema = object({
7545
+ /** Unique row id. */
7546
+ id: string(),
7547
+ /** Epoch ms the operation completed. */
7548
+ at: number(),
7549
+ domain: OpsLogDomainSchema,
7550
+ op: OpsLogOpSchema,
7551
+ reason: OpsLogReasonSchema,
7552
+ /** The camera the op targeted; null for a cluster/global op. */
7553
+ deviceId: number().nullable(),
7554
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7555
+ nodeId: string(),
7556
+ /** Buckets / rows deleted (op-specific unit). */
7557
+ itemsAffected: number(),
7558
+ /** Bytes reclaimed by the op (0 when not measurable). */
7559
+ bytesReclaimed: number(),
7560
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7561
+ detail: string().nullable(),
7562
+ /** Who/what triggered the op. */
7563
+ actor: string()
7564
+ });
7565
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7566
+ var OpsLogQueryInputSchema = object({
7567
+ /** Restrict to a single camera; omit for every row. */
7568
+ deviceId: number().optional(),
7569
+ /** Max rows returned, newest-first. */
7570
+ limit: number().int().min(1).max(1e3).optional()
7571
+ });
7572
+ /**
7517
7573
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7518
7574
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7519
7575
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -15082,9 +15138,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
15082
15138
  * `package` backs the package-drop detector — a package zone is a
15083
15139
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
15084
15140
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
15085
- * The orchestrator provider that writes this stage lands in a later
15086
- * slice; until then the mirror carries only `{motion, detection}` and
15087
- * consumers read `package` as absent (treat as `[]`).
15141
+ * The orchestrator provider writes this stage as a first-class slice
15142
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
15143
+ * package}` shape, so consumers read the current package rules directly
15144
+ * off `device.state.zoneRules.value.package`.
15088
15145
  */
15089
15146
  runtimeState: object({
15090
15147
  motion: array(ZoneRuleSchema).readonly(),
@@ -19413,6 +19470,26 @@ var TrackCascadeCountsSchema = object({
19413
19470
  /** Per-track CLIP search vectors removed (best-effort). */
19414
19471
  embeddings: number().int()
19415
19472
  });
19473
+ /** Event-store footprint for one camera. */
19474
+ var EventStoreDeviceFootprintSchema = object({
19475
+ deviceId: number(),
19476
+ /** Persisted event rows (motion + object + audio) for the camera. */
19477
+ rows: number().int(),
19478
+ /** Event-owned media bytes on disk for the camera. */
19479
+ bytes: number().int()
19480
+ });
19481
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19482
+ var EventStoreFootprintSchema = object({
19483
+ totalRows: number().int(),
19484
+ totalBytes: number().int(),
19485
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19486
+ });
19487
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19488
+ var EventPruneCountsSchema = object({
19489
+ motion: number().int(),
19490
+ object: number().int(),
19491
+ audio: number().int()
19492
+ });
19416
19493
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19417
19494
  deviceId: number(),
19418
19495
  trackId: string()
@@ -19476,6 +19553,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19476
19553
  }), {
19477
19554
  kind: "mutation",
19478
19555
  auth: "admin"
19556
+ }), method(object({}), EventStoreFootprintSchema, {
19557
+ kind: "query",
19558
+ auth: "admin"
19559
+ }), method(object({
19560
+ olderThanMs: number(),
19561
+ reason: OpsLogReasonSchema.optional()
19562
+ }), EventPruneCountsSchema, {
19563
+ kind: "mutation",
19564
+ auth: "admin"
19565
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19566
+ kind: "mutation",
19567
+ auth: "admin"
19568
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19569
+ kind: "query",
19570
+ auth: "admin"
19479
19571
  }), method(object({
19480
19572
  eventId: string(),
19481
19573
  kind: MediaFileKindEnum.optional()
@@ -22924,13 +23016,29 @@ method(object({
22924
23016
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22925
23017
  kind: "mutation",
22926
23018
  auth: "admin"
22927
- }), method(object({ deviceId: number() }), object({
23019
+ }), method(object({
23020
+ deviceId: number(),
23021
+ reason: OpsLogReasonSchema.optional()
23022
+ }), object({
22928
23023
  floorMs: number().nullable(),
22929
23024
  deletedBuckets: number().int(),
22930
23025
  reclaimedBytes: number().int()
22931
23026
  }), {
22932
23027
  kind: "mutation",
22933
23028
  auth: "admin"
23029
+ }), method(object({
23030
+ deviceId: number(),
23031
+ fromMs: number().optional(),
23032
+ toMs: number().optional()
23033
+ }), object({
23034
+ deletedBuckets: number().int(),
23035
+ reclaimedBytes: number().int()
23036
+ }), {
23037
+ kind: "mutation",
23038
+ auth: "admin"
23039
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
23040
+ kind: "query",
23041
+ auth: "admin"
22934
23042
  });
22935
23043
  /**
22936
23044
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -26263,6 +26371,12 @@ Object.freeze({
26263
26371
  addonId: null,
26264
26372
  access: "delete"
26265
26373
  },
26374
+ "pipelineAnalytics.deleteDeviceEvents": {
26375
+ capName: "pipeline-analytics",
26376
+ capScope: "device",
26377
+ addonId: null,
26378
+ access: "delete"
26379
+ },
26266
26380
  "pipelineAnalytics.deleteTracks": {
26267
26381
  capName: "pipeline-analytics",
26268
26382
  capScope: "device",
@@ -26293,6 +26407,12 @@ Object.freeze({
26293
26407
  addonId: null,
26294
26408
  access: "view"
26295
26409
  },
26410
+ "pipelineAnalytics.getEventStoreFootprint": {
26411
+ capName: "pipeline-analytics",
26412
+ capScope: "device",
26413
+ addonId: null,
26414
+ access: "view"
26415
+ },
26296
26416
  "pipelineAnalytics.getKeyEvents": {
26297
26417
  capName: "pipeline-analytics",
26298
26418
  capScope: "device",
@@ -26335,6 +26455,12 @@ Object.freeze({
26335
26455
  addonId: null,
26336
26456
  access: "view"
26337
26457
  },
26458
+ "pipelineAnalytics.listOpsLog": {
26459
+ capName: "pipeline-analytics",
26460
+ capScope: "device",
26461
+ addonId: null,
26462
+ access: "view"
26463
+ },
26338
26464
  "pipelineAnalytics.listRecentTracks": {
26339
26465
  capName: "pipeline-analytics",
26340
26466
  capScope: "device",
@@ -26347,6 +26473,12 @@ Object.freeze({
26347
26473
  addonId: null,
26348
26474
  access: "view"
26349
26475
  },
26476
+ "pipelineAnalytics.pruneEvents": {
26477
+ capName: "pipeline-analytics",
26478
+ capScope: "device",
26479
+ addonId: null,
26480
+ access: "create"
26481
+ },
26350
26482
  "pipelineAnalytics.pruneEventsBefore": {
26351
26483
  capName: "pipeline-analytics",
26352
26484
  capScope: "device",
@@ -27109,6 +27241,12 @@ Object.freeze({
27109
27241
  addonId: null,
27110
27242
  access: "create"
27111
27243
  },
27244
+ "recording.deleteFootprint": {
27245
+ capName: "recording",
27246
+ capScope: "system",
27247
+ addonId: null,
27248
+ access: "delete"
27249
+ },
27112
27250
  "recording.getAvailability": {
27113
27251
  capName: "recording",
27114
27252
  capScope: "system",
@@ -27139,6 +27277,12 @@ Object.freeze({
27139
27277
  addonId: null,
27140
27278
  access: "view"
27141
27279
  },
27280
+ "recording.listOpsLog": {
27281
+ capName: "recording",
27282
+ capScope: "system",
27283
+ addonId: null,
27284
+ access: "view"
27285
+ },
27142
27286
  "recording.locateSegment": {
27143
27287
  capName: "recording",
27144
27288
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -7515,6 +7515,62 @@ var RecordingConfigSchema = object({
7515
7515
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7516
7516
  });
7517
7517
  /**
7518
+ * Ops-log — the durable, append-only operations audit shared by the
7519
+ * recordings and events management surfaces.
7520
+ *
7521
+ * ONE row shape is reused for both domains so a single "Activity" view can
7522
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7523
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7524
+ * management operation, WHY it ran (reason), and its measurable effect
7525
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7526
+ * never fail the operation it records.
7527
+ */
7528
+ /** Which management domain the operation belongs to. */
7529
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7530
+ /** The kind of management operation performed. */
7531
+ var OpsLogOpSchema = _enum([
7532
+ "prune",
7533
+ "manual-delete",
7534
+ "rescan",
7535
+ "retention-run"
7536
+ ]);
7537
+ /** Why the operation ran. */
7538
+ var OpsLogReasonSchema = _enum([
7539
+ "retention",
7540
+ "quota",
7541
+ "manual",
7542
+ "operator"
7543
+ ]);
7544
+ /** One audit row, shared verbatim by both domains. */
7545
+ var OpsLogEntrySchema = object({
7546
+ /** Unique row id. */
7547
+ id: string(),
7548
+ /** Epoch ms the operation completed. */
7549
+ at: number(),
7550
+ domain: OpsLogDomainSchema,
7551
+ op: OpsLogOpSchema,
7552
+ reason: OpsLogReasonSchema,
7553
+ /** The camera the op targeted; null for a cluster/global op. */
7554
+ deviceId: number().nullable(),
7555
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7556
+ nodeId: string(),
7557
+ /** Buckets / rows deleted (op-specific unit). */
7558
+ itemsAffected: number(),
7559
+ /** Bytes reclaimed by the op (0 when not measurable). */
7560
+ bytesReclaimed: number(),
7561
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7562
+ detail: string().nullable(),
7563
+ /** Who/what triggered the op. */
7564
+ actor: string()
7565
+ });
7566
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7567
+ var OpsLogQueryInputSchema = object({
7568
+ /** Restrict to a single camera; omit for every row. */
7569
+ deviceId: number().optional(),
7570
+ /** Max rows returned, newest-first. */
7571
+ limit: number().int().min(1).max(1e3).optional()
7572
+ });
7573
+ /**
7518
7574
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7519
7575
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7520
7576
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -15083,9 +15139,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
15083
15139
  * `package` backs the package-drop detector — a package zone is a
15084
15140
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
15085
15141
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
15086
- * The orchestrator provider that writes this stage lands in a later
15087
- * slice; until then the mirror carries only `{motion, detection}` and
15088
- * consumers read `package` as absent (treat as `[]`).
15142
+ * The orchestrator provider writes this stage as a first-class slice
15143
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
15144
+ * package}` shape, so consumers read the current package rules directly
15145
+ * off `device.state.zoneRules.value.package`.
15089
15146
  */
15090
15147
  runtimeState: object({
15091
15148
  motion: array(ZoneRuleSchema).readonly(),
@@ -19414,6 +19471,26 @@ var TrackCascadeCountsSchema = object({
19414
19471
  /** Per-track CLIP search vectors removed (best-effort). */
19415
19472
  embeddings: number().int()
19416
19473
  });
19474
+ /** Event-store footprint for one camera. */
19475
+ var EventStoreDeviceFootprintSchema = object({
19476
+ deviceId: number(),
19477
+ /** Persisted event rows (motion + object + audio) for the camera. */
19478
+ rows: number().int(),
19479
+ /** Event-owned media bytes on disk for the camera. */
19480
+ bytes: number().int()
19481
+ });
19482
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19483
+ var EventStoreFootprintSchema = object({
19484
+ totalRows: number().int(),
19485
+ totalBytes: number().int(),
19486
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19487
+ });
19488
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19489
+ var EventPruneCountsSchema = object({
19490
+ motion: number().int(),
19491
+ object: number().int(),
19492
+ audio: number().int()
19493
+ });
19417
19494
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19418
19495
  deviceId: number(),
19419
19496
  trackId: string()
@@ -19477,6 +19554,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19477
19554
  }), {
19478
19555
  kind: "mutation",
19479
19556
  auth: "admin"
19557
+ }), method(object({}), EventStoreFootprintSchema, {
19558
+ kind: "query",
19559
+ auth: "admin"
19560
+ }), method(object({
19561
+ olderThanMs: number(),
19562
+ reason: OpsLogReasonSchema.optional()
19563
+ }), EventPruneCountsSchema, {
19564
+ kind: "mutation",
19565
+ auth: "admin"
19566
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19567
+ kind: "mutation",
19568
+ auth: "admin"
19569
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19570
+ kind: "query",
19571
+ auth: "admin"
19480
19572
  }), method(object({
19481
19573
  eventId: string(),
19482
19574
  kind: MediaFileKindEnum.optional()
@@ -22925,13 +23017,29 @@ method(object({
22925
23017
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22926
23018
  kind: "mutation",
22927
23019
  auth: "admin"
22928
- }), method(object({ deviceId: number() }), object({
23020
+ }), method(object({
23021
+ deviceId: number(),
23022
+ reason: OpsLogReasonSchema.optional()
23023
+ }), object({
22929
23024
  floorMs: number().nullable(),
22930
23025
  deletedBuckets: number().int(),
22931
23026
  reclaimedBytes: number().int()
22932
23027
  }), {
22933
23028
  kind: "mutation",
22934
23029
  auth: "admin"
23030
+ }), method(object({
23031
+ deviceId: number(),
23032
+ fromMs: number().optional(),
23033
+ toMs: number().optional()
23034
+ }), object({
23035
+ deletedBuckets: number().int(),
23036
+ reclaimedBytes: number().int()
23037
+ }), {
23038
+ kind: "mutation",
23039
+ auth: "admin"
23040
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
23041
+ kind: "query",
23042
+ auth: "admin"
22935
23043
  });
22936
23044
  /**
22937
23045
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -26264,6 +26372,12 @@ Object.freeze({
26264
26372
  addonId: null,
26265
26373
  access: "delete"
26266
26374
  },
26375
+ "pipelineAnalytics.deleteDeviceEvents": {
26376
+ capName: "pipeline-analytics",
26377
+ capScope: "device",
26378
+ addonId: null,
26379
+ access: "delete"
26380
+ },
26267
26381
  "pipelineAnalytics.deleteTracks": {
26268
26382
  capName: "pipeline-analytics",
26269
26383
  capScope: "device",
@@ -26294,6 +26408,12 @@ Object.freeze({
26294
26408
  addonId: null,
26295
26409
  access: "view"
26296
26410
  },
26411
+ "pipelineAnalytics.getEventStoreFootprint": {
26412
+ capName: "pipeline-analytics",
26413
+ capScope: "device",
26414
+ addonId: null,
26415
+ access: "view"
26416
+ },
26297
26417
  "pipelineAnalytics.getKeyEvents": {
26298
26418
  capName: "pipeline-analytics",
26299
26419
  capScope: "device",
@@ -26336,6 +26456,12 @@ Object.freeze({
26336
26456
  addonId: null,
26337
26457
  access: "view"
26338
26458
  },
26459
+ "pipelineAnalytics.listOpsLog": {
26460
+ capName: "pipeline-analytics",
26461
+ capScope: "device",
26462
+ addonId: null,
26463
+ access: "view"
26464
+ },
26339
26465
  "pipelineAnalytics.listRecentTracks": {
26340
26466
  capName: "pipeline-analytics",
26341
26467
  capScope: "device",
@@ -26348,6 +26474,12 @@ Object.freeze({
26348
26474
  addonId: null,
26349
26475
  access: "view"
26350
26476
  },
26477
+ "pipelineAnalytics.pruneEvents": {
26478
+ capName: "pipeline-analytics",
26479
+ capScope: "device",
26480
+ addonId: null,
26481
+ access: "create"
26482
+ },
26351
26483
  "pipelineAnalytics.pruneEventsBefore": {
26352
26484
  capName: "pipeline-analytics",
26353
26485
  capScope: "device",
@@ -27110,6 +27242,12 @@ Object.freeze({
27110
27242
  addonId: null,
27111
27243
  access: "create"
27112
27244
  },
27245
+ "recording.deleteFootprint": {
27246
+ capName: "recording",
27247
+ capScope: "system",
27248
+ addonId: null,
27249
+ access: "delete"
27250
+ },
27113
27251
  "recording.getAvailability": {
27114
27252
  capName: "recording",
27115
27253
  capScope: "system",
@@ -27140,6 +27278,12 @@ Object.freeze({
27140
27278
  addonId: null,
27141
27279
  access: "view"
27142
27280
  },
27281
+ "recording.listOpsLog": {
27282
+ capName: "recording",
27283
+ capScope: "system",
27284
+ addonId: null,
27285
+ access: "view"
27286
+ },
27143
27287
  "recording.locateSegment": {
27144
27288
  capName: "recording",
27145
27289
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-hikvision",
3
- "version": "1.1.27",
3
+ "version": "1.1.28",
4
4
  "description": "Hikvision camera device provider addon for CamStack — ISAPI over HTTP(S) with digest auth (snapshot, alarm stream, RTSP discovery)",
5
5
  "keywords": [
6
6
  "camstack",