@camstack/addon-notifiers 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 +192 -4
- package/dist/addon.mjs +192 -4
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
let node_zlib = require("node:zlib");
|
|
6
|
-
//#region ../types/dist/event-category-
|
|
6
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
7
7
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
8
8
|
EventCategory["SystemBoot"] = "system.boot";
|
|
9
9
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -156,6 +156,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
156
156
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
157
157
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
158
158
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
159
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
160
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
161
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
162
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
163
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
159
164
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
160
165
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
161
166
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -445,6 +450,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
445
450
|
*/
|
|
446
451
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
447
452
|
/**
|
|
453
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
454
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
455
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
456
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
457
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
458
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
459
|
+
* this bus topic drives notifier rules + live UI. See
|
|
460
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
461
|
+
*/
|
|
462
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
463
|
+
/**
|
|
464
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
465
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
466
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
467
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
468
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
469
|
+
*/
|
|
470
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
471
|
+
/**
|
|
448
472
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
449
473
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
450
474
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5183,6 +5207,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5183
5207
|
};
|
|
5184
5208
|
return inst;
|
|
5185
5209
|
}
|
|
5210
|
+
//#endregion
|
|
5211
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5212
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5213
|
+
var ZodIssueCode = {
|
|
5214
|
+
invalid_type: "invalid_type",
|
|
5215
|
+
too_big: "too_big",
|
|
5216
|
+
too_small: "too_small",
|
|
5217
|
+
invalid_format: "invalid_format",
|
|
5218
|
+
not_multiple_of: "not_multiple_of",
|
|
5219
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5220
|
+
invalid_union: "invalid_union",
|
|
5221
|
+
invalid_key: "invalid_key",
|
|
5222
|
+
invalid_element: "invalid_element",
|
|
5223
|
+
invalid_value: "invalid_value",
|
|
5224
|
+
custom: "custom"
|
|
5225
|
+
};
|
|
5226
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5227
|
+
var ZodFirstPartyTypeKind;
|
|
5228
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5186
5229
|
Object.fromEntries([
|
|
5187
5230
|
{
|
|
5188
5231
|
id: "overview",
|
|
@@ -12848,7 +12891,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
12848
12891
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
12849
12892
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
12850
12893
|
*/
|
|
12851
|
-
var ZoneRuleStageEnum = _enum([
|
|
12894
|
+
var ZoneRuleStageEnum = _enum([
|
|
12895
|
+
"motion",
|
|
12896
|
+
"detection",
|
|
12897
|
+
"package"
|
|
12898
|
+
]);
|
|
12852
12899
|
DeviceType.Camera, method(object({
|
|
12853
12900
|
deviceId: number(),
|
|
12854
12901
|
stage: ZoneRuleStageEnum
|
|
@@ -12861,7 +12908,8 @@ DeviceType.Camera, method(object({
|
|
|
12861
12908
|
auth: "admin"
|
|
12862
12909
|
}), object({
|
|
12863
12910
|
motion: array(ZoneRuleSchema).readonly(),
|
|
12864
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
12911
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
12912
|
+
package: array(ZoneRuleSchema).readonly()
|
|
12865
12913
|
});
|
|
12866
12914
|
var ProviderStatusSchema = object({
|
|
12867
12915
|
connected: boolean(),
|
|
@@ -16077,6 +16125,7 @@ var EventKindIconSchema = _enum([
|
|
|
16077
16125
|
"smoke",
|
|
16078
16126
|
"water",
|
|
16079
16127
|
"button",
|
|
16128
|
+
"package",
|
|
16080
16129
|
"generic"
|
|
16081
16130
|
]);
|
|
16082
16131
|
var EventKindCategorySchema = _enum([
|
|
@@ -16084,7 +16133,8 @@ var EventKindCategorySchema = _enum([
|
|
|
16084
16133
|
"audio",
|
|
16085
16134
|
"detection",
|
|
16086
16135
|
"sensor",
|
|
16087
|
-
"custom"
|
|
16136
|
+
"custom",
|
|
16137
|
+
"package"
|
|
16088
16138
|
]);
|
|
16089
16139
|
var EventKindDescriptorSchema = object({
|
|
16090
16140
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -19730,6 +19780,108 @@ method(object({
|
|
|
19730
19780
|
auth: "admin"
|
|
19731
19781
|
});
|
|
19732
19782
|
/**
|
|
19783
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
19784
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
19785
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
19786
|
+
* delete-after-download.
|
|
19787
|
+
*
|
|
19788
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
19789
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
19790
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
19791
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
19792
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
19793
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
19794
|
+
* SQLite); history rows survive file deletion for audit.
|
|
19795
|
+
*/
|
|
19796
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
19797
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
19798
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
19799
|
+
var ExportTimelapseSchema = object({
|
|
19800
|
+
everyMs: number().int().positive(),
|
|
19801
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
19802
|
+
});
|
|
19803
|
+
/**
|
|
19804
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
19805
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
19806
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
19807
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
19808
|
+
*/
|
|
19809
|
+
var ExportOptionsSchema = object({
|
|
19810
|
+
speed: ExportSpeedSchema.optional(),
|
|
19811
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
19812
|
+
includeAudio: boolean(),
|
|
19813
|
+
maxLifeMs: number().int().positive(),
|
|
19814
|
+
deleteAfterDownload: boolean(),
|
|
19815
|
+
title: string().max(200).optional()
|
|
19816
|
+
}).superRefine((v, ctx) => {
|
|
19817
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
19818
|
+
code: ZodIssueCode.custom,
|
|
19819
|
+
message: "speed and timelapse are mutually exclusive",
|
|
19820
|
+
path: ["timelapse"]
|
|
19821
|
+
});
|
|
19822
|
+
});
|
|
19823
|
+
var ExportStateSchema = _enum([
|
|
19824
|
+
"queued",
|
|
19825
|
+
"rendering",
|
|
19826
|
+
"ready",
|
|
19827
|
+
"failed",
|
|
19828
|
+
"expired",
|
|
19829
|
+
"deleted"
|
|
19830
|
+
]);
|
|
19831
|
+
/** One export job / history row. */
|
|
19832
|
+
var ExportRecordSchema = object({
|
|
19833
|
+
id: string(),
|
|
19834
|
+
deviceId: number(),
|
|
19835
|
+
profile: string(),
|
|
19836
|
+
fromMs: number(),
|
|
19837
|
+
toMs: number(),
|
|
19838
|
+
options: ExportOptionsSchema,
|
|
19839
|
+
state: ExportStateSchema,
|
|
19840
|
+
/** 0–100 while rendering; null otherwise. */
|
|
19841
|
+
progressPct: number().nullable(),
|
|
19842
|
+
/** File size once ready; null before. */
|
|
19843
|
+
fileBytes: number().nullable(),
|
|
19844
|
+
expiresAt: number(),
|
|
19845
|
+
deleteAfterDownload: boolean(),
|
|
19846
|
+
/** Epoch of the first complete download; null until then. */
|
|
19847
|
+
downloadedAt: number().nullable(),
|
|
19848
|
+
createdAt: number(),
|
|
19849
|
+
/** User id/name that requested the export. */
|
|
19850
|
+
createdBy: string(),
|
|
19851
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
19852
|
+
error: string().nullable()
|
|
19853
|
+
});
|
|
19854
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
19855
|
+
var ExportDownloadSchema = object({
|
|
19856
|
+
url: string(),
|
|
19857
|
+
endpoints: array(string())
|
|
19858
|
+
});
|
|
19859
|
+
method(object({
|
|
19860
|
+
deviceId: number(),
|
|
19861
|
+
profile: string(),
|
|
19862
|
+
fromMs: number(),
|
|
19863
|
+
toMs: number(),
|
|
19864
|
+
options: ExportOptionsSchema
|
|
19865
|
+
}), ExportRecordSchema, {
|
|
19866
|
+
kind: "mutation",
|
|
19867
|
+
auth: "protected"
|
|
19868
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
19869
|
+
kind: "query",
|
|
19870
|
+
auth: "protected"
|
|
19871
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19872
|
+
kind: "query",
|
|
19873
|
+
auth: "protected"
|
|
19874
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19875
|
+
kind: "mutation",
|
|
19876
|
+
auth: "protected"
|
|
19877
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19878
|
+
kind: "mutation",
|
|
19879
|
+
auth: "protected"
|
|
19880
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
19881
|
+
kind: "query",
|
|
19882
|
+
auth: "protected"
|
|
19883
|
+
});
|
|
19884
|
+
/**
|
|
19733
19885
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
19734
19886
|
* payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
|
|
19735
19887
|
* `deviceId`.
|
|
@@ -23653,6 +23805,42 @@ Object.freeze({
|
|
|
23653
23805
|
addonId: null,
|
|
23654
23806
|
access: "create"
|
|
23655
23807
|
},
|
|
23808
|
+
"recordingExport.cancelExport": {
|
|
23809
|
+
capName: "recordingExport",
|
|
23810
|
+
capScope: "system",
|
|
23811
|
+
addonId: null,
|
|
23812
|
+
access: "create"
|
|
23813
|
+
},
|
|
23814
|
+
"recordingExport.createExport": {
|
|
23815
|
+
capName: "recordingExport",
|
|
23816
|
+
capScope: "system",
|
|
23817
|
+
addonId: null,
|
|
23818
|
+
access: "create"
|
|
23819
|
+
},
|
|
23820
|
+
"recordingExport.deleteExport": {
|
|
23821
|
+
capName: "recordingExport",
|
|
23822
|
+
capScope: "system",
|
|
23823
|
+
addonId: null,
|
|
23824
|
+
access: "delete"
|
|
23825
|
+
},
|
|
23826
|
+
"recordingExport.getDownloadUrl": {
|
|
23827
|
+
capName: "recordingExport",
|
|
23828
|
+
capScope: "system",
|
|
23829
|
+
addonId: null,
|
|
23830
|
+
access: "view"
|
|
23831
|
+
},
|
|
23832
|
+
"recordingExport.getExport": {
|
|
23833
|
+
capName: "recordingExport",
|
|
23834
|
+
capScope: "system",
|
|
23835
|
+
addonId: null,
|
|
23836
|
+
access: "view"
|
|
23837
|
+
},
|
|
23838
|
+
"recordingExport.listExports": {
|
|
23839
|
+
capName: "recordingExport",
|
|
23840
|
+
capScope: "system",
|
|
23841
|
+
addonId: null,
|
|
23842
|
+
access: "view"
|
|
23843
|
+
},
|
|
23656
23844
|
"sceneMonitor.captureReference": {
|
|
23657
23845
|
capName: "scene-monitor",
|
|
23658
23846
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { brotliCompressSync, deflateSync, gzipSync } from "node:zlib";
|
|
2
|
-
//#region ../types/dist/event-category-
|
|
2
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
3
3
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
4
4
|
EventCategory["SystemBoot"] = "system.boot";
|
|
5
5
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -152,6 +152,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
152
152
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
153
153
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
154
154
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
155
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
156
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
157
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
158
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
159
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
155
160
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
156
161
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
157
162
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -441,6 +446,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
441
446
|
*/
|
|
442
447
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
443
448
|
/**
|
|
449
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
450
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
451
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
452
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
453
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
454
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
455
|
+
* this bus topic drives notifier rules + live UI. See
|
|
456
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
457
|
+
*/
|
|
458
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
459
|
+
/**
|
|
460
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
461
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
462
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
463
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
464
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
465
|
+
*/
|
|
466
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
467
|
+
/**
|
|
444
468
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
445
469
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
446
470
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5179,6 +5203,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5179
5203
|
};
|
|
5180
5204
|
return inst;
|
|
5181
5205
|
}
|
|
5206
|
+
//#endregion
|
|
5207
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5208
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5209
|
+
var ZodIssueCode = {
|
|
5210
|
+
invalid_type: "invalid_type",
|
|
5211
|
+
too_big: "too_big",
|
|
5212
|
+
too_small: "too_small",
|
|
5213
|
+
invalid_format: "invalid_format",
|
|
5214
|
+
not_multiple_of: "not_multiple_of",
|
|
5215
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5216
|
+
invalid_union: "invalid_union",
|
|
5217
|
+
invalid_key: "invalid_key",
|
|
5218
|
+
invalid_element: "invalid_element",
|
|
5219
|
+
invalid_value: "invalid_value",
|
|
5220
|
+
custom: "custom"
|
|
5221
|
+
};
|
|
5222
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5223
|
+
var ZodFirstPartyTypeKind;
|
|
5224
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5182
5225
|
Object.fromEntries([
|
|
5183
5226
|
{
|
|
5184
5227
|
id: "overview",
|
|
@@ -12844,7 +12887,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
12844
12887
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
12845
12888
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
12846
12889
|
*/
|
|
12847
|
-
var ZoneRuleStageEnum = _enum([
|
|
12890
|
+
var ZoneRuleStageEnum = _enum([
|
|
12891
|
+
"motion",
|
|
12892
|
+
"detection",
|
|
12893
|
+
"package"
|
|
12894
|
+
]);
|
|
12848
12895
|
DeviceType.Camera, method(object({
|
|
12849
12896
|
deviceId: number(),
|
|
12850
12897
|
stage: ZoneRuleStageEnum
|
|
@@ -12857,7 +12904,8 @@ DeviceType.Camera, method(object({
|
|
|
12857
12904
|
auth: "admin"
|
|
12858
12905
|
}), object({
|
|
12859
12906
|
motion: array(ZoneRuleSchema).readonly(),
|
|
12860
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
12907
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
12908
|
+
package: array(ZoneRuleSchema).readonly()
|
|
12861
12909
|
});
|
|
12862
12910
|
var ProviderStatusSchema = object({
|
|
12863
12911
|
connected: boolean(),
|
|
@@ -16073,6 +16121,7 @@ var EventKindIconSchema = _enum([
|
|
|
16073
16121
|
"smoke",
|
|
16074
16122
|
"water",
|
|
16075
16123
|
"button",
|
|
16124
|
+
"package",
|
|
16076
16125
|
"generic"
|
|
16077
16126
|
]);
|
|
16078
16127
|
var EventKindCategorySchema = _enum([
|
|
@@ -16080,7 +16129,8 @@ var EventKindCategorySchema = _enum([
|
|
|
16080
16129
|
"audio",
|
|
16081
16130
|
"detection",
|
|
16082
16131
|
"sensor",
|
|
16083
|
-
"custom"
|
|
16132
|
+
"custom",
|
|
16133
|
+
"package"
|
|
16084
16134
|
]);
|
|
16085
16135
|
var EventKindDescriptorSchema = object({
|
|
16086
16136
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -19726,6 +19776,108 @@ method(object({
|
|
|
19726
19776
|
auth: "admin"
|
|
19727
19777
|
});
|
|
19728
19778
|
/**
|
|
19779
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
19780
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
19781
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
19782
|
+
* delete-after-download.
|
|
19783
|
+
*
|
|
19784
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
19785
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
19786
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
19787
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
19788
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
19789
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
19790
|
+
* SQLite); history rows survive file deletion for audit.
|
|
19791
|
+
*/
|
|
19792
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
19793
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
19794
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
19795
|
+
var ExportTimelapseSchema = object({
|
|
19796
|
+
everyMs: number().int().positive(),
|
|
19797
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
19798
|
+
});
|
|
19799
|
+
/**
|
|
19800
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
19801
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
19802
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
19803
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
19804
|
+
*/
|
|
19805
|
+
var ExportOptionsSchema = object({
|
|
19806
|
+
speed: ExportSpeedSchema.optional(),
|
|
19807
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
19808
|
+
includeAudio: boolean(),
|
|
19809
|
+
maxLifeMs: number().int().positive(),
|
|
19810
|
+
deleteAfterDownload: boolean(),
|
|
19811
|
+
title: string().max(200).optional()
|
|
19812
|
+
}).superRefine((v, ctx) => {
|
|
19813
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
19814
|
+
code: ZodIssueCode.custom,
|
|
19815
|
+
message: "speed and timelapse are mutually exclusive",
|
|
19816
|
+
path: ["timelapse"]
|
|
19817
|
+
});
|
|
19818
|
+
});
|
|
19819
|
+
var ExportStateSchema = _enum([
|
|
19820
|
+
"queued",
|
|
19821
|
+
"rendering",
|
|
19822
|
+
"ready",
|
|
19823
|
+
"failed",
|
|
19824
|
+
"expired",
|
|
19825
|
+
"deleted"
|
|
19826
|
+
]);
|
|
19827
|
+
/** One export job / history row. */
|
|
19828
|
+
var ExportRecordSchema = object({
|
|
19829
|
+
id: string(),
|
|
19830
|
+
deviceId: number(),
|
|
19831
|
+
profile: string(),
|
|
19832
|
+
fromMs: number(),
|
|
19833
|
+
toMs: number(),
|
|
19834
|
+
options: ExportOptionsSchema,
|
|
19835
|
+
state: ExportStateSchema,
|
|
19836
|
+
/** 0–100 while rendering; null otherwise. */
|
|
19837
|
+
progressPct: number().nullable(),
|
|
19838
|
+
/** File size once ready; null before. */
|
|
19839
|
+
fileBytes: number().nullable(),
|
|
19840
|
+
expiresAt: number(),
|
|
19841
|
+
deleteAfterDownload: boolean(),
|
|
19842
|
+
/** Epoch of the first complete download; null until then. */
|
|
19843
|
+
downloadedAt: number().nullable(),
|
|
19844
|
+
createdAt: number(),
|
|
19845
|
+
/** User id/name that requested the export. */
|
|
19846
|
+
createdBy: string(),
|
|
19847
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
19848
|
+
error: string().nullable()
|
|
19849
|
+
});
|
|
19850
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
19851
|
+
var ExportDownloadSchema = object({
|
|
19852
|
+
url: string(),
|
|
19853
|
+
endpoints: array(string())
|
|
19854
|
+
});
|
|
19855
|
+
method(object({
|
|
19856
|
+
deviceId: number(),
|
|
19857
|
+
profile: string(),
|
|
19858
|
+
fromMs: number(),
|
|
19859
|
+
toMs: number(),
|
|
19860
|
+
options: ExportOptionsSchema
|
|
19861
|
+
}), ExportRecordSchema, {
|
|
19862
|
+
kind: "mutation",
|
|
19863
|
+
auth: "protected"
|
|
19864
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
19865
|
+
kind: "query",
|
|
19866
|
+
auth: "protected"
|
|
19867
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19868
|
+
kind: "query",
|
|
19869
|
+
auth: "protected"
|
|
19870
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19871
|
+
kind: "mutation",
|
|
19872
|
+
auth: "protected"
|
|
19873
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
19874
|
+
kind: "mutation",
|
|
19875
|
+
auth: "protected"
|
|
19876
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
19877
|
+
kind: "query",
|
|
19878
|
+
auth: "protected"
|
|
19879
|
+
});
|
|
19880
|
+
/**
|
|
19729
19881
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
19730
19882
|
* payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
|
|
19731
19883
|
* `deviceId`.
|
|
@@ -23649,6 +23801,42 @@ Object.freeze({
|
|
|
23649
23801
|
addonId: null,
|
|
23650
23802
|
access: "create"
|
|
23651
23803
|
},
|
|
23804
|
+
"recordingExport.cancelExport": {
|
|
23805
|
+
capName: "recordingExport",
|
|
23806
|
+
capScope: "system",
|
|
23807
|
+
addonId: null,
|
|
23808
|
+
access: "create"
|
|
23809
|
+
},
|
|
23810
|
+
"recordingExport.createExport": {
|
|
23811
|
+
capName: "recordingExport",
|
|
23812
|
+
capScope: "system",
|
|
23813
|
+
addonId: null,
|
|
23814
|
+
access: "create"
|
|
23815
|
+
},
|
|
23816
|
+
"recordingExport.deleteExport": {
|
|
23817
|
+
capName: "recordingExport",
|
|
23818
|
+
capScope: "system",
|
|
23819
|
+
addonId: null,
|
|
23820
|
+
access: "delete"
|
|
23821
|
+
},
|
|
23822
|
+
"recordingExport.getDownloadUrl": {
|
|
23823
|
+
capName: "recordingExport",
|
|
23824
|
+
capScope: "system",
|
|
23825
|
+
addonId: null,
|
|
23826
|
+
access: "view"
|
|
23827
|
+
},
|
|
23828
|
+
"recordingExport.getExport": {
|
|
23829
|
+
capName: "recordingExport",
|
|
23830
|
+
capScope: "system",
|
|
23831
|
+
addonId: null,
|
|
23832
|
+
access: "view"
|
|
23833
|
+
},
|
|
23834
|
+
"recordingExport.listExports": {
|
|
23835
|
+
capName: "recordingExport",
|
|
23836
|
+
capScope: "system",
|
|
23837
|
+
addonId: null,
|
|
23838
|
+
access: "view"
|
|
23839
|
+
},
|
|
23652
23840
|
"sceneMonitor.captureReference": {
|
|
23653
23841
|
capName: "scene-monitor",
|
|
23654
23842
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-notifiers",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.28",
|
|
4
4
|
"description": "System notifiers addon for CamStack — a `notification-output` collection provider hosting per-kind notifier adapters (ntfy, pushover, gotify, telegram, discord, webhook, zentik).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|