camstack 1.2.68 → 1.2.70
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-BhE8zNfY.js
|
|
23637
|
+
var require_dist_BhE8zNfY = __commonJS({
|
|
23638
|
+
"../system/dist/dist-BhE8zNfY.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(),
|
|
@@ -37190,6 +37286,39 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
37190
37286
|
/** Present when the pass ended by throwing. */
|
|
37191
37287
|
error: zod.z.string().nullable()
|
|
37192
37288
|
});
|
|
37289
|
+
var MediaReclaimStartResultSchema = zod.z.object({
|
|
37290
|
+
started: zod.z.boolean(),
|
|
37291
|
+
/** True when a pass was already running; the new request is ignored. */
|
|
37292
|
+
alreadyRunning: zod.z.boolean()
|
|
37293
|
+
});
|
|
37294
|
+
var MediaReclaimInputSchema = zod.z.object({
|
|
37295
|
+
mode: zod.z.enum(["report", "reclaim"]).default("report"),
|
|
37296
|
+
scopes: zod.z.array(zod.z.enum(["motion-still", "track-filmstrip"])).min(1).optional(),
|
|
37297
|
+
deviceIds: zod.z.array(zod.z.number().int()).min(1).optional(),
|
|
37298
|
+
restart: zod.z.boolean().optional(),
|
|
37299
|
+
pageSize: zod.z.number().int().min(50).max(5e3).optional(),
|
|
37300
|
+
maxRowsPerDevice: zod.z.number().int().min(1).max(5e5).optional(),
|
|
37301
|
+
maxReclaimPerDevice: zod.z.number().int().min(1).max(5e5).optional(),
|
|
37302
|
+
maxBytesPerRun: zod.z.number().int().min(1).optional(),
|
|
37303
|
+
budgetMinutes: zod.z.number().int().min(1).max(720).optional(),
|
|
37304
|
+
throttleBytesPerSec: zod.z.number().int().min(64 * 1024).optional(),
|
|
37305
|
+
graceMinutes: zod.z.number().int().min(1).max(10080).optional()
|
|
37306
|
+
});
|
|
37307
|
+
var MediaReclaimStatusSchema = zod.z.object({
|
|
37308
|
+
running: zod.z.boolean(),
|
|
37309
|
+
mode: zod.z.enum(["report", "reclaim"]).nullable(),
|
|
37310
|
+
totalExamined: zod.z.number(),
|
|
37311
|
+
totalEligible: zod.z.number(),
|
|
37312
|
+
totalReclaimed: zod.z.number(),
|
|
37313
|
+
totalBytesReclaimed: zod.z.number(),
|
|
37314
|
+
totalRefused: zod.z.number(),
|
|
37315
|
+
/** Device+scope windows finished in this pass. */
|
|
37316
|
+
devicesDone: zod.z.number(),
|
|
37317
|
+
complete: zod.z.boolean().nullable(),
|
|
37318
|
+
startedAtMs: zod.z.number().nullable(),
|
|
37319
|
+
finishedAtMs: zod.z.number().nullable(),
|
|
37320
|
+
error: zod.z.string().nullable()
|
|
37321
|
+
});
|
|
37193
37322
|
var ReplayFrameInputSchema = zod.z.object({
|
|
37194
37323
|
timestamp: zod.z.number(),
|
|
37195
37324
|
frame: PipelineRunResultBridge
|
|
@@ -37320,6 +37449,21 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
37320
37449
|
* scored on-read (no write). Degrades to `[]` on error.
|
|
37321
37450
|
*/
|
|
37322
37451
|
getKeyEvents: method(KeyEventQueryInput, zod.z.array(KeyEventSchema).readonly()),
|
|
37452
|
+
/**
|
|
37453
|
+
* The same ranking, for a SET of cameras, in one round trip.
|
|
37454
|
+
*
|
|
37455
|
+
* The Detection Intelligence events feed asks this of every selected
|
|
37456
|
+
* camera and re-asks on a 30s timer. Fanned out client-side that is N
|
|
37457
|
+
* round trips — browser → hub → post-analysis — for N independent,
|
|
37458
|
+
* already-indexed store queries. Batched, the queries are unchanged and
|
|
37459
|
+
* run concurrently INSIDE the owner; only the transport collapses.
|
|
37460
|
+
*
|
|
37461
|
+
* Deliberately per-device rather than pre-merged: `limit` stays per
|
|
37462
|
+
* camera (a total would let a busy camera starve a quiet one), and a
|
|
37463
|
+
* caller that renders one camera's lane needs to know which camera a row
|
|
37464
|
+
* came from. `getKeyEvents` stays for single-device callers.
|
|
37465
|
+
*/
|
|
37466
|
+
getKeyEventsBatch: method(KeyEventBatchQueryInput, zod.z.array(KeyEventsForDeviceSchema).readonly()),
|
|
37323
37467
|
/** Server-side bucketed event counts for the 24-hour timeline.
|
|
37324
37468
|
* Returns one entry per non-empty bucket; empty buckets are omitted. */
|
|
37325
37469
|
getEventDensity: method(zod.z.object({
|
|
@@ -37598,6 +37742,20 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
37598
37742
|
auth: "admin"
|
|
37599
37743
|
}),
|
|
37600
37744
|
/**
|
|
37745
|
+
* Reclaim the standing debug-media backlog (motion-visit stills + track
|
|
37746
|
+
* filmstrips). DETACHED: returns `{ started }` immediately. The pass is
|
|
37747
|
+
* tens of minutes; awaiting it is a timeout, not a verdict. Dry-run unless
|
|
37748
|
+
* `mode: 'reclaim'`. Poll `getMediaReclaimStatus`.
|
|
37749
|
+
*/
|
|
37750
|
+
reclaimDebugMedia: method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
|
|
37751
|
+
kind: "mutation",
|
|
37752
|
+
auth: "admin"
|
|
37753
|
+
}),
|
|
37754
|
+
getMediaReclaimStatus: method(zod.z.object({}), MediaReclaimStatusSchema, {
|
|
37755
|
+
kind: "query",
|
|
37756
|
+
auth: "admin"
|
|
37757
|
+
}),
|
|
37758
|
+
/**
|
|
37601
37759
|
* The CHEAP QUESTION, asked before any media moves: how big is the dataset
|
|
37602
37760
|
* the marked (`markForTrain`) tracks would produce?
|
|
37603
37761
|
*
|
|
@@ -47264,6 +47422,23 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
47264
47422
|
kind: "query",
|
|
47265
47423
|
auth: "admin"
|
|
47266
47424
|
}),
|
|
47425
|
+
/**
|
|
47426
|
+
* Does this location's LEDGER tell the truth about its disk? (D319)
|
|
47427
|
+
*
|
|
47428
|
+
* One `readdir` per claimed hour, diffed both ways: durable rows whose file
|
|
47429
|
+
* is not there, and files no durable row names. `apply` defaults to FALSE —
|
|
47430
|
+
* the report is the product, and the dry run is how an operator
|
|
47431
|
+
* sanity-checks the destructive run before authorising it.
|
|
47432
|
+
*
|
|
47433
|
+
* REFUSES a source that is still a write target: a listing of a live
|
|
47434
|
+
* location is a lower bound, which is not the strong evidence that lets
|
|
47435
|
+
* this pass forget without a budget. A live location is reconciled by the
|
|
47436
|
+
* mover, under D318's bound.
|
|
47437
|
+
*/
|
|
47438
|
+
reconcileLedgerAgainstDisk: method(LedgerWalkInputSchema, LedgerWalkReportSchema, {
|
|
47439
|
+
kind: "mutation",
|
|
47440
|
+
auth: "admin"
|
|
47441
|
+
}),
|
|
47267
47442
|
/** Cancel a running or queued relocate job. A queued job never runs. */
|
|
47268
47443
|
cancelRelocateJob: method(zod.z.object({ jobId: zod.z.string() }), zod.z.object({ cancelled: zod.z.boolean() }), {
|
|
47269
47444
|
kind: "mutation",
|
|
@@ -47561,6 +47736,10 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
47561
47736
|
monitors: zod.z.array(SceneMonitorSchema),
|
|
47562
47737
|
lastFetchedAt: zod.z.number()
|
|
47563
47738
|
});
|
|
47739
|
+
var SceneMonitorStatusForDeviceSchema = zod.z.object({
|
|
47740
|
+
deviceId: zod.z.number(),
|
|
47741
|
+
status: SceneMonitorStatusSchema.nullable()
|
|
47742
|
+
});
|
|
47564
47743
|
var sceneMonitorCapability = {
|
|
47565
47744
|
name: "scene-monitor",
|
|
47566
47745
|
scope: "device",
|
|
@@ -47570,6 +47749,22 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
47570
47749
|
deviceTypes: [DeviceType.Camera],
|
|
47571
47750
|
methods: {
|
|
47572
47751
|
listScenes: method(zod.z.object({ deviceId: zod.z.number() }), SceneMonitorStatusSchema),
|
|
47752
|
+
/**
|
|
47753
|
+
* The same answer, for a SET of cameras, in one round trip.
|
|
47754
|
+
*
|
|
47755
|
+
* `/scenes` renders every camera and re-reads them on a 30s safety-net
|
|
47756
|
+
* poll behind the push slice. Fanned out client-side that was one query
|
|
47757
|
+
* per camera — 29 round trips through the browser, the hub and the
|
|
47758
|
+
* post-analysis runner every 30 seconds to read an in-memory map the
|
|
47759
|
+
* owner had already merged. The work is unchanged (`statusFor` per
|
|
47760
|
+
* device, all in-process at the owner); what collapses is the transport.
|
|
47761
|
+
*
|
|
47762
|
+
* A camera that cannot answer still gets a row, with `status: null` —
|
|
47763
|
+
* see {@link SceneMonitorStatusForDeviceSchema}. Never fewer rows than
|
|
47764
|
+
* ids: a caller that asked for twenty-nine and got twenty-seven cannot
|
|
47765
|
+
* tell which two are missing, or that any are.
|
|
47766
|
+
*/
|
|
47767
|
+
listScenesBatch: method(zod.z.object({ deviceIds: zod.z.array(zod.z.number()).min(1).max(200) }), zod.z.array(SceneMonitorStatusForDeviceSchema).readonly()),
|
|
47573
47768
|
createScene: method(zod.z.object({
|
|
47574
47769
|
deviceId: zod.z.number(),
|
|
47575
47770
|
label: zod.z.string(),
|
|
@@ -49370,6 +49565,11 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
49370
49565
|
* than as repeated tracks/events. */
|
|
49371
49566
|
stationaryObjects: zod.z.array(StationaryObjectSchema).readonly().optional()
|
|
49372
49567
|
});
|
|
49568
|
+
var CameraOccupancySnapshotForDeviceSchema = zod.z.object({
|
|
49569
|
+
deviceId: zod.z.number(),
|
|
49570
|
+
read: zod.z.enum(["read", "unreadable"]),
|
|
49571
|
+
snapshot: CameraOccupancySnapshotSchema.nullable()
|
|
49572
|
+
});
|
|
49373
49573
|
var HistoryResolutionEnum = zod.z.enum([
|
|
49374
49574
|
"minute",
|
|
49375
49575
|
"5min",
|
|
@@ -49399,6 +49599,20 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
49399
49599
|
* (no inference result emitted since boot or since binding was
|
|
49400
49600
|
* activated). */
|
|
49401
49601
|
getCurrentSnapshot: method(zod.z.object({ deviceId: zod.z.number() }), CameraOccupancySnapshotSchema.nullable()),
|
|
49602
|
+
/**
|
|
49603
|
+
* The same snapshot, for a SET of cameras, in one round trip.
|
|
49604
|
+
*
|
|
49605
|
+
* The Events page's Stationary section polls this every 15s for every
|
|
49606
|
+
* selected camera. Fanned out client-side that is one query per camera to
|
|
49607
|
+
* read a `Map.get` at the owner — the answer costs nothing, the round trip
|
|
49608
|
+
* costs everything. Batched, N transports become one and the per-device
|
|
49609
|
+
* work is unchanged.
|
|
49610
|
+
*
|
|
49611
|
+
* Every requested deviceId gets a row, tagged `read` — see
|
|
49612
|
+
* {@link CameraOccupancySnapshotForDeviceSchema}. A camera the owner could
|
|
49613
|
+
* not answer for is `'unreadable'`, never an empty reading.
|
|
49614
|
+
*/
|
|
49615
|
+
getCurrentSnapshotBatch: method(zod.z.object({ deviceIds: zod.z.array(zod.z.number()).min(1).max(200) }), zod.z.array(CameraOccupancySnapshotForDeviceSchema).readonly()),
|
|
49402
49616
|
/** Time-series object count inside one zone. `className` optional —
|
|
49403
49617
|
* omit to count every class in the zone. */
|
|
49404
49618
|
getZoneHistory: method(zod.z.object({
|
|
@@ -53346,6 +53560,18 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
53346
53560
|
addonId: null,
|
|
53347
53561
|
access: "view"
|
|
53348
53562
|
},
|
|
53563
|
+
"pipelineAnalytics.getKeyEventsBatch": {
|
|
53564
|
+
capName: "pipeline-analytics",
|
|
53565
|
+
capScope: "device",
|
|
53566
|
+
addonId: null,
|
|
53567
|
+
access: "view"
|
|
53568
|
+
},
|
|
53569
|
+
"pipelineAnalytics.getMediaReclaimStatus": {
|
|
53570
|
+
capName: "pipeline-analytics",
|
|
53571
|
+
capScope: "device",
|
|
53572
|
+
addonId: null,
|
|
53573
|
+
access: "view"
|
|
53574
|
+
},
|
|
53349
53575
|
"pipelineAnalytics.getMotionEvents": {
|
|
53350
53576
|
capName: "pipeline-analytics",
|
|
53351
53577
|
capScope: "device",
|
|
@@ -53520,6 +53746,12 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
53520
53746
|
addonId: null,
|
|
53521
53747
|
access: "create"
|
|
53522
53748
|
},
|
|
53749
|
+
"pipelineAnalytics.reclaimDebugMedia": {
|
|
53750
|
+
capName: "pipeline-analytics",
|
|
53751
|
+
capScope: "device",
|
|
53752
|
+
addonId: null,
|
|
53753
|
+
access: "create"
|
|
53754
|
+
},
|
|
53523
53755
|
"pipelineAnalytics.reconcileFromDisk": {
|
|
53524
53756
|
capName: "pipeline-analytics",
|
|
53525
53757
|
capScope: "device",
|
|
@@ -54522,6 +54754,12 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
54522
54754
|
addonId: null,
|
|
54523
54755
|
access: "view"
|
|
54524
54756
|
},
|
|
54757
|
+
"recording.reconcileLedgerAgainstDisk": {
|
|
54758
|
+
capName: "recording",
|
|
54759
|
+
capScope: "system",
|
|
54760
|
+
addonId: null,
|
|
54761
|
+
access: "create"
|
|
54762
|
+
},
|
|
54525
54763
|
"recording.refreshStorageLocationsForMigration": {
|
|
54526
54764
|
capName: "recording",
|
|
54527
54765
|
capScope: "system",
|
|
@@ -54648,6 +54886,12 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
54648
54886
|
addonId: null,
|
|
54649
54887
|
access: "view"
|
|
54650
54888
|
},
|
|
54889
|
+
"sceneMonitor.listScenesBatch": {
|
|
54890
|
+
capName: "scene-monitor",
|
|
54891
|
+
capScope: "device",
|
|
54892
|
+
addonId: null,
|
|
54893
|
+
access: "view"
|
|
54894
|
+
},
|
|
54651
54895
|
"sceneMonitor.recheckNow": {
|
|
54652
54896
|
capName: "scene-monitor",
|
|
54653
54897
|
capScope: "device",
|
|
@@ -56004,6 +56248,12 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
56004
56248
|
addonId: null,
|
|
56005
56249
|
access: "view"
|
|
56006
56250
|
},
|
|
56251
|
+
"zoneAnalytics.getCurrentSnapshotBatch": {
|
|
56252
|
+
capName: "zone-analytics",
|
|
56253
|
+
capScope: "device",
|
|
56254
|
+
addonId: null,
|
|
56255
|
+
access: "view"
|
|
56256
|
+
},
|
|
56007
56257
|
"zoneAnalytics.getUnzonedHistory": {
|
|
56008
56258
|
capName: "zone-analytics",
|
|
56009
56259
|
capScope: "device",
|
|
@@ -57008,6 +57258,11 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
57008
57258
|
form: "single",
|
|
57009
57259
|
optional: false
|
|
57010
57260
|
}],
|
|
57261
|
+
"pipelineAnalytics.getKeyEventsBatch": [{
|
|
57262
|
+
name: "deviceIds",
|
|
57263
|
+
form: "array",
|
|
57264
|
+
optional: false
|
|
57265
|
+
}],
|
|
57011
57266
|
"pipelineAnalytics.getMotionEvents": [{
|
|
57012
57267
|
name: "deviceId",
|
|
57013
57268
|
form: "single",
|
|
@@ -57113,6 +57368,11 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
57113
57368
|
form: "single",
|
|
57114
57369
|
optional: true
|
|
57115
57370
|
}],
|
|
57371
|
+
"pipelineAnalytics.reclaimDebugMedia": [{
|
|
57372
|
+
name: "deviceIds",
|
|
57373
|
+
form: "array",
|
|
57374
|
+
optional: true
|
|
57375
|
+
}],
|
|
57116
57376
|
"pipelineAnalytics.reconcileFromDisk": [{
|
|
57117
57377
|
name: "deviceId",
|
|
57118
57378
|
form: "single",
|
|
@@ -57448,6 +57708,11 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
57448
57708
|
form: "single",
|
|
57449
57709
|
optional: false
|
|
57450
57710
|
}],
|
|
57711
|
+
"recording.reconcileLedgerAgainstDisk": [{
|
|
57712
|
+
name: "deviceId",
|
|
57713
|
+
form: "single",
|
|
57714
|
+
optional: true
|
|
57715
|
+
}],
|
|
57451
57716
|
"recording.relocateFootage": [{
|
|
57452
57717
|
name: "deviceId",
|
|
57453
57718
|
form: "single",
|
|
@@ -57513,6 +57778,11 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
57513
57778
|
form: "single",
|
|
57514
57779
|
optional: false
|
|
57515
57780
|
}],
|
|
57781
|
+
"sceneMonitor.listScenesBatch": [{
|
|
57782
|
+
name: "deviceIds",
|
|
57783
|
+
form: "array",
|
|
57784
|
+
optional: false
|
|
57785
|
+
}],
|
|
57516
57786
|
"sceneMonitor.recheckNow": [{
|
|
57517
57787
|
name: "deviceId",
|
|
57518
57788
|
form: "single",
|
|
@@ -57774,6 +58044,11 @@ var require_dist_CCIBlacf = __commonJS({
|
|
|
57774
58044
|
form: "single",
|
|
57775
58045
|
optional: false
|
|
57776
58046
|
}],
|
|
58047
|
+
"zoneAnalytics.getCurrentSnapshotBatch": [{
|
|
58048
|
+
name: "deviceIds",
|
|
58049
|
+
form: "array",
|
|
58050
|
+
optional: false
|
|
58051
|
+
}],
|
|
57777
58052
|
"zoneAnalytics.getUnzonedHistory": [{
|
|
57778
58053
|
name: "deviceId",
|
|
57779
58054
|
form: "single",
|
|
@@ -59207,7 +59482,7 @@ var require_alerts_addon = __commonJS({
|
|
|
59207
59482
|
[Symbol.toStringTag]: { value: "Module" }
|
|
59208
59483
|
});
|
|
59209
59484
|
require_chunk_Cek0wNdY();
|
|
59210
|
-
var require_dist10 =
|
|
59485
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
59211
59486
|
function selectExpired(alerts, cutoffMs) {
|
|
59212
59487
|
return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
|
|
59213
59488
|
}
|
|
@@ -60026,7 +60301,7 @@ var require_console_logging = __commonJS({
|
|
|
60026
60301
|
[Symbol.toStringTag]: { value: "Module" }
|
|
60027
60302
|
});
|
|
60028
60303
|
require_chunk_Cek0wNdY();
|
|
60029
|
-
var require_dist10 =
|
|
60304
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
60030
60305
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
60031
60306
|
var LEVEL_RANK = {
|
|
60032
60307
|
debug: 0,
|
|
@@ -60120,7 +60395,7 @@ var require_core_blocks_addon = __commonJS({
|
|
|
60120
60395
|
"use strict";
|
|
60121
60396
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
60122
60397
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
60123
|
-
var require_dist10 =
|
|
60398
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
60124
60399
|
var node_crypto = __require("crypto");
|
|
60125
60400
|
var node_fs_promises = __require("fs/promises");
|
|
60126
60401
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -61017,11 +61292,11 @@ var require_core_blocks = __commonJS({
|
|
|
61017
61292
|
}
|
|
61018
61293
|
});
|
|
61019
61294
|
|
|
61020
|
-
// ../system/dist/retired-settings-keys-
|
|
61021
|
-
var
|
|
61022
|
-
"../system/dist/retired-settings-keys-
|
|
61295
|
+
// ../system/dist/retired-settings-keys-CqDbI-vK.js
|
|
61296
|
+
var require_retired_settings_keys_CqDbI_vK = __commonJS({
|
|
61297
|
+
"../system/dist/retired-settings-keys-CqDbI-vK.js"(exports) {
|
|
61023
61298
|
"use strict";
|
|
61024
|
-
var require_dist10 =
|
|
61299
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
61025
61300
|
function settingsStoreIsAuthoritativeHere(env) {
|
|
61026
61301
|
const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
|
|
61027
61302
|
return raw === "" || raw === "hub";
|
|
@@ -63235,8 +63510,8 @@ var require_device_manager_addon = __commonJS({
|
|
|
63235
63510
|
[Symbol.toStringTag]: { value: "Module" }
|
|
63236
63511
|
});
|
|
63237
63512
|
require_chunk_Cek0wNdY();
|
|
63238
|
-
var require_dist10 =
|
|
63239
|
-
var require_retired_settings_keys =
|
|
63513
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
63514
|
+
var require_retired_settings_keys = require_retired_settings_keys_CqDbI_vK();
|
|
63240
63515
|
var node_crypto = __require("crypto");
|
|
63241
63516
|
var _camstack_types_node = require_node();
|
|
63242
63517
|
var JOB_HISTORY = 20;
|
|
@@ -64214,6 +64489,9 @@ var require_device_manager_addon = __commonJS({
|
|
|
64214
64489
|
for (const f of features) if (DEVICE_FEATURE_VALUES.has(f)) out.push(f);
|
|
64215
64490
|
return out;
|
|
64216
64491
|
}
|
|
64492
|
+
function persistedIsCamera(type) {
|
|
64493
|
+
return type === require_dist10.DeviceType.Camera;
|
|
64494
|
+
}
|
|
64217
64495
|
function buildSourceInfoFromConfig(persistedConfig, stableId, addonId) {
|
|
64218
64496
|
const id = typeof persistedConfig["entityId"] === "string" ? persistedConfig["entityId"] : void 0;
|
|
64219
64497
|
const system = typeof persistedConfig["system"] === "string" ? persistedConfig["system"] : void 0;
|
|
@@ -64360,7 +64638,7 @@ var require_device_manager_addon = __commonJS({
|
|
|
64360
64638
|
online: pctx.host.resolveDeviceOnline(m.id, pctx.registry !== null),
|
|
64361
64639
|
probed: pctx.host.resolveDeviceProbed(m.id),
|
|
64362
64640
|
features: persistedFeatures(m.features),
|
|
64363
|
-
isCamera: persistedType
|
|
64641
|
+
isCamera: persistedIsCamera(persistedType),
|
|
64364
64642
|
config: persistedConfig ?? {},
|
|
64365
64643
|
metadata,
|
|
64366
64644
|
...m.integrationId !== void 0 ? { integrationId: m.integrationId } : {},
|
|
@@ -64405,7 +64683,7 @@ var require_device_manager_addon = __commonJS({
|
|
|
64405
64683
|
online: pctx.host.resolveDeviceOnline(deviceId, true),
|
|
64406
64684
|
probed: pctx.host.resolveDeviceProbed(deviceId),
|
|
64407
64685
|
features: persistedFeatures(m.features),
|
|
64408
|
-
isCamera:
|
|
64686
|
+
isCamera: persistedIsCamera(m.type),
|
|
64409
64687
|
config: persistedConfig ?? {},
|
|
64410
64688
|
metadata,
|
|
64411
64689
|
...m.integrationId !== void 0 ? { integrationId: m.integrationId } : {},
|
|
@@ -64453,7 +64731,7 @@ var require_device_manager_addon = __commonJS({
|
|
|
64453
64731
|
online: pctx.host.resolveDeviceOnline(m.id, pctx.registry !== null),
|
|
64454
64732
|
probed: pctx.host.resolveDeviceProbed(m.id),
|
|
64455
64733
|
features: persistedFeatures(m.features),
|
|
64456
|
-
isCamera:
|
|
64734
|
+
isCamera: persistedIsCamera(m.type),
|
|
64457
64735
|
config: persistedConfig,
|
|
64458
64736
|
metadata,
|
|
64459
64737
|
...m.integrationId !== void 0 ? { integrationId: m.integrationId } : {},
|
|
@@ -68049,7 +68327,7 @@ var require_hub_forwarder = __commonJS({
|
|
|
68049
68327
|
[Symbol.toStringTag]: { value: "Module" }
|
|
68050
68328
|
});
|
|
68051
68329
|
require_chunk_Cek0wNdY();
|
|
68052
|
-
var require_dist10 =
|
|
68330
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
68053
68331
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
68054
68332
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
68055
68333
|
var HubForwarderDestination = class {
|
|
@@ -68186,7 +68464,7 @@ var require_liveness_monitor_addon = __commonJS({
|
|
|
68186
68464
|
"use strict";
|
|
68187
68465
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
68188
68466
|
require_chunk_Cek0wNdY();
|
|
68189
|
-
var require_dist10 =
|
|
68467
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
68190
68468
|
var NO_DEVICES = "liveness:no-devices";
|
|
68191
68469
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
68192
68470
|
var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
|
|
@@ -68376,7 +68654,7 @@ var require_local_auth_addon = __commonJS({
|
|
|
68376
68654
|
[Symbol.toStringTag]: { value: "Module" }
|
|
68377
68655
|
});
|
|
68378
68656
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
68379
|
-
var require_dist10 =
|
|
68657
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
68380
68658
|
var node_crypto = __require("crypto");
|
|
68381
68659
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
68382
68660
|
var crypto$1 = __require("crypto");
|
|
@@ -76189,7 +76467,7 @@ var require_loki_logging = __commonJS({
|
|
|
76189
76467
|
[Symbol.toStringTag]: { value: "Module" }
|
|
76190
76468
|
});
|
|
76191
76469
|
require_chunk_Cek0wNdY();
|
|
76192
|
-
var require_dist10 =
|
|
76470
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
76193
76471
|
function sanitizeLabelName(raw) {
|
|
76194
76472
|
const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
|
|
76195
76473
|
return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
|
|
@@ -76754,7 +77032,7 @@ var require_native_metrics_addon = __commonJS({
|
|
|
76754
77032
|
[Symbol.toStringTag]: { value: "Module" }
|
|
76755
77033
|
});
|
|
76756
77034
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
76757
|
-
var require_dist10 =
|
|
77035
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
76758
77036
|
var node_fs_promises = __require("fs/promises");
|
|
76759
77037
|
var node_child_process = __require("child_process");
|
|
76760
77038
|
var node_util = __require("util");
|
|
@@ -79376,7 +79654,7 @@ var require_filesystem_storage_addon = __commonJS({
|
|
|
79376
79654
|
[Symbol.toStringTag]: { value: "Module" }
|
|
79377
79655
|
});
|
|
79378
79656
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
79379
|
-
var require_dist10 =
|
|
79657
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
79380
79658
|
var node_crypto = __require("crypto");
|
|
79381
79659
|
var node_fs_promises = __require("fs/promises");
|
|
79382
79660
|
var node_path = __require("path");
|
|
@@ -80492,8 +80770,8 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
80492
80770
|
[Symbol.toStringTag]: { value: "Module" }
|
|
80493
80771
|
});
|
|
80494
80772
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
80495
|
-
var require_dist10 =
|
|
80496
|
-
var require_retired_settings_keys =
|
|
80773
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
80774
|
+
var require_retired_settings_keys = require_retired_settings_keys_CqDbI_vK();
|
|
80497
80775
|
var node_crypto = __require("crypto");
|
|
80498
80776
|
var node_fs = __require("fs");
|
|
80499
80777
|
var node_module = __require("module");
|
|
@@ -80529,6 +80807,14 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
80529
80807
|
var SQLITE_PROFILE_REPORT_INTERVAL_MS = 6e4;
|
|
80530
80808
|
var SQLITE_PROFILE_REPORT_FLOOR_MS = 250;
|
|
80531
80809
|
var SQLITE_PROFILE_TOP_N = 5;
|
|
80810
|
+
var SQLITE_ENGINE_STORM_WALL_SHARE = 0.5;
|
|
80811
|
+
function sqliteEngineStorm(stats, windowMs) {
|
|
80812
|
+
if (windowMs <= 0) return null;
|
|
80813
|
+
const top = stats[0];
|
|
80814
|
+
if (top === void 0) return null;
|
|
80815
|
+
if (top.totalMs / windowMs < 0.5) return null;
|
|
80816
|
+
return top;
|
|
80817
|
+
}
|
|
80532
80818
|
function rowsOf(value) {
|
|
80533
80819
|
if (Array.isArray(value)) return value.length;
|
|
80534
80820
|
if (value === void 0 || value === null) return 0;
|
|
@@ -80663,21 +80949,39 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
80663
80949
|
const stats = this.drain();
|
|
80664
80950
|
const busyMs = stats.reduce((acc, s) => acc + s.totalMs, 0);
|
|
80665
80951
|
if (busyMs < this.reportFloorMs) return;
|
|
80952
|
+
const busyPct = Math.round(busyMs / windowMs * 100);
|
|
80953
|
+
const calls = stats.reduce((acc, s) => acc + s.calls, 0);
|
|
80954
|
+
const top = stats.slice(0, this.topN).map((s) => ({
|
|
80955
|
+
op: s.op,
|
|
80956
|
+
collection: s.collection,
|
|
80957
|
+
...s.owner === void 0 ? {} : { owner: s.owner },
|
|
80958
|
+
...s.shape === void 0 ? {} : { shape: s.shape },
|
|
80959
|
+
calls: s.calls,
|
|
80960
|
+
totalMs: Math.round(s.totalMs),
|
|
80961
|
+
maxMs: Math.round(s.maxMs),
|
|
80962
|
+
rows: s.rows
|
|
80963
|
+
}));
|
|
80666
80964
|
this.logger.info("sqlite engine busy", { meta: {
|
|
80667
80965
|
busyMs: Math.round(busyMs),
|
|
80668
80966
|
windowMs: Math.round(windowMs),
|
|
80669
|
-
busyPct
|
|
80670
|
-
calls
|
|
80671
|
-
top
|
|
80672
|
-
|
|
80673
|
-
|
|
80674
|
-
|
|
80675
|
-
|
|
80676
|
-
|
|
80677
|
-
|
|
80678
|
-
|
|
80679
|
-
|
|
80680
|
-
|
|
80967
|
+
busyPct,
|
|
80968
|
+
calls,
|
|
80969
|
+
top
|
|
80970
|
+
} });
|
|
80971
|
+
const storm = sqliteEngineStorm(stats, windowMs);
|
|
80972
|
+
if (storm !== null) this.logger.warn("sqlite engine storm", { meta: {
|
|
80973
|
+
busyMs: Math.round(busyMs),
|
|
80974
|
+
windowMs: Math.round(windowMs),
|
|
80975
|
+
busyPct,
|
|
80976
|
+
wallPct: Math.round(storm.totalMs / windowMs * 100),
|
|
80977
|
+
op: storm.op,
|
|
80978
|
+
collection: storm.collection,
|
|
80979
|
+
...storm.owner === void 0 ? {} : { owner: storm.owner },
|
|
80980
|
+
...storm.shape === void 0 ? {} : { shape: storm.shape },
|
|
80981
|
+
calls: storm.calls,
|
|
80982
|
+
totalMs: Math.round(storm.totalMs),
|
|
80983
|
+
maxMs: Math.round(storm.maxMs),
|
|
80984
|
+
rows: storm.rows
|
|
80681
80985
|
} });
|
|
80682
80986
|
}
|
|
80683
80987
|
start() {
|
|
@@ -82757,6 +83061,7 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
82757
83061
|
return this.vectorIndex;
|
|
82758
83062
|
}
|
|
82759
83063
|
};
|
|
83064
|
+
exports.SQLITE_ENGINE_STORM_WALL_SHARE = SQLITE_ENGINE_STORM_WALL_SHARE;
|
|
82760
83065
|
exports.SQLITE_JOURNAL_SIZE_LIMIT_BYTES = SQLITE_JOURNAL_SIZE_LIMIT_BYTES;
|
|
82761
83066
|
exports.SQLITE_MMAP_CEILING_BYTES = SQLITE_MMAP_CEILING_BYTES;
|
|
82762
83067
|
exports.SQLITE_MMAP_FLOOR_BYTES = SQLITE_MMAP_FLOOR_BYTES;
|
|
@@ -82776,6 +83081,7 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
82776
83081
|
exports.WAL_MAINTENANCE_INTERVAL_MS = WAL_MAINTENANCE_INTERVAL_MS;
|
|
82777
83082
|
exports.WalMaintenance = WalMaintenance;
|
|
82778
83083
|
exports.prefixRange = prefixRange;
|
|
83084
|
+
exports.sqliteEngineStorm = sqliteEngineStorm;
|
|
82779
83085
|
exports.sqliteMmapSizeFor = sqliteMmapSizeFor;
|
|
82780
83086
|
exports.sqlitePageCacheKibFor = sqlitePageCacheKibFor;
|
|
82781
83087
|
}
|
|
@@ -82840,6 +83146,7 @@ var require_sqlite_storage = __commonJS({
|
|
|
82840
83146
|
exports.DeviceStore$1 = DeviceStore;
|
|
82841
83147
|
exports.FilesystemStorageAddon = require_builtins_sqlite_storage_filesystem_storage_addon.FilesystemStorageAddon;
|
|
82842
83148
|
exports.FilesystemStorageProvider = require_builtins_sqlite_storage_filesystem_storage_addon.FilesystemStorageProvider;
|
|
83149
|
+
exports.SQLITE_ENGINE_STORM_WALL_SHARE = require_builtins_sqlite_storage_sqlite_settings_addon.SQLITE_ENGINE_STORM_WALL_SHARE;
|
|
82843
83150
|
exports.SQLITE_JOURNAL_SIZE_LIMIT_BYTES = require_builtins_sqlite_storage_sqlite_settings_addon.SQLITE_JOURNAL_SIZE_LIMIT_BYTES;
|
|
82844
83151
|
exports.SQLITE_MMAP_CEILING_BYTES = require_builtins_sqlite_storage_sqlite_settings_addon.SQLITE_MMAP_CEILING_BYTES;
|
|
82845
83152
|
exports.SQLITE_MMAP_FLOOR_BYTES = require_builtins_sqlite_storage_sqlite_settings_addon.SQLITE_MMAP_FLOOR_BYTES;
|
|
@@ -82858,6 +83165,7 @@ var require_sqlite_storage = __commonJS({
|
|
|
82858
83165
|
exports.WAL_MAINTENANCE_INTERVAL_MS = require_builtins_sqlite_storage_sqlite_settings_addon.WAL_MAINTENANCE_INTERVAL_MS;
|
|
82859
83166
|
exports.WalMaintenance = require_builtins_sqlite_storage_sqlite_settings_addon.WalMaintenance;
|
|
82860
83167
|
exports.default = require_builtins_sqlite_storage_filesystem_storage_addon.FilesystemStorageAddon;
|
|
83168
|
+
exports.sqliteEngineStorm = require_builtins_sqlite_storage_sqlite_settings_addon.sqliteEngineStorm;
|
|
82861
83169
|
exports.sqliteMmapSizeFor = require_builtins_sqlite_storage_sqlite_settings_addon.sqliteMmapSizeFor;
|
|
82862
83170
|
exports.sqlitePageCacheKibFor = require_builtins_sqlite_storage_sqlite_settings_addon.sqlitePageCacheKibFor;
|
|
82863
83171
|
}
|
|
@@ -82872,7 +83180,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
82872
83180
|
[Symbol.toStringTag]: { value: "Module" }
|
|
82873
83181
|
});
|
|
82874
83182
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
82875
|
-
var require_dist10 =
|
|
83183
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
82876
83184
|
var node_crypto = __require("crypto");
|
|
82877
83185
|
var node_fs_promises = __require("fs/promises");
|
|
82878
83186
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -83056,17 +83364,13 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
83056
83364
|
"recordings",
|
|
83057
83365
|
"recordingsLow",
|
|
83058
83366
|
"eventMedia",
|
|
83059
|
-
"backups"
|
|
83060
|
-
"galleryMedia"
|
|
83367
|
+
"backups"
|
|
83061
83368
|
];
|
|
83062
83369
|
var MOVER_CLASSES = [
|
|
83063
83370
|
"recordings",
|
|
83064
83371
|
"recordingsLow",
|
|
83065
|
-
"eventMedia"
|
|
83066
|
-
"galleryMedia"
|
|
83372
|
+
"eventMedia"
|
|
83067
83373
|
];
|
|
83068
|
-
var BLOCKING_ONLY_CLASSES = ["galleryMedia"];
|
|
83069
|
-
var GALLERY_FORBIDDEN_NEIGHBOUR_TYPES = ["recordings", "recordingsLow"];
|
|
83070
83374
|
var MOVE_LANES = ["media", "footage"];
|
|
83071
83375
|
var PARTICIPANTS = [
|
|
83072
83376
|
"pipeline",
|
|
@@ -83091,6 +83395,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
83091
83395
|
this.deps = deps;
|
|
83092
83396
|
}
|
|
83093
83397
|
async plan(input) {
|
|
83398
|
+
refuseRetiredGalleryClass(input.destinations);
|
|
83094
83399
|
const mode = input.mode ?? "blocking";
|
|
83095
83400
|
const moves = [];
|
|
83096
83401
|
const findings = [];
|
|
@@ -83104,8 +83409,6 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
83104
83409
|
if (target.type !== storageClass) throw new Error(`Storage location "${targetId}" is type "${target.type}", expected "${storageClass}"`);
|
|
83105
83410
|
if (source.id === target.id) throw new Error(`Storage location "${targetId}" is already the "${storageClass}" default`);
|
|
83106
83411
|
if (!MOVER_CLASSES.includes(storageClass)) throw new Error(`No mover owns "${storageClass}" \u2014 the migration can repoint its default but cannot move its bytes. Move it by hand, then repoint the default with upsertLocation.`);
|
|
83107
|
-
if (mode === "nonBlocking" && BLOCKING_ONLY_CLASSES.includes(storageClass)) throw new Error(`"${storageClass}" is a single-cardinality storage class: it can never exist at two locations at once, so it cannot be repointed first and drained behind. Use mode "blocking".`);
|
|
83108
|
-
await this.refuseGalleryOntoRecordingsVolume(storageClass, targetId);
|
|
83109
83412
|
moves.push({
|
|
83110
83413
|
storageClass,
|
|
83111
83414
|
fromLocationId: source.id,
|
|
@@ -83115,11 +83418,6 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
83115
83418
|
error: null,
|
|
83116
83419
|
progress: null
|
|
83117
83420
|
});
|
|
83118
|
-
if (BLOCKING_ONLY_CLASSES.includes(storageClass)) findings.push({
|
|
83119
|
-
code: "blockingOnly",
|
|
83120
|
-
storageClass,
|
|
83121
|
-
message: `"${storageClass}" is single-cardinality: this move is stop-the-world for its whole duration, in every mode. It is a few KB per enrolled sample, which is why that is acceptable.`
|
|
83122
|
-
});
|
|
83123
83421
|
findings.push(...await this.deviceFindings(storageClass, source.id, target.id));
|
|
83124
83422
|
}
|
|
83125
83423
|
if (moves.length === 0) throw new Error("select at least one storage class");
|
|
@@ -83154,29 +83452,6 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
83154
83452
|
findings
|
|
83155
83453
|
};
|
|
83156
83454
|
}
|
|
83157
|
-
/**
|
|
83158
|
-
* HARD refusal: `galleryMedia` onto a volume a recordings class lives on.
|
|
83159
|
-
*
|
|
83160
|
-
* This is the one same-device case that is a refusal rather than a finding,
|
|
83161
|
-
* because its consequence is silent and arrives months later — the gallery is
|
|
83162
|
-
* wiped by the next footage wipe, quota eviction or recordings disk swap, and
|
|
83163
|
-
* nothing at that moment points back at this migration.
|
|
83164
|
-
*
|
|
83165
|
-
* It can only refuse what it can SEE. `deviceKeyOf` is a realpath, so it
|
|
83166
|
-
* catches a symlink, a bind mount and a literally-shared directory — and
|
|
83167
|
-
* misses two distinct directories on one filesystem, and any location pinned
|
|
83168
|
-
* to another node. Those come back `null`/distinct and produce a
|
|
83169
|
-
* `deviceIdentityUnknown` finding instead.
|
|
83170
|
-
*/
|
|
83171
|
-
async refuseGalleryOntoRecordingsVolume(storageClass, targetId) {
|
|
83172
|
-
if (storageClass !== "galleryMedia") return;
|
|
83173
|
-
const targetKey = await this.deviceKey(targetId);
|
|
83174
|
-
if (targetKey === null) return;
|
|
83175
|
-
for (const type of GALLERY_FORBIDDEN_NEIGHBOUR_TYPES) for (const neighbour of this.deps.locations.listLocations({ type })) {
|
|
83176
|
-
if (await this.deviceKey(neighbour.id) !== targetKey) continue;
|
|
83177
|
-
throw new Error(`Storage location "${targetId}" shares a volume with "${neighbour.id}" (${type}). galleryMedia is deliberately NOT on the recordings volume: enrolment images survive every retention sweep, so they must also survive a footage wipe, a quota eviction and a recordings disk swap. Choose a destination on another volume.`);
|
|
83178
|
-
}
|
|
83179
|
-
}
|
|
83180
83455
|
/** Same-device observations that are reported, not refused. */
|
|
83181
83456
|
async deviceFindings(storageClass, sourceId, targetId) {
|
|
83182
83457
|
if (this.deps.deviceKeyOf === void 0) return [];
|
|
@@ -83308,7 +83583,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
83308
83583
|
if (laneOf(storageClass) === "media") {
|
|
83309
83584
|
const count = await unanswerable(this.deps.participants.analytics.residue({
|
|
83310
83585
|
toLocationId: target.id,
|
|
83311
|
-
mode:
|
|
83586
|
+
mode: "move"
|
|
83312
83587
|
}));
|
|
83313
83588
|
if (count !== null && count.rows === 0) continue;
|
|
83314
83589
|
out.push({
|
|
@@ -83588,9 +83863,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
83588
83863
|
*
|
|
83589
83864
|
* Two lanes — the recorder's footage engine and post-analysis's media engine
|
|
83590
83865
|
* — run in parallel with each other and strictly FIFO within themselves.
|
|
83591
|
-
* `
|
|
83592
|
-
* the same `MediaRelocateEngine`, which refuses a second running job; starting
|
|
83593
|
-
* both would fail the second one instantly.
|
|
83866
|
+
* `eventMedia` is the only class on the media lane.
|
|
83594
83867
|
*/
|
|
83595
83868
|
async startOrResumeMoves(job) {
|
|
83596
83869
|
if (job.cancelRequested) return;
|
|
@@ -83720,7 +83993,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
83720
83993
|
const input2 = {
|
|
83721
83994
|
toLocationId: move.toLocationId,
|
|
83722
83995
|
throttleMbps: job.throttleMbps,
|
|
83723
|
-
mode:
|
|
83996
|
+
mode: "move"
|
|
83724
83997
|
};
|
|
83725
83998
|
return (unleased ? await this.deps.participants.analytics.startDrain(input2) : await this.deps.participants.analytics.startMove({
|
|
83726
83999
|
...input2,
|
|
@@ -83781,7 +84054,11 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
83781
84054
|
return job.phase === "done" || job.phase === "failed" || job.phase === "cancelled";
|
|
83782
84055
|
}
|
|
83783
84056
|
function laneOf(storageClass) {
|
|
83784
|
-
return storageClass === "eventMedia"
|
|
84057
|
+
return storageClass === "eventMedia" ? "media" : "footage";
|
|
84058
|
+
}
|
|
84059
|
+
function refuseRetiredGalleryClass(destinations) {
|
|
84060
|
+
if (destinations.galleryMedia === void 0) return;
|
|
84061
|
+
throw new Error("galleryMedia is no longer a storage class. Enrolled gallery lives in the pipeline-analytics addon data directory, not a location the operator places.");
|
|
83785
84062
|
}
|
|
83786
84063
|
function runsUnleased(job) {
|
|
83787
84064
|
if (job.phase === "sealing" || job.phase === "draining") return true;
|
|
@@ -84052,14 +84329,13 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
84052
84329
|
/**
|
|
84053
84330
|
* Shout about a persisted row that is BOTH the type default and disabled.
|
|
84054
84331
|
*
|
|
84055
|
-
* `upsertLocation`
|
|
84056
|
-
*
|
|
84057
|
-
*
|
|
84058
|
-
*
|
|
84059
|
-
*
|
|
84332
|
+
* `upsertLocation` can now produce this (enabled is the write set; `isDefault`
|
|
84333
|
+
* is store residue). Hydrate also writes rows straight into the map, so a
|
|
84334
|
+
* hand-edited store or a row written by another build can too. It matters
|
|
84335
|
+
* because every bare-type ref still resolves through {@link getDefaultLocation}
|
|
84336
|
+
* until Stage 5 of the enabled-write-set design: on such a row
|
|
84060
84337
|
* `storage.write({ location: 'eventMedia' })` and the migration coordinator's
|
|
84061
|
-
* drain destination both point at a disk the operator turned off.
|
|
84062
|
-
* one thing this model must never do silently.
|
|
84338
|
+
* drain destination both point at a disk the operator turned off.
|
|
84063
84339
|
*
|
|
84064
84340
|
* Reported, never repaired: flipping an operator's flag back on at boot would
|
|
84065
84341
|
* be the system overruling the switch instead of obeying it. The coordinator
|
|
@@ -84344,6 +84620,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
84344
84620
|
createdAt: existing?.createdAt ?? now,
|
|
84345
84621
|
updatedAt: now
|
|
84346
84622
|
};
|
|
84623
|
+
refuseLastWriteTargetDisabled(existing, next, this.locations.values());
|
|
84347
84624
|
const demoted = [];
|
|
84348
84625
|
if (next.isDefault) {
|
|
84349
84626
|
for (const [otherId, otherLoc] of this.locations) if (otherLoc.type === next.type && otherLoc.id !== next.id && otherLoc.isDefault) {
|
|
@@ -84638,9 +84915,20 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
84638
84915
|
if (existing) return {};
|
|
84639
84916
|
return { enabled: input.isDefault || !typeAlreadyHasLocation };
|
|
84640
84917
|
}
|
|
84641
|
-
if (input.isDefault && requested === false) return { enabled: true };
|
|
84642
84918
|
return { enabled: requested };
|
|
84643
84919
|
}
|
|
84920
|
+
var OPTIONAL_WRITE_TYPES = /* @__PURE__ */ new Set(["backups"]);
|
|
84921
|
+
function refuseLastWriteTargetDisabled(existing, next, locations) {
|
|
84922
|
+
if (OPTIONAL_WRITE_TYPES.has(next.type)) return;
|
|
84923
|
+
if (next.enabled !== false) return;
|
|
84924
|
+
if (existing === void 0) return;
|
|
84925
|
+
if (existing.enabled === false) return;
|
|
84926
|
+
for (const loc of locations) {
|
|
84927
|
+
if (loc.id === next.id || loc.type !== next.type) continue;
|
|
84928
|
+
if (loc.enabled !== false) return;
|
|
84929
|
+
}
|
|
84930
|
+
throw new Error(`Cannot disable "${next.id}": it is the last enabled location of type "${next.type}". Enable another location of this type first.`);
|
|
84931
|
+
}
|
|
84644
84932
|
var DEFAULT_MAX_ROUNDS = 8;
|
|
84645
84933
|
var DEFAULT_HYSTERESIS_PERCENT = 1;
|
|
84646
84934
|
var StoragePressureManager = class {
|
|
@@ -85469,7 +85757,7 @@ var require_system_config_addon = __commonJS({
|
|
|
85469
85757
|
[Symbol.toStringTag]: { value: "Module" }
|
|
85470
85758
|
});
|
|
85471
85759
|
require_chunk_Cek0wNdY();
|
|
85472
|
-
var require_dist10 =
|
|
85760
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
85473
85761
|
var SECTION_TITLES = {
|
|
85474
85762
|
server: "Server",
|
|
85475
85763
|
auth: "Authentication"
|
|
@@ -103530,7 +103818,7 @@ var require_winston_logging = __commonJS({
|
|
|
103530
103818
|
[Symbol.toStringTag]: { value: "Module" }
|
|
103531
103819
|
});
|
|
103532
103820
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
103533
|
-
var require_dist10 =
|
|
103821
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
103534
103822
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
103535
103823
|
var node_path = __require("path");
|
|
103536
103824
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -105473,9 +105761,9 @@ var require_event_category_BaEgqJNv = __commonJS({
|
|
|
105473
105761
|
}
|
|
105474
105762
|
});
|
|
105475
105763
|
|
|
105476
|
-
// ../types/dist/sleep-
|
|
105477
|
-
var
|
|
105478
|
-
"../types/dist/sleep-
|
|
105764
|
+
// ../types/dist/sleep-CqVyhcl-.js
|
|
105765
|
+
var require_sleep_CqVyhcl = __commonJS({
|
|
105766
|
+
"../types/dist/sleep-CqVyhcl-.js"(exports) {
|
|
105479
105767
|
"use strict";
|
|
105480
105768
|
var require_event_category = require_event_category_BaEgqJNv();
|
|
105481
105769
|
var zod = require_zod();
|
|
@@ -108158,6 +108446,7 @@ var require_sleep_D5821NGq = __commonJS({
|
|
|
108158
108446
|
listEventKindsBatch: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listEventKindsBatch", "query", input),
|
|
108159
108447
|
getSensorEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getSensorEvents", "query", input),
|
|
108160
108448
|
getKeyEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getKeyEvents", "query", input),
|
|
108449
|
+
getKeyEventsBatch: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getKeyEventsBatch", "query", input),
|
|
108161
108450
|
getEventDensity: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getEventDensity", "query", input),
|
|
108162
108451
|
pruneEventsBefore: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneEventsBefore", "mutation", input),
|
|
108163
108452
|
pruneTracksBefore: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "pruneTracksBefore", "mutation", input),
|
|
@@ -108181,6 +108470,8 @@ var require_sleep_D5821NGq = __commonJS({
|
|
|
108181
108470
|
listRelocateMediaJobs: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listRelocateMediaJobs", "query", input),
|
|
108182
108471
|
cancelRelocateMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "cancelRelocateMedia", "mutation", input),
|
|
108183
108472
|
listOpsLog: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listOpsLog", "query", input),
|
|
108473
|
+
reclaimDebugMedia: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "reclaimDebugMedia", "mutation", input),
|
|
108474
|
+
getMediaReclaimStatus: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getMediaReclaimStatus", "query", input),
|
|
108184
108475
|
getTrainingExportSummary: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getTrainingExportSummary", "query", input),
|
|
108185
108476
|
getTrainingExportUrl: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getTrainingExportUrl", "query", input),
|
|
108186
108477
|
listRetrainStaging: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listRetrainStaging", "query", input),
|
|
@@ -108239,6 +108530,7 @@ var require_sleep_D5821NGq = __commonJS({
|
|
|
108239
108530
|
reboot: { reboot: (input) => dispatch("reboot", "reboot", "reboot", "mutation", input) },
|
|
108240
108531
|
sceneMonitor: {
|
|
108241
108532
|
listScenes: (input) => dispatch("scene-monitor", "sceneMonitor", "listScenes", "query", input),
|
|
108533
|
+
listScenesBatch: (input) => dispatch("scene-monitor", "sceneMonitor", "listScenesBatch", "query", input),
|
|
108242
108534
|
createScene: (input) => dispatch("scene-monitor", "sceneMonitor", "createScene", "mutation", input),
|
|
108243
108535
|
updateScene: (input) => dispatch("scene-monitor", "sceneMonitor", "updateScene", "mutation", input),
|
|
108244
108536
|
deleteScene: (input) => dispatch("scene-monitor", "sceneMonitor", "deleteScene", "mutation", input),
|
|
@@ -108323,6 +108615,7 @@ var require_sleep_D5821NGq = __commonJS({
|
|
|
108323
108615
|
},
|
|
108324
108616
|
zoneAnalytics: {
|
|
108325
108617
|
getCurrentSnapshot: (input) => dispatch("zone-analytics", "zoneAnalytics", "getCurrentSnapshot", "query", input),
|
|
108618
|
+
getCurrentSnapshotBatch: (input) => dispatch("zone-analytics", "zoneAnalytics", "getCurrentSnapshotBatch", "query", input),
|
|
108326
108619
|
getZoneHistory: (input) => dispatch("zone-analytics", "zoneAnalytics", "getZoneHistory", "query", input),
|
|
108327
108620
|
getCameraHistory: (input) => dispatch("zone-analytics", "zoneAnalytics", "getCameraHistory", "query", input),
|
|
108328
108621
|
getUnzonedHistory: (input) => dispatch("zone-analytics", "zoneAnalytics", "getUnzonedHistory", "query", input)
|
|
@@ -109143,7 +109436,7 @@ var require_addon = __commonJS({
|
|
|
109143
109436
|
"use strict";
|
|
109144
109437
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
109145
109438
|
var require_event_category = require_event_category_BaEgqJNv();
|
|
109146
|
-
var require_sleep =
|
|
109439
|
+
var require_sleep = require_sleep_CqVyhcl();
|
|
109147
109440
|
var require_err_msg = require_err_msg_COpsHMw2();
|
|
109148
109441
|
var CAP_INPUT_DEFAULTS = Object.freeze({
|
|
109149
109442
|
"addons": { "getLogs": { "limit": 100 } },
|
|
@@ -109253,11 +109546,13 @@ var require_addon = __commonJS({
|
|
|
109253
109546
|
"pipeline-analytics": {
|
|
109254
109547
|
"getAudioEvents": { "limit": 1e3 },
|
|
109255
109548
|
"getKeyEvents": { "limit": 50 },
|
|
109549
|
+
"getKeyEventsBatch": { "limit": 50 },
|
|
109256
109550
|
"getMotionEvents": { "limit": 1e3 },
|
|
109257
109551
|
"getObjectEvents": { "limit": 1e3 },
|
|
109258
109552
|
"getSensorEvents": { "limit": 1e3 },
|
|
109259
109553
|
"listGroups": { "limit": 40 },
|
|
109260
109554
|
"listRecentTracks": { "limit": 200 },
|
|
109555
|
+
"reclaimDebugMedia": { "mode": "report" },
|
|
109261
109556
|
"searchObjectEvents": {
|
|
109262
109557
|
"limit": 50,
|
|
109263
109558
|
"minScore": 0.2
|
|
@@ -116025,12 +116320,12 @@ var require_dist2 = __commonJS({
|
|
|
116025
116320
|
}
|
|
116026
116321
|
});
|
|
116027
116322
|
|
|
116028
|
-
// ../system/dist/manifest-system-deps-
|
|
116029
|
-
var
|
|
116030
|
-
"../system/dist/manifest-system-deps-
|
|
116323
|
+
// ../system/dist/manifest-system-deps-uflHvHDB.js
|
|
116324
|
+
var require_manifest_system_deps_uflHvHDB = __commonJS({
|
|
116325
|
+
"../system/dist/manifest-system-deps-uflHvHDB.js"(exports) {
|
|
116031
116326
|
"use strict";
|
|
116032
116327
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
116033
|
-
|
|
116328
|
+
require_dist_BhE8zNfY();
|
|
116034
116329
|
var node_crypto = __require("crypto");
|
|
116035
116330
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
116036
116331
|
var _camstack_types_node = require_node();
|
|
@@ -123315,6 +123610,93 @@ var require_manifest_system_deps_alrkBKVQ = __commonJS({
|
|
|
123315
123610
|
}
|
|
123316
123611
|
await deps.installPythonRequirements(reqAbs);
|
|
123317
123612
|
}
|
|
123613
|
+
var DISTRO_PACKAGE_ALLOWLIST = {
|
|
123614
|
+
apt: ["smbclient"],
|
|
123615
|
+
apk: ["samba-client"],
|
|
123616
|
+
dnf: ["samba-client"]
|
|
123617
|
+
};
|
|
123618
|
+
function packageIsAllowlisted(manager, packageName) {
|
|
123619
|
+
if (manager === "brew") return true;
|
|
123620
|
+
if (packageName.length === 0) return false;
|
|
123621
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9+._-]*$/.test(packageName)) return false;
|
|
123622
|
+
return DISTRO_PACKAGE_ALLOWLIST[manager].includes(packageName);
|
|
123623
|
+
}
|
|
123624
|
+
function decidePackageInstall(input) {
|
|
123625
|
+
if (input.manager === "brew") return { kind: "local" };
|
|
123626
|
+
if (!packageIsAllowlisted(input.manager, input.packageName)) return {
|
|
123627
|
+
kind: "refuse",
|
|
123628
|
+
reason: "not-allowlisted"
|
|
123629
|
+
};
|
|
123630
|
+
if (!input.helperAvailable) return {
|
|
123631
|
+
kind: "refuse",
|
|
123632
|
+
reason: "helper-unavailable"
|
|
123633
|
+
};
|
|
123634
|
+
return { kind: "helper" };
|
|
123635
|
+
}
|
|
123636
|
+
function pkgdSocketPath() {
|
|
123637
|
+
return process.env["CAMSTACK_PKGD_SOCKET"] ?? "/run/camstack/pkgd.sock";
|
|
123638
|
+
}
|
|
123639
|
+
function privilegedHelperAvailable(socketPath = pkgdSocketPath()) {
|
|
123640
|
+
return (0, node_fs.existsSync)(socketPath);
|
|
123641
|
+
}
|
|
123642
|
+
function requestPrivilegedInstall(req, socketPath = pkgdSocketPath(), timeoutMs = 360 * 1e3) {
|
|
123643
|
+
return new Promise((resolve) => {
|
|
123644
|
+
const socket = (0, node_net.createConnection)({ path: socketPath });
|
|
123645
|
+
const chunks = [];
|
|
123646
|
+
const finish = (result) => {
|
|
123647
|
+
socket.destroy();
|
|
123648
|
+
resolve(result);
|
|
123649
|
+
};
|
|
123650
|
+
const timer = setTimeout(() => {
|
|
123651
|
+
finish({
|
|
123652
|
+
ok: false,
|
|
123653
|
+
error: `privileged helper timed out after ${timeoutMs}ms`
|
|
123654
|
+
});
|
|
123655
|
+
}, timeoutMs);
|
|
123656
|
+
socket.on("connect", () => {
|
|
123657
|
+
socket.write(`${JSON.stringify({
|
|
123658
|
+
v: 1,
|
|
123659
|
+
...req
|
|
123660
|
+
})}
|
|
123661
|
+
`);
|
|
123662
|
+
});
|
|
123663
|
+
socket.on("data", (data) => {
|
|
123664
|
+
chunks.push(data);
|
|
123665
|
+
const text = Buffer.concat(chunks).toString("utf8");
|
|
123666
|
+
const nl = text.indexOf("\n");
|
|
123667
|
+
if (nl === -1) return;
|
|
123668
|
+
clearTimeout(timer);
|
|
123669
|
+
try {
|
|
123670
|
+
const parsed = JSON.parse(text.slice(0, nl));
|
|
123671
|
+
finish({
|
|
123672
|
+
ok: parsed.ok === true,
|
|
123673
|
+
...parsed.error !== void 0 ? { error: parsed.error } : {}
|
|
123674
|
+
});
|
|
123675
|
+
} catch (err) {
|
|
123676
|
+
finish({
|
|
123677
|
+
ok: false,
|
|
123678
|
+
error: err instanceof Error ? err.message : String(err)
|
|
123679
|
+
});
|
|
123680
|
+
}
|
|
123681
|
+
});
|
|
123682
|
+
socket.on("error", (err) => {
|
|
123683
|
+
clearTimeout(timer);
|
|
123684
|
+
finish({
|
|
123685
|
+
ok: false,
|
|
123686
|
+
error: err.message
|
|
123687
|
+
});
|
|
123688
|
+
});
|
|
123689
|
+
socket.on("end", () => {
|
|
123690
|
+
if (chunks.length === 0) {
|
|
123691
|
+
clearTimeout(timer);
|
|
123692
|
+
finish({
|
|
123693
|
+
ok: false,
|
|
123694
|
+
error: "privileged helper closed without a reply"
|
|
123695
|
+
});
|
|
123696
|
+
}
|
|
123697
|
+
});
|
|
123698
|
+
});
|
|
123699
|
+
}
|
|
123318
123700
|
var execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
|
|
123319
123701
|
var INSTALL_TIMEOUT_MS = 300 * 1e3;
|
|
123320
123702
|
var PROBE_TIMEOUT_MS = 1e4;
|
|
@@ -123325,12 +123707,16 @@ var require_manifest_system_deps_alrkBKVQ = __commonJS({
|
|
|
123325
123707
|
const detectManager = options.detectManager ?? defaultDetectManager;
|
|
123326
123708
|
const run = options.run ?? defaultRun;
|
|
123327
123709
|
const platform = options.platform ?? process.platform;
|
|
123710
|
+
const helperAvailable = options.helperAvailable ?? (async () => privilegedHelperAvailable());
|
|
123711
|
+
const requestInstall = options.requestInstall ?? ((req) => requestPrivilegedInstall(req));
|
|
123328
123712
|
for (const dep of deps) try {
|
|
123329
123713
|
await satisfyOne(dep, declaration.id, {
|
|
123330
123714
|
hasBinary,
|
|
123331
123715
|
detectManager,
|
|
123332
123716
|
run,
|
|
123333
|
-
platform
|
|
123717
|
+
platform,
|
|
123718
|
+
helperAvailable,
|
|
123719
|
+
requestInstall
|
|
123334
123720
|
}, logger);
|
|
123335
123721
|
} catch (err) {
|
|
123336
123722
|
logger.warn("system dependency step failed", { meta: {
|
|
@@ -123368,15 +123754,43 @@ var require_manifest_system_deps_alrkBKVQ = __commonJS({
|
|
|
123368
123754
|
} });
|
|
123369
123755
|
return;
|
|
123370
123756
|
}
|
|
123371
|
-
const
|
|
123757
|
+
const decision = decidePackageInstall({
|
|
123758
|
+
manager,
|
|
123759
|
+
packageName,
|
|
123760
|
+
helperAvailable: await rt.helperAvailable()
|
|
123761
|
+
});
|
|
123762
|
+
if (decision.kind === "refuse") {
|
|
123763
|
+
const message = decision.reason === "helper-unavailable" ? "system dependency missing and the privileged helper is not running \u2014 apt cannot run as uid 1001" : "system dependency missing and the package is not on the helper allowlist";
|
|
123764
|
+
logger.warn(message, { meta: {
|
|
123765
|
+
addonId,
|
|
123766
|
+
binary: dep.binary,
|
|
123767
|
+
manager,
|
|
123768
|
+
package: packageName,
|
|
123769
|
+
reason: decision.reason,
|
|
123770
|
+
...dep.reason !== void 0 ? { reason: dep.reason } : {}
|
|
123771
|
+
} });
|
|
123772
|
+
return;
|
|
123773
|
+
}
|
|
123372
123774
|
logger.info("installing system dependency", { meta: {
|
|
123373
123775
|
addonId,
|
|
123374
123776
|
binary: dep.binary,
|
|
123375
123777
|
manager,
|
|
123376
|
-
package: packageName
|
|
123778
|
+
package: packageName,
|
|
123779
|
+
via: decision.kind
|
|
123377
123780
|
} });
|
|
123378
123781
|
try {
|
|
123379
|
-
|
|
123782
|
+
if (decision.kind === "helper") {
|
|
123783
|
+
const result = await rt.requestInstall({
|
|
123784
|
+
addonId,
|
|
123785
|
+
binary: dep.binary,
|
|
123786
|
+
manager,
|
|
123787
|
+
packageName
|
|
123788
|
+
});
|
|
123789
|
+
if (!result.ok) throw new Error(result.error ?? "privileged helper refused");
|
|
123790
|
+
} else {
|
|
123791
|
+
const plan = planFor(manager, packageName);
|
|
123792
|
+
for (const [command, args] of plan.steps) await rt.run(command, args);
|
|
123793
|
+
}
|
|
123380
123794
|
} catch (err) {
|
|
123381
123795
|
logger.warn("system dependency install failed \u2014 the addon loads, its capability must refuse", { meta: {
|
|
123382
123796
|
addonId,
|
|
@@ -128059,7 +128473,7 @@ var require_dist3 = __commonJS({
|
|
|
128059
128473
|
"use strict";
|
|
128060
128474
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
128061
128475
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
128062
|
-
var require_dist10 =
|
|
128476
|
+
var require_dist10 = require_dist_BhE8zNfY();
|
|
128063
128477
|
var require_builtins_alerts_alerts_addon = require_alerts_addon();
|
|
128064
128478
|
require_alerts();
|
|
128065
128479
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
@@ -128085,7 +128499,7 @@ var require_dist3 = __commonJS({
|
|
|
128085
128499
|
var require_builtins_winston_logging_index = require_winston_logging();
|
|
128086
128500
|
var require_file_data_plane = require_file_data_plane_DO8KbxCe();
|
|
128087
128501
|
var require_tls$1 = require_tls_BxQlomxd();
|
|
128088
|
-
var require_manifest_system_deps =
|
|
128502
|
+
var require_manifest_system_deps = require_manifest_system_deps_uflHvHDB();
|
|
128089
128503
|
var require_resource_monitor = require_resource_monitor_CdnzxBLP();
|
|
128090
128504
|
var require_custom_action_registry = require_custom_action_registry_jY0NOZK8();
|
|
128091
128505
|
var zod = require_zod();
|
|
@@ -133973,19 +134387,37 @@ var require_dist3 = __commonJS({
|
|
|
133973
134387
|
if (!isRecord$1(parsed) || !("value" in parsed)) return parsed;
|
|
133974
134388
|
return parsed.value;
|
|
133975
134389
|
}
|
|
134390
|
+
var PREFIX_PAGE_ROWS = 1e3;
|
|
134391
|
+
var PREFIX_PAGE_BUDGET = 512;
|
|
133976
134392
|
async function loadPrefixed(door, collection, prefix) {
|
|
133977
134393
|
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
134394
|
const result = {};
|
|
133983
|
-
|
|
133984
|
-
|
|
133985
|
-
if (
|
|
133986
|
-
|
|
134395
|
+
let cursor = range?.lo ?? null;
|
|
134396
|
+
for (let page = 0; ; page++) {
|
|
134397
|
+
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.`);
|
|
134398
|
+
const rows = await door.query({
|
|
134399
|
+
collection,
|
|
134400
|
+
filter: {
|
|
134401
|
+
...range !== null && cursor !== null ? { whereBetween: { id: [cursor, range.hi] } } : {},
|
|
134402
|
+
orderBy: {
|
|
134403
|
+
field: "id",
|
|
134404
|
+
direction: "asc"
|
|
134405
|
+
},
|
|
134406
|
+
limit: PREFIX_PAGE_ROWS
|
|
134407
|
+
}
|
|
134408
|
+
});
|
|
134409
|
+
for (const row of rows) {
|
|
134410
|
+
if (range !== null && (row.id < range.lo || row.id >= range.hi)) continue;
|
|
134411
|
+
if (!row.id.startsWith(prefix)) continue;
|
|
134412
|
+
result[row.id.slice(prefix.length)] = unwrapValue(row.data);
|
|
134413
|
+
}
|
|
134414
|
+
if (rows.length < PREFIX_PAGE_ROWS) return result;
|
|
134415
|
+
const last = rows[rows.length - 1];
|
|
134416
|
+
if (last === void 0) return result;
|
|
134417
|
+
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.`);
|
|
134418
|
+
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.`);
|
|
134419
|
+
cursor = last.id;
|
|
133987
134420
|
}
|
|
133988
|
-
return result;
|
|
133989
134421
|
}
|
|
133990
134422
|
async function replacePrefixed(door, collection, prefix, values, wrap3) {
|
|
133991
134423
|
const range = require_builtins_sqlite_storage_sqlite_settings_addon.prefixRange(prefix);
|
|
@@ -208909,7 +209341,7 @@ var require_dist4 = __commonJS({
|
|
|
208909
209341
|
"use strict";
|
|
208910
209342
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
208911
209343
|
var require_event_category = require_event_category_BaEgqJNv();
|
|
208912
|
-
var require_sleep =
|
|
209344
|
+
var require_sleep = require_sleep_CqVyhcl();
|
|
208913
209345
|
var require_canonical_hash = require_canonical_hash_DNV8S5ET();
|
|
208914
209346
|
var require_enums2 = require_enums();
|
|
208915
209347
|
var require_err_msg = require_err_msg_COpsHMw2();
|
|
@@ -210256,6 +210688,20 @@ var require_dist4 = __commonJS({
|
|
|
210256
210688
|
* in its row, not in its name, so `MediaRelocateEngine` never reconciles one.
|
|
210257
210689
|
*/
|
|
210258
210690
|
rowsReconciled: zod.z.number().int().nonnegative().optional(),
|
|
210691
|
+
/**
|
|
210692
|
+
* Rows this run FORGOT because the file they name is not on disk.
|
|
210693
|
+
*
|
|
210694
|
+
* The mover derived the path from the row's own fields and `stat`ed it; an
|
|
210695
|
+
* ENOENT there is a per-path confirmation that the segment is gone (D296),
|
|
210696
|
+
* and the durable row is dropped through the same channel eviction uses. It
|
|
210697
|
+
* is reported for the same reason `rowsReconciled` is: this is a durable
|
|
210698
|
+
* mutation nobody asked for, and a migration that quietly erases hour rows is
|
|
210699
|
+
* the same failure as one that quietly skips them (D295).
|
|
210700
|
+
*
|
|
210701
|
+
* The production drain of 2026-08-30 would have reported 11 074 here — the
|
|
210702
|
+
* ledger claimed 5.65 GB of footage that no longer existed.
|
|
210703
|
+
*/
|
|
210704
|
+
rowsForgotten: zod.z.number().int().nonnegative().optional(),
|
|
210259
210705
|
startedAt: zod.z.number(),
|
|
210260
210706
|
finishedAt: zod.z.number().nullable(),
|
|
210261
210707
|
error: zod.z.string().nullable()
|
|
@@ -210463,6 +210909,71 @@ var require_dist4 = __commonJS({
|
|
|
210463
210909
|
segments: zod.z.number().int().nonnegative(),
|
|
210464
210910
|
bytes: zod.z.number().int().nonnegative()
|
|
210465
210911
|
}).nullable();
|
|
210912
|
+
var LedgerWalkInputSchema = zod.z.object({
|
|
210913
|
+
locationId: zod.z.string().min(1),
|
|
210914
|
+
/** Forget the confirmed-absent rows, rather than only counting them. */
|
|
210915
|
+
apply: zod.z.boolean().optional(),
|
|
210916
|
+
/** Narrow to one camera. */
|
|
210917
|
+
deviceId: zod.z.number().int().positive().optional(),
|
|
210918
|
+
/** Narrow to these recording profiles; empty/absent = every profile. */
|
|
210919
|
+
profiles: zod.z.array(zod.z.string().min(1)).optional()
|
|
210920
|
+
});
|
|
210921
|
+
var LedgerWalkRefusalSchema = zod.z.enum([
|
|
210922
|
+
"location-unknown",
|
|
210923
|
+
"source-writable",
|
|
210924
|
+
"no-ledger",
|
|
210925
|
+
"archive-unreadable",
|
|
210926
|
+
"anchor-absent",
|
|
210927
|
+
"anchor-unreadable",
|
|
210928
|
+
"anchor-moved"
|
|
210929
|
+
]);
|
|
210930
|
+
var LedgerWalkSkipReasonSchema = zod.z.enum([
|
|
210931
|
+
"live-tail",
|
|
210932
|
+
"listing-error",
|
|
210933
|
+
"path-mismatch",
|
|
210934
|
+
"durable-refused"
|
|
210935
|
+
]);
|
|
210936
|
+
var LedgerWalkSkipCountsSchema = zod.z.object({
|
|
210937
|
+
"live-tail": zod.z.number().int().nonnegative(),
|
|
210938
|
+
"listing-error": zod.z.number().int().nonnegative(),
|
|
210939
|
+
"path-mismatch": zod.z.number().int().nonnegative(),
|
|
210940
|
+
"durable-refused": zod.z.number().int().nonnegative()
|
|
210941
|
+
});
|
|
210942
|
+
var LedgerWalkDeviceReportSchema = zod.z.object({
|
|
210943
|
+
deviceId: zod.z.number().int(),
|
|
210944
|
+
hoursWalked: zod.z.number().int().nonnegative(),
|
|
210945
|
+
hoursMissing: zod.z.number().int().nonnegative(),
|
|
210946
|
+
ghostSegments: zod.z.number().int().nonnegative(),
|
|
210947
|
+
ghostBytes: zod.z.number().int().nonnegative(),
|
|
210948
|
+
forgottenSegments: zod.z.number().int().nonnegative(),
|
|
210949
|
+
orphanFiles: zod.z.number().int().nonnegative()
|
|
210950
|
+
});
|
|
210951
|
+
var LedgerWalkReportSchema = zod.z.object({
|
|
210952
|
+
locationId: zod.z.string(),
|
|
210953
|
+
applied: zod.z.boolean(),
|
|
210954
|
+
refused: LedgerWalkRefusalSchema.nullable(),
|
|
210955
|
+
archiveSegments: zod.z.number().int().nonnegative().nullable(),
|
|
210956
|
+
archiveBytes: zod.z.number().int().nonnegative().nullable(),
|
|
210957
|
+
hoursClaimed: zod.z.number().int().nonnegative(),
|
|
210958
|
+
hoursWalked: zod.z.number().int().nonnegative(),
|
|
210959
|
+
hoursMissing: zod.z.number().int().nonnegative(),
|
|
210960
|
+
/** `readdir` calls issued — the cost, stated in the unit that is paid. */
|
|
210961
|
+
listings: zod.z.number().int().nonnegative(),
|
|
210962
|
+
segmentsClaimed: zod.z.number().int().nonnegative(),
|
|
210963
|
+
ghostSegments: zod.z.number().int().nonnegative(),
|
|
210964
|
+
ghostBytes: zod.z.number().int().nonnegative(),
|
|
210965
|
+
ghostHoursWhole: zod.z.number().int().nonnegative(),
|
|
210966
|
+
forgottenSegments: zod.z.number().int().nonnegative(),
|
|
210967
|
+
forgottenBytes: zod.z.number().int().nonnegative(),
|
|
210968
|
+
/** Files under a claimed hour that no durable row names. Never deleted. */
|
|
210969
|
+
orphanFiles: zod.z.number().int().nonnegative(),
|
|
210970
|
+
orphanSample: zod.z.array(zod.z.string()).readonly(),
|
|
210971
|
+
hoursSkipped: zod.z.number().int().nonnegative(),
|
|
210972
|
+
skippedByReason: LedgerWalkSkipCountsSchema,
|
|
210973
|
+
/** The walk stopped at its per-pass hour bound with claims unwalked. */
|
|
210974
|
+
bounded: zod.z.boolean(),
|
|
210975
|
+
byDevice: zod.z.array(LedgerWalkDeviceReportSchema).readonly()
|
|
210976
|
+
});
|
|
210466
210977
|
var RelocatableMediaCountSchema = zod.z.object({ rows: zod.z.number().int().nonnegative() }).nullable();
|
|
210467
210978
|
var RelocatableMediaCountInputSchema = zod.z.object({
|
|
210468
210979
|
toLocationId: zod.z.string().min(1),
|
|
@@ -222962,13 +223473,15 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222962
223473
|
groups: zod.z.array(AnalyticsGroupRecordSchema).readonly(),
|
|
222963
223474
|
nextCursor: zod.z.string().nullable()
|
|
222964
223475
|
});
|
|
223476
|
+
var KEY_EVENTS_DEFAULT_LIMIT = 50;
|
|
223477
|
+
var KEY_EVENTS_MAX_LIMIT = 200;
|
|
222965
223478
|
var KeyEventQueryInput = zod.z.object({
|
|
222966
223479
|
deviceId: zod.z.number(),
|
|
222967
223480
|
/** Window lower bound (track firstSeen ≥ since). */
|
|
222968
223481
|
since: zod.z.number(),
|
|
222969
223482
|
/** Window upper bound (track firstSeen ≤ until). */
|
|
222970
223483
|
until: zod.z.number(),
|
|
222971
|
-
limit: zod.z.number().int().min(1).max(
|
|
223484
|
+
limit: zod.z.number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
|
|
222972
223485
|
/** Drop tracks scoring below this importance. */
|
|
222973
223486
|
minImportance: zod.z.number().min(0).max(1).optional(),
|
|
222974
223487
|
/** Restrict to a single class (e.g. 'person'). */
|
|
@@ -222990,6 +223503,21 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222990
223503
|
...TrackFlagFields,
|
|
222991
223504
|
...TrackRetrainFields
|
|
222992
223505
|
});
|
|
223506
|
+
var KeyEventBatchQueryInput = zod.z.object({
|
|
223507
|
+
deviceIds: zod.z.array(zod.z.number()).min(1).max(200),
|
|
223508
|
+
since: zod.z.number(),
|
|
223509
|
+
until: zod.z.number(),
|
|
223510
|
+
/** Applied PER CAMERA, exactly as `getKeyEvents.limit` is — never a total
|
|
223511
|
+
* across the set, which would let a busy camera starve a quiet one of its
|
|
223512
|
+
* rows and change what the merged feed contains. */
|
|
223513
|
+
limit: zod.z.number().int().min(1).max(KEY_EVENTS_MAX_LIMIT).default(KEY_EVENTS_DEFAULT_LIMIT),
|
|
223514
|
+
minImportance: zod.z.number().min(0).max(1).optional(),
|
|
223515
|
+
classFilter: zod.z.string().optional()
|
|
223516
|
+
});
|
|
223517
|
+
var KeyEventsForDeviceSchema = zod.z.object({
|
|
223518
|
+
deviceId: zod.z.number(),
|
|
223519
|
+
events: zod.z.array(KeyEventSchema).readonly()
|
|
223520
|
+
});
|
|
222993
223521
|
var TrackedDetectionSchema = zod.z.object({
|
|
222994
223522
|
trackId: zod.z.string(),
|
|
222995
223523
|
className: zod.z.string(),
|
|
@@ -223154,6 +223682,39 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
223154
223682
|
/** Present when the pass ended by throwing. */
|
|
223155
223683
|
error: zod.z.string().nullable()
|
|
223156
223684
|
});
|
|
223685
|
+
var MediaReclaimStartResultSchema = zod.z.object({
|
|
223686
|
+
started: zod.z.boolean(),
|
|
223687
|
+
/** True when a pass was already running; the new request is ignored. */
|
|
223688
|
+
alreadyRunning: zod.z.boolean()
|
|
223689
|
+
});
|
|
223690
|
+
var MediaReclaimInputSchema = zod.z.object({
|
|
223691
|
+
mode: zod.z.enum(["report", "reclaim"]).default("report"),
|
|
223692
|
+
scopes: zod.z.array(zod.z.enum(["motion-still", "track-filmstrip"])).min(1).optional(),
|
|
223693
|
+
deviceIds: zod.z.array(zod.z.number().int()).min(1).optional(),
|
|
223694
|
+
restart: zod.z.boolean().optional(),
|
|
223695
|
+
pageSize: zod.z.number().int().min(50).max(5e3).optional(),
|
|
223696
|
+
maxRowsPerDevice: zod.z.number().int().min(1).max(5e5).optional(),
|
|
223697
|
+
maxReclaimPerDevice: zod.z.number().int().min(1).max(5e5).optional(),
|
|
223698
|
+
maxBytesPerRun: zod.z.number().int().min(1).optional(),
|
|
223699
|
+
budgetMinutes: zod.z.number().int().min(1).max(720).optional(),
|
|
223700
|
+
throttleBytesPerSec: zod.z.number().int().min(64 * 1024).optional(),
|
|
223701
|
+
graceMinutes: zod.z.number().int().min(1).max(10080).optional()
|
|
223702
|
+
});
|
|
223703
|
+
var MediaReclaimStatusSchema = zod.z.object({
|
|
223704
|
+
running: zod.z.boolean(),
|
|
223705
|
+
mode: zod.z.enum(["report", "reclaim"]).nullable(),
|
|
223706
|
+
totalExamined: zod.z.number(),
|
|
223707
|
+
totalEligible: zod.z.number(),
|
|
223708
|
+
totalReclaimed: zod.z.number(),
|
|
223709
|
+
totalBytesReclaimed: zod.z.number(),
|
|
223710
|
+
totalRefused: zod.z.number(),
|
|
223711
|
+
/** Device+scope windows finished in this pass. */
|
|
223712
|
+
devicesDone: zod.z.number(),
|
|
223713
|
+
complete: zod.z.boolean().nullable(),
|
|
223714
|
+
startedAtMs: zod.z.number().nullable(),
|
|
223715
|
+
finishedAtMs: zod.z.number().nullable(),
|
|
223716
|
+
error: zod.z.string().nullable()
|
|
223717
|
+
});
|
|
223157
223718
|
var ReplayFrameInputSchema = zod.z.object({
|
|
223158
223719
|
timestamp: zod.z.number(),
|
|
223159
223720
|
frame: PipelineRunResultBridge
|
|
@@ -223284,6 +223845,21 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
223284
223845
|
* scored on-read (no write). Degrades to `[]` on error.
|
|
223285
223846
|
*/
|
|
223286
223847
|
getKeyEvents: require_sleep.method(KeyEventQueryInput, zod.z.array(KeyEventSchema).readonly()),
|
|
223848
|
+
/**
|
|
223849
|
+
* The same ranking, for a SET of cameras, in one round trip.
|
|
223850
|
+
*
|
|
223851
|
+
* The Detection Intelligence events feed asks this of every selected
|
|
223852
|
+
* camera and re-asks on a 30s timer. Fanned out client-side that is N
|
|
223853
|
+
* round trips — browser → hub → post-analysis — for N independent,
|
|
223854
|
+
* already-indexed store queries. Batched, the queries are unchanged and
|
|
223855
|
+
* run concurrently INSIDE the owner; only the transport collapses.
|
|
223856
|
+
*
|
|
223857
|
+
* Deliberately per-device rather than pre-merged: `limit` stays per
|
|
223858
|
+
* camera (a total would let a busy camera starve a quiet one), and a
|
|
223859
|
+
* caller that renders one camera's lane needs to know which camera a row
|
|
223860
|
+
* came from. `getKeyEvents` stays for single-device callers.
|
|
223861
|
+
*/
|
|
223862
|
+
getKeyEventsBatch: require_sleep.method(KeyEventBatchQueryInput, zod.z.array(KeyEventsForDeviceSchema).readonly()),
|
|
223287
223863
|
/** Server-side bucketed event counts for the 24-hour timeline.
|
|
223288
223864
|
* Returns one entry per non-empty bucket; empty buckets are omitted. */
|
|
223289
223865
|
getEventDensity: require_sleep.method(zod.z.object({
|
|
@@ -223562,6 +224138,20 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
223562
224138
|
auth: "admin"
|
|
223563
224139
|
}),
|
|
223564
224140
|
/**
|
|
224141
|
+
* Reclaim the standing debug-media backlog (motion-visit stills + track
|
|
224142
|
+
* filmstrips). DETACHED: returns `{ started }` immediately. The pass is
|
|
224143
|
+
* tens of minutes; awaiting it is a timeout, not a verdict. Dry-run unless
|
|
224144
|
+
* `mode: 'reclaim'`. Poll `getMediaReclaimStatus`.
|
|
224145
|
+
*/
|
|
224146
|
+
reclaimDebugMedia: require_sleep.method(MediaReclaimInputSchema, MediaReclaimStartResultSchema, {
|
|
224147
|
+
kind: "mutation",
|
|
224148
|
+
auth: "admin"
|
|
224149
|
+
}),
|
|
224150
|
+
getMediaReclaimStatus: require_sleep.method(zod.z.object({}), MediaReclaimStatusSchema, {
|
|
224151
|
+
kind: "query",
|
|
224152
|
+
auth: "admin"
|
|
224153
|
+
}),
|
|
224154
|
+
/**
|
|
223565
224155
|
* The CHEAP QUESTION, asked before any media moves: how big is the dataset
|
|
223566
224156
|
* the marked (`markForTrain`) tracks would produce?
|
|
223567
224157
|
*
|
|
@@ -233401,6 +233991,23 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
233401
233991
|
kind: "query",
|
|
233402
233992
|
auth: "admin"
|
|
233403
233993
|
}),
|
|
233994
|
+
/**
|
|
233995
|
+
* Does this location's LEDGER tell the truth about its disk? (D319)
|
|
233996
|
+
*
|
|
233997
|
+
* One `readdir` per claimed hour, diffed both ways: durable rows whose file
|
|
233998
|
+
* is not there, and files no durable row names. `apply` defaults to FALSE —
|
|
233999
|
+
* the report is the product, and the dry run is how an operator
|
|
234000
|
+
* sanity-checks the destructive run before authorising it.
|
|
234001
|
+
*
|
|
234002
|
+
* REFUSES a source that is still a write target: a listing of a live
|
|
234003
|
+
* location is a lower bound, which is not the strong evidence that lets
|
|
234004
|
+
* this pass forget without a budget. A live location is reconciled by the
|
|
234005
|
+
* mover, under D318's bound.
|
|
234006
|
+
*/
|
|
234007
|
+
reconcileLedgerAgainstDisk: require_sleep.method(LedgerWalkInputSchema, LedgerWalkReportSchema, {
|
|
234008
|
+
kind: "mutation",
|
|
234009
|
+
auth: "admin"
|
|
234010
|
+
}),
|
|
233404
234011
|
/** Cancel a running or queued relocate job. A queued job never runs. */
|
|
233405
234012
|
cancelRelocateJob: require_sleep.method(zod.z.object({ jobId: zod.z.string() }), zod.z.object({ cancelled: zod.z.boolean() }), {
|
|
233406
234013
|
kind: "mutation",
|
|
@@ -233715,6 +234322,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
233715
234322
|
monitors: zod.z.array(SceneMonitorSchema),
|
|
233716
234323
|
lastFetchedAt: zod.z.number()
|
|
233717
234324
|
});
|
|
234325
|
+
var SceneMonitorStatusForDeviceSchema = zod.z.object({
|
|
234326
|
+
deviceId: zod.z.number(),
|
|
234327
|
+
status: SceneMonitorStatusSchema.nullable()
|
|
234328
|
+
});
|
|
233718
234329
|
var sceneMonitorCapability = {
|
|
233719
234330
|
name: "scene-monitor",
|
|
233720
234331
|
scope: "device",
|
|
@@ -233724,6 +234335,22 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
233724
234335
|
deviceTypes: [require_sleep.DeviceType.Camera],
|
|
233725
234336
|
methods: {
|
|
233726
234337
|
listScenes: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), SceneMonitorStatusSchema),
|
|
234338
|
+
/**
|
|
234339
|
+
* The same answer, for a SET of cameras, in one round trip.
|
|
234340
|
+
*
|
|
234341
|
+
* `/scenes` renders every camera and re-reads them on a 30s safety-net
|
|
234342
|
+
* poll behind the push slice. Fanned out client-side that was one query
|
|
234343
|
+
* per camera — 29 round trips through the browser, the hub and the
|
|
234344
|
+
* post-analysis runner every 30 seconds to read an in-memory map the
|
|
234345
|
+
* owner had already merged. The work is unchanged (`statusFor` per
|
|
234346
|
+
* device, all in-process at the owner); what collapses is the transport.
|
|
234347
|
+
*
|
|
234348
|
+
* A camera that cannot answer still gets a row, with `status: null` —
|
|
234349
|
+
* see {@link SceneMonitorStatusForDeviceSchema}. Never fewer rows than
|
|
234350
|
+
* ids: a caller that asked for twenty-nine and got twenty-seven cannot
|
|
234351
|
+
* tell which two are missing, or that any are.
|
|
234352
|
+
*/
|
|
234353
|
+
listScenesBatch: require_sleep.method(zod.z.object({ deviceIds: zod.z.array(zod.z.number()).min(1).max(200) }), zod.z.array(SceneMonitorStatusForDeviceSchema).readonly()),
|
|
233727
234354
|
createScene: require_sleep.method(zod.z.object({
|
|
233728
234355
|
deviceId: zod.z.number(),
|
|
233729
234356
|
label: zod.z.string(),
|
|
@@ -235525,6 +236152,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
235525
236152
|
* than as repeated tracks/events. */
|
|
235526
236153
|
stationaryObjects: zod.z.array(StationaryObjectSchema).readonly().optional()
|
|
235527
236154
|
});
|
|
236155
|
+
var CameraOccupancySnapshotForDeviceSchema = zod.z.object({
|
|
236156
|
+
deviceId: zod.z.number(),
|
|
236157
|
+
read: zod.z.enum(["read", "unreadable"]),
|
|
236158
|
+
snapshot: CameraOccupancySnapshotSchema.nullable()
|
|
236159
|
+
});
|
|
235528
236160
|
var HistoryResolutionEnum = zod.z.enum([
|
|
235529
236161
|
"minute",
|
|
235530
236162
|
"5min",
|
|
@@ -235554,6 +236186,20 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
235554
236186
|
* (no inference result emitted since boot or since binding was
|
|
235555
236187
|
* activated). */
|
|
235556
236188
|
getCurrentSnapshot: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), CameraOccupancySnapshotSchema.nullable()),
|
|
236189
|
+
/**
|
|
236190
|
+
* The same snapshot, for a SET of cameras, in one round trip.
|
|
236191
|
+
*
|
|
236192
|
+
* The Events page's Stationary section polls this every 15s for every
|
|
236193
|
+
* selected camera. Fanned out client-side that is one query per camera to
|
|
236194
|
+
* read a `Map.get` at the owner — the answer costs nothing, the round trip
|
|
236195
|
+
* costs everything. Batched, N transports become one and the per-device
|
|
236196
|
+
* work is unchanged.
|
|
236197
|
+
*
|
|
236198
|
+
* Every requested deviceId gets a row, tagged `read` — see
|
|
236199
|
+
* {@link CameraOccupancySnapshotForDeviceSchema}. A camera the owner could
|
|
236200
|
+
* not answer for is `'unreadable'`, never an empty reading.
|
|
236201
|
+
*/
|
|
236202
|
+
getCurrentSnapshotBatch: require_sleep.method(zod.z.object({ deviceIds: zod.z.array(zod.z.number()).min(1).max(200) }), zod.z.array(CameraOccupancySnapshotForDeviceSchema).readonly()),
|
|
235557
236203
|
/** Time-series object count inside one zone. `className` optional —
|
|
235558
236204
|
* omit to count every class in the zone. */
|
|
235559
236205
|
getZoneHistory: require_sleep.method(zod.z.object({
|
|
@@ -242419,6 +243065,18 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
242419
243065
|
addonId: null,
|
|
242420
243066
|
access: "view"
|
|
242421
243067
|
},
|
|
243068
|
+
"pipelineAnalytics.getKeyEventsBatch": {
|
|
243069
|
+
capName: "pipeline-analytics",
|
|
243070
|
+
capScope: "device",
|
|
243071
|
+
addonId: null,
|
|
243072
|
+
access: "view"
|
|
243073
|
+
},
|
|
243074
|
+
"pipelineAnalytics.getMediaReclaimStatus": {
|
|
243075
|
+
capName: "pipeline-analytics",
|
|
243076
|
+
capScope: "device",
|
|
243077
|
+
addonId: null,
|
|
243078
|
+
access: "view"
|
|
243079
|
+
},
|
|
242422
243080
|
"pipelineAnalytics.getMotionEvents": {
|
|
242423
243081
|
capName: "pipeline-analytics",
|
|
242424
243082
|
capScope: "device",
|
|
@@ -242593,6 +243251,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
242593
243251
|
addonId: null,
|
|
242594
243252
|
access: "create"
|
|
242595
243253
|
},
|
|
243254
|
+
"pipelineAnalytics.reclaimDebugMedia": {
|
|
243255
|
+
capName: "pipeline-analytics",
|
|
243256
|
+
capScope: "device",
|
|
243257
|
+
addonId: null,
|
|
243258
|
+
access: "create"
|
|
243259
|
+
},
|
|
242596
243260
|
"pipelineAnalytics.reconcileFromDisk": {
|
|
242597
243261
|
capName: "pipeline-analytics",
|
|
242598
243262
|
capScope: "device",
|
|
@@ -243595,6 +244259,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
243595
244259
|
addonId: null,
|
|
243596
244260
|
access: "view"
|
|
243597
244261
|
},
|
|
244262
|
+
"recording.reconcileLedgerAgainstDisk": {
|
|
244263
|
+
capName: "recording",
|
|
244264
|
+
capScope: "system",
|
|
244265
|
+
addonId: null,
|
|
244266
|
+
access: "create"
|
|
244267
|
+
},
|
|
243598
244268
|
"recording.refreshStorageLocationsForMigration": {
|
|
243599
244269
|
capName: "recording",
|
|
243600
244270
|
capScope: "system",
|
|
@@ -243721,6 +244391,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
243721
244391
|
addonId: null,
|
|
243722
244392
|
access: "view"
|
|
243723
244393
|
},
|
|
244394
|
+
"sceneMonitor.listScenesBatch": {
|
|
244395
|
+
capName: "scene-monitor",
|
|
244396
|
+
capScope: "device",
|
|
244397
|
+
addonId: null,
|
|
244398
|
+
access: "view"
|
|
244399
|
+
},
|
|
243724
244400
|
"sceneMonitor.recheckNow": {
|
|
243725
244401
|
capName: "scene-monitor",
|
|
243726
244402
|
capScope: "device",
|
|
@@ -245077,6 +245753,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
245077
245753
|
addonId: null,
|
|
245078
245754
|
access: "view"
|
|
245079
245755
|
},
|
|
245756
|
+
"zoneAnalytics.getCurrentSnapshotBatch": {
|
|
245757
|
+
capName: "zone-analytics",
|
|
245758
|
+
capScope: "device",
|
|
245759
|
+
addonId: null,
|
|
245760
|
+
access: "view"
|
|
245761
|
+
},
|
|
245080
245762
|
"zoneAnalytics.getUnzonedHistory": {
|
|
245081
245763
|
capName: "zone-analytics",
|
|
245082
245764
|
capScope: "device",
|
|
@@ -246339,6 +247021,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
246339
247021
|
form: "single",
|
|
246340
247022
|
optional: false
|
|
246341
247023
|
}],
|
|
247024
|
+
"pipelineAnalytics.getKeyEventsBatch": [{
|
|
247025
|
+
name: "deviceIds",
|
|
247026
|
+
form: "array",
|
|
247027
|
+
optional: false
|
|
247028
|
+
}],
|
|
246342
247029
|
"pipelineAnalytics.getMotionEvents": [{
|
|
246343
247030
|
name: "deviceId",
|
|
246344
247031
|
form: "single",
|
|
@@ -246444,6 +247131,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
246444
247131
|
form: "single",
|
|
246445
247132
|
optional: true
|
|
246446
247133
|
}],
|
|
247134
|
+
"pipelineAnalytics.reclaimDebugMedia": [{
|
|
247135
|
+
name: "deviceIds",
|
|
247136
|
+
form: "array",
|
|
247137
|
+
optional: true
|
|
247138
|
+
}],
|
|
246447
247139
|
"pipelineAnalytics.reconcileFromDisk": [{
|
|
246448
247140
|
name: "deviceId",
|
|
246449
247141
|
form: "single",
|
|
@@ -246779,6 +247471,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
246779
247471
|
form: "single",
|
|
246780
247472
|
optional: false
|
|
246781
247473
|
}],
|
|
247474
|
+
"recording.reconcileLedgerAgainstDisk": [{
|
|
247475
|
+
name: "deviceId",
|
|
247476
|
+
form: "single",
|
|
247477
|
+
optional: true
|
|
247478
|
+
}],
|
|
246782
247479
|
"recording.relocateFootage": [{
|
|
246783
247480
|
name: "deviceId",
|
|
246784
247481
|
form: "single",
|
|
@@ -246844,6 +247541,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
246844
247541
|
form: "single",
|
|
246845
247542
|
optional: false
|
|
246846
247543
|
}],
|
|
247544
|
+
"sceneMonitor.listScenesBatch": [{
|
|
247545
|
+
name: "deviceIds",
|
|
247546
|
+
form: "array",
|
|
247547
|
+
optional: false
|
|
247548
|
+
}],
|
|
246847
247549
|
"sceneMonitor.recheckNow": [{
|
|
246848
247550
|
name: "deviceId",
|
|
246849
247551
|
form: "single",
|
|
@@ -247105,6 +247807,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
247105
247807
|
form: "single",
|
|
247106
247808
|
optional: false
|
|
247107
247809
|
}],
|
|
247810
|
+
"zoneAnalytics.getCurrentSnapshotBatch": [{
|
|
247811
|
+
name: "deviceIds",
|
|
247812
|
+
form: "array",
|
|
247813
|
+
optional: false
|
|
247814
|
+
}],
|
|
247108
247815
|
"zoneAnalytics.getUnzonedHistory": [{
|
|
247109
247816
|
name: "deviceId",
|
|
247110
247817
|
form: "single",
|
|
@@ -247257,6 +247964,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
247257
247964
|
"recording.readGopBytes",
|
|
247258
247965
|
"recording.readSegmentBytes",
|
|
247259
247966
|
"recording.readWindowBytes",
|
|
247967
|
+
"recording.reconcileLedgerAgainstDisk",
|
|
247260
247968
|
"recording.relocateFootage",
|
|
247261
247969
|
"recording.renderClip",
|
|
247262
247970
|
"recording.renderGif",
|
|
@@ -248142,6 +248850,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
248142
248850
|
relocateFootage: (input) => dispatch("recording", "relocateFootage", "mutation", input),
|
|
248143
248851
|
listRelocateJobs: (input) => dispatch("recording", "listRelocateJobs", "query", input),
|
|
248144
248852
|
getRelocateResidue: (input) => dispatch("recording", "getRelocateResidue", "query", input),
|
|
248853
|
+
reconcileLedgerAgainstDisk: (input) => dispatch("recording", "reconcileLedgerAgainstDisk", "mutation", input),
|
|
248145
248854
|
cancelRelocateJob: (input) => dispatch("recording", "cancelRelocateJob", "mutation", input),
|
|
248146
248855
|
planStorageRebalance: (input) => dispatch("recording", "planStorageRebalance", "query", input),
|
|
248147
248856
|
startStorageRebalance: (input) => dispatch("recording", "startStorageRebalance", "mutation", input)
|
|
@@ -251102,6 +251811,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
251102
251811
|
exports.CameraMetricsSchema = CameraMetricsSchema;
|
|
251103
251812
|
exports.CameraMetricsWithDeviceIdSchema = CameraMetricsWithDeviceIdSchema;
|
|
251104
251813
|
exports.CameraMotionStatusSchema = CameraMotionStatusSchema;
|
|
251814
|
+
exports.CameraOccupancySnapshotForDeviceSchema = CameraOccupancySnapshotForDeviceSchema;
|
|
251105
251815
|
exports.CameraRecordingModeSchema = CameraRecordingModeSchema;
|
|
251106
251816
|
exports.CameraRecordingStatusSchema = CameraRecordingStatusSchema;
|
|
251107
251817
|
exports.CameraSourceStatusSchema = CameraSourceStatusSchema;
|
|
@@ -251352,6 +252062,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
251352
252062
|
exports.LabelTierSchema = LabelTierSchema;
|
|
251353
252063
|
exports.LawnMowerActivitySchema = LawnMowerActivitySchema;
|
|
251354
252064
|
exports.LawnMowerControlStatusSchema = LawnMowerControlStatusSchema;
|
|
252065
|
+
exports.LedgerWalkDeviceReportSchema = LedgerWalkDeviceReportSchema;
|
|
252066
|
+
exports.LedgerWalkInputSchema = LedgerWalkInputSchema;
|
|
252067
|
+
exports.LedgerWalkRefusalSchema = LedgerWalkRefusalSchema;
|
|
252068
|
+
exports.LedgerWalkReportSchema = LedgerWalkReportSchema;
|
|
252069
|
+
exports.LedgerWalkSkipCountsSchema = LedgerWalkSkipCountsSchema;
|
|
252070
|
+
exports.LedgerWalkSkipReasonSchema = LedgerWalkSkipReasonSchema;
|
|
251355
252071
|
exports.LinkedDeviceSchema = LinkedDeviceSchema;
|
|
251356
252072
|
exports.LinkedDevicesModeSchema = LinkedDevicesModeSchema;
|
|
251357
252073
|
exports.ListGroupsPageSchema = ListGroupsPageSchema;
|
|
@@ -251773,6 +252489,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
251773
252489
|
exports.SceneConfirmSchema = SceneConfirmSchema;
|
|
251774
252490
|
exports.SceneMonitorSchema = SceneMonitorSchema;
|
|
251775
252491
|
exports.SceneMonitorStateSchema = SceneMonitorStateSchema;
|
|
252492
|
+
exports.SceneMonitorStatusForDeviceSchema = SceneMonitorStatusForDeviceSchema;
|
|
251776
252493
|
exports.SceneMonitorStatusSchema = SceneMonitorStatusSchema;
|
|
251777
252494
|
exports.SceneReferenceSchema = SceneReferenceSchema;
|
|
251778
252495
|
exports.SceneUnavailableSchema = SceneUnavailableSchema;
|
|
@@ -410593,6 +411310,7 @@ var require_cap_providers = __commonJS({
|
|
|
410593
411310
|
exports.buildSettingsStoreGateway = buildSettingsStoreGateway;
|
|
410594
411311
|
exports.buildNetworkQualityProvider = buildNetworkQualityProvider;
|
|
410595
411312
|
exports.buildToastProvider = buildToastProvider;
|
|
411313
|
+
exports.computeTopologyPass = computeTopologyPass;
|
|
410596
411314
|
exports.computeTopology = computeTopology;
|
|
410597
411315
|
exports.createNodeRootPackageLookup = createNodeRootPackageLookup;
|
|
410598
411316
|
exports.buildNodesProvider = buildNodesProvider;
|
|
@@ -410741,9 +411459,19 @@ var require_cap_providers = __commonJS({
|
|
|
410741
411459
|
}
|
|
410742
411460
|
return ips;
|
|
410743
411461
|
}
|
|
411462
|
+
async function computeTopologyPass(agentRegistry, addonRegistry, getNodeRootPackage) {
|
|
411463
|
+
const [nodes, liveNodes] = await computeTopologyInternal(agentRegistry, addonRegistry, getNodeRootPackage);
|
|
411464
|
+
return { nodes, liveNodes };
|
|
411465
|
+
}
|
|
410744
411466
|
async function computeTopology(agentRegistry, addonRegistry, getNodeRootPackage) {
|
|
410745
|
-
const nodes = await agentRegistry
|
|
410746
|
-
|
|
411467
|
+
const [nodes] = await computeTopologyInternal(agentRegistry, addonRegistry, getNodeRootPackage);
|
|
411468
|
+
return nodes;
|
|
411469
|
+
}
|
|
411470
|
+
async function computeTopologyInternal(agentRegistry, addonRegistry, getNodeRootPackage) {
|
|
411471
|
+
const [nodes, history] = await Promise.all([
|
|
411472
|
+
agentRegistry.listNodes(),
|
|
411473
|
+
agentRegistry.getClusterNodeHistory()
|
|
411474
|
+
]);
|
|
410747
411475
|
const historyById = new Map(history.map((h) => [h.id, h]));
|
|
410748
411476
|
const liveIds = new Set(nodes.map((n) => n.info.id));
|
|
410749
411477
|
const allAddons = addonRegistry?.listAddons() ?? [];
|
|
@@ -410898,7 +411626,7 @@ var require_cap_providers = __commonJS({
|
|
|
410898
411626
|
categories: [],
|
|
410899
411627
|
rootPackage: null
|
|
410900
411628
|
}));
|
|
410901
|
-
return [...liveNodes, ...offlineNodes];
|
|
411629
|
+
return [[...liveNodes, ...offlineNodes], nodes];
|
|
410902
411630
|
}
|
|
410903
411631
|
function createNodeRootPackageLookup(moleculer, serverUpdate) {
|
|
410904
411632
|
return (nodeId, isHub) => {
|
|
@@ -420624,6 +421352,19 @@ var require_agent_registry_service = __commonJS({
|
|
|
420624
421352
|
addonIds: [...entry.agentAddons ?? []]
|
|
420625
421353
|
};
|
|
420626
421354
|
}
|
|
421355
|
+
function toSubProcess(p) {
|
|
421356
|
+
return {
|
|
421357
|
+
pid: p.pid ?? 0,
|
|
421358
|
+
name: p.name ?? "",
|
|
421359
|
+
command: "moleculer-service",
|
|
421360
|
+
state: p.state ?? "running",
|
|
421361
|
+
cpuPercent: p.cpuPercent ?? 0,
|
|
421362
|
+
memoryRss: p.memoryRss ?? 0,
|
|
421363
|
+
uptimeSeconds: p.uptimeSeconds ?? 0,
|
|
421364
|
+
addonIds: p.addonIds ?? [],
|
|
421365
|
+
groupId: p.groupId ?? null
|
|
421366
|
+
};
|
|
421367
|
+
}
|
|
420627
421368
|
var AgentRegistryService = class {
|
|
420628
421369
|
eventBus;
|
|
420629
421370
|
moleculer;
|
|
@@ -421150,107 +421891,113 @@ var require_agent_registry_service = __commonJS({
|
|
|
421150
421891
|
return toNodeLiveness(this.moleculer.broker.registry.getNodeList({ onlyAvailable: false }));
|
|
421151
421892
|
}
|
|
421152
421893
|
async listNodes() {
|
|
421153
|
-
|
|
421894
|
+
const registry = this.moleculer.broker.registry;
|
|
421895
|
+
const nodes = registry?.getNodeList?.({ onlyAvailable: false }) ?? [];
|
|
421896
|
+
const remoteTargets = nodes.filter((node) => typeof node.id === "string" && node.id !== "hub" && !node.id.includes("/"));
|
|
421897
|
+
const [hubEntry, remoteEntries] = await Promise.all([
|
|
421898
|
+
this.listHubProcesses().then((procs) => this.buildHubEntry(procs)),
|
|
421899
|
+
Promise.all(remoteTargets.map((node) => node.available ? (
|
|
421900
|
+
// Online: one wave of `$agent.status` + `$process.list`.
|
|
421901
|
+
this.buildRemoteEntry(node.id)
|
|
421902
|
+
) : (
|
|
421903
|
+
// Offline: skip the RPC fan-out entirely (the node is unreachable —
|
|
421904
|
+
// those calls would just time out) and surface a minimal,
|
|
421905
|
+
// honestly-degraded row instead.
|
|
421906
|
+
Promise.resolve(this.buildOfflineEntry(node))
|
|
421907
|
+
)))
|
|
421908
|
+
]);
|
|
421909
|
+
return [hubEntry, ...remoteEntries.filter((entry) => entry !== null)];
|
|
421910
|
+
}
|
|
421911
|
+
/** The hub's own runner subprocesses (`$process.list`, hub-local). */
|
|
421912
|
+
async listHubProcesses() {
|
|
421154
421913
|
try {
|
|
421155
421914
|
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
|
-
}));
|
|
421915
|
+
return processes.map(toSubProcess);
|
|
421167
421916
|
} catch {
|
|
421917
|
+
return [];
|
|
421168
421918
|
}
|
|
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
421919
|
}
|
|
421248
421920
|
/**
|
|
421249
|
-
*
|
|
421250
|
-
*
|
|
421251
|
-
* `
|
|
421921
|
+
* One online agent's row: `$agent.status` for the descriptor + live metrics,
|
|
421922
|
+
* `$process.list` for real sub-process stats. `null` when the node has no
|
|
421923
|
+
* `$agent` service (it is then simply absent from the list, as before).
|
|
421924
|
+
*
|
|
421925
|
+
* The two calls are ONE wave, not two: `$process.list` never reads anything
|
|
421926
|
+
* from `$agent.status` — only its FALLBACK does, and the fallback is applied
|
|
421927
|
+
* after both have settled.
|
|
421928
|
+
*/
|
|
421929
|
+
async buildRemoteEntry(nodeId) {
|
|
421930
|
+
const [statusResult, processResult] = await Promise.allSettled([
|
|
421931
|
+
this.broker.call("$agent.status", {}, { nodeID: nodeId, timeout: 5e3 }),
|
|
421932
|
+
this.broker.call("$process.list", {}, { nodeID: nodeId, timeout: 5e3 })
|
|
421933
|
+
]);
|
|
421934
|
+
if (statusResult.status === "rejected")
|
|
421935
|
+
return null;
|
|
421936
|
+
const status = statusResult.value;
|
|
421937
|
+
const subProcesses = processResult.status === "fulfilled" ? processResult.value.map(toSubProcess) : (
|
|
421938
|
+
// Fall back to the addon list from $agent.status (no stats)
|
|
421939
|
+
status.addons?.map((a) => ({
|
|
421940
|
+
pid: 0,
|
|
421941
|
+
name: a.id ?? "",
|
|
421942
|
+
command: "moleculer-service",
|
|
421943
|
+
state: a.status ?? "running",
|
|
421944
|
+
cpuPercent: 0,
|
|
421945
|
+
memoryRss: 0,
|
|
421946
|
+
uptimeSeconds: 0
|
|
421947
|
+
})) ?? []
|
|
421948
|
+
);
|
|
421949
|
+
const agentAddons = status.addons?.map((a) => a.id) ?? [];
|
|
421950
|
+
const hostname = typeof status.hostname === "string" ? status.hostname : null;
|
|
421951
|
+
const agentName = typeof status.name === "string" ? status.name : nodeId;
|
|
421952
|
+
return {
|
|
421953
|
+
info: {
|
|
421954
|
+
id: nodeId,
|
|
421955
|
+
name: agentName,
|
|
421956
|
+
hostname: hostname ?? nodeId,
|
|
421957
|
+
capabilities: [],
|
|
421958
|
+
platform: status.platform ?? "unknown",
|
|
421959
|
+
arch: status.arch ?? "unknown",
|
|
421960
|
+
cpuCores: status.cpuCores ?? 0,
|
|
421961
|
+
memoryMB: status.totalMemoryMB ?? 0,
|
|
421962
|
+
cpuModel: status.cpuModel
|
|
421963
|
+
},
|
|
421964
|
+
localIps: Array.isArray(status.localIps) ? status.localIps : [],
|
|
421965
|
+
status: {
|
|
421966
|
+
activeCameras: 0,
|
|
421967
|
+
cpuPercent: status.cpuPercent ?? 0,
|
|
421968
|
+
memoryPercent: status.memoryPercent ?? 0,
|
|
421969
|
+
fps: {},
|
|
421970
|
+
errors: []
|
|
421971
|
+
},
|
|
421972
|
+
connectedSince: typeof status.uptime === "number" ? Date.now() - status.uptime * 1e3 : Date.now(),
|
|
421973
|
+
isHub: false,
|
|
421974
|
+
subProcesses,
|
|
421975
|
+
agentAddons
|
|
421976
|
+
};
|
|
421977
|
+
}
|
|
421978
|
+
/**
|
|
421979
|
+
* A1 (R2 capture point): snapshot every ONLINE node's static descriptor +
|
|
421980
|
+
* last-known addon roster into the durable, routing-blind history store.
|
|
421981
|
+
* This is the ONLY place cpuModel/cores/memory/localIps are resolved from a
|
|
421982
|
+
* live `$agent.status`, so it is where an offline row's descriptor must be
|
|
421983
|
+
* captured while the node is still reachable. Offline entries are NOT
|
|
421984
|
+
* re-snapshotted — their `lastActive` is stamped on `$node.disconnected`
|
|
421985
|
+
* instead. This is a separate durable store, never a `knownAgents`-style
|
|
421986
|
+
* shadow of `HubNodeRegistry` (which stays the ephemeral live cap authority).
|
|
421987
|
+
*
|
|
421988
|
+
* **It belongs to the PERIODIC PASS, not to a read** (D317). It used to run
|
|
421989
|
+
* at the tail of `listNodes()`, which made every operator poll of
|
|
421990
|
+
* `nodes.topology` perform one durable read-back — and, past the five-minute
|
|
421991
|
+
* heartbeat, one durable write — per online node, in a phase that had to
|
|
421992
|
+
* finish before the history read could even start. Measured on the live hub
|
|
421993
|
+
* on 2026-08-31: one settings-store round trip cost 14.8–18.3 s and
|
|
421994
|
+
* `nodes.topology` cost exactly two of them, 30.5 s. `TopologyEmitterService`
|
|
421995
|
+
* already recomputes this picture every 30 s; the capture is its work.
|
|
421996
|
+
*
|
|
421997
|
+
* Never throws — the store swallows its own errors and this awaits
|
|
421998
|
+
* `allSettled` so a storage hiccup can never fail the pass.
|
|
421252
421999
|
*/
|
|
421253
|
-
async
|
|
422000
|
+
async captureNodeHistory(entries) {
|
|
421254
422001
|
if (!this.historyStore)
|
|
421255
422002
|
return;
|
|
421256
422003
|
const online = entries.filter((e) => e.isOnline !== false);
|
|
@@ -423900,7 +424647,7 @@ var require_topology_emitter_service = __commonJS({
|
|
|
423900
424647
|
return;
|
|
423901
424648
|
this.emitting = true;
|
|
423902
424649
|
try {
|
|
423903
|
-
const nodes = await (0, cap_providers_1.
|
|
424650
|
+
const { nodes, liveNodes } = await (0, cap_providers_1.computeTopologyPass)(this.agentRegistry, this.addonRegistry, this.getNodeRootPackage);
|
|
423904
424651
|
this.eventBus.emit({
|
|
423905
424652
|
id: (0, node_crypto_1.randomUUID)(),
|
|
423906
424653
|
timestamp: /* @__PURE__ */ new Date(),
|
|
@@ -423908,6 +424655,7 @@ var require_topology_emitter_service = __commonJS({
|
|
|
423908
424655
|
category: types_1.EventCategory.ClusterTopologySnapshot,
|
|
423909
424656
|
data: { nodes, timestamp: Date.now() }
|
|
423910
424657
|
});
|
|
424658
|
+
await this.agentRegistry.captureNodeHistory(liveNodes);
|
|
423911
424659
|
} catch {
|
|
423912
424660
|
} finally {
|
|
423913
424661
|
this.emitting = false;
|