@camstack/addon-provider-reolink 1.1.27 → 1.1.29
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 +347 -8
- package/dist/addon.mjs +347 -8
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -26,7 +26,7 @@ let fs_promises = require("fs/promises");
|
|
|
26
26
|
fs_promises = require_chunk.__toESM(fs_promises, 1);
|
|
27
27
|
let node_os = require("node:os");
|
|
28
28
|
node_os = require_chunk.__toESM(node_os);
|
|
29
|
-
//#region ../types/dist/event-category-
|
|
29
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
30
30
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
31
31
|
EventCategory["SystemBoot"] = "system.boot";
|
|
32
32
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -179,6 +179,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
179
179
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
180
180
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
181
181
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
182
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
183
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
184
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
185
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
186
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
182
187
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
183
188
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
184
189
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -468,6 +473,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
468
473
|
*/
|
|
469
474
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
470
475
|
/**
|
|
476
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
477
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
478
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
479
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
480
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
481
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
482
|
+
* this bus topic drives notifier rules + live UI. See
|
|
483
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
484
|
+
*/
|
|
485
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
486
|
+
/**
|
|
487
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
488
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
489
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
490
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
491
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
492
|
+
*/
|
|
493
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
494
|
+
/**
|
|
471
495
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
472
496
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
473
497
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5206,6 +5230,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5206
5230
|
};
|
|
5207
5231
|
return inst;
|
|
5208
5232
|
}
|
|
5233
|
+
//#endregion
|
|
5234
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5235
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5236
|
+
var ZodIssueCode$16 = {
|
|
5237
|
+
invalid_type: "invalid_type",
|
|
5238
|
+
too_big: "too_big",
|
|
5239
|
+
too_small: "too_small",
|
|
5240
|
+
invalid_format: "invalid_format",
|
|
5241
|
+
not_multiple_of: "not_multiple_of",
|
|
5242
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5243
|
+
invalid_union: "invalid_union",
|
|
5244
|
+
invalid_key: "invalid_key",
|
|
5245
|
+
invalid_element: "invalid_element",
|
|
5246
|
+
invalid_value: "invalid_value",
|
|
5247
|
+
custom: "custom"
|
|
5248
|
+
};
|
|
5249
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5250
|
+
var ZodFirstPartyTypeKind$16;
|
|
5251
|
+
ZodFirstPartyTypeKind$16 || (ZodFirstPartyTypeKind$16 = {});
|
|
5209
5252
|
Object.fromEntries([
|
|
5210
5253
|
{
|
|
5211
5254
|
id: "overview",
|
|
@@ -7515,6 +7558,62 @@ var RecordingConfigSchema = object({
|
|
|
7515
7558
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7516
7559
|
});
|
|
7517
7560
|
/**
|
|
7561
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7562
|
+
* recordings and events management surfaces.
|
|
7563
|
+
*
|
|
7564
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7565
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7566
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7567
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7568
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7569
|
+
* never fail the operation it records.
|
|
7570
|
+
*/
|
|
7571
|
+
/** Which management domain the operation belongs to. */
|
|
7572
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7573
|
+
/** The kind of management operation performed. */
|
|
7574
|
+
var OpsLogOpSchema = _enum([
|
|
7575
|
+
"prune",
|
|
7576
|
+
"manual-delete",
|
|
7577
|
+
"rescan",
|
|
7578
|
+
"retention-run"
|
|
7579
|
+
]);
|
|
7580
|
+
/** Why the operation ran. */
|
|
7581
|
+
var OpsLogReasonSchema = _enum([
|
|
7582
|
+
"retention",
|
|
7583
|
+
"quota",
|
|
7584
|
+
"manual",
|
|
7585
|
+
"operator"
|
|
7586
|
+
]);
|
|
7587
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7588
|
+
var OpsLogEntrySchema = object({
|
|
7589
|
+
/** Unique row id. */
|
|
7590
|
+
id: string(),
|
|
7591
|
+
/** Epoch ms the operation completed. */
|
|
7592
|
+
at: number(),
|
|
7593
|
+
domain: OpsLogDomainSchema,
|
|
7594
|
+
op: OpsLogOpSchema,
|
|
7595
|
+
reason: OpsLogReasonSchema,
|
|
7596
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7597
|
+
deviceId: number().nullable(),
|
|
7598
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7599
|
+
nodeId: string(),
|
|
7600
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7601
|
+
itemsAffected: number(),
|
|
7602
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7603
|
+
bytesReclaimed: number(),
|
|
7604
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7605
|
+
detail: string().nullable(),
|
|
7606
|
+
/** Who/what triggered the op. */
|
|
7607
|
+
actor: string()
|
|
7608
|
+
});
|
|
7609
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7610
|
+
var OpsLogQueryInputSchema = object({
|
|
7611
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7612
|
+
deviceId: number().optional(),
|
|
7613
|
+
/** Max rows returned, newest-first. */
|
|
7614
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7615
|
+
});
|
|
7616
|
+
/**
|
|
7518
7617
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7519
7618
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7520
7619
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -14909,7 +15008,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
14909
15008
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
14910
15009
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
14911
15010
|
*/
|
|
14912
|
-
var ZoneRuleStageEnum = _enum([
|
|
15011
|
+
var ZoneRuleStageEnum = _enum([
|
|
15012
|
+
"motion",
|
|
15013
|
+
"detection",
|
|
15014
|
+
"package"
|
|
15015
|
+
]);
|
|
14913
15016
|
/**
|
|
14914
15017
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
14915
15018
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -15003,16 +15106,25 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
15003
15106
|
})
|
|
15004
15107
|
},
|
|
15005
15108
|
/**
|
|
15006
|
-
* Runtime-state slice —
|
|
15109
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
15007
15110
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
15008
|
-
* of
|
|
15009
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
15111
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
15112
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
15010
15113
|
* complete current set. Consumers that only care about one stage
|
|
15011
15114
|
* just read the matching property.
|
|
15115
|
+
*
|
|
15116
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
15117
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
15118
|
+
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
15119
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15120
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15121
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15122
|
+
* off `device.state.zoneRules.value.package`.
|
|
15012
15123
|
*/
|
|
15013
15124
|
runtimeState: object({
|
|
15014
15125
|
motion: array(ZoneRuleSchema).readonly(),
|
|
15015
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
15126
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
15127
|
+
package: array(ZoneRuleSchema).readonly()
|
|
15016
15128
|
})
|
|
15017
15129
|
},
|
|
15018
15130
|
zones: zonesCapability
|
|
@@ -18986,6 +19098,7 @@ var EventKindIconSchema = _enum([
|
|
|
18986
19098
|
"smoke",
|
|
18987
19099
|
"water",
|
|
18988
19100
|
"button",
|
|
19101
|
+
"package",
|
|
18989
19102
|
"generic"
|
|
18990
19103
|
]);
|
|
18991
19104
|
var EventKindCategorySchema = _enum([
|
|
@@ -18993,7 +19106,8 @@ var EventKindCategorySchema = _enum([
|
|
|
18993
19106
|
"audio",
|
|
18994
19107
|
"detection",
|
|
18995
19108
|
"sensor",
|
|
18996
|
-
"custom"
|
|
19109
|
+
"custom",
|
|
19110
|
+
"package"
|
|
18997
19111
|
]);
|
|
18998
19112
|
var EventKindDescriptorSchema = object({
|
|
18999
19113
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -19334,6 +19448,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19334
19448
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19335
19449
|
embeddings: number().int()
|
|
19336
19450
|
});
|
|
19451
|
+
/** Event-store footprint for one camera. */
|
|
19452
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19453
|
+
deviceId: number(),
|
|
19454
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19455
|
+
rows: number().int(),
|
|
19456
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19457
|
+
bytes: number().int()
|
|
19458
|
+
});
|
|
19459
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19460
|
+
var EventStoreFootprintSchema = object({
|
|
19461
|
+
totalRows: number().int(),
|
|
19462
|
+
totalBytes: number().int(),
|
|
19463
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19464
|
+
});
|
|
19465
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19466
|
+
var EventPruneCountsSchema = object({
|
|
19467
|
+
motion: number().int(),
|
|
19468
|
+
object: number().int(),
|
|
19469
|
+
audio: number().int()
|
|
19470
|
+
});
|
|
19337
19471
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19338
19472
|
deviceId: number(),
|
|
19339
19473
|
trackId: string()
|
|
@@ -19397,6 +19531,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19397
19531
|
}), {
|
|
19398
19532
|
kind: "mutation",
|
|
19399
19533
|
auth: "admin"
|
|
19534
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19535
|
+
kind: "query",
|
|
19536
|
+
auth: "admin"
|
|
19537
|
+
}), method(object({
|
|
19538
|
+
olderThanMs: number(),
|
|
19539
|
+
reason: OpsLogReasonSchema.optional()
|
|
19540
|
+
}), EventPruneCountsSchema, {
|
|
19541
|
+
kind: "mutation",
|
|
19542
|
+
auth: "admin"
|
|
19543
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19544
|
+
kind: "mutation",
|
|
19545
|
+
auth: "admin"
|
|
19546
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19547
|
+
kind: "query",
|
|
19548
|
+
auth: "admin"
|
|
19400
19549
|
}), method(object({
|
|
19401
19550
|
eventId: string(),
|
|
19402
19551
|
kind: MediaFileKindEnum.optional()
|
|
@@ -22799,13 +22948,131 @@ method(object({
|
|
|
22799
22948
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22800
22949
|
kind: "mutation",
|
|
22801
22950
|
auth: "admin"
|
|
22802
|
-
}), method(object({
|
|
22951
|
+
}), method(object({
|
|
22952
|
+
deviceId: number(),
|
|
22953
|
+
reason: OpsLogReasonSchema.optional()
|
|
22954
|
+
}), object({
|
|
22803
22955
|
floorMs: number().nullable(),
|
|
22804
22956
|
deletedBuckets: number().int(),
|
|
22805
22957
|
reclaimedBytes: number().int()
|
|
22806
22958
|
}), {
|
|
22807
22959
|
kind: "mutation",
|
|
22808
22960
|
auth: "admin"
|
|
22961
|
+
}), method(object({
|
|
22962
|
+
deviceId: number(),
|
|
22963
|
+
fromMs: number().optional(),
|
|
22964
|
+
toMs: number().optional()
|
|
22965
|
+
}), object({
|
|
22966
|
+
deletedBuckets: number().int(),
|
|
22967
|
+
reclaimedBytes: number().int()
|
|
22968
|
+
}), {
|
|
22969
|
+
kind: "mutation",
|
|
22970
|
+
auth: "admin"
|
|
22971
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
22972
|
+
kind: "query",
|
|
22973
|
+
auth: "admin"
|
|
22974
|
+
});
|
|
22975
|
+
/**
|
|
22976
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
22977
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
22978
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
22979
|
+
* delete-after-download.
|
|
22980
|
+
*
|
|
22981
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
22982
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
22983
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
22984
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
22985
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
22986
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
22987
|
+
* SQLite); history rows survive file deletion for audit.
|
|
22988
|
+
*/
|
|
22989
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
22990
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
22991
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
22992
|
+
var ExportTimelapseSchema = object({
|
|
22993
|
+
everyMs: number().int().positive(),
|
|
22994
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
22995
|
+
});
|
|
22996
|
+
/**
|
|
22997
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
22998
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
22999
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
23000
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
23001
|
+
*/
|
|
23002
|
+
var ExportOptionsSchema = object({
|
|
23003
|
+
speed: ExportSpeedSchema.optional(),
|
|
23004
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
23005
|
+
includeAudio: boolean(),
|
|
23006
|
+
maxLifeMs: number().int().positive(),
|
|
23007
|
+
deleteAfterDownload: boolean(),
|
|
23008
|
+
title: string().max(200).optional()
|
|
23009
|
+
}).superRefine((v, ctx) => {
|
|
23010
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
23011
|
+
code: ZodIssueCode$16.custom,
|
|
23012
|
+
message: "speed and timelapse are mutually exclusive",
|
|
23013
|
+
path: ["timelapse"]
|
|
23014
|
+
});
|
|
23015
|
+
});
|
|
23016
|
+
var ExportStateSchema = _enum([
|
|
23017
|
+
"queued",
|
|
23018
|
+
"rendering",
|
|
23019
|
+
"ready",
|
|
23020
|
+
"failed",
|
|
23021
|
+
"expired",
|
|
23022
|
+
"deleted"
|
|
23023
|
+
]);
|
|
23024
|
+
/** One export job / history row. */
|
|
23025
|
+
var ExportRecordSchema = object({
|
|
23026
|
+
id: string(),
|
|
23027
|
+
deviceId: number(),
|
|
23028
|
+
profile: string(),
|
|
23029
|
+
fromMs: number(),
|
|
23030
|
+
toMs: number(),
|
|
23031
|
+
options: ExportOptionsSchema,
|
|
23032
|
+
state: ExportStateSchema,
|
|
23033
|
+
/** 0–100 while rendering; null otherwise. */
|
|
23034
|
+
progressPct: number().nullable(),
|
|
23035
|
+
/** File size once ready; null before. */
|
|
23036
|
+
fileBytes: number().nullable(),
|
|
23037
|
+
expiresAt: number(),
|
|
23038
|
+
deleteAfterDownload: boolean(),
|
|
23039
|
+
/** Epoch of the first complete download; null until then. */
|
|
23040
|
+
downloadedAt: number().nullable(),
|
|
23041
|
+
createdAt: number(),
|
|
23042
|
+
/** User id/name that requested the export. */
|
|
23043
|
+
createdBy: string(),
|
|
23044
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
23045
|
+
error: string().nullable()
|
|
23046
|
+
});
|
|
23047
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
23048
|
+
var ExportDownloadSchema = object({
|
|
23049
|
+
url: string(),
|
|
23050
|
+
endpoints: array(string())
|
|
23051
|
+
});
|
|
23052
|
+
method(object({
|
|
23053
|
+
deviceId: number(),
|
|
23054
|
+
profile: string(),
|
|
23055
|
+
fromMs: number(),
|
|
23056
|
+
toMs: number(),
|
|
23057
|
+
options: ExportOptionsSchema
|
|
23058
|
+
}), ExportRecordSchema, {
|
|
23059
|
+
kind: "mutation",
|
|
23060
|
+
auth: "protected"
|
|
23061
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
23062
|
+
kind: "query",
|
|
23063
|
+
auth: "protected"
|
|
23064
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23065
|
+
kind: "query",
|
|
23066
|
+
auth: "protected"
|
|
23067
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23068
|
+
kind: "mutation",
|
|
23069
|
+
auth: "protected"
|
|
23070
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23071
|
+
kind: "mutation",
|
|
23072
|
+
auth: "protected"
|
|
23073
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
23074
|
+
kind: "query",
|
|
23075
|
+
auth: "protected"
|
|
22809
23076
|
});
|
|
22810
23077
|
/**
|
|
22811
23078
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
@@ -26036,6 +26303,12 @@ Object.freeze({
|
|
|
26036
26303
|
addonId: null,
|
|
26037
26304
|
access: "delete"
|
|
26038
26305
|
},
|
|
26306
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26307
|
+
capName: "pipeline-analytics",
|
|
26308
|
+
capScope: "device",
|
|
26309
|
+
addonId: null,
|
|
26310
|
+
access: "delete"
|
|
26311
|
+
},
|
|
26039
26312
|
"pipelineAnalytics.deleteTracks": {
|
|
26040
26313
|
capName: "pipeline-analytics",
|
|
26041
26314
|
capScope: "device",
|
|
@@ -26066,6 +26339,12 @@ Object.freeze({
|
|
|
26066
26339
|
addonId: null,
|
|
26067
26340
|
access: "view"
|
|
26068
26341
|
},
|
|
26342
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26343
|
+
capName: "pipeline-analytics",
|
|
26344
|
+
capScope: "device",
|
|
26345
|
+
addonId: null,
|
|
26346
|
+
access: "view"
|
|
26347
|
+
},
|
|
26069
26348
|
"pipelineAnalytics.getKeyEvents": {
|
|
26070
26349
|
capName: "pipeline-analytics",
|
|
26071
26350
|
capScope: "device",
|
|
@@ -26108,6 +26387,12 @@ Object.freeze({
|
|
|
26108
26387
|
addonId: null,
|
|
26109
26388
|
access: "view"
|
|
26110
26389
|
},
|
|
26390
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26391
|
+
capName: "pipeline-analytics",
|
|
26392
|
+
capScope: "device",
|
|
26393
|
+
addonId: null,
|
|
26394
|
+
access: "view"
|
|
26395
|
+
},
|
|
26111
26396
|
"pipelineAnalytics.listRecentTracks": {
|
|
26112
26397
|
capName: "pipeline-analytics",
|
|
26113
26398
|
capScope: "device",
|
|
@@ -26120,6 +26405,12 @@ Object.freeze({
|
|
|
26120
26405
|
addonId: null,
|
|
26121
26406
|
access: "view"
|
|
26122
26407
|
},
|
|
26408
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26409
|
+
capName: "pipeline-analytics",
|
|
26410
|
+
capScope: "device",
|
|
26411
|
+
addonId: null,
|
|
26412
|
+
access: "create"
|
|
26413
|
+
},
|
|
26123
26414
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
26124
26415
|
capName: "pipeline-analytics",
|
|
26125
26416
|
capScope: "device",
|
|
@@ -26882,6 +27173,12 @@ Object.freeze({
|
|
|
26882
27173
|
addonId: null,
|
|
26883
27174
|
access: "create"
|
|
26884
27175
|
},
|
|
27176
|
+
"recording.deleteFootprint": {
|
|
27177
|
+
capName: "recording",
|
|
27178
|
+
capScope: "system",
|
|
27179
|
+
addonId: null,
|
|
27180
|
+
access: "delete"
|
|
27181
|
+
},
|
|
26885
27182
|
"recording.getAvailability": {
|
|
26886
27183
|
capName: "recording",
|
|
26887
27184
|
capScope: "system",
|
|
@@ -26912,6 +27209,12 @@ Object.freeze({
|
|
|
26912
27209
|
addonId: null,
|
|
26913
27210
|
access: "view"
|
|
26914
27211
|
},
|
|
27212
|
+
"recording.listOpsLog": {
|
|
27213
|
+
capName: "recording",
|
|
27214
|
+
capScope: "system",
|
|
27215
|
+
addonId: null,
|
|
27216
|
+
access: "view"
|
|
27217
|
+
},
|
|
26915
27218
|
"recording.locateSegment": {
|
|
26916
27219
|
capName: "recording",
|
|
26917
27220
|
capScope: "system",
|
|
@@ -26942,6 +27245,42 @@ Object.freeze({
|
|
|
26942
27245
|
addonId: null,
|
|
26943
27246
|
access: "create"
|
|
26944
27247
|
},
|
|
27248
|
+
"recordingExport.cancelExport": {
|
|
27249
|
+
capName: "recordingExport",
|
|
27250
|
+
capScope: "system",
|
|
27251
|
+
addonId: null,
|
|
27252
|
+
access: "create"
|
|
27253
|
+
},
|
|
27254
|
+
"recordingExport.createExport": {
|
|
27255
|
+
capName: "recordingExport",
|
|
27256
|
+
capScope: "system",
|
|
27257
|
+
addonId: null,
|
|
27258
|
+
access: "create"
|
|
27259
|
+
},
|
|
27260
|
+
"recordingExport.deleteExport": {
|
|
27261
|
+
capName: "recordingExport",
|
|
27262
|
+
capScope: "system",
|
|
27263
|
+
addonId: null,
|
|
27264
|
+
access: "delete"
|
|
27265
|
+
},
|
|
27266
|
+
"recordingExport.getDownloadUrl": {
|
|
27267
|
+
capName: "recordingExport",
|
|
27268
|
+
capScope: "system",
|
|
27269
|
+
addonId: null,
|
|
27270
|
+
access: "view"
|
|
27271
|
+
},
|
|
27272
|
+
"recordingExport.getExport": {
|
|
27273
|
+
capName: "recordingExport",
|
|
27274
|
+
capScope: "system",
|
|
27275
|
+
addonId: null,
|
|
27276
|
+
access: "view"
|
|
27277
|
+
},
|
|
27278
|
+
"recordingExport.listExports": {
|
|
27279
|
+
capName: "recordingExport",
|
|
27280
|
+
capScope: "system",
|
|
27281
|
+
addonId: null,
|
|
27282
|
+
access: "view"
|
|
27283
|
+
},
|
|
26945
27284
|
"sceneMonitor.captureReference": {
|
|
26946
27285
|
capName: "scene-monitor",
|
|
26947
27286
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -21,7 +21,7 @@ import netImpl from "net";
|
|
|
21
21
|
import { fileURLToPath } from "url";
|
|
22
22
|
import { mkdir } from "fs/promises";
|
|
23
23
|
import os from "node:os";
|
|
24
|
-
//#region ../types/dist/event-category-
|
|
24
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
25
25
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
26
26
|
EventCategory["SystemBoot"] = "system.boot";
|
|
27
27
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -174,6 +174,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
174
174
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
175
175
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
176
176
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
177
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
178
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
179
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
180
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
181
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
177
182
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
178
183
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
179
184
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -463,6 +468,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
463
468
|
*/
|
|
464
469
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
465
470
|
/**
|
|
471
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
472
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
473
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
474
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
475
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
476
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
477
|
+
* this bus topic drives notifier rules + live UI. See
|
|
478
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
479
|
+
*/
|
|
480
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
481
|
+
/**
|
|
482
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
483
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
484
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
485
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
486
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
487
|
+
*/
|
|
488
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
489
|
+
/**
|
|
466
490
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
467
491
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
468
492
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5201,6 +5225,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5201
5225
|
};
|
|
5202
5226
|
return inst;
|
|
5203
5227
|
}
|
|
5228
|
+
//#endregion
|
|
5229
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5230
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5231
|
+
var ZodIssueCode$16 = {
|
|
5232
|
+
invalid_type: "invalid_type",
|
|
5233
|
+
too_big: "too_big",
|
|
5234
|
+
too_small: "too_small",
|
|
5235
|
+
invalid_format: "invalid_format",
|
|
5236
|
+
not_multiple_of: "not_multiple_of",
|
|
5237
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5238
|
+
invalid_union: "invalid_union",
|
|
5239
|
+
invalid_key: "invalid_key",
|
|
5240
|
+
invalid_element: "invalid_element",
|
|
5241
|
+
invalid_value: "invalid_value",
|
|
5242
|
+
custom: "custom"
|
|
5243
|
+
};
|
|
5244
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5245
|
+
var ZodFirstPartyTypeKind$16;
|
|
5246
|
+
ZodFirstPartyTypeKind$16 || (ZodFirstPartyTypeKind$16 = {});
|
|
5204
5247
|
Object.fromEntries([
|
|
5205
5248
|
{
|
|
5206
5249
|
id: "overview",
|
|
@@ -7510,6 +7553,62 @@ var RecordingConfigSchema = object({
|
|
|
7510
7553
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7511
7554
|
});
|
|
7512
7555
|
/**
|
|
7556
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7557
|
+
* recordings and events management surfaces.
|
|
7558
|
+
*
|
|
7559
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7560
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7561
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7562
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7563
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7564
|
+
* never fail the operation it records.
|
|
7565
|
+
*/
|
|
7566
|
+
/** Which management domain the operation belongs to. */
|
|
7567
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7568
|
+
/** The kind of management operation performed. */
|
|
7569
|
+
var OpsLogOpSchema = _enum([
|
|
7570
|
+
"prune",
|
|
7571
|
+
"manual-delete",
|
|
7572
|
+
"rescan",
|
|
7573
|
+
"retention-run"
|
|
7574
|
+
]);
|
|
7575
|
+
/** Why the operation ran. */
|
|
7576
|
+
var OpsLogReasonSchema = _enum([
|
|
7577
|
+
"retention",
|
|
7578
|
+
"quota",
|
|
7579
|
+
"manual",
|
|
7580
|
+
"operator"
|
|
7581
|
+
]);
|
|
7582
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7583
|
+
var OpsLogEntrySchema = object({
|
|
7584
|
+
/** Unique row id. */
|
|
7585
|
+
id: string(),
|
|
7586
|
+
/** Epoch ms the operation completed. */
|
|
7587
|
+
at: number(),
|
|
7588
|
+
domain: OpsLogDomainSchema,
|
|
7589
|
+
op: OpsLogOpSchema,
|
|
7590
|
+
reason: OpsLogReasonSchema,
|
|
7591
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7592
|
+
deviceId: number().nullable(),
|
|
7593
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7594
|
+
nodeId: string(),
|
|
7595
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7596
|
+
itemsAffected: number(),
|
|
7597
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7598
|
+
bytesReclaimed: number(),
|
|
7599
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7600
|
+
detail: string().nullable(),
|
|
7601
|
+
/** Who/what triggered the op. */
|
|
7602
|
+
actor: string()
|
|
7603
|
+
});
|
|
7604
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7605
|
+
var OpsLogQueryInputSchema = object({
|
|
7606
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7607
|
+
deviceId: number().optional(),
|
|
7608
|
+
/** Max rows returned, newest-first. */
|
|
7609
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7610
|
+
});
|
|
7611
|
+
/**
|
|
7513
7612
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7514
7613
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7515
7614
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -14904,7 +15003,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
14904
15003
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
14905
15004
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
14906
15005
|
*/
|
|
14907
|
-
var ZoneRuleStageEnum = _enum([
|
|
15006
|
+
var ZoneRuleStageEnum = _enum([
|
|
15007
|
+
"motion",
|
|
15008
|
+
"detection",
|
|
15009
|
+
"package"
|
|
15010
|
+
]);
|
|
14908
15011
|
/**
|
|
14909
15012
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
14910
15013
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -14998,16 +15101,25 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14998
15101
|
})
|
|
14999
15102
|
},
|
|
15000
15103
|
/**
|
|
15001
|
-
* Runtime-state slice —
|
|
15104
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
15002
15105
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
15003
|
-
* of
|
|
15004
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
15106
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
15107
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
15005
15108
|
* complete current set. Consumers that only care about one stage
|
|
15006
15109
|
* just read the matching property.
|
|
15110
|
+
*
|
|
15111
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
15112
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
15113
|
+
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
15114
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
15115
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
15116
|
+
* package}` shape, so consumers read the current package rules directly
|
|
15117
|
+
* off `device.state.zoneRules.value.package`.
|
|
15007
15118
|
*/
|
|
15008
15119
|
runtimeState: object({
|
|
15009
15120
|
motion: array(ZoneRuleSchema).readonly(),
|
|
15010
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
15121
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
15122
|
+
package: array(ZoneRuleSchema).readonly()
|
|
15011
15123
|
})
|
|
15012
15124
|
},
|
|
15013
15125
|
zones: zonesCapability
|
|
@@ -18981,6 +19093,7 @@ var EventKindIconSchema = _enum([
|
|
|
18981
19093
|
"smoke",
|
|
18982
19094
|
"water",
|
|
18983
19095
|
"button",
|
|
19096
|
+
"package",
|
|
18984
19097
|
"generic"
|
|
18985
19098
|
]);
|
|
18986
19099
|
var EventKindCategorySchema = _enum([
|
|
@@ -18988,7 +19101,8 @@ var EventKindCategorySchema = _enum([
|
|
|
18988
19101
|
"audio",
|
|
18989
19102
|
"detection",
|
|
18990
19103
|
"sensor",
|
|
18991
|
-
"custom"
|
|
19104
|
+
"custom",
|
|
19105
|
+
"package"
|
|
18992
19106
|
]);
|
|
18993
19107
|
var EventKindDescriptorSchema = object({
|
|
18994
19108
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -19329,6 +19443,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19329
19443
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19330
19444
|
embeddings: number().int()
|
|
19331
19445
|
});
|
|
19446
|
+
/** Event-store footprint for one camera. */
|
|
19447
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19448
|
+
deviceId: number(),
|
|
19449
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19450
|
+
rows: number().int(),
|
|
19451
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19452
|
+
bytes: number().int()
|
|
19453
|
+
});
|
|
19454
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19455
|
+
var EventStoreFootprintSchema = object({
|
|
19456
|
+
totalRows: number().int(),
|
|
19457
|
+
totalBytes: number().int(),
|
|
19458
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19459
|
+
});
|
|
19460
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19461
|
+
var EventPruneCountsSchema = object({
|
|
19462
|
+
motion: number().int(),
|
|
19463
|
+
object: number().int(),
|
|
19464
|
+
audio: number().int()
|
|
19465
|
+
});
|
|
19332
19466
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19333
19467
|
deviceId: number(),
|
|
19334
19468
|
trackId: string()
|
|
@@ -19392,6 +19526,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19392
19526
|
}), {
|
|
19393
19527
|
kind: "mutation",
|
|
19394
19528
|
auth: "admin"
|
|
19529
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19530
|
+
kind: "query",
|
|
19531
|
+
auth: "admin"
|
|
19532
|
+
}), method(object({
|
|
19533
|
+
olderThanMs: number(),
|
|
19534
|
+
reason: OpsLogReasonSchema.optional()
|
|
19535
|
+
}), EventPruneCountsSchema, {
|
|
19536
|
+
kind: "mutation",
|
|
19537
|
+
auth: "admin"
|
|
19538
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19539
|
+
kind: "mutation",
|
|
19540
|
+
auth: "admin"
|
|
19541
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19542
|
+
kind: "query",
|
|
19543
|
+
auth: "admin"
|
|
19395
19544
|
}), method(object({
|
|
19396
19545
|
eventId: string(),
|
|
19397
19546
|
kind: MediaFileKindEnum.optional()
|
|
@@ -22794,13 +22943,131 @@ method(object({
|
|
|
22794
22943
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22795
22944
|
kind: "mutation",
|
|
22796
22945
|
auth: "admin"
|
|
22797
|
-
}), method(object({
|
|
22946
|
+
}), method(object({
|
|
22947
|
+
deviceId: number(),
|
|
22948
|
+
reason: OpsLogReasonSchema.optional()
|
|
22949
|
+
}), object({
|
|
22798
22950
|
floorMs: number().nullable(),
|
|
22799
22951
|
deletedBuckets: number().int(),
|
|
22800
22952
|
reclaimedBytes: number().int()
|
|
22801
22953
|
}), {
|
|
22802
22954
|
kind: "mutation",
|
|
22803
22955
|
auth: "admin"
|
|
22956
|
+
}), method(object({
|
|
22957
|
+
deviceId: number(),
|
|
22958
|
+
fromMs: number().optional(),
|
|
22959
|
+
toMs: number().optional()
|
|
22960
|
+
}), object({
|
|
22961
|
+
deletedBuckets: number().int(),
|
|
22962
|
+
reclaimedBytes: number().int()
|
|
22963
|
+
}), {
|
|
22964
|
+
kind: "mutation",
|
|
22965
|
+
auth: "admin"
|
|
22966
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
22967
|
+
kind: "query",
|
|
22968
|
+
auth: "admin"
|
|
22969
|
+
});
|
|
22970
|
+
/**
|
|
22971
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
22972
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
22973
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
22974
|
+
* delete-after-download.
|
|
22975
|
+
*
|
|
22976
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
22977
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
22978
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
22979
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
22980
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
22981
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
22982
|
+
* SQLite); history rows survive file deletion for audit.
|
|
22983
|
+
*/
|
|
22984
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
22985
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
22986
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
22987
|
+
var ExportTimelapseSchema = object({
|
|
22988
|
+
everyMs: number().int().positive(),
|
|
22989
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
22990
|
+
});
|
|
22991
|
+
/**
|
|
22992
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
22993
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
22994
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
22995
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
22996
|
+
*/
|
|
22997
|
+
var ExportOptionsSchema = object({
|
|
22998
|
+
speed: ExportSpeedSchema.optional(),
|
|
22999
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
23000
|
+
includeAudio: boolean(),
|
|
23001
|
+
maxLifeMs: number().int().positive(),
|
|
23002
|
+
deleteAfterDownload: boolean(),
|
|
23003
|
+
title: string().max(200).optional()
|
|
23004
|
+
}).superRefine((v, ctx) => {
|
|
23005
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
23006
|
+
code: ZodIssueCode$16.custom,
|
|
23007
|
+
message: "speed and timelapse are mutually exclusive",
|
|
23008
|
+
path: ["timelapse"]
|
|
23009
|
+
});
|
|
23010
|
+
});
|
|
23011
|
+
var ExportStateSchema = _enum([
|
|
23012
|
+
"queued",
|
|
23013
|
+
"rendering",
|
|
23014
|
+
"ready",
|
|
23015
|
+
"failed",
|
|
23016
|
+
"expired",
|
|
23017
|
+
"deleted"
|
|
23018
|
+
]);
|
|
23019
|
+
/** One export job / history row. */
|
|
23020
|
+
var ExportRecordSchema = object({
|
|
23021
|
+
id: string(),
|
|
23022
|
+
deviceId: number(),
|
|
23023
|
+
profile: string(),
|
|
23024
|
+
fromMs: number(),
|
|
23025
|
+
toMs: number(),
|
|
23026
|
+
options: ExportOptionsSchema,
|
|
23027
|
+
state: ExportStateSchema,
|
|
23028
|
+
/** 0–100 while rendering; null otherwise. */
|
|
23029
|
+
progressPct: number().nullable(),
|
|
23030
|
+
/** File size once ready; null before. */
|
|
23031
|
+
fileBytes: number().nullable(),
|
|
23032
|
+
expiresAt: number(),
|
|
23033
|
+
deleteAfterDownload: boolean(),
|
|
23034
|
+
/** Epoch of the first complete download; null until then. */
|
|
23035
|
+
downloadedAt: number().nullable(),
|
|
23036
|
+
createdAt: number(),
|
|
23037
|
+
/** User id/name that requested the export. */
|
|
23038
|
+
createdBy: string(),
|
|
23039
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
23040
|
+
error: string().nullable()
|
|
23041
|
+
});
|
|
23042
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
23043
|
+
var ExportDownloadSchema = object({
|
|
23044
|
+
url: string(),
|
|
23045
|
+
endpoints: array(string())
|
|
23046
|
+
});
|
|
23047
|
+
method(object({
|
|
23048
|
+
deviceId: number(),
|
|
23049
|
+
profile: string(),
|
|
23050
|
+
fromMs: number(),
|
|
23051
|
+
toMs: number(),
|
|
23052
|
+
options: ExportOptionsSchema
|
|
23053
|
+
}), ExportRecordSchema, {
|
|
23054
|
+
kind: "mutation",
|
|
23055
|
+
auth: "protected"
|
|
23056
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
23057
|
+
kind: "query",
|
|
23058
|
+
auth: "protected"
|
|
23059
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23060
|
+
kind: "query",
|
|
23061
|
+
auth: "protected"
|
|
23062
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23063
|
+
kind: "mutation",
|
|
23064
|
+
auth: "protected"
|
|
23065
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
23066
|
+
kind: "mutation",
|
|
23067
|
+
auth: "protected"
|
|
23068
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
23069
|
+
kind: "query",
|
|
23070
|
+
auth: "protected"
|
|
22804
23071
|
});
|
|
22805
23072
|
/**
|
|
22806
23073
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
@@ -26031,6 +26298,12 @@ Object.freeze({
|
|
|
26031
26298
|
addonId: null,
|
|
26032
26299
|
access: "delete"
|
|
26033
26300
|
},
|
|
26301
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
26302
|
+
capName: "pipeline-analytics",
|
|
26303
|
+
capScope: "device",
|
|
26304
|
+
addonId: null,
|
|
26305
|
+
access: "delete"
|
|
26306
|
+
},
|
|
26034
26307
|
"pipelineAnalytics.deleteTracks": {
|
|
26035
26308
|
capName: "pipeline-analytics",
|
|
26036
26309
|
capScope: "device",
|
|
@@ -26061,6 +26334,12 @@ Object.freeze({
|
|
|
26061
26334
|
addonId: null,
|
|
26062
26335
|
access: "view"
|
|
26063
26336
|
},
|
|
26337
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
26338
|
+
capName: "pipeline-analytics",
|
|
26339
|
+
capScope: "device",
|
|
26340
|
+
addonId: null,
|
|
26341
|
+
access: "view"
|
|
26342
|
+
},
|
|
26064
26343
|
"pipelineAnalytics.getKeyEvents": {
|
|
26065
26344
|
capName: "pipeline-analytics",
|
|
26066
26345
|
capScope: "device",
|
|
@@ -26103,6 +26382,12 @@ Object.freeze({
|
|
|
26103
26382
|
addonId: null,
|
|
26104
26383
|
access: "view"
|
|
26105
26384
|
},
|
|
26385
|
+
"pipelineAnalytics.listOpsLog": {
|
|
26386
|
+
capName: "pipeline-analytics",
|
|
26387
|
+
capScope: "device",
|
|
26388
|
+
addonId: null,
|
|
26389
|
+
access: "view"
|
|
26390
|
+
},
|
|
26106
26391
|
"pipelineAnalytics.listRecentTracks": {
|
|
26107
26392
|
capName: "pipeline-analytics",
|
|
26108
26393
|
capScope: "device",
|
|
@@ -26115,6 +26400,12 @@ Object.freeze({
|
|
|
26115
26400
|
addonId: null,
|
|
26116
26401
|
access: "view"
|
|
26117
26402
|
},
|
|
26403
|
+
"pipelineAnalytics.pruneEvents": {
|
|
26404
|
+
capName: "pipeline-analytics",
|
|
26405
|
+
capScope: "device",
|
|
26406
|
+
addonId: null,
|
|
26407
|
+
access: "create"
|
|
26408
|
+
},
|
|
26118
26409
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
26119
26410
|
capName: "pipeline-analytics",
|
|
26120
26411
|
capScope: "device",
|
|
@@ -26877,6 +27168,12 @@ Object.freeze({
|
|
|
26877
27168
|
addonId: null,
|
|
26878
27169
|
access: "create"
|
|
26879
27170
|
},
|
|
27171
|
+
"recording.deleteFootprint": {
|
|
27172
|
+
capName: "recording",
|
|
27173
|
+
capScope: "system",
|
|
27174
|
+
addonId: null,
|
|
27175
|
+
access: "delete"
|
|
27176
|
+
},
|
|
26880
27177
|
"recording.getAvailability": {
|
|
26881
27178
|
capName: "recording",
|
|
26882
27179
|
capScope: "system",
|
|
@@ -26907,6 +27204,12 @@ Object.freeze({
|
|
|
26907
27204
|
addonId: null,
|
|
26908
27205
|
access: "view"
|
|
26909
27206
|
},
|
|
27207
|
+
"recording.listOpsLog": {
|
|
27208
|
+
capName: "recording",
|
|
27209
|
+
capScope: "system",
|
|
27210
|
+
addonId: null,
|
|
27211
|
+
access: "view"
|
|
27212
|
+
},
|
|
26910
27213
|
"recording.locateSegment": {
|
|
26911
27214
|
capName: "recording",
|
|
26912
27215
|
capScope: "system",
|
|
@@ -26937,6 +27240,42 @@ Object.freeze({
|
|
|
26937
27240
|
addonId: null,
|
|
26938
27241
|
access: "create"
|
|
26939
27242
|
},
|
|
27243
|
+
"recordingExport.cancelExport": {
|
|
27244
|
+
capName: "recordingExport",
|
|
27245
|
+
capScope: "system",
|
|
27246
|
+
addonId: null,
|
|
27247
|
+
access: "create"
|
|
27248
|
+
},
|
|
27249
|
+
"recordingExport.createExport": {
|
|
27250
|
+
capName: "recordingExport",
|
|
27251
|
+
capScope: "system",
|
|
27252
|
+
addonId: null,
|
|
27253
|
+
access: "create"
|
|
27254
|
+
},
|
|
27255
|
+
"recordingExport.deleteExport": {
|
|
27256
|
+
capName: "recordingExport",
|
|
27257
|
+
capScope: "system",
|
|
27258
|
+
addonId: null,
|
|
27259
|
+
access: "delete"
|
|
27260
|
+
},
|
|
27261
|
+
"recordingExport.getDownloadUrl": {
|
|
27262
|
+
capName: "recordingExport",
|
|
27263
|
+
capScope: "system",
|
|
27264
|
+
addonId: null,
|
|
27265
|
+
access: "view"
|
|
27266
|
+
},
|
|
27267
|
+
"recordingExport.getExport": {
|
|
27268
|
+
capName: "recordingExport",
|
|
27269
|
+
capScope: "system",
|
|
27270
|
+
addonId: null,
|
|
27271
|
+
access: "view"
|
|
27272
|
+
},
|
|
27273
|
+
"recordingExport.listExports": {
|
|
27274
|
+
capName: "recordingExport",
|
|
27275
|
+
capScope: "system",
|
|
27276
|
+
addonId: null,
|
|
27277
|
+
access: "view"
|
|
27278
|
+
},
|
|
26940
27279
|
"sceneMonitor.captureReference": {
|
|
26941
27280
|
capName: "scene-monitor",
|
|
26942
27281
|
capScope: "device",
|