@camstack/addon-provider-rademacher 0.1.11 → 0.1.12
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
|
@@ -984,7 +984,7 @@ var Rademacher = class {
|
|
|
984
984
|
}
|
|
985
985
|
};
|
|
986
986
|
//#endregion
|
|
987
|
-
//#region ../types/dist/event-category-
|
|
987
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
988
988
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
989
989
|
EventCategory["SystemBoot"] = "system.boot";
|
|
990
990
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -1137,6 +1137,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1137
1137
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
1138
1138
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
1139
1139
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
1140
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
1141
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
1142
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
1143
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
1144
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
1140
1145
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
1141
1146
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
1142
1147
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -1426,6 +1431,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1426
1431
|
*/
|
|
1427
1432
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
1428
1433
|
/**
|
|
1434
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
1435
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
1436
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
1437
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
1438
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
1439
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
1440
|
+
* this bus topic drives notifier rules + live UI. See
|
|
1441
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
1442
|
+
*/
|
|
1443
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
1444
|
+
/**
|
|
1445
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
1446
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
1447
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
1448
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
1449
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
1450
|
+
*/
|
|
1451
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
1452
|
+
/**
|
|
1429
1453
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
1430
1454
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
1431
1455
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -6178,6 +6202,25 @@ function preprocess(fn, schema) {
|
|
|
6178
6202
|
out: schema
|
|
6179
6203
|
});
|
|
6180
6204
|
}
|
|
6205
|
+
//#endregion
|
|
6206
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
6207
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
6208
|
+
var ZodIssueCode = {
|
|
6209
|
+
invalid_type: "invalid_type",
|
|
6210
|
+
too_big: "too_big",
|
|
6211
|
+
too_small: "too_small",
|
|
6212
|
+
invalid_format: "invalid_format",
|
|
6213
|
+
not_multiple_of: "not_multiple_of",
|
|
6214
|
+
unrecognized_keys: "unrecognized_keys",
|
|
6215
|
+
invalid_union: "invalid_union",
|
|
6216
|
+
invalid_key: "invalid_key",
|
|
6217
|
+
invalid_element: "invalid_element",
|
|
6218
|
+
invalid_value: "invalid_value",
|
|
6219
|
+
custom: "custom"
|
|
6220
|
+
};
|
|
6221
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
6222
|
+
var ZodFirstPartyTypeKind;
|
|
6223
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6181
6224
|
Object.fromEntries([
|
|
6182
6225
|
{
|
|
6183
6226
|
id: "overview",
|
|
@@ -15655,7 +15698,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
15655
15698
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
15656
15699
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
15657
15700
|
*/
|
|
15658
|
-
var ZoneRuleStageEnum = _enum([
|
|
15701
|
+
var ZoneRuleStageEnum = _enum([
|
|
15702
|
+
"motion",
|
|
15703
|
+
"detection",
|
|
15704
|
+
"package"
|
|
15705
|
+
]);
|
|
15659
15706
|
/**
|
|
15660
15707
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
15661
15708
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -15749,16 +15796,24 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
15749
15796
|
})
|
|
15750
15797
|
},
|
|
15751
15798
|
/**
|
|
15752
|
-
* Runtime-state slice —
|
|
15799
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
15753
15800
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
15754
|
-
* of
|
|
15755
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
15801
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
15802
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
15756
15803
|
* complete current set. Consumers that only care about one stage
|
|
15757
15804
|
* just read the matching property.
|
|
15805
|
+
*
|
|
15806
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
15807
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
15808
|
+
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
15809
|
+
* The orchestrator provider that writes this stage lands in a later
|
|
15810
|
+
* slice; until then the mirror carries only `{motion, detection}` and
|
|
15811
|
+
* consumers read `package` as absent (treat as `[]`).
|
|
15758
15812
|
*/
|
|
15759
15813
|
runtimeState: object({
|
|
15760
15814
|
motion: array(ZoneRuleSchema).readonly(),
|
|
15761
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
15815
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
15816
|
+
package: array(ZoneRuleSchema).readonly()
|
|
15762
15817
|
})
|
|
15763
15818
|
},
|
|
15764
15819
|
zones: zonesCapability
|
|
@@ -19720,6 +19775,7 @@ var EventKindIconSchema = _enum([
|
|
|
19720
19775
|
"smoke",
|
|
19721
19776
|
"water",
|
|
19722
19777
|
"button",
|
|
19778
|
+
"package",
|
|
19723
19779
|
"generic"
|
|
19724
19780
|
]);
|
|
19725
19781
|
var EventKindCategorySchema = _enum([
|
|
@@ -19727,7 +19783,8 @@ var EventKindCategorySchema = _enum([
|
|
|
19727
19783
|
"audio",
|
|
19728
19784
|
"detection",
|
|
19729
19785
|
"sensor",
|
|
19730
|
-
"custom"
|
|
19786
|
+
"custom",
|
|
19787
|
+
"package"
|
|
19731
19788
|
]);
|
|
19732
19789
|
var EventKindDescriptorSchema = object({
|
|
19733
19790
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -23373,6 +23430,108 @@ method(object({
|
|
|
23373
23430
|
auth: "admin"
|
|
23374
23431
|
});
|
|
23375
23432
|
/**
|
|
23433
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
23434
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
23435
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
23436
|
+
* delete-after-download.
|
|
23437
|
+
*
|
|
23438
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
23439
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
23440
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
23441
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
23442
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
23443
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
23444
|
+
* SQLite); history rows survive file deletion for audit.
|
|
23445
|
+
*/
|
|
23446
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
23447
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
23448
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
23449
|
+
var ExportTimelapseSchema = object({
|
|
23450
|
+
everyMs: number().int().positive(),
|
|
23451
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
23452
|
+
});
|
|
23453
|
+
/**
|
|
23454
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
23455
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
23456
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
23457
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
23458
|
+
*/
|
|
23459
|
+
var ExportOptionsSchema = object({
|
|
23460
|
+
speed: ExportSpeedSchema.optional(),
|
|
23461
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
23462
|
+
includeAudio: boolean(),
|
|
23463
|
+
maxLifeMs: number().int().positive(),
|
|
23464
|
+
deleteAfterDownload: boolean(),
|
|
23465
|
+
title: string().max(200).optional()
|
|
23466
|
+
}).superRefine((v, ctx) => {
|
|
23467
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
23468
|
+
code: ZodIssueCode.custom,
|
|
23469
|
+
message: "speed and timelapse are mutually exclusive",
|
|
23470
|
+
path: ["timelapse"]
|
|
23471
|
+
});
|
|
23472
|
+
});
|
|
23473
|
+
var ExportStateSchema = _enum([
|
|
23474
|
+
"queued",
|
|
23475
|
+
"rendering",
|
|
23476
|
+
"ready",
|
|
23477
|
+
"failed",
|
|
23478
|
+
"expired",
|
|
23479
|
+
"deleted"
|
|
23480
|
+
]);
|
|
23481
|
+
/** One export job / history row. */
|
|
23482
|
+
var ExportRecordSchema = object({
|
|
23483
|
+
id: string(),
|
|
23484
|
+
deviceId: number(),
|
|
23485
|
+
profile: string(),
|
|
23486
|
+
fromMs: number(),
|
|
23487
|
+
toMs: number(),
|
|
23488
|
+
options: ExportOptionsSchema,
|
|
23489
|
+
state: ExportStateSchema,
|
|
23490
|
+
/** 0–100 while rendering; null otherwise. */
|
|
23491
|
+
progressPct: number().nullable(),
|
|
23492
|
+
/** File size once ready; null before. */
|
|
23493
|
+
fileBytes: number().nullable(),
|
|
23494
|
+
expiresAt: number(),
|
|
23495
|
+
deleteAfterDownload: boolean(),
|
|
23496
|
+
/** Epoch of the first complete download; null until then. */
|
|
23497
|
+
downloadedAt: number().nullable(),
|
|
23498
|
+
createdAt: number(),
|
|
23499
|
+
/** User id/name that requested the export. */
|
|
23500
|
+
createdBy: string(),
|
|
23501
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
23502
|
+
error: string().nullable()
|
|
23503
|
+
});
|
|
23504
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
23505
|
+
var ExportDownloadSchema = object({
|
|
23506
|
+
url: string(),
|
|
23507
|
+
endpoints: array(string())
|
|
23508
|
+
});
|
|
23509
|
+
method(object({
|
|
23510
|
+
deviceId: number(),
|
|
23511
|
+
profile: string(),
|
|
23512
|
+
fromMs: number(),
|
|
23513
|
+
toMs: number(),
|
|
23514
|
+
options: ExportOptionsSchema
|
|
23515
|
+
}), ExportRecordSchema, {
|
|
23516
|
+
kind: "mutation",
|
|
23517
|
+
auth: "protected"
|
|
23518
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
23519
|
+
kind: "query",
|
|
23520
|
+
auth: "protected"
|
|
23521
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23522
|
+
kind: "query",
|
|
23523
|
+
auth: "protected"
|
|
23524
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23525
|
+
kind: "mutation",
|
|
23526
|
+
auth: "protected"
|
|
23527
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23528
|
+
kind: "mutation",
|
|
23529
|
+
auth: "protected"
|
|
23530
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
23531
|
+
kind: "query",
|
|
23532
|
+
auth: "protected"
|
|
23533
|
+
});
|
|
23534
|
+
/**
|
|
23376
23535
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
23377
23536
|
* payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
|
|
23378
23537
|
* `deviceId`.
|
|
@@ -27296,6 +27455,42 @@ Object.freeze({
|
|
|
27296
27455
|
addonId: null,
|
|
27297
27456
|
access: "create"
|
|
27298
27457
|
},
|
|
27458
|
+
"recordingExport.cancelExport": {
|
|
27459
|
+
capName: "recordingExport",
|
|
27460
|
+
capScope: "system",
|
|
27461
|
+
addonId: null,
|
|
27462
|
+
access: "create"
|
|
27463
|
+
},
|
|
27464
|
+
"recordingExport.createExport": {
|
|
27465
|
+
capName: "recordingExport",
|
|
27466
|
+
capScope: "system",
|
|
27467
|
+
addonId: null,
|
|
27468
|
+
access: "create"
|
|
27469
|
+
},
|
|
27470
|
+
"recordingExport.deleteExport": {
|
|
27471
|
+
capName: "recordingExport",
|
|
27472
|
+
capScope: "system",
|
|
27473
|
+
addonId: null,
|
|
27474
|
+
access: "delete"
|
|
27475
|
+
},
|
|
27476
|
+
"recordingExport.getDownloadUrl": {
|
|
27477
|
+
capName: "recordingExport",
|
|
27478
|
+
capScope: "system",
|
|
27479
|
+
addonId: null,
|
|
27480
|
+
access: "view"
|
|
27481
|
+
},
|
|
27482
|
+
"recordingExport.getExport": {
|
|
27483
|
+
capName: "recordingExport",
|
|
27484
|
+
capScope: "system",
|
|
27485
|
+
addonId: null,
|
|
27486
|
+
access: "view"
|
|
27487
|
+
},
|
|
27488
|
+
"recordingExport.listExports": {
|
|
27489
|
+
capName: "recordingExport",
|
|
27490
|
+
capScope: "system",
|
|
27491
|
+
addonId: null,
|
|
27492
|
+
access: "view"
|
|
27493
|
+
},
|
|
27299
27494
|
"sceneMonitor.captureReference": {
|
|
27300
27495
|
capName: "scene-monitor",
|
|
27301
27496
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -983,7 +983,7 @@ var Rademacher = class {
|
|
|
983
983
|
}
|
|
984
984
|
};
|
|
985
985
|
//#endregion
|
|
986
|
-
//#region ../types/dist/event-category-
|
|
986
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
987
987
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
988
988
|
EventCategory["SystemBoot"] = "system.boot";
|
|
989
989
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -1136,6 +1136,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1136
1136
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
1137
1137
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
1138
1138
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
1139
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
1140
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
1141
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
1142
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
1143
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
1139
1144
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
1140
1145
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
1141
1146
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -1425,6 +1430,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
1425
1430
|
*/
|
|
1426
1431
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
1427
1432
|
/**
|
|
1433
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
1434
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
1435
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
1436
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
1437
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
1438
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
1439
|
+
* this bus topic drives notifier rules + live UI. See
|
|
1440
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
1441
|
+
*/
|
|
1442
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
1443
|
+
/**
|
|
1444
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
1445
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
1446
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
1447
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
1448
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
1449
|
+
*/
|
|
1450
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
1451
|
+
/**
|
|
1428
1452
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
1429
1453
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
1430
1454
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -6177,6 +6201,25 @@ function preprocess(fn, schema) {
|
|
|
6177
6201
|
out: schema
|
|
6178
6202
|
});
|
|
6179
6203
|
}
|
|
6204
|
+
//#endregion
|
|
6205
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
6206
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
6207
|
+
var ZodIssueCode = {
|
|
6208
|
+
invalid_type: "invalid_type",
|
|
6209
|
+
too_big: "too_big",
|
|
6210
|
+
too_small: "too_small",
|
|
6211
|
+
invalid_format: "invalid_format",
|
|
6212
|
+
not_multiple_of: "not_multiple_of",
|
|
6213
|
+
unrecognized_keys: "unrecognized_keys",
|
|
6214
|
+
invalid_union: "invalid_union",
|
|
6215
|
+
invalid_key: "invalid_key",
|
|
6216
|
+
invalid_element: "invalid_element",
|
|
6217
|
+
invalid_value: "invalid_value",
|
|
6218
|
+
custom: "custom"
|
|
6219
|
+
};
|
|
6220
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
6221
|
+
var ZodFirstPartyTypeKind;
|
|
6222
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
6180
6223
|
Object.fromEntries([
|
|
6181
6224
|
{
|
|
6182
6225
|
id: "overview",
|
|
@@ -15654,7 +15697,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
15654
15697
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
15655
15698
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
15656
15699
|
*/
|
|
15657
|
-
var ZoneRuleStageEnum = _enum([
|
|
15700
|
+
var ZoneRuleStageEnum = _enum([
|
|
15701
|
+
"motion",
|
|
15702
|
+
"detection",
|
|
15703
|
+
"package"
|
|
15704
|
+
]);
|
|
15658
15705
|
/**
|
|
15659
15706
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
15660
15707
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -15748,16 +15795,24 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
15748
15795
|
})
|
|
15749
15796
|
},
|
|
15750
15797
|
/**
|
|
15751
|
-
* Runtime-state slice —
|
|
15798
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
15752
15799
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
15753
|
-
* of
|
|
15754
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
15800
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
15801
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
15755
15802
|
* complete current set. Consumers that only care about one stage
|
|
15756
15803
|
* just read the matching property.
|
|
15804
|
+
*
|
|
15805
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
15806
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
15807
|
+
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
15808
|
+
* The orchestrator provider that writes this stage lands in a later
|
|
15809
|
+
* slice; until then the mirror carries only `{motion, detection}` and
|
|
15810
|
+
* consumers read `package` as absent (treat as `[]`).
|
|
15757
15811
|
*/
|
|
15758
15812
|
runtimeState: object({
|
|
15759
15813
|
motion: array(ZoneRuleSchema).readonly(),
|
|
15760
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
15814
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
15815
|
+
package: array(ZoneRuleSchema).readonly()
|
|
15761
15816
|
})
|
|
15762
15817
|
},
|
|
15763
15818
|
zones: zonesCapability
|
|
@@ -19719,6 +19774,7 @@ var EventKindIconSchema = _enum([
|
|
|
19719
19774
|
"smoke",
|
|
19720
19775
|
"water",
|
|
19721
19776
|
"button",
|
|
19777
|
+
"package",
|
|
19722
19778
|
"generic"
|
|
19723
19779
|
]);
|
|
19724
19780
|
var EventKindCategorySchema = _enum([
|
|
@@ -19726,7 +19782,8 @@ var EventKindCategorySchema = _enum([
|
|
|
19726
19782
|
"audio",
|
|
19727
19783
|
"detection",
|
|
19728
19784
|
"sensor",
|
|
19729
|
-
"custom"
|
|
19785
|
+
"custom",
|
|
19786
|
+
"package"
|
|
19730
19787
|
]);
|
|
19731
19788
|
var EventKindDescriptorSchema = object({
|
|
19732
19789
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -23372,6 +23429,108 @@ method(object({
|
|
|
23372
23429
|
auth: "admin"
|
|
23373
23430
|
});
|
|
23374
23431
|
/**
|
|
23432
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
23433
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
23434
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
23435
|
+
* delete-after-download.
|
|
23436
|
+
*
|
|
23437
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
23438
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
23439
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
23440
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
23441
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
23442
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
23443
|
+
* SQLite); history rows survive file deletion for audit.
|
|
23444
|
+
*/
|
|
23445
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
23446
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
23447
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
23448
|
+
var ExportTimelapseSchema = object({
|
|
23449
|
+
everyMs: number().int().positive(),
|
|
23450
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
23451
|
+
});
|
|
23452
|
+
/**
|
|
23453
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
23454
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
23455
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
23456
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
23457
|
+
*/
|
|
23458
|
+
var ExportOptionsSchema = object({
|
|
23459
|
+
speed: ExportSpeedSchema.optional(),
|
|
23460
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
23461
|
+
includeAudio: boolean(),
|
|
23462
|
+
maxLifeMs: number().int().positive(),
|
|
23463
|
+
deleteAfterDownload: boolean(),
|
|
23464
|
+
title: string().max(200).optional()
|
|
23465
|
+
}).superRefine((v, ctx) => {
|
|
23466
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
23467
|
+
code: ZodIssueCode.custom,
|
|
23468
|
+
message: "speed and timelapse are mutually exclusive",
|
|
23469
|
+
path: ["timelapse"]
|
|
23470
|
+
});
|
|
23471
|
+
});
|
|
23472
|
+
var ExportStateSchema = _enum([
|
|
23473
|
+
"queued",
|
|
23474
|
+
"rendering",
|
|
23475
|
+
"ready",
|
|
23476
|
+
"failed",
|
|
23477
|
+
"expired",
|
|
23478
|
+
"deleted"
|
|
23479
|
+
]);
|
|
23480
|
+
/** One export job / history row. */
|
|
23481
|
+
var ExportRecordSchema = object({
|
|
23482
|
+
id: string(),
|
|
23483
|
+
deviceId: number(),
|
|
23484
|
+
profile: string(),
|
|
23485
|
+
fromMs: number(),
|
|
23486
|
+
toMs: number(),
|
|
23487
|
+
options: ExportOptionsSchema,
|
|
23488
|
+
state: ExportStateSchema,
|
|
23489
|
+
/** 0–100 while rendering; null otherwise. */
|
|
23490
|
+
progressPct: number().nullable(),
|
|
23491
|
+
/** File size once ready; null before. */
|
|
23492
|
+
fileBytes: number().nullable(),
|
|
23493
|
+
expiresAt: number(),
|
|
23494
|
+
deleteAfterDownload: boolean(),
|
|
23495
|
+
/** Epoch of the first complete download; null until then. */
|
|
23496
|
+
downloadedAt: number().nullable(),
|
|
23497
|
+
createdAt: number(),
|
|
23498
|
+
/** User id/name that requested the export. */
|
|
23499
|
+
createdBy: string(),
|
|
23500
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
23501
|
+
error: string().nullable()
|
|
23502
|
+
});
|
|
23503
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
23504
|
+
var ExportDownloadSchema = object({
|
|
23505
|
+
url: string(),
|
|
23506
|
+
endpoints: array(string())
|
|
23507
|
+
});
|
|
23508
|
+
method(object({
|
|
23509
|
+
deviceId: number(),
|
|
23510
|
+
profile: string(),
|
|
23511
|
+
fromMs: number(),
|
|
23512
|
+
toMs: number(),
|
|
23513
|
+
options: ExportOptionsSchema
|
|
23514
|
+
}), ExportRecordSchema, {
|
|
23515
|
+
kind: "mutation",
|
|
23516
|
+
auth: "protected"
|
|
23517
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
23518
|
+
kind: "query",
|
|
23519
|
+
auth: "protected"
|
|
23520
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23521
|
+
kind: "query",
|
|
23522
|
+
auth: "protected"
|
|
23523
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23524
|
+
kind: "mutation",
|
|
23525
|
+
auth: "protected"
|
|
23526
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23527
|
+
kind: "mutation",
|
|
23528
|
+
auth: "protected"
|
|
23529
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
23530
|
+
kind: "query",
|
|
23531
|
+
auth: "protected"
|
|
23532
|
+
});
|
|
23533
|
+
/**
|
|
23375
23534
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
23376
23535
|
* payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
|
|
23377
23536
|
* `deviceId`.
|
|
@@ -27295,6 +27454,42 @@ Object.freeze({
|
|
|
27295
27454
|
addonId: null,
|
|
27296
27455
|
access: "create"
|
|
27297
27456
|
},
|
|
27457
|
+
"recordingExport.cancelExport": {
|
|
27458
|
+
capName: "recordingExport",
|
|
27459
|
+
capScope: "system",
|
|
27460
|
+
addonId: null,
|
|
27461
|
+
access: "create"
|
|
27462
|
+
},
|
|
27463
|
+
"recordingExport.createExport": {
|
|
27464
|
+
capName: "recordingExport",
|
|
27465
|
+
capScope: "system",
|
|
27466
|
+
addonId: null,
|
|
27467
|
+
access: "create"
|
|
27468
|
+
},
|
|
27469
|
+
"recordingExport.deleteExport": {
|
|
27470
|
+
capName: "recordingExport",
|
|
27471
|
+
capScope: "system",
|
|
27472
|
+
addonId: null,
|
|
27473
|
+
access: "delete"
|
|
27474
|
+
},
|
|
27475
|
+
"recordingExport.getDownloadUrl": {
|
|
27476
|
+
capName: "recordingExport",
|
|
27477
|
+
capScope: "system",
|
|
27478
|
+
addonId: null,
|
|
27479
|
+
access: "view"
|
|
27480
|
+
},
|
|
27481
|
+
"recordingExport.getExport": {
|
|
27482
|
+
capName: "recordingExport",
|
|
27483
|
+
capScope: "system",
|
|
27484
|
+
addonId: null,
|
|
27485
|
+
access: "view"
|
|
27486
|
+
},
|
|
27487
|
+
"recordingExport.listExports": {
|
|
27488
|
+
capName: "recordingExport",
|
|
27489
|
+
capScope: "system",
|
|
27490
|
+
addonId: null,
|
|
27491
|
+
access: "view"
|
|
27492
|
+
},
|
|
27298
27493
|
"sceneMonitor.captureReference": {
|
|
27299
27494
|
capName: "scene-monitor",
|
|
27300
27495
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-rademacher",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "Rademacher HomePilot device-provider addon for CamStack — wraps the @apocaliss92/noderademacher local-hub client (roller shutters over the cover cap)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|