@camstack/addon-provider-amcrest 0.1.12 → 0.1.13
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 +202 -7
- package/dist/addon.mjs +202 -7
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -4,7 +4,7 @@ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).expor
|
|
|
4
4
|
//#endregion
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
6
6
|
let node_os = require("node:os");
|
|
7
|
-
//#region ../types/dist/event-category-
|
|
7
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
8
8
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
9
9
|
EventCategory["SystemBoot"] = "system.boot";
|
|
10
10
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -157,6 +157,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
157
157
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
158
158
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
159
159
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
160
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
161
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
162
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
163
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
164
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
160
165
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
161
166
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
162
167
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -446,6 +451,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
446
451
|
*/
|
|
447
452
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
448
453
|
/**
|
|
454
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
455
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
456
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
457
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
458
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
459
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
460
|
+
* this bus topic drives notifier rules + live UI. See
|
|
461
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
462
|
+
*/
|
|
463
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
464
|
+
/**
|
|
465
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
466
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
467
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
468
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
469
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
470
|
+
*/
|
|
471
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
472
|
+
/**
|
|
449
473
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
450
474
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
451
475
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5184,6 +5208,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5184
5208
|
};
|
|
5185
5209
|
return inst;
|
|
5186
5210
|
}
|
|
5211
|
+
//#endregion
|
|
5212
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5213
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5214
|
+
var ZodIssueCode = {
|
|
5215
|
+
invalid_type: "invalid_type",
|
|
5216
|
+
too_big: "too_big",
|
|
5217
|
+
too_small: "too_small",
|
|
5218
|
+
invalid_format: "invalid_format",
|
|
5219
|
+
not_multiple_of: "not_multiple_of",
|
|
5220
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5221
|
+
invalid_union: "invalid_union",
|
|
5222
|
+
invalid_key: "invalid_key",
|
|
5223
|
+
invalid_element: "invalid_element",
|
|
5224
|
+
invalid_value: "invalid_value",
|
|
5225
|
+
custom: "custom"
|
|
5226
|
+
};
|
|
5227
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5228
|
+
var ZodFirstPartyTypeKind;
|
|
5229
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5187
5230
|
Object.fromEntries([
|
|
5188
5231
|
{
|
|
5189
5232
|
id: "overview",
|
|
@@ -14739,7 +14782,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
14739
14782
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
14740
14783
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
14741
14784
|
*/
|
|
14742
|
-
var ZoneRuleStageEnum = _enum([
|
|
14785
|
+
var ZoneRuleStageEnum = _enum([
|
|
14786
|
+
"motion",
|
|
14787
|
+
"detection",
|
|
14788
|
+
"package"
|
|
14789
|
+
]);
|
|
14743
14790
|
/**
|
|
14744
14791
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
14745
14792
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -14833,16 +14880,24 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14833
14880
|
})
|
|
14834
14881
|
},
|
|
14835
14882
|
/**
|
|
14836
|
-
* Runtime-state slice —
|
|
14883
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
14837
14884
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
14838
|
-
* of
|
|
14839
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
14885
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
14886
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
14840
14887
|
* complete current set. Consumers that only care about one stage
|
|
14841
14888
|
* just read the matching property.
|
|
14889
|
+
*
|
|
14890
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
14891
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14892
|
+
* (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 `[]`).
|
|
14842
14896
|
*/
|
|
14843
14897
|
runtimeState: object({
|
|
14844
14898
|
motion: array(ZoneRuleSchema).readonly(),
|
|
14845
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
14899
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
14900
|
+
package: array(ZoneRuleSchema).readonly()
|
|
14846
14901
|
})
|
|
14847
14902
|
},
|
|
14848
14903
|
zones: zonesCapability
|
|
@@ -18804,6 +18859,7 @@ var EventKindIconSchema = _enum([
|
|
|
18804
18859
|
"smoke",
|
|
18805
18860
|
"water",
|
|
18806
18861
|
"button",
|
|
18862
|
+
"package",
|
|
18807
18863
|
"generic"
|
|
18808
18864
|
]);
|
|
18809
18865
|
var EventKindCategorySchema = _enum([
|
|
@@ -18811,7 +18867,8 @@ var EventKindCategorySchema = _enum([
|
|
|
18811
18867
|
"audio",
|
|
18812
18868
|
"detection",
|
|
18813
18869
|
"sensor",
|
|
18814
|
-
"custom"
|
|
18870
|
+
"custom",
|
|
18871
|
+
"package"
|
|
18815
18872
|
]);
|
|
18816
18873
|
var EventKindDescriptorSchema = object({
|
|
18817
18874
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -22596,6 +22653,108 @@ method(object({
|
|
|
22596
22653
|
auth: "admin"
|
|
22597
22654
|
});
|
|
22598
22655
|
/**
|
|
22656
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
22657
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
22658
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
22659
|
+
* delete-after-download.
|
|
22660
|
+
*
|
|
22661
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
22662
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
22663
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
22664
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
22665
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
22666
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
22667
|
+
* SQLite); history rows survive file deletion for audit.
|
|
22668
|
+
*/
|
|
22669
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
22670
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
22671
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
22672
|
+
var ExportTimelapseSchema = object({
|
|
22673
|
+
everyMs: number().int().positive(),
|
|
22674
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
22675
|
+
});
|
|
22676
|
+
/**
|
|
22677
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
22678
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
22679
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
22680
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
22681
|
+
*/
|
|
22682
|
+
var ExportOptionsSchema = object({
|
|
22683
|
+
speed: ExportSpeedSchema.optional(),
|
|
22684
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
22685
|
+
includeAudio: boolean(),
|
|
22686
|
+
maxLifeMs: number().int().positive(),
|
|
22687
|
+
deleteAfterDownload: boolean(),
|
|
22688
|
+
title: string().max(200).optional()
|
|
22689
|
+
}).superRefine((v, ctx) => {
|
|
22690
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
22691
|
+
code: ZodIssueCode.custom,
|
|
22692
|
+
message: "speed and timelapse are mutually exclusive",
|
|
22693
|
+
path: ["timelapse"]
|
|
22694
|
+
});
|
|
22695
|
+
});
|
|
22696
|
+
var ExportStateSchema = _enum([
|
|
22697
|
+
"queued",
|
|
22698
|
+
"rendering",
|
|
22699
|
+
"ready",
|
|
22700
|
+
"failed",
|
|
22701
|
+
"expired",
|
|
22702
|
+
"deleted"
|
|
22703
|
+
]);
|
|
22704
|
+
/** One export job / history row. */
|
|
22705
|
+
var ExportRecordSchema = object({
|
|
22706
|
+
id: string(),
|
|
22707
|
+
deviceId: number(),
|
|
22708
|
+
profile: string(),
|
|
22709
|
+
fromMs: number(),
|
|
22710
|
+
toMs: number(),
|
|
22711
|
+
options: ExportOptionsSchema,
|
|
22712
|
+
state: ExportStateSchema,
|
|
22713
|
+
/** 0–100 while rendering; null otherwise. */
|
|
22714
|
+
progressPct: number().nullable(),
|
|
22715
|
+
/** File size once ready; null before. */
|
|
22716
|
+
fileBytes: number().nullable(),
|
|
22717
|
+
expiresAt: number(),
|
|
22718
|
+
deleteAfterDownload: boolean(),
|
|
22719
|
+
/** Epoch of the first complete download; null until then. */
|
|
22720
|
+
downloadedAt: number().nullable(),
|
|
22721
|
+
createdAt: number(),
|
|
22722
|
+
/** User id/name that requested the export. */
|
|
22723
|
+
createdBy: string(),
|
|
22724
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
22725
|
+
error: string().nullable()
|
|
22726
|
+
});
|
|
22727
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
22728
|
+
var ExportDownloadSchema = object({
|
|
22729
|
+
url: string(),
|
|
22730
|
+
endpoints: array(string())
|
|
22731
|
+
});
|
|
22732
|
+
method(object({
|
|
22733
|
+
deviceId: number(),
|
|
22734
|
+
profile: string(),
|
|
22735
|
+
fromMs: number(),
|
|
22736
|
+
toMs: number(),
|
|
22737
|
+
options: ExportOptionsSchema
|
|
22738
|
+
}), ExportRecordSchema, {
|
|
22739
|
+
kind: "mutation",
|
|
22740
|
+
auth: "protected"
|
|
22741
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
22742
|
+
kind: "query",
|
|
22743
|
+
auth: "protected"
|
|
22744
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22745
|
+
kind: "query",
|
|
22746
|
+
auth: "protected"
|
|
22747
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22748
|
+
kind: "mutation",
|
|
22749
|
+
auth: "protected"
|
|
22750
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22751
|
+
kind: "mutation",
|
|
22752
|
+
auth: "protected"
|
|
22753
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
22754
|
+
kind: "query",
|
|
22755
|
+
auth: "protected"
|
|
22756
|
+
});
|
|
22757
|
+
/**
|
|
22599
22758
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
22600
22759
|
* payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
|
|
22601
22760
|
* `deviceId`.
|
|
@@ -26730,6 +26889,42 @@ Object.freeze({
|
|
|
26730
26889
|
addonId: null,
|
|
26731
26890
|
access: "create"
|
|
26732
26891
|
},
|
|
26892
|
+
"recordingExport.cancelExport": {
|
|
26893
|
+
capName: "recordingExport",
|
|
26894
|
+
capScope: "system",
|
|
26895
|
+
addonId: null,
|
|
26896
|
+
access: "create"
|
|
26897
|
+
},
|
|
26898
|
+
"recordingExport.createExport": {
|
|
26899
|
+
capName: "recordingExport",
|
|
26900
|
+
capScope: "system",
|
|
26901
|
+
addonId: null,
|
|
26902
|
+
access: "create"
|
|
26903
|
+
},
|
|
26904
|
+
"recordingExport.deleteExport": {
|
|
26905
|
+
capName: "recordingExport",
|
|
26906
|
+
capScope: "system",
|
|
26907
|
+
addonId: null,
|
|
26908
|
+
access: "delete"
|
|
26909
|
+
},
|
|
26910
|
+
"recordingExport.getDownloadUrl": {
|
|
26911
|
+
capName: "recordingExport",
|
|
26912
|
+
capScope: "system",
|
|
26913
|
+
addonId: null,
|
|
26914
|
+
access: "view"
|
|
26915
|
+
},
|
|
26916
|
+
"recordingExport.getExport": {
|
|
26917
|
+
capName: "recordingExport",
|
|
26918
|
+
capScope: "system",
|
|
26919
|
+
addonId: null,
|
|
26920
|
+
access: "view"
|
|
26921
|
+
},
|
|
26922
|
+
"recordingExport.listExports": {
|
|
26923
|
+
capName: "recordingExport",
|
|
26924
|
+
capScope: "system",
|
|
26925
|
+
addonId: null,
|
|
26926
|
+
access: "view"
|
|
26927
|
+
},
|
|
26733
26928
|
"sceneMonitor.captureReference": {
|
|
26734
26929
|
capName: "scene-monitor",
|
|
26735
26930
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { networkInterfaces } from "node:os";
|
|
|
5
5
|
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
6
6
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
7
7
|
//#endregion
|
|
8
|
-
//#region ../types/dist/event-category-
|
|
8
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
9
9
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
10
10
|
EventCategory["SystemBoot"] = "system.boot";
|
|
11
11
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -158,6 +158,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
158
158
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
159
159
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
160
160
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
161
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
162
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
163
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
164
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
165
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
161
166
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
162
167
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
163
168
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -447,6 +452,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
447
452
|
*/
|
|
448
453
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
449
454
|
/**
|
|
455
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
456
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
457
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
458
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
459
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
460
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
461
|
+
* this bus topic drives notifier rules + live UI. See
|
|
462
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
463
|
+
*/
|
|
464
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
465
|
+
/**
|
|
466
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
467
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
468
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
469
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
470
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
471
|
+
*/
|
|
472
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
473
|
+
/**
|
|
450
474
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
451
475
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
452
476
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5185,6 +5209,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5185
5209
|
};
|
|
5186
5210
|
return inst;
|
|
5187
5211
|
}
|
|
5212
|
+
//#endregion
|
|
5213
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5214
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5215
|
+
var ZodIssueCode = {
|
|
5216
|
+
invalid_type: "invalid_type",
|
|
5217
|
+
too_big: "too_big",
|
|
5218
|
+
too_small: "too_small",
|
|
5219
|
+
invalid_format: "invalid_format",
|
|
5220
|
+
not_multiple_of: "not_multiple_of",
|
|
5221
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5222
|
+
invalid_union: "invalid_union",
|
|
5223
|
+
invalid_key: "invalid_key",
|
|
5224
|
+
invalid_element: "invalid_element",
|
|
5225
|
+
invalid_value: "invalid_value",
|
|
5226
|
+
custom: "custom"
|
|
5227
|
+
};
|
|
5228
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5229
|
+
var ZodFirstPartyTypeKind;
|
|
5230
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5188
5231
|
Object.fromEntries([
|
|
5189
5232
|
{
|
|
5190
5233
|
id: "overview",
|
|
@@ -14740,7 +14783,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
14740
14783
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
14741
14784
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
14742
14785
|
*/
|
|
14743
|
-
var ZoneRuleStageEnum = _enum([
|
|
14786
|
+
var ZoneRuleStageEnum = _enum([
|
|
14787
|
+
"motion",
|
|
14788
|
+
"detection",
|
|
14789
|
+
"package"
|
|
14790
|
+
]);
|
|
14744
14791
|
/**
|
|
14745
14792
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
14746
14793
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -14834,16 +14881,24 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14834
14881
|
})
|
|
14835
14882
|
},
|
|
14836
14883
|
/**
|
|
14837
|
-
* Runtime-state slice —
|
|
14884
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
14838
14885
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
14839
|
-
* of
|
|
14840
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
14886
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
14887
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
14841
14888
|
* complete current set. Consumers that only care about one stage
|
|
14842
14889
|
* just read the matching property.
|
|
14890
|
+
*
|
|
14891
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
14892
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14893
|
+
* (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 `[]`).
|
|
14843
14897
|
*/
|
|
14844
14898
|
runtimeState: object({
|
|
14845
14899
|
motion: array(ZoneRuleSchema).readonly(),
|
|
14846
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
14900
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
14901
|
+
package: array(ZoneRuleSchema).readonly()
|
|
14847
14902
|
})
|
|
14848
14903
|
},
|
|
14849
14904
|
zones: zonesCapability
|
|
@@ -18805,6 +18860,7 @@ var EventKindIconSchema = _enum([
|
|
|
18805
18860
|
"smoke",
|
|
18806
18861
|
"water",
|
|
18807
18862
|
"button",
|
|
18863
|
+
"package",
|
|
18808
18864
|
"generic"
|
|
18809
18865
|
]);
|
|
18810
18866
|
var EventKindCategorySchema = _enum([
|
|
@@ -18812,7 +18868,8 @@ var EventKindCategorySchema = _enum([
|
|
|
18812
18868
|
"audio",
|
|
18813
18869
|
"detection",
|
|
18814
18870
|
"sensor",
|
|
18815
|
-
"custom"
|
|
18871
|
+
"custom",
|
|
18872
|
+
"package"
|
|
18816
18873
|
]);
|
|
18817
18874
|
var EventKindDescriptorSchema = object({
|
|
18818
18875
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -22597,6 +22654,108 @@ method(object({
|
|
|
22597
22654
|
auth: "admin"
|
|
22598
22655
|
});
|
|
22599
22656
|
/**
|
|
22657
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
22658
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
22659
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
22660
|
+
* delete-after-download.
|
|
22661
|
+
*
|
|
22662
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
22663
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
22664
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
22665
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
22666
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
22667
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
22668
|
+
* SQLite); history rows survive file deletion for audit.
|
|
22669
|
+
*/
|
|
22670
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
22671
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
22672
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
22673
|
+
var ExportTimelapseSchema = object({
|
|
22674
|
+
everyMs: number().int().positive(),
|
|
22675
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
22676
|
+
});
|
|
22677
|
+
/**
|
|
22678
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
22679
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
22680
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
22681
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
22682
|
+
*/
|
|
22683
|
+
var ExportOptionsSchema = object({
|
|
22684
|
+
speed: ExportSpeedSchema.optional(),
|
|
22685
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
22686
|
+
includeAudio: boolean(),
|
|
22687
|
+
maxLifeMs: number().int().positive(),
|
|
22688
|
+
deleteAfterDownload: boolean(),
|
|
22689
|
+
title: string().max(200).optional()
|
|
22690
|
+
}).superRefine((v, ctx) => {
|
|
22691
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
22692
|
+
code: ZodIssueCode.custom,
|
|
22693
|
+
message: "speed and timelapse are mutually exclusive",
|
|
22694
|
+
path: ["timelapse"]
|
|
22695
|
+
});
|
|
22696
|
+
});
|
|
22697
|
+
var ExportStateSchema = _enum([
|
|
22698
|
+
"queued",
|
|
22699
|
+
"rendering",
|
|
22700
|
+
"ready",
|
|
22701
|
+
"failed",
|
|
22702
|
+
"expired",
|
|
22703
|
+
"deleted"
|
|
22704
|
+
]);
|
|
22705
|
+
/** One export job / history row. */
|
|
22706
|
+
var ExportRecordSchema = object({
|
|
22707
|
+
id: string(),
|
|
22708
|
+
deviceId: number(),
|
|
22709
|
+
profile: string(),
|
|
22710
|
+
fromMs: number(),
|
|
22711
|
+
toMs: number(),
|
|
22712
|
+
options: ExportOptionsSchema,
|
|
22713
|
+
state: ExportStateSchema,
|
|
22714
|
+
/** 0–100 while rendering; null otherwise. */
|
|
22715
|
+
progressPct: number().nullable(),
|
|
22716
|
+
/** File size once ready; null before. */
|
|
22717
|
+
fileBytes: number().nullable(),
|
|
22718
|
+
expiresAt: number(),
|
|
22719
|
+
deleteAfterDownload: boolean(),
|
|
22720
|
+
/** Epoch of the first complete download; null until then. */
|
|
22721
|
+
downloadedAt: number().nullable(),
|
|
22722
|
+
createdAt: number(),
|
|
22723
|
+
/** User id/name that requested the export. */
|
|
22724
|
+
createdBy: string(),
|
|
22725
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
22726
|
+
error: string().nullable()
|
|
22727
|
+
});
|
|
22728
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
22729
|
+
var ExportDownloadSchema = object({
|
|
22730
|
+
url: string(),
|
|
22731
|
+
endpoints: array(string())
|
|
22732
|
+
});
|
|
22733
|
+
method(object({
|
|
22734
|
+
deviceId: number(),
|
|
22735
|
+
profile: string(),
|
|
22736
|
+
fromMs: number(),
|
|
22737
|
+
toMs: number(),
|
|
22738
|
+
options: ExportOptionsSchema
|
|
22739
|
+
}), ExportRecordSchema, {
|
|
22740
|
+
kind: "mutation",
|
|
22741
|
+
auth: "protected"
|
|
22742
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
22743
|
+
kind: "query",
|
|
22744
|
+
auth: "protected"
|
|
22745
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22746
|
+
kind: "query",
|
|
22747
|
+
auth: "protected"
|
|
22748
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22749
|
+
kind: "mutation",
|
|
22750
|
+
auth: "protected"
|
|
22751
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22752
|
+
kind: "mutation",
|
|
22753
|
+
auth: "protected"
|
|
22754
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
22755
|
+
kind: "query",
|
|
22756
|
+
auth: "protected"
|
|
22757
|
+
});
|
|
22758
|
+
/**
|
|
22600
22759
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
22601
22760
|
* payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
|
|
22602
22761
|
* `deviceId`.
|
|
@@ -26731,6 +26890,42 @@ Object.freeze({
|
|
|
26731
26890
|
addonId: null,
|
|
26732
26891
|
access: "create"
|
|
26733
26892
|
},
|
|
26893
|
+
"recordingExport.cancelExport": {
|
|
26894
|
+
capName: "recordingExport",
|
|
26895
|
+
capScope: "system",
|
|
26896
|
+
addonId: null,
|
|
26897
|
+
access: "create"
|
|
26898
|
+
},
|
|
26899
|
+
"recordingExport.createExport": {
|
|
26900
|
+
capName: "recordingExport",
|
|
26901
|
+
capScope: "system",
|
|
26902
|
+
addonId: null,
|
|
26903
|
+
access: "create"
|
|
26904
|
+
},
|
|
26905
|
+
"recordingExport.deleteExport": {
|
|
26906
|
+
capName: "recordingExport",
|
|
26907
|
+
capScope: "system",
|
|
26908
|
+
addonId: null,
|
|
26909
|
+
access: "delete"
|
|
26910
|
+
},
|
|
26911
|
+
"recordingExport.getDownloadUrl": {
|
|
26912
|
+
capName: "recordingExport",
|
|
26913
|
+
capScope: "system",
|
|
26914
|
+
addonId: null,
|
|
26915
|
+
access: "view"
|
|
26916
|
+
},
|
|
26917
|
+
"recordingExport.getExport": {
|
|
26918
|
+
capName: "recordingExport",
|
|
26919
|
+
capScope: "system",
|
|
26920
|
+
addonId: null,
|
|
26921
|
+
access: "view"
|
|
26922
|
+
},
|
|
26923
|
+
"recordingExport.listExports": {
|
|
26924
|
+
capName: "recordingExport",
|
|
26925
|
+
capScope: "system",
|
|
26926
|
+
addonId: null,
|
|
26927
|
+
access: "view"
|
|
26928
|
+
},
|
|
26734
26929
|
"sceneMonitor.captureReference": {
|
|
26735
26930
|
capName: "scene-monitor",
|
|
26736
26931
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-amcrest",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
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",
|