@camstack/addon-mqtt-broker 1.1.25 → 1.1.26
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/mqtt-broker.addon.js +192 -4
- package/dist/mqtt-broker.addon.mjs +192 -4
- package/package.json +1 -1
|
@@ -44,7 +44,7 @@ let crypto$10 = __toESM(crypto$1, 1);
|
|
|
44
44
|
crypto$1 = __toESM(crypto$1);
|
|
45
45
|
let node_fs = require("node:fs");
|
|
46
46
|
let node_path = require("node:path");
|
|
47
|
-
//#region ../types/dist/event-category-
|
|
47
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
48
48
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
49
49
|
EventCategory["SystemBoot"] = "system.boot";
|
|
50
50
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -197,6 +197,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
197
197
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
198
198
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
199
199
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
200
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
201
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
202
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
203
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
204
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
200
205
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
201
206
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
202
207
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -486,6 +491,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
486
491
|
*/
|
|
487
492
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
488
493
|
/**
|
|
494
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
495
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
496
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
497
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
498
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
499
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
500
|
+
* this bus topic drives notifier rules + live UI. See
|
|
501
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
502
|
+
*/
|
|
503
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
504
|
+
/**
|
|
505
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
506
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
507
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
508
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
509
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
510
|
+
*/
|
|
511
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
512
|
+
/**
|
|
489
513
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
490
514
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
491
515
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5224,6 +5248,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5224
5248
|
};
|
|
5225
5249
|
return inst;
|
|
5226
5250
|
}
|
|
5251
|
+
//#endregion
|
|
5252
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5253
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5254
|
+
var ZodIssueCode = {
|
|
5255
|
+
invalid_type: "invalid_type",
|
|
5256
|
+
too_big: "too_big",
|
|
5257
|
+
too_small: "too_small",
|
|
5258
|
+
invalid_format: "invalid_format",
|
|
5259
|
+
not_multiple_of: "not_multiple_of",
|
|
5260
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5261
|
+
invalid_union: "invalid_union",
|
|
5262
|
+
invalid_key: "invalid_key",
|
|
5263
|
+
invalid_element: "invalid_element",
|
|
5264
|
+
invalid_value: "invalid_value",
|
|
5265
|
+
custom: "custom"
|
|
5266
|
+
};
|
|
5267
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5268
|
+
var ZodFirstPartyTypeKind;
|
|
5269
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5227
5270
|
Object.fromEntries([
|
|
5228
5271
|
{
|
|
5229
5272
|
id: "overview",
|
|
@@ -12579,7 +12622,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
12579
12622
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
12580
12623
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
12581
12624
|
*/
|
|
12582
|
-
var ZoneRuleStageEnum = _enum([
|
|
12625
|
+
var ZoneRuleStageEnum = _enum([
|
|
12626
|
+
"motion",
|
|
12627
|
+
"detection",
|
|
12628
|
+
"package"
|
|
12629
|
+
]);
|
|
12583
12630
|
DeviceType.Camera, method(object({
|
|
12584
12631
|
deviceId: number(),
|
|
12585
12632
|
stage: ZoneRuleStageEnum
|
|
@@ -12592,7 +12639,8 @@ DeviceType.Camera, method(object({
|
|
|
12592
12639
|
auth: "admin"
|
|
12593
12640
|
}), object({
|
|
12594
12641
|
motion: array(ZoneRuleSchema).readonly(),
|
|
12595
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
12642
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
12643
|
+
package: array(ZoneRuleSchema).readonly()
|
|
12596
12644
|
});
|
|
12597
12645
|
var ProviderStatusSchema = object({
|
|
12598
12646
|
connected: boolean(),
|
|
@@ -15843,6 +15891,7 @@ var EventKindIconSchema = _enum([
|
|
|
15843
15891
|
"smoke",
|
|
15844
15892
|
"water",
|
|
15845
15893
|
"button",
|
|
15894
|
+
"package",
|
|
15846
15895
|
"generic"
|
|
15847
15896
|
]);
|
|
15848
15897
|
var EventKindCategorySchema = _enum([
|
|
@@ -15850,7 +15899,8 @@ var EventKindCategorySchema = _enum([
|
|
|
15850
15899
|
"audio",
|
|
15851
15900
|
"detection",
|
|
15852
15901
|
"sensor",
|
|
15853
|
-
"custom"
|
|
15902
|
+
"custom",
|
|
15903
|
+
"package"
|
|
15854
15904
|
]);
|
|
15855
15905
|
var EventKindDescriptorSchema = object({
|
|
15856
15906
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -19496,6 +19546,108 @@ method(object({
|
|
|
19496
19546
|
auth: "admin"
|
|
19497
19547
|
});
|
|
19498
19548
|
/**
|
|
19549
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
19550
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
19551
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
19552
|
+
* delete-after-download.
|
|
19553
|
+
*
|
|
19554
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
19555
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
19556
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
19557
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
19558
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
19559
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
19560
|
+
* SQLite); history rows survive file deletion for audit.
|
|
19561
|
+
*/
|
|
19562
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
19563
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
19564
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
19565
|
+
var ExportTimelapseSchema = object({
|
|
19566
|
+
everyMs: number().int().positive(),
|
|
19567
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
19568
|
+
});
|
|
19569
|
+
/**
|
|
19570
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
19571
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
19572
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
19573
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
19574
|
+
*/
|
|
19575
|
+
var ExportOptionsSchema = object({
|
|
19576
|
+
speed: ExportSpeedSchema.optional(),
|
|
19577
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
19578
|
+
includeAudio: boolean(),
|
|
19579
|
+
maxLifeMs: number().int().positive(),
|
|
19580
|
+
deleteAfterDownload: boolean(),
|
|
19581
|
+
title: string().max(200).optional()
|
|
19582
|
+
}).superRefine((v, ctx) => {
|
|
19583
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
19584
|
+
code: ZodIssueCode.custom,
|
|
19585
|
+
message: "speed and timelapse are mutually exclusive",
|
|
19586
|
+
path: ["timelapse"]
|
|
19587
|
+
});
|
|
19588
|
+
});
|
|
19589
|
+
var ExportStateSchema = _enum([
|
|
19590
|
+
"queued",
|
|
19591
|
+
"rendering",
|
|
19592
|
+
"ready",
|
|
19593
|
+
"failed",
|
|
19594
|
+
"expired",
|
|
19595
|
+
"deleted"
|
|
19596
|
+
]);
|
|
19597
|
+
/** One export job / history row. */
|
|
19598
|
+
var ExportRecordSchema = object({
|
|
19599
|
+
id: string(),
|
|
19600
|
+
deviceId: number(),
|
|
19601
|
+
profile: string(),
|
|
19602
|
+
fromMs: number(),
|
|
19603
|
+
toMs: number(),
|
|
19604
|
+
options: ExportOptionsSchema,
|
|
19605
|
+
state: ExportStateSchema,
|
|
19606
|
+
/** 0–100 while rendering; null otherwise. */
|
|
19607
|
+
progressPct: number().nullable(),
|
|
19608
|
+
/** File size once ready; null before. */
|
|
19609
|
+
fileBytes: number().nullable(),
|
|
19610
|
+
expiresAt: number(),
|
|
19611
|
+
deleteAfterDownload: boolean(),
|
|
19612
|
+
/** Epoch of the first complete download; null until then. */
|
|
19613
|
+
downloadedAt: number().nullable(),
|
|
19614
|
+
createdAt: number(),
|
|
19615
|
+
/** User id/name that requested the export. */
|
|
19616
|
+
createdBy: string(),
|
|
19617
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
19618
|
+
error: string().nullable()
|
|
19619
|
+
});
|
|
19620
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
19621
|
+
var ExportDownloadSchema = object({
|
|
19622
|
+
url: string(),
|
|
19623
|
+
endpoints: array(string())
|
|
19624
|
+
});
|
|
19625
|
+
method(object({
|
|
19626
|
+
deviceId: number(),
|
|
19627
|
+
profile: string(),
|
|
19628
|
+
fromMs: number(),
|
|
19629
|
+
toMs: number(),
|
|
19630
|
+
options: ExportOptionsSchema
|
|
19631
|
+
}), ExportRecordSchema, {
|
|
19632
|
+
kind: "mutation",
|
|
19633
|
+
auth: "protected"
|
|
19634
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
19635
|
+
kind: "query",
|
|
19636
|
+
auth: "protected"
|
|
19637
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19638
|
+
kind: "query",
|
|
19639
|
+
auth: "protected"
|
|
19640
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19641
|
+
kind: "mutation",
|
|
19642
|
+
auth: "protected"
|
|
19643
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19644
|
+
kind: "mutation",
|
|
19645
|
+
auth: "protected"
|
|
19646
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
19647
|
+
kind: "query",
|
|
19648
|
+
auth: "protected"
|
|
19649
|
+
});
|
|
19650
|
+
/**
|
|
19499
19651
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
19500
19652
|
* payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
|
|
19501
19653
|
* `deviceId`.
|
|
@@ -23419,6 +23571,42 @@ Object.freeze({
|
|
|
23419
23571
|
addonId: null,
|
|
23420
23572
|
access: "create"
|
|
23421
23573
|
},
|
|
23574
|
+
"recordingExport.cancelExport": {
|
|
23575
|
+
capName: "recordingExport",
|
|
23576
|
+
capScope: "system",
|
|
23577
|
+
addonId: null,
|
|
23578
|
+
access: "create"
|
|
23579
|
+
},
|
|
23580
|
+
"recordingExport.createExport": {
|
|
23581
|
+
capName: "recordingExport",
|
|
23582
|
+
capScope: "system",
|
|
23583
|
+
addonId: null,
|
|
23584
|
+
access: "create"
|
|
23585
|
+
},
|
|
23586
|
+
"recordingExport.deleteExport": {
|
|
23587
|
+
capName: "recordingExport",
|
|
23588
|
+
capScope: "system",
|
|
23589
|
+
addonId: null,
|
|
23590
|
+
access: "delete"
|
|
23591
|
+
},
|
|
23592
|
+
"recordingExport.getDownloadUrl": {
|
|
23593
|
+
capName: "recordingExport",
|
|
23594
|
+
capScope: "system",
|
|
23595
|
+
addonId: null,
|
|
23596
|
+
access: "view"
|
|
23597
|
+
},
|
|
23598
|
+
"recordingExport.getExport": {
|
|
23599
|
+
capName: "recordingExport",
|
|
23600
|
+
capScope: "system",
|
|
23601
|
+
addonId: null,
|
|
23602
|
+
access: "view"
|
|
23603
|
+
},
|
|
23604
|
+
"recordingExport.listExports": {
|
|
23605
|
+
capName: "recordingExport",
|
|
23606
|
+
capScope: "system",
|
|
23607
|
+
addonId: null,
|
|
23608
|
+
access: "view"
|
|
23609
|
+
},
|
|
23422
23610
|
"sceneMonitor.captureReference": {
|
|
23423
23611
|
capName: "scene-monitor",
|
|
23424
23612
|
capScope: "device",
|
|
@@ -39,7 +39,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
39
39
|
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
40
40
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
41
41
|
//#endregion
|
|
42
|
-
//#region ../types/dist/event-category-
|
|
42
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
43
43
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
44
44
|
EventCategory["SystemBoot"] = "system.boot";
|
|
45
45
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -192,6 +192,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
192
192
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
193
193
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
194
194
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
195
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
196
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
197
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
198
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
199
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
195
200
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
196
201
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
197
202
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -481,6 +486,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
481
486
|
*/
|
|
482
487
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
483
488
|
/**
|
|
489
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
490
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
491
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
492
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
493
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
494
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
495
|
+
* this bus topic drives notifier rules + live UI. See
|
|
496
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
497
|
+
*/
|
|
498
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
499
|
+
/**
|
|
500
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
501
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
502
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
503
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
504
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
505
|
+
*/
|
|
506
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
507
|
+
/**
|
|
484
508
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
485
509
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
486
510
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5219,6 +5243,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5219
5243
|
};
|
|
5220
5244
|
return inst;
|
|
5221
5245
|
}
|
|
5246
|
+
//#endregion
|
|
5247
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5248
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5249
|
+
var ZodIssueCode = {
|
|
5250
|
+
invalid_type: "invalid_type",
|
|
5251
|
+
too_big: "too_big",
|
|
5252
|
+
too_small: "too_small",
|
|
5253
|
+
invalid_format: "invalid_format",
|
|
5254
|
+
not_multiple_of: "not_multiple_of",
|
|
5255
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5256
|
+
invalid_union: "invalid_union",
|
|
5257
|
+
invalid_key: "invalid_key",
|
|
5258
|
+
invalid_element: "invalid_element",
|
|
5259
|
+
invalid_value: "invalid_value",
|
|
5260
|
+
custom: "custom"
|
|
5261
|
+
};
|
|
5262
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5263
|
+
var ZodFirstPartyTypeKind;
|
|
5264
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5222
5265
|
Object.fromEntries([
|
|
5223
5266
|
{
|
|
5224
5267
|
id: "overview",
|
|
@@ -12574,7 +12617,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
12574
12617
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
12575
12618
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
12576
12619
|
*/
|
|
12577
|
-
var ZoneRuleStageEnum = _enum([
|
|
12620
|
+
var ZoneRuleStageEnum = _enum([
|
|
12621
|
+
"motion",
|
|
12622
|
+
"detection",
|
|
12623
|
+
"package"
|
|
12624
|
+
]);
|
|
12578
12625
|
DeviceType.Camera, method(object({
|
|
12579
12626
|
deviceId: number(),
|
|
12580
12627
|
stage: ZoneRuleStageEnum
|
|
@@ -12587,7 +12634,8 @@ DeviceType.Camera, method(object({
|
|
|
12587
12634
|
auth: "admin"
|
|
12588
12635
|
}), object({
|
|
12589
12636
|
motion: array(ZoneRuleSchema).readonly(),
|
|
12590
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
12637
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
12638
|
+
package: array(ZoneRuleSchema).readonly()
|
|
12591
12639
|
});
|
|
12592
12640
|
var ProviderStatusSchema = object({
|
|
12593
12641
|
connected: boolean(),
|
|
@@ -15838,6 +15886,7 @@ var EventKindIconSchema = _enum([
|
|
|
15838
15886
|
"smoke",
|
|
15839
15887
|
"water",
|
|
15840
15888
|
"button",
|
|
15889
|
+
"package",
|
|
15841
15890
|
"generic"
|
|
15842
15891
|
]);
|
|
15843
15892
|
var EventKindCategorySchema = _enum([
|
|
@@ -15845,7 +15894,8 @@ var EventKindCategorySchema = _enum([
|
|
|
15845
15894
|
"audio",
|
|
15846
15895
|
"detection",
|
|
15847
15896
|
"sensor",
|
|
15848
|
-
"custom"
|
|
15897
|
+
"custom",
|
|
15898
|
+
"package"
|
|
15849
15899
|
]);
|
|
15850
15900
|
var EventKindDescriptorSchema = object({
|
|
15851
15901
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -19491,6 +19541,108 @@ method(object({
|
|
|
19491
19541
|
auth: "admin"
|
|
19492
19542
|
});
|
|
19493
19543
|
/**
|
|
19544
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
19545
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
19546
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
19547
|
+
* delete-after-download.
|
|
19548
|
+
*
|
|
19549
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
19550
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
19551
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
19552
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
19553
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
19554
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
19555
|
+
* SQLite); history rows survive file deletion for audit.
|
|
19556
|
+
*/
|
|
19557
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
19558
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
19559
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
19560
|
+
var ExportTimelapseSchema = object({
|
|
19561
|
+
everyMs: number().int().positive(),
|
|
19562
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
19563
|
+
});
|
|
19564
|
+
/**
|
|
19565
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
19566
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
19567
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
19568
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
19569
|
+
*/
|
|
19570
|
+
var ExportOptionsSchema = object({
|
|
19571
|
+
speed: ExportSpeedSchema.optional(),
|
|
19572
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
19573
|
+
includeAudio: boolean(),
|
|
19574
|
+
maxLifeMs: number().int().positive(),
|
|
19575
|
+
deleteAfterDownload: boolean(),
|
|
19576
|
+
title: string().max(200).optional()
|
|
19577
|
+
}).superRefine((v, ctx) => {
|
|
19578
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
19579
|
+
code: ZodIssueCode.custom,
|
|
19580
|
+
message: "speed and timelapse are mutually exclusive",
|
|
19581
|
+
path: ["timelapse"]
|
|
19582
|
+
});
|
|
19583
|
+
});
|
|
19584
|
+
var ExportStateSchema = _enum([
|
|
19585
|
+
"queued",
|
|
19586
|
+
"rendering",
|
|
19587
|
+
"ready",
|
|
19588
|
+
"failed",
|
|
19589
|
+
"expired",
|
|
19590
|
+
"deleted"
|
|
19591
|
+
]);
|
|
19592
|
+
/** One export job / history row. */
|
|
19593
|
+
var ExportRecordSchema = object({
|
|
19594
|
+
id: string(),
|
|
19595
|
+
deviceId: number(),
|
|
19596
|
+
profile: string(),
|
|
19597
|
+
fromMs: number(),
|
|
19598
|
+
toMs: number(),
|
|
19599
|
+
options: ExportOptionsSchema,
|
|
19600
|
+
state: ExportStateSchema,
|
|
19601
|
+
/** 0–100 while rendering; null otherwise. */
|
|
19602
|
+
progressPct: number().nullable(),
|
|
19603
|
+
/** File size once ready; null before. */
|
|
19604
|
+
fileBytes: number().nullable(),
|
|
19605
|
+
expiresAt: number(),
|
|
19606
|
+
deleteAfterDownload: boolean(),
|
|
19607
|
+
/** Epoch of the first complete download; null until then. */
|
|
19608
|
+
downloadedAt: number().nullable(),
|
|
19609
|
+
createdAt: number(),
|
|
19610
|
+
/** User id/name that requested the export. */
|
|
19611
|
+
createdBy: string(),
|
|
19612
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
19613
|
+
error: string().nullable()
|
|
19614
|
+
});
|
|
19615
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
19616
|
+
var ExportDownloadSchema = object({
|
|
19617
|
+
url: string(),
|
|
19618
|
+
endpoints: array(string())
|
|
19619
|
+
});
|
|
19620
|
+
method(object({
|
|
19621
|
+
deviceId: number(),
|
|
19622
|
+
profile: string(),
|
|
19623
|
+
fromMs: number(),
|
|
19624
|
+
toMs: number(),
|
|
19625
|
+
options: ExportOptionsSchema
|
|
19626
|
+
}), ExportRecordSchema, {
|
|
19627
|
+
kind: "mutation",
|
|
19628
|
+
auth: "protected"
|
|
19629
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
19630
|
+
kind: "query",
|
|
19631
|
+
auth: "protected"
|
|
19632
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19633
|
+
kind: "query",
|
|
19634
|
+
auth: "protected"
|
|
19635
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19636
|
+
kind: "mutation",
|
|
19637
|
+
auth: "protected"
|
|
19638
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19639
|
+
kind: "mutation",
|
|
19640
|
+
auth: "protected"
|
|
19641
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
19642
|
+
kind: "query",
|
|
19643
|
+
auth: "protected"
|
|
19644
|
+
});
|
|
19645
|
+
/**
|
|
19494
19646
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
19495
19647
|
* payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
|
|
19496
19648
|
* `deviceId`.
|
|
@@ -23414,6 +23566,42 @@ Object.freeze({
|
|
|
23414
23566
|
addonId: null,
|
|
23415
23567
|
access: "create"
|
|
23416
23568
|
},
|
|
23569
|
+
"recordingExport.cancelExport": {
|
|
23570
|
+
capName: "recordingExport",
|
|
23571
|
+
capScope: "system",
|
|
23572
|
+
addonId: null,
|
|
23573
|
+
access: "create"
|
|
23574
|
+
},
|
|
23575
|
+
"recordingExport.createExport": {
|
|
23576
|
+
capName: "recordingExport",
|
|
23577
|
+
capScope: "system",
|
|
23578
|
+
addonId: null,
|
|
23579
|
+
access: "create"
|
|
23580
|
+
},
|
|
23581
|
+
"recordingExport.deleteExport": {
|
|
23582
|
+
capName: "recordingExport",
|
|
23583
|
+
capScope: "system",
|
|
23584
|
+
addonId: null,
|
|
23585
|
+
access: "delete"
|
|
23586
|
+
},
|
|
23587
|
+
"recordingExport.getDownloadUrl": {
|
|
23588
|
+
capName: "recordingExport",
|
|
23589
|
+
capScope: "system",
|
|
23590
|
+
addonId: null,
|
|
23591
|
+
access: "view"
|
|
23592
|
+
},
|
|
23593
|
+
"recordingExport.getExport": {
|
|
23594
|
+
capName: "recordingExport",
|
|
23595
|
+
capScope: "system",
|
|
23596
|
+
addonId: null,
|
|
23597
|
+
access: "view"
|
|
23598
|
+
},
|
|
23599
|
+
"recordingExport.listExports": {
|
|
23600
|
+
capName: "recordingExport",
|
|
23601
|
+
capScope: "system",
|
|
23602
|
+
addonId: null,
|
|
23603
|
+
access: "view"
|
|
23604
|
+
},
|
|
23417
23605
|
"sceneMonitor.captureReference": {
|
|
23418
23606
|
capName: "scene-monitor",
|
|
23419
23607
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-mqtt-broker",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.26",
|
|
4
4
|
"description": "MQTT broker registry addon for CamStack — manages external broker entries + an optional embedded aedes broker. Consumers spin up their own `mqtt.js` clients via the `mqtt-broker` cap.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|