@camstack/addon-provider-amcrest 0.1.13 → 0.1.14

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
@@ -7337,6 +7337,62 @@ var RecordingConfigSchema = object({
7337
7337
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7338
7338
  });
7339
7339
  /**
7340
+ * Ops-log — the durable, append-only operations audit shared by the
7341
+ * recordings and events management surfaces.
7342
+ *
7343
+ * ONE row shape is reused for both domains so a single "Activity" view can
7344
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7345
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7346
+ * management operation, WHY it ran (reason), and its measurable effect
7347
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7348
+ * never fail the operation it records.
7349
+ */
7350
+ /** Which management domain the operation belongs to. */
7351
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7352
+ /** The kind of management operation performed. */
7353
+ var OpsLogOpSchema = _enum([
7354
+ "prune",
7355
+ "manual-delete",
7356
+ "rescan",
7357
+ "retention-run"
7358
+ ]);
7359
+ /** Why the operation ran. */
7360
+ var OpsLogReasonSchema = _enum([
7361
+ "retention",
7362
+ "quota",
7363
+ "manual",
7364
+ "operator"
7365
+ ]);
7366
+ /** One audit row, shared verbatim by both domains. */
7367
+ var OpsLogEntrySchema = object({
7368
+ /** Unique row id. */
7369
+ id: string(),
7370
+ /** Epoch ms the operation completed. */
7371
+ at: number(),
7372
+ domain: OpsLogDomainSchema,
7373
+ op: OpsLogOpSchema,
7374
+ reason: OpsLogReasonSchema,
7375
+ /** The camera the op targeted; null for a cluster/global op. */
7376
+ deviceId: number().nullable(),
7377
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7378
+ nodeId: string(),
7379
+ /** Buckets / rows deleted (op-specific unit). */
7380
+ itemsAffected: number(),
7381
+ /** Bytes reclaimed by the op (0 when not measurable). */
7382
+ bytesReclaimed: number(),
7383
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7384
+ detail: string().nullable(),
7385
+ /** Who/what triggered the op. */
7386
+ actor: string()
7387
+ });
7388
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7389
+ var OpsLogQueryInputSchema = object({
7390
+ /** Restrict to a single camera; omit for every row. */
7391
+ deviceId: number().optional(),
7392
+ /** Max rows returned, newest-first. */
7393
+ limit: number().int().min(1).max(1e3).optional()
7394
+ });
7395
+ /**
7340
7396
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7341
7397
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7342
7398
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -14890,9 +14946,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
14890
14946
  * `package` backs the package-drop detector — a package zone is a
14891
14947
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
14892
14948
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
14893
- * The orchestrator provider that writes this stage lands in a later
14894
- * slice; until then the mirror carries only `{motion, detection}` and
14895
- * consumers read `package` as absent (treat as `[]`).
14949
+ * The orchestrator provider writes this stage as a first-class slice
14950
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
14951
+ * package}` shape, so consumers read the current package rules directly
14952
+ * off `device.state.zoneRules.value.package`.
14896
14953
  */
14897
14954
  runtimeState: object({
14898
14955
  motion: array(ZoneRuleSchema).readonly(),
@@ -19209,6 +19266,26 @@ var TrackCascadeCountsSchema = object({
19209
19266
  /** Per-track CLIP search vectors removed (best-effort). */
19210
19267
  embeddings: number().int()
19211
19268
  });
19269
+ /** Event-store footprint for one camera. */
19270
+ var EventStoreDeviceFootprintSchema = object({
19271
+ deviceId: number(),
19272
+ /** Persisted event rows (motion + object + audio) for the camera. */
19273
+ rows: number().int(),
19274
+ /** Event-owned media bytes on disk for the camera. */
19275
+ bytes: number().int()
19276
+ });
19277
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19278
+ var EventStoreFootprintSchema = object({
19279
+ totalRows: number().int(),
19280
+ totalBytes: number().int(),
19281
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19282
+ });
19283
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19284
+ var EventPruneCountsSchema = object({
19285
+ motion: number().int(),
19286
+ object: number().int(),
19287
+ audio: number().int()
19288
+ });
19212
19289
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19213
19290
  deviceId: number(),
19214
19291
  trackId: string()
@@ -19272,6 +19349,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19272
19349
  }), {
19273
19350
  kind: "mutation",
19274
19351
  auth: "admin"
19352
+ }), method(object({}), EventStoreFootprintSchema, {
19353
+ kind: "query",
19354
+ auth: "admin"
19355
+ }), method(object({
19356
+ olderThanMs: number(),
19357
+ reason: OpsLogReasonSchema.optional()
19358
+ }), EventPruneCountsSchema, {
19359
+ kind: "mutation",
19360
+ auth: "admin"
19361
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19362
+ kind: "mutation",
19363
+ auth: "admin"
19364
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19365
+ kind: "query",
19366
+ auth: "admin"
19275
19367
  }), method(object({
19276
19368
  eventId: string(),
19277
19369
  kind: MediaFileKindEnum.optional()
@@ -22644,13 +22736,29 @@ method(object({
22644
22736
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22645
22737
  kind: "mutation",
22646
22738
  auth: "admin"
22647
- }), method(object({ deviceId: number() }), object({
22739
+ }), method(object({
22740
+ deviceId: number(),
22741
+ reason: OpsLogReasonSchema.optional()
22742
+ }), object({
22648
22743
  floorMs: number().nullable(),
22649
22744
  deletedBuckets: number().int(),
22650
22745
  reclaimedBytes: number().int()
22651
22746
  }), {
22652
22747
  kind: "mutation",
22653
22748
  auth: "admin"
22749
+ }), method(object({
22750
+ deviceId: number(),
22751
+ fromMs: number().optional(),
22752
+ toMs: number().optional()
22753
+ }), object({
22754
+ deletedBuckets: number().int(),
22755
+ reclaimedBytes: number().int()
22756
+ }), {
22757
+ kind: "mutation",
22758
+ auth: "admin"
22759
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
22760
+ kind: "query",
22761
+ auth: "admin"
22654
22762
  });
22655
22763
  /**
22656
22764
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -25983,6 +26091,12 @@ Object.freeze({
25983
26091
  addonId: null,
25984
26092
  access: "delete"
25985
26093
  },
26094
+ "pipelineAnalytics.deleteDeviceEvents": {
26095
+ capName: "pipeline-analytics",
26096
+ capScope: "device",
26097
+ addonId: null,
26098
+ access: "delete"
26099
+ },
25986
26100
  "pipelineAnalytics.deleteTracks": {
25987
26101
  capName: "pipeline-analytics",
25988
26102
  capScope: "device",
@@ -26013,6 +26127,12 @@ Object.freeze({
26013
26127
  addonId: null,
26014
26128
  access: "view"
26015
26129
  },
26130
+ "pipelineAnalytics.getEventStoreFootprint": {
26131
+ capName: "pipeline-analytics",
26132
+ capScope: "device",
26133
+ addonId: null,
26134
+ access: "view"
26135
+ },
26016
26136
  "pipelineAnalytics.getKeyEvents": {
26017
26137
  capName: "pipeline-analytics",
26018
26138
  capScope: "device",
@@ -26055,6 +26175,12 @@ Object.freeze({
26055
26175
  addonId: null,
26056
26176
  access: "view"
26057
26177
  },
26178
+ "pipelineAnalytics.listOpsLog": {
26179
+ capName: "pipeline-analytics",
26180
+ capScope: "device",
26181
+ addonId: null,
26182
+ access: "view"
26183
+ },
26058
26184
  "pipelineAnalytics.listRecentTracks": {
26059
26185
  capName: "pipeline-analytics",
26060
26186
  capScope: "device",
@@ -26067,6 +26193,12 @@ Object.freeze({
26067
26193
  addonId: null,
26068
26194
  access: "view"
26069
26195
  },
26196
+ "pipelineAnalytics.pruneEvents": {
26197
+ capName: "pipeline-analytics",
26198
+ capScope: "device",
26199
+ addonId: null,
26200
+ access: "create"
26201
+ },
26070
26202
  "pipelineAnalytics.pruneEventsBefore": {
26071
26203
  capName: "pipeline-analytics",
26072
26204
  capScope: "device",
@@ -26829,6 +26961,12 @@ Object.freeze({
26829
26961
  addonId: null,
26830
26962
  access: "create"
26831
26963
  },
26964
+ "recording.deleteFootprint": {
26965
+ capName: "recording",
26966
+ capScope: "system",
26967
+ addonId: null,
26968
+ access: "delete"
26969
+ },
26832
26970
  "recording.getAvailability": {
26833
26971
  capName: "recording",
26834
26972
  capScope: "system",
@@ -26859,6 +26997,12 @@ Object.freeze({
26859
26997
  addonId: null,
26860
26998
  access: "view"
26861
26999
  },
27000
+ "recording.listOpsLog": {
27001
+ capName: "recording",
27002
+ capScope: "system",
27003
+ addonId: null,
27004
+ access: "view"
27005
+ },
26862
27006
  "recording.locateSegment": {
26863
27007
  capName: "recording",
26864
27008
  capScope: "system",
package/dist/addon.mjs CHANGED
@@ -7338,6 +7338,62 @@ var RecordingConfigSchema = object({
7338
7338
  scrubThumbnails: ScrubThumbnailPresetSchema.optional()
7339
7339
  });
7340
7340
  /**
7341
+ * Ops-log — the durable, append-only operations audit shared by the
7342
+ * recordings and events management surfaces.
7343
+ *
7344
+ * ONE row shape is reused for both domains so a single "Activity" view can
7345
+ * merge the recorder's DurableState ring (recordings ops-log) and the
7346
+ * pipeline-analytics SQLite collection (events ops-log). Each row records a
7347
+ * management operation, WHY it ran (reason), and its measurable effect
7348
+ * (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
7349
+ * never fail the operation it records.
7350
+ */
7351
+ /** Which management domain the operation belongs to. */
7352
+ var OpsLogDomainSchema = _enum(["recording", "events"]);
7353
+ /** The kind of management operation performed. */
7354
+ var OpsLogOpSchema = _enum([
7355
+ "prune",
7356
+ "manual-delete",
7357
+ "rescan",
7358
+ "retention-run"
7359
+ ]);
7360
+ /** Why the operation ran. */
7361
+ var OpsLogReasonSchema = _enum([
7362
+ "retention",
7363
+ "quota",
7364
+ "manual",
7365
+ "operator"
7366
+ ]);
7367
+ /** One audit row, shared verbatim by both domains. */
7368
+ var OpsLogEntrySchema = object({
7369
+ /** Unique row id. */
7370
+ id: string(),
7371
+ /** Epoch ms the operation completed. */
7372
+ at: number(),
7373
+ domain: OpsLogDomainSchema,
7374
+ op: OpsLogOpSchema,
7375
+ reason: OpsLogReasonSchema,
7376
+ /** The camera the op targeted; null for a cluster/global op. */
7377
+ deviceId: number().nullable(),
7378
+ /** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
7379
+ nodeId: string(),
7380
+ /** Buckets / rows deleted (op-specific unit). */
7381
+ itemsAffected: number(),
7382
+ /** Bytes reclaimed by the op (0 when not measurable). */
7383
+ bytesReclaimed: number(),
7384
+ /** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
7385
+ detail: string().nullable(),
7386
+ /** Who/what triggered the op. */
7387
+ actor: string()
7388
+ });
7389
+ /** Shared query input for the per-domain `listOpsLog` cap methods. */
7390
+ var OpsLogQueryInputSchema = object({
7391
+ /** Restrict to a single camera; omit for every row. */
7392
+ deviceId: number().optional(),
7393
+ /** Max rows returned, newest-first. */
7394
+ limit: number().int().min(1).max(1e3).optional()
7395
+ });
7396
+ /**
7341
7397
  * `StorageLocationType` — an addon-declared id that identifies the *kind* of
7342
7398
  * storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
7343
7399
  * so the persisted record schema and the consumer-facing cap can both consume it
@@ -14891,9 +14947,10 @@ var DEVICE_LOCAL_STATE_CAPS = {
14891
14947
  * `package` backs the package-drop detector — a package zone is a
14892
14948
  * `ZoneRule` on the `'package'` stage referencing drawn polygons
14893
14949
  * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
14894
- * The orchestrator provider that writes this stage lands in a later
14895
- * slice; until then the mirror carries only `{motion, detection}` and
14896
- * consumers read `package` as absent (treat as `[]`).
14950
+ * The orchestrator provider writes this stage as a first-class slice
14951
+ * (Phase 4): every mutation mirrors the full `{motion, detection,
14952
+ * package}` shape, so consumers read the current package rules directly
14953
+ * off `device.state.zoneRules.value.package`.
14897
14954
  */
14898
14955
  runtimeState: object({
14899
14956
  motion: array(ZoneRuleSchema).readonly(),
@@ -19210,6 +19267,26 @@ var TrackCascadeCountsSchema = object({
19210
19267
  /** Per-track CLIP search vectors removed (best-effort). */
19211
19268
  embeddings: number().int()
19212
19269
  });
19270
+ /** Event-store footprint for one camera. */
19271
+ var EventStoreDeviceFootprintSchema = object({
19272
+ deviceId: number(),
19273
+ /** Persisted event rows (motion + object + audio) for the camera. */
19274
+ rows: number().int(),
19275
+ /** Event-owned media bytes on disk for the camera. */
19276
+ bytes: number().int()
19277
+ });
19278
+ /** Aggregate event-store footprint: global totals + per-camera breakdown. */
19279
+ var EventStoreFootprintSchema = object({
19280
+ totalRows: number().int(),
19281
+ totalBytes: number().int(),
19282
+ devices: array(EventStoreDeviceFootprintSchema).readonly()
19283
+ });
19284
+ /** Per-kind counts returned by the event-prune / device-delete mutations. */
19285
+ var EventPruneCountsSchema = object({
19286
+ motion: number().int(),
19287
+ object: number().int(),
19288
+ audio: number().int()
19289
+ });
19213
19290
  DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
19214
19291
  deviceId: number(),
19215
19292
  trackId: string()
@@ -19273,6 +19350,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
19273
19350
  }), {
19274
19351
  kind: "mutation",
19275
19352
  auth: "admin"
19353
+ }), method(object({}), EventStoreFootprintSchema, {
19354
+ kind: "query",
19355
+ auth: "admin"
19356
+ }), method(object({
19357
+ olderThanMs: number(),
19358
+ reason: OpsLogReasonSchema.optional()
19359
+ }), EventPruneCountsSchema, {
19360
+ kind: "mutation",
19361
+ auth: "admin"
19362
+ }), method(object({ deviceId: number() }), EventPruneCountsSchema, {
19363
+ kind: "mutation",
19364
+ auth: "admin"
19365
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
19366
+ kind: "query",
19367
+ auth: "admin"
19276
19368
  }), method(object({
19277
19369
  eventId: string(),
19278
19370
  kind: MediaFileKindEnum.optional()
@@ -22645,13 +22737,29 @@ method(object({
22645
22737
  }), method(object({ deviceId: number() }), RecordingStatusSchema, {
22646
22738
  kind: "mutation",
22647
22739
  auth: "admin"
22648
- }), method(object({ deviceId: number() }), object({
22740
+ }), method(object({
22741
+ deviceId: number(),
22742
+ reason: OpsLogReasonSchema.optional()
22743
+ }), object({
22649
22744
  floorMs: number().nullable(),
22650
22745
  deletedBuckets: number().int(),
22651
22746
  reclaimedBytes: number().int()
22652
22747
  }), {
22653
22748
  kind: "mutation",
22654
22749
  auth: "admin"
22750
+ }), method(object({
22751
+ deviceId: number(),
22752
+ fromMs: number().optional(),
22753
+ toMs: number().optional()
22754
+ }), object({
22755
+ deletedBuckets: number().int(),
22756
+ reclaimedBytes: number().int()
22757
+ }), {
22758
+ kind: "mutation",
22759
+ auth: "admin"
22760
+ }), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
22761
+ kind: "query",
22762
+ auth: "admin"
22655
22763
  });
22656
22764
  /**
22657
22765
  * `recordingExport` cap — render a footage time range into a single downloadable
@@ -25984,6 +26092,12 @@ Object.freeze({
25984
26092
  addonId: null,
25985
26093
  access: "delete"
25986
26094
  },
26095
+ "pipelineAnalytics.deleteDeviceEvents": {
26096
+ capName: "pipeline-analytics",
26097
+ capScope: "device",
26098
+ addonId: null,
26099
+ access: "delete"
26100
+ },
25987
26101
  "pipelineAnalytics.deleteTracks": {
25988
26102
  capName: "pipeline-analytics",
25989
26103
  capScope: "device",
@@ -26014,6 +26128,12 @@ Object.freeze({
26014
26128
  addonId: null,
26015
26129
  access: "view"
26016
26130
  },
26131
+ "pipelineAnalytics.getEventStoreFootprint": {
26132
+ capName: "pipeline-analytics",
26133
+ capScope: "device",
26134
+ addonId: null,
26135
+ access: "view"
26136
+ },
26017
26137
  "pipelineAnalytics.getKeyEvents": {
26018
26138
  capName: "pipeline-analytics",
26019
26139
  capScope: "device",
@@ -26056,6 +26176,12 @@ Object.freeze({
26056
26176
  addonId: null,
26057
26177
  access: "view"
26058
26178
  },
26179
+ "pipelineAnalytics.listOpsLog": {
26180
+ capName: "pipeline-analytics",
26181
+ capScope: "device",
26182
+ addonId: null,
26183
+ access: "view"
26184
+ },
26059
26185
  "pipelineAnalytics.listRecentTracks": {
26060
26186
  capName: "pipeline-analytics",
26061
26187
  capScope: "device",
@@ -26068,6 +26194,12 @@ Object.freeze({
26068
26194
  addonId: null,
26069
26195
  access: "view"
26070
26196
  },
26197
+ "pipelineAnalytics.pruneEvents": {
26198
+ capName: "pipeline-analytics",
26199
+ capScope: "device",
26200
+ addonId: null,
26201
+ access: "create"
26202
+ },
26071
26203
  "pipelineAnalytics.pruneEventsBefore": {
26072
26204
  capName: "pipeline-analytics",
26073
26205
  capScope: "device",
@@ -26830,6 +26962,12 @@ Object.freeze({
26830
26962
  addonId: null,
26831
26963
  access: "create"
26832
26964
  },
26965
+ "recording.deleteFootprint": {
26966
+ capName: "recording",
26967
+ capScope: "system",
26968
+ addonId: null,
26969
+ access: "delete"
26970
+ },
26833
26971
  "recording.getAvailability": {
26834
26972
  capName: "recording",
26835
26973
  capScope: "system",
@@ -26860,6 +26998,12 @@ Object.freeze({
26860
26998
  addonId: null,
26861
26999
  access: "view"
26862
27000
  },
27001
+ "recording.listOpsLog": {
27002
+ capName: "recording",
27003
+ capScope: "system",
27004
+ addonId: null,
27005
+ access: "view"
27006
+ },
26863
27007
  "recording.locateSegment": {
26864
27008
  capName: "recording",
26865
27009
  capScope: "system",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-provider-amcrest",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "description": "Amcrest/Dahua camera device provider addon for CamStack — Dahua CGI over HTTP(S) with digest auth (snapshot, RTSP catalog, PTZ, image/day-night config)",
5
5
  "keywords": [
6
6
  "camstack",