@camstack/addon-provider-dreame 0.1.31 → 0.1.33
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
|
@@ -37,7 +37,7 @@ let crypto$1 = require("crypto");
|
|
|
37
37
|
let events = require("events");
|
|
38
38
|
let zlib = require("zlib");
|
|
39
39
|
zlib = __toESM(zlib, 1);
|
|
40
|
-
//#region ../types/dist/event-category-
|
|
40
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
41
41
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
42
42
|
EventCategory["SystemBoot"] = "system.boot";
|
|
43
43
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -190,6 +190,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
190
190
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
191
191
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
192
192
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
193
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
194
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
195
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
196
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
197
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
193
198
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
194
199
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
195
200
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -479,6 +484,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
479
484
|
*/
|
|
480
485
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
481
486
|
/**
|
|
487
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
488
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
489
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
490
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
491
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
492
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
493
|
+
* this bus topic drives notifier rules + live UI. See
|
|
494
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
495
|
+
*/
|
|
496
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
497
|
+
/**
|
|
498
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
499
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
500
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
501
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
502
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
503
|
+
*/
|
|
504
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
505
|
+
/**
|
|
482
506
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
483
507
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
484
508
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5231,6 +5255,25 @@ function preprocess(fn, schema) {
|
|
|
5231
5255
|
out: schema
|
|
5232
5256
|
});
|
|
5233
5257
|
}
|
|
5258
|
+
//#endregion
|
|
5259
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5260
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5261
|
+
var ZodIssueCode$1 = {
|
|
5262
|
+
invalid_type: "invalid_type",
|
|
5263
|
+
too_big: "too_big",
|
|
5264
|
+
too_small: "too_small",
|
|
5265
|
+
invalid_format: "invalid_format",
|
|
5266
|
+
not_multiple_of: "not_multiple_of",
|
|
5267
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5268
|
+
invalid_union: "invalid_union",
|
|
5269
|
+
invalid_key: "invalid_key",
|
|
5270
|
+
invalid_element: "invalid_element",
|
|
5271
|
+
invalid_value: "invalid_value",
|
|
5272
|
+
custom: "custom"
|
|
5273
|
+
};
|
|
5274
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5275
|
+
var ZodFirstPartyTypeKind$1;
|
|
5276
|
+
ZodFirstPartyTypeKind$1 || (ZodFirstPartyTypeKind$1 = {});
|
|
5234
5277
|
Object.fromEntries([
|
|
5235
5278
|
{
|
|
5236
5279
|
id: "overview",
|
|
@@ -7353,6 +7396,62 @@ var RecordingConfigSchema = object({
|
|
|
7353
7396
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7354
7397
|
});
|
|
7355
7398
|
/**
|
|
7399
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7400
|
+
* recordings and events management surfaces.
|
|
7401
|
+
*
|
|
7402
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7403
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7404
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7405
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7406
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7407
|
+
* never fail the operation it records.
|
|
7408
|
+
*/
|
|
7409
|
+
/** Which management domain the operation belongs to. */
|
|
7410
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7411
|
+
/** The kind of management operation performed. */
|
|
7412
|
+
var OpsLogOpSchema = _enum([
|
|
7413
|
+
"prune",
|
|
7414
|
+
"manual-delete",
|
|
7415
|
+
"rescan",
|
|
7416
|
+
"retention-run"
|
|
7417
|
+
]);
|
|
7418
|
+
/** Why the operation ran. */
|
|
7419
|
+
var OpsLogReasonSchema = _enum([
|
|
7420
|
+
"retention",
|
|
7421
|
+
"quota",
|
|
7422
|
+
"manual",
|
|
7423
|
+
"operator"
|
|
7424
|
+
]);
|
|
7425
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7426
|
+
var OpsLogEntrySchema = object({
|
|
7427
|
+
/** Unique row id. */
|
|
7428
|
+
id: string(),
|
|
7429
|
+
/** Epoch ms the operation completed. */
|
|
7430
|
+
at: number(),
|
|
7431
|
+
domain: OpsLogDomainSchema,
|
|
7432
|
+
op: OpsLogOpSchema,
|
|
7433
|
+
reason: OpsLogReasonSchema,
|
|
7434
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7435
|
+
deviceId: number().nullable(),
|
|
7436
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7437
|
+
nodeId: string(),
|
|
7438
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7439
|
+
itemsAffected: number(),
|
|
7440
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7441
|
+
bytesReclaimed: number(),
|
|
7442
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7443
|
+
detail: string().nullable(),
|
|
7444
|
+
/** Who/what triggered the op. */
|
|
7445
|
+
actor: string()
|
|
7446
|
+
});
|
|
7447
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7448
|
+
var OpsLogQueryInputSchema = object({
|
|
7449
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7450
|
+
deviceId: number().optional(),
|
|
7451
|
+
/** Max rows returned, newest-first. */
|
|
7452
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7453
|
+
});
|
|
7454
|
+
/**
|
|
7356
7455
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7357
7456
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7358
7457
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -14708,7 +14807,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
14708
14807
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
14709
14808
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
14710
14809
|
*/
|
|
14711
|
-
var ZoneRuleStageEnum = _enum([
|
|
14810
|
+
var ZoneRuleStageEnum = _enum([
|
|
14811
|
+
"motion",
|
|
14812
|
+
"detection",
|
|
14813
|
+
"package"
|
|
14814
|
+
]);
|
|
14712
14815
|
/**
|
|
14713
14816
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
14714
14817
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -14802,16 +14905,25 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14802
14905
|
})
|
|
14803
14906
|
},
|
|
14804
14907
|
/**
|
|
14805
|
-
* Runtime-state slice —
|
|
14908
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
14806
14909
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
14807
|
-
* of
|
|
14808
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
14910
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
14911
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
14809
14912
|
* complete current set. Consumers that only care about one stage
|
|
14810
14913
|
* just read the matching property.
|
|
14914
|
+
*
|
|
14915
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
14916
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14917
|
+
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
14918
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
14919
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
14920
|
+
* package}` shape, so consumers read the current package rules directly
|
|
14921
|
+
* off `device.state.zoneRules.value.package`.
|
|
14811
14922
|
*/
|
|
14812
14923
|
runtimeState: object({
|
|
14813
14924
|
motion: array(ZoneRuleSchema).readonly(),
|
|
14814
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
14925
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
14926
|
+
package: array(ZoneRuleSchema).readonly()
|
|
14815
14927
|
})
|
|
14816
14928
|
},
|
|
14817
14929
|
zones: zonesCapability
|
|
@@ -18790,6 +18902,7 @@ var EventKindIconSchema = _enum([
|
|
|
18790
18902
|
"smoke",
|
|
18791
18903
|
"water",
|
|
18792
18904
|
"button",
|
|
18905
|
+
"package",
|
|
18793
18906
|
"generic"
|
|
18794
18907
|
]);
|
|
18795
18908
|
var EventKindCategorySchema = _enum([
|
|
@@ -18797,7 +18910,8 @@ var EventKindCategorySchema = _enum([
|
|
|
18797
18910
|
"audio",
|
|
18798
18911
|
"detection",
|
|
18799
18912
|
"sensor",
|
|
18800
|
-
"custom"
|
|
18913
|
+
"custom",
|
|
18914
|
+
"package"
|
|
18801
18915
|
]);
|
|
18802
18916
|
var EventKindDescriptorSchema = object({
|
|
18803
18917
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -19138,6 +19252,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19138
19252
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19139
19253
|
embeddings: number().int()
|
|
19140
19254
|
});
|
|
19255
|
+
/** Event-store footprint for one camera. */
|
|
19256
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19257
|
+
deviceId: number(),
|
|
19258
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19259
|
+
rows: number().int(),
|
|
19260
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19261
|
+
bytes: number().int()
|
|
19262
|
+
});
|
|
19263
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19264
|
+
var EventStoreFootprintSchema = object({
|
|
19265
|
+
totalRows: number().int(),
|
|
19266
|
+
totalBytes: number().int(),
|
|
19267
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19268
|
+
});
|
|
19269
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19270
|
+
var EventPruneCountsSchema = object({
|
|
19271
|
+
motion: number().int(),
|
|
19272
|
+
object: number().int(),
|
|
19273
|
+
audio: number().int()
|
|
19274
|
+
});
|
|
19141
19275
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19142
19276
|
deviceId: number(),
|
|
19143
19277
|
trackId: string()
|
|
@@ -19201,6 +19335,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19201
19335
|
}), {
|
|
19202
19336
|
kind: "mutation",
|
|
19203
19337
|
auth: "admin"
|
|
19338
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19339
|
+
kind: "query",
|
|
19340
|
+
auth: "admin"
|
|
19341
|
+
}), method(object({
|
|
19342
|
+
olderThanMs: number(),
|
|
19343
|
+
reason: OpsLogReasonSchema.optional()
|
|
19344
|
+
}), EventPruneCountsSchema, {
|
|
19345
|
+
kind: "mutation",
|
|
19346
|
+
auth: "admin"
|
|
19347
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19348
|
+
kind: "mutation",
|
|
19349
|
+
auth: "admin"
|
|
19350
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19351
|
+
kind: "query",
|
|
19352
|
+
auth: "admin"
|
|
19204
19353
|
}), method(object({
|
|
19205
19354
|
eventId: string(),
|
|
19206
19355
|
kind: MediaFileKindEnum.optional()
|
|
@@ -22451,13 +22600,131 @@ method(object({
|
|
|
22451
22600
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22452
22601
|
kind: "mutation",
|
|
22453
22602
|
auth: "admin"
|
|
22454
|
-
}), method(object({
|
|
22603
|
+
}), method(object({
|
|
22604
|
+
deviceId: number(),
|
|
22605
|
+
reason: OpsLogReasonSchema.optional()
|
|
22606
|
+
}), object({
|
|
22455
22607
|
floorMs: number().nullable(),
|
|
22456
22608
|
deletedBuckets: number().int(),
|
|
22457
22609
|
reclaimedBytes: number().int()
|
|
22458
22610
|
}), {
|
|
22459
22611
|
kind: "mutation",
|
|
22460
22612
|
auth: "admin"
|
|
22613
|
+
}), method(object({
|
|
22614
|
+
deviceId: number(),
|
|
22615
|
+
fromMs: number().optional(),
|
|
22616
|
+
toMs: number().optional()
|
|
22617
|
+
}), object({
|
|
22618
|
+
deletedBuckets: number().int(),
|
|
22619
|
+
reclaimedBytes: number().int()
|
|
22620
|
+
}), {
|
|
22621
|
+
kind: "mutation",
|
|
22622
|
+
auth: "admin"
|
|
22623
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
22624
|
+
kind: "query",
|
|
22625
|
+
auth: "admin"
|
|
22626
|
+
});
|
|
22627
|
+
/**
|
|
22628
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
22629
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
22630
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
22631
|
+
* delete-after-download.
|
|
22632
|
+
*
|
|
22633
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
22634
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
22635
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
22636
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
22637
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
22638
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
22639
|
+
* SQLite); history rows survive file deletion for audit.
|
|
22640
|
+
*/
|
|
22641
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
22642
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
22643
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
22644
|
+
var ExportTimelapseSchema = object({
|
|
22645
|
+
everyMs: number().int().positive(),
|
|
22646
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
22647
|
+
});
|
|
22648
|
+
/**
|
|
22649
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
22650
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
22651
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
22652
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
22653
|
+
*/
|
|
22654
|
+
var ExportOptionsSchema = object({
|
|
22655
|
+
speed: ExportSpeedSchema.optional(),
|
|
22656
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
22657
|
+
includeAudio: boolean(),
|
|
22658
|
+
maxLifeMs: number().int().positive(),
|
|
22659
|
+
deleteAfterDownload: boolean(),
|
|
22660
|
+
title: string().max(200).optional()
|
|
22661
|
+
}).superRefine((v, ctx) => {
|
|
22662
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
22663
|
+
code: ZodIssueCode$1.custom,
|
|
22664
|
+
message: "speed and timelapse are mutually exclusive",
|
|
22665
|
+
path: ["timelapse"]
|
|
22666
|
+
});
|
|
22667
|
+
});
|
|
22668
|
+
var ExportStateSchema = _enum([
|
|
22669
|
+
"queued",
|
|
22670
|
+
"rendering",
|
|
22671
|
+
"ready",
|
|
22672
|
+
"failed",
|
|
22673
|
+
"expired",
|
|
22674
|
+
"deleted"
|
|
22675
|
+
]);
|
|
22676
|
+
/** One export job / history row. */
|
|
22677
|
+
var ExportRecordSchema = object({
|
|
22678
|
+
id: string(),
|
|
22679
|
+
deviceId: number(),
|
|
22680
|
+
profile: string(),
|
|
22681
|
+
fromMs: number(),
|
|
22682
|
+
toMs: number(),
|
|
22683
|
+
options: ExportOptionsSchema,
|
|
22684
|
+
state: ExportStateSchema,
|
|
22685
|
+
/** 0–100 while rendering; null otherwise. */
|
|
22686
|
+
progressPct: number().nullable(),
|
|
22687
|
+
/** File size once ready; null before. */
|
|
22688
|
+
fileBytes: number().nullable(),
|
|
22689
|
+
expiresAt: number(),
|
|
22690
|
+
deleteAfterDownload: boolean(),
|
|
22691
|
+
/** Epoch of the first complete download; null until then. */
|
|
22692
|
+
downloadedAt: number().nullable(),
|
|
22693
|
+
createdAt: number(),
|
|
22694
|
+
/** User id/name that requested the export. */
|
|
22695
|
+
createdBy: string(),
|
|
22696
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
22697
|
+
error: string().nullable()
|
|
22698
|
+
});
|
|
22699
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
22700
|
+
var ExportDownloadSchema = object({
|
|
22701
|
+
url: string(),
|
|
22702
|
+
endpoints: array(string())
|
|
22703
|
+
});
|
|
22704
|
+
method(object({
|
|
22705
|
+
deviceId: number(),
|
|
22706
|
+
profile: string(),
|
|
22707
|
+
fromMs: number(),
|
|
22708
|
+
toMs: number(),
|
|
22709
|
+
options: ExportOptionsSchema
|
|
22710
|
+
}), ExportRecordSchema, {
|
|
22711
|
+
kind: "mutation",
|
|
22712
|
+
auth: "protected"
|
|
22713
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
22714
|
+
kind: "query",
|
|
22715
|
+
auth: "protected"
|
|
22716
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22717
|
+
kind: "query",
|
|
22718
|
+
auth: "protected"
|
|
22719
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22720
|
+
kind: "mutation",
|
|
22721
|
+
auth: "protected"
|
|
22722
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22723
|
+
kind: "mutation",
|
|
22724
|
+
auth: "protected"
|
|
22725
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
22726
|
+
kind: "query",
|
|
22727
|
+
auth: "protected"
|
|
22461
22728
|
});
|
|
22462
22729
|
/**
|
|
22463
22730
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
@@ -25477,6 +25744,12 @@ Object.freeze({
|
|
|
25477
25744
|
addonId: null,
|
|
25478
25745
|
access: "delete"
|
|
25479
25746
|
},
|
|
25747
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
25748
|
+
capName: "pipeline-analytics",
|
|
25749
|
+
capScope: "device",
|
|
25750
|
+
addonId: null,
|
|
25751
|
+
access: "delete"
|
|
25752
|
+
},
|
|
25480
25753
|
"pipelineAnalytics.deleteTracks": {
|
|
25481
25754
|
capName: "pipeline-analytics",
|
|
25482
25755
|
capScope: "device",
|
|
@@ -25507,6 +25780,12 @@ Object.freeze({
|
|
|
25507
25780
|
addonId: null,
|
|
25508
25781
|
access: "view"
|
|
25509
25782
|
},
|
|
25783
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
25784
|
+
capName: "pipeline-analytics",
|
|
25785
|
+
capScope: "device",
|
|
25786
|
+
addonId: null,
|
|
25787
|
+
access: "view"
|
|
25788
|
+
},
|
|
25510
25789
|
"pipelineAnalytics.getKeyEvents": {
|
|
25511
25790
|
capName: "pipeline-analytics",
|
|
25512
25791
|
capScope: "device",
|
|
@@ -25549,6 +25828,12 @@ Object.freeze({
|
|
|
25549
25828
|
addonId: null,
|
|
25550
25829
|
access: "view"
|
|
25551
25830
|
},
|
|
25831
|
+
"pipelineAnalytics.listOpsLog": {
|
|
25832
|
+
capName: "pipeline-analytics",
|
|
25833
|
+
capScope: "device",
|
|
25834
|
+
addonId: null,
|
|
25835
|
+
access: "view"
|
|
25836
|
+
},
|
|
25552
25837
|
"pipelineAnalytics.listRecentTracks": {
|
|
25553
25838
|
capName: "pipeline-analytics",
|
|
25554
25839
|
capScope: "device",
|
|
@@ -25561,6 +25846,12 @@ Object.freeze({
|
|
|
25561
25846
|
addonId: null,
|
|
25562
25847
|
access: "view"
|
|
25563
25848
|
},
|
|
25849
|
+
"pipelineAnalytics.pruneEvents": {
|
|
25850
|
+
capName: "pipeline-analytics",
|
|
25851
|
+
capScope: "device",
|
|
25852
|
+
addonId: null,
|
|
25853
|
+
access: "create"
|
|
25854
|
+
},
|
|
25564
25855
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
25565
25856
|
capName: "pipeline-analytics",
|
|
25566
25857
|
capScope: "device",
|
|
@@ -26323,6 +26614,12 @@ Object.freeze({
|
|
|
26323
26614
|
addonId: null,
|
|
26324
26615
|
access: "create"
|
|
26325
26616
|
},
|
|
26617
|
+
"recording.deleteFootprint": {
|
|
26618
|
+
capName: "recording",
|
|
26619
|
+
capScope: "system",
|
|
26620
|
+
addonId: null,
|
|
26621
|
+
access: "delete"
|
|
26622
|
+
},
|
|
26326
26623
|
"recording.getAvailability": {
|
|
26327
26624
|
capName: "recording",
|
|
26328
26625
|
capScope: "system",
|
|
@@ -26353,6 +26650,12 @@ Object.freeze({
|
|
|
26353
26650
|
addonId: null,
|
|
26354
26651
|
access: "view"
|
|
26355
26652
|
},
|
|
26653
|
+
"recording.listOpsLog": {
|
|
26654
|
+
capName: "recording",
|
|
26655
|
+
capScope: "system",
|
|
26656
|
+
addonId: null,
|
|
26657
|
+
access: "view"
|
|
26658
|
+
},
|
|
26356
26659
|
"recording.locateSegment": {
|
|
26357
26660
|
capName: "recording",
|
|
26358
26661
|
capScope: "system",
|
|
@@ -26383,6 +26686,42 @@ Object.freeze({
|
|
|
26383
26686
|
addonId: null,
|
|
26384
26687
|
access: "create"
|
|
26385
26688
|
},
|
|
26689
|
+
"recordingExport.cancelExport": {
|
|
26690
|
+
capName: "recordingExport",
|
|
26691
|
+
capScope: "system",
|
|
26692
|
+
addonId: null,
|
|
26693
|
+
access: "create"
|
|
26694
|
+
},
|
|
26695
|
+
"recordingExport.createExport": {
|
|
26696
|
+
capName: "recordingExport",
|
|
26697
|
+
capScope: "system",
|
|
26698
|
+
addonId: null,
|
|
26699
|
+
access: "create"
|
|
26700
|
+
},
|
|
26701
|
+
"recordingExport.deleteExport": {
|
|
26702
|
+
capName: "recordingExport",
|
|
26703
|
+
capScope: "system",
|
|
26704
|
+
addonId: null,
|
|
26705
|
+
access: "delete"
|
|
26706
|
+
},
|
|
26707
|
+
"recordingExport.getDownloadUrl": {
|
|
26708
|
+
capName: "recordingExport",
|
|
26709
|
+
capScope: "system",
|
|
26710
|
+
addonId: null,
|
|
26711
|
+
access: "view"
|
|
26712
|
+
},
|
|
26713
|
+
"recordingExport.getExport": {
|
|
26714
|
+
capName: "recordingExport",
|
|
26715
|
+
capScope: "system",
|
|
26716
|
+
addonId: null,
|
|
26717
|
+
access: "view"
|
|
26718
|
+
},
|
|
26719
|
+
"recordingExport.listExports": {
|
|
26720
|
+
capName: "recordingExport",
|
|
26721
|
+
capScope: "system",
|
|
26722
|
+
addonId: null,
|
|
26723
|
+
access: "view"
|
|
26724
|
+
},
|
|
26386
26725
|
"sceneMonitor.captureReference": {
|
|
26387
26726
|
capName: "scene-monitor",
|
|
26388
26727
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -37,7 +37,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
37
37
|
var __toCommonJS = (mod) => __hasOwnProp.call(mod, "module.exports") ? mod["module.exports"] : __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
38
38
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
39
39
|
//#endregion
|
|
40
|
-
//#region ../types/dist/event-category-
|
|
40
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
41
41
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
42
42
|
EventCategory["SystemBoot"] = "system.boot";
|
|
43
43
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -190,6 +190,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
190
190
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
191
191
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
192
192
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
193
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
194
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
195
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
196
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
197
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
193
198
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
194
199
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
195
200
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -479,6 +484,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
479
484
|
*/
|
|
480
485
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
481
486
|
/**
|
|
487
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
488
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
489
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
490
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
491
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
492
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
493
|
+
* this bus topic drives notifier rules + live UI. See
|
|
494
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
495
|
+
*/
|
|
496
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
497
|
+
/**
|
|
498
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
499
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
500
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
501
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
502
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
503
|
+
*/
|
|
504
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
505
|
+
/**
|
|
482
506
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
483
507
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
484
508
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5231,6 +5255,25 @@ function preprocess(fn, schema) {
|
|
|
5231
5255
|
out: schema
|
|
5232
5256
|
});
|
|
5233
5257
|
}
|
|
5258
|
+
//#endregion
|
|
5259
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5260
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5261
|
+
var ZodIssueCode$1 = {
|
|
5262
|
+
invalid_type: "invalid_type",
|
|
5263
|
+
too_big: "too_big",
|
|
5264
|
+
too_small: "too_small",
|
|
5265
|
+
invalid_format: "invalid_format",
|
|
5266
|
+
not_multiple_of: "not_multiple_of",
|
|
5267
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5268
|
+
invalid_union: "invalid_union",
|
|
5269
|
+
invalid_key: "invalid_key",
|
|
5270
|
+
invalid_element: "invalid_element",
|
|
5271
|
+
invalid_value: "invalid_value",
|
|
5272
|
+
custom: "custom"
|
|
5273
|
+
};
|
|
5274
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5275
|
+
var ZodFirstPartyTypeKind$1;
|
|
5276
|
+
ZodFirstPartyTypeKind$1 || (ZodFirstPartyTypeKind$1 = {});
|
|
5234
5277
|
Object.fromEntries([
|
|
5235
5278
|
{
|
|
5236
5279
|
id: "overview",
|
|
@@ -7353,6 +7396,62 @@ var RecordingConfigSchema = object({
|
|
|
7353
7396
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7354
7397
|
});
|
|
7355
7398
|
/**
|
|
7399
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7400
|
+
* recordings and events management surfaces.
|
|
7401
|
+
*
|
|
7402
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7403
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7404
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7405
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7406
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7407
|
+
* never fail the operation it records.
|
|
7408
|
+
*/
|
|
7409
|
+
/** Which management domain the operation belongs to. */
|
|
7410
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7411
|
+
/** The kind of management operation performed. */
|
|
7412
|
+
var OpsLogOpSchema = _enum([
|
|
7413
|
+
"prune",
|
|
7414
|
+
"manual-delete",
|
|
7415
|
+
"rescan",
|
|
7416
|
+
"retention-run"
|
|
7417
|
+
]);
|
|
7418
|
+
/** Why the operation ran. */
|
|
7419
|
+
var OpsLogReasonSchema = _enum([
|
|
7420
|
+
"retention",
|
|
7421
|
+
"quota",
|
|
7422
|
+
"manual",
|
|
7423
|
+
"operator"
|
|
7424
|
+
]);
|
|
7425
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7426
|
+
var OpsLogEntrySchema = object({
|
|
7427
|
+
/** Unique row id. */
|
|
7428
|
+
id: string(),
|
|
7429
|
+
/** Epoch ms the operation completed. */
|
|
7430
|
+
at: number(),
|
|
7431
|
+
domain: OpsLogDomainSchema,
|
|
7432
|
+
op: OpsLogOpSchema,
|
|
7433
|
+
reason: OpsLogReasonSchema,
|
|
7434
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7435
|
+
deviceId: number().nullable(),
|
|
7436
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7437
|
+
nodeId: string(),
|
|
7438
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7439
|
+
itemsAffected: number(),
|
|
7440
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7441
|
+
bytesReclaimed: number(),
|
|
7442
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7443
|
+
detail: string().nullable(),
|
|
7444
|
+
/** Who/what triggered the op. */
|
|
7445
|
+
actor: string()
|
|
7446
|
+
});
|
|
7447
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7448
|
+
var OpsLogQueryInputSchema = object({
|
|
7449
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7450
|
+
deviceId: number().optional(),
|
|
7451
|
+
/** Max rows returned, newest-first. */
|
|
7452
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7453
|
+
});
|
|
7454
|
+
/**
|
|
7356
7455
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7357
7456
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7358
7457
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -14708,7 +14807,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
14708
14807
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
14709
14808
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
14710
14809
|
*/
|
|
14711
|
-
var ZoneRuleStageEnum = _enum([
|
|
14810
|
+
var ZoneRuleStageEnum = _enum([
|
|
14811
|
+
"motion",
|
|
14812
|
+
"detection",
|
|
14813
|
+
"package"
|
|
14814
|
+
]);
|
|
14712
14815
|
/**
|
|
14713
14816
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
14714
14817
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -14802,16 +14905,25 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14802
14905
|
})
|
|
14803
14906
|
},
|
|
14804
14907
|
/**
|
|
14805
|
-
* Runtime-state slice —
|
|
14908
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
14806
14909
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
14807
|
-
* of
|
|
14808
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
14910
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
14911
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
14809
14912
|
* complete current set. Consumers that only care about one stage
|
|
14810
14913
|
* just read the matching property.
|
|
14914
|
+
*
|
|
14915
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
14916
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14917
|
+
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
14918
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
14919
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
14920
|
+
* package}` shape, so consumers read the current package rules directly
|
|
14921
|
+
* off `device.state.zoneRules.value.package`.
|
|
14811
14922
|
*/
|
|
14812
14923
|
runtimeState: object({
|
|
14813
14924
|
motion: array(ZoneRuleSchema).readonly(),
|
|
14814
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
14925
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
14926
|
+
package: array(ZoneRuleSchema).readonly()
|
|
14815
14927
|
})
|
|
14816
14928
|
},
|
|
14817
14929
|
zones: zonesCapability
|
|
@@ -18790,6 +18902,7 @@ var EventKindIconSchema = _enum([
|
|
|
18790
18902
|
"smoke",
|
|
18791
18903
|
"water",
|
|
18792
18904
|
"button",
|
|
18905
|
+
"package",
|
|
18793
18906
|
"generic"
|
|
18794
18907
|
]);
|
|
18795
18908
|
var EventKindCategorySchema = _enum([
|
|
@@ -18797,7 +18910,8 @@ var EventKindCategorySchema = _enum([
|
|
|
18797
18910
|
"audio",
|
|
18798
18911
|
"detection",
|
|
18799
18912
|
"sensor",
|
|
18800
|
-
"custom"
|
|
18913
|
+
"custom",
|
|
18914
|
+
"package"
|
|
18801
18915
|
]);
|
|
18802
18916
|
var EventKindDescriptorSchema = object({
|
|
18803
18917
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -19138,6 +19252,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19138
19252
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19139
19253
|
embeddings: number().int()
|
|
19140
19254
|
});
|
|
19255
|
+
/** Event-store footprint for one camera. */
|
|
19256
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19257
|
+
deviceId: number(),
|
|
19258
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19259
|
+
rows: number().int(),
|
|
19260
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19261
|
+
bytes: number().int()
|
|
19262
|
+
});
|
|
19263
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19264
|
+
var EventStoreFootprintSchema = object({
|
|
19265
|
+
totalRows: number().int(),
|
|
19266
|
+
totalBytes: number().int(),
|
|
19267
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19268
|
+
});
|
|
19269
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19270
|
+
var EventPruneCountsSchema = object({
|
|
19271
|
+
motion: number().int(),
|
|
19272
|
+
object: number().int(),
|
|
19273
|
+
audio: number().int()
|
|
19274
|
+
});
|
|
19141
19275
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19142
19276
|
deviceId: number(),
|
|
19143
19277
|
trackId: string()
|
|
@@ -19201,6 +19335,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19201
19335
|
}), {
|
|
19202
19336
|
kind: "mutation",
|
|
19203
19337
|
auth: "admin"
|
|
19338
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19339
|
+
kind: "query",
|
|
19340
|
+
auth: "admin"
|
|
19341
|
+
}), method(object({
|
|
19342
|
+
olderThanMs: number(),
|
|
19343
|
+
reason: OpsLogReasonSchema.optional()
|
|
19344
|
+
}), EventPruneCountsSchema, {
|
|
19345
|
+
kind: "mutation",
|
|
19346
|
+
auth: "admin"
|
|
19347
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19348
|
+
kind: "mutation",
|
|
19349
|
+
auth: "admin"
|
|
19350
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19351
|
+
kind: "query",
|
|
19352
|
+
auth: "admin"
|
|
19204
19353
|
}), method(object({
|
|
19205
19354
|
eventId: string(),
|
|
19206
19355
|
kind: MediaFileKindEnum.optional()
|
|
@@ -22451,13 +22600,131 @@ method(object({
|
|
|
22451
22600
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22452
22601
|
kind: "mutation",
|
|
22453
22602
|
auth: "admin"
|
|
22454
|
-
}), method(object({
|
|
22603
|
+
}), method(object({
|
|
22604
|
+
deviceId: number(),
|
|
22605
|
+
reason: OpsLogReasonSchema.optional()
|
|
22606
|
+
}), object({
|
|
22455
22607
|
floorMs: number().nullable(),
|
|
22456
22608
|
deletedBuckets: number().int(),
|
|
22457
22609
|
reclaimedBytes: number().int()
|
|
22458
22610
|
}), {
|
|
22459
22611
|
kind: "mutation",
|
|
22460
22612
|
auth: "admin"
|
|
22613
|
+
}), method(object({
|
|
22614
|
+
deviceId: number(),
|
|
22615
|
+
fromMs: number().optional(),
|
|
22616
|
+
toMs: number().optional()
|
|
22617
|
+
}), object({
|
|
22618
|
+
deletedBuckets: number().int(),
|
|
22619
|
+
reclaimedBytes: number().int()
|
|
22620
|
+
}), {
|
|
22621
|
+
kind: "mutation",
|
|
22622
|
+
auth: "admin"
|
|
22623
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
22624
|
+
kind: "query",
|
|
22625
|
+
auth: "admin"
|
|
22626
|
+
});
|
|
22627
|
+
/**
|
|
22628
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
22629
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
22630
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
22631
|
+
* delete-after-download.
|
|
22632
|
+
*
|
|
22633
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
22634
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
22635
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
22636
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
22637
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
22638
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
22639
|
+
* SQLite); history rows survive file deletion for audit.
|
|
22640
|
+
*/
|
|
22641
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
22642
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
22643
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
22644
|
+
var ExportTimelapseSchema = object({
|
|
22645
|
+
everyMs: number().int().positive(),
|
|
22646
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
22647
|
+
});
|
|
22648
|
+
/**
|
|
22649
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
22650
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
22651
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
22652
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
22653
|
+
*/
|
|
22654
|
+
var ExportOptionsSchema = object({
|
|
22655
|
+
speed: ExportSpeedSchema.optional(),
|
|
22656
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
22657
|
+
includeAudio: boolean(),
|
|
22658
|
+
maxLifeMs: number().int().positive(),
|
|
22659
|
+
deleteAfterDownload: boolean(),
|
|
22660
|
+
title: string().max(200).optional()
|
|
22661
|
+
}).superRefine((v, ctx) => {
|
|
22662
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
22663
|
+
code: ZodIssueCode$1.custom,
|
|
22664
|
+
message: "speed and timelapse are mutually exclusive",
|
|
22665
|
+
path: ["timelapse"]
|
|
22666
|
+
});
|
|
22667
|
+
});
|
|
22668
|
+
var ExportStateSchema = _enum([
|
|
22669
|
+
"queued",
|
|
22670
|
+
"rendering",
|
|
22671
|
+
"ready",
|
|
22672
|
+
"failed",
|
|
22673
|
+
"expired",
|
|
22674
|
+
"deleted"
|
|
22675
|
+
]);
|
|
22676
|
+
/** One export job / history row. */
|
|
22677
|
+
var ExportRecordSchema = object({
|
|
22678
|
+
id: string(),
|
|
22679
|
+
deviceId: number(),
|
|
22680
|
+
profile: string(),
|
|
22681
|
+
fromMs: number(),
|
|
22682
|
+
toMs: number(),
|
|
22683
|
+
options: ExportOptionsSchema,
|
|
22684
|
+
state: ExportStateSchema,
|
|
22685
|
+
/** 0–100 while rendering; null otherwise. */
|
|
22686
|
+
progressPct: number().nullable(),
|
|
22687
|
+
/** File size once ready; null before. */
|
|
22688
|
+
fileBytes: number().nullable(),
|
|
22689
|
+
expiresAt: number(),
|
|
22690
|
+
deleteAfterDownload: boolean(),
|
|
22691
|
+
/** Epoch of the first complete download; null until then. */
|
|
22692
|
+
downloadedAt: number().nullable(),
|
|
22693
|
+
createdAt: number(),
|
|
22694
|
+
/** User id/name that requested the export. */
|
|
22695
|
+
createdBy: string(),
|
|
22696
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
22697
|
+
error: string().nullable()
|
|
22698
|
+
});
|
|
22699
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
22700
|
+
var ExportDownloadSchema = object({
|
|
22701
|
+
url: string(),
|
|
22702
|
+
endpoints: array(string())
|
|
22703
|
+
});
|
|
22704
|
+
method(object({
|
|
22705
|
+
deviceId: number(),
|
|
22706
|
+
profile: string(),
|
|
22707
|
+
fromMs: number(),
|
|
22708
|
+
toMs: number(),
|
|
22709
|
+
options: ExportOptionsSchema
|
|
22710
|
+
}), ExportRecordSchema, {
|
|
22711
|
+
kind: "mutation",
|
|
22712
|
+
auth: "protected"
|
|
22713
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
22714
|
+
kind: "query",
|
|
22715
|
+
auth: "protected"
|
|
22716
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22717
|
+
kind: "query",
|
|
22718
|
+
auth: "protected"
|
|
22719
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22720
|
+
kind: "mutation",
|
|
22721
|
+
auth: "protected"
|
|
22722
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22723
|
+
kind: "mutation",
|
|
22724
|
+
auth: "protected"
|
|
22725
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
22726
|
+
kind: "query",
|
|
22727
|
+
auth: "protected"
|
|
22461
22728
|
});
|
|
22462
22729
|
/**
|
|
22463
22730
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
@@ -25477,6 +25744,12 @@ Object.freeze({
|
|
|
25477
25744
|
addonId: null,
|
|
25478
25745
|
access: "delete"
|
|
25479
25746
|
},
|
|
25747
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
25748
|
+
capName: "pipeline-analytics",
|
|
25749
|
+
capScope: "device",
|
|
25750
|
+
addonId: null,
|
|
25751
|
+
access: "delete"
|
|
25752
|
+
},
|
|
25480
25753
|
"pipelineAnalytics.deleteTracks": {
|
|
25481
25754
|
capName: "pipeline-analytics",
|
|
25482
25755
|
capScope: "device",
|
|
@@ -25507,6 +25780,12 @@ Object.freeze({
|
|
|
25507
25780
|
addonId: null,
|
|
25508
25781
|
access: "view"
|
|
25509
25782
|
},
|
|
25783
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
25784
|
+
capName: "pipeline-analytics",
|
|
25785
|
+
capScope: "device",
|
|
25786
|
+
addonId: null,
|
|
25787
|
+
access: "view"
|
|
25788
|
+
},
|
|
25510
25789
|
"pipelineAnalytics.getKeyEvents": {
|
|
25511
25790
|
capName: "pipeline-analytics",
|
|
25512
25791
|
capScope: "device",
|
|
@@ -25549,6 +25828,12 @@ Object.freeze({
|
|
|
25549
25828
|
addonId: null,
|
|
25550
25829
|
access: "view"
|
|
25551
25830
|
},
|
|
25831
|
+
"pipelineAnalytics.listOpsLog": {
|
|
25832
|
+
capName: "pipeline-analytics",
|
|
25833
|
+
capScope: "device",
|
|
25834
|
+
addonId: null,
|
|
25835
|
+
access: "view"
|
|
25836
|
+
},
|
|
25552
25837
|
"pipelineAnalytics.listRecentTracks": {
|
|
25553
25838
|
capName: "pipeline-analytics",
|
|
25554
25839
|
capScope: "device",
|
|
@@ -25561,6 +25846,12 @@ Object.freeze({
|
|
|
25561
25846
|
addonId: null,
|
|
25562
25847
|
access: "view"
|
|
25563
25848
|
},
|
|
25849
|
+
"pipelineAnalytics.pruneEvents": {
|
|
25850
|
+
capName: "pipeline-analytics",
|
|
25851
|
+
capScope: "device",
|
|
25852
|
+
addonId: null,
|
|
25853
|
+
access: "create"
|
|
25854
|
+
},
|
|
25564
25855
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
25565
25856
|
capName: "pipeline-analytics",
|
|
25566
25857
|
capScope: "device",
|
|
@@ -26323,6 +26614,12 @@ Object.freeze({
|
|
|
26323
26614
|
addonId: null,
|
|
26324
26615
|
access: "create"
|
|
26325
26616
|
},
|
|
26617
|
+
"recording.deleteFootprint": {
|
|
26618
|
+
capName: "recording",
|
|
26619
|
+
capScope: "system",
|
|
26620
|
+
addonId: null,
|
|
26621
|
+
access: "delete"
|
|
26622
|
+
},
|
|
26326
26623
|
"recording.getAvailability": {
|
|
26327
26624
|
capName: "recording",
|
|
26328
26625
|
capScope: "system",
|
|
@@ -26353,6 +26650,12 @@ Object.freeze({
|
|
|
26353
26650
|
addonId: null,
|
|
26354
26651
|
access: "view"
|
|
26355
26652
|
},
|
|
26653
|
+
"recording.listOpsLog": {
|
|
26654
|
+
capName: "recording",
|
|
26655
|
+
capScope: "system",
|
|
26656
|
+
addonId: null,
|
|
26657
|
+
access: "view"
|
|
26658
|
+
},
|
|
26356
26659
|
"recording.locateSegment": {
|
|
26357
26660
|
capName: "recording",
|
|
26358
26661
|
capScope: "system",
|
|
@@ -26383,6 +26686,42 @@ Object.freeze({
|
|
|
26383
26686
|
addonId: null,
|
|
26384
26687
|
access: "create"
|
|
26385
26688
|
},
|
|
26689
|
+
"recordingExport.cancelExport": {
|
|
26690
|
+
capName: "recordingExport",
|
|
26691
|
+
capScope: "system",
|
|
26692
|
+
addonId: null,
|
|
26693
|
+
access: "create"
|
|
26694
|
+
},
|
|
26695
|
+
"recordingExport.createExport": {
|
|
26696
|
+
capName: "recordingExport",
|
|
26697
|
+
capScope: "system",
|
|
26698
|
+
addonId: null,
|
|
26699
|
+
access: "create"
|
|
26700
|
+
},
|
|
26701
|
+
"recordingExport.deleteExport": {
|
|
26702
|
+
capName: "recordingExport",
|
|
26703
|
+
capScope: "system",
|
|
26704
|
+
addonId: null,
|
|
26705
|
+
access: "delete"
|
|
26706
|
+
},
|
|
26707
|
+
"recordingExport.getDownloadUrl": {
|
|
26708
|
+
capName: "recordingExport",
|
|
26709
|
+
capScope: "system",
|
|
26710
|
+
addonId: null,
|
|
26711
|
+
access: "view"
|
|
26712
|
+
},
|
|
26713
|
+
"recordingExport.getExport": {
|
|
26714
|
+
capName: "recordingExport",
|
|
26715
|
+
capScope: "system",
|
|
26716
|
+
addonId: null,
|
|
26717
|
+
access: "view"
|
|
26718
|
+
},
|
|
26719
|
+
"recordingExport.listExports": {
|
|
26720
|
+
capName: "recordingExport",
|
|
26721
|
+
capScope: "system",
|
|
26722
|
+
addonId: null,
|
|
26723
|
+
access: "view"
|
|
26724
|
+
},
|
|
26386
26725
|
"sceneMonitor.captureReference": {
|
|
26387
26726
|
capName: "scene-monitor",
|
|
26388
26727
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-dreame",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.33",
|
|
4
4
|
"description": "Dreame robot-vacuum / lawn-mower device-provider addon for CamStack — wraps the @apocaliss92/nodedreame Dreamehome cloud client",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|