@camstack/addon-matter-broker 0.1.22 → 0.1.23

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
@@ -13,7 +13,7 @@ let node_stream_promises = require("node:stream/promises");
13
13
  let node_net = require("node:net");
14
14
  let node_dgram = require("node:dgram");
15
15
  node_dgram = require_esm.__toESM(node_dgram, 1);
16
- //#region ../types/dist/event-category-H4AVePnn.mjs
16
+ //#region ../types/dist/event-category-D4HJq7Mw.mjs
17
17
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
18
18
  EventCategory["SystemBoot"] = "system.boot";
19
19
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -166,6 +166,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
166
166
  /** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
167
167
  * thumb is a scrub gap the recorder's keyframe backfill covers. */
168
168
  EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
169
+ /** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
170
+ * progress bar the client reconciles via `recordingExport.getExport`. */
171
+ EventCategory["RecordingExportProgress"] = "recording.export.progress";
172
+ EventCategory["RecordingExportCompleted"] = "recording.export.completed";
173
+ EventCategory["RecordingExportFailed"] = "recording.export.failed";
169
174
  EventCategory["DetectionEvent"] = "detection.event";
170
175
  EventCategory["SessionTrackNew"] = "session.track.new";
171
176
  EventCategory["SessionTrackExpired"] = "session.track.expired";
@@ -455,6 +460,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
455
460
  */
456
461
  EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
457
462
  /**
463
+ * Fired by `addon-post-analysis` when a package-drop is confirmed inside
464
+ * a package zone — a newly-appeared stationary object of a package class
465
+ * that cleared the class / zone / dwell / size gates. Payload:
466
+ * `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
467
+ * entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
468
+ * Telemetry (D8): the durable record is the `package-events` store row;
469
+ * this bus topic drives notifier rules + live UI. See
470
+ * docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
471
+ */
472
+ EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
473
+ /**
474
+ * Fired by `addon-post-analysis` when a previously-delivered package
475
+ * leaves its zone (the stationary entry departed — moved or swept).
476
+ * Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
477
+ * `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
478
+ * Telemetry (D8). See package-zones-design §5.2.
479
+ */
480
+ EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
481
+ /**
458
482
  * Fired by `addon-post-analysis` whenever a gallery face row changes:
459
483
  * `kind:'buffered'` a new detected face was persisted, `'assigned'` /
460
484
  * `'unassigned'` its identity link changed, `'deleted'` the row was
@@ -5207,6 +5231,25 @@ function preprocess(fn, schema) {
5207
5231
  out: schema
5208
5232
  });
5209
5233
  }
5234
+ //#endregion
5235
+ //#region ../../node_modules/zod/v4/classic/compat.js
5236
+ /** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
5237
+ var ZodIssueCode = {
5238
+ invalid_type: "invalid_type",
5239
+ too_big: "too_big",
5240
+ too_small: "too_small",
5241
+ invalid_format: "invalid_format",
5242
+ not_multiple_of: "not_multiple_of",
5243
+ unrecognized_keys: "unrecognized_keys",
5244
+ invalid_union: "invalid_union",
5245
+ invalid_key: "invalid_key",
5246
+ invalid_element: "invalid_element",
5247
+ invalid_value: "invalid_value",
5248
+ custom: "custom"
5249
+ };
5250
+ /** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
5251
+ var ZodFirstPartyTypeKind;
5252
+ ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5210
5253
  Object.fromEntries([
5211
5254
  {
5212
5255
  id: "overview",
@@ -14684,7 +14727,11 @@ array(ZoneRuleSchema).readonly();
14684
14727
  * Extend the enum here when a new gating consumer comes online (audio
14685
14728
  * gating, alert filtering, …) — no other surface needs to change.
14686
14729
  */
14687
- var ZoneRuleStageEnum = _enum(["motion", "detection"]);
14730
+ var ZoneRuleStageEnum = _enum([
14731
+ "motion",
14732
+ "detection",
14733
+ "package"
14734
+ ]);
14688
14735
  /**
14689
14736
  * Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
14690
14737
  * `state` getter looks up the cap definition here to construct a
@@ -14778,16 +14825,24 @@ var DEVICE_LOCAL_STATE_CAPS = {
14778
14825
  })
14779
14826
  },
14780
14827
  /**
14781
- * Runtime-state slice — both stages mirrored together so consumers
14828
+ * Runtime-state slice — every stage mirrored together so consumers
14782
14829
  * see one reactive handle (`device.state.zoneRules.value`) instead
14783
- * of two. Bulk-replace mutations on either stage write the full
14784
- * `{motion, detection}` shape, so subscribers always get the
14830
+ * of one per stage. Bulk-replace mutations on any stage write the full
14831
+ * `{motion, detection, package}` shape, so subscribers always get the
14785
14832
  * complete current set. Consumers that only care about one stage
14786
14833
  * just read the matching property.
14834
+ *
14835
+ * `package` backs the package-drop detector — a package zone is a
14836
+ * `ZoneRule` on the `'package'` stage referencing drawn polygons
14837
+ * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
14838
+ * The orchestrator provider that writes this stage lands in a later
14839
+ * slice; until then the mirror carries only `{motion, detection}` and
14840
+ * consumers read `package` as absent (treat as `[]`).
14787
14841
  */
14788
14842
  runtimeState: object({
14789
14843
  motion: array(ZoneRuleSchema).readonly(),
14790
- detection: array(ZoneRuleSchema).readonly()
14844
+ detection: array(ZoneRuleSchema).readonly(),
14845
+ package: array(ZoneRuleSchema).readonly()
14791
14846
  })
14792
14847
  },
14793
14848
  zones: zonesCapability
@@ -18815,6 +18870,7 @@ var EventKindIconSchema = _enum([
18815
18870
  "smoke",
18816
18871
  "water",
18817
18872
  "button",
18873
+ "package",
18818
18874
  "generic"
18819
18875
  ]);
18820
18876
  var EventKindCategorySchema = _enum([
@@ -18822,7 +18878,8 @@ var EventKindCategorySchema = _enum([
18822
18878
  "audio",
18823
18879
  "detection",
18824
18880
  "sensor",
18825
- "custom"
18881
+ "custom",
18882
+ "package"
18826
18883
  ]);
18827
18884
  var EventKindDescriptorSchema = object({
18828
18885
  /** Stable kind id (e.g. 'motion', 'person', 'contact'). */
@@ -22485,6 +22542,108 @@ method(object({
22485
22542
  auth: "admin"
22486
22543
  });
22487
22544
  /**
22545
+ * `recordingExport` cap — render a footage time range into a single downloadable
22546
+ * MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
22547
+ * bounded lifetime with a durable history, auto-expiry, and optional
22548
+ * delete-after-download.
22549
+ *
22550
+ * Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
22551
+ * recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
22552
+ * default `hub`) registers it. Device-scoped methods carry `deviceId` in their
22553
+ * input and dispatch to that single provider; the render runs on the node that
22554
+ * owns the footage (no cross-node segment transfer). Download rides the
22555
+ * framework addon data-plane. State persists in a DurableState blob (NOT
22556
+ * SQLite); history rows survive file deletion for audit.
22557
+ */
22558
+ /** Playback-speed multiplier for the render (1 = realtime). */
22559
+ var ExportSpeedSchema = number().min(.25).max(32);
22560
+ /** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
22561
+ var ExportTimelapseSchema = object({
22562
+ everyMs: number().int().positive(),
22563
+ outputFps: number().int().min(1).max(60).optional()
22564
+ });
22565
+ /**
22566
+ * Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
22567
+ * is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
22568
+ * silent. `maxLifeMs` bounds how long the finished file is kept;
22569
+ * `deleteAfterDownload` removes it shortly after the first complete download.
22570
+ */
22571
+ var ExportOptionsSchema = object({
22572
+ speed: ExportSpeedSchema.optional(),
22573
+ timelapse: ExportTimelapseSchema.optional(),
22574
+ includeAudio: boolean(),
22575
+ maxLifeMs: number().int().positive(),
22576
+ deleteAfterDownload: boolean(),
22577
+ title: string$2().max(200).optional()
22578
+ }).superRefine((v, ctx) => {
22579
+ if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
22580
+ code: ZodIssueCode.custom,
22581
+ message: "speed and timelapse are mutually exclusive",
22582
+ path: ["timelapse"]
22583
+ });
22584
+ });
22585
+ var ExportStateSchema = _enum([
22586
+ "queued",
22587
+ "rendering",
22588
+ "ready",
22589
+ "failed",
22590
+ "expired",
22591
+ "deleted"
22592
+ ]);
22593
+ /** One export job / history row. */
22594
+ var ExportRecordSchema = object({
22595
+ id: string$2(),
22596
+ deviceId: number(),
22597
+ profile: string$2(),
22598
+ fromMs: number(),
22599
+ toMs: number(),
22600
+ options: ExportOptionsSchema,
22601
+ state: ExportStateSchema,
22602
+ /** 0–100 while rendering; null otherwise. */
22603
+ progressPct: number().nullable(),
22604
+ /** File size once ready; null before. */
22605
+ fileBytes: number().nullable(),
22606
+ expiresAt: number(),
22607
+ deleteAfterDownload: boolean(),
22608
+ /** Epoch of the first complete download; null until then. */
22609
+ downloadedAt: number().nullable(),
22610
+ createdAt: number(),
22611
+ /** User id/name that requested the export. */
22612
+ createdBy: string$2(),
22613
+ /** Failure reason when state is 'failed'; null otherwise. */
22614
+ error: string$2().nullable()
22615
+ });
22616
+ /** Candidate download URLs (LAN first, then operator extra hosts). */
22617
+ var ExportDownloadSchema = object({
22618
+ url: string$2(),
22619
+ endpoints: array(string$2())
22620
+ });
22621
+ method(object({
22622
+ deviceId: number(),
22623
+ profile: string$2(),
22624
+ fromMs: number(),
22625
+ toMs: number(),
22626
+ options: ExportOptionsSchema
22627
+ }), ExportRecordSchema, {
22628
+ kind: "mutation",
22629
+ auth: "protected"
22630
+ }), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
22631
+ kind: "query",
22632
+ auth: "protected"
22633
+ }), method(object({ exportId: string$2() }), ExportRecordSchema, {
22634
+ kind: "query",
22635
+ auth: "protected"
22636
+ }), method(object({ exportId: string$2() }), ExportRecordSchema, {
22637
+ kind: "mutation",
22638
+ auth: "protected"
22639
+ }), method(object({ exportId: string$2() }), ExportRecordSchema, {
22640
+ kind: "mutation",
22641
+ auth: "protected"
22642
+ }), method(object({ exportId: string$2() }), ExportDownloadSchema, {
22643
+ kind: "query",
22644
+ auth: "protected"
22645
+ });
22646
+ /**
22488
22647
  * One publishable camera stream as its OWNING PROVIDER describes it — the same
22489
22648
  * payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
22490
22649
  * `deviceId`.
@@ -26408,6 +26567,42 @@ Object.freeze({
26408
26567
  addonId: null,
26409
26568
  access: "create"
26410
26569
  },
26570
+ "recordingExport.cancelExport": {
26571
+ capName: "recordingExport",
26572
+ capScope: "system",
26573
+ addonId: null,
26574
+ access: "create"
26575
+ },
26576
+ "recordingExport.createExport": {
26577
+ capName: "recordingExport",
26578
+ capScope: "system",
26579
+ addonId: null,
26580
+ access: "create"
26581
+ },
26582
+ "recordingExport.deleteExport": {
26583
+ capName: "recordingExport",
26584
+ capScope: "system",
26585
+ addonId: null,
26586
+ access: "delete"
26587
+ },
26588
+ "recordingExport.getDownloadUrl": {
26589
+ capName: "recordingExport",
26590
+ capScope: "system",
26591
+ addonId: null,
26592
+ access: "view"
26593
+ },
26594
+ "recordingExport.getExport": {
26595
+ capName: "recordingExport",
26596
+ capScope: "system",
26597
+ addonId: null,
26598
+ access: "view"
26599
+ },
26600
+ "recordingExport.listExports": {
26601
+ capName: "recordingExport",
26602
+ capScope: "system",
26603
+ addonId: null,
26604
+ access: "view"
26605
+ },
26411
26606
  "sceneMonitor.captureReference": {
26412
26607
  capName: "scene-monitor",
26413
26608
  capScope: "device",
package/dist/addon.mjs CHANGED
@@ -11,7 +11,7 @@ import { networkInterfaces, tmpdir, uptime } from "node:os";
11
11
  import { finished } from "node:stream/promises";
12
12
  import { createConnection, createServer as createServer$2 } from "node:net";
13
13
  import * as dgram from "node:dgram";
14
- //#region ../types/dist/event-category-H4AVePnn.mjs
14
+ //#region ../types/dist/event-category-D4HJq7Mw.mjs
15
15
  var EventCategory = /* @__PURE__ */ function(EventCategory) {
16
16
  EventCategory["SystemBoot"] = "system.boot";
17
17
  EventCategory["SystemAddonsReady"] = "system.addons-ready";
@@ -164,6 +164,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
164
164
  /** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
165
165
  * thumb is a scrub gap the recorder's keyframe backfill covers. */
166
166
  EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
167
+ /** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
168
+ * progress bar the client reconciles via `recordingExport.getExport`. */
169
+ EventCategory["RecordingExportProgress"] = "recording.export.progress";
170
+ EventCategory["RecordingExportCompleted"] = "recording.export.completed";
171
+ EventCategory["RecordingExportFailed"] = "recording.export.failed";
167
172
  EventCategory["DetectionEvent"] = "detection.event";
168
173
  EventCategory["SessionTrackNew"] = "session.track.new";
169
174
  EventCategory["SessionTrackExpired"] = "session.track.expired";
@@ -453,6 +458,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
453
458
  */
454
459
  EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
455
460
  /**
461
+ * Fired by `addon-post-analysis` when a package-drop is confirmed inside
462
+ * a package zone — a newly-appeared stationary object of a package class
463
+ * that cleared the class / zone / dwell / size gates. Payload:
464
+ * `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
465
+ * entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
466
+ * Telemetry (D8): the durable record is the `package-events` store row;
467
+ * this bus topic drives notifier rules + live UI. See
468
+ * docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
469
+ */
470
+ EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
471
+ /**
472
+ * Fired by `addon-post-analysis` when a previously-delivered package
473
+ * leaves its zone (the stationary entry departed — moved or swept).
474
+ * Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
475
+ * `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
476
+ * Telemetry (D8). See package-zones-design §5.2.
477
+ */
478
+ EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
479
+ /**
456
480
  * Fired by `addon-post-analysis` whenever a gallery face row changes:
457
481
  * `kind:'buffered'` a new detected face was persisted, `'assigned'` /
458
482
  * `'unassigned'` its identity link changed, `'deleted'` the row was
@@ -5205,6 +5229,25 @@ function preprocess(fn, schema) {
5205
5229
  out: schema
5206
5230
  });
5207
5231
  }
5232
+ //#endregion
5233
+ //#region ../../node_modules/zod/v4/classic/compat.js
5234
+ /** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
5235
+ var ZodIssueCode = {
5236
+ invalid_type: "invalid_type",
5237
+ too_big: "too_big",
5238
+ too_small: "too_small",
5239
+ invalid_format: "invalid_format",
5240
+ not_multiple_of: "not_multiple_of",
5241
+ unrecognized_keys: "unrecognized_keys",
5242
+ invalid_union: "invalid_union",
5243
+ invalid_key: "invalid_key",
5244
+ invalid_element: "invalid_element",
5245
+ invalid_value: "invalid_value",
5246
+ custom: "custom"
5247
+ };
5248
+ /** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
5249
+ var ZodFirstPartyTypeKind;
5250
+ ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5208
5251
  Object.fromEntries([
5209
5252
  {
5210
5253
  id: "overview",
@@ -14682,7 +14725,11 @@ array(ZoneRuleSchema).readonly();
14682
14725
  * Extend the enum here when a new gating consumer comes online (audio
14683
14726
  * gating, alert filtering, …) — no other surface needs to change.
14684
14727
  */
14685
- var ZoneRuleStageEnum = _enum(["motion", "detection"]);
14728
+ var ZoneRuleStageEnum = _enum([
14729
+ "motion",
14730
+ "detection",
14731
+ "package"
14732
+ ]);
14686
14733
  /**
14687
14734
  * Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
14688
14735
  * `state` getter looks up the cap definition here to construct a
@@ -14776,16 +14823,24 @@ var DEVICE_LOCAL_STATE_CAPS = {
14776
14823
  })
14777
14824
  },
14778
14825
  /**
14779
- * Runtime-state slice — both stages mirrored together so consumers
14826
+ * Runtime-state slice — every stage mirrored together so consumers
14780
14827
  * see one reactive handle (`device.state.zoneRules.value`) instead
14781
- * of two. Bulk-replace mutations on either stage write the full
14782
- * `{motion, detection}` shape, so subscribers always get the
14828
+ * of one per stage. Bulk-replace mutations on any stage write the full
14829
+ * `{motion, detection, package}` shape, so subscribers always get the
14783
14830
  * complete current set. Consumers that only care about one stage
14784
14831
  * just read the matching property.
14832
+ *
14833
+ * `package` backs the package-drop detector — a package zone is a
14834
+ * `ZoneRule` on the `'package'` stage referencing drawn polygons
14835
+ * (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
14836
+ * The orchestrator provider that writes this stage lands in a later
14837
+ * slice; until then the mirror carries only `{motion, detection}` and
14838
+ * consumers read `package` as absent (treat as `[]`).
14785
14839
  */
14786
14840
  runtimeState: object({
14787
14841
  motion: array(ZoneRuleSchema).readonly(),
14788
- detection: array(ZoneRuleSchema).readonly()
14842
+ detection: array(ZoneRuleSchema).readonly(),
14843
+ package: array(ZoneRuleSchema).readonly()
14789
14844
  })
14790
14845
  },
14791
14846
  zones: zonesCapability
@@ -18813,6 +18868,7 @@ var EventKindIconSchema = _enum([
18813
18868
  "smoke",
18814
18869
  "water",
18815
18870
  "button",
18871
+ "package",
18816
18872
  "generic"
18817
18873
  ]);
18818
18874
  var EventKindCategorySchema = _enum([
@@ -18820,7 +18876,8 @@ var EventKindCategorySchema = _enum([
18820
18876
  "audio",
18821
18877
  "detection",
18822
18878
  "sensor",
18823
- "custom"
18879
+ "custom",
18880
+ "package"
18824
18881
  ]);
18825
18882
  var EventKindDescriptorSchema = object({
18826
18883
  /** Stable kind id (e.g. 'motion', 'person', 'contact'). */
@@ -22483,6 +22540,108 @@ method(object({
22483
22540
  auth: "admin"
22484
22541
  });
22485
22542
  /**
22543
+ * `recordingExport` cap — render a footage time range into a single downloadable
22544
+ * MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
22545
+ * bounded lifetime with a durable history, auto-expiry, and optional
22546
+ * delete-after-download.
22547
+ *
22548
+ * Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
22549
+ * recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
22550
+ * default `hub`) registers it. Device-scoped methods carry `deviceId` in their
22551
+ * input and dispatch to that single provider; the render runs on the node that
22552
+ * owns the footage (no cross-node segment transfer). Download rides the
22553
+ * framework addon data-plane. State persists in a DurableState blob (NOT
22554
+ * SQLite); history rows survive file deletion for audit.
22555
+ */
22556
+ /** Playback-speed multiplier for the render (1 = realtime). */
22557
+ var ExportSpeedSchema = number().min(.25).max(32);
22558
+ /** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
22559
+ var ExportTimelapseSchema = object({
22560
+ everyMs: number().int().positive(),
22561
+ outputFps: number().int().min(1).max(60).optional()
22562
+ });
22563
+ /**
22564
+ * Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
22565
+ * is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
22566
+ * silent. `maxLifeMs` bounds how long the finished file is kept;
22567
+ * `deleteAfterDownload` removes it shortly after the first complete download.
22568
+ */
22569
+ var ExportOptionsSchema = object({
22570
+ speed: ExportSpeedSchema.optional(),
22571
+ timelapse: ExportTimelapseSchema.optional(),
22572
+ includeAudio: boolean(),
22573
+ maxLifeMs: number().int().positive(),
22574
+ deleteAfterDownload: boolean(),
22575
+ title: string$2().max(200).optional()
22576
+ }).superRefine((v, ctx) => {
22577
+ if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
22578
+ code: ZodIssueCode.custom,
22579
+ message: "speed and timelapse are mutually exclusive",
22580
+ path: ["timelapse"]
22581
+ });
22582
+ });
22583
+ var ExportStateSchema = _enum([
22584
+ "queued",
22585
+ "rendering",
22586
+ "ready",
22587
+ "failed",
22588
+ "expired",
22589
+ "deleted"
22590
+ ]);
22591
+ /** One export job / history row. */
22592
+ var ExportRecordSchema = object({
22593
+ id: string$2(),
22594
+ deviceId: number(),
22595
+ profile: string$2(),
22596
+ fromMs: number(),
22597
+ toMs: number(),
22598
+ options: ExportOptionsSchema,
22599
+ state: ExportStateSchema,
22600
+ /** 0–100 while rendering; null otherwise. */
22601
+ progressPct: number().nullable(),
22602
+ /** File size once ready; null before. */
22603
+ fileBytes: number().nullable(),
22604
+ expiresAt: number(),
22605
+ deleteAfterDownload: boolean(),
22606
+ /** Epoch of the first complete download; null until then. */
22607
+ downloadedAt: number().nullable(),
22608
+ createdAt: number(),
22609
+ /** User id/name that requested the export. */
22610
+ createdBy: string$2(),
22611
+ /** Failure reason when state is 'failed'; null otherwise. */
22612
+ error: string$2().nullable()
22613
+ });
22614
+ /** Candidate download URLs (LAN first, then operator extra hosts). */
22615
+ var ExportDownloadSchema = object({
22616
+ url: string$2(),
22617
+ endpoints: array(string$2())
22618
+ });
22619
+ method(object({
22620
+ deviceId: number(),
22621
+ profile: string$2(),
22622
+ fromMs: number(),
22623
+ toMs: number(),
22624
+ options: ExportOptionsSchema
22625
+ }), ExportRecordSchema, {
22626
+ kind: "mutation",
22627
+ auth: "protected"
22628
+ }), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
22629
+ kind: "query",
22630
+ auth: "protected"
22631
+ }), method(object({ exportId: string$2() }), ExportRecordSchema, {
22632
+ kind: "query",
22633
+ auth: "protected"
22634
+ }), method(object({ exportId: string$2() }), ExportRecordSchema, {
22635
+ kind: "mutation",
22636
+ auth: "protected"
22637
+ }), method(object({ exportId: string$2() }), ExportRecordSchema, {
22638
+ kind: "mutation",
22639
+ auth: "protected"
22640
+ }), method(object({ exportId: string$2() }), ExportDownloadSchema, {
22641
+ kind: "query",
22642
+ auth: "protected"
22643
+ });
22644
+ /**
22486
22645
  * One publishable camera stream as its OWNING PROVIDER describes it — the same
22487
22646
  * payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
22488
22647
  * `deviceId`.
@@ -26406,6 +26565,42 @@ Object.freeze({
26406
26565
  addonId: null,
26407
26566
  access: "create"
26408
26567
  },
26568
+ "recordingExport.cancelExport": {
26569
+ capName: "recordingExport",
26570
+ capScope: "system",
26571
+ addonId: null,
26572
+ access: "create"
26573
+ },
26574
+ "recordingExport.createExport": {
26575
+ capName: "recordingExport",
26576
+ capScope: "system",
26577
+ addonId: null,
26578
+ access: "create"
26579
+ },
26580
+ "recordingExport.deleteExport": {
26581
+ capName: "recordingExport",
26582
+ capScope: "system",
26583
+ addonId: null,
26584
+ access: "delete"
26585
+ },
26586
+ "recordingExport.getDownloadUrl": {
26587
+ capName: "recordingExport",
26588
+ capScope: "system",
26589
+ addonId: null,
26590
+ access: "view"
26591
+ },
26592
+ "recordingExport.getExport": {
26593
+ capName: "recordingExport",
26594
+ capScope: "system",
26595
+ addonId: null,
26596
+ access: "view"
26597
+ },
26598
+ "recordingExport.listExports": {
26599
+ capName: "recordingExport",
26600
+ capScope: "system",
26601
+ addonId: null,
26602
+ access: "view"
26603
+ },
26409
26604
  "sceneMonitor.captureReference": {
26410
26605
  capName: "scene-monitor",
26411
26606
  capScope: "device",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-matter-broker",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "description": "Matter broker addon for CamStack — owns a Matter fabric (commissioning + the long-lived controller) via the matter.js controller and brokers commissioned Matter nodes into CamStack",
5
5
  "keywords": [
6
6
  "camstack",