@camstack/addon-provider-wyze 0.1.22 → 0.1.24
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
|
@@ -30,7 +30,7 @@ let events = require("events");
|
|
|
30
30
|
let net = require("net");
|
|
31
31
|
net = __toESM(net, 1);
|
|
32
32
|
let node_child_process = require("node:child_process");
|
|
33
|
-
//#region ../types/dist/event-category-
|
|
33
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
34
34
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
35
35
|
EventCategory["SystemBoot"] = "system.boot";
|
|
36
36
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -183,6 +183,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
183
183
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
184
184
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
185
185
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
186
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
187
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
188
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
189
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
190
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
186
191
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
187
192
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
188
193
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -472,6 +477,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
472
477
|
*/
|
|
473
478
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
474
479
|
/**
|
|
480
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
481
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
482
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
483
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
484
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
485
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
486
|
+
* this bus topic drives notifier rules + live UI. See
|
|
487
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
488
|
+
*/
|
|
489
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
490
|
+
/**
|
|
491
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
492
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
493
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
494
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
495
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
496
|
+
*/
|
|
497
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
498
|
+
/**
|
|
475
499
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
476
500
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
477
501
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5210,6 +5234,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5210
5234
|
};
|
|
5211
5235
|
return inst;
|
|
5212
5236
|
}
|
|
5237
|
+
//#endregion
|
|
5238
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5239
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5240
|
+
var ZodIssueCode = {
|
|
5241
|
+
invalid_type: "invalid_type",
|
|
5242
|
+
too_big: "too_big",
|
|
5243
|
+
too_small: "too_small",
|
|
5244
|
+
invalid_format: "invalid_format",
|
|
5245
|
+
not_multiple_of: "not_multiple_of",
|
|
5246
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5247
|
+
invalid_union: "invalid_union",
|
|
5248
|
+
invalid_key: "invalid_key",
|
|
5249
|
+
invalid_element: "invalid_element",
|
|
5250
|
+
invalid_value: "invalid_value",
|
|
5251
|
+
custom: "custom"
|
|
5252
|
+
};
|
|
5253
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5254
|
+
var ZodFirstPartyTypeKind;
|
|
5255
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5213
5256
|
Object.fromEntries([
|
|
5214
5257
|
{
|
|
5215
5258
|
id: "overview",
|
|
@@ -7332,6 +7375,62 @@ var RecordingConfigSchema = object({
|
|
|
7332
7375
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7333
7376
|
});
|
|
7334
7377
|
/**
|
|
7378
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7379
|
+
* recordings and events management surfaces.
|
|
7380
|
+
*
|
|
7381
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7382
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7383
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7384
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7385
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7386
|
+
* never fail the operation it records.
|
|
7387
|
+
*/
|
|
7388
|
+
/** Which management domain the operation belongs to. */
|
|
7389
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7390
|
+
/** The kind of management operation performed. */
|
|
7391
|
+
var OpsLogOpSchema = _enum([
|
|
7392
|
+
"prune",
|
|
7393
|
+
"manual-delete",
|
|
7394
|
+
"rescan",
|
|
7395
|
+
"retention-run"
|
|
7396
|
+
]);
|
|
7397
|
+
/** Why the operation ran. */
|
|
7398
|
+
var OpsLogReasonSchema = _enum([
|
|
7399
|
+
"retention",
|
|
7400
|
+
"quota",
|
|
7401
|
+
"manual",
|
|
7402
|
+
"operator"
|
|
7403
|
+
]);
|
|
7404
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7405
|
+
var OpsLogEntrySchema = object({
|
|
7406
|
+
/** Unique row id. */
|
|
7407
|
+
id: string(),
|
|
7408
|
+
/** Epoch ms the operation completed. */
|
|
7409
|
+
at: number(),
|
|
7410
|
+
domain: OpsLogDomainSchema,
|
|
7411
|
+
op: OpsLogOpSchema,
|
|
7412
|
+
reason: OpsLogReasonSchema,
|
|
7413
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7414
|
+
deviceId: number().nullable(),
|
|
7415
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7416
|
+
nodeId: string(),
|
|
7417
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7418
|
+
itemsAffected: number(),
|
|
7419
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7420
|
+
bytesReclaimed: number(),
|
|
7421
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7422
|
+
detail: string().nullable(),
|
|
7423
|
+
/** Who/what triggered the op. */
|
|
7424
|
+
actor: string()
|
|
7425
|
+
});
|
|
7426
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7427
|
+
var OpsLogQueryInputSchema = object({
|
|
7428
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7429
|
+
deviceId: number().optional(),
|
|
7430
|
+
/** Max rows returned, newest-first. */
|
|
7431
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7432
|
+
});
|
|
7433
|
+
/**
|
|
7335
7434
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7336
7435
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7337
7436
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -14687,7 +14786,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
14687
14786
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
14688
14787
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
14689
14788
|
*/
|
|
14690
|
-
var ZoneRuleStageEnum = _enum([
|
|
14789
|
+
var ZoneRuleStageEnum = _enum([
|
|
14790
|
+
"motion",
|
|
14791
|
+
"detection",
|
|
14792
|
+
"package"
|
|
14793
|
+
]);
|
|
14691
14794
|
/**
|
|
14692
14795
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
14693
14796
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -14781,16 +14884,25 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14781
14884
|
})
|
|
14782
14885
|
},
|
|
14783
14886
|
/**
|
|
14784
|
-
* Runtime-state slice —
|
|
14887
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
14785
14888
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
14786
|
-
* of
|
|
14787
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
14889
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
14890
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
14788
14891
|
* complete current set. Consumers that only care about one stage
|
|
14789
14892
|
* just read the matching property.
|
|
14893
|
+
*
|
|
14894
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
14895
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14896
|
+
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
14897
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
14898
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
14899
|
+
* package}` shape, so consumers read the current package rules directly
|
|
14900
|
+
* off `device.state.zoneRules.value.package`.
|
|
14790
14901
|
*/
|
|
14791
14902
|
runtimeState: object({
|
|
14792
14903
|
motion: array(ZoneRuleSchema).readonly(),
|
|
14793
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
14904
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
14905
|
+
package: array(ZoneRuleSchema).readonly()
|
|
14794
14906
|
})
|
|
14795
14907
|
},
|
|
14796
14908
|
zones: zonesCapability
|
|
@@ -18769,6 +18881,7 @@ var EventKindIconSchema = _enum([
|
|
|
18769
18881
|
"smoke",
|
|
18770
18882
|
"water",
|
|
18771
18883
|
"button",
|
|
18884
|
+
"package",
|
|
18772
18885
|
"generic"
|
|
18773
18886
|
]);
|
|
18774
18887
|
var EventKindCategorySchema = _enum([
|
|
@@ -18776,7 +18889,8 @@ var EventKindCategorySchema = _enum([
|
|
|
18776
18889
|
"audio",
|
|
18777
18890
|
"detection",
|
|
18778
18891
|
"sensor",
|
|
18779
|
-
"custom"
|
|
18892
|
+
"custom",
|
|
18893
|
+
"package"
|
|
18780
18894
|
]);
|
|
18781
18895
|
var EventKindDescriptorSchema = object({
|
|
18782
18896
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -19117,6 +19231,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19117
19231
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19118
19232
|
embeddings: number().int()
|
|
19119
19233
|
});
|
|
19234
|
+
/** Event-store footprint for one camera. */
|
|
19235
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19236
|
+
deviceId: number(),
|
|
19237
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19238
|
+
rows: number().int(),
|
|
19239
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19240
|
+
bytes: number().int()
|
|
19241
|
+
});
|
|
19242
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19243
|
+
var EventStoreFootprintSchema = object({
|
|
19244
|
+
totalRows: number().int(),
|
|
19245
|
+
totalBytes: number().int(),
|
|
19246
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19247
|
+
});
|
|
19248
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19249
|
+
var EventPruneCountsSchema = object({
|
|
19250
|
+
motion: number().int(),
|
|
19251
|
+
object: number().int(),
|
|
19252
|
+
audio: number().int()
|
|
19253
|
+
});
|
|
19120
19254
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19121
19255
|
deviceId: number(),
|
|
19122
19256
|
trackId: string()
|
|
@@ -19180,6 +19314,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19180
19314
|
}), {
|
|
19181
19315
|
kind: "mutation",
|
|
19182
19316
|
auth: "admin"
|
|
19317
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19318
|
+
kind: "query",
|
|
19319
|
+
auth: "admin"
|
|
19320
|
+
}), method(object({
|
|
19321
|
+
olderThanMs: number(),
|
|
19322
|
+
reason: OpsLogReasonSchema.optional()
|
|
19323
|
+
}), EventPruneCountsSchema, {
|
|
19324
|
+
kind: "mutation",
|
|
19325
|
+
auth: "admin"
|
|
19326
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19327
|
+
kind: "mutation",
|
|
19328
|
+
auth: "admin"
|
|
19329
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19330
|
+
kind: "query",
|
|
19331
|
+
auth: "admin"
|
|
19183
19332
|
}), method(object({
|
|
19184
19333
|
eventId: string(),
|
|
19185
19334
|
kind: MediaFileKindEnum.optional()
|
|
@@ -22515,13 +22664,131 @@ method(object({
|
|
|
22515
22664
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22516
22665
|
kind: "mutation",
|
|
22517
22666
|
auth: "admin"
|
|
22518
|
-
}), method(object({
|
|
22667
|
+
}), method(object({
|
|
22668
|
+
deviceId: number(),
|
|
22669
|
+
reason: OpsLogReasonSchema.optional()
|
|
22670
|
+
}), object({
|
|
22519
22671
|
floorMs: number().nullable(),
|
|
22520
22672
|
deletedBuckets: number().int(),
|
|
22521
22673
|
reclaimedBytes: number().int()
|
|
22522
22674
|
}), {
|
|
22523
22675
|
kind: "mutation",
|
|
22524
22676
|
auth: "admin"
|
|
22677
|
+
}), method(object({
|
|
22678
|
+
deviceId: number(),
|
|
22679
|
+
fromMs: number().optional(),
|
|
22680
|
+
toMs: number().optional()
|
|
22681
|
+
}), object({
|
|
22682
|
+
deletedBuckets: number().int(),
|
|
22683
|
+
reclaimedBytes: number().int()
|
|
22684
|
+
}), {
|
|
22685
|
+
kind: "mutation",
|
|
22686
|
+
auth: "admin"
|
|
22687
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
22688
|
+
kind: "query",
|
|
22689
|
+
auth: "admin"
|
|
22690
|
+
});
|
|
22691
|
+
/**
|
|
22692
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
22693
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
22694
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
22695
|
+
* delete-after-download.
|
|
22696
|
+
*
|
|
22697
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
22698
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
22699
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
22700
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
22701
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
22702
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
22703
|
+
* SQLite); history rows survive file deletion for audit.
|
|
22704
|
+
*/
|
|
22705
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
22706
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
22707
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
22708
|
+
var ExportTimelapseSchema = object({
|
|
22709
|
+
everyMs: number().int().positive(),
|
|
22710
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
22711
|
+
});
|
|
22712
|
+
/**
|
|
22713
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
22714
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
22715
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
22716
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
22717
|
+
*/
|
|
22718
|
+
var ExportOptionsSchema = object({
|
|
22719
|
+
speed: ExportSpeedSchema.optional(),
|
|
22720
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
22721
|
+
includeAudio: boolean(),
|
|
22722
|
+
maxLifeMs: number().int().positive(),
|
|
22723
|
+
deleteAfterDownload: boolean(),
|
|
22724
|
+
title: string().max(200).optional()
|
|
22725
|
+
}).superRefine((v, ctx) => {
|
|
22726
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
22727
|
+
code: ZodIssueCode.custom,
|
|
22728
|
+
message: "speed and timelapse are mutually exclusive",
|
|
22729
|
+
path: ["timelapse"]
|
|
22730
|
+
});
|
|
22731
|
+
});
|
|
22732
|
+
var ExportStateSchema = _enum([
|
|
22733
|
+
"queued",
|
|
22734
|
+
"rendering",
|
|
22735
|
+
"ready",
|
|
22736
|
+
"failed",
|
|
22737
|
+
"expired",
|
|
22738
|
+
"deleted"
|
|
22739
|
+
]);
|
|
22740
|
+
/** One export job / history row. */
|
|
22741
|
+
var ExportRecordSchema = object({
|
|
22742
|
+
id: string(),
|
|
22743
|
+
deviceId: number(),
|
|
22744
|
+
profile: string(),
|
|
22745
|
+
fromMs: number(),
|
|
22746
|
+
toMs: number(),
|
|
22747
|
+
options: ExportOptionsSchema,
|
|
22748
|
+
state: ExportStateSchema,
|
|
22749
|
+
/** 0–100 while rendering; null otherwise. */
|
|
22750
|
+
progressPct: number().nullable(),
|
|
22751
|
+
/** File size once ready; null before. */
|
|
22752
|
+
fileBytes: number().nullable(),
|
|
22753
|
+
expiresAt: number(),
|
|
22754
|
+
deleteAfterDownload: boolean(),
|
|
22755
|
+
/** Epoch of the first complete download; null until then. */
|
|
22756
|
+
downloadedAt: number().nullable(),
|
|
22757
|
+
createdAt: number(),
|
|
22758
|
+
/** User id/name that requested the export. */
|
|
22759
|
+
createdBy: string(),
|
|
22760
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
22761
|
+
error: string().nullable()
|
|
22762
|
+
});
|
|
22763
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
22764
|
+
var ExportDownloadSchema = object({
|
|
22765
|
+
url: string(),
|
|
22766
|
+
endpoints: array(string())
|
|
22767
|
+
});
|
|
22768
|
+
method(object({
|
|
22769
|
+
deviceId: number(),
|
|
22770
|
+
profile: string(),
|
|
22771
|
+
fromMs: number(),
|
|
22772
|
+
toMs: number(),
|
|
22773
|
+
options: ExportOptionsSchema
|
|
22774
|
+
}), ExportRecordSchema, {
|
|
22775
|
+
kind: "mutation",
|
|
22776
|
+
auth: "protected"
|
|
22777
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
22778
|
+
kind: "query",
|
|
22779
|
+
auth: "protected"
|
|
22780
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22781
|
+
kind: "query",
|
|
22782
|
+
auth: "protected"
|
|
22783
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22784
|
+
kind: "mutation",
|
|
22785
|
+
auth: "protected"
|
|
22786
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22787
|
+
kind: "mutation",
|
|
22788
|
+
auth: "protected"
|
|
22789
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
22790
|
+
kind: "query",
|
|
22791
|
+
auth: "protected"
|
|
22525
22792
|
});
|
|
22526
22793
|
/**
|
|
22527
22794
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
@@ -25554,6 +25821,12 @@ Object.freeze({
|
|
|
25554
25821
|
addonId: null,
|
|
25555
25822
|
access: "delete"
|
|
25556
25823
|
},
|
|
25824
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
25825
|
+
capName: "pipeline-analytics",
|
|
25826
|
+
capScope: "device",
|
|
25827
|
+
addonId: null,
|
|
25828
|
+
access: "delete"
|
|
25829
|
+
},
|
|
25557
25830
|
"pipelineAnalytics.deleteTracks": {
|
|
25558
25831
|
capName: "pipeline-analytics",
|
|
25559
25832
|
capScope: "device",
|
|
@@ -25584,6 +25857,12 @@ Object.freeze({
|
|
|
25584
25857
|
addonId: null,
|
|
25585
25858
|
access: "view"
|
|
25586
25859
|
},
|
|
25860
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
25861
|
+
capName: "pipeline-analytics",
|
|
25862
|
+
capScope: "device",
|
|
25863
|
+
addonId: null,
|
|
25864
|
+
access: "view"
|
|
25865
|
+
},
|
|
25587
25866
|
"pipelineAnalytics.getKeyEvents": {
|
|
25588
25867
|
capName: "pipeline-analytics",
|
|
25589
25868
|
capScope: "device",
|
|
@@ -25626,6 +25905,12 @@ Object.freeze({
|
|
|
25626
25905
|
addonId: null,
|
|
25627
25906
|
access: "view"
|
|
25628
25907
|
},
|
|
25908
|
+
"pipelineAnalytics.listOpsLog": {
|
|
25909
|
+
capName: "pipeline-analytics",
|
|
25910
|
+
capScope: "device",
|
|
25911
|
+
addonId: null,
|
|
25912
|
+
access: "view"
|
|
25913
|
+
},
|
|
25629
25914
|
"pipelineAnalytics.listRecentTracks": {
|
|
25630
25915
|
capName: "pipeline-analytics",
|
|
25631
25916
|
capScope: "device",
|
|
@@ -25638,6 +25923,12 @@ Object.freeze({
|
|
|
25638
25923
|
addonId: null,
|
|
25639
25924
|
access: "view"
|
|
25640
25925
|
},
|
|
25926
|
+
"pipelineAnalytics.pruneEvents": {
|
|
25927
|
+
capName: "pipeline-analytics",
|
|
25928
|
+
capScope: "device",
|
|
25929
|
+
addonId: null,
|
|
25930
|
+
access: "create"
|
|
25931
|
+
},
|
|
25641
25932
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
25642
25933
|
capName: "pipeline-analytics",
|
|
25643
25934
|
capScope: "device",
|
|
@@ -26400,6 +26691,12 @@ Object.freeze({
|
|
|
26400
26691
|
addonId: null,
|
|
26401
26692
|
access: "create"
|
|
26402
26693
|
},
|
|
26694
|
+
"recording.deleteFootprint": {
|
|
26695
|
+
capName: "recording",
|
|
26696
|
+
capScope: "system",
|
|
26697
|
+
addonId: null,
|
|
26698
|
+
access: "delete"
|
|
26699
|
+
},
|
|
26403
26700
|
"recording.getAvailability": {
|
|
26404
26701
|
capName: "recording",
|
|
26405
26702
|
capScope: "system",
|
|
@@ -26430,6 +26727,12 @@ Object.freeze({
|
|
|
26430
26727
|
addonId: null,
|
|
26431
26728
|
access: "view"
|
|
26432
26729
|
},
|
|
26730
|
+
"recording.listOpsLog": {
|
|
26731
|
+
capName: "recording",
|
|
26732
|
+
capScope: "system",
|
|
26733
|
+
addonId: null,
|
|
26734
|
+
access: "view"
|
|
26735
|
+
},
|
|
26433
26736
|
"recording.locateSegment": {
|
|
26434
26737
|
capName: "recording",
|
|
26435
26738
|
capScope: "system",
|
|
@@ -26460,6 +26763,42 @@ Object.freeze({
|
|
|
26460
26763
|
addonId: null,
|
|
26461
26764
|
access: "create"
|
|
26462
26765
|
},
|
|
26766
|
+
"recordingExport.cancelExport": {
|
|
26767
|
+
capName: "recordingExport",
|
|
26768
|
+
capScope: "system",
|
|
26769
|
+
addonId: null,
|
|
26770
|
+
access: "create"
|
|
26771
|
+
},
|
|
26772
|
+
"recordingExport.createExport": {
|
|
26773
|
+
capName: "recordingExport",
|
|
26774
|
+
capScope: "system",
|
|
26775
|
+
addonId: null,
|
|
26776
|
+
access: "create"
|
|
26777
|
+
},
|
|
26778
|
+
"recordingExport.deleteExport": {
|
|
26779
|
+
capName: "recordingExport",
|
|
26780
|
+
capScope: "system",
|
|
26781
|
+
addonId: null,
|
|
26782
|
+
access: "delete"
|
|
26783
|
+
},
|
|
26784
|
+
"recordingExport.getDownloadUrl": {
|
|
26785
|
+
capName: "recordingExport",
|
|
26786
|
+
capScope: "system",
|
|
26787
|
+
addonId: null,
|
|
26788
|
+
access: "view"
|
|
26789
|
+
},
|
|
26790
|
+
"recordingExport.getExport": {
|
|
26791
|
+
capName: "recordingExport",
|
|
26792
|
+
capScope: "system",
|
|
26793
|
+
addonId: null,
|
|
26794
|
+
access: "view"
|
|
26795
|
+
},
|
|
26796
|
+
"recordingExport.listExports": {
|
|
26797
|
+
capName: "recordingExport",
|
|
26798
|
+
capScope: "system",
|
|
26799
|
+
addonId: null,
|
|
26800
|
+
access: "view"
|
|
26801
|
+
},
|
|
26463
26802
|
"sceneMonitor.captureReference": {
|
|
26464
26803
|
capName: "scene-monitor",
|
|
26465
26804
|
capScope: "device",
|
package/dist/addon.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { spawn } from "node:child_process";
|
|
|
9
9
|
//#region \0rolldown/runtime.js
|
|
10
10
|
var __require$1 = /* @__PURE__ */ createRequire(import.meta.url);
|
|
11
11
|
//#endregion
|
|
12
|
-
//#region ../types/dist/event-category-
|
|
12
|
+
//#region ../types/dist/event-category-D4HJq7Mw.mjs
|
|
13
13
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
14
14
|
EventCategory["SystemBoot"] = "system.boot";
|
|
15
15
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -162,6 +162,11 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
162
162
|
/** Runner-sampled scrub thumbnail (~1/5 s/camera). Telemetry (D8): a lost
|
|
163
163
|
* thumb is a scrub gap the recorder's keyframe backfill covers. */
|
|
164
164
|
EventCategory["RecordingThumbSampled"] = "recording.thumb-sampled";
|
|
165
|
+
/** Export render progress (0–100). Telemetry (D8): a lost tick is a stale
|
|
166
|
+
* progress bar the client reconciles via `recordingExport.getExport`. */
|
|
167
|
+
EventCategory["RecordingExportProgress"] = "recording.export.progress";
|
|
168
|
+
EventCategory["RecordingExportCompleted"] = "recording.export.completed";
|
|
169
|
+
EventCategory["RecordingExportFailed"] = "recording.export.failed";
|
|
165
170
|
EventCategory["DetectionEvent"] = "detection.event";
|
|
166
171
|
EventCategory["SessionTrackNew"] = "session.track.new";
|
|
167
172
|
EventCategory["SessionTrackExpired"] = "session.track.expired";
|
|
@@ -451,6 +456,25 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
451
456
|
*/
|
|
452
457
|
EventCategory["PipelineAnalyticsStationaryChanged"] = "pipeline-analytics.stationary-changed";
|
|
453
458
|
/**
|
|
459
|
+
* Fired by `addon-post-analysis` when a package-drop is confirmed inside
|
|
460
|
+
* a package zone — a newly-appeared stationary object of a package class
|
|
461
|
+
* that cleared the class / zone / dwell / size gates. Payload:
|
|
462
|
+
* `PipelineAnalyticsPackageDeliveredPayload` carrying `{ deviceId,
|
|
463
|
+
* entryId, className, zoneIds, keyFrameMediaKey?, bbox, timestamp }`.
|
|
464
|
+
* Telemetry (D8): the durable record is the `package-events` store row;
|
|
465
|
+
* this bus topic drives notifier rules + live UI. See
|
|
466
|
+
* docs/superpowers/specs/2026-07-17-package-zones-design.md §5.1.
|
|
467
|
+
*/
|
|
468
|
+
EventCategory["PipelineAnalyticsPackageDelivered"] = "pipeline-analytics.package-delivered";
|
|
469
|
+
/**
|
|
470
|
+
* Fired by `addon-post-analysis` when a previously-delivered package
|
|
471
|
+
* leaves its zone (the stationary entry departed — moved or swept).
|
|
472
|
+
* Payload: `PipelineAnalyticsPackagePickedUpPayload` carrying
|
|
473
|
+
* `{ deviceId, entryId, deliveredEventId, className, timestamp }`.
|
|
474
|
+
* Telemetry (D8). See package-zones-design §5.2.
|
|
475
|
+
*/
|
|
476
|
+
EventCategory["PipelineAnalyticsPackagePickedUp"] = "pipeline-analytics.package-picked-up";
|
|
477
|
+
/**
|
|
454
478
|
* Fired by `addon-post-analysis` whenever a gallery face row changes:
|
|
455
479
|
* `kind:'buffered'` a new detected face was persisted, `'assigned'` /
|
|
456
480
|
* `'unassigned'` its identity link changed, `'deleted'` the row was
|
|
@@ -5189,6 +5213,25 @@ function _instanceof(cls, params = {}) {
|
|
|
5189
5213
|
};
|
|
5190
5214
|
return inst;
|
|
5191
5215
|
}
|
|
5216
|
+
//#endregion
|
|
5217
|
+
//#region ../../node_modules/zod/v4/classic/compat.js
|
|
5218
|
+
/** @deprecated Use the raw string literal codes instead, e.g. "invalid_type". */
|
|
5219
|
+
var ZodIssueCode = {
|
|
5220
|
+
invalid_type: "invalid_type",
|
|
5221
|
+
too_big: "too_big",
|
|
5222
|
+
too_small: "too_small",
|
|
5223
|
+
invalid_format: "invalid_format",
|
|
5224
|
+
not_multiple_of: "not_multiple_of",
|
|
5225
|
+
unrecognized_keys: "unrecognized_keys",
|
|
5226
|
+
invalid_union: "invalid_union",
|
|
5227
|
+
invalid_key: "invalid_key",
|
|
5228
|
+
invalid_element: "invalid_element",
|
|
5229
|
+
invalid_value: "invalid_value",
|
|
5230
|
+
custom: "custom"
|
|
5231
|
+
};
|
|
5232
|
+
/** @deprecated Do not use. Stub definition, only included for zod-to-json-schema compatibility. */
|
|
5233
|
+
var ZodFirstPartyTypeKind;
|
|
5234
|
+
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5192
5235
|
Object.fromEntries([
|
|
5193
5236
|
{
|
|
5194
5237
|
id: "overview",
|
|
@@ -7311,6 +7354,62 @@ var RecordingConfigSchema = object({
|
|
|
7311
7354
|
scrubThumbnails: ScrubThumbnailPresetSchema.optional()
|
|
7312
7355
|
});
|
|
7313
7356
|
/**
|
|
7357
|
+
* Ops-log — the durable, append-only operations audit shared by the
|
|
7358
|
+
* recordings and events management surfaces.
|
|
7359
|
+
*
|
|
7360
|
+
* ONE row shape is reused for both domains so a single "Activity" view can
|
|
7361
|
+
* merge the recorder's DurableState ring (recordings ops-log) and the
|
|
7362
|
+
* pipeline-analytics SQLite collection (events ops-log). Each row records a
|
|
7363
|
+
* management operation, WHY it ran (reason), and its measurable effect
|
|
7364
|
+
* (itemsAffected + bytesReclaimed). Writes are best-effort — a failed log must
|
|
7365
|
+
* never fail the operation it records.
|
|
7366
|
+
*/
|
|
7367
|
+
/** Which management domain the operation belongs to. */
|
|
7368
|
+
var OpsLogDomainSchema = _enum(["recording", "events"]);
|
|
7369
|
+
/** The kind of management operation performed. */
|
|
7370
|
+
var OpsLogOpSchema = _enum([
|
|
7371
|
+
"prune",
|
|
7372
|
+
"manual-delete",
|
|
7373
|
+
"rescan",
|
|
7374
|
+
"retention-run"
|
|
7375
|
+
]);
|
|
7376
|
+
/** Why the operation ran. */
|
|
7377
|
+
var OpsLogReasonSchema = _enum([
|
|
7378
|
+
"retention",
|
|
7379
|
+
"quota",
|
|
7380
|
+
"manual",
|
|
7381
|
+
"operator"
|
|
7382
|
+
]);
|
|
7383
|
+
/** One audit row, shared verbatim by both domains. */
|
|
7384
|
+
var OpsLogEntrySchema = object({
|
|
7385
|
+
/** Unique row id. */
|
|
7386
|
+
id: string(),
|
|
7387
|
+
/** Epoch ms the operation completed. */
|
|
7388
|
+
at: number(),
|
|
7389
|
+
domain: OpsLogDomainSchema,
|
|
7390
|
+
op: OpsLogOpSchema,
|
|
7391
|
+
reason: OpsLogReasonSchema,
|
|
7392
|
+
/** The camera the op targeted; null for a cluster/global op. */
|
|
7393
|
+
deviceId: number().nullable(),
|
|
7394
|
+
/** Node that performed the op (the log carries nodeId — no cross-node aggregation). */
|
|
7395
|
+
nodeId: string(),
|
|
7396
|
+
/** Buckets / rows deleted (op-specific unit). */
|
|
7397
|
+
itemsAffected: number(),
|
|
7398
|
+
/** Bytes reclaimed by the op (0 when not measurable). */
|
|
7399
|
+
bytesReclaimed: number(),
|
|
7400
|
+
/** Free-text detail (e.g. "floor moved to <ts>"); null when none. */
|
|
7401
|
+
detail: string().nullable(),
|
|
7402
|
+
/** Who/what triggered the op. */
|
|
7403
|
+
actor: string()
|
|
7404
|
+
});
|
|
7405
|
+
/** Shared query input for the per-domain `listOpsLog` cap methods. */
|
|
7406
|
+
var OpsLogQueryInputSchema = object({
|
|
7407
|
+
/** Restrict to a single camera; omit for every row. */
|
|
7408
|
+
deviceId: number().optional(),
|
|
7409
|
+
/** Max rows returned, newest-first. */
|
|
7410
|
+
limit: number().int().min(1).max(1e3).optional()
|
|
7411
|
+
});
|
|
7412
|
+
/**
|
|
7314
7413
|
* `StorageLocationType` — an addon-declared id that identifies the *kind* of
|
|
7315
7414
|
* storage a location serves. Defined here (not in `capabilities/storage.cap.ts`)
|
|
7316
7415
|
* so the persisted record schema and the consumer-facing cap can both consume it
|
|
@@ -14666,7 +14765,11 @@ array(ZoneRuleSchema).readonly();
|
|
|
14666
14765
|
* Extend the enum here when a new gating consumer comes online (audio
|
|
14667
14766
|
* gating, alert filtering, …) — no other surface needs to change.
|
|
14668
14767
|
*/
|
|
14669
|
-
var ZoneRuleStageEnum = _enum([
|
|
14768
|
+
var ZoneRuleStageEnum = _enum([
|
|
14769
|
+
"motion",
|
|
14770
|
+
"detection",
|
|
14771
|
+
"package"
|
|
14772
|
+
]);
|
|
14670
14773
|
/**
|
|
14671
14774
|
* Runtime registry: cap-property-name → cap definition. `BaseDevice`'s
|
|
14672
14775
|
* `state` getter looks up the cap definition here to construct a
|
|
@@ -14760,16 +14863,25 @@ var DEVICE_LOCAL_STATE_CAPS = {
|
|
|
14760
14863
|
})
|
|
14761
14864
|
},
|
|
14762
14865
|
/**
|
|
14763
|
-
* Runtime-state slice —
|
|
14866
|
+
* Runtime-state slice — every stage mirrored together so consumers
|
|
14764
14867
|
* see one reactive handle (`device.state.zoneRules.value`) instead
|
|
14765
|
-
* of
|
|
14766
|
-
* `{motion, detection}` shape, so subscribers always get the
|
|
14868
|
+
* of one per stage. Bulk-replace mutations on any stage write the full
|
|
14869
|
+
* `{motion, detection, package}` shape, so subscribers always get the
|
|
14767
14870
|
* complete current set. Consumers that only care about one stage
|
|
14768
14871
|
* just read the matching property.
|
|
14872
|
+
*
|
|
14873
|
+
* `package` backs the package-drop detector — a package zone is a
|
|
14874
|
+
* `ZoneRule` on the `'package'` stage referencing drawn polygons
|
|
14875
|
+
* (see docs/superpowers/specs/2026-07-17-package-zones-design.md §3.1).
|
|
14876
|
+
* The orchestrator provider writes this stage as a first-class slice
|
|
14877
|
+
* (Phase 4): every mutation mirrors the full `{motion, detection,
|
|
14878
|
+
* package}` shape, so consumers read the current package rules directly
|
|
14879
|
+
* off `device.state.zoneRules.value.package`.
|
|
14769
14880
|
*/
|
|
14770
14881
|
runtimeState: object({
|
|
14771
14882
|
motion: array(ZoneRuleSchema).readonly(),
|
|
14772
|
-
detection: array(ZoneRuleSchema).readonly()
|
|
14883
|
+
detection: array(ZoneRuleSchema).readonly(),
|
|
14884
|
+
package: array(ZoneRuleSchema).readonly()
|
|
14773
14885
|
})
|
|
14774
14886
|
},
|
|
14775
14887
|
zones: zonesCapability
|
|
@@ -18748,6 +18860,7 @@ var EventKindIconSchema = _enum([
|
|
|
18748
18860
|
"smoke",
|
|
18749
18861
|
"water",
|
|
18750
18862
|
"button",
|
|
18863
|
+
"package",
|
|
18751
18864
|
"generic"
|
|
18752
18865
|
]);
|
|
18753
18866
|
var EventKindCategorySchema = _enum([
|
|
@@ -18755,7 +18868,8 @@ var EventKindCategorySchema = _enum([
|
|
|
18755
18868
|
"audio",
|
|
18756
18869
|
"detection",
|
|
18757
18870
|
"sensor",
|
|
18758
|
-
"custom"
|
|
18871
|
+
"custom",
|
|
18872
|
+
"package"
|
|
18759
18873
|
]);
|
|
18760
18874
|
var EventKindDescriptorSchema = object({
|
|
18761
18875
|
/** Stable kind id (e.g. 'motion', 'person', 'contact'). */
|
|
@@ -19096,6 +19210,26 @@ var TrackCascadeCountsSchema = object({
|
|
|
19096
19210
|
/** Per-track CLIP search vectors removed (best-effort). */
|
|
19097
19211
|
embeddings: number().int()
|
|
19098
19212
|
});
|
|
19213
|
+
/** Event-store footprint for one camera. */
|
|
19214
|
+
var EventStoreDeviceFootprintSchema = object({
|
|
19215
|
+
deviceId: number(),
|
|
19216
|
+
/** Persisted event rows (motion + object + audio) for the camera. */
|
|
19217
|
+
rows: number().int(),
|
|
19218
|
+
/** Event-owned media bytes on disk for the camera. */
|
|
19219
|
+
bytes: number().int()
|
|
19220
|
+
});
|
|
19221
|
+
/** Aggregate event-store footprint: global totals + per-camera breakdown. */
|
|
19222
|
+
var EventStoreFootprintSchema = object({
|
|
19223
|
+
totalRows: number().int(),
|
|
19224
|
+
totalBytes: number().int(),
|
|
19225
|
+
devices: array(EventStoreDeviceFootprintSchema).readonly()
|
|
19226
|
+
});
|
|
19227
|
+
/** Per-kind counts returned by the event-prune / device-delete mutations. */
|
|
19228
|
+
var EventPruneCountsSchema = object({
|
|
19229
|
+
motion: number().int(),
|
|
19230
|
+
object: number().int(),
|
|
19231
|
+
audio: number().int()
|
|
19232
|
+
});
|
|
19099
19233
|
DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).readonly()), method(object({
|
|
19100
19234
|
deviceId: number(),
|
|
19101
19235
|
trackId: string()
|
|
@@ -19159,6 +19293,21 @@ DeviceType.Camera, method(object({ deviceId: number() }), array(TrackSchema).rea
|
|
|
19159
19293
|
}), {
|
|
19160
19294
|
kind: "mutation",
|
|
19161
19295
|
auth: "admin"
|
|
19296
|
+
}), method(object({}), EventStoreFootprintSchema, {
|
|
19297
|
+
kind: "query",
|
|
19298
|
+
auth: "admin"
|
|
19299
|
+
}), method(object({
|
|
19300
|
+
olderThanMs: number(),
|
|
19301
|
+
reason: OpsLogReasonSchema.optional()
|
|
19302
|
+
}), EventPruneCountsSchema, {
|
|
19303
|
+
kind: "mutation",
|
|
19304
|
+
auth: "admin"
|
|
19305
|
+
}), method(object({ deviceId: number() }), EventPruneCountsSchema, {
|
|
19306
|
+
kind: "mutation",
|
|
19307
|
+
auth: "admin"
|
|
19308
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
19309
|
+
kind: "query",
|
|
19310
|
+
auth: "admin"
|
|
19162
19311
|
}), method(object({
|
|
19163
19312
|
eventId: string(),
|
|
19164
19313
|
kind: MediaFileKindEnum.optional()
|
|
@@ -22494,13 +22643,131 @@ method(object({
|
|
|
22494
22643
|
}), method(object({ deviceId: number() }), RecordingStatusSchema, {
|
|
22495
22644
|
kind: "mutation",
|
|
22496
22645
|
auth: "admin"
|
|
22497
|
-
}), method(object({
|
|
22646
|
+
}), method(object({
|
|
22647
|
+
deviceId: number(),
|
|
22648
|
+
reason: OpsLogReasonSchema.optional()
|
|
22649
|
+
}), object({
|
|
22498
22650
|
floorMs: number().nullable(),
|
|
22499
22651
|
deletedBuckets: number().int(),
|
|
22500
22652
|
reclaimedBytes: number().int()
|
|
22501
22653
|
}), {
|
|
22502
22654
|
kind: "mutation",
|
|
22503
22655
|
auth: "admin"
|
|
22656
|
+
}), method(object({
|
|
22657
|
+
deviceId: number(),
|
|
22658
|
+
fromMs: number().optional(),
|
|
22659
|
+
toMs: number().optional()
|
|
22660
|
+
}), object({
|
|
22661
|
+
deletedBuckets: number().int(),
|
|
22662
|
+
reclaimedBytes: number().int()
|
|
22663
|
+
}), {
|
|
22664
|
+
kind: "mutation",
|
|
22665
|
+
auth: "admin"
|
|
22666
|
+
}), method(OpsLogQueryInputSchema, array(OpsLogEntrySchema).readonly(), {
|
|
22667
|
+
kind: "query",
|
|
22668
|
+
auth: "admin"
|
|
22669
|
+
});
|
|
22670
|
+
/**
|
|
22671
|
+
* `recordingExport` cap — render a footage time range into a single downloadable
|
|
22672
|
+
* MP4 (regular / accelerated / decelerated / timelapse, ± audio), kept for a
|
|
22673
|
+
* bounded lifetime with a durable history, auto-expiry, and optional
|
|
22674
|
+
* delete-after-download.
|
|
22675
|
+
*
|
|
22676
|
+
* Like `recording` this is a `scope:'system', mode:'singleton'` cap: the
|
|
22677
|
+
* recorder self-gates so exactly ONE node (the designated `recordingNodeId`,
|
|
22678
|
+
* default `hub`) registers it. Device-scoped methods carry `deviceId` in their
|
|
22679
|
+
* input and dispatch to that single provider; the render runs on the node that
|
|
22680
|
+
* owns the footage (no cross-node segment transfer). Download rides the
|
|
22681
|
+
* framework addon data-plane. State persists in a DurableState blob (NOT
|
|
22682
|
+
* SQLite); history rows survive file deletion for audit.
|
|
22683
|
+
*/
|
|
22684
|
+
/** Playback-speed multiplier for the render (1 = realtime). */
|
|
22685
|
+
var ExportSpeedSchema = number().min(.25).max(32);
|
|
22686
|
+
/** Timelapse cadence — sample one source frame per `everyMs`, output at `outputFps`. */
|
|
22687
|
+
var ExportTimelapseSchema = object({
|
|
22688
|
+
everyMs: number().int().positive(),
|
|
22689
|
+
outputFps: number().int().min(1).max(60).optional()
|
|
22690
|
+
});
|
|
22691
|
+
/**
|
|
22692
|
+
* Render options. `speed` and `timelapse` are mutually exclusive. `includeAudio`
|
|
22693
|
+
* is honoured only for a realtime-ish speed (0.5–2×); timelapse is always
|
|
22694
|
+
* silent. `maxLifeMs` bounds how long the finished file is kept;
|
|
22695
|
+
* `deleteAfterDownload` removes it shortly after the first complete download.
|
|
22696
|
+
*/
|
|
22697
|
+
var ExportOptionsSchema = object({
|
|
22698
|
+
speed: ExportSpeedSchema.optional(),
|
|
22699
|
+
timelapse: ExportTimelapseSchema.optional(),
|
|
22700
|
+
includeAudio: boolean(),
|
|
22701
|
+
maxLifeMs: number().int().positive(),
|
|
22702
|
+
deleteAfterDownload: boolean(),
|
|
22703
|
+
title: string().max(200).optional()
|
|
22704
|
+
}).superRefine((v, ctx) => {
|
|
22705
|
+
if (v.speed !== void 0 && v.timelapse !== void 0) ctx.addIssue({
|
|
22706
|
+
code: ZodIssueCode.custom,
|
|
22707
|
+
message: "speed and timelapse are mutually exclusive",
|
|
22708
|
+
path: ["timelapse"]
|
|
22709
|
+
});
|
|
22710
|
+
});
|
|
22711
|
+
var ExportStateSchema = _enum([
|
|
22712
|
+
"queued",
|
|
22713
|
+
"rendering",
|
|
22714
|
+
"ready",
|
|
22715
|
+
"failed",
|
|
22716
|
+
"expired",
|
|
22717
|
+
"deleted"
|
|
22718
|
+
]);
|
|
22719
|
+
/** One export job / history row. */
|
|
22720
|
+
var ExportRecordSchema = object({
|
|
22721
|
+
id: string(),
|
|
22722
|
+
deviceId: number(),
|
|
22723
|
+
profile: string(),
|
|
22724
|
+
fromMs: number(),
|
|
22725
|
+
toMs: number(),
|
|
22726
|
+
options: ExportOptionsSchema,
|
|
22727
|
+
state: ExportStateSchema,
|
|
22728
|
+
/** 0–100 while rendering; null otherwise. */
|
|
22729
|
+
progressPct: number().nullable(),
|
|
22730
|
+
/** File size once ready; null before. */
|
|
22731
|
+
fileBytes: number().nullable(),
|
|
22732
|
+
expiresAt: number(),
|
|
22733
|
+
deleteAfterDownload: boolean(),
|
|
22734
|
+
/** Epoch of the first complete download; null until then. */
|
|
22735
|
+
downloadedAt: number().nullable(),
|
|
22736
|
+
createdAt: number(),
|
|
22737
|
+
/** User id/name that requested the export. */
|
|
22738
|
+
createdBy: string(),
|
|
22739
|
+
/** Failure reason when state is 'failed'; null otherwise. */
|
|
22740
|
+
error: string().nullable()
|
|
22741
|
+
});
|
|
22742
|
+
/** Candidate download URLs (LAN first, then operator extra hosts). */
|
|
22743
|
+
var ExportDownloadSchema = object({
|
|
22744
|
+
url: string(),
|
|
22745
|
+
endpoints: array(string())
|
|
22746
|
+
});
|
|
22747
|
+
method(object({
|
|
22748
|
+
deviceId: number(),
|
|
22749
|
+
profile: string(),
|
|
22750
|
+
fromMs: number(),
|
|
22751
|
+
toMs: number(),
|
|
22752
|
+
options: ExportOptionsSchema
|
|
22753
|
+
}), ExportRecordSchema, {
|
|
22754
|
+
kind: "mutation",
|
|
22755
|
+
auth: "protected"
|
|
22756
|
+
}), method(object({ deviceId: number().optional() }), array(ExportRecordSchema), {
|
|
22757
|
+
kind: "query",
|
|
22758
|
+
auth: "protected"
|
|
22759
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22760
|
+
kind: "query",
|
|
22761
|
+
auth: "protected"
|
|
22762
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22763
|
+
kind: "mutation",
|
|
22764
|
+
auth: "protected"
|
|
22765
|
+
}), method(object({ exportId: string() }), ExportRecordSchema, {
|
|
22766
|
+
kind: "mutation",
|
|
22767
|
+
auth: "protected"
|
|
22768
|
+
}), method(object({ exportId: string() }), ExportDownloadSchema, {
|
|
22769
|
+
kind: "query",
|
|
22770
|
+
auth: "protected"
|
|
22504
22771
|
});
|
|
22505
22772
|
/**
|
|
22506
22773
|
* One publishable camera stream as its OWNING PROVIDER describes it — the same
|
|
@@ -25533,6 +25800,12 @@ Object.freeze({
|
|
|
25533
25800
|
addonId: null,
|
|
25534
25801
|
access: "delete"
|
|
25535
25802
|
},
|
|
25803
|
+
"pipelineAnalytics.deleteDeviceEvents": {
|
|
25804
|
+
capName: "pipeline-analytics",
|
|
25805
|
+
capScope: "device",
|
|
25806
|
+
addonId: null,
|
|
25807
|
+
access: "delete"
|
|
25808
|
+
},
|
|
25536
25809
|
"pipelineAnalytics.deleteTracks": {
|
|
25537
25810
|
capName: "pipeline-analytics",
|
|
25538
25811
|
capScope: "device",
|
|
@@ -25563,6 +25836,12 @@ Object.freeze({
|
|
|
25563
25836
|
addonId: null,
|
|
25564
25837
|
access: "view"
|
|
25565
25838
|
},
|
|
25839
|
+
"pipelineAnalytics.getEventStoreFootprint": {
|
|
25840
|
+
capName: "pipeline-analytics",
|
|
25841
|
+
capScope: "device",
|
|
25842
|
+
addonId: null,
|
|
25843
|
+
access: "view"
|
|
25844
|
+
},
|
|
25566
25845
|
"pipelineAnalytics.getKeyEvents": {
|
|
25567
25846
|
capName: "pipeline-analytics",
|
|
25568
25847
|
capScope: "device",
|
|
@@ -25605,6 +25884,12 @@ Object.freeze({
|
|
|
25605
25884
|
addonId: null,
|
|
25606
25885
|
access: "view"
|
|
25607
25886
|
},
|
|
25887
|
+
"pipelineAnalytics.listOpsLog": {
|
|
25888
|
+
capName: "pipeline-analytics",
|
|
25889
|
+
capScope: "device",
|
|
25890
|
+
addonId: null,
|
|
25891
|
+
access: "view"
|
|
25892
|
+
},
|
|
25608
25893
|
"pipelineAnalytics.listRecentTracks": {
|
|
25609
25894
|
capName: "pipeline-analytics",
|
|
25610
25895
|
capScope: "device",
|
|
@@ -25617,6 +25902,12 @@ Object.freeze({
|
|
|
25617
25902
|
addonId: null,
|
|
25618
25903
|
access: "view"
|
|
25619
25904
|
},
|
|
25905
|
+
"pipelineAnalytics.pruneEvents": {
|
|
25906
|
+
capName: "pipeline-analytics",
|
|
25907
|
+
capScope: "device",
|
|
25908
|
+
addonId: null,
|
|
25909
|
+
access: "create"
|
|
25910
|
+
},
|
|
25620
25911
|
"pipelineAnalytics.pruneEventsBefore": {
|
|
25621
25912
|
capName: "pipeline-analytics",
|
|
25622
25913
|
capScope: "device",
|
|
@@ -26379,6 +26670,12 @@ Object.freeze({
|
|
|
26379
26670
|
addonId: null,
|
|
26380
26671
|
access: "create"
|
|
26381
26672
|
},
|
|
26673
|
+
"recording.deleteFootprint": {
|
|
26674
|
+
capName: "recording",
|
|
26675
|
+
capScope: "system",
|
|
26676
|
+
addonId: null,
|
|
26677
|
+
access: "delete"
|
|
26678
|
+
},
|
|
26382
26679
|
"recording.getAvailability": {
|
|
26383
26680
|
capName: "recording",
|
|
26384
26681
|
capScope: "system",
|
|
@@ -26409,6 +26706,12 @@ Object.freeze({
|
|
|
26409
26706
|
addonId: null,
|
|
26410
26707
|
access: "view"
|
|
26411
26708
|
},
|
|
26709
|
+
"recording.listOpsLog": {
|
|
26710
|
+
capName: "recording",
|
|
26711
|
+
capScope: "system",
|
|
26712
|
+
addonId: null,
|
|
26713
|
+
access: "view"
|
|
26714
|
+
},
|
|
26412
26715
|
"recording.locateSegment": {
|
|
26413
26716
|
capName: "recording",
|
|
26414
26717
|
capScope: "system",
|
|
@@ -26439,6 +26742,42 @@ Object.freeze({
|
|
|
26439
26742
|
addonId: null,
|
|
26440
26743
|
access: "create"
|
|
26441
26744
|
},
|
|
26745
|
+
"recordingExport.cancelExport": {
|
|
26746
|
+
capName: "recordingExport",
|
|
26747
|
+
capScope: "system",
|
|
26748
|
+
addonId: null,
|
|
26749
|
+
access: "create"
|
|
26750
|
+
},
|
|
26751
|
+
"recordingExport.createExport": {
|
|
26752
|
+
capName: "recordingExport",
|
|
26753
|
+
capScope: "system",
|
|
26754
|
+
addonId: null,
|
|
26755
|
+
access: "create"
|
|
26756
|
+
},
|
|
26757
|
+
"recordingExport.deleteExport": {
|
|
26758
|
+
capName: "recordingExport",
|
|
26759
|
+
capScope: "system",
|
|
26760
|
+
addonId: null,
|
|
26761
|
+
access: "delete"
|
|
26762
|
+
},
|
|
26763
|
+
"recordingExport.getDownloadUrl": {
|
|
26764
|
+
capName: "recordingExport",
|
|
26765
|
+
capScope: "system",
|
|
26766
|
+
addonId: null,
|
|
26767
|
+
access: "view"
|
|
26768
|
+
},
|
|
26769
|
+
"recordingExport.getExport": {
|
|
26770
|
+
capName: "recordingExport",
|
|
26771
|
+
capScope: "system",
|
|
26772
|
+
addonId: null,
|
|
26773
|
+
access: "view"
|
|
26774
|
+
},
|
|
26775
|
+
"recordingExport.listExports": {
|
|
26776
|
+
capName: "recordingExport",
|
|
26777
|
+
capScope: "system",
|
|
26778
|
+
addonId: null,
|
|
26779
|
+
access: "view"
|
|
26780
|
+
},
|
|
26442
26781
|
"sceneMonitor.captureReference": {
|
|
26443
26782
|
capName: "scene-monitor",
|
|
26444
26783
|
capScope: "device",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-provider-wyze",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.24",
|
|
4
4
|
"description": "Wyze camera device-provider addon for CamStack — wraps the @apocaliss92/wyze-bridge-js P2P/DTLS client, feeding the stream-broker via the pull-rfc4571 lazy-publish path (a structural twin of addon-provider-reolink)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|