@camstack/addon-provider-unraid 0.1.10 → 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 +228 -8
- package/dist/addon.mjs +228 -8
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
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
|
|
@@ -5193,6 +5217,25 @@ function preprocess(fn, schema) {
|
|
|
5193
5217
|
out: schema
|
|
5194
5218
|
});
|
|
5195
5219
|
}
|
|
5220
|
+
//#endregion
|
|
5221
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5222
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5223
|
+
var ZodIssueCode = {
|
|
5224
|
+
invalid_type: "invalid_type",
|
|
5225
|
+
too_big: "too_big",
|
|
5226
|
+
too_small: "too_small",
|
|
5227
|
+
invalid_format: "invalid_format",
|
|
5228
|
+
not_multiple_of: "not_multiple_of",
|
|
5229
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5230
|
+
invalid_union: "invalid_union",
|
|
5231
|
+
invalid_key: "invalid_key",
|
|
5232
|
+
invalid_element: "invalid_element",
|
|
5233
|
+
invalid_value: "invalid_value",
|
|
5234
|
+
custom: "custom"
|
|
5235
|
+
};
|
|
5236
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5237
|
+
var ZodFirstPartyTypeKind;
|
|
5238
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5196
5239
|
Object.fromEntries([
|
|
5197
5240
|
{
|
|
5198
5241
|
id: "overview",
|
|
@@ -7251,6 +7294,24 @@ var RecordingRetentionSchema = object({
|
|
|
7251
7294
|
maxSizeGb: number().min(0).optional()
|
|
7252
7295
|
});
|
|
7253
7296
|
/**
|
|
7297
|
+
* Scrub-thumbnail fidelity preset — the single per-camera selector bundling the
|
|
7298
|
+
* sprite tile RESOLUTION + JPEG QUALITY the recorder packs timeline-scrub
|
|
7299
|
+
* previews at. Five graduated steps; absent on a config = `standard` (the
|
|
7300
|
+
* shipped default, matching `sheet-geometry`/`sheet-composer`).
|
|
7301
|
+
*
|
|
7302
|
+
* Existing sheets are IMMUTABLE — a changed preset applies to NEW windows only.
|
|
7303
|
+
* Each window's index sidecar carries its own tile dims, so a camera whose
|
|
7304
|
+
* preset changed over time renders every historical window at the dims it was
|
|
7305
|
+
* written with.
|
|
7306
|
+
*/
|
|
7307
|
+
var ScrubThumbnailPresetSchema = _enum([
|
|
7308
|
+
"minimal",
|
|
7309
|
+
"low",
|
|
7310
|
+
"standard",
|
|
7311
|
+
"high",
|
|
7312
|
+
"max"
|
|
7313
|
+
]);
|
|
7314
|
+
/**
|
|
7254
7315
|
* The full per-camera recording intent — the wire shape of a RecordingTarget.
|
|
7255
7316
|
*
|
|
7256
7317
|
* `mode` is the authoritative storage choice; `schedule`/`triggers`/`pre`/`post`
|
|
@@ -7287,7 +7348,14 @@ var RecordingConfigSchema = object({
|
|
|
7287
7348
|
* derived into bands once via `migrateConfigToBands`.
|
|
7288
7349
|
*/
|
|
7289
7350
|
bands: array(RecordingBandSchema).optional(),
|
|
7290
|
-
retention: RecordingRetentionSchema.optional()
|
|
7351
|
+
retention: RecordingRetentionSchema.optional(),
|
|
7352
|
+
/**
|
|
7353
|
+
* Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
|
|
7354
|
+
* timeline-scrub sprite previews). Absent = `standard`. Applies to NEW
|
|
7355
|
+
* windows only — existing sheets are immutable, and each window's index
|
|
7356
|
+
* carries its own tile dims so mixed-preset history renders correctly.
|
|
7357
|
+
*/
|
|
7358
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7291
7359
|
});
|
|
7292
7360
|
/**
|
|
7293
7361
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
@@ -14645,7 +14713,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
14645
14713
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
14646
14714
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
14647
14715
|
*/
|
|
14648
|
-
var ZoneRuleStageEnum = _enum([
|
|
14716
|
+
var ZoneRuleStageEnum = _enum([
|
|
14717
|
+
"motion",
|
|
14718
|
+
"detection",
|
|
14719
|
+
"package"
|
|
14720
|
+
]);
|
|
14649
14721
|
/**
|
|
14650
14722
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
14651
14723
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -14739,16 +14811,24 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14739
14811
|
})
|
|
14740
14812
|
},
|
|
14741
14813
|
/**
|
|
14742
|
-
* Runtime-state slice —
|
|
14814
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
14743
14815
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
14744
|
-
* of
|
|
14745
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
14816
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
14817
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
14746
14818
|
* complete current set. Consumers that only care about one stage
|
|
14747
14819
|
* just read the matching property.
|
|
14820
|
+
*
|
|
14821
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
14822
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14823
|
+
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
14824
|
+
* The orchestrator provider that writes this stage lands in a later
|
|
14825
|
+
* slice; until then the mirror carries only `{motion, detection}` and
|
|
14826
|
+
* consumers read `package` as absent (treat as `[]`).
|
|
14748
14827
|
*/
|
|
14749
14828
|
runtimeState: object({
|
|
14750
14829
|
motion: array(ZoneRuleSchema).readonly(),
|
|
14751
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
14830
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
14831
|
+
package: array(ZoneRuleSchema).readonly()
|
|
14752
14832
|
})
|
|
14753
14833
|
},
|
|
14754
14834
|
zones: zonesCapability
|
|
@@ -18710,6 +18790,7 @@ var EventKindIconSchema = _enum([
|
|
|
18710
18790
|
"smoke",
|
|
18711
18791
|
"water",
|
|
18712
18792
|
"button",
|
|
18793
|
+
"package",
|
|
18713
18794
|
"generic"
|
|
18714
18795
|
]);
|
|
18715
18796
|
var EventKindCategorySchema = _enum([
|
|
@@ -18717,7 +18798,8 @@ var EventKindCategorySchema = _enum([
|
|
|
18717
18798
|
"audio",
|
|
18718
18799
|
"detection",
|
|
18719
18800
|
"sensor",
|
|
18720
|
-
"custom"
|
|
18801
|
+
"custom",
|
|
18802
|
+
"package"
|
|
18721
18803
|
]);
|
|
18722
18804
|
var EventKindDescriptorSchema = object({
|
|
18723
18805
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -22380,6 +22462,108 @@ method(object({
|
|
|
22380
22462
|
auth: "admin"
|
|
22381
22463
|
});
|
|
22382
22464
|
/**
|
|
22465
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
22466
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
22467
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
22468
|
+
* delete-after-download.
|
|
22469
|
+
*
|
|
22470
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
22471
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
22472
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
22473
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
22474
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
22475
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
22476
|
+
* SQLite); history rows survive file deletion for audit.
|
|
22477
|
+
*/
|
|
22478
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
22479
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
22480
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
22481
|
+
var ExportTimelapseSchema = object({
|
|
22482
|
+
everyMs: number().int().positive(),
|
|
22483
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
22484
|
+
});
|
|
22485
|
+
/**
|
|
22486
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
22487
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
22488
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
22489
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
22490
|
+
*/
|
|
22491
|
+
var ExportOptionsSchema = object({
|
|
22492
|
+
speed: ExportSpeedSchema.optional(),
|
|
22493
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
22494
|
+
includeAudio: boolean(),
|
|
22495
|
+
maxLifeMs: number().int().positive(),
|
|
22496
|
+
deleteAfterDownload: boolean(),
|
|
22497
|
+
title: string().max(200).optional()
|
|
22498
|
+
}).superRefine((v, ctx) => {
|
|
22499
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
22500
|
+
code: ZodIssueCode.custom,
|
|
22501
|
+
message: "speed and timelapse are mutually exclusive",
|
|
22502
|
+
path: ["timelapse"]
|
|
22503
|
+
});
|
|
22504
|
+
});
|
|
22505
|
+
var ExportStateSchema = _enum([
|
|
22506
|
+
"queued",
|
|
22507
|
+
"rendering",
|
|
22508
|
+
"ready",
|
|
22509
|
+
"failed",
|
|
22510
|
+
"expired",
|
|
22511
|
+
"deleted"
|
|
22512
|
+
]);
|
|
22513
|
+
/** One export job / history row. */
|
|
22514
|
+
var ExportRecordSchema = object({
|
|
22515
|
+
id: string(),
|
|
22516
|
+
deviceId: number(),
|
|
22517
|
+
profile: string(),
|
|
22518
|
+
fromMs: number(),
|
|
22519
|
+
toMs: number(),
|
|
22520
|
+
options: ExportOptionsSchema,
|
|
22521
|
+
state: ExportStateSchema,
|
|
22522
|
+
/** 0–100 while rendering; null otherwise. */
|
|
22523
|
+
progressPct: number().nullable(),
|
|
22524
|
+
/** File size once ready; null before. */
|
|
22525
|
+
fileBytes: number().nullable(),
|
|
22526
|
+
expiresAt: number(),
|
|
22527
|
+
deleteAfterDownload: boolean(),
|
|
22528
|
+
/** Epoch of the first complete download; null until then. */
|
|
22529
|
+
downloadedAt: number().nullable(),
|
|
22530
|
+
createdAt: number(),
|
|
22531
|
+
/** User id/name that requested the export. */
|
|
22532
|
+
createdBy: string(),
|
|
22533
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
22534
|
+
error: string().nullable()
|
|
22535
|
+
});
|
|
22536
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
22537
|
+
var ExportDownloadSchema = object({
|
|
22538
|
+
url: string(),
|
|
22539
|
+
endpoints: array(string())
|
|
22540
|
+
});
|
|
22541
|
+
method(object({
|
|
22542
|
+
deviceId: number(),
|
|
22543
|
+
profile: string(),
|
|
22544
|
+
fromMs: number(),
|
|
22545
|
+
toMs: number(),
|
|
22546
|
+
options: ExportOptionsSchema
|
|
22547
|
+
}), ExportRecordSchema, {
|
|
22548
|
+
kind: "mutation",
|
|
22549
|
+
auth: "protected"
|
|
22550
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
22551
|
+
kind: "query",
|
|
22552
|
+
auth: "protected"
|
|
22553
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22554
|
+
kind: "query",
|
|
22555
|
+
auth: "protected"
|
|
22556
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22557
|
+
kind: "mutation",
|
|
22558
|
+
auth: "protected"
|
|
22559
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22560
|
+
kind: "mutation",
|
|
22561
|
+
auth: "protected"
|
|
22562
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
22563
|
+
kind: "query",
|
|
22564
|
+
auth: "protected"
|
|
22565
|
+
});
|
|
22566
|
+
/**
|
|
22383
22567
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
22384
22568
|
* payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
|
|
22385
22569
|
* `deviceId`.
|
|
@@ -26303,6 +26487,42 @@ Object.freeze({
|
|
|
26303
26487
|
addonId: null,
|
|
26304
26488
|
access: "create"
|
|
26305
26489
|
},
|
|
26490
|
+
"recordingExport.cancelExport": {
|
|
26491
|
+
capName: "recordingExport",
|
|
26492
|
+
capScope: "system",
|
|
26493
|
+
addonId: null,
|
|
26494
|
+
access: "create"
|
|
26495
|
+
},
|
|
26496
|
+
"recordingExport.createExport": {
|
|
26497
|
+
capName: "recordingExport",
|
|
26498
|
+
capScope: "system",
|
|
26499
|
+
addonId: null,
|
|
26500
|
+
access: "create"
|
|
26501
|
+
},
|
|
26502
|
+
"recordingExport.deleteExport": {
|
|
26503
|
+
capName: "recordingExport",
|
|
26504
|
+
capScope: "system",
|
|
26505
|
+
addonId: null,
|
|
26506
|
+
access: "delete"
|
|
26507
|
+
},
|
|
26508
|
+
"recordingExport.getDownloadUrl": {
|
|
26509
|
+
capName: "recordingExport",
|
|
26510
|
+
capScope: "system",
|
|
26511
|
+
addonId: null,
|
|
26512
|
+
access: "view"
|
|
26513
|
+
},
|
|
26514
|
+
"recordingExport.getExport": {
|
|
26515
|
+
capName: "recordingExport",
|
|
26516
|
+
capScope: "system",
|
|
26517
|
+
addonId: null,
|
|
26518
|
+
access: "view"
|
|
26519
|
+
},
|
|
26520
|
+
"recordingExport.listExports": {
|
|
26521
|
+
capName: "recordingExport",
|
|
26522
|
+
capScope: "system",
|
|
26523
|
+
addonId: null,
|
|
26524
|
+
access: "view"
|
|
26525
|
+
},
|
|
26306
26526
|
"sceneMonitor.captureReference": {
|
|
26307
26527
|
capName: "scene-monitor",
|
|
26308
26528
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region ../types/dist/event-category-
|
|
1
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
2
2
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
3
3
|
EventCategory["SystemBoot"] = "system.boot";
|
|
4
4
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -151,6 +151,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
151
151
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
152
152
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
153
153
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
154
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
155
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
156
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
157
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
158
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
154
159
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
155
160
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
156
161
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -440,6 +445,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
440
445
|
*/
|
|
441
446
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
442
447
|
/**
|
|
448
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
449
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
450
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
451
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
452
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
453
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
454
|
+
* this bus topic drives notifier rules + live UI. See
|
|
455
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
456
|
+
*/
|
|
457
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
458
|
+
/**
|
|
459
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
460
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
461
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
462
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
463
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
464
|
+
*/
|
|
465
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
466
|
+
/**
|
|
443
467
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
444
468
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
445
469
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5192,6 +5216,25 @@ function preprocess(fn, schema) {
|
|
|
5192
5216
|
out: schema
|
|
5193
5217
|
});
|
|
5194
5218
|
}
|
|
5219
|
+
//#endregion
|
|
5220
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5221
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5222
|
+
var ZodIssueCode = {
|
|
5223
|
+
invalid_type: "invalid_type",
|
|
5224
|
+
too_big: "too_big",
|
|
5225
|
+
too_small: "too_small",
|
|
5226
|
+
invalid_format: "invalid_format",
|
|
5227
|
+
not_multiple_of: "not_multiple_of",
|
|
5228
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5229
|
+
invalid_union: "invalid_union",
|
|
5230
|
+
invalid_key: "invalid_key",
|
|
5231
|
+
invalid_element: "invalid_element",
|
|
5232
|
+
invalid_value: "invalid_value",
|
|
5233
|
+
custom: "custom"
|
|
5234
|
+
};
|
|
5235
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5236
|
+
var ZodFirstPartyTypeKind;
|
|
5237
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5195
5238
|
Object.fromEntries([
|
|
5196
5239
|
{
|
|
5197
5240
|
id: "overview",
|
|
@@ -7250,6 +7293,24 @@ var RecordingRetentionSchema = object({
|
|
|
7250
7293
|
maxSizeGb: number().min(0).optional()
|
|
7251
7294
|
});
|
|
7252
7295
|
/**
|
|
7296
|
+
* Scrub-thumbnail fidelity preset — the single per-camera selector bundling the
|
|
7297
|
+
* sprite tile RESOLUTION + JPEG QUALITY the recorder packs timeline-scrub
|
|
7298
|
+
* previews at. Five graduated steps; absent on a config = `standard` (the
|
|
7299
|
+
* shipped default, matching `sheet-geometry`/`sheet-composer`).
|
|
7300
|
+
*
|
|
7301
|
+
* Existing sheets are IMMUTABLE — a changed preset applies to NEW windows only.
|
|
7302
|
+
* Each window's index sidecar carries its own tile dims, so a camera whose
|
|
7303
|
+
* preset changed over time renders every historical window at the dims it was
|
|
7304
|
+
* written with.
|
|
7305
|
+
*/
|
|
7306
|
+
var ScrubThumbnailPresetSchema = _enum([
|
|
7307
|
+
"minimal",
|
|
7308
|
+
"low",
|
|
7309
|
+
"standard",
|
|
7310
|
+
"high",
|
|
7311
|
+
"max"
|
|
7312
|
+
]);
|
|
7313
|
+
/**
|
|
7253
7314
|
* The full per-camera recording intent — the wire shape of a RecordingTarget.
|
|
7254
7315
|
*
|
|
7255
7316
|
* `mode` is the authoritative storage choice; `schedule`/`triggers`/`pre`/`post`
|
|
@@ -7286,7 +7347,14 @@ var RecordingConfigSchema = object({
|
|
|
7286
7347
|
* derived into bands once via `migrateConfigToBands`.
|
|
7287
7348
|
*/
|
|
7288
7349
|
bands: array(RecordingBandSchema).optional(),
|
|
7289
|
-
retention: RecordingRetentionSchema.optional()
|
|
7350
|
+
retention: RecordingRetentionSchema.optional(),
|
|
7351
|
+
/**
|
|
7352
|
+
* Per-camera scrub-thumbnail fidelity preset (resolution + JPEG quality for
|
|
7353
|
+
* timeline-scrub sprite previews). Absent = `standard`. Applies to NEW
|
|
7354
|
+
* windows only — existing sheets are immutable, and each window's index
|
|
7355
|
+
* carries its own tile dims so mixed-preset history renders correctly.
|
|
7356
|
+
*/
|
|
7357
|
+
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7290
7358
|
});
|
|
7291
7359
|
/**
|
|
7292
7360
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
@@ -14644,7 +14712,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
14644
14712
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
14645
14713
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
14646
14714
|
*/
|
|
14647
|
-
var ZoneRuleStageEnum = _enum([
|
|
14715
|
+
var ZoneRuleStageEnum = _enum([
|
|
14716
|
+
"motion",
|
|
14717
|
+
"detection",
|
|
14718
|
+
"package"
|
|
14719
|
+
]);
|
|
14648
14720
|
/**
|
|
14649
14721
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
14650
14722
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -14738,16 +14810,24 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14738
14810
|
})
|
|
14739
14811
|
},
|
|
14740
14812
|
/**
|
|
14741
|
-
* Runtime-state slice —
|
|
14813
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
14742
14814
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
14743
|
-
* of
|
|
14744
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
14815
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
14816
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
14745
14817
|
* complete current set. Consumers that only care about one stage
|
|
14746
14818
|
* just read the matching property.
|
|
14819
|
+
*
|
|
14820
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
14821
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14822
|
+
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
14823
|
+
* The orchestrator provider that writes this stage lands in a later
|
|
14824
|
+
* slice; until then the mirror carries only `{motion, detection}` and
|
|
14825
|
+
* consumers read `package` as absent (treat as `[]`).
|
|
14747
14826
|
*/
|
|
14748
14827
|
runtimeState: object({
|
|
14749
14828
|
motion: array(ZoneRuleSchema).readonly(),
|
|
14750
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
14829
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
14830
|
+
package: array(ZoneRuleSchema).readonly()
|
|
14751
14831
|
})
|
|
14752
14832
|
},
|
|
14753
14833
|
zones: zonesCapability
|
|
@@ -18709,6 +18789,7 @@ var EventKindIconSchema = _enum([
|
|
|
18709
18789
|
"smoke",
|
|
18710
18790
|
"water",
|
|
18711
18791
|
"button",
|
|
18792
|
+
"package",
|
|
18712
18793
|
"generic"
|
|
18713
18794
|
]);
|
|
18714
18795
|
var EventKindCategorySchema = _enum([
|
|
@@ -18716,7 +18797,8 @@ var EventKindCategorySchema = _enum([
|
|
|
18716
18797
|
"audio",
|
|
18717
18798
|
"detection",
|
|
18718
18799
|
"sensor",
|
|
18719
|
-
"custom"
|
|
18800
|
+
"custom",
|
|
18801
|
+
"package"
|
|
18720
18802
|
]);
|
|
18721
18803
|
var EventKindDescriptorSchema = object({
|
|
18722
18804
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -22379,6 +22461,108 @@ method(object({
|
|
|
22379
22461
|
auth: "admin"
|
|
22380
22462
|
});
|
|
22381
22463
|
/**
|
|
22464
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
22465
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
22466
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
22467
|
+
* delete-after-download.
|
|
22468
|
+
*
|
|
22469
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
22470
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
22471
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
22472
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
22473
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
22474
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
22475
|
+
* SQLite); history rows survive file deletion for audit.
|
|
22476
|
+
*/
|
|
22477
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
22478
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
22479
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
22480
|
+
var ExportTimelapseSchema = object({
|
|
22481
|
+
everyMs: number().int().positive(),
|
|
22482
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
22483
|
+
});
|
|
22484
|
+
/**
|
|
22485
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
22486
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
22487
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
22488
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
22489
|
+
*/
|
|
22490
|
+
var ExportOptionsSchema = object({
|
|
22491
|
+
speed: ExportSpeedSchema.optional(),
|
|
22492
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
22493
|
+
includeAudio: boolean(),
|
|
22494
|
+
maxLifeMs: number().int().positive(),
|
|
22495
|
+
deleteAfterDownload: boolean(),
|
|
22496
|
+
title: string().max(200).optional()
|
|
22497
|
+
}).superRefine((v, ctx) => {
|
|
22498
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
22499
|
+
code: ZodIssueCode.custom,
|
|
22500
|
+
message: "speed and timelapse are mutually exclusive",
|
|
22501
|
+
path: ["timelapse"]
|
|
22502
|
+
});
|
|
22503
|
+
});
|
|
22504
|
+
var ExportStateSchema = _enum([
|
|
22505
|
+
"queued",
|
|
22506
|
+
"rendering",
|
|
22507
|
+
"ready",
|
|
22508
|
+
"failed",
|
|
22509
|
+
"expired",
|
|
22510
|
+
"deleted"
|
|
22511
|
+
]);
|
|
22512
|
+
/** One export job / history row. */
|
|
22513
|
+
var ExportRecordSchema = object({
|
|
22514
|
+
id: string(),
|
|
22515
|
+
deviceId: number(),
|
|
22516
|
+
profile: string(),
|
|
22517
|
+
fromMs: number(),
|
|
22518
|
+
toMs: number(),
|
|
22519
|
+
options: ExportOptionsSchema,
|
|
22520
|
+
state: ExportStateSchema,
|
|
22521
|
+
/** 0–100 while rendering; null otherwise. */
|
|
22522
|
+
progressPct: number().nullable(),
|
|
22523
|
+
/** File size once ready; null before. */
|
|
22524
|
+
fileBytes: number().nullable(),
|
|
22525
|
+
expiresAt: number(),
|
|
22526
|
+
deleteAfterDownload: boolean(),
|
|
22527
|
+
/** Epoch of the first complete download; null until then. */
|
|
22528
|
+
downloadedAt: number().nullable(),
|
|
22529
|
+
createdAt: number(),
|
|
22530
|
+
/** User id/name that requested the export. */
|
|
22531
|
+
createdBy: string(),
|
|
22532
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
22533
|
+
error: string().nullable()
|
|
22534
|
+
});
|
|
22535
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
22536
|
+
var ExportDownloadSchema = object({
|
|
22537
|
+
url: string(),
|
|
22538
|
+
endpoints: array(string())
|
|
22539
|
+
});
|
|
22540
|
+
method(object({
|
|
22541
|
+
deviceId: number(),
|
|
22542
|
+
profile: string(),
|
|
22543
|
+
fromMs: number(),
|
|
22544
|
+
toMs: number(),
|
|
22545
|
+
options: ExportOptionsSchema
|
|
22546
|
+
}), ExportRecordSchema, {
|
|
22547
|
+
kind: "mutation",
|
|
22548
|
+
auth: "protected"
|
|
22549
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
22550
|
+
kind: "query",
|
|
22551
|
+
auth: "protected"
|
|
22552
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22553
|
+
kind: "query",
|
|
22554
|
+
auth: "protected"
|
|
22555
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22556
|
+
kind: "mutation",
|
|
22557
|
+
auth: "protected"
|
|
22558
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22559
|
+
kind: "mutation",
|
|
22560
|
+
auth: "protected"
|
|
22561
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
22562
|
+
kind: "query",
|
|
22563
|
+
auth: "protected"
|
|
22564
|
+
});
|
|
22565
|
+
/**
|
|
22382
22566
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
22383
22567
|
* payload the (legacy) push `streamBroker.publishCameraStream` carried, minus
|
|
22384
22568
|
* `deviceId`.
|
|
@@ -26302,6 +26486,42 @@ Object.freeze({
|
|
|
26302
26486
|
addonId: null,
|
|
26303
26487
|
access: "create"
|
|
26304
26488
|
},
|
|
26489
|
+
"recordingExport.cancelExport": {
|
|
26490
|
+
capName: "recordingExport",
|
|
26491
|
+
capScope: "system",
|
|
26492
|
+
addonId: null,
|
|
26493
|
+
access: "create"
|
|
26494
|
+
},
|
|
26495
|
+
"recordingExport.createExport": {
|
|
26496
|
+
capName: "recordingExport",
|
|
26497
|
+
capScope: "system",
|
|
26498
|
+
addonId: null,
|
|
26499
|
+
access: "create"
|
|
26500
|
+
},
|
|
26501
|
+
"recordingExport.deleteExport": {
|
|
26502
|
+
capName: "recordingExport",
|
|
26503
|
+
capScope: "system",
|
|
26504
|
+
addonId: null,
|
|
26505
|
+
access: "delete"
|
|
26506
|
+
},
|
|
26507
|
+
"recordingExport.getDownloadUrl": {
|
|
26508
|
+
capName: "recordingExport",
|
|
26509
|
+
capScope: "system",
|
|
26510
|
+
addonId: null,
|
|
26511
|
+
access: "view"
|
|
26512
|
+
},
|
|
26513
|
+
"recordingExport.getExport": {
|
|
26514
|
+
capName: "recordingExport",
|
|
26515
|
+
capScope: "system",
|
|
26516
|
+
addonId: null,
|
|
26517
|
+
access: "view"
|
|
26518
|
+
},
|
|
26519
|
+
"recordingExport.listExports": {
|
|
26520
|
+
capName: "recordingExport",
|
|
26521
|
+
capScope: "system",
|
|
26522
|
+
addonId: null,
|
|
26523
|
+
access: "view"
|
|
26524
|
+
},
|
|
26305
26525
|
"sceneMonitor.captureReference": {
|
|
26306
26526
|
capName: "scene-monitor",
|
|
26307
26527
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-unraid",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "Unraid device-provider addon for CamStack — one Container per Unraid instance fanning out array, disk, docker and notification entities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|