camstack 1.2.68 → 1.2.69
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.
|
@@ -23633,9 +23633,9 @@ var require_zod = __commonJS({
|
|
|
23633
23633
|
}
|
|
23634
23634
|
});
|
|
23635
23635
|
|
|
23636
|
-
// ../system/dist/dist-
|
|
23637
|
-
var
|
|
23638
|
-
"../system/dist/dist-
|
|
23636
|
+
// ../system/dist/dist-B29Skpzo.js
|
|
23637
|
+
var require_dist_B29Skpzo = __commonJS({
|
|
23638
|
+
"../system/dist/dist-B29Skpzo.js"(exports) {
|
|
23639
23639
|
"use strict";
|
|
23640
23640
|
var zod = require_zod();
|
|
23641
23641
|
var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
|
|
@@ -26274,6 +26274,20 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
26274
26274
|
* in its row, not in its name, so `MediaRelocateEngine` never reconciles one.
|
|
26275
26275
|
*/
|
|
26276
26276
|
rowsReconciled: zod.z.number().int().nonnegative().optional(),
|
|
26277
|
+
/**
|
|
26278
|
+
* Rows this run FORGOT because the file they name is not on disk.
|
|
26279
|
+
*
|
|
26280
|
+
* The mover derived the path from the row's own fields and `stat`ed it; an
|
|
26281
|
+
* ENOENT there is a per-path confirmation that the segment is gone (D296),
|
|
26282
|
+
* and the durable row is dropped through the same channel eviction uses. It
|
|
26283
|
+
* is reported for the same reason `rowsReconciled` is: this is a durable
|
|
26284
|
+
* mutation nobody asked for, and a migration that quietly erases hour rows is
|
|
26285
|
+
* the same failure as one that quietly skips them (D295).
|
|
26286
|
+
*
|
|
26287
|
+
* The production drain of 2026-08-30 would have reported 11 074 here — the
|
|
26288
|
+
* ledger claimed 5.65 GB of footage that no longer existed.
|
|
26289
|
+
*/
|
|
26290
|
+
rowsForgotten: zod.z.number().int().nonnegative().optional(),
|
|
26277
26291
|
startedAt: zod.z.number(),
|
|
26278
26292
|
finishedAt: zod.z.number().nullable(),
|
|
26279
26293
|
error: zod.z.string().nullable()
|
|
@@ -26481,6 +26495,71 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
26481
26495
|
segments: zod.z.number().int().nonnegative(),
|
|
26482
26496
|
bytes: zod.z.number().int().nonnegative()
|
|
26483
26497
|
}).nullable();
|
|
26498
|
+
var LedgerWalkInputSchema = zod.z.object({
|
|
26499
|
+
locationId: zod.z.string().min(1),
|
|
26500
|
+
/** Forget the confirmed-absent rows, rather than only counting them. */
|
|
26501
|
+
apply: zod.z.boolean().optional(),
|
|
26502
|
+
/** Narrow to one camera. */
|
|
26503
|
+
deviceId: zod.z.number().int().positive().optional(),
|
|
26504
|
+
/** Narrow to these recording profiles; empty/absent = every profile. */
|
|
26505
|
+
profiles: zod.z.array(zod.z.string().min(1)).optional()
|
|
26506
|
+
});
|
|
26507
|
+
var LedgerWalkRefusalSchema = zod.z.enum([
|
|
26508
|
+
"location-unknown",
|
|
26509
|
+
"source-writable",
|
|
26510
|
+
"no-ledger",
|
|
26511
|
+
"archive-unreadable",
|
|
26512
|
+
"anchor-absent",
|
|
26513
|
+
"anchor-unreadable",
|
|
26514
|
+
"anchor-moved"
|
|
26515
|
+
]);
|
|
26516
|
+
zod.z.enum([
|
|
26517
|
+
"live-tail",
|
|
26518
|
+
"listing-error",
|
|
26519
|
+
"path-mismatch",
|
|
26520
|
+
"durable-refused"
|
|
26521
|
+
]);
|
|
26522
|
+
var LedgerWalkSkipCountsSchema = zod.z.object({
|
|
26523
|
+
"live-tail": zod.z.number().int().nonnegative(),
|
|
26524
|
+
"listing-error": zod.z.number().int().nonnegative(),
|
|
26525
|
+
"path-mismatch": zod.z.number().int().nonnegative(),
|
|
26526
|
+
"durable-refused": zod.z.number().int().nonnegative()
|
|
26527
|
+
});
|
|
26528
|
+
var LedgerWalkDeviceReportSchema = zod.z.object({
|
|
26529
|
+
deviceId: zod.z.number().int(),
|
|
26530
|
+
hoursWalked: zod.z.number().int().nonnegative(),
|
|
26531
|
+
hoursMissing: zod.z.number().int().nonnegative(),
|
|
26532
|
+
ghostSegments: zod.z.number().int().nonnegative(),
|
|
26533
|
+
ghostBytes: zod.z.number().int().nonnegative(),
|
|
26534
|
+
forgottenSegments: zod.z.number().int().nonnegative(),
|
|
26535
|
+
orphanFiles: zod.z.number().int().nonnegative()
|
|
26536
|
+
});
|
|
26537
|
+
var LedgerWalkReportSchema = zod.z.object({
|
|
26538
|
+
locationId: zod.z.string(),
|
|
26539
|
+
applied: zod.z.boolean(),
|
|
26540
|
+
refused: LedgerWalkRefusalSchema.nullable(),
|
|
26541
|
+
archiveSegments: zod.z.number().int().nonnegative().nullable(),
|
|
26542
|
+
archiveBytes: zod.z.number().int().nonnegative().nullable(),
|
|
26543
|
+
hoursClaimed: zod.z.number().int().nonnegative(),
|
|
26544
|
+
hoursWalked: zod.z.number().int().nonnegative(),
|
|
26545
|
+
hoursMissing: zod.z.number().int().nonnegative(),
|
|
26546
|
+
/** `readdir` calls issued — the cost, stated in the unit that is paid. */
|
|
26547
|
+
listings: zod.z.number().int().nonnegative(),
|
|
26548
|
+
segmentsClaimed: zod.z.number().int().nonnegative(),
|
|
26549
|
+
ghostSegments: zod.z.number().int().nonnegative(),
|
|
26550
|
+
ghostBytes: zod.z.number().int().nonnegative(),
|
|
26551
|
+
ghostHoursWhole: zod.z.number().int().nonnegative(),
|
|
26552
|
+
forgottenSegments: zod.z.number().int().nonnegative(),
|
|
26553
|
+
forgottenBytes: zod.z.number().int().nonnegative(),
|
|
26554
|
+
/** Files under a claimed hour that no durable row names. Never deleted. */
|
|
26555
|
+
orphanFiles: zod.z.number().int().nonnegative(),
|
|
26556
|
+
orphanSample: zod.z.array(zod.z.string()).readonly(),
|
|
26557
|
+
hoursSkipped: zod.z.number().int().nonnegative(),
|
|
26558
|
+
skippedByReason: LedgerWalkSkipCountsSchema,
|
|
26559
|
+
/** The walk stopped at its per-pass hour bound with claims unwalked. */
|
|
26560
|
+
bounded: zod.z.boolean(),
|
|
26561
|
+
byDevice: zod.z.array(LedgerWalkDeviceReportSchema).readonly()
|
|
26562
|
+
});
|
|
26484
26563
|
var RelocatableMediaCountSchema = zod.z.object({ rows: zod.z.number().int().nonnegative() }).nullable();
|
|
26485
26564
|
var RelocatableMediaCountInputSchema = zod.z.object({
|
|
26486
26565
|
toLocationId: zod.z.string().min(1),
|
|
@@ -36998,13 +37077,15 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
36998
37077
|
groups: zod.z.array(AnalyticsGroupRecordSchema).readonly(),
|
|
36999
37078
|
nextCursor: zod.z.string().nullable()
|
|
37000
37079
|
});
|
|
37080
|
+
var KEY_EVENTS_DEFAULT_LIMIT = 50;
|
|
37081
|
+
var KEY_EVENTS_MAX_LIMIT = 200;
|
|
37001
37082
|
var KeyEventQueryInput = zod.z.object({
|
|
37002
37083
|
deviceId: zod.z.number(),
|
|
37003
37084
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
37004
37085
|
since: zod.z.number(),
|
|
37005
37086
|
/** Window upper bound (track firstSeen ≤ until). */
|
|
37006
37087
|
until: zod.z.number(),
|
|
37007
|
-
limit: zod.z.number().int().min(1).max(
|
|
37088
|
+
limit: zod.z.number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
|
|
37008
37089
|
/** Drop tracks scoring below this importance. */
|
|
37009
37090
|
minImportance: zod.z.number().min(0).max(1).optional(),
|
|
37010
37091
|
/** Restrict to a single class (e.g. 'person'). */
|
|
@@ -37026,6 +37107,21 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
37026
37107
|
...TrackFlagFields,
|
|
37027
37108
|
...TrackRetrainFields
|
|
37028
37109
|
});
|
|
37110
|
+
var KeyEventBatchQueryInput = zod.z.object({
|
|
37111
|
+
deviceIds: zod.z.array(zod.z.number()).min(1).max(200),
|
|
37112
|
+
since: zod.z.number(),
|
|
37113
|
+
until: zod.z.number(),
|
|
37114
|
+
/** Applied PER CAMERA, exactly as `getKeyEvents.limit` is — never a total
|
|
37115
|
+
* across the set, which would let a busy camera starve a quiet one of its
|
|
37116
|
+
* rows and change what the merged feed contains. */
|
|
37117
|
+
limit: zod.z.number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
|
|
37118
|
+
minImportance: zod.z.number().min(0).max(1).optional(),
|
|
37119
|
+
classFilter: zod.z.string().optional()
|
|
37120
|
+
});
|
|
37121
|
+
var KeyEventsForDeviceSchema = zod.z.object({
|
|
37122
|
+
deviceId: zod.z.number(),
|
|
37123
|
+
events: zod.z.array(KeyEventSchema).readonly()
|
|
37124
|
+
});
|
|
37029
37125
|
zod.z.object({
|
|
37030
37126
|
trackId: zod.z.string(),
|
|
37031
37127
|
className: zod.z.string(),
|
|
@@ -37320,6 +37416,21 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
37320
37416
|
* scored on-read (no write). Degrades to `[]` on error.
|
|
37321
37417
|
*/
|
|
37322
37418
|
getKeyEvents: method(KeyEventQueryInput, zod.z.array(KeyEventSchema).readonly()),
|
|
37419
|
+
/**
|
|
37420
|
+
* The same ranking, for a SET of cameras, in one round trip.
|
|
37421
|
+
*
|
|
37422
|
+
* The Detection Intelligence events feed asks this of every selected
|
|
37423
|
+
* camera and re-asks on a 30s timer. Fanned out client-side that is N
|
|
37424
|
+
* round trips — browser → hub → post-analysis — for N independent,
|
|
37425
|
+
* already-indexed store queries. Batched, the queries are unchanged and
|
|
37426
|
+
* run concurrently INSIDE the owner; only the transport collapses.
|
|
37427
|
+
*
|
|
37428
|
+
* Deliberately per-device rather than pre-merged: `limit` stays per
|
|
37429
|
+
* camera (a total would let a busy camera starve a quiet one), and a
|
|
37430
|
+
* caller that renders one camera's lane needs to know which camera a row
|
|
37431
|
+
* came from. `getKeyEvents` stays for single-device callers.
|
|
37432
|
+
*/
|
|
37433
|
+
getKeyEventsBatch: method(KeyEventBatchQueryInput, zod.z.array(KeyEventsForDeviceSchema).readonly()),
|
|
37323
37434
|
/** Server-side bucketed event counts for the 24-hour timeline.
|
|
37324
37435
|
* Returns one entry per non-empty bucket; empty buckets are omitted. */
|
|
37325
37436
|
getEventDensity: method(zod.z.object({
|
|
@@ -47264,6 +47375,23 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
47264
47375
|
kind: "query",
|
|
47265
47376
|
auth: "admin"
|
|
47266
47377
|
}),
|
|
47378
|
+
/**
|
|
47379
|
+
* Does this location's LEDGER tell the truth about its disk? (D319)
|
|
47380
|
+
*
|
|
47381
|
+
* One `readdir` per claimed hour, diffed both ways: durable rows whose file
|
|
47382
|
+
* is not there, and files no durable row names. `apply` defaults to FALSE —
|
|
47383
|
+
* the report is the product, and the dry run is how an operator
|
|
47384
|
+
* sanity-checks the destructive run before authorising it.
|
|
47385
|
+
*
|
|
47386
|
+
* REFUSES a source that is still a write target: a listing of a live
|
|
47387
|
+
* location is a lower bound, which is not the strong evidence that lets
|
|
47388
|
+
* this pass forget without a budget. A live location is reconciled by the
|
|
47389
|
+
* mover, under D318's bound.
|
|
47390
|
+
*/
|
|
47391
|
+
reconcileLedgerAgainstDisk: method(LedgerWalkInputSchema, LedgerWalkReportSchema, {
|
|
47392
|
+
kind: "mutation",
|
|
47393
|
+
auth: "admin"
|
|
47394
|
+
}),
|
|
47267
47395
|
/** Cancel a running or queued relocate job. A queued job never runs. */
|
|
47268
47396
|
cancelRelocateJob: method(zod.z.object({ jobId: zod.z.string() }), zod.z.object({ cancelled: zod.z.boolean() }), {
|
|
47269
47397
|
kind: "mutation",
|
|
@@ -47561,6 +47689,10 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
47561
47689
|
monitors: zod.z.array(SceneMonitorSchema),
|
|
47562
47690
|
lastFetchedAt: zod.z.number()
|
|
47563
47691
|
});
|
|
47692
|
+
var SceneMonitorStatusForDeviceSchema = zod.z.object({
|
|
47693
|
+
deviceId: zod.z.number(),
|
|
47694
|
+
status: SceneMonitorStatusSchema.nullable()
|
|
47695
|
+
});
|
|
47564
47696
|
var sceneMonitorCapability = {
|
|
47565
47697
|
name: "scene-monitor",
|
|
47566
47698
|
scope: "device",
|
|
@@ -47570,6 +47702,22 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
47570
47702
|
deviceTypes: [DeviceType.Camera],
|
|
47571
47703
|
methods: {
|
|
47572
47704
|
listScenes: method(zod.z.object({ deviceId: zod.z.number() }), SceneMonitorStatusSchema),
|
|
47705
|
+
/**
|
|
47706
|
+
* The same answer, for a SET of cameras, in one round trip.
|
|
47707
|
+
*
|
|
47708
|
+
* `/scenes` renders every camera and re-reads them on a 30s safety-net
|
|
47709
|
+
* poll behind the push slice. Fanned out client-side that was one query
|
|
47710
|
+
* per camera — 29 round trips through the browser, the hub and the
|
|
47711
|
+
* post-analysis runner every 30 seconds to read an in-memory map the
|
|
47712
|
+
* owner had already merged. The work is unchanged (`statusFor` per
|
|
47713
|
+
* device, all in-process at the owner); what collapses is the transport.
|
|
47714
|
+
*
|
|
47715
|
+
* A camera that cannot answer still gets a row, with `status: null` —
|
|
47716
|
+
* see {@link SceneMonitorStatusForDeviceSchema}. Never fewer rows than
|
|
47717
|
+
* ids: a caller that asked for twenty-nine and got twenty-seven cannot
|
|
47718
|
+
* tell which two are missing, or that any are.
|
|
47719
|
+
*/
|
|
47720
|
+
listScenesBatch: method(zod.z.object({ deviceIds: zod.z.array(zod.z.number()).min(1).max(200) }), zod.z.array(SceneMonitorStatusForDeviceSchema).readonly()),
|
|
47573
47721
|
createScene: method(zod.z.object({
|
|
47574
47722
|
deviceId: zod.z.number(),
|
|
47575
47723
|
label: zod.z.string(),
|
|
@@ -49370,6 +49518,11 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
49370
49518
|
* than as repeated tracks/events. */
|
|
49371
49519
|
stationaryObjects: zod.z.array(StationaryObjectSchema).readonly().optional()
|
|
49372
49520
|
});
|
|
49521
|
+
var CameraOccupancySnapshotForDeviceSchema = zod.z.object({
|
|
49522
|
+
deviceId: zod.z.number(),
|
|
49523
|
+
read: zod.z.enum(["read", "unreadable"]),
|
|
49524
|
+
snapshot: CameraOccupancySnapshotSchema.nullable()
|
|
49525
|
+
});
|
|
49373
49526
|
var HistoryResolutionEnum = zod.z.enum([
|
|
49374
49527
|
"minute",
|
|
49375
49528
|
"5min",
|
|
@@ -49399,6 +49552,20 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
49399
49552
|
* (no inference result emitted since boot or since binding was
|
|
49400
49553
|
* activated). */
|
|
49401
49554
|
getCurrentSnapshot: method(zod.z.object({ deviceId: zod.z.number() }), CameraOccupancySnapshotSchema.nullable()),
|
|
49555
|
+
/**
|
|
49556
|
+
* The same snapshot, for a SET of cameras, in one round trip.
|
|
49557
|
+
*
|
|
49558
|
+
* The Events page's Stationary section polls this every 15s for every
|
|
49559
|
+
* selected camera. Fanned out client-side that is one query per camera to
|
|
49560
|
+
* read a `Map.get` at the owner — the answer costs nothing, the round trip
|
|
49561
|
+
* costs everything. Batched, N transports become one and the per-device
|
|
49562
|
+
* work is unchanged.
|
|
49563
|
+
*
|
|
49564
|
+
* Every requested deviceId gets a row, tagged `read` — see
|
|
49565
|
+
* {@link CameraOccupancySnapshotForDeviceSchema}. A camera the owner could
|
|
49566
|
+
* not answer for is `'unreadable'`, never an empty reading.
|
|
49567
|
+
*/
|
|
49568
|
+
getCurrentSnapshotBatch: method(zod.z.object({ deviceIds: zod.z.array(zod.z.number()).min(1).max(200) }), zod.z.array(CameraOccupancySnapshotForDeviceSchema).readonly()),
|
|
49402
49569
|
/** Time-series object count inside one zone. `className` optional —
|
|
49403
49570
|
* omit to count every class in the zone. */
|
|
49404
49571
|
getZoneHistory: method(zod.z.object({
|
|
@@ -53346,6 +53513,12 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
53346
53513
|
addonId: null,
|
|
53347
53514
|
access: "view"
|
|
53348
53515
|
},
|
|
53516
|
+
"pipelineAnalytics.getKeyEventsBatch": {
|
|
53517
|
+
capName: "pipeline-analytics",
|
|
53518
|
+
capScope: "device",
|
|
53519
|
+
addonId: null,
|
|
53520
|
+
access: "view"
|
|
53521
|
+
},
|
|
53349
53522
|
"pipelineAnalytics.getMotionEvents": {
|
|
53350
53523
|
capName: "pipeline-analytics",
|
|
53351
53524
|
capScope: "device",
|
|
@@ -54522,6 +54695,12 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
54522
54695
|
addonId: null,
|
|
54523
54696
|
access: "view"
|
|
54524
54697
|
},
|
|
54698
|
+
"recording.reconcileLedgerAgainstDisk": {
|
|
54699
|
+
capName: "recording",
|
|
54700
|
+
capScope: "system",
|
|
54701
|
+
addonId: null,
|
|
54702
|
+
access: "create"
|
|
54703
|
+
},
|
|
54525
54704
|
"recording.refreshStorageLocationsForMigration": {
|
|
54526
54705
|
capName: "recording",
|
|
54527
54706
|
capScope: "system",
|
|
@@ -54648,6 +54827,12 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
54648
54827
|
addonId: null,
|
|
54649
54828
|
access: "view"
|
|
54650
54829
|
},
|
|
54830
|
+
"sceneMonitor.listScenesBatch": {
|
|
54831
|
+
capName: "scene-monitor",
|
|
54832
|
+
capScope: "device",
|
|
54833
|
+
addonId: null,
|
|
54834
|
+
access: "view"
|
|
54835
|
+
},
|
|
54651
54836
|
"sceneMonitor.recheckNow": {
|
|
54652
54837
|
capName: "scene-monitor",
|
|
54653
54838
|
capScope: "device",
|
|
@@ -56004,6 +56189,12 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
56004
56189
|
addonId: null,
|
|
56005
56190
|
access: "view"
|
|
56006
56191
|
},
|
|
56192
|
+
"zoneAnalytics.getCurrentSnapshotBatch": {
|
|
56193
|
+
capName: "zone-analytics",
|
|
56194
|
+
capScope: "device",
|
|
56195
|
+
addonId: null,
|
|
56196
|
+
access: "view"
|
|
56197
|
+
},
|
|
56007
56198
|
"zoneAnalytics.getUnzonedHistory": {
|
|
56008
56199
|
capName: "zone-analytics",
|
|
56009
56200
|
capScope: "device",
|
|
@@ -57008,6 +57199,11 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
57008
57199
|
form: "single",
|
|
57009
57200
|
optional: false
|
|
57010
57201
|
}],
|
|
57202
|
+
"pipelineAnalytics.getKeyEventsBatch": [{
|
|
57203
|
+
name: "deviceIds",
|
|
57204
|
+
form: "array",
|
|
57205
|
+
optional: false
|
|
57206
|
+
}],
|
|
57011
57207
|
"pipelineAnalytics.getMotionEvents": [{
|
|
57012
57208
|
name: "deviceId",
|
|
57013
57209
|
form: "single",
|
|
@@ -57448,6 +57644,11 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
57448
57644
|
form: "single",
|
|
57449
57645
|
optional: false
|
|
57450
57646
|
}],
|
|
57647
|
+
"recording.reconcileLedgerAgainstDisk": [{
|
|
57648
|
+
name: "deviceId",
|
|
57649
|
+
form: "single",
|
|
57650
|
+
optional: true
|
|
57651
|
+
}],
|
|
57451
57652
|
"recording.relocateFootage": [{
|
|
57452
57653
|
name: "deviceId",
|
|
57453
57654
|
form: "single",
|
|
@@ -57513,6 +57714,11 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
57513
57714
|
form: "single",
|
|
57514
57715
|
optional: false
|
|
57515
57716
|
}],
|
|
57717
|
+
"sceneMonitor.listScenesBatch": [{
|
|
57718
|
+
name: "deviceIds",
|
|
57719
|
+
form: "array",
|
|
57720
|
+
optional: false
|
|
57721
|
+
}],
|
|
57516
57722
|
"sceneMonitor.recheckNow": [{
|
|
57517
57723
|
name: "deviceId",
|
|
57518
57724
|
form: "single",
|
|
@@ -57774,6 +57980,11 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
57774
57980
|
form: "single",
|
|
57775
57981
|
optional: false
|
|
57776
57982
|
}],
|
|
57983
|
+
"zoneAnalytics.getCurrentSnapshotBatch": [{
|
|
57984
|
+
name: "deviceIds",
|
|
57985
|
+
form: "array",
|
|
57986
|
+
optional: false
|
|
57987
|
+
}],
|
|
57777
57988
|
"zoneAnalytics.getUnzonedHistory": [{
|
|
57778
57989
|
name: "deviceId",
|
|
57779
57990
|
form: "single",
|
|
@@ -59207,7 +59418,7 @@ var require_alerts_addon = __commonJS({
|
|
|
59207
59418
|
[Symbol.toStringTag]: { value: "Module" }
|
|
59208
59419
|
});
|
|
59209
59420
|
require_chunk_Cek0wNdY();
|
|
59210
|
-
var require_dist10 =
|
|
59421
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
59211
59422
|
function selectExpired(alerts, cutoffMs) {
|
|
59212
59423
|
return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
|
|
59213
59424
|
}
|
|
@@ -60026,7 +60237,7 @@ var require_console_logging = __commonJS({
|
|
|
60026
60237
|
[Symbol.toStringTag]: { value: "Module" }
|
|
60027
60238
|
});
|
|
60028
60239
|
require_chunk_Cek0wNdY();
|
|
60029
|
-
var require_dist10 =
|
|
60240
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
60030
60241
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
60031
60242
|
var LEVEL_RANK = {
|
|
60032
60243
|
debug: 0,
|
|
@@ -60120,7 +60331,7 @@ var require_core_blocks_addon = __commonJS({
|
|
|
60120
60331
|
"use strict";
|
|
60121
60332
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
60122
60333
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
60123
|
-
var require_dist10 =
|
|
60334
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
60124
60335
|
var node_crypto = __require("crypto");
|
|
60125
60336
|
var node_fs_promises = __require("fs/promises");
|
|
60126
60337
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -61017,11 +61228,11 @@ var require_core_blocks = __commonJS({
|
|
|
61017
61228
|
}
|
|
61018
61229
|
});
|
|
61019
61230
|
|
|
61020
|
-
// ../system/dist/retired-settings-keys-
|
|
61021
|
-
var
|
|
61022
|
-
"../system/dist/retired-settings-keys-
|
|
61231
|
+
// ../system/dist/retired-settings-keys-CRL0qOnU.js
|
|
61232
|
+
var require_retired_settings_keys_CRL0qOnU = __commonJS({
|
|
61233
|
+
"../system/dist/retired-settings-keys-CRL0qOnU.js"(exports) {
|
|
61023
61234
|
"use strict";
|
|
61024
|
-
var require_dist10 =
|
|
61235
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
61025
61236
|
function settingsStoreIsAuthoritativeHere(env) {
|
|
61026
61237
|
const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
|
|
61027
61238
|
return raw === "" || raw === "hub";
|
|
@@ -63235,8 +63446,8 @@ var require_device_manager_addon = __commonJS({
|
|
|
63235
63446
|
[Symbol.toStringTag]: { value: "Module" }
|
|
63236
63447
|
});
|
|
63237
63448
|
require_chunk_Cek0wNdY();
|
|
63238
|
-
var require_dist10 =
|
|
63239
|
-
var require_retired_settings_keys =
|
|
63449
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
63450
|
+
var require_retired_settings_keys = require_retired_settings_keys_CRL0qOnU();
|
|
63240
63451
|
var node_crypto = __require("crypto");
|
|
63241
63452
|
var _camstack_types_node = require_node();
|
|
63242
63453
|
var JOB_HISTORY = 20;
|
|
@@ -68049,7 +68260,7 @@ var require_hub_forwarder = __commonJS({
|
|
|
68049
68260
|
[Symbol.toStringTag]: { value: "Module" }
|
|
68050
68261
|
});
|
|
68051
68262
|
require_chunk_Cek0wNdY();
|
|
68052
|
-
var require_dist10 =
|
|
68263
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
68053
68264
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
68054
68265
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
68055
68266
|
var HubForwarderDestination = class {
|
|
@@ -68186,7 +68397,7 @@ var require_liveness_monitor_addon = __commonJS({
|
|
|
68186
68397
|
"use strict";
|
|
68187
68398
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
68188
68399
|
require_chunk_Cek0wNdY();
|
|
68189
|
-
var require_dist10 =
|
|
68400
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
68190
68401
|
var NO_DEVICES = "liveness:no-devices";
|
|
68191
68402
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
68192
68403
|
var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
|
|
@@ -68376,7 +68587,7 @@ var require_local_auth_addon = __commonJS({
|
|
|
68376
68587
|
[Symbol.toStringTag]: { value: "Module" }
|
|
68377
68588
|
});
|
|
68378
68589
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
68379
|
-
var require_dist10 =
|
|
68590
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
68380
68591
|
var node_crypto = __require("crypto");
|
|
68381
68592
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
68382
68593
|
var crypto$1 = __require("crypto");
|
|
@@ -76189,7 +76400,7 @@ var require_loki_logging = __commonJS({
|
|
|
76189
76400
|
[Symbol.toStringTag]: { value: "Module" }
|
|
76190
76401
|
});
|
|
76191
76402
|
require_chunk_Cek0wNdY();
|
|
76192
|
-
var require_dist10 =
|
|
76403
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
76193
76404
|
function sanitizeLabelName(raw) {
|
|
76194
76405
|
const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
|
|
76195
76406
|
return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
|
|
@@ -76754,7 +76965,7 @@ var require_native_metrics_addon = __commonJS({
|
|
|
76754
76965
|
[Symbol.toStringTag]: { value: "Module" }
|
|
76755
76966
|
});
|
|
76756
76967
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
76757
|
-
var require_dist10 =
|
|
76968
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
76758
76969
|
var node_fs_promises = __require("fs/promises");
|
|
76759
76970
|
var node_child_process = __require("child_process");
|
|
76760
76971
|
var node_util = __require("util");
|
|
@@ -79376,7 +79587,7 @@ var require_filesystem_storage_addon = __commonJS({
|
|
|
79376
79587
|
[Symbol.toStringTag]: { value: "Module" }
|
|
79377
79588
|
});
|
|
79378
79589
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
79379
|
-
var require_dist10 =
|
|
79590
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
79380
79591
|
var node_crypto = __require("crypto");
|
|
79381
79592
|
var node_fs_promises = __require("fs/promises");
|
|
79382
79593
|
var node_path = __require("path");
|
|
@@ -80492,8 +80703,8 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
80492
80703
|
[Symbol.toStringTag]: { value: "Module" }
|
|
80493
80704
|
});
|
|
80494
80705
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
80495
|
-
var require_dist10 =
|
|
80496
|
-
var require_retired_settings_keys =
|
|
80706
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
80707
|
+
var require_retired_settings_keys = require_retired_settings_keys_CRL0qOnU();
|
|
80497
80708
|
var node_crypto = __require("crypto");
|
|
80498
80709
|
var node_fs = __require("fs");
|
|
80499
80710
|
var node_module = __require("module");
|
|
@@ -82872,7 +83083,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
82872
83083
|
[Symbol.toStringTag]: { value: "Module" }
|
|
82873
83084
|
});
|
|
82874
83085
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
82875
|
-
var require_dist10 =
|
|
83086
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
82876
83087
|
var node_crypto = __require("crypto");
|
|
82877
83088
|
var node_fs_promises = __require("fs/promises");
|
|
82878
83089
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -85469,7 +85680,7 @@ var require_system_config_addon = __commonJS({
|
|
|
85469
85680
|
[Symbol.toStringTag]: { value: "Module" }
|
|
85470
85681
|
});
|
|
85471
85682
|
require_chunk_Cek0wNdY();
|
|
85472
|
-
var require_dist10 =
|
|
85683
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
85473
85684
|
var SECTION_TITLES = {
|
|
85474
85685
|
server: "Server",
|
|
85475
85686
|
auth: "Authentication"
|
|
@@ -103530,7 +103741,7 @@ var require_winston_logging = __commonJS({
|
|
|
103530
103741
|
[Symbol.toStringTag]: { value: "Module" }
|
|
103531
103742
|
});
|
|
103532
103743
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
103533
|
-
var require_dist10 =
|
|
103744
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
103534
103745
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
103535
103746
|
var node_path = __require("path");
|
|
103536
103747
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -105473,9 +105684,9 @@ var require_event_category_BaEgqJNv = __commonJS({
|
|
|
105473
105684
|
}
|
|
105474
105685
|
});
|
|
105475
105686
|
|
|
105476
|
-
// ../types/dist/sleep-
|
|
105477
|
-
var
|
|
105478
|
-
"../types/dist/sleep-
|
|
105687
|
+
// ../types/dist/sleep-DIg3xuEw.js
|
|
105688
|
+
var require_sleep_DIg3xuEw = __commonJS({
|
|
105689
|
+
"../types/dist/sleep-DIg3xuEw.js"(exports) {
|
|
105479
105690
|
"use strict";
|
|
105480
105691
|
var require_event_category = require_event_category_BaEgqJNv();
|
|
105481
105692
|
var zod = require_zod();
|
|
@@ -108158,6 +108369,7 @@ var require_sleep_D5821NGq = __commonJS({
|
|
|
108158
108369
|
listEventKindsBatch: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listEventKindsBatch", "query", input),
|
|
108159
108370
|
getSensorEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getSensorEvents", "query", input),
|
|
108160
108371
|
getKeyEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getKeyEvents", "query", input),
|
|
108372
|
+
getKeyEventsBatch: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getKeyEventsBatch", "query", input),
|
|
108161
108373
|
getEventDensity: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventDensity", "query", input),
|
|
108162
108374
|
pruneEventsBefore: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneEventsBefore", "mutation", input),
|
|
108163
108375
|
pruneTracksBefore: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneTracksBefore", "mutation", input),
|
|
@@ -108239,6 +108451,7 @@ var require_sleep_D5821NGq = __commonJS({
|
|
|
108239
108451
|
reboot: { reboot: (input) => dispatch("reboot", "reboot", "reboot", "mutation", input) },
|
|
108240
108452
|
sceneMonitor: {
|
|
108241
108453
|
listScenes: (input) => dispatch("scene-monitor", "sceneMonitor", "listScenes", "query", input),
|
|
108454
|
+
listScenesBatch: (input) => dispatch("scene-monitor", "sceneMonitor", "listScenesBatch", "query", input),
|
|
108242
108455
|
createScene: (input) => dispatch("scene-monitor", "sceneMonitor", "createScene", "mutation", input),
|
|
108243
108456
|
updateScene: (input) => dispatch("scene-monitor", "sceneMonitor", "updateScene", "mutation", input),
|
|
108244
108457
|
deleteScene: (input) => dispatch("scene-monitor", "sceneMonitor", "deleteScene", "mutation", input),
|
|
@@ -108323,6 +108536,7 @@ var require_sleep_D5821NGq = __commonJS({
|
|
|
108323
108536
|
},
|
|
108324
108537
|
zoneAnalytics: {
|
|
108325
108538
|
getCurrentSnapshot: (input) => dispatch("zone-analytics", "zoneAnalytics", "getCurrentSnapshot", "query", input),
|
|
108539
|
+
getCurrentSnapshotBatch: (input) => dispatch("zone-analytics", "zoneAnalytics", "getCurrentSnapshotBatch", "query", input),
|
|
108326
108540
|
getZoneHistory: (input) => dispatch("zone-analytics", "zoneAnalytics", "getZoneHistory", "query", input),
|
|
108327
108541
|
getCameraHistory: (input) => dispatch("zone-analytics", "zoneAnalytics", "getCameraHistory", "query", input),
|
|
108328
108542
|
getUnzonedHistory: (input) => dispatch("zone-analytics", "zoneAnalytics", "getUnzonedHistory", "query", input)
|
|
@@ -109143,7 +109357,7 @@ var require_addon = __commonJS({
|
|
|
109143
109357
|
"use strict";
|
|
109144
109358
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
109145
109359
|
var require_event_category = require_event_category_BaEgqJNv();
|
|
109146
|
-
var require_sleep =
|
|
109360
|
+
var require_sleep = require_sleep_DIg3xuEw();
|
|
109147
109361
|
var require_err_msg = require_err_msg_COpsHMw2();
|
|
109148
109362
|
var CAP_INPUT_DEFAULTS = Object.freeze({
|
|
109149
109363
|
"addons": { "getLogs": { "limit": 100 } },
|
|
@@ -109253,6 +109467,7 @@ var require_addon = __commonJS({
|
|
|
109253
109467
|
"pipeline-analytics": {
|
|
109254
109468
|
"getAudioEvents": { "limit": 1e3 },
|
|
109255
109469
|
"getKeyEvents": { "limit": 50 },
|
|
109470
|
+
"getKeyEventsBatch": { "limit": 50 },
|
|
109256
109471
|
"getMotionEvents": { "limit": 1e3 },
|
|
109257
109472
|
"getObjectEvents": { "limit": 1e3 },
|
|
109258
109473
|
"getSensorEvents": { "limit": 1e3 },
|
|
@@ -116025,12 +116240,12 @@ var require_dist2 = __commonJS({
|
|
|
116025
116240
|
}
|
|
116026
116241
|
});
|
|
116027
116242
|
|
|
116028
|
-
// ../system/dist/manifest-system-deps-
|
|
116029
|
-
var
|
|
116030
|
-
"../system/dist/manifest-system-deps-
|
|
116243
|
+
// ../system/dist/manifest-system-deps-DBje540e.js
|
|
116244
|
+
var require_manifest_system_deps_DBje540e = __commonJS({
|
|
116245
|
+
"../system/dist/manifest-system-deps-DBje540e.js"(exports) {
|
|
116031
116246
|
"use strict";
|
|
116032
116247
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
116033
|
-
|
|
116248
|
+
require_dist_B29Skpzo();
|
|
116034
116249
|
var node_crypto = __require("crypto");
|
|
116035
116250
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
116036
116251
|
var _camstack_types_node = require_node();
|
|
@@ -128059,7 +128274,7 @@ var require_dist3 = __commonJS({
|
|
|
128059
128274
|
"use strict";
|
|
128060
128275
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
128061
128276
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
128062
|
-
var require_dist10 =
|
|
128277
|
+
var require_dist10 = require_dist_B29Skpzo();
|
|
128063
128278
|
var require_builtins_alerts_alerts_addon = require_alerts_addon();
|
|
128064
128279
|
require_alerts();
|
|
128065
128280
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
@@ -128085,7 +128300,7 @@ var require_dist3 = __commonJS({
|
|
|
128085
128300
|
var require_builtins_winston_logging_index = require_winston_logging();
|
|
128086
128301
|
var require_file_data_plane = require_file_data_plane_DO8KbxCe();
|
|
128087
128302
|
var require_tls$1 = require_tls_BxQlomxd();
|
|
128088
|
-
var require_manifest_system_deps =
|
|
128303
|
+
var require_manifest_system_deps = require_manifest_system_deps_DBje540e();
|
|
128089
128304
|
var require_resource_monitor = require_resource_monitor_CdnzxBLP();
|
|
128090
128305
|
var require_custom_action_registry = require_custom_action_registry_jY0NOZK8();
|
|
128091
128306
|
var zod = require_zod();
|
|
@@ -133973,19 +134188,37 @@ var require_dist3 = __commonJS({
|
|
|
133973
134188
|
if (!isRecord$1(parsed) || !("value" in parsed)) return parsed;
|
|
133974
134189
|
return parsed.value;
|
|
133975
134190
|
}
|
|
134191
|
+
var PREFIX_PAGE_ROWS = 1e3;
|
|
134192
|
+
var PREFIX_PAGE_BUDGET = 512;
|
|
133976
134193
|
async function loadPrefixed(door, collection, prefix) {
|
|
133977
134194
|
const range = require_builtins_sqlite_storage_sqlite_settings_addon.prefixRange(prefix);
|
|
133978
|
-
const rows = await door.query({
|
|
133979
|
-
collection,
|
|
133980
|
-
...range !== null ? { filter: { whereBetween: { id: [range.lo, range.hi] } } } : {}
|
|
133981
|
-
});
|
|
133982
134195
|
const result = {};
|
|
133983
|
-
|
|
133984
|
-
|
|
133985
|
-
if (
|
|
133986
|
-
|
|
134196
|
+
let cursor = range?.lo ?? null;
|
|
134197
|
+
for (let page = 0; ; page++) {
|
|
134198
|
+
if (page >= PREFIX_PAGE_BUDGET) throw new Error(`settings door: reading "${prefix}" from "${collection}" exceeded ${PREFIX_PAGE_BUDGET} pages of ${PREFIX_PAGE_ROWS} rows. Refusing to return the part that was read \u2014 a partial scope read is indistinguishable from an empty one.`);
|
|
134199
|
+
const rows = await door.query({
|
|
134200
|
+
collection,
|
|
134201
|
+
filter: {
|
|
134202
|
+
...range !== null && cursor !== null ? { whereBetween: { id: [cursor, range.hi] } } : {},
|
|
134203
|
+
orderBy: {
|
|
134204
|
+
field: "id",
|
|
134205
|
+
direction: "asc"
|
|
134206
|
+
},
|
|
134207
|
+
limit: PREFIX_PAGE_ROWS
|
|
134208
|
+
}
|
|
134209
|
+
});
|
|
134210
|
+
for (const row of rows) {
|
|
134211
|
+
if (range !== null && (row.id < range.lo || row.id >= range.hi)) continue;
|
|
134212
|
+
if (!row.id.startsWith(prefix)) continue;
|
|
134213
|
+
result[row.id.slice(prefix.length)] = unwrapValue(row.data);
|
|
134214
|
+
}
|
|
134215
|
+
if (rows.length < PREFIX_PAGE_ROWS) return result;
|
|
134216
|
+
const last = rows[rows.length - 1];
|
|
134217
|
+
if (last === void 0) return result;
|
|
134218
|
+
if (range === null) throw new Error(`settings door: prefix "${prefix}" on "${collection}" cannot be expressed as an id range, and the unfiltered read filled a page \u2014 the answer would be partial. Use an ASCII, non-empty prefix.`);
|
|
134219
|
+
if (last.id === cursor) throw new Error(`settings door: reading "${prefix}" from "${collection}" made no progress at id "${last.id}" \u2014 ids under a prefix must be unique.`);
|
|
134220
|
+
cursor = last.id;
|
|
133987
134221
|
}
|
|
133988
|
-
return result;
|
|
133989
134222
|
}
|
|
133990
134223
|
async function replacePrefixed(door, collection, prefix, values, wrap3) {
|
|
133991
134224
|
const range = require_builtins_sqlite_storage_sqlite_settings_addon.prefixRange(prefix);
|
|
@@ -208909,7 +209142,7 @@ var require_dist4 = __commonJS({
|
|
|
208909
209142
|
"use strict";
|
|
208910
209143
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
208911
209144
|
var require_event_category = require_event_category_BaEgqJNv();
|
|
208912
|
-
var require_sleep =
|
|
209145
|
+
var require_sleep = require_sleep_DIg3xuEw();
|
|
208913
209146
|
var require_canonical_hash = require_canonical_hash_DNV8S5ET();
|
|
208914
209147
|
var require_enums2 = require_enums();
|
|
208915
209148
|
var require_err_msg = require_err_msg_COpsHMw2();
|
|
@@ -210256,6 +210489,20 @@ var require_dist4 = __commonJS({
|
|
|
210256
210489
|
* in its row, not in its name, so `MediaRelocateEngine` never reconciles one.
|
|
210257
210490
|
*/
|
|
210258
210491
|
rowsReconciled: zod.z.number().int().nonnegative().optional(),
|
|
210492
|
+
/**
|
|
210493
|
+
* Rows this run FORGOT because the file they name is not on disk.
|
|
210494
|
+
*
|
|
210495
|
+
* The mover derived the path from the row's own fields and `stat`ed it; an
|
|
210496
|
+
* ENOENT there is a per-path confirmation that the segment is gone (D296),
|
|
210497
|
+
* and the durable row is dropped through the same channel eviction uses. It
|
|
210498
|
+
* is reported for the same reason `rowsReconciled` is: this is a durable
|
|
210499
|
+
* mutation nobody asked for, and a migration that quietly erases hour rows is
|
|
210500
|
+
* the same failure as one that quietly skips them (D295).
|
|
210501
|
+
*
|
|
210502
|
+
* The production drain of 2026-08-30 would have reported 11 074 here — the
|
|
210503
|
+
* ledger claimed 5.65 GB of footage that no longer existed.
|
|
210504
|
+
*/
|
|
210505
|
+
rowsForgotten: zod.z.number().int().nonnegative().optional(),
|
|
210259
210506
|
startedAt: zod.z.number(),
|
|
210260
210507
|
finishedAt: zod.z.number().nullable(),
|
|
210261
210508
|
error: zod.z.string().nullable()
|
|
@@ -210463,6 +210710,71 @@ var require_dist4 = __commonJS({
|
|
|
210463
210710
|
segments: zod.z.number().int().nonnegative(),
|
|
210464
210711
|
bytes: zod.z.number().int().nonnegative()
|
|
210465
210712
|
}).nullable();
|
|
210713
|
+
var LedgerWalkInputSchema = zod.z.object({
|
|
210714
|
+
locationId: zod.z.string().min(1),
|
|
210715
|
+
/** Forget the confirmed-absent rows, rather than only counting them. */
|
|
210716
|
+
apply: zod.z.boolean().optional(),
|
|
210717
|
+
/** Narrow to one camera. */
|
|
210718
|
+
deviceId: zod.z.number().int().positive().optional(),
|
|
210719
|
+
/** Narrow to these recording profiles; empty/absent = every profile. */
|
|
210720
|
+
profiles: zod.z.array(zod.z.string().min(1)).optional()
|
|
210721
|
+
});
|
|
210722
|
+
var LedgerWalkRefusalSchema = zod.z.enum([
|
|
210723
|
+
"location-unknown",
|
|
210724
|
+
"source-writable",
|
|
210725
|
+
"no-ledger",
|
|
210726
|
+
"archive-unreadable",
|
|
210727
|
+
"anchor-absent",
|
|
210728
|
+
"anchor-unreadable",
|
|
210729
|
+
"anchor-moved"
|
|
210730
|
+
]);
|
|
210731
|
+
var LedgerWalkSkipReasonSchema = zod.z.enum([
|
|
210732
|
+
"live-tail",
|
|
210733
|
+
"listing-error",
|
|
210734
|
+
"path-mismatch",
|
|
210735
|
+
"durable-refused"
|
|
210736
|
+
]);
|
|
210737
|
+
var LedgerWalkSkipCountsSchema = zod.z.object({
|
|
210738
|
+
"live-tail": zod.z.number().int().nonnegative(),
|
|
210739
|
+
"listing-error": zod.z.number().int().nonnegative(),
|
|
210740
|
+
"path-mismatch": zod.z.number().int().nonnegative(),
|
|
210741
|
+
"durable-refused": zod.z.number().int().nonnegative()
|
|
210742
|
+
});
|
|
210743
|
+
var LedgerWalkDeviceReportSchema = zod.z.object({
|
|
210744
|
+
deviceId: zod.z.number().int(),
|
|
210745
|
+
hoursWalked: zod.z.number().int().nonnegative(),
|
|
210746
|
+
hoursMissing: zod.z.number().int().nonnegative(),
|
|
210747
|
+
ghostSegments: zod.z.number().int().nonnegative(),
|
|
210748
|
+
ghostBytes: zod.z.number().int().nonnegative(),
|
|
210749
|
+
forgottenSegments: zod.z.number().int().nonnegative(),
|
|
210750
|
+
orphanFiles: zod.z.number().int().nonnegative()
|
|
210751
|
+
});
|
|
210752
|
+
var LedgerWalkReportSchema = zod.z.object({
|
|
210753
|
+
locationId: zod.z.string(),
|
|
210754
|
+
applied: zod.z.boolean(),
|
|
210755
|
+
refused: LedgerWalkRefusalSchema.nullable(),
|
|
210756
|
+
archiveSegments: zod.z.number().int().nonnegative().nullable(),
|
|
210757
|
+
archiveBytes: zod.z.number().int().nonnegative().nullable(),
|
|
210758
|
+
hoursClaimed: zod.z.number().int().nonnegative(),
|
|
210759
|
+
hoursWalked: zod.z.number().int().nonnegative(),
|
|
210760
|
+
hoursMissing: zod.z.number().int().nonnegative(),
|
|
210761
|
+
/** `readdir` calls issued — the cost, stated in the unit that is paid. */
|
|
210762
|
+
listings: zod.z.number().int().nonnegative(),
|
|
210763
|
+
segmentsClaimed: zod.z.number().int().nonnegative(),
|
|
210764
|
+
ghostSegments: zod.z.number().int().nonnegative(),
|
|
210765
|
+
ghostBytes: zod.z.number().int().nonnegative(),
|
|
210766
|
+
ghostHoursWhole: zod.z.number().int().nonnegative(),
|
|
210767
|
+
forgottenSegments: zod.z.number().int().nonnegative(),
|
|
210768
|
+
forgottenBytes: zod.z.number().int().nonnegative(),
|
|
210769
|
+
/** Files under a claimed hour that no durable row names. Never deleted. */
|
|
210770
|
+
orphanFiles: zod.z.number().int().nonnegative(),
|
|
210771
|
+
orphanSample: zod.z.array(zod.z.string()).readonly(),
|
|
210772
|
+
hoursSkipped: zod.z.number().int().nonnegative(),
|
|
210773
|
+
skippedByReason: LedgerWalkSkipCountsSchema,
|
|
210774
|
+
/** The walk stopped at its per-pass hour bound with claims unwalked. */
|
|
210775
|
+
bounded: zod.z.boolean(),
|
|
210776
|
+
byDevice: zod.z.array(LedgerWalkDeviceReportSchema).readonly()
|
|
210777
|
+
});
|
|
210466
210778
|
var RelocatableMediaCountSchema = zod.z.object({ rows: zod.z.number().int().nonnegative() }).nullable();
|
|
210467
210779
|
var RelocatableMediaCountInputSchema = zod.z.object({
|
|
210468
210780
|
toLocationId: zod.z.string().min(1),
|
|
@@ -222962,13 +223274,15 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222962
223274
|
groups: zod.z.array(AnalyticsGroupRecordSchema).readonly(),
|
|
222963
223275
|
nextCursor: zod.z.string().nullable()
|
|
222964
223276
|
});
|
|
223277
|
+
var KEY_EVENTS_DEFAULT_LIMIT = 50;
|
|
223278
|
+
var KEY_EVENTS_MAX_LIMIT = 200;
|
|
222965
223279
|
var KeyEventQueryInput = zod.z.object({
|
|
222966
223280
|
deviceId: zod.z.number(),
|
|
222967
223281
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
222968
223282
|
since: zod.z.number(),
|
|
222969
223283
|
/** Window upper bound (track firstSeen ≤ until). */
|
|
222970
223284
|
until: zod.z.number(),
|
|
222971
|
-
limit: zod.z.number().int().min(1).max(
|
|
223285
|
+
limit: zod.z.number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
|
|
222972
223286
|
/** Drop tracks scoring below this importance. */
|
|
222973
223287
|
minImportance: zod.z.number().min(0).max(1).optional(),
|
|
222974
223288
|
/** Restrict to a single class (e.g. 'person'). */
|
|
@@ -222990,6 +223304,21 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222990
223304
|
...TrackFlagFields,
|
|
222991
223305
|
...TrackRetrainFields
|
|
222992
223306
|
});
|
|
223307
|
+
var KeyEventBatchQueryInput = zod.z.object({
|
|
223308
|
+
deviceIds: zod.z.array(zod.z.number()).min(1).max(200),
|
|
223309
|
+
since: zod.z.number(),
|
|
223310
|
+
until: zod.z.number(),
|
|
223311
|
+
/** Applied PER CAMERA, exactly as `getKeyEvents.limit` is — never a total
|
|
223312
|
+
* across the set, which would let a busy camera starve a quiet one of its
|
|
223313
|
+
* rows and change what the merged feed contains. */
|
|
223314
|
+
limit: zod.z.number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
|
|
223315
|
+
minImportance: zod.z.number().min(0).max(1).optional(),
|
|
223316
|
+
classFilter: zod.z.string().optional()
|
|
223317
|
+
});
|
|
223318
|
+
var KeyEventsForDeviceSchema = zod.z.object({
|
|
223319
|
+
deviceId: zod.z.number(),
|
|
223320
|
+
events: zod.z.array(KeyEventSchema).readonly()
|
|
223321
|
+
});
|
|
222993
223322
|
var TrackedDetectionSchema = zod.z.object({
|
|
222994
223323
|
trackId: zod.z.string(),
|
|
222995
223324
|
className: zod.z.string(),
|
|
@@ -223284,6 +223613,21 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
223284
223613
|
* scored on-read (no write). Degrades to `[]` on error.
|
|
223285
223614
|
*/
|
|
223286
223615
|
getKeyEvents: require_sleep.method(KeyEventQueryInput, zod.z.array(KeyEventSchema).readonly()),
|
|
223616
|
+
/**
|
|
223617
|
+
* The same ranking, for a SET of cameras, in one round trip.
|
|
223618
|
+
*
|
|
223619
|
+
* The Detection Intelligence events feed asks this of every selected
|
|
223620
|
+
* camera and re-asks on a 30s timer. Fanned out client-side that is N
|
|
223621
|
+
* round trips — browser → hub → post-analysis — for N independent,
|
|
223622
|
+
* already-indexed store queries. Batched, the queries are unchanged and
|
|
223623
|
+
* run concurrently INSIDE the owner; only the transport collapses.
|
|
223624
|
+
*
|
|
223625
|
+
* Deliberately per-device rather than pre-merged: `limit` stays per
|
|
223626
|
+
* camera (a total would let a busy camera starve a quiet one), and a
|
|
223627
|
+
* caller that renders one camera's lane needs to know which camera a row
|
|
223628
|
+
* came from. `getKeyEvents` stays for single-device callers.
|
|
223629
|
+
*/
|
|
223630
|
+
getKeyEventsBatch: require_sleep.method(KeyEventBatchQueryInput, zod.z.array(KeyEventsForDeviceSchema).readonly()),
|
|
223287
223631
|
/** Server-side bucketed event counts for the 24-hour timeline.
|
|
223288
223632
|
* Returns one entry per non-empty bucket; empty buckets are omitted. */
|
|
223289
223633
|
getEventDensity: require_sleep.method(zod.z.object({
|
|
@@ -233401,6 +233745,23 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
233401
233745
|
kind: "query",
|
|
233402
233746
|
auth: "admin"
|
|
233403
233747
|
}),
|
|
233748
|
+
/**
|
|
233749
|
+
* Does this location's LEDGER tell the truth about its disk? (D319)
|
|
233750
|
+
*
|
|
233751
|
+
* One `readdir` per claimed hour, diffed both ways: durable rows whose file
|
|
233752
|
+
* is not there, and files no durable row names. `apply` defaults to FALSE —
|
|
233753
|
+
* the report is the product, and the dry run is how an operator
|
|
233754
|
+
* sanity-checks the destructive run before authorising it.
|
|
233755
|
+
*
|
|
233756
|
+
* REFUSES a source that is still a write target: a listing of a live
|
|
233757
|
+
* location is a lower bound, which is not the strong evidence that lets
|
|
233758
|
+
* this pass forget without a budget. A live location is reconciled by the
|
|
233759
|
+
* mover, under D318's bound.
|
|
233760
|
+
*/
|
|
233761
|
+
reconcileLedgerAgainstDisk: require_sleep.method(LedgerWalkInputSchema, LedgerWalkReportSchema, {
|
|
233762
|
+
kind: "mutation",
|
|
233763
|
+
auth: "admin"
|
|
233764
|
+
}),
|
|
233404
233765
|
/** Cancel a running or queued relocate job. A queued job never runs. */
|
|
233405
233766
|
cancelRelocateJob: require_sleep.method(zod.z.object({ jobId: zod.z.string() }), zod.z.object({ cancelled: zod.z.boolean() }), {
|
|
233406
233767
|
kind: "mutation",
|
|
@@ -233715,6 +234076,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
233715
234076
|
monitors: zod.z.array(SceneMonitorSchema),
|
|
233716
234077
|
lastFetchedAt: zod.z.number()
|
|
233717
234078
|
});
|
|
234079
|
+
var SceneMonitorStatusForDeviceSchema = zod.z.object({
|
|
234080
|
+
deviceId: zod.z.number(),
|
|
234081
|
+
status: SceneMonitorStatusSchema.nullable()
|
|
234082
|
+
});
|
|
233718
234083
|
var sceneMonitorCapability = {
|
|
233719
234084
|
name: "scene-monitor",
|
|
233720
234085
|
scope: "device",
|
|
@@ -233724,6 +234089,22 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
233724
234089
|
deviceTypes: [require_sleep.DeviceType.Camera],
|
|
233725
234090
|
methods: {
|
|
233726
234091
|
listScenes: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), SceneMonitorStatusSchema),
|
|
234092
|
+
/**
|
|
234093
|
+
* The same answer, for a SET of cameras, in one round trip.
|
|
234094
|
+
*
|
|
234095
|
+
* `/scenes` renders every camera and re-reads them on a 30s safety-net
|
|
234096
|
+
* poll behind the push slice. Fanned out client-side that was one query
|
|
234097
|
+
* per camera — 29 round trips through the browser, the hub and the
|
|
234098
|
+
* post-analysis runner every 30 seconds to read an in-memory map the
|
|
234099
|
+
* owner had already merged. The work is unchanged (`statusFor` per
|
|
234100
|
+
* device, all in-process at the owner); what collapses is the transport.
|
|
234101
|
+
*
|
|
234102
|
+
* A camera that cannot answer still gets a row, with `status: null` —
|
|
234103
|
+
* see {@link SceneMonitorStatusForDeviceSchema}. Never fewer rows than
|
|
234104
|
+
* ids: a caller that asked for twenty-nine and got twenty-seven cannot
|
|
234105
|
+
* tell which two are missing, or that any are.
|
|
234106
|
+
*/
|
|
234107
|
+
listScenesBatch: require_sleep.method(zod.z.object({ deviceIds: zod.z.array(zod.z.number()).min(1).max(200) }), zod.z.array(SceneMonitorStatusForDeviceSchema).readonly()),
|
|
233727
234108
|
createScene: require_sleep.method(zod.z.object({
|
|
233728
234109
|
deviceId: zod.z.number(),
|
|
233729
234110
|
label: zod.z.string(),
|
|
@@ -235525,6 +235906,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
235525
235906
|
* than as repeated tracks/events. */
|
|
235526
235907
|
stationaryObjects: zod.z.array(StationaryObjectSchema).readonly().optional()
|
|
235527
235908
|
});
|
|
235909
|
+
var CameraOccupancySnapshotForDeviceSchema = zod.z.object({
|
|
235910
|
+
deviceId: zod.z.number(),
|
|
235911
|
+
read: zod.z.enum(["read", "unreadable"]),
|
|
235912
|
+
snapshot: CameraOccupancySnapshotSchema.nullable()
|
|
235913
|
+
});
|
|
235528
235914
|
var HistoryResolutionEnum = zod.z.enum([
|
|
235529
235915
|
"minute",
|
|
235530
235916
|
"5min",
|
|
@@ -235554,6 +235940,20 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
235554
235940
|
* (no inference result emitted since boot or since binding was
|
|
235555
235941
|
* activated). */
|
|
235556
235942
|
getCurrentSnapshot: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), CameraOccupancySnapshotSchema.nullable()),
|
|
235943
|
+
/**
|
|
235944
|
+
* The same snapshot, for a SET of cameras, in one round trip.
|
|
235945
|
+
*
|
|
235946
|
+
* The Events page's Stationary section polls this every 15s for every
|
|
235947
|
+
* selected camera. Fanned out client-side that is one query per camera to
|
|
235948
|
+
* read a `Map.get` at the owner — the answer costs nothing, the round trip
|
|
235949
|
+
* costs everything. Batched, N transports become one and the per-device
|
|
235950
|
+
* work is unchanged.
|
|
235951
|
+
*
|
|
235952
|
+
* Every requested deviceId gets a row, tagged `read` — see
|
|
235953
|
+
* {@link CameraOccupancySnapshotForDeviceSchema}. A camera the owner could
|
|
235954
|
+
* not answer for is `'unreadable'`, never an empty reading.
|
|
235955
|
+
*/
|
|
235956
|
+
getCurrentSnapshotBatch: require_sleep.method(zod.z.object({ deviceIds: zod.z.array(zod.z.number()).min(1).max(200) }), zod.z.array(CameraOccupancySnapshotForDeviceSchema).readonly()),
|
|
235557
235957
|
/** Time-series object count inside one zone. `className` optional —
|
|
235558
235958
|
* omit to count every class in the zone. */
|
|
235559
235959
|
getZoneHistory: require_sleep.method(zod.z.object({
|
|
@@ -242419,6 +242819,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
242419
242819
|
addonId: null,
|
|
242420
242820
|
access: "view"
|
|
242421
242821
|
},
|
|
242822
|
+
"pipelineAnalytics.getKeyEventsBatch": {
|
|
242823
|
+
capName: "pipeline-analytics",
|
|
242824
|
+
capScope: "device",
|
|
242825
|
+
addonId: null,
|
|
242826
|
+
access: "view"
|
|
242827
|
+
},
|
|
242422
242828
|
"pipelineAnalytics.getMotionEvents": {
|
|
242423
242829
|
capName: "pipeline-analytics",
|
|
242424
242830
|
capScope: "device",
|
|
@@ -243595,6 +244001,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
243595
244001
|
addonId: null,
|
|
243596
244002
|
access: "view"
|
|
243597
244003
|
},
|
|
244004
|
+
"recording.reconcileLedgerAgainstDisk": {
|
|
244005
|
+
capName: "recording",
|
|
244006
|
+
capScope: "system",
|
|
244007
|
+
addonId: null,
|
|
244008
|
+
access: "create"
|
|
244009
|
+
},
|
|
243598
244010
|
"recording.refreshStorageLocationsForMigration": {
|
|
243599
244011
|
capName: "recording",
|
|
243600
244012
|
capScope: "system",
|
|
@@ -243721,6 +244133,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
243721
244133
|
addonId: null,
|
|
243722
244134
|
access: "view"
|
|
243723
244135
|
},
|
|
244136
|
+
"sceneMonitor.listScenesBatch": {
|
|
244137
|
+
capName: "scene-monitor",
|
|
244138
|
+
capScope: "device",
|
|
244139
|
+
addonId: null,
|
|
244140
|
+
access: "view"
|
|
244141
|
+
},
|
|
243724
244142
|
"sceneMonitor.recheckNow": {
|
|
243725
244143
|
capName: "scene-monitor",
|
|
243726
244144
|
capScope: "device",
|
|
@@ -245077,6 +245495,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
245077
245495
|
addonId: null,
|
|
245078
245496
|
access: "view"
|
|
245079
245497
|
},
|
|
245498
|
+
"zoneAnalytics.getCurrentSnapshotBatch": {
|
|
245499
|
+
capName: "zone-analytics",
|
|
245500
|
+
capScope: "device",
|
|
245501
|
+
addonId: null,
|
|
245502
|
+
access: "view"
|
|
245503
|
+
},
|
|
245080
245504
|
"zoneAnalytics.getUnzonedHistory": {
|
|
245081
245505
|
capName: "zone-analytics",
|
|
245082
245506
|
capScope: "device",
|
|
@@ -246339,6 +246763,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
246339
246763
|
form: "single",
|
|
246340
246764
|
optional: false
|
|
246341
246765
|
}],
|
|
246766
|
+
"pipelineAnalytics.getKeyEventsBatch": [{
|
|
246767
|
+
name: "deviceIds",
|
|
246768
|
+
form: "array",
|
|
246769
|
+
optional: false
|
|
246770
|
+
}],
|
|
246342
246771
|
"pipelineAnalytics.getMotionEvents": [{
|
|
246343
246772
|
name: "deviceId",
|
|
246344
246773
|
form: "single",
|
|
@@ -246779,6 +247208,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
246779
247208
|
form: "single",
|
|
246780
247209
|
optional: false
|
|
246781
247210
|
}],
|
|
247211
|
+
"recording.reconcileLedgerAgainstDisk": [{
|
|
247212
|
+
name: "deviceId",
|
|
247213
|
+
form: "single",
|
|
247214
|
+
optional: true
|
|
247215
|
+
}],
|
|
246782
247216
|
"recording.relocateFootage": [{
|
|
246783
247217
|
name: "deviceId",
|
|
246784
247218
|
form: "single",
|
|
@@ -246844,6 +247278,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
246844
247278
|
form: "single",
|
|
246845
247279
|
optional: false
|
|
246846
247280
|
}],
|
|
247281
|
+
"sceneMonitor.listScenesBatch": [{
|
|
247282
|
+
name: "deviceIds",
|
|
247283
|
+
form: "array",
|
|
247284
|
+
optional: false
|
|
247285
|
+
}],
|
|
246847
247286
|
"sceneMonitor.recheckNow": [{
|
|
246848
247287
|
name: "deviceId",
|
|
246849
247288
|
form: "single",
|
|
@@ -247105,6 +247544,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
247105
247544
|
form: "single",
|
|
247106
247545
|
optional: false
|
|
247107
247546
|
}],
|
|
247547
|
+
"zoneAnalytics.getCurrentSnapshotBatch": [{
|
|
247548
|
+
name: "deviceIds",
|
|
247549
|
+
form: "array",
|
|
247550
|
+
optional: false
|
|
247551
|
+
}],
|
|
247108
247552
|
"zoneAnalytics.getUnzonedHistory": [{
|
|
247109
247553
|
name: "deviceId",
|
|
247110
247554
|
form: "single",
|
|
@@ -247257,6 +247701,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
247257
247701
|
"recording.readGopBytes",
|
|
247258
247702
|
"recording.readSegmentBytes",
|
|
247259
247703
|
"recording.readWindowBytes",
|
|
247704
|
+
"recording.reconcileLedgerAgainstDisk",
|
|
247260
247705
|
"recording.relocateFootage",
|
|
247261
247706
|
"recording.renderClip",
|
|
247262
247707
|
"recording.renderGif",
|
|
@@ -248142,6 +248587,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
248142
248587
|
relocateFootage: (input) => dispatch("recording", "relocateFootage", "mutation", input),
|
|
248143
248588
|
listRelocateJobs: (input) => dispatch("recording", "listRelocateJobs", "query", input),
|
|
248144
248589
|
getRelocateResidue: (input) => dispatch("recording", "getRelocateResidue", "query", input),
|
|
248590
|
+
reconcileLedgerAgainstDisk: (input) => dispatch("recording", "reconcileLedgerAgainstDisk", "mutation", input),
|
|
248145
248591
|
cancelRelocateJob: (input) => dispatch("recording", "cancelRelocateJob", "mutation", input),
|
|
248146
248592
|
planStorageRebalance: (input) => dispatch("recording", "planStorageRebalance", "query", input),
|
|
248147
248593
|
startStorageRebalance: (input) => dispatch("recording", "startStorageRebalance", "mutation", input)
|
|
@@ -251102,6 +251548,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
251102
251548
|
exports.CameraMetricsSchema = CameraMetricsSchema;
|
|
251103
251549
|
exports.CameraMetricsWithDeviceIdSchema = CameraMetricsWithDeviceIdSchema;
|
|
251104
251550
|
exports.CameraMotionStatusSchema = CameraMotionStatusSchema;
|
|
251551
|
+
exports.CameraOccupancySnapshotForDeviceSchema = CameraOccupancySnapshotForDeviceSchema;
|
|
251105
251552
|
exports.CameraRecordingModeSchema = CameraRecordingModeSchema;
|
|
251106
251553
|
exports.CameraRecordingStatusSchema = CameraRecordingStatusSchema;
|
|
251107
251554
|
exports.CameraSourceStatusSchema = CameraSourceStatusSchema;
|
|
@@ -251352,6 +251799,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
251352
251799
|
exports.LabelTierSchema = LabelTierSchema;
|
|
251353
251800
|
exports.LawnMowerActivitySchema = LawnMowerActivitySchema;
|
|
251354
251801
|
exports.LawnMowerControlStatusSchema = LawnMowerControlStatusSchema;
|
|
251802
|
+
exports.LedgerWalkDeviceReportSchema = LedgerWalkDeviceReportSchema;
|
|
251803
|
+
exports.LedgerWalkInputSchema = LedgerWalkInputSchema;
|
|
251804
|
+
exports.LedgerWalkRefusalSchema = LedgerWalkRefusalSchema;
|
|
251805
|
+
exports.LedgerWalkReportSchema = LedgerWalkReportSchema;
|
|
251806
|
+
exports.LedgerWalkSkipCountsSchema = LedgerWalkSkipCountsSchema;
|
|
251807
|
+
exports.LedgerWalkSkipReasonSchema = LedgerWalkSkipReasonSchema;
|
|
251355
251808
|
exports.LinkedDeviceSchema = LinkedDeviceSchema;
|
|
251356
251809
|
exports.LinkedDevicesModeSchema = LinkedDevicesModeSchema;
|
|
251357
251810
|
exports.ListGroupsPageSchema = ListGroupsPageSchema;
|
|
@@ -251773,6 +252226,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
251773
252226
|
exports.SceneConfirmSchema = SceneConfirmSchema;
|
|
251774
252227
|
exports.SceneMonitorSchema = SceneMonitorSchema;
|
|
251775
252228
|
exports.SceneMonitorStateSchema = SceneMonitorStateSchema;
|
|
252229
|
+
exports.SceneMonitorStatusForDeviceSchema = SceneMonitorStatusForDeviceSchema;
|
|
251776
252230
|
exports.SceneMonitorStatusSchema = SceneMonitorStatusSchema;
|
|
251777
252231
|
exports.SceneReferenceSchema = SceneReferenceSchema;
|
|
251778
252232
|
exports.SceneUnavailableSchema = SceneUnavailableSchema;
|
|
@@ -410593,6 +411047,7 @@ var require_cap_providers = __commonJS({
|
|
|
410593
411047
|
exports.buildSettingsStoreGateway = buildSettingsStoreGateway;
|
|
410594
411048
|
exports.buildNetworkQualityProvider = buildNetworkQualityProvider;
|
|
410595
411049
|
exports.buildToastProvider = buildToastProvider;
|
|
411050
|
+
exports.computeTopologyPass = computeTopologyPass;
|
|
410596
411051
|
exports.computeTopology = computeTopology;
|
|
410597
411052
|
exports.createNodeRootPackageLookup = createNodeRootPackageLookup;
|
|
410598
411053
|
exports.buildNodesProvider = buildNodesProvider;
|
|
@@ -410741,9 +411196,19 @@ var require_cap_providers = __commonJS({
|
|
|
410741
411196
|
}
|
|
410742
411197
|
return ips;
|
|
410743
411198
|
}
|
|
411199
|
+
async function computeTopologyPass(agentRegistry, addonRegistry, getNodeRootPackage) {
|
|
411200
|
+
const [nodes, liveNodes] = await computeTopologyInternal(agentRegistry, addonRegistry, getNodeRootPackage);
|
|
411201
|
+
return { nodes, liveNodes };
|
|
411202
|
+
}
|
|
410744
411203
|
async function computeTopology(agentRegistry, addonRegistry, getNodeRootPackage) {
|
|
410745
|
-
const nodes = await agentRegistry
|
|
410746
|
-
|
|
411204
|
+
const [nodes] = await computeTopologyInternal(agentRegistry, addonRegistry, getNodeRootPackage);
|
|
411205
|
+
return nodes;
|
|
411206
|
+
}
|
|
411207
|
+
async function computeTopologyInternal(agentRegistry, addonRegistry, getNodeRootPackage) {
|
|
411208
|
+
const [nodes, history] = await Promise.all([
|
|
411209
|
+
agentRegistry.listNodes(),
|
|
411210
|
+
agentRegistry.getClusterNodeHistory()
|
|
411211
|
+
]);
|
|
410747
411212
|
const historyById = new Map(history.map((h) => [h.id, h]));
|
|
410748
411213
|
const liveIds = new Set(nodes.map((n) => n.info.id));
|
|
410749
411214
|
const allAddons = addonRegistry?.listAddons() ?? [];
|
|
@@ -410898,7 +411363,7 @@ var require_cap_providers = __commonJS({
|
|
|
410898
411363
|
categories: [],
|
|
410899
411364
|
rootPackage: null
|
|
410900
411365
|
}));
|
|
410901
|
-
return [...liveNodes, ...offlineNodes];
|
|
411366
|
+
return [[...liveNodes, ...offlineNodes], nodes];
|
|
410902
411367
|
}
|
|
410903
411368
|
function createNodeRootPackageLookup(moleculer, serverUpdate) {
|
|
410904
411369
|
return (nodeId, isHub) => {
|
|
@@ -420624,6 +421089,19 @@ var require_agent_registry_service = __commonJS({
|
|
|
420624
421089
|
addonIds: [...entry.agentAddons ?? []]
|
|
420625
421090
|
};
|
|
420626
421091
|
}
|
|
421092
|
+
function toSubProcess(p) {
|
|
421093
|
+
return {
|
|
421094
|
+
pid: p.pid ?? 0,
|
|
421095
|
+
name: p.name ?? "",
|
|
421096
|
+
command: "moleculer-service",
|
|
421097
|
+
state: p.state ?? "running",
|
|
421098
|
+
cpuPercent: p.cpuPercent ?? 0,
|
|
421099
|
+
memoryRss: p.memoryRss ?? 0,
|
|
421100
|
+
uptimeSeconds: p.uptimeSeconds ?? 0,
|
|
421101
|
+
addonIds: p.addonIds ?? [],
|
|
421102
|
+
groupId: p.groupId ?? null
|
|
421103
|
+
};
|
|
421104
|
+
}
|
|
420627
421105
|
var AgentRegistryService = class {
|
|
420628
421106
|
eventBus;
|
|
420629
421107
|
moleculer;
|
|
@@ -421150,107 +421628,113 @@ var require_agent_registry_service = __commonJS({
|
|
|
421150
421628
|
return toNodeLiveness(this.moleculer.broker.registry.getNodeList({ onlyAvailable: false }));
|
|
421151
421629
|
}
|
|
421152
421630
|
async listNodes() {
|
|
421153
|
-
|
|
421631
|
+
const registry = this.moleculer.broker.registry;
|
|
421632
|
+
const nodes = registry?.getNodeList?.({ onlyAvailable: false }) ?? [];
|
|
421633
|
+
const remoteTargets = nodes.filter((node) => typeof node.id === "string" && node.id !== "hub" && !node.id.includes("/"));
|
|
421634
|
+
const [hubEntry, remoteEntries] = await Promise.all([
|
|
421635
|
+
this.listHubProcesses().then((procs) => this.buildHubEntry(procs)),
|
|
421636
|
+
Promise.all(remoteTargets.map((node) => node.available ? (
|
|
421637
|
+
// Online: one wave of `$agent.status` + `$process.list`.
|
|
421638
|
+
this.buildRemoteEntry(node.id)
|
|
421639
|
+
) : (
|
|
421640
|
+
// Offline: skip the RPC fan-out entirely (the node is unreachable —
|
|
421641
|
+
// those calls would just time out) and surface a minimal,
|
|
421642
|
+
// honestly-degraded row instead.
|
|
421643
|
+
Promise.resolve(this.buildOfflineEntry(node))
|
|
421644
|
+
)))
|
|
421645
|
+
]);
|
|
421646
|
+
return [hubEntry, ...remoteEntries.filter((entry) => entry !== null)];
|
|
421647
|
+
}
|
|
421648
|
+
/** The hub's own runner subprocesses (`$process.list`, hub-local). */
|
|
421649
|
+
async listHubProcesses() {
|
|
421154
421650
|
try {
|
|
421155
421651
|
const processes = await this.broker.call("$process.list");
|
|
421156
|
-
|
|
421157
|
-
pid: p.pid ?? 0,
|
|
421158
|
-
name: p.name ?? "",
|
|
421159
|
-
command: "moleculer-service",
|
|
421160
|
-
state: p.state ?? "running",
|
|
421161
|
-
cpuPercent: p.cpuPercent ?? 0,
|
|
421162
|
-
memoryRss: p.memoryRss ?? 0,
|
|
421163
|
-
uptimeSeconds: p.uptimeSeconds ?? 0,
|
|
421164
|
-
addonIds: p.addonIds ?? [],
|
|
421165
|
-
groupId: p.groupId ?? null
|
|
421166
|
-
}));
|
|
421652
|
+
return processes.map(toSubProcess);
|
|
421167
421653
|
} catch {
|
|
421654
|
+
return [];
|
|
421168
421655
|
}
|
|
421169
|
-
const hubEntry = await this.buildHubEntry(hubProcesses);
|
|
421170
|
-
const remoteEntries = [];
|
|
421171
|
-
const registry = this.moleculer.broker.registry;
|
|
421172
|
-
const nodes = registry?.getNodeList?.({ onlyAvailable: false }) ?? [];
|
|
421173
|
-
for (const node of nodes) {
|
|
421174
|
-
const nodeId = node.id;
|
|
421175
|
-
if (typeof nodeId !== "string" || nodeId === "hub" || nodeId.includes("/"))
|
|
421176
|
-
continue;
|
|
421177
|
-
if (!node.available) {
|
|
421178
|
-
remoteEntries.push(this.buildOfflineEntry(node));
|
|
421179
|
-
continue;
|
|
421180
|
-
}
|
|
421181
|
-
try {
|
|
421182
|
-
const status = await this.broker.call("$agent.status", {}, {
|
|
421183
|
-
nodeID: nodeId,
|
|
421184
|
-
timeout: 5e3
|
|
421185
|
-
});
|
|
421186
|
-
let subProcesses = [];
|
|
421187
|
-
try {
|
|
421188
|
-
const processes = await this.broker.call("$process.list", {}, {
|
|
421189
|
-
nodeID: nodeId,
|
|
421190
|
-
timeout: 5e3
|
|
421191
|
-
});
|
|
421192
|
-
subProcesses = processes.map((p) => ({
|
|
421193
|
-
pid: p.pid ?? 0,
|
|
421194
|
-
name: p.name ?? "",
|
|
421195
|
-
command: "moleculer-service",
|
|
421196
|
-
state: p.state ?? "running",
|
|
421197
|
-
cpuPercent: p.cpuPercent ?? 0,
|
|
421198
|
-
memoryRss: p.memoryRss ?? 0,
|
|
421199
|
-
uptimeSeconds: p.uptimeSeconds ?? 0,
|
|
421200
|
-
addonIds: p.addonIds ?? [],
|
|
421201
|
-
groupId: p.groupId ?? null
|
|
421202
|
-
}));
|
|
421203
|
-
} catch {
|
|
421204
|
-
subProcesses = status.addons?.map((a) => ({
|
|
421205
|
-
pid: 0,
|
|
421206
|
-
name: a.id ?? "",
|
|
421207
|
-
command: "moleculer-service",
|
|
421208
|
-
state: a.status ?? "running",
|
|
421209
|
-
cpuPercent: 0,
|
|
421210
|
-
memoryRss: 0,
|
|
421211
|
-
uptimeSeconds: 0
|
|
421212
|
-
})) ?? [];
|
|
421213
|
-
}
|
|
421214
|
-
const agentAddons = status.addons?.map((a) => a.id) ?? [];
|
|
421215
|
-
const hostname = typeof status.hostname === "string" ? status.hostname : null;
|
|
421216
|
-
const agentName = typeof status.name === "string" ? status.name : nodeId;
|
|
421217
|
-
remoteEntries.push({
|
|
421218
|
-
info: {
|
|
421219
|
-
id: nodeId,
|
|
421220
|
-
name: agentName,
|
|
421221
|
-
hostname: hostname ?? nodeId,
|
|
421222
|
-
capabilities: [],
|
|
421223
|
-
platform: status.platform ?? "unknown",
|
|
421224
|
-
arch: status.arch ?? "unknown",
|
|
421225
|
-
cpuCores: status.cpuCores ?? 0,
|
|
421226
|
-
memoryMB: status.totalMemoryMB ?? 0,
|
|
421227
|
-
cpuModel: status.cpuModel
|
|
421228
|
-
},
|
|
421229
|
-
localIps: Array.isArray(status.localIps) ? status.localIps : [],
|
|
421230
|
-
status: {
|
|
421231
|
-
activeCameras: 0,
|
|
421232
|
-
cpuPercent: status.cpuPercent ?? 0,
|
|
421233
|
-
memoryPercent: status.memoryPercent ?? 0,
|
|
421234
|
-
fps: {},
|
|
421235
|
-
errors: []
|
|
421236
|
-
},
|
|
421237
|
-
connectedSince: typeof status.uptime === "number" ? Date.now() - status.uptime * 1e3 : Date.now(),
|
|
421238
|
-
isHub: false,
|
|
421239
|
-
subProcesses,
|
|
421240
|
-
agentAddons
|
|
421241
|
-
});
|
|
421242
|
-
} catch {
|
|
421243
|
-
}
|
|
421244
|
-
}
|
|
421245
|
-
await this.snapshotOnlineNodes([hubEntry, ...remoteEntries]);
|
|
421246
|
-
return [hubEntry, ...remoteEntries];
|
|
421247
421656
|
}
|
|
421248
421657
|
/**
|
|
421249
|
-
*
|
|
421250
|
-
*
|
|
421251
|
-
* `
|
|
421658
|
+
* One online agent's row: `$agent.status` for the descriptor + live metrics,
|
|
421659
|
+
* `$process.list` for real sub-process stats. `null` when the node has no
|
|
421660
|
+
* `$agent` service (it is then simply absent from the list, as before).
|
|
421661
|
+
*
|
|
421662
|
+
* The two calls are ONE wave, not two: `$process.list` never reads anything
|
|
421663
|
+
* from `$agent.status` — only its FALLBACK does, and the fallback is applied
|
|
421664
|
+
* after both have settled.
|
|
421665
|
+
*/
|
|
421666
|
+
async buildRemoteEntry(nodeId) {
|
|
421667
|
+
const [statusResult, processResult] = await Promise.allSettled([
|
|
421668
|
+
this.broker.call("$agent.status", {}, { nodeID: nodeId, timeout: 5e3 }),
|
|
421669
|
+
this.broker.call("$process.list", {}, { nodeID: nodeId, timeout: 5e3 })
|
|
421670
|
+
]);
|
|
421671
|
+
if (statusResult.status === "rejected")
|
|
421672
|
+
return null;
|
|
421673
|
+
const status = statusResult.value;
|
|
421674
|
+
const subProcesses = processResult.status === "fulfilled" ? processResult.value.map(toSubProcess) : (
|
|
421675
|
+
// Fall back to the addon list from $agent.status (no stats)
|
|
421676
|
+
status.addons?.map((a) => ({
|
|
421677
|
+
pid: 0,
|
|
421678
|
+
name: a.id ?? "",
|
|
421679
|
+
command: "moleculer-service",
|
|
421680
|
+
state: a.status ?? "running",
|
|
421681
|
+
cpuPercent: 0,
|
|
421682
|
+
memoryRss: 0,
|
|
421683
|
+
uptimeSeconds: 0
|
|
421684
|
+
})) ?? []
|
|
421685
|
+
);
|
|
421686
|
+
const agentAddons = status.addons?.map((a) => a.id) ?? [];
|
|
421687
|
+
const hostname = typeof status.hostname === "string" ? status.hostname : null;
|
|
421688
|
+
const agentName = typeof status.name === "string" ? status.name : nodeId;
|
|
421689
|
+
return {
|
|
421690
|
+
info: {
|
|
421691
|
+
id: nodeId,
|
|
421692
|
+
name: agentName,
|
|
421693
|
+
hostname: hostname ?? nodeId,
|
|
421694
|
+
capabilities: [],
|
|
421695
|
+
platform: status.platform ?? "unknown",
|
|
421696
|
+
arch: status.arch ?? "unknown",
|
|
421697
|
+
cpuCores: status.cpuCores ?? 0,
|
|
421698
|
+
memoryMB: status.totalMemoryMB ?? 0,
|
|
421699
|
+
cpuModel: status.cpuModel
|
|
421700
|
+
},
|
|
421701
|
+
localIps: Array.isArray(status.localIps) ? status.localIps : [],
|
|
421702
|
+
status: {
|
|
421703
|
+
activeCameras: 0,
|
|
421704
|
+
cpuPercent: status.cpuPercent ?? 0,
|
|
421705
|
+
memoryPercent: status.memoryPercent ?? 0,
|
|
421706
|
+
fps: {},
|
|
421707
|
+
errors: []
|
|
421708
|
+
},
|
|
421709
|
+
connectedSince: typeof status.uptime === "number" ? Date.now() - status.uptime * 1e3 : Date.now(),
|
|
421710
|
+
isHub: false,
|
|
421711
|
+
subProcesses,
|
|
421712
|
+
agentAddons
|
|
421713
|
+
};
|
|
421714
|
+
}
|
|
421715
|
+
/**
|
|
421716
|
+
* A1 (R2 capture point): snapshot every ONLINE node's static descriptor +
|
|
421717
|
+
* last-known addon roster into the durable, routing-blind history store.
|
|
421718
|
+
* This is the ONLY place cpuModel/cores/memory/localIps are resolved from a
|
|
421719
|
+
* live `$agent.status`, so it is where an offline row's descriptor must be
|
|
421720
|
+
* captured while the node is still reachable. Offline entries are NOT
|
|
421721
|
+
* re-snapshotted — their `lastActive` is stamped on `$node.disconnected`
|
|
421722
|
+
* instead. This is a separate durable store, never a `knownAgents`-style
|
|
421723
|
+
* shadow of `HubNodeRegistry` (which stays the ephemeral live cap authority).
|
|
421724
|
+
*
|
|
421725
|
+
* **It belongs to the PERIODIC PASS, not to a read** (D317). It used to run
|
|
421726
|
+
* at the tail of `listNodes()`, which made every operator poll of
|
|
421727
|
+
* `nodes.topology` perform one durable read-back — and, past the five-minute
|
|
421728
|
+
* heartbeat, one durable write — per online node, in a phase that had to
|
|
421729
|
+
* finish before the history read could even start. Measured on the live hub
|
|
421730
|
+
* on 2026-08-31: one settings-store round trip cost 14.8–18.3 s and
|
|
421731
|
+
* `nodes.topology` cost exactly two of them, 30.5 s. `TopologyEmitterService`
|
|
421732
|
+
* already recomputes this picture every 30 s; the capture is its work.
|
|
421733
|
+
*
|
|
421734
|
+
* Never throws — the store swallows its own errors and this awaits
|
|
421735
|
+
* `allSettled` so a storage hiccup can never fail the pass.
|
|
421252
421736
|
*/
|
|
421253
|
-
async
|
|
421737
|
+
async captureNodeHistory(entries) {
|
|
421254
421738
|
if (!this.historyStore)
|
|
421255
421739
|
return;
|
|
421256
421740
|
const online = entries.filter((e) => e.isOnline !== false);
|
|
@@ -423900,7 +424384,7 @@ var require_topology_emitter_service = __commonJS({
|
|
|
423900
424384
|
return;
|
|
423901
424385
|
this.emitting = true;
|
|
423902
424386
|
try {
|
|
423903
|
-
const nodes = await (0, cap_providers_1.
|
|
424387
|
+
const { nodes, liveNodes } = await (0, cap_providers_1.computeTopologyPass)(this.agentRegistry, this.addonRegistry, this.getNodeRootPackage);
|
|
423904
424388
|
this.eventBus.emit({
|
|
423905
424389
|
id: (0, node_crypto_1.randomUUID)(),
|
|
423906
424390
|
timestamp: /* @__PURE__ */ new Date(),
|
|
@@ -423908,6 +424392,7 @@ var require_topology_emitter_service = __commonJS({
|
|
|
423908
424392
|
category: types_1.EventCategory.ClusterTopologySnapshot,
|
|
423909
424393
|
data: { nodes, timestamp: Date.now() }
|
|
423910
424394
|
});
|
|
424395
|
+
await this.agentRegistry.captureNodeHistory(liveNodes);
|
|
423911
424396
|
} catch {
|
|
423912
424397
|
} finally {
|
|
423913
424398
|
this.emitting = false;
|