camstack 1.2.145 → 1.2.147
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-CEIkHEdy.js
|
|
23637
|
+
var require_dist_CEIkHEdy = __commonJS({
|
|
23638
|
+
"../system/dist/dist-CEIkHEdy.js"(exports) {
|
|
23639
23639
|
"use strict";
|
|
23640
23640
|
var zod = require_zod();
|
|
23641
23641
|
var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
|
|
@@ -23776,6 +23776,7 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
23776
23776
|
EventCategory2["LocalNetworkChanged"] = "network.local.changed";
|
|
23777
23777
|
EventCategory2["MeshNetworkChanged"] = "network.mesh.changed";
|
|
23778
23778
|
EventCategory2["BackupCompleted"] = "backup.completed";
|
|
23779
|
+
EventCategory2["BackupRunCompleted"] = "backup.run-completed";
|
|
23779
23780
|
EventCategory2["BackupRestored"] = "backup.restored";
|
|
23780
23781
|
EventCategory2["NotificationDispatched"] = "notification.dispatched";
|
|
23781
23782
|
EventCategory2["NotificationFailed"] = "notification.failed";
|
|
@@ -25889,7 +25890,23 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
25889
25890
|
"zerolatency",
|
|
25890
25891
|
"film",
|
|
25891
25892
|
"animation"
|
|
25892
|
-
]).optional()
|
|
25893
|
+
]).optional(),
|
|
25894
|
+
/**
|
|
25895
|
+
* ONE slice per access unit.
|
|
25896
|
+
*
|
|
25897
|
+
* `-tune zerolatency` turns on x264's sliced threads, and a frame then leaves
|
|
25898
|
+
* the encoder as five NAL slices that share one RTP timestamp and carry one
|
|
25899
|
+
* marker bit. A libwebrtc depacketiser sees five frame-starts and one
|
|
25900
|
+
* frame-end per frame: the first pictures render and the video then freezes
|
|
25901
|
+
* for good while the audio, on its own plane, plays on. Measured on this hub
|
|
25902
|
+
* 2026-09-13 against the Echo, and reduced to one slice by this flag alone.
|
|
25903
|
+
*
|
|
25904
|
+
* A NAMED field and not a raw flag, because {@link EgressEncodeSchema} omits
|
|
25905
|
+
* `outputArgs` on purpose: an opaque array is part of the sharing key, so two
|
|
25906
|
+
* consumers meaning the same thing spelled differently would stop sharing one
|
|
25907
|
+
* child. Absent means "whatever the encoder does" — today's behaviour.
|
|
25908
|
+
*/
|
|
25909
|
+
singleSlicePerFrame: zod.z.boolean().optional()
|
|
25893
25910
|
});
|
|
25894
25911
|
var AudioEncodeSchema = zod.z.union([zod.z.literal("passthrough"), zod.z.object({
|
|
25895
25912
|
codec: zod.z.enum([
|
|
@@ -25937,7 +25954,7 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
25937
25954
|
audio: "passthrough"
|
|
25938
25955
|
};
|
|
25939
25956
|
({ ...BASE_LIVE_EGRESS_PROFILE }, { ...BASE_LIVE_EGRESS_PROFILE.video });
|
|
25940
|
-
({ ...BASE_LIVE_EGRESS_PROFILE });
|
|
25957
|
+
({ ...BASE_LIVE_EGRESS_PROFILE }, { ...BASE_LIVE_EGRESS_PROFILE.video });
|
|
25941
25958
|
var wiringProbeKindSchema = zod.z.enum([
|
|
25942
25959
|
"singleton",
|
|
25943
25960
|
"device",
|
|
@@ -29430,6 +29447,39 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
29430
29447
|
exposesDeviceSettings: true,
|
|
29431
29448
|
methods: {}
|
|
29432
29449
|
};
|
|
29450
|
+
var StreamSignalSchema = zod.z.object({
|
|
29451
|
+
/** Stable id chosen by the provider, e.g. `'motion'`, `'person'`, `'tamper'`. */
|
|
29452
|
+
code: zod.z.string().min(1),
|
|
29453
|
+
/** What an operator reads in the picker. The provider's own wording. */
|
|
29454
|
+
label: zod.z.string().min(1),
|
|
29455
|
+
/**
|
|
29456
|
+
* Whether the provider recommends this signal ON when a camera is first set
|
|
29457
|
+
* up. A provider knows which of its signals are cheap and reliable; an
|
|
29458
|
+
* operator should not have to discover that by trial. Reolink recommends
|
|
29459
|
+
* both of its own.
|
|
29460
|
+
*/
|
|
29461
|
+
recommended: zod.z.boolean()
|
|
29462
|
+
});
|
|
29463
|
+
var StreamSignalsStatusSchema = zod.z.object({
|
|
29464
|
+
signals: zod.z.array(StreamSignalSchema),
|
|
29465
|
+
lastFetchedAt: zod.z.number()
|
|
29466
|
+
});
|
|
29467
|
+
var streamSignalsCapability = {
|
|
29468
|
+
name: "stream-signals",
|
|
29469
|
+
scope: "device",
|
|
29470
|
+
deviceNative: true,
|
|
29471
|
+
mode: "singleton",
|
|
29472
|
+
deviceTypes: Object.values(DeviceType),
|
|
29473
|
+
runtimeState: StreamSignalsStatusSchema,
|
|
29474
|
+
methods: {
|
|
29475
|
+
/**
|
|
29476
|
+
* What this device can emit. Empty is a valid and common answer — most
|
|
29477
|
+
* cameras have nothing to offer here, and an empty list is what makes the
|
|
29478
|
+
* broker's picker show nothing rather than a false choice.
|
|
29479
|
+
*/
|
|
29480
|
+
listSignals: method(zod.z.void(), zod.z.array(StreamSignalSchema).readonly())
|
|
29481
|
+
}
|
|
29482
|
+
};
|
|
29433
29483
|
var StreamFormatSchema = zod.z.enum([
|
|
29434
29484
|
"webrtc",
|
|
29435
29485
|
"hls",
|
|
@@ -29782,6 +29832,46 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
29782
29832
|
mode: "singleton",
|
|
29783
29833
|
exposesDeviceSettings: true,
|
|
29784
29834
|
methods: {
|
|
29835
|
+
/**
|
|
29836
|
+
* A device reporting that one of ITS OWN signals just fired.
|
|
29837
|
+
*
|
|
29838
|
+
* The provider calls this; nothing polls. The broker then decides whether
|
|
29839
|
+
* to wake the source, and the decision has two terms that must BOTH hold:
|
|
29840
|
+
*
|
|
29841
|
+
* - the signal is ENABLED for this camera (the operator's per-camera
|
|
29842
|
+
* choice — a camera may declare a signal the operator does not want
|
|
29843
|
+
* waking anything), and
|
|
29844
|
+
* - a consumer is actually attached and waiting on the prestream. Waking
|
|
29845
|
+
* a camera nobody is watching is the one thing a battery camera must
|
|
29846
|
+
* never do, and a signal arriving with no consumer is exactly that.
|
|
29847
|
+
*
|
|
29848
|
+
* Reported, never inferred: a signal that fires while the stream is
|
|
29849
|
+
* already up refreshes the hold instead of starting a second one, which is
|
|
29850
|
+
* what makes continuous motion keep a camera awake without stacking
|
|
29851
|
+
* timers.
|
|
29852
|
+
*
|
|
29853
|
+
* `code` is the provider's own, from `streamSignals.listSignals`. An
|
|
29854
|
+
* unknown code is REFUSED rather than treated as a wildcard wake — a
|
|
29855
|
+
* provider and an operator disagreeing about a name must not become a
|
|
29856
|
+
* camera that wakes for everything.
|
|
29857
|
+
*/
|
|
29858
|
+
reportStreamSignal: method(zod.z.object({
|
|
29859
|
+
deviceId: zod.z.number().int().nonnegative(),
|
|
29860
|
+
/** The provider's signal code. */
|
|
29861
|
+
code: zod.z.string().min(1),
|
|
29862
|
+
/** Ms epoch. Absent ⇒ now. */
|
|
29863
|
+
at: zod.z.number().optional()
|
|
29864
|
+
}), zod.z.object({
|
|
29865
|
+
/** Whether the broker acted on it, and if not, why. */
|
|
29866
|
+
accepted: zod.z.boolean(),
|
|
29867
|
+
reason: zod.z.enum([
|
|
29868
|
+
"woke",
|
|
29869
|
+
"hold-extended",
|
|
29870
|
+
"not-enabled",
|
|
29871
|
+
"no-consumer",
|
|
29872
|
+
"unknown-code"
|
|
29873
|
+
])
|
|
29874
|
+
}), { kind: "mutation" }),
|
|
29785
29875
|
publishCameraStream: method(zod.z.object({
|
|
29786
29876
|
deviceId: zod.z.number().int().nonnegative(),
|
|
29787
29877
|
camStreamId: zod.z.string().min(1),
|
|
@@ -30259,6 +30349,16 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
30259
30349
|
acceptCodecs: zod.z.array(StreamCodecSchema).readonly().optional(),
|
|
30260
30350
|
/** Minimum vertical resolution. Streams shorter than this are dropped. */
|
|
30261
30351
|
minHeight: zod.z.number().int().positive().optional(),
|
|
30352
|
+
/**
|
|
30353
|
+
* Maximum vertical resolution. Streams TALLER than this are dropped.
|
|
30354
|
+
*
|
|
30355
|
+
* A consumer can have a ceiling as real as its floor: Alexa documents
|
|
30356
|
+
* 480p to 1080p, and a 4K stream is as unusable to an Echo as a 360p one.
|
|
30357
|
+
* Without this the ceiling had to be re-implemented by every caller — and
|
|
30358
|
+
* one caller implementing it privately is how a second scoring authority
|
|
30359
|
+
* gets born.
|
|
30360
|
+
*/
|
|
30361
|
+
maxHeight: zod.z.number().int().positive().optional(),
|
|
30262
30362
|
/** Minimum horizontal resolution. */
|
|
30263
30363
|
minWidth: zod.z.number().int().positive().optional(),
|
|
30264
30364
|
/**
|
|
@@ -30275,7 +30375,22 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
30275
30375
|
* transcoded" guard: if the device is already serving the consumer's
|
|
30276
30376
|
* codec end-to-end, there's nothing to optimise.
|
|
30277
30377
|
*/
|
|
30278
|
-
requireSiblingCodec: zod.z.array(StreamCodecSchema).readonly().optional()
|
|
30378
|
+
requireSiblingCodec: zod.z.array(StreamCodecSchema).readonly().optional(),
|
|
30379
|
+
/**
|
|
30380
|
+
* Whether a stream the consumer CANNOT decode may still be picked, on the
|
|
30381
|
+
* understanding that it will be transcoded.
|
|
30382
|
+
*
|
|
30383
|
+
* Default `false` — today's behaviour, and the right one for a bypass
|
|
30384
|
+
* question ("is there a stream I can forward untouched?"). Set `true` to
|
|
30385
|
+
* ask the larger question: "what is the best stream for me, transcoding if
|
|
30386
|
+
* I must?" A stream that satisfies `acceptCodecs` always outranks one that
|
|
30387
|
+
* does not, so a passthrough is never lost to a transcode; the answer says
|
|
30388
|
+
* which it is in {@link PickedCamStreamSchema.transcodes}.
|
|
30389
|
+
*
|
|
30390
|
+
* This is what lets one picker serve both the bypass and the full source
|
|
30391
|
+
* choice, instead of a consumer scoring privately when the bypass misses.
|
|
30392
|
+
*/
|
|
30393
|
+
allowTranscode: zod.z.boolean().optional()
|
|
30279
30394
|
}).readonly();
|
|
30280
30395
|
var PickStreamPreferencesSchema = zod.z.object({
|
|
30281
30396
|
/**
|
|
@@ -30289,12 +30404,32 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
30289
30404
|
* picks the tallest stream; `'lowest'` picks the shortest (used by
|
|
30290
30405
|
* memory-constrained consumers / Apple Home guest sessions).
|
|
30291
30406
|
*/
|
|
30292
|
-
resolutionPreference: zod.z.enum(["highest", "lowest"]).optional()
|
|
30407
|
+
resolutionPreference: zod.z.enum(["highest", "lowest"]).optional(),
|
|
30408
|
+
/**
|
|
30409
|
+
* The height the consumer actually wants to DELIVER.
|
|
30410
|
+
*
|
|
30411
|
+
* Not a constraint — an ordering. With it set, the SMALLEST stream at or
|
|
30412
|
+
* above the target wins, and only if nothing reaches it does the tallest
|
|
30413
|
+
* take over. Pulling 1296 lines to draw 720 on a 1280x800 Echo panel costs
|
|
30414
|
+
* a decode and buys nothing, and `resolutionPreference: 'highest'` cannot
|
|
30415
|
+
* express that: it says "as big as possible", which is a different wish.
|
|
30416
|
+
*
|
|
30417
|
+
* Ignored when absent, so every existing caller keeps its ordering.
|
|
30418
|
+
*/
|
|
30419
|
+
targetHeight: zod.z.number().int().positive().optional()
|
|
30293
30420
|
}).readonly();
|
|
30294
30421
|
var PickedCamStreamSchema = zod.z.object({
|
|
30295
30422
|
camStreamId: zod.z.string(),
|
|
30296
30423
|
codec: zod.z.string().optional(),
|
|
30297
30424
|
resolution: CamStreamResolutionSchema.optional(),
|
|
30425
|
+
/**
|
|
30426
|
+
* Whether serving this stream requires a decode + re-encode.
|
|
30427
|
+
*
|
|
30428
|
+
* `false` is a stream the consumer can take as it stands. Only ever `true`
|
|
30429
|
+
* when the caller asked for it with `allowTranscode`, so a caller that did
|
|
30430
|
+
* not ask cannot be handed a cost it never agreed to pay.
|
|
30431
|
+
*/
|
|
30432
|
+
transcodes: zod.z.boolean(),
|
|
30298
30433
|
/** One-line explanation of why this stream won — for logs / debug UI. */
|
|
30299
30434
|
reason: zod.z.string()
|
|
30300
30435
|
});
|
|
@@ -35208,6 +35343,8 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
35208
35343
|
"device-enabled",
|
|
35209
35344
|
"device-battery-low",
|
|
35210
35345
|
"device-battery-normal",
|
|
35346
|
+
"device-consumable-low",
|
|
35347
|
+
"device-consumable-normal",
|
|
35211
35348
|
"stream-online",
|
|
35212
35349
|
"stream-offline",
|
|
35213
35350
|
"node-online",
|
|
@@ -35226,6 +35363,7 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
35226
35363
|
"addon-updated",
|
|
35227
35364
|
"server-updated",
|
|
35228
35365
|
"export-completed",
|
|
35366
|
+
"backup-completed",
|
|
35229
35367
|
"camera-online",
|
|
35230
35368
|
"camera-offline",
|
|
35231
35369
|
"camera-disabled",
|
|
@@ -38084,13 +38222,91 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
38084
38222
|
deviceIds: zod.z.array(zod.z.number()).min(1),
|
|
38085
38223
|
since: zod.z.number().optional(),
|
|
38086
38224
|
until: zod.z.number().optional(),
|
|
38087
|
-
limit: zod.z.number().int().min(1).max(200).default(50)
|
|
38225
|
+
limit: zod.z.number().int().min(1).max(200).default(50),
|
|
38226
|
+
/** The same member-wise filter {@link listRecentSummaries} takes — one
|
|
38227
|
+
* meaning of "dog" on every summary surface. */
|
|
38228
|
+
classes: zod.z.array(zod.z.string().min(1).max(60)).max(40).optional()
|
|
38229
|
+
});
|
|
38230
|
+
var SummaryMemberSchema = zod.z.object({
|
|
38231
|
+
trackId: zod.z.string(),
|
|
38232
|
+
/**
|
|
38233
|
+
* The track's class at the time it JOINED, or `null` when it was unresolved
|
|
38234
|
+
* and the track no longer exists to fill it.
|
|
38235
|
+
*
|
|
38236
|
+
* The join, not the latest opinion: class voting can re-decide a track's
|
|
38237
|
+
* class afterwards, and a group's composition is the history of who came
|
|
38238
|
+
* together. A consumer counts these to badge a thumbnail — "two people and a
|
|
38239
|
+
* dog" — rather than being handed a second, denormalised tally that would
|
|
38240
|
+
* drift from the members it claims to describe.
|
|
38241
|
+
*/
|
|
38242
|
+
className: zod.z.string().nullable(),
|
|
38243
|
+
/** `primary` is the one member that carries the group's identity. */
|
|
38244
|
+
role: zod.z.enum([
|
|
38245
|
+
"primary",
|
|
38246
|
+
"sibling",
|
|
38247
|
+
"child"
|
|
38248
|
+
]).nullable(),
|
|
38249
|
+
joinedAt: zod.z.number(),
|
|
38250
|
+
/** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
|
|
38251
|
+
* at read time. Absent when nothing resolved, never an empty string. */
|
|
38252
|
+
label: zod.z.string().optional(),
|
|
38253
|
+
/** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
|
|
38254
|
+
* recognised nobody, and absent for a member whose track has been pruned —
|
|
38255
|
+
* a thumbnail that names the wrong person is worse than one naming nobody. */
|
|
38256
|
+
subLabel: zod.z.string().optional()
|
|
38088
38257
|
});
|
|
38089
|
-
var SummariesPageSchema = zod.z.object({ summaries: zod.z.array(SummarySchema).readonly() });
|
|
38090
38258
|
var SummaryDetailSchema = zod.z.object({
|
|
38091
38259
|
summary: SummarySchema,
|
|
38092
|
-
/**
|
|
38093
|
-
|
|
38260
|
+
/** Members in absorption order, oldest join first. */
|
|
38261
|
+
members: zod.z.array(SummaryMemberSchema).readonly()
|
|
38262
|
+
});
|
|
38263
|
+
var SummaryListItemSchema = zod.z.object({
|
|
38264
|
+
summary: SummarySchema,
|
|
38265
|
+
/** Class counts, most numerous first; `className: null` is a member whose
|
|
38266
|
+
* class never resolved, counted so the counts add up to `memberCount`. */
|
|
38267
|
+
classes: zod.z.array(zod.z.object({
|
|
38268
|
+
className: zod.z.string().nullable(),
|
|
38269
|
+
count: zod.z.number().int().positive()
|
|
38270
|
+
})).readonly()
|
|
38271
|
+
});
|
|
38272
|
+
var SummariesPageSchema = zod.z.object({ summaries: zod.z.array(SummaryListItemSchema).readonly() });
|
|
38273
|
+
var RecentSummariesQueryInput = zod.z.object({
|
|
38274
|
+
/** Devices to merge. An empty array yields an empty page. */
|
|
38275
|
+
deviceIds: zod.z.array(zod.z.number()),
|
|
38276
|
+
/** Window lower bound on `lastActiveAt` (inclusive). */
|
|
38277
|
+
since: zod.z.number().optional(),
|
|
38278
|
+
/** Window upper bound on `lastActiveAt` (inclusive). */
|
|
38279
|
+
until: zod.z.number().optional(),
|
|
38280
|
+
limit: zod.z.number().int().min(1).max(500).default(100),
|
|
38281
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
38282
|
+
cursor: zod.z.string().optional(),
|
|
38283
|
+
/**
|
|
38284
|
+
* Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
|
|
38285
|
+
* deliberately the same name: the events filter tree emits one list of ticked
|
|
38286
|
+
* taxonomy nodes, and a summaries feed that called it something else would
|
|
38287
|
+
* make the operator's one filter component produce two shapes.
|
|
38288
|
+
*
|
|
38289
|
+
* A question about the MEMBERS: a group matches when ANY of them does. "Show
|
|
38290
|
+
* me the arrivals with a dog" has to return the group of four people who had
|
|
38291
|
+
* one with them; a filter on the group's own fields could only ever answer
|
|
38292
|
+
* about its primary.
|
|
38293
|
+
*
|
|
38294
|
+
* Matched against all THREE tiers of a member — the class (`animal`), the
|
|
38295
|
+
* sub-class (`dog`) and the instance (a name, a plate) — because which tier a
|
|
38296
|
+
* ticked node lives on is the taxonomy's business, not the caller's. `dog` is
|
|
38297
|
+
* an event kind in the tree and a tier-1 label on an `animal` track; a filter
|
|
38298
|
+
* that read only the class would answer "animal" and never "dog".
|
|
38299
|
+
*
|
|
38300
|
+
* ABSENT or EMPTY means no filter — absent is not a selection of none.
|
|
38301
|
+
*/
|
|
38302
|
+
classes: zod.z.array(zod.z.string().min(1).max(60)).max(40).optional()
|
|
38303
|
+
});
|
|
38304
|
+
var RecentSummariesPageSchema = zod.z.object({
|
|
38305
|
+
/** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
|
|
38306
|
+
* {@link listSummaries} — one list shape, so a card renders the same
|
|
38307
|
+
* whichever feed drew it. */
|
|
38308
|
+
summaries: zod.z.array(SummaryListItemSchema).readonly(),
|
|
38309
|
+
nextCursor: zod.z.string().nullable()
|
|
38094
38310
|
});
|
|
38095
38311
|
var RecentTracksPageSchema = zod.z.object({
|
|
38096
38312
|
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
@@ -38442,6 +38658,11 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
38442
38658
|
listRecentTracks: method(RecentTracksQueryInput, RecentTracksPageSchema),
|
|
38443
38659
|
/** Newest first by `openedAt`, for a camera set, inside an optional window. */
|
|
38444
38660
|
listSummaries: method(SummariesQueryInput, SummariesPageSchema),
|
|
38661
|
+
/**
|
|
38662
|
+
* The PAGED feed — the reel and the Events gallery. Same cursor contract as
|
|
38663
|
+
* {@link listRecentTracks}, so one screen cannot hold two ideas of newest.
|
|
38664
|
+
*/
|
|
38665
|
+
listRecentSummaries: method(RecentSummariesQueryInput, RecentSummariesPageSchema),
|
|
38445
38666
|
/** One summary with its member track ids; `null` for an id nobody wrote. */
|
|
38446
38667
|
getSummary: method(zod.z.object({ id: zod.z.string() }), SummaryDetailSchema.nullable()),
|
|
38447
38668
|
clearTracks: method(zod.z.object({ deviceId: zod.z.number() }), zod.z.void(), {
|
|
@@ -42731,10 +42952,28 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
42731
42952
|
getSessionState: method(zod.z.object({
|
|
42732
42953
|
deviceId: zod.z.number().int().nonnegative(),
|
|
42733
42954
|
sessionId: zod.z.string()
|
|
42734
|
-
}), zod.z.object({
|
|
42735
|
-
|
|
42736
|
-
|
|
42737
|
-
|
|
42955
|
+
}), zod.z.object({
|
|
42956
|
+
pendingRenegotiation: zod.z.object({
|
|
42957
|
+
target: WebrtcStreamTargetSchema,
|
|
42958
|
+
epoch: zod.z.number()
|
|
42959
|
+
}).nullable(),
|
|
42960
|
+
/**
|
|
42961
|
+
* Whether the session still EXISTS.
|
|
42962
|
+
*
|
|
42963
|
+
* A consumer that holds a resource for the life of a session needs to
|
|
42964
|
+
* be able to ask, because a session does not always end the way it
|
|
42965
|
+
* began. Measured on this hub 2026-09-13: an Echo that got stuck never
|
|
42966
|
+
* sent `SessionDisconnected`, so the Alexa exporter's
|
|
42967
|
+
* `releaseEgressTranscode` never ran, and a 2304x1296 HEVC to 720p
|
|
42968
|
+
* H.264 transcode kept running for NOBODY for more than twenty
|
|
42969
|
+
* minutes. The WebRTC session had logged `WebRTC session closed`
|
|
42970
|
+
* minutes earlier — the broker knew; the holder had no way to ask.
|
|
42971
|
+
*
|
|
42972
|
+
* `false` for a session id the provider has never heard of, which is
|
|
42973
|
+
* the same answer as "it ended": either way nothing is holding it up.
|
|
42974
|
+
*/
|
|
42975
|
+
alive: zod.z.boolean()
|
|
42976
|
+
}))
|
|
42738
42977
|
},
|
|
42739
42978
|
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
42740
42979
|
mount: { kind: "server-provided" }
|
|
@@ -50683,7 +50922,29 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
50683
50922
|
* disarmed the channels it did not mention would make the Levels page and
|
|
50684
50923
|
* the Diagnostics page fight over the same value.
|
|
50685
50924
|
*/
|
|
50686
|
-
channels: zod.z.array(LogChannelWindowPatchSchema).readonly().optional()
|
|
50925
|
+
channels: zod.z.array(LogChannelWindowPatchSchema).readonly().optional(),
|
|
50926
|
+
/**
|
|
50927
|
+
* How many days the analytics OPS LOG is kept — the audit trail of what
|
|
50928
|
+
* retention actually deleted.
|
|
50929
|
+
*
|
|
50930
|
+
* It lives HERE, on the logging document, and not on the analytics addon's
|
|
50931
|
+
* settings form, on the operator's instruction: every other log-ish window in
|
|
50932
|
+
* this system is configured through this one document, and a retention audit
|
|
50933
|
+
* configured somewhere else is a second place to look when the question is
|
|
50934
|
+
* "what happened to my data".
|
|
50935
|
+
*
|
|
50936
|
+
* That placement has a cost worth stating: this document ships in the
|
|
50937
|
+
* framework closure, so this knob needs a published `@camstack/server` while
|
|
50938
|
+
* the four windows beside it (D485) reach a node on `camstack deploy`.
|
|
50939
|
+
*
|
|
50940
|
+
* `retention-model.ts` argued this one must NOT follow a device window,
|
|
50941
|
+
* because the audit trail is the history of the SWEEP and not of the camera.
|
|
50942
|
+
* That argument stands and is untouched — what changes is that 30 days stops
|
|
50943
|
+
* being a constant nobody can reach. `0` keeps it forever. The floor is 1 day
|
|
50944
|
+
* rather than 0-as-delete: an audit log truncated to nothing is precisely the
|
|
50945
|
+
* state in which the next 9.5 GiB leak cannot be explained.
|
|
50946
|
+
*/
|
|
50947
|
+
opsLogRetentionDays: zod.z.number().int().min(0).max(3650).optional()
|
|
50687
50948
|
});
|
|
50688
50949
|
var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: zod.z.string() });
|
|
50689
50950
|
var ReportedFailureContributionSchema = FailureContributionSchema.extend({ addonId: zod.z.string() });
|
|
@@ -50722,6 +50983,14 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
50722
50983
|
channels: zod.z.array(LogChannelDescriptorSchema).readonly(),
|
|
50723
50984
|
/** The channels ARMED right now, each with its deadline. */
|
|
50724
50985
|
activeChannels: zod.z.array(LogChannelWindowStateSchema).readonly(),
|
|
50986
|
+
/**
|
|
50987
|
+
* The ops-log window in days, as it is in force. `0` = kept forever.
|
|
50988
|
+
*
|
|
50989
|
+
* Reported rather than left to the caller's memory of what it wrote: this is
|
|
50990
|
+
* the value the analytics sweep will actually use, and an operator asking how
|
|
50991
|
+
* long their audit trail lives should not have to infer it from a default.
|
|
50992
|
+
*/
|
|
50993
|
+
opsLogRetentionDays: zod.z.number().int().min(0),
|
|
50725
50994
|
persisted: zod.z.boolean()
|
|
50726
50995
|
});
|
|
50727
50996
|
var systemCapability = {
|
|
@@ -52377,6 +52646,7 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
52377
52646
|
streamBrokerCapability,
|
|
52378
52647
|
streamCatalogCapability,
|
|
52379
52648
|
streamParamsCapability,
|
|
52649
|
+
streamSignalsCapability,
|
|
52380
52650
|
switchCapability,
|
|
52381
52651
|
systemCapability,
|
|
52382
52652
|
tamperCapability,
|
|
@@ -55851,6 +56121,12 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
55851
56121
|
addonId: null,
|
|
55852
56122
|
access: "view"
|
|
55853
56123
|
},
|
|
56124
|
+
"pipelineAnalytics.listRecentSummaries": {
|
|
56125
|
+
capName: "pipeline-analytics",
|
|
56126
|
+
capScope: "device",
|
|
56127
|
+
addonId: null,
|
|
56128
|
+
access: "view"
|
|
56129
|
+
},
|
|
55854
56130
|
"pipelineAnalytics.listRecentTracks": {
|
|
55855
56131
|
capName: "pipeline-analytics",
|
|
55856
56132
|
capScope: "device",
|
|
@@ -57813,6 +58089,12 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
57813
58089
|
addonId: null,
|
|
57814
58090
|
access: "create"
|
|
57815
58091
|
},
|
|
58092
|
+
"streamBroker.reportStreamSignal": {
|
|
58093
|
+
capName: "stream-broker",
|
|
58094
|
+
capScope: "system",
|
|
58095
|
+
addonId: null,
|
|
58096
|
+
access: "create"
|
|
58097
|
+
},
|
|
57816
58098
|
"streamBroker.restartProfile": {
|
|
57817
58099
|
capName: "stream-broker",
|
|
57818
58100
|
capScope: "system",
|
|
@@ -57897,6 +58179,12 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
57897
58179
|
addonId: null,
|
|
57898
58180
|
access: "create"
|
|
57899
58181
|
},
|
|
58182
|
+
"streamSignals.listSignals": {
|
|
58183
|
+
capName: "stream-signals",
|
|
58184
|
+
capScope: "device",
|
|
58185
|
+
addonId: null,
|
|
58186
|
+
access: "view"
|
|
58187
|
+
},
|
|
57900
58188
|
"switch.setState": {
|
|
57901
58189
|
capName: "switch",
|
|
57902
58190
|
capScope: "device",
|
|
@@ -59678,6 +59966,11 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
59678
59966
|
form: "single",
|
|
59679
59967
|
optional: true
|
|
59680
59968
|
}],
|
|
59969
|
+
"pipelineAnalytics.listRecentSummaries": [{
|
|
59970
|
+
name: "deviceIds",
|
|
59971
|
+
form: "array",
|
|
59972
|
+
optional: false
|
|
59973
|
+
}],
|
|
59681
59974
|
"pipelineAnalytics.listRecentTracks": [{
|
|
59682
59975
|
name: "deviceIds",
|
|
59683
59976
|
form: "array",
|
|
@@ -60264,6 +60557,11 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
60264
60557
|
form: "single",
|
|
60265
60558
|
optional: false
|
|
60266
60559
|
}],
|
|
60560
|
+
"streamBroker.reportStreamSignal": [{
|
|
60561
|
+
name: "deviceId",
|
|
60562
|
+
form: "single",
|
|
60563
|
+
optional: false
|
|
60564
|
+
}],
|
|
60267
60565
|
"streamBroker.restartProfile": [{
|
|
60268
60566
|
name: "deviceId",
|
|
60269
60567
|
form: "single",
|
|
@@ -60715,6 +61013,10 @@ var require_dist_B84YlKAH = __commonJS({
|
|
|
60715
61013
|
durability: "restored",
|
|
60716
61014
|
volatileFields: ["lastFetchedAt"]
|
|
60717
61015
|
},
|
|
61016
|
+
"stream-signals": {
|
|
61017
|
+
durability: "session",
|
|
61018
|
+
volatileFields: []
|
|
61019
|
+
},
|
|
60718
61020
|
"switch": {
|
|
60719
61021
|
durability: "restored",
|
|
60720
61022
|
volatileFields: ["lastChangedAt"]
|
|
@@ -61999,7 +62301,7 @@ var require_alerts_addon = __commonJS({
|
|
|
61999
62301
|
[Symbol.toStringTag]: { value: "Module" }
|
|
62000
62302
|
});
|
|
62001
62303
|
require_chunk_Cek0wNdY();
|
|
62002
|
-
var require_dist10 =
|
|
62304
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
62003
62305
|
function selectExpired(alerts, cutoffMs) {
|
|
62004
62306
|
return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
|
|
62005
62307
|
}
|
|
@@ -62818,7 +63120,7 @@ var require_console_logging = __commonJS({
|
|
|
62818
63120
|
[Symbol.toStringTag]: { value: "Module" }
|
|
62819
63121
|
});
|
|
62820
63122
|
require_chunk_Cek0wNdY();
|
|
62821
|
-
var require_dist10 =
|
|
63123
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
62822
63124
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
62823
63125
|
var LEVEL_RANK = {
|
|
62824
63126
|
debug: 0,
|
|
@@ -62912,7 +63214,7 @@ var require_core_blocks_addon = __commonJS({
|
|
|
62912
63214
|
"use strict";
|
|
62913
63215
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
62914
63216
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
62915
|
-
var require_dist10 =
|
|
63217
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
62916
63218
|
var node_crypto = __require("crypto");
|
|
62917
63219
|
var node_fs_promises = __require("fs/promises");
|
|
62918
63220
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -63809,11 +64111,11 @@ var require_core_blocks = __commonJS({
|
|
|
63809
64111
|
}
|
|
63810
64112
|
});
|
|
63811
64113
|
|
|
63812
|
-
// ../system/dist/retired-settings-keys-
|
|
63813
|
-
var
|
|
63814
|
-
"../system/dist/retired-settings-keys-
|
|
64114
|
+
// ../system/dist/retired-settings-keys-FLZlwa2U.js
|
|
64115
|
+
var require_retired_settings_keys_FLZlwa2U = __commonJS({
|
|
64116
|
+
"../system/dist/retired-settings-keys-FLZlwa2U.js"(exports) {
|
|
63815
64117
|
"use strict";
|
|
63816
|
-
var require_dist10 =
|
|
64118
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
63817
64119
|
function settingsStoreIsAuthoritativeHere(env) {
|
|
63818
64120
|
const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
|
|
63819
64121
|
return raw === "" || raw === "hub";
|
|
@@ -64093,9 +64395,9 @@ var require_retired_settings_keys_Cxgwa0bk = __commonJS({
|
|
|
64093
64395
|
}
|
|
64094
64396
|
});
|
|
64095
64397
|
|
|
64096
|
-
// ../types/dist/canonical-hash-
|
|
64097
|
-
var
|
|
64098
|
-
"../types/dist/canonical-hash-
|
|
64398
|
+
// ../types/dist/canonical-hash-9lydiEzx.js
|
|
64399
|
+
var require_canonical_hash_9lydiEzx = __commonJS({
|
|
64400
|
+
"../types/dist/canonical-hash-9lydiEzx.js"(exports) {
|
|
64099
64401
|
"use strict";
|
|
64100
64402
|
var node_crypto = __require("crypto");
|
|
64101
64403
|
var AUDIO_ENCODER_BY_CODEC = {
|
|
@@ -64182,6 +64484,7 @@ var require_canonical_hash_DNV8S5ET = __commonJS({
|
|
|
64182
64484
|
];
|
|
64183
64485
|
if (video.preset !== void 0) args.push("-preset", video.preset);
|
|
64184
64486
|
if (video.tune !== void 0) args.push("-tune", video.tune);
|
|
64487
|
+
if (video.singleSlicePerFrame === true && video.encoder === "libx264") args.push("-x264-params", "sliced-threads=0");
|
|
64185
64488
|
if (video.profile !== void 0) args.push("-profile:v", video.profile);
|
|
64186
64489
|
if (video.level !== void 0) args.push("-level", video.level);
|
|
64187
64490
|
if (video.pixelFormat !== void 0) args.push("-pix_fmt", video.pixelFormat);
|
|
@@ -64365,6 +64668,7 @@ var require_canonical_hash_DNV8S5ET = __commonJS({
|
|
|
64365
64668
|
scale,
|
|
64366
64669
|
...v.preset !== void 0 ? { preset: v.preset } : {},
|
|
64367
64670
|
...v.tune !== void 0 ? { tune: v.tune } : {},
|
|
64671
|
+
...v.singleSlicePerFrame !== void 0 ? { singleSlicePerFrame: v.singleSlicePerFrame } : {},
|
|
64368
64672
|
...v.profile !== void 0 ? { profile: v.profile } : {},
|
|
64369
64673
|
...v.level !== void 0 ? { level: v.level } : {},
|
|
64370
64674
|
...input.pixelFormat !== void 0 ? { pixelFormat: input.pixelFormat } : {},
|
|
@@ -64695,7 +64999,7 @@ var require_node = __commonJS({
|
|
|
64695
64999
|
value: mod,
|
|
64696
65000
|
enumerable: true
|
|
64697
65001
|
}) : target, mod));
|
|
64698
|
-
var require_canonical_hash =
|
|
65002
|
+
var require_canonical_hash = require_canonical_hash_9lydiEzx();
|
|
64699
65003
|
var require_err_msg = require_err_msg_COpsHMw2();
|
|
64700
65004
|
var node_crypto = __require("crypto");
|
|
64701
65005
|
var node_fs = __require("fs");
|
|
@@ -66048,8 +66352,8 @@ var require_device_manager_addon = __commonJS({
|
|
|
66048
66352
|
[Symbol.toStringTag]: { value: "Module" }
|
|
66049
66353
|
});
|
|
66050
66354
|
require_chunk_Cek0wNdY();
|
|
66051
|
-
var require_dist10 =
|
|
66052
|
-
var require_retired_settings_keys =
|
|
66355
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
66356
|
+
var require_retired_settings_keys = require_retired_settings_keys_FLZlwa2U();
|
|
66053
66357
|
var node_crypto = __require("crypto");
|
|
66054
66358
|
var _camstack_types_node = require_node();
|
|
66055
66359
|
var JOB_HISTORY = 20;
|
|
@@ -71674,7 +71978,7 @@ var require_hub_forwarder = __commonJS({
|
|
|
71674
71978
|
[Symbol.toStringTag]: { value: "Module" }
|
|
71675
71979
|
});
|
|
71676
71980
|
require_chunk_Cek0wNdY();
|
|
71677
|
-
var require_dist10 =
|
|
71981
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
71678
71982
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
71679
71983
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
71680
71984
|
var HubForwarderDestination = class {
|
|
@@ -71811,7 +72115,7 @@ var require_liveness_monitor_addon = __commonJS({
|
|
|
71811
72115
|
"use strict";
|
|
71812
72116
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
71813
72117
|
require_chunk_Cek0wNdY();
|
|
71814
|
-
var require_dist10 =
|
|
72118
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
71815
72119
|
var NO_DEVICES = "liveness:no-devices";
|
|
71816
72120
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
71817
72121
|
var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
|
|
@@ -72007,7 +72311,7 @@ var require_local_auth_addon = __commonJS({
|
|
|
72007
72311
|
[Symbol.toStringTag]: { value: "Module" }
|
|
72008
72312
|
});
|
|
72009
72313
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
72010
|
-
var require_dist10 =
|
|
72314
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
72011
72315
|
var node_crypto = __require("crypto");
|
|
72012
72316
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
72013
72317
|
var crypto$1 = __require("crypto");
|
|
@@ -79820,7 +80124,7 @@ var require_loki_logging = __commonJS({
|
|
|
79820
80124
|
[Symbol.toStringTag]: { value: "Module" }
|
|
79821
80125
|
});
|
|
79822
80126
|
require_chunk_Cek0wNdY();
|
|
79823
|
-
var require_dist10 =
|
|
80127
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
79824
80128
|
function sanitizeLabelName(raw) {
|
|
79825
80129
|
const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
|
|
79826
80130
|
return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
|
|
@@ -80407,7 +80711,7 @@ var require_native_metrics_addon = __commonJS({
|
|
|
80407
80711
|
[Symbol.toStringTag]: { value: "Module" }
|
|
80408
80712
|
});
|
|
80409
80713
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
80410
|
-
var require_dist10 =
|
|
80714
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
80411
80715
|
var node_fs_promises = __require("fs/promises");
|
|
80412
80716
|
var node_fs = __require("fs");
|
|
80413
80717
|
node_fs = require_chunk.__toESM(node_fs);
|
|
@@ -83160,7 +83464,7 @@ var require_filesystem_storage_addon = __commonJS({
|
|
|
83160
83464
|
[Symbol.toStringTag]: { value: "Module" }
|
|
83161
83465
|
});
|
|
83162
83466
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
83163
|
-
var require_dist10 =
|
|
83467
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
83164
83468
|
var node_crypto = __require("crypto");
|
|
83165
83469
|
var node_fs_promises = __require("fs/promises");
|
|
83166
83470
|
var node_path = __require("path");
|
|
@@ -84387,8 +84691,8 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
84387
84691
|
[Symbol.toStringTag]: { value: "Module" }
|
|
84388
84692
|
});
|
|
84389
84693
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
84390
|
-
var require_dist10 =
|
|
84391
|
-
var require_retired_settings_keys =
|
|
84694
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
84695
|
+
var require_retired_settings_keys = require_retired_settings_keys_FLZlwa2U();
|
|
84392
84696
|
var require_wal_checkpoint_policy = require_wal_checkpoint_policy_CCJZngds();
|
|
84393
84697
|
var node_crypto = __require("crypto");
|
|
84394
84698
|
var node_path = __require("path");
|
|
@@ -87175,7 +87479,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
87175
87479
|
[Symbol.toStringTag]: { value: "Module" }
|
|
87176
87480
|
});
|
|
87177
87481
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
87178
|
-
var require_dist10 =
|
|
87482
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
87179
87483
|
var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
|
|
87180
87484
|
var zod = require_zod();
|
|
87181
87485
|
var node_crypto = __require("crypto");
|
|
@@ -88520,6 +88824,57 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
88520
88824
|
const percent = require_dist10.gbToBytes(minFreeGb) / totalBytes * 100;
|
|
88521
88825
|
return Math.min(100, percent);
|
|
88522
88826
|
}
|
|
88827
|
+
function unknown(reason) {
|
|
88828
|
+
return {
|
|
88829
|
+
kind: "unknown",
|
|
88830
|
+
reason
|
|
88831
|
+
};
|
|
88832
|
+
}
|
|
88833
|
+
function freePercentOf(capacity) {
|
|
88834
|
+
if (capacity === null || capacity.totalBytes <= 0) return 100;
|
|
88835
|
+
return capacity.availableBytes / capacity.totalBytes * 100;
|
|
88836
|
+
}
|
|
88837
|
+
function volumeTotalBytesOf(capacity) {
|
|
88838
|
+
return capacity === null ? 0 : capacity.totalBytes;
|
|
88839
|
+
}
|
|
88840
|
+
function probePathFor(location, locality, localNodeId, cwd) {
|
|
88841
|
+
if (locality !== true) {
|
|
88842
|
+
const why = locality === false ? `is served by the remote provider "${location.providerId}" (nodeLocal: false) \u2014 its bytes live on the remote host and no local statfs describes them` : `is served by "${location.providerId}", which this node has not classified yet (no getProviderInfo answer) \u2014 a local statfs would be a guess`;
|
|
88843
|
+
return { reason: `location "${location.id}" ${why}` };
|
|
88844
|
+
}
|
|
88845
|
+
if (location.nodeId !== void 0 && location.nodeId !== localNodeId) return { reason: `location "${location.id}" lives on node "${location.nodeId}" and this is "${localNodeId}" \u2014 only the owning node can statfs its own volumes` };
|
|
88846
|
+
const basePath = location.config["basePath"];
|
|
88847
|
+
if (typeof basePath !== "string" || basePath.length === 0) return { reason: `location "${location.id}" declares no basePath to measure` };
|
|
88848
|
+
if (!node_path.default.isAbsolute(basePath)) return { reason: `location "${location.id}" declares a RELATIVE basePath ("${basePath}") \u2014 that is a path inside its provider's own namespace, not on this node's filesystem, and resolving it against "${cwd}" would measure an unrelated volume` };
|
|
88849
|
+
return { path: node_path.default.resolve(basePath) };
|
|
88850
|
+
}
|
|
88851
|
+
async function readLocalVolumeCapacity(location, locality, localNodeId, deps) {
|
|
88852
|
+
const target = probePathFor(location, locality, localNodeId, deps.cwd);
|
|
88853
|
+
if ("reason" in target) return unknown(target.reason);
|
|
88854
|
+
const root = node_path.default.parse(target.path).root;
|
|
88855
|
+
let probed = target.path;
|
|
88856
|
+
for (; ; ) try {
|
|
88857
|
+
await deps.probe.access(probed);
|
|
88858
|
+
break;
|
|
88859
|
+
} catch {
|
|
88860
|
+
const parent = node_path.default.dirname(probed);
|
|
88861
|
+
if (parent === probed) return unknown(`nothing on the path "${target.path}" exists on this node \u2014 the volume is not mounted, so the root filesystem's size is not an answer about it`);
|
|
88862
|
+
probed = parent;
|
|
88863
|
+
}
|
|
88864
|
+
if (probed === root && target.path !== root) return unknown(`only the filesystem root exists on the path "${target.path}" \u2014 the volume is not mounted, so the root filesystem's size is not an answer about it`);
|
|
88865
|
+
try {
|
|
88866
|
+
const st = await deps.probe.statfs(probed);
|
|
88867
|
+
return {
|
|
88868
|
+
kind: "measured",
|
|
88869
|
+
path: probed,
|
|
88870
|
+
totalBytes: st.blocks * st.bsize,
|
|
88871
|
+
availableBytes: st.bavail * st.bsize
|
|
88872
|
+
};
|
|
88873
|
+
} catch (err) {
|
|
88874
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
88875
|
+
return unknown(`statfs("${probed}") failed: ${reason}`);
|
|
88876
|
+
}
|
|
88877
|
+
}
|
|
88523
88878
|
var FRAMEWORK_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
88524
88879
|
"basePath",
|
|
88525
88880
|
"readOnly",
|
|
@@ -90572,31 +90927,53 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
90572
90927
|
} });
|
|
90573
90928
|
throw new Error(refusal);
|
|
90574
90929
|
}
|
|
90575
|
-
/**
|
|
90576
|
-
*
|
|
90930
|
+
/**
|
|
90931
|
+
* The volume figures for one location, or `null` when this node cannot take
|
|
90932
|
+
* a measurement that is genuinely about it.
|
|
90933
|
+
*
|
|
90934
|
+
* The decision lives in `location-volume-capacity.ts` — including why a
|
|
90935
|
+
* remote-provider location (the SMB share that was reporting the hub's own
|
|
90936
|
+
* disk) gets nothing rather than a number. Here we only supply the node id,
|
|
90937
|
+
* the provider's declared locality and the real filesystem, and log the
|
|
90938
|
+
* reason once per distinct fault: `listLocations` is on the admin UI's poll,
|
|
90939
|
+
* so a line per call would be a line per second.
|
|
90940
|
+
*/
|
|
90577
90941
|
async localCapacityOf(loc) {
|
|
90578
|
-
const localNode = this.service?.getLocalNodeId() ??
|
|
90579
|
-
|
|
90580
|
-
|
|
90581
|
-
|
|
90582
|
-
|
|
90583
|
-
|
|
90584
|
-
|
|
90585
|
-
|
|
90586
|
-
|
|
90587
|
-
|
|
90588
|
-
const parent = node_path.dirname(target);
|
|
90589
|
-
if (!parent || parent === target) return null;
|
|
90590
|
-
target = parent;
|
|
90591
|
-
}
|
|
90592
|
-
const st = await node_fs_promises.statfs(target);
|
|
90593
|
-
return {
|
|
90594
|
-
totalBytes: st.blocks * st.bsize,
|
|
90595
|
-
availableBytes: st.bavail * st.bsize
|
|
90596
|
-
};
|
|
90597
|
-
} catch {
|
|
90942
|
+
const localNode = this.service?.getLocalNodeId() ?? HUB_NODE_ID;
|
|
90943
|
+
const result = await readLocalVolumeCapacity(loc, this.providerIsNodeLocal(loc), localNode, {
|
|
90944
|
+
probe: {
|
|
90945
|
+
access: (target) => node_fs_promises.access(target),
|
|
90946
|
+
statfs: async (target) => node_fs_promises.statfs(target)
|
|
90947
|
+
},
|
|
90948
|
+
cwd: node_path.resolve(".")
|
|
90949
|
+
});
|
|
90950
|
+
if (result.kind === "unknown") {
|
|
90951
|
+
this.logCapacityUnknownOnce(loc.id, result.reason);
|
|
90598
90952
|
return null;
|
|
90599
90953
|
}
|
|
90954
|
+
this.clearCapacityUnknown(loc.id, result.path);
|
|
90955
|
+
return {
|
|
90956
|
+
totalBytes: result.totalBytes,
|
|
90957
|
+
availableBytes: result.availableBytes
|
|
90958
|
+
};
|
|
90959
|
+
}
|
|
90960
|
+
/** locationId → the last unmeasurable reason logged for it. */
|
|
90961
|
+
capacityUnknownLogged = /* @__PURE__ */ new Map();
|
|
90962
|
+
logCapacityUnknownOnce(locationId, reason) {
|
|
90963
|
+
if (this.capacityUnknownLogged.get(locationId) === reason) return;
|
|
90964
|
+
this.capacityUnknownLogged.set(locationId, reason);
|
|
90965
|
+
this.ctx.logger.warn("storage-orchestrator: capacity is UNKNOWN for a location \u2014 reporting nothing rather than another volume\u2019s figures", { meta: {
|
|
90966
|
+
locationId,
|
|
90967
|
+
reason
|
|
90968
|
+
} });
|
|
90969
|
+
}
|
|
90970
|
+
clearCapacityUnknown(locationId, measuredPath) {
|
|
90971
|
+
if (!this.capacityUnknownLogged.has(locationId)) return;
|
|
90972
|
+
this.capacityUnknownLogged.delete(locationId);
|
|
90973
|
+
this.ctx.logger.info("storage-orchestrator: capacity is measurable again", { meta: {
|
|
90974
|
+
locationId,
|
|
90975
|
+
measuredPath
|
|
90976
|
+
} });
|
|
90600
90977
|
}
|
|
90601
90978
|
/** Per-location cap on EVICTABLE bytes (`config.maxUsedGb`): the operator's
|
|
90602
90979
|
* "recordings may use at most N GB in total" — enforced by the pressure
|
|
@@ -90685,28 +91062,30 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
90685
91062
|
} });
|
|
90686
91063
|
return occupancy;
|
|
90687
91064
|
}
|
|
90688
|
-
/**
|
|
91065
|
+
/**
|
|
91066
|
+
* The pressure guard's two readings come from the SAME probe the UI's
|
|
91067
|
+
* capacity does — one capacity truth per location, not two.
|
|
91068
|
+
*
|
|
91069
|
+
* They used to `statfs` the raw `basePath` themselves, which on this node
|
|
91070
|
+
* answers for whatever local path happens to carry that name: a location
|
|
91071
|
+
* owned by another node, or served by a remote provider, could decide
|
|
91072
|
+
* eviction from the hub's own disk. Both now degrade exactly as they did
|
|
91073
|
+
* when the path was unstattable — `100` (guard inert) and `0` (no byte
|
|
91074
|
+
* target) — but they do so for every reading that is not ABOUT the location,
|
|
91075
|
+
* not only for the ones that threw.
|
|
91076
|
+
*/
|
|
91077
|
+
async volumeCapacityOf(locationId) {
|
|
91078
|
+
const loc = this.service?.listLocations().find((l) => l.id === locationId);
|
|
91079
|
+
if (!loc) return null;
|
|
91080
|
+
return this.localCapacityOf(loc);
|
|
91081
|
+
}
|
|
91082
|
+
/** Free capacity (%) on a location's volume; 100 (guard inert) when unmeasurable. */
|
|
90689
91083
|
async locationFreePercent(locationId) {
|
|
90690
|
-
|
|
90691
|
-
if (!bp) return 100;
|
|
90692
|
-
try {
|
|
90693
|
-
const st = await node_fs_promises.statfs(bp);
|
|
90694
|
-
if (st.blocks <= 0) return 100;
|
|
90695
|
-
return st.bavail / st.blocks * 100;
|
|
90696
|
-
} catch {
|
|
90697
|
-
return 100;
|
|
90698
|
-
}
|
|
91084
|
+
return freePercentOf(await this.volumeCapacityOf(locationId));
|
|
90699
91085
|
}
|
|
90700
|
-
/** Total bytes on a location's volume
|
|
91086
|
+
/** Total bytes on a location's volume; 0 when unmeasurable. */
|
|
90701
91087
|
async locationVolumeTotalBytes(locationId) {
|
|
90702
|
-
|
|
90703
|
-
if (!bp) return 0;
|
|
90704
|
-
try {
|
|
90705
|
-
const st = await node_fs_promises.statfs(bp);
|
|
90706
|
-
return st.blocks * st.bsize;
|
|
90707
|
-
} catch {
|
|
90708
|
-
return 0;
|
|
90709
|
-
}
|
|
91088
|
+
return volumeTotalBytesOf(await this.volumeCapacityOf(locationId));
|
|
90710
91089
|
}
|
|
90711
91090
|
/**
|
|
90712
91091
|
* Seed default storage locations from the addon-declared
|
|
@@ -90827,7 +91206,7 @@ var require_system_config_addon = __commonJS({
|
|
|
90827
91206
|
[Symbol.toStringTag]: { value: "Module" }
|
|
90828
91207
|
});
|
|
90829
91208
|
require_chunk_Cek0wNdY();
|
|
90830
|
-
var require_dist10 =
|
|
91209
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
90831
91210
|
var SECTION_TITLES = {
|
|
90832
91211
|
server: "Server",
|
|
90833
91212
|
auth: "Authentication"
|
|
@@ -108888,7 +109267,7 @@ var require_winston_logging = __commonJS({
|
|
|
108888
109267
|
[Symbol.toStringTag]: { value: "Module" }
|
|
108889
109268
|
});
|
|
108890
109269
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
108891
|
-
var require_dist10 =
|
|
109270
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
108892
109271
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
108893
109272
|
var node_path = __require("path");
|
|
108894
109273
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -110757,9 +111136,9 @@ ${(0, node_fs.readFileSync)(ca.caCertPath, "utf-8").trimEnd()}
|
|
|
110757
111136
|
}
|
|
110758
111137
|
});
|
|
110759
111138
|
|
|
110760
|
-
// ../types/dist/event-category-
|
|
110761
|
-
var
|
|
110762
|
-
"../types/dist/event-category-
|
|
111139
|
+
// ../types/dist/event-category-BVfsrBYA.js
|
|
111140
|
+
var require_event_category_BVfsrBYA = __commonJS({
|
|
111141
|
+
"../types/dist/event-category-BVfsrBYA.js"(exports) {
|
|
110763
111142
|
"use strict";
|
|
110764
111143
|
var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
|
|
110765
111144
|
EventCategory2["SystemBoot"] = "system.boot";
|
|
@@ -110899,6 +111278,7 @@ var require_event_category_yW4s1MGD = __commonJS({
|
|
|
110899
111278
|
EventCategory2["LocalNetworkChanged"] = "network.local.changed";
|
|
110900
111279
|
EventCategory2["MeshNetworkChanged"] = "network.mesh.changed";
|
|
110901
111280
|
EventCategory2["BackupCompleted"] = "backup.completed";
|
|
111281
|
+
EventCategory2["BackupRunCompleted"] = "backup.run-completed";
|
|
110902
111282
|
EventCategory2["BackupRestored"] = "backup.restored";
|
|
110903
111283
|
EventCategory2["NotificationDispatched"] = "notification.dispatched";
|
|
110904
111284
|
EventCategory2["NotificationFailed"] = "notification.failed";
|
|
@@ -110925,11 +111305,11 @@ var require_event_category_yW4s1MGD = __commonJS({
|
|
|
110925
111305
|
}
|
|
110926
111306
|
});
|
|
110927
111307
|
|
|
110928
|
-
// ../types/dist/sleep-
|
|
110929
|
-
var
|
|
110930
|
-
"../types/dist/sleep-
|
|
111308
|
+
// ../types/dist/sleep-D7dV-FZB.js
|
|
111309
|
+
var require_sleep_D7dV_FZB = __commonJS({
|
|
111310
|
+
"../types/dist/sleep-D7dV-FZB.js"(exports) {
|
|
110931
111311
|
"use strict";
|
|
110932
|
-
var require_event_category =
|
|
111312
|
+
var require_event_category = require_event_category_BVfsrBYA();
|
|
110933
111313
|
var zod = require_zod();
|
|
110934
111314
|
var AUDIO_CHUNK_FORMATS = [
|
|
110935
111315
|
"f32le",
|
|
@@ -113424,6 +113804,7 @@ var require_sleep_CfDqEZrs = __commonJS({
|
|
|
113424
113804
|
smoke: createSliceHandle(stateSource, binding.deviceId, "smoke"),
|
|
113425
113805
|
streamCatalog: createSliceHandle(stateSource, binding.deviceId, "stream-catalog"),
|
|
113426
113806
|
streamParams: createSliceHandle(stateSource, binding.deviceId, "stream-params"),
|
|
113807
|
+
streamSignals: createSliceHandle(stateSource, binding.deviceId, "stream-signals"),
|
|
113427
113808
|
switch: createSliceHandle(stateSource, binding.deviceId, "switch"),
|
|
113428
113809
|
tamper: createSliceHandle(stateSource, binding.deviceId, "tamper"),
|
|
113429
113810
|
temperatureSensor: createSliceHandle(stateSource, binding.deviceId, "temperature-sensor"),
|
|
@@ -113706,6 +114087,7 @@ var require_sleep_CfDqEZrs = __commonJS({
|
|
|
113706
114087
|
listTracks: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listTracks", "query", input),
|
|
113707
114088
|
listRecentTracks: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listRecentTracks", "query", input),
|
|
113708
114089
|
listSummaries: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listSummaries", "query", input),
|
|
114090
|
+
listRecentSummaries: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listRecentSummaries", "query", input),
|
|
113709
114091
|
getSummary: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getSummary", "query", input),
|
|
113710
114092
|
clearTracks: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "clearTracks", "mutation", input),
|
|
113711
114093
|
getMotionEvents: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getMotionEvents", "query", input),
|
|
@@ -113837,6 +114219,7 @@ var require_sleep_CfDqEZrs = __commonJS({
|
|
|
113837
114219
|
getConfigSchema: (input) => dispatch("stream-params", "streamParams", "getConfigSchema", "query", input),
|
|
113838
114220
|
getStatus: (input) => dispatch("stream-params", "streamParams", "getStatus", "query", input)
|
|
113839
114221
|
},
|
|
114222
|
+
streamSignals: { listSignals: (input) => dispatch("stream-signals", "streamSignals", "listSignals", "query", input) },
|
|
113840
114223
|
switch: {
|
|
113841
114224
|
setState: (input) => dispatch("switch", "switch", "setState", "mutation", input),
|
|
113842
114225
|
getStatus: (input) => dispatch("switch", "switch", "getStatus", "query", input)
|
|
@@ -114046,6 +114429,7 @@ var require_sleep_CfDqEZrs = __commonJS({
|
|
|
114046
114429
|
},
|
|
114047
114430
|
recordingExport: { listExports: (input) => dispatchSystem("recordingExport", "listExports", "query", input) },
|
|
114048
114431
|
streamBroker: {
|
|
114432
|
+
reportStreamSignal: (input) => dispatchSystem("streamBroker", "reportStreamSignal", "mutation", input),
|
|
114049
114433
|
publishCameraStream: (input) => dispatchSystem("streamBroker", "publishCameraStream", "mutation", input),
|
|
114050
114434
|
retractCameraStream: (input) => dispatchSystem("streamBroker", "retractCameraStream", "mutation", input),
|
|
114051
114435
|
assignProfile: (input) => dispatchSystem("streamBroker", "assignProfile", "mutation", input),
|
|
@@ -114132,6 +114516,7 @@ var require_sleep_CfDqEZrs = __commonJS({
|
|
|
114132
114516
|
"snapshot",
|
|
114133
114517
|
"stream-catalog",
|
|
114134
114518
|
"stream-params",
|
|
114519
|
+
"stream-signals",
|
|
114135
114520
|
"switch",
|
|
114136
114521
|
"tamper",
|
|
114137
114522
|
"temperature-sensor",
|
|
@@ -114759,8 +115144,8 @@ var require_addon = __commonJS({
|
|
|
114759
115144
|
"../types/dist/addon.js"(exports) {
|
|
114760
115145
|
"use strict";
|
|
114761
115146
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
114762
|
-
var require_sleep =
|
|
114763
|
-
var require_event_category =
|
|
115147
|
+
var require_sleep = require_sleep_D7dV_FZB();
|
|
115148
|
+
var require_event_category = require_event_category_BVfsrBYA();
|
|
114764
115149
|
var require_err_msg = require_err_msg_COpsHMw2();
|
|
114765
115150
|
var CAP_INPUT_DEFAULTS = Object.freeze({
|
|
114766
115151
|
"addons": { "getLogs": { "limit": 100 } },
|
|
@@ -114880,6 +115265,7 @@ var require_addon = __commonJS({
|
|
|
114880
115265
|
"getMotionEvents": { "limit": 1e3 },
|
|
114881
115266
|
"getObjectEvents": { "limit": 1e3 },
|
|
114882
115267
|
"getSensorEvents": { "limit": 1e3 },
|
|
115268
|
+
"listRecentSummaries": { "limit": 100 },
|
|
114883
115269
|
"listRecentTracks": { "limit": 200 },
|
|
114884
115270
|
"listSummaries": { "limit": 50 },
|
|
114885
115271
|
"reclaimDebugMedia": { "mode": "report" },
|
|
@@ -121624,9 +122010,9 @@ var require_dist2 = __commonJS({
|
|
|
121624
122010
|
}
|
|
121625
122011
|
});
|
|
121626
122012
|
|
|
121627
|
-
// ../system/dist/manifest-system-deps-
|
|
121628
|
-
var
|
|
121629
|
-
"../system/dist/manifest-system-deps-
|
|
122013
|
+
// ../system/dist/manifest-system-deps-CrSP0Kkp.js
|
|
122014
|
+
var require_manifest_system_deps_CrSP0Kkp = __commonJS({
|
|
122015
|
+
"../system/dist/manifest-system-deps-CrSP0Kkp.js"(exports) {
|
|
121630
122016
|
"use strict";
|
|
121631
122017
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
121632
122018
|
require_hub_cap_forward_DmHNjbB0();
|
|
@@ -123070,6 +123456,19 @@ var require_manifest_system_deps_8x1jgPz = __commonJS({
|
|
|
123070
123456
|
});
|
|
123071
123457
|
return cachedInvocation;
|
|
123072
123458
|
}
|
|
123459
|
+
function buildNpmChildEnv(env, execPath) {
|
|
123460
|
+
const nodeDir = node_path.dirname(execPath);
|
|
123461
|
+
const current = env["PATH"];
|
|
123462
|
+
if (current === void 0 || current.length === 0) return {
|
|
123463
|
+
...env,
|
|
123464
|
+
PATH: nodeDir
|
|
123465
|
+
};
|
|
123466
|
+
if (current === nodeDir || current.startsWith(`${nodeDir}${node_path.delimiter}`)) return { ...env };
|
|
123467
|
+
return {
|
|
123468
|
+
...env,
|
|
123469
|
+
PATH: `${nodeDir}${node_path.delimiter}${current}`
|
|
123470
|
+
};
|
|
123471
|
+
}
|
|
123073
123472
|
async function runNpm(args, options) {
|
|
123074
123473
|
const invocation = await resolveNpmInvocation({
|
|
123075
123474
|
cacheDir: options.cacheDir,
|
|
@@ -123078,7 +123477,8 @@ var require_manifest_system_deps_8x1jgPz = __commonJS({
|
|
|
123078
123477
|
});
|
|
123079
123478
|
return execFileAsync$2(invocation.command, [...invocation.argsPrefix, ...args], {
|
|
123080
123479
|
...options.cwd !== void 0 ? { cwd: options.cwd } : {},
|
|
123081
|
-
timeout: options.timeout ?? 3e5
|
|
123480
|
+
timeout: options.timeout ?? 3e5,
|
|
123481
|
+
env: buildNpmChildEnv(options.env ?? process.env, process.execPath)
|
|
123082
123482
|
});
|
|
123083
123483
|
}
|
|
123084
123484
|
async function resolveUncached(options) {
|
|
@@ -130581,6 +130981,12 @@ var require_manifest_system_deps_8x1jgPz = __commonJS({
|
|
|
130581
130981
|
return buildNativeCapProxy;
|
|
130582
130982
|
}
|
|
130583
130983
|
});
|
|
130984
|
+
Object.defineProperty(exports, "buildNpmChildEnv", {
|
|
130985
|
+
enumerable: true,
|
|
130986
|
+
get: function() {
|
|
130987
|
+
return buildNpmChildEnv;
|
|
130988
|
+
}
|
|
130989
|
+
});
|
|
130584
130990
|
Object.defineProperty(exports, "buildUdsNativeCapProxy", {
|
|
130585
130991
|
enumerable: true,
|
|
130586
130992
|
get: function() {
|
|
@@ -131148,11 +131554,11 @@ var require_manifest_system_deps_8x1jgPz = __commonJS({
|
|
|
131148
131554
|
}
|
|
131149
131555
|
});
|
|
131150
131556
|
|
|
131151
|
-
// ../system/dist/custom-action-registry-
|
|
131152
|
-
var
|
|
131153
|
-
"../system/dist/custom-action-registry-
|
|
131557
|
+
// ../system/dist/custom-action-registry-YHpAdksL.js
|
|
131558
|
+
var require_custom_action_registry_YHpAdksL = __commonJS({
|
|
131559
|
+
"../system/dist/custom-action-registry-YHpAdksL.js"(exports) {
|
|
131154
131560
|
"use strict";
|
|
131155
|
-
var require_dist10 =
|
|
131561
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
131156
131562
|
var CustomActionRegistry = class {
|
|
131157
131563
|
byAddon = /* @__PURE__ */ new Map();
|
|
131158
131564
|
registerAddon(addonId, catalog, handler) {
|
|
@@ -134966,7 +135372,7 @@ var require_dist3 = __commonJS({
|
|
|
134966
135372
|
"use strict";
|
|
134967
135373
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
134968
135374
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
134969
|
-
var require_dist10 =
|
|
135375
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
134970
135376
|
var require_builtins_alerts_alerts_addon = require_alerts_addon();
|
|
134971
135377
|
require_alerts();
|
|
134972
135378
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
@@ -134993,9 +135399,9 @@ var require_dist3 = __commonJS({
|
|
|
134993
135399
|
var require_builtins_winston_logging_index = require_winston_logging();
|
|
134994
135400
|
var require_event_loop_stall_monitor = require_event_loop_stall_monitor_CAsHdMwP();
|
|
134995
135401
|
var require_tls$1 = require_tls_BFs4PzoW();
|
|
134996
|
-
var require_manifest_system_deps =
|
|
135402
|
+
var require_manifest_system_deps = require_manifest_system_deps_CrSP0Kkp();
|
|
134997
135403
|
var require_resource_monitor = require_resource_monitor_LVE1BoLs();
|
|
134998
|
-
var require_custom_action_registry =
|
|
135404
|
+
var require_custom_action_registry = require_custom_action_registry_YHpAdksL();
|
|
134999
135405
|
var zod = require_zod();
|
|
135000
135406
|
var node_crypto = __require("crypto");
|
|
135001
135407
|
var _camstack_types_node = require_node();
|
|
@@ -215841,6 +216247,7 @@ globstar while`, t, d, e, f, m), this.matchOne(t.slice(d), e.slice(f), s)) retur
|
|
|
215841
216247
|
exports.buildLinkChain = require_manifest_system_deps.buildLinkChain;
|
|
215842
216248
|
exports.buildNativeCapProxy = require_manifest_system_deps.buildNativeCapProxy;
|
|
215843
216249
|
exports.buildNodeManifest = buildNodeManifest;
|
|
216250
|
+
exports.buildNpmChildEnv = require_manifest_system_deps.buildNpmChildEnv;
|
|
215844
216251
|
exports.buildStorageLocationRegistry = require_builtins_storage_orchestrator_storage_orchestrator_addon.buildStorageLocationRegistry;
|
|
215845
216252
|
exports.buildUdsNativeCapProxy = require_manifest_system_deps.buildUdsNativeCapProxy;
|
|
215846
216253
|
exports.builderMountedCapNames = builderMountedCapNames;
|
|
@@ -216083,7 +216490,7 @@ var require_enums = __commonJS({
|
|
|
216083
216490
|
"../types/dist/enums.js"(exports) {
|
|
216084
216491
|
"use strict";
|
|
216085
216492
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
216086
|
-
var require_event_category =
|
|
216493
|
+
var require_event_category = require_event_category_BVfsrBYA();
|
|
216087
216494
|
var EventSourceType = /* @__PURE__ */ (function(EventSourceType2) {
|
|
216088
216495
|
EventSourceType2["Addon"] = "addon";
|
|
216089
216496
|
EventSourceType2["Core"] = "core";
|
|
@@ -216103,9 +216510,9 @@ var require_dist4 = __commonJS({
|
|
|
216103
216510
|
"../types/dist/index.js"(exports) {
|
|
216104
216511
|
"use strict";
|
|
216105
216512
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
216106
|
-
var require_sleep =
|
|
216107
|
-
var require_event_category =
|
|
216108
|
-
var require_canonical_hash =
|
|
216513
|
+
var require_sleep = require_sleep_D7dV_FZB();
|
|
216514
|
+
var require_event_category = require_event_category_BVfsrBYA();
|
|
216515
|
+
var require_canonical_hash = require_canonical_hash_9lydiEzx();
|
|
216109
216516
|
var require_enums2 = require_enums();
|
|
216110
216517
|
var require_err_msg = require_err_msg_COpsHMw2();
|
|
216111
216518
|
var zod = require_zod();
|
|
@@ -216285,7 +216692,23 @@ var require_dist4 = __commonJS({
|
|
|
216285
216692
|
"zerolatency",
|
|
216286
216693
|
"film",
|
|
216287
216694
|
"animation"
|
|
216288
|
-
]).optional()
|
|
216695
|
+
]).optional(),
|
|
216696
|
+
/**
|
|
216697
|
+
* ONE slice per access unit.
|
|
216698
|
+
*
|
|
216699
|
+
* `-tune zerolatency` turns on x264's sliced threads, and a frame then leaves
|
|
216700
|
+
* the encoder as five NAL slices that share one RTP timestamp and carry one
|
|
216701
|
+
* marker bit. A libwebrtc depacketiser sees five frame-starts and one
|
|
216702
|
+
* frame-end per frame: the first pictures render and the video then freezes
|
|
216703
|
+
* for good while the audio, on its own plane, plays on. Measured on this hub
|
|
216704
|
+
* 2026-09-13 against the Echo, and reduced to one slice by this flag alone.
|
|
216705
|
+
*
|
|
216706
|
+
* A NAMED field and not a raw flag, because {@link EgressEncodeSchema} omits
|
|
216707
|
+
* `outputArgs` on purpose: an opaque array is part of the sharing key, so two
|
|
216708
|
+
* consumers meaning the same thing spelled differently would stop sharing one
|
|
216709
|
+
* child. Absent means "whatever the encoder does" — today's behaviour.
|
|
216710
|
+
*/
|
|
216711
|
+
singleSlicePerFrame: zod.z.boolean().optional()
|
|
216289
216712
|
});
|
|
216290
216713
|
var AudioEncodeSchema = zod.z.union([zod.z.literal("passthrough"), zod.z.object({
|
|
216291
216714
|
codec: zod.z.enum([
|
|
@@ -216330,6 +216753,50 @@ var require_dist4 = __commonJS({
|
|
|
216330
216753
|
audio: "passthrough"
|
|
216331
216754
|
};
|
|
216332
216755
|
}
|
|
216756
|
+
function compareToTarget(a, b, target) {
|
|
216757
|
+
const aReaches = a >= target;
|
|
216758
|
+
if (aReaches !== b >= target) return aReaches ? -1 : 1;
|
|
216759
|
+
return aReaches ? a - b : b - a;
|
|
216760
|
+
}
|
|
216761
|
+
function canonicalCodec(value) {
|
|
216762
|
+
const v = value.toLowerCase().replace(/[.\s-]/g, "");
|
|
216763
|
+
if (v === "hevc" || v === "hvc1" || v === "hev1") return "h265";
|
|
216764
|
+
if (v === "avc" || v === "avc1") return "h264";
|
|
216765
|
+
return v;
|
|
216766
|
+
}
|
|
216767
|
+
function codecIsAccepted(codec, accept) {
|
|
216768
|
+
if (accept.length === 0) return true;
|
|
216769
|
+
if (codec === void 0) return false;
|
|
216770
|
+
const c = canonicalCodec(codec);
|
|
216771
|
+
return accept.some((a) => canonicalCodec(a) === c);
|
|
216772
|
+
}
|
|
216773
|
+
function providerRank(camStreamId, preferred) {
|
|
216774
|
+
for (let i = 0; i < preferred.length; i += 1) if (camStreamId.startsWith(preferred[i])) return i;
|
|
216775
|
+
return preferred.length;
|
|
216776
|
+
}
|
|
216777
|
+
function rankStreams(candidates, ranking) {
|
|
216778
|
+
const usable = candidates.filter((c) => ranking.allowTranscode || codecIsAccepted(c.codec, ranking.acceptCodecs));
|
|
216779
|
+
if (usable.length === 0) return null;
|
|
216780
|
+
const target = ranking.targetHeight;
|
|
216781
|
+
const scored = usable.map((candidate) => ({
|
|
216782
|
+
candidate,
|
|
216783
|
+
transcodes: !codecIsAccepted(candidate.codec, ranking.acceptCodecs),
|
|
216784
|
+
provider: providerRank(candidate.camStreamId, ranking.preferredProviders),
|
|
216785
|
+
height: candidate.height ?? 0
|
|
216786
|
+
}));
|
|
216787
|
+
scored.sort((a, b) => {
|
|
216788
|
+
if (a.transcodes !== b.transcodes) return a.transcodes ? 1 : -1;
|
|
216789
|
+
if (a.provider !== b.provider) return a.provider - b.provider;
|
|
216790
|
+
if (target !== void 0) return compareToTarget(a.height, b.height, target);
|
|
216791
|
+
return ranking.resolutionPreference === "highest" ? b.height - a.height : a.height - b.height;
|
|
216792
|
+
});
|
|
216793
|
+
const winner = scored[0];
|
|
216794
|
+
if (winner === void 0) return null;
|
|
216795
|
+
return {
|
|
216796
|
+
candidate: winner.candidate,
|
|
216797
|
+
transcodes: winner.transcodes
|
|
216798
|
+
};
|
|
216799
|
+
}
|
|
216333
216800
|
var BASE_LIVE_EGRESS_PROFILE = {
|
|
216334
216801
|
video: {
|
|
216335
216802
|
codec: "h264",
|
|
@@ -216358,7 +216825,11 @@ var require_dist4 = __commonJS({
|
|
|
216358
216825
|
};
|
|
216359
216826
|
var ALEXA_EGRESS_PROFILE = {
|
|
216360
216827
|
...BASE_LIVE_EGRESS_PROFILE,
|
|
216361
|
-
audio: { codec: "opus" }
|
|
216828
|
+
audio: { codec: "opus" },
|
|
216829
|
+
video: {
|
|
216830
|
+
...BASE_LIVE_EGRESS_PROFILE.video,
|
|
216831
|
+
singleSlicePerFrame: true
|
|
216832
|
+
}
|
|
216362
216833
|
};
|
|
216363
216834
|
var RATE_CONTROL_TIGHT = {
|
|
216364
216835
|
kind: "cbr",
|
|
@@ -216446,7 +216917,8 @@ var require_dist4 = __commonJS({
|
|
|
216446
216917
|
gopFrames: video.gopFrames ?? -1,
|
|
216447
216918
|
bf: video.bf ?? -1,
|
|
216448
216919
|
preset: video.preset ?? UNSET,
|
|
216449
|
-
tune: video.tune ?? UNSET
|
|
216920
|
+
tune: video.tune ?? UNSET,
|
|
216921
|
+
singleSlicePerFrame: video.singleSlicePerFrame === void 0 ? UNSET : String(video.singleSlicePerFrame)
|
|
216450
216922
|
};
|
|
216451
216923
|
}
|
|
216452
216924
|
function canonicalAudio(audio) {
|
|
@@ -218843,22 +219315,10 @@ var require_dist4 = __commonJS({
|
|
|
218843
219315
|
}
|
|
218844
219316
|
function pickClosestResolution(entries2, target) {
|
|
218845
219317
|
const targetPixels = target.width * target.height;
|
|
218846
|
-
|
|
218847
|
-
|
|
218848
|
-
|
|
218849
|
-
|
|
218850
|
-
const pixels = e.resolution.width * e.resolution.height;
|
|
218851
|
-
if (pixels >= targetPixels) {
|
|
218852
|
-
if (!bestAbove || pixels < bestAbove.pixels) bestAbove = {
|
|
218853
|
-
entry: e,
|
|
218854
|
-
pixels
|
|
218855
|
-
};
|
|
218856
|
-
} else if (!bestBelow || pixels > bestBelow.pixels) bestBelow = {
|
|
218857
|
-
entry: e,
|
|
218858
|
-
pixels
|
|
218859
|
-
};
|
|
218860
|
-
}
|
|
218861
|
-
return bestAbove?.entry ?? bestBelow?.entry;
|
|
219318
|
+
return [...entries2.flatMap((entry) => entry.resolution === void 0 ? [] : [{
|
|
219319
|
+
entry,
|
|
219320
|
+
pixels: entry.resolution.width * entry.resolution.height
|
|
219321
|
+
}])].sort((a, b) => compareToTarget(a.pixels, b.pixels, targetPixels))[0]?.entry;
|
|
218862
219322
|
}
|
|
218863
219323
|
var FORMAT_KEYS = [
|
|
218864
219324
|
"onnx",
|
|
@@ -221720,6 +222180,39 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
221720
222180
|
exposesDeviceSettings: true,
|
|
221721
222181
|
methods: {}
|
|
221722
222182
|
};
|
|
222183
|
+
var StreamSignalSchema = zod.z.object({
|
|
222184
|
+
/** Stable id chosen by the provider, e.g. `'motion'`, `'person'`, `'tamper'`. */
|
|
222185
|
+
code: zod.z.string().min(1),
|
|
222186
|
+
/** What an operator reads in the picker. The provider's own wording. */
|
|
222187
|
+
label: zod.z.string().min(1),
|
|
222188
|
+
/**
|
|
222189
|
+
* Whether the provider recommends this signal ON when a camera is first set
|
|
222190
|
+
* up. A provider knows which of its signals are cheap and reliable; an
|
|
222191
|
+
* operator should not have to discover that by trial. Reolink recommends
|
|
222192
|
+
* both of its own.
|
|
222193
|
+
*/
|
|
222194
|
+
recommended: zod.z.boolean()
|
|
222195
|
+
});
|
|
222196
|
+
var StreamSignalsStatusSchema = zod.z.object({
|
|
222197
|
+
signals: zod.z.array(StreamSignalSchema),
|
|
222198
|
+
lastFetchedAt: zod.z.number()
|
|
222199
|
+
});
|
|
222200
|
+
var streamSignalsCapability = {
|
|
222201
|
+
name: "stream-signals",
|
|
222202
|
+
scope: "device",
|
|
222203
|
+
deviceNative: true,
|
|
222204
|
+
mode: "singleton",
|
|
222205
|
+
deviceTypes: Object.values(require_sleep.DeviceType),
|
|
222206
|
+
runtimeState: StreamSignalsStatusSchema,
|
|
222207
|
+
methods: {
|
|
222208
|
+
/**
|
|
222209
|
+
* What this device can emit. Empty is a valid and common answer — most
|
|
222210
|
+
* cameras have nothing to offer here, and an empty list is what makes the
|
|
222211
|
+
* broker's picker show nothing rather than a false choice.
|
|
222212
|
+
*/
|
|
222213
|
+
listSignals: require_sleep.method(zod.z.void(), zod.z.array(StreamSignalSchema).readonly())
|
|
222214
|
+
}
|
|
222215
|
+
};
|
|
221723
222216
|
var StreamFormatSchema = zod.z.enum([
|
|
221724
222217
|
"webrtc",
|
|
221725
222218
|
"hls",
|
|
@@ -222072,6 +222565,46 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222072
222565
|
mode: "singleton",
|
|
222073
222566
|
exposesDeviceSettings: true,
|
|
222074
222567
|
methods: {
|
|
222568
|
+
/**
|
|
222569
|
+
* A device reporting that one of ITS OWN signals just fired.
|
|
222570
|
+
*
|
|
222571
|
+
* The provider calls this; nothing polls. The broker then decides whether
|
|
222572
|
+
* to wake the source, and the decision has two terms that must BOTH hold:
|
|
222573
|
+
*
|
|
222574
|
+
* - the signal is ENABLED for this camera (the operator's per-camera
|
|
222575
|
+
* choice — a camera may declare a signal the operator does not want
|
|
222576
|
+
* waking anything), and
|
|
222577
|
+
* - a consumer is actually attached and waiting on the prestream. Waking
|
|
222578
|
+
* a camera nobody is watching is the one thing a battery camera must
|
|
222579
|
+
* never do, and a signal arriving with no consumer is exactly that.
|
|
222580
|
+
*
|
|
222581
|
+
* Reported, never inferred: a signal that fires while the stream is
|
|
222582
|
+
* already up refreshes the hold instead of starting a second one, which is
|
|
222583
|
+
* what makes continuous motion keep a camera awake without stacking
|
|
222584
|
+
* timers.
|
|
222585
|
+
*
|
|
222586
|
+
* `code` is the provider's own, from `streamSignals.listSignals`. An
|
|
222587
|
+
* unknown code is REFUSED rather than treated as a wildcard wake — a
|
|
222588
|
+
* provider and an operator disagreeing about a name must not become a
|
|
222589
|
+
* camera that wakes for everything.
|
|
222590
|
+
*/
|
|
222591
|
+
reportStreamSignal: require_sleep.method(zod.z.object({
|
|
222592
|
+
deviceId: zod.z.number().int().nonnegative(),
|
|
222593
|
+
/** The provider's signal code. */
|
|
222594
|
+
code: zod.z.string().min(1),
|
|
222595
|
+
/** Ms epoch. Absent ⇒ now. */
|
|
222596
|
+
at: zod.z.number().optional()
|
|
222597
|
+
}), zod.z.object({
|
|
222598
|
+
/** Whether the broker acted on it, and if not, why. */
|
|
222599
|
+
accepted: zod.z.boolean(),
|
|
222600
|
+
reason: zod.z.enum([
|
|
222601
|
+
"woke",
|
|
222602
|
+
"hold-extended",
|
|
222603
|
+
"not-enabled",
|
|
222604
|
+
"no-consumer",
|
|
222605
|
+
"unknown-code"
|
|
222606
|
+
])
|
|
222607
|
+
}), { kind: "mutation" }),
|
|
222075
222608
|
publishCameraStream: require_sleep.method(zod.z.object({
|
|
222076
222609
|
deviceId: zod.z.number().int().nonnegative(),
|
|
222077
222610
|
camStreamId: zod.z.string().min(1),
|
|
@@ -222549,6 +223082,16 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222549
223082
|
acceptCodecs: zod.z.array(StreamCodecSchema).readonly().optional(),
|
|
222550
223083
|
/** Minimum vertical resolution. Streams shorter than this are dropped. */
|
|
222551
223084
|
minHeight: zod.z.number().int().positive().optional(),
|
|
223085
|
+
/**
|
|
223086
|
+
* Maximum vertical resolution. Streams TALLER than this are dropped.
|
|
223087
|
+
*
|
|
223088
|
+
* A consumer can have a ceiling as real as its floor: Alexa documents
|
|
223089
|
+
* 480p to 1080p, and a 4K stream is as unusable to an Echo as a 360p one.
|
|
223090
|
+
* Without this the ceiling had to be re-implemented by every caller — and
|
|
223091
|
+
* one caller implementing it privately is how a second scoring authority
|
|
223092
|
+
* gets born.
|
|
223093
|
+
*/
|
|
223094
|
+
maxHeight: zod.z.number().int().positive().optional(),
|
|
222552
223095
|
/** Minimum horizontal resolution. */
|
|
222553
223096
|
minWidth: zod.z.number().int().positive().optional(),
|
|
222554
223097
|
/**
|
|
@@ -222565,7 +223108,22 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222565
223108
|
* transcoded" guard: if the device is already serving the consumer's
|
|
222566
223109
|
* codec end-to-end, there's nothing to optimise.
|
|
222567
223110
|
*/
|
|
222568
|
-
requireSiblingCodec: zod.z.array(StreamCodecSchema).readonly().optional()
|
|
223111
|
+
requireSiblingCodec: zod.z.array(StreamCodecSchema).readonly().optional(),
|
|
223112
|
+
/**
|
|
223113
|
+
* Whether a stream the consumer CANNOT decode may still be picked, on the
|
|
223114
|
+
* understanding that it will be transcoded.
|
|
223115
|
+
*
|
|
223116
|
+
* Default `false` — today's behaviour, and the right one for a bypass
|
|
223117
|
+
* question ("is there a stream I can forward untouched?"). Set `true` to
|
|
223118
|
+
* ask the larger question: "what is the best stream for me, transcoding if
|
|
223119
|
+
* I must?" A stream that satisfies `acceptCodecs` always outranks one that
|
|
223120
|
+
* does not, so a passthrough is never lost to a transcode; the answer says
|
|
223121
|
+
* which it is in {@link PickedCamStreamSchema.transcodes}.
|
|
223122
|
+
*
|
|
223123
|
+
* This is what lets one picker serve both the bypass and the full source
|
|
223124
|
+
* choice, instead of a consumer scoring privately when the bypass misses.
|
|
223125
|
+
*/
|
|
223126
|
+
allowTranscode: zod.z.boolean().optional()
|
|
222569
223127
|
}).readonly();
|
|
222570
223128
|
var PickStreamPreferencesSchema = zod.z.object({
|
|
222571
223129
|
/**
|
|
@@ -222579,12 +223137,32 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222579
223137
|
* picks the tallest stream; `'lowest'` picks the shortest (used by
|
|
222580
223138
|
* memory-constrained consumers / Apple Home guest sessions).
|
|
222581
223139
|
*/
|
|
222582
|
-
resolutionPreference: zod.z.enum(["highest", "lowest"]).optional()
|
|
223140
|
+
resolutionPreference: zod.z.enum(["highest", "lowest"]).optional(),
|
|
223141
|
+
/**
|
|
223142
|
+
* The height the consumer actually wants to DELIVER.
|
|
223143
|
+
*
|
|
223144
|
+
* Not a constraint — an ordering. With it set, the SMALLEST stream at or
|
|
223145
|
+
* above the target wins, and only if nothing reaches it does the tallest
|
|
223146
|
+
* take over. Pulling 1296 lines to draw 720 on a 1280x800 Echo panel costs
|
|
223147
|
+
* a decode and buys nothing, and `resolutionPreference: 'highest'` cannot
|
|
223148
|
+
* express that: it says "as big as possible", which is a different wish.
|
|
223149
|
+
*
|
|
223150
|
+
* Ignored when absent, so every existing caller keeps its ordering.
|
|
223151
|
+
*/
|
|
223152
|
+
targetHeight: zod.z.number().int().positive().optional()
|
|
222583
223153
|
}).readonly();
|
|
222584
223154
|
var PickedCamStreamSchema = zod.z.object({
|
|
222585
223155
|
camStreamId: zod.z.string(),
|
|
222586
223156
|
codec: zod.z.string().optional(),
|
|
222587
223157
|
resolution: require_sleep.CamStreamResolutionSchema.optional(),
|
|
223158
|
+
/**
|
|
223159
|
+
* Whether serving this stream requires a decode + re-encode.
|
|
223160
|
+
*
|
|
223161
|
+
* `false` is a stream the consumer can take as it stands. Only ever `true`
|
|
223162
|
+
* when the caller asked for it with `allowTranscode`, so a caller that did
|
|
223163
|
+
* not ask cannot be handed a cost it never agreed to pay.
|
|
223164
|
+
*/
|
|
223165
|
+
transcodes: zod.z.boolean(),
|
|
222588
223166
|
/** One-line explanation of why this stream won — for logs / debug UI. */
|
|
222589
223167
|
reason: zod.z.string()
|
|
222590
223168
|
});
|
|
@@ -227963,6 +228541,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
227963
228541
|
"device-enabled",
|
|
227964
228542
|
"device-battery-low",
|
|
227965
228543
|
"device-battery-normal",
|
|
228544
|
+
"device-consumable-low",
|
|
228545
|
+
"device-consumable-normal",
|
|
227966
228546
|
"stream-online",
|
|
227967
228547
|
"stream-offline",
|
|
227968
228548
|
"node-online",
|
|
@@ -227981,6 +228561,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
227981
228561
|
"addon-updated",
|
|
227982
228562
|
"server-updated",
|
|
227983
228563
|
"export-completed",
|
|
228564
|
+
"backup-completed",
|
|
227984
228565
|
"camera-online",
|
|
227985
228566
|
"camera-offline",
|
|
227986
228567
|
"camera-disabled",
|
|
@@ -228842,10 +229423,22 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
228842
229423
|
value: "server-updated",
|
|
228843
229424
|
label: "Server updated"
|
|
228844
229425
|
},
|
|
229426
|
+
{
|
|
229427
|
+
value: "device-consumable-low",
|
|
229428
|
+
label: "Consumable low"
|
|
229429
|
+
},
|
|
229430
|
+
{
|
|
229431
|
+
value: "device-consumable-normal",
|
|
229432
|
+
label: "Consumable replaced"
|
|
229433
|
+
},
|
|
228845
229434
|
{
|
|
228846
229435
|
value: "export-completed",
|
|
228847
229436
|
label: "Export completed"
|
|
228848
229437
|
},
|
|
229438
|
+
{
|
|
229439
|
+
value: "backup-completed",
|
|
229440
|
+
label: "Backup completed"
|
|
229441
|
+
},
|
|
228849
229442
|
{
|
|
228850
229443
|
value: "alarm-arming",
|
|
228851
229444
|
label: "Alarm arming (exit delay)"
|
|
@@ -231303,13 +231896,91 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
231303
231896
|
deviceIds: zod.z.array(zod.z.number()).min(1),
|
|
231304
231897
|
since: zod.z.number().optional(),
|
|
231305
231898
|
until: zod.z.number().optional(),
|
|
231306
|
-
limit: zod.z.number().int().min(1).max(200).default(50)
|
|
231899
|
+
limit: zod.z.number().int().min(1).max(200).default(50),
|
|
231900
|
+
/** The same member-wise filter {@link listRecentSummaries} takes — one
|
|
231901
|
+
* meaning of "dog" on every summary surface. */
|
|
231902
|
+
classes: zod.z.array(zod.z.string().min(1).max(60)).max(40).optional()
|
|
231903
|
+
});
|
|
231904
|
+
var SummaryMemberSchema = zod.z.object({
|
|
231905
|
+
trackId: zod.z.string(),
|
|
231906
|
+
/**
|
|
231907
|
+
* The track's class at the time it JOINED, or `null` when it was unresolved
|
|
231908
|
+
* and the track no longer exists to fill it.
|
|
231909
|
+
*
|
|
231910
|
+
* The join, not the latest opinion: class voting can re-decide a track's
|
|
231911
|
+
* class afterwards, and a group's composition is the history of who came
|
|
231912
|
+
* together. A consumer counts these to badge a thumbnail — "two people and a
|
|
231913
|
+
* dog" — rather than being handed a second, denormalised tally that would
|
|
231914
|
+
* drift from the members it claims to describe.
|
|
231915
|
+
*/
|
|
231916
|
+
className: zod.z.string().nullable(),
|
|
231917
|
+
/** `primary` is the one member that carries the group's identity. */
|
|
231918
|
+
role: zod.z.enum([
|
|
231919
|
+
"primary",
|
|
231920
|
+
"sibling",
|
|
231921
|
+
"child"
|
|
231922
|
+
]).nullable(),
|
|
231923
|
+
joinedAt: zod.z.number(),
|
|
231924
|
+
/** Tier 1 — the sub-class (`dog`, `van`), resolved from the member's track
|
|
231925
|
+
* at read time. Absent when nothing resolved, never an empty string. */
|
|
231926
|
+
label: zod.z.string().optional(),
|
|
231927
|
+
/** Tier 2 — the instance: a person's name, a plate. Absent when the pipeline
|
|
231928
|
+
* recognised nobody, and absent for a member whose track has been pruned —
|
|
231929
|
+
* a thumbnail that names the wrong person is worse than one naming nobody. */
|
|
231930
|
+
subLabel: zod.z.string().optional()
|
|
231307
231931
|
});
|
|
231308
|
-
var SummariesPageSchema = zod.z.object({ summaries: zod.z.array(SummarySchema).readonly() });
|
|
231309
231932
|
var SummaryDetailSchema = zod.z.object({
|
|
231310
231933
|
summary: SummarySchema,
|
|
231311
|
-
/**
|
|
231312
|
-
|
|
231934
|
+
/** Members in absorption order, oldest join first. */
|
|
231935
|
+
members: zod.z.array(SummaryMemberSchema).readonly()
|
|
231936
|
+
});
|
|
231937
|
+
var SummaryListItemSchema = zod.z.object({
|
|
231938
|
+
summary: SummarySchema,
|
|
231939
|
+
/** Class counts, most numerous first; `className: null` is a member whose
|
|
231940
|
+
* class never resolved, counted so the counts add up to `memberCount`. */
|
|
231941
|
+
classes: zod.z.array(zod.z.object({
|
|
231942
|
+
className: zod.z.string().nullable(),
|
|
231943
|
+
count: zod.z.number().int().positive()
|
|
231944
|
+
})).readonly()
|
|
231945
|
+
});
|
|
231946
|
+
var SummariesPageSchema = zod.z.object({ summaries: zod.z.array(SummaryListItemSchema).readonly() });
|
|
231947
|
+
var RecentSummariesQueryInput = zod.z.object({
|
|
231948
|
+
/** Devices to merge. An empty array yields an empty page. */
|
|
231949
|
+
deviceIds: zod.z.array(zod.z.number()),
|
|
231950
|
+
/** Window lower bound on `lastActiveAt` (inclusive). */
|
|
231951
|
+
since: zod.z.number().optional(),
|
|
231952
|
+
/** Window upper bound on `lastActiveAt` (inclusive). */
|
|
231953
|
+
until: zod.z.number().optional(),
|
|
231954
|
+
limit: zod.z.number().int().min(1).max(500).default(100),
|
|
231955
|
+
/** Opaque continuation cursor from a previous page's `nextCursor`. */
|
|
231956
|
+
cursor: zod.z.string().optional(),
|
|
231957
|
+
/**
|
|
231958
|
+
* Restrict to these classes — THE SAME FIELD `listRecentTracks` takes, and
|
|
231959
|
+
* deliberately the same name: the events filter tree emits one list of ticked
|
|
231960
|
+
* taxonomy nodes, and a summaries feed that called it something else would
|
|
231961
|
+
* make the operator's one filter component produce two shapes.
|
|
231962
|
+
*
|
|
231963
|
+
* A question about the MEMBERS: a group matches when ANY of them does. "Show
|
|
231964
|
+
* me the arrivals with a dog" has to return the group of four people who had
|
|
231965
|
+
* one with them; a filter on the group's own fields could only ever answer
|
|
231966
|
+
* about its primary.
|
|
231967
|
+
*
|
|
231968
|
+
* Matched against all THREE tiers of a member — the class (`animal`), the
|
|
231969
|
+
* sub-class (`dog`) and the instance (a name, a plate) — because which tier a
|
|
231970
|
+
* ticked node lives on is the taxonomy's business, not the caller's. `dog` is
|
|
231971
|
+
* an event kind in the tree and a tier-1 label on an `animal` track; a filter
|
|
231972
|
+
* that read only the class would answer "animal" and never "dog".
|
|
231973
|
+
*
|
|
231974
|
+
* ABSENT or EMPTY means no filter — absent is not a selection of none.
|
|
231975
|
+
*/
|
|
231976
|
+
classes: zod.z.array(zod.z.string().min(1).max(60)).max(40).optional()
|
|
231977
|
+
});
|
|
231978
|
+
var RecentSummariesPageSchema = zod.z.object({
|
|
231979
|
+
/** Ordered by (`lastActiveAt` DESC, id DESC). Same light item as
|
|
231980
|
+
* {@link listSummaries} — one list shape, so a card renders the same
|
|
231981
|
+
* whichever feed drew it. */
|
|
231982
|
+
summaries: zod.z.array(SummaryListItemSchema).readonly(),
|
|
231983
|
+
nextCursor: zod.z.string().nullable()
|
|
231313
231984
|
});
|
|
231314
231985
|
var RecentTracksPageSchema = zod.z.object({
|
|
231315
231986
|
/** Merged page, ordered by (`lastSeen` DESC, `trackId` DESC). */
|
|
@@ -231662,6 +232333,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
231662
232333
|
listRecentTracks: require_sleep.method(RecentTracksQueryInput, RecentTracksPageSchema),
|
|
231663
232334
|
/** Newest first by `openedAt`, for a camera set, inside an optional window. */
|
|
231664
232335
|
listSummaries: require_sleep.method(SummariesQueryInput, SummariesPageSchema),
|
|
232336
|
+
/**
|
|
232337
|
+
* The PAGED feed — the reel and the Events gallery. Same cursor contract as
|
|
232338
|
+
* {@link listRecentTracks}, so one screen cannot hold two ideas of newest.
|
|
232339
|
+
*/
|
|
232340
|
+
listRecentSummaries: require_sleep.method(RecentSummariesQueryInput, RecentSummariesPageSchema),
|
|
231665
232341
|
/** One summary with its member track ids; `null` for an id nobody wrote. */
|
|
231666
232342
|
getSummary: require_sleep.method(zod.z.object({ id: zod.z.string() }), SummaryDetailSchema.nullable()),
|
|
231667
232343
|
clearTracks: require_sleep.method(zod.z.object({ deviceId: zod.z.number() }), zod.z.void(), {
|
|
@@ -236147,10 +236823,28 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
236147
236823
|
getSessionState: require_sleep.method(zod.z.object({
|
|
236148
236824
|
deviceId: zod.z.number().int().nonnegative(),
|
|
236149
236825
|
sessionId: zod.z.string()
|
|
236150
|
-
}), zod.z.object({
|
|
236151
|
-
|
|
236152
|
-
|
|
236153
|
-
|
|
236826
|
+
}), zod.z.object({
|
|
236827
|
+
pendingRenegotiation: zod.z.object({
|
|
236828
|
+
target: WebrtcStreamTargetSchema,
|
|
236829
|
+
epoch: zod.z.number()
|
|
236830
|
+
}).nullable(),
|
|
236831
|
+
/**
|
|
236832
|
+
* Whether the session still EXISTS.
|
|
236833
|
+
*
|
|
236834
|
+
* A consumer that holds a resource for the life of a session needs to
|
|
236835
|
+
* be able to ask, because a session does not always end the way it
|
|
236836
|
+
* began. Measured on this hub 2026-09-13: an Echo that got stuck never
|
|
236837
|
+
* sent `SessionDisconnected`, so the Alexa exporter's
|
|
236838
|
+
* `releaseEgressTranscode` never ran, and a 2304x1296 HEVC to 720p
|
|
236839
|
+
* H.264 transcode kept running for NOBODY for more than twenty
|
|
236840
|
+
* minutes. The WebRTC session had logged `WebRTC session closed`
|
|
236841
|
+
* minutes earlier — the broker knew; the holder had no way to ask.
|
|
236842
|
+
*
|
|
236843
|
+
* `false` for a session id the provider has never heard of, which is
|
|
236844
|
+
* the same answer as "it ended": either way nothing is holding it up.
|
|
236845
|
+
*/
|
|
236846
|
+
alive: zod.z.boolean()
|
|
236847
|
+
}))
|
|
236154
236848
|
},
|
|
236155
236849
|
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
236156
236850
|
mount: { kind: "server-provided" }
|
|
@@ -244265,7 +244959,29 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
244265
244959
|
* disarmed the channels it did not mention would make the Levels page and
|
|
244266
244960
|
* the Diagnostics page fight over the same value.
|
|
244267
244961
|
*/
|
|
244268
|
-
channels: zod.z.array(LogChannelWindowPatchSchema).readonly().optional()
|
|
244962
|
+
channels: zod.z.array(LogChannelWindowPatchSchema).readonly().optional(),
|
|
244963
|
+
/**
|
|
244964
|
+
* How many days the analytics OPS LOG is kept — the audit trail of what
|
|
244965
|
+
* retention actually deleted.
|
|
244966
|
+
*
|
|
244967
|
+
* It lives HERE, on the logging document, and not on the analytics addon's
|
|
244968
|
+
* settings form, on the operator's instruction: every other log-ish window in
|
|
244969
|
+
* this system is configured through this one document, and a retention audit
|
|
244970
|
+
* configured somewhere else is a second place to look when the question is
|
|
244971
|
+
* "what happened to my data".
|
|
244972
|
+
*
|
|
244973
|
+
* That placement has a cost worth stating: this document ships in the
|
|
244974
|
+
* framework closure, so this knob needs a published `@camstack/server` while
|
|
244975
|
+
* the four windows beside it (D485) reach a node on `camstack deploy`.
|
|
244976
|
+
*
|
|
244977
|
+
* `retention-model.ts` argued this one must NOT follow a device window,
|
|
244978
|
+
* because the audit trail is the history of the SWEEP and not of the camera.
|
|
244979
|
+
* That argument stands and is untouched — what changes is that 30 days stops
|
|
244980
|
+
* being a constant nobody can reach. `0` keeps it forever. The floor is 1 day
|
|
244981
|
+
* rather than 0-as-delete: an audit log truncated to nothing is precisely the
|
|
244982
|
+
* state in which the next 9.5 GiB leak cannot be explained.
|
|
244983
|
+
*/
|
|
244984
|
+
opsLogRetentionDays: zod.z.number().int().min(0).max(3650).optional()
|
|
244269
244985
|
});
|
|
244270
244986
|
var ReportedLoadContributionSchema = LoadContributionSchema.extend({ addonId: zod.z.string() });
|
|
244271
244987
|
var ReportedFailureContributionSchema = FailureContributionSchema.extend({ addonId: zod.z.string() });
|
|
@@ -244304,6 +245020,14 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
244304
245020
|
channels: zod.z.array(LogChannelDescriptorSchema).readonly(),
|
|
244305
245021
|
/** The channels ARMED right now, each with its deadline. */
|
|
244306
245022
|
activeChannels: zod.z.array(LogChannelWindowStateSchema).readonly(),
|
|
245023
|
+
/**
|
|
245024
|
+
* The ops-log window in days, as it is in force. `0` = kept forever.
|
|
245025
|
+
*
|
|
245026
|
+
* Reported rather than left to the caller's memory of what it wrote: this is
|
|
245027
|
+
* the value the analytics sweep will actually use, and an operator asking how
|
|
245028
|
+
* long their audit trail lives should not have to infer it from a default.
|
|
245029
|
+
*/
|
|
245030
|
+
opsLogRetentionDays: zod.z.number().int().min(0),
|
|
244307
245031
|
persisted: zod.z.boolean()
|
|
244308
245032
|
});
|
|
244309
245033
|
var systemCapability = {
|
|
@@ -245787,6 +246511,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
245787
246511
|
smoke: smokeCapability,
|
|
245788
246512
|
streamCatalog: streamCatalogCapability,
|
|
245789
246513
|
streamParams: streamParamsCapability,
|
|
246514
|
+
streamSignals: streamSignalsCapability,
|
|
245790
246515
|
switch: switchCapability,
|
|
245791
246516
|
tamper: tamperCapability,
|
|
245792
246517
|
temperatureSensor: temperatureSensorCapability,
|
|
@@ -248524,6 +249249,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
248524
249249
|
streamBroker: "stream-broker",
|
|
248525
249250
|
streamCatalog: "stream-catalog",
|
|
248526
249251
|
streamParams: "stream-params",
|
|
249252
|
+
streamSignals: "stream-signals",
|
|
248527
249253
|
switch: "switch",
|
|
248528
249254
|
system: "system",
|
|
248529
249255
|
tamper: "tamper",
|
|
@@ -249084,6 +249810,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
249084
249810
|
key: "streamParams",
|
|
249085
249811
|
name: "stream-params"
|
|
249086
249812
|
},
|
|
249813
|
+
{
|
|
249814
|
+
key: "streamSignals",
|
|
249815
|
+
name: "stream-signals"
|
|
249816
|
+
},
|
|
249087
249817
|
{
|
|
249088
249818
|
key: "switch",
|
|
249089
249819
|
name: "switch"
|
|
@@ -249308,6 +250038,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
249308
250038
|
streamBrokerCapability,
|
|
249309
250039
|
streamCatalogCapability,
|
|
249310
250040
|
streamParamsCapability,
|
|
250041
|
+
streamSignalsCapability,
|
|
249311
250042
|
switchCapability,
|
|
249312
250043
|
systemCapability,
|
|
249313
250044
|
tamperCapability,
|
|
@@ -252782,6 +253513,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
252782
253513
|
addonId: null,
|
|
252783
253514
|
access: "view"
|
|
252784
253515
|
},
|
|
253516
|
+
"pipelineAnalytics.listRecentSummaries": {
|
|
253517
|
+
capName: "pipeline-analytics",
|
|
253518
|
+
capScope: "device",
|
|
253519
|
+
addonId: null,
|
|
253520
|
+
access: "view"
|
|
253521
|
+
},
|
|
252785
253522
|
"pipelineAnalytics.listRecentTracks": {
|
|
252786
253523
|
capName: "pipeline-analytics",
|
|
252787
253524
|
capScope: "device",
|
|
@@ -254744,6 +255481,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
254744
255481
|
addonId: null,
|
|
254745
255482
|
access: "create"
|
|
254746
255483
|
},
|
|
255484
|
+
"streamBroker.reportStreamSignal": {
|
|
255485
|
+
capName: "stream-broker",
|
|
255486
|
+
capScope: "system",
|
|
255487
|
+
addonId: null,
|
|
255488
|
+
access: "create"
|
|
255489
|
+
},
|
|
254747
255490
|
"streamBroker.restartProfile": {
|
|
254748
255491
|
capName: "stream-broker",
|
|
254749
255492
|
capScope: "system",
|
|
@@ -254828,6 +255571,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
254828
255571
|
addonId: null,
|
|
254829
255572
|
access: "create"
|
|
254830
255573
|
},
|
|
255574
|
+
"streamSignals.listSignals": {
|
|
255575
|
+
capName: "stream-signals",
|
|
255576
|
+
capScope: "device",
|
|
255577
|
+
addonId: null,
|
|
255578
|
+
access: "view"
|
|
255579
|
+
},
|
|
254831
255580
|
"switch.setState": {
|
|
254832
255581
|
capName: "switch",
|
|
254833
255582
|
capScope: "device",
|
|
@@ -255631,6 +256380,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
255631
256380
|
"stream-broker",
|
|
255632
256381
|
"stream-catalog",
|
|
255633
256382
|
"stream-params",
|
|
256383
|
+
"stream-signals",
|
|
255634
256384
|
"switch",
|
|
255635
256385
|
"system",
|
|
255636
256386
|
"terminal-session",
|
|
@@ -255697,6 +256447,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
255697
256447
|
"snapshot",
|
|
255698
256448
|
"stream-catalog",
|
|
255699
256449
|
"stream-params",
|
|
256450
|
+
"stream-signals",
|
|
255700
256451
|
"switch",
|
|
255701
256452
|
"update",
|
|
255702
256453
|
"vacuum-control",
|
|
@@ -256873,6 +257624,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
256873
257624
|
form: "single",
|
|
256874
257625
|
optional: true
|
|
256875
257626
|
}],
|
|
257627
|
+
"pipelineAnalytics.listRecentSummaries": [{
|
|
257628
|
+
name: "deviceIds",
|
|
257629
|
+
form: "array",
|
|
257630
|
+
optional: false
|
|
257631
|
+
}],
|
|
256876
257632
|
"pipelineAnalytics.listRecentTracks": [{
|
|
256877
257633
|
name: "deviceIds",
|
|
256878
257634
|
form: "array",
|
|
@@ -257459,6 +258215,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
257459
258215
|
form: "single",
|
|
257460
258216
|
optional: false
|
|
257461
258217
|
}],
|
|
258218
|
+
"streamBroker.reportStreamSignal": [{
|
|
258219
|
+
name: "deviceId",
|
|
258220
|
+
form: "single",
|
|
258221
|
+
optional: false
|
|
258222
|
+
}],
|
|
257462
258223
|
"streamBroker.restartProfile": [{
|
|
257463
258224
|
name: "deviceId",
|
|
257464
258225
|
form: "single",
|
|
@@ -257816,6 +258577,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
257816
258577
|
"streamBroker.produceEventMedia",
|
|
257817
258578
|
"streamBroker.publishCameraStream",
|
|
257818
258579
|
"streamBroker.renderPreBufferClip",
|
|
258580
|
+
"streamBroker.reportStreamSignal",
|
|
257819
258581
|
"streamBroker.restartProfile",
|
|
257820
258582
|
"streamBroker.retractCameraStream",
|
|
257821
258583
|
"streamBroker.setDeviceAudioMute",
|
|
@@ -258065,6 +258827,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
258065
258827
|
durability: "restored",
|
|
258066
258828
|
volatileFields: ["lastFetchedAt"]
|
|
258067
258829
|
},
|
|
258830
|
+
"stream-signals": {
|
|
258831
|
+
durability: "session",
|
|
258832
|
+
volatileFields: []
|
|
258833
|
+
},
|
|
258068
258834
|
"switch": {
|
|
258069
258835
|
durability: "restored",
|
|
258070
258836
|
volatileFields: ["lastChangedAt"]
|
|
@@ -262523,6 +263289,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
262523
263289
|
exports.StreamProfileOptionsSchema = StreamProfileOptionsSchema;
|
|
262524
263290
|
exports.StreamProfilePatchSchema = StreamProfilePatchSchema;
|
|
262525
263291
|
exports.StreamProfileSchema = StreamProfileSchema;
|
|
263292
|
+
exports.StreamSignalSchema = StreamSignalSchema;
|
|
263293
|
+
exports.StreamSignalsStatusSchema = StreamSignalsStatusSchema;
|
|
262526
263294
|
exports.StreamSourceEntrySchema = require_sleep.StreamSourceEntrySchema;
|
|
262527
263295
|
exports.StreamSourceSchema = require_sleep.StreamSourceSchema;
|
|
262528
263296
|
exports.SubscribeAudioChunksInputSchema = require_sleep.SubscribeAudioChunksInputSchema;
|
|
@@ -262708,12 +263476,14 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
262708
263476
|
exports.clusterModelSettingKey = clusterModelSettingKey;
|
|
262709
263477
|
exports.clusterStepSettingFieldsFor = clusterStepSettingFieldsFor;
|
|
262710
263478
|
exports.clusterStepSettingKey = clusterStepSettingKey;
|
|
263479
|
+
exports.codecIsAccepted = codecIsAccepted;
|
|
262711
263480
|
exports.collectHydratedFieldEntries = require_sleep.collectHydratedFieldEntries;
|
|
262712
263481
|
exports.collectHydratedFieldValues = require_sleep.collectHydratedFieldValues;
|
|
262713
263482
|
exports.collectSecretConfigKeys = collectSecretConfigKeys;
|
|
262714
263483
|
exports.colorCapability = colorCapability;
|
|
262715
263484
|
exports.colorForKind = colorForKind;
|
|
262716
263485
|
exports.commitWatchdogRestart = commitWatchdogRestart;
|
|
263486
|
+
exports.compareToTarget = compareToTarget;
|
|
262717
263487
|
exports.compileExpression = compileExpression;
|
|
262718
263488
|
exports.compileExpressionSafe = compileExpressionSafe;
|
|
262719
263489
|
exports.composeSwitchedOff = composeSwitchedOff;
|
|
@@ -262972,6 +263742,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
262972
263742
|
exports.ptzAutotrackCapability = ptzAutotrackCapability;
|
|
262973
263743
|
exports.ptzCapability = ptzCapability;
|
|
262974
263744
|
exports.pythonScriptForBackend = pythonScriptForBackend;
|
|
263745
|
+
exports.rankStreams = rankStreams;
|
|
262975
263746
|
exports.readClusterStepModels = readClusterStepModels;
|
|
262976
263747
|
exports.readClusterStepSettings = readClusterStepSettings;
|
|
262977
263748
|
exports.readDetailCropConvention = readDetailCropConvention;
|
|
@@ -263056,6 +263827,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
263056
263827
|
exports.streamParamsCapability = streamParamsCapability;
|
|
263057
263828
|
exports.streamPixels = streamPixels;
|
|
263058
263829
|
exports.streamQualityLabel = streamQualityLabel;
|
|
263830
|
+
exports.streamSignalsCapability = streamSignalsCapability;
|
|
263059
263831
|
exports.stripRetiredBandPreBufferSec = stripRetiredBandPreBufferSec;
|
|
263060
263832
|
exports.strippedOfLegacyReadOnly = strippedOfLegacyReadOnly;
|
|
263061
263833
|
exports.subKindsOf = subKindsOf;
|
|
@@ -264680,6 +265452,15 @@ var require_server_root = __commonJS({
|
|
|
264680
265452
|
__name(buildNpmRegistryArgs, "buildNpmRegistryArgs");
|
|
264681
265453
|
var NPM_VIEW_TIMEOUT_MS = 2e4;
|
|
264682
265454
|
var NPM_INSTALL_TIMEOUT_MS = 15 * 6e4;
|
|
265455
|
+
var CLOSURE_ALLOW_SCRIPTS = {
|
|
265456
|
+
"@camstack/server": true,
|
|
265457
|
+
"better-sqlite3": true,
|
|
265458
|
+
"node-av": true,
|
|
265459
|
+
"node-pty": true,
|
|
265460
|
+
ssh2: true,
|
|
265461
|
+
"cpu-features": true,
|
|
265462
|
+
esbuild: true
|
|
265463
|
+
};
|
|
264683
265464
|
var RESTART_REASON_PREFIX = "server-update";
|
|
264684
265465
|
var STALE_TRANSIENT_MS = 24 * 60 * 60 * 1e3;
|
|
264685
265466
|
function readWrapperProbes() {
|
|
@@ -264727,6 +265508,7 @@ var require_server_root = __commonJS({
|
|
|
264727
265508
|
dataDir;
|
|
264728
265509
|
execNpm;
|
|
264729
265510
|
ensureNativePrebuildsFn;
|
|
265511
|
+
applyClosurePatchesFn;
|
|
264730
265512
|
env;
|
|
264731
265513
|
readWrapperProbesFn;
|
|
264732
265514
|
now;
|
|
@@ -264755,6 +265537,7 @@ var require_server_root = __commonJS({
|
|
|
264755
265537
|
};
|
|
264756
265538
|
});
|
|
264757
265539
|
this.ensureNativePrebuildsFn = options.ensureNativePrebuilds ?? (async () => void 0);
|
|
265540
|
+
this.applyClosurePatchesFn = options.applyClosurePatches ?? (async () => void 0);
|
|
264758
265541
|
this.env = options.env ?? process.env;
|
|
264759
265542
|
this.readWrapperProbesFn = options.readWrapperProbes ?? readWrapperProbes;
|
|
264760
265543
|
this.now = options.now ?? Date.now;
|
|
@@ -265070,7 +265853,8 @@ var require_server_root = __commonJS({
|
|
|
265070
265853
|
} else {
|
|
265071
265854
|
fs6.writeFileSync(path6.join(stagingDir, "package.json"), JSON.stringify({
|
|
265072
265855
|
name: "camstack-node-root",
|
|
265073
|
-
private: true
|
|
265856
|
+
private: true,
|
|
265857
|
+
allowScripts: CLOSURE_ALLOW_SCRIPTS
|
|
265074
265858
|
}, null, 2), "utf-8");
|
|
265075
265859
|
await this.execNpm([
|
|
265076
265860
|
...installArgs,
|
|
@@ -265103,6 +265887,15 @@ var require_server_root = __commonJS({
|
|
|
265103
265887
|
if (missingNatives.length > 0) {
|
|
265104
265888
|
throw new Error(`staged closure missing native prebuilds: ${missingNatives.join(", ")} \u2014 refusing to arm a swap that would break the forked runners`);
|
|
265105
265889
|
}
|
|
265890
|
+
try {
|
|
265891
|
+
await this.applyClosurePatchesFn(stagingDir);
|
|
265892
|
+
} catch (err) {
|
|
265893
|
+
this.logger.warn("closure-patch apply step failed \u2014 validator will decide", {
|
|
265894
|
+
meta: {
|
|
265895
|
+
error: err instanceof Error ? err.message : String(err)
|
|
265896
|
+
}
|
|
265897
|
+
});
|
|
265898
|
+
}
|
|
265106
265899
|
const unpatched = findUnappliedClosurePatches(stagingDir);
|
|
265107
265900
|
if (unpatched.length > 0) {
|
|
265108
265901
|
throw new Error(`staged closure did not apply its shipped patches: ${unpatched.join(", ")} \u2014 refusing to arm a swap into an unpatched closure`);
|
|
@@ -265150,6 +265943,7 @@ var require_server_root = __commonJS({
|
|
|
265150
265943
|
return {
|
|
265151
265944
|
name: "camstack-node-root",
|
|
265152
265945
|
private: true,
|
|
265946
|
+
allowScripts: CLOSURE_ALLOW_SCRIPTS,
|
|
265153
265947
|
dependencies: {
|
|
265154
265948
|
[this.spec.packageName]: fileRef(rootTgz)
|
|
265155
265949
|
},
|
|
@@ -396107,6 +396901,78 @@ var require_system_ensure_prebuilds = __commonJS({
|
|
|
396107
396901
|
}
|
|
396108
396902
|
});
|
|
396109
396903
|
|
|
396904
|
+
// ../../server/backend/dist/core/server-update/system-apply-closure-patches.js
|
|
396905
|
+
var require_system_apply_closure_patches = __commonJS({
|
|
396906
|
+
"../../server/backend/dist/core/server-update/system-apply-closure-patches.js"(exports) {
|
|
396907
|
+
"use strict";
|
|
396908
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
396909
|
+
if (k2 === void 0) k2 = k;
|
|
396910
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
396911
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
396912
|
+
desc = { enumerable: true, get: function() {
|
|
396913
|
+
return m[k];
|
|
396914
|
+
} };
|
|
396915
|
+
}
|
|
396916
|
+
Object.defineProperty(o, k2, desc);
|
|
396917
|
+
}) : (function(o, m, k, k2) {
|
|
396918
|
+
if (k2 === void 0) k2 = k;
|
|
396919
|
+
o[k2] = m[k];
|
|
396920
|
+
}));
|
|
396921
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v) {
|
|
396922
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
396923
|
+
}) : function(o, v) {
|
|
396924
|
+
o["default"] = v;
|
|
396925
|
+
});
|
|
396926
|
+
var __importStar = exports && exports.__importStar || /* @__PURE__ */ (function() {
|
|
396927
|
+
var ownKeys = function(o) {
|
|
396928
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
396929
|
+
var ar = [];
|
|
396930
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
396931
|
+
return ar;
|
|
396932
|
+
};
|
|
396933
|
+
return ownKeys(o);
|
|
396934
|
+
};
|
|
396935
|
+
return function(mod) {
|
|
396936
|
+
if (mod && mod.__esModule) return mod;
|
|
396937
|
+
var result = {};
|
|
396938
|
+
if (mod != null) {
|
|
396939
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
396940
|
+
}
|
|
396941
|
+
__setModuleDefault(result, mod);
|
|
396942
|
+
return result;
|
|
396943
|
+
};
|
|
396944
|
+
})();
|
|
396945
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
396946
|
+
exports.buildSystemApplyClosurePatches = buildSystemApplyClosurePatches;
|
|
396947
|
+
var node_child_process_1 = __require("child_process");
|
|
396948
|
+
var fs = __importStar(__require("fs"));
|
|
396949
|
+
var path = __importStar(__require("path"));
|
|
396950
|
+
var node_util_1 = __require("util");
|
|
396951
|
+
var execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
396952
|
+
var APPLIER_REL = ["node_modules", "@camstack", "server", "scripts", "closure-postinstall.mjs"];
|
|
396953
|
+
var APPLY_TIMEOUT_MS = 6e4;
|
|
396954
|
+
function buildSystemApplyClosurePatches(logger) {
|
|
396955
|
+
return async (closureDir) => {
|
|
396956
|
+
const applier = path.join(closureDir, ...APPLIER_REL);
|
|
396957
|
+
if (!fs.existsSync(applier)) {
|
|
396958
|
+
logger.debug("closure ships no patch applier \u2014 nothing to apply", {
|
|
396959
|
+
meta: { applier }
|
|
396960
|
+
});
|
|
396961
|
+
return;
|
|
396962
|
+
}
|
|
396963
|
+
const { stdout, stderr } = await execFileAsync(process.execPath, [applier], {
|
|
396964
|
+
cwd: path.dirname(path.dirname(applier)),
|
|
396965
|
+
timeout: APPLY_TIMEOUT_MS
|
|
396966
|
+
});
|
|
396967
|
+
const output = `${stdout}${stderr}`.trim();
|
|
396968
|
+
if (output.length > 0) {
|
|
396969
|
+
logger.info("closure patches applied", { meta: { output } });
|
|
396970
|
+
}
|
|
396971
|
+
};
|
|
396972
|
+
}
|
|
396973
|
+
}
|
|
396974
|
+
});
|
|
396975
|
+
|
|
396110
396976
|
// ../../server/backend/dist/core/server-update/system-exec-npm.js
|
|
396111
396977
|
var require_system_exec_npm = __commonJS({
|
|
396112
396978
|
"../../server/backend/dist/core/server-update/system-exec-npm.js"(exports) {
|
|
@@ -396494,6 +397360,7 @@ var require_agent_update_service = __commonJS({
|
|
|
396494
397360
|
var system_1 = require_dist3();
|
|
396495
397361
|
var types_1 = require_dist4();
|
|
396496
397362
|
var system_ensure_prebuilds_js_1 = require_system_ensure_prebuilds();
|
|
397363
|
+
var system_apply_closure_patches_js_1 = require_system_apply_closure_patches();
|
|
396497
397364
|
var system_exec_npm_js_1 = require_system_exec_npm();
|
|
396498
397365
|
var update_availability_emitter_js_1 = require_update_availability_emitter();
|
|
396499
397366
|
var update_availability_store_js_1 = require_update_availability_store();
|
|
@@ -396582,6 +397449,11 @@ var require_agent_update_service = __commonJS({
|
|
|
396582
397449
|
// ships the identical bare Node, so its `applyServerUpdate` staging would
|
|
396583
397450
|
// hit the same source-only `better-sqlite3` miss without this.
|
|
396584
397451
|
ensureNativePrebuilds: options.ensureNativePrebuilds ?? (0, system_ensure_prebuilds_js_1.buildSystemEnsureNativePrebuilds)(options.logger),
|
|
397452
|
+
// Apply the closure patches ourselves. npm 12 blocks the root package's
|
|
397453
|
+
// postinstall by default, and a silently-unpatched closure is refused by
|
|
397454
|
+
// the validator — an update that can never apply. Idempotent, so this
|
|
397455
|
+
// costs nothing where npm did run the lifecycle.
|
|
397456
|
+
applyClosurePatches: options.applyClosurePatches ?? (0, system_apply_closure_patches_js_1.buildSystemApplyClosurePatches)(options.logger),
|
|
396585
397457
|
env: options.env,
|
|
396586
397458
|
now: options.now
|
|
396587
397459
|
});
|
|
@@ -421021,7 +421893,7 @@ var require_logging_settings = __commonJS({
|
|
|
421021
421893
|
"../../server/backend/dist/api/core/logging-settings.js"(exports) {
|
|
421022
421894
|
"use strict";
|
|
421023
421895
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
421024
|
-
exports.LoggingSettingsService = exports.MAX_CHANNEL_WINDOW_MS = exports.EMPTY_LOG_CHANNEL_PLANE = exports.HUB_NODE_ID = exports.LOGGING_SETTINGS_KEY = void 0;
|
|
421896
|
+
exports.LoggingSettingsService = exports.MAX_CHANNEL_WINDOW_MS = exports.EMPTY_LOG_CHANNEL_PLANE = exports.OPS_LOG_RETENTION_DEFAULT_DAYS = exports.HUB_NODE_ID = exports.LOGGING_SETTINGS_KEY = void 0;
|
|
421025
421897
|
exports.buildLogChannelPlane = buildLogChannelPlane;
|
|
421026
421898
|
exports.toLoggingSettingsRecord = toLoggingSettingsRecord;
|
|
421027
421899
|
exports.resolveLevel = resolveLevel;
|
|
@@ -421037,6 +421909,7 @@ var require_logging_settings = __commonJS({
|
|
|
421037
421909
|
var SYSTEM_SETTINGS_COLLECTION = "system-settings";
|
|
421038
421910
|
exports.HUB_NODE_ID = "hub";
|
|
421039
421911
|
var LOG_LEVELS = ["debug", "info", "warn", "error"];
|
|
421912
|
+
exports.OPS_LOG_RETENTION_DEFAULT_DAYS = 30;
|
|
421040
421913
|
exports.EMPTY_LOG_CHANNEL_PLANE = {
|
|
421041
421914
|
declarations: async () => [],
|
|
421042
421915
|
apply: async () => {
|
|
@@ -421118,6 +421991,9 @@ var require_logging_settings = __commonJS({
|
|
|
421118
421991
|
if (levelChanged) {
|
|
421119
421992
|
next = mergeLevel(next, scope, component, patch.level ?? null, this.now());
|
|
421120
421993
|
}
|
|
421994
|
+
if (patch.opsLogRetentionDays !== void 0) {
|
|
421995
|
+
next = { ...next, opsLogRetentionDays: patch.opsLogRetentionDays, updatedAt: this.now() };
|
|
421996
|
+
}
|
|
421121
421997
|
if (channelsChanged) {
|
|
421122
421998
|
const declared = await this.channels.declarations();
|
|
421123
421999
|
const rejected = validateChannelPatch(patch.channels ?? [], declared);
|
|
@@ -421207,6 +422083,7 @@ var require_logging_settings = __commonJS({
|
|
|
421207
422083
|
activeWindows: await this.describeWindows(),
|
|
421208
422084
|
channels: await this.declaredChannels(),
|
|
421209
422085
|
activeChannels: describeChannelWindows(record ?? {}, this.now()),
|
|
422086
|
+
opsLogRetentionDays: record?.opsLogRetentionDays ?? exports.OPS_LOG_RETENTION_DEFAULT_DAYS,
|
|
421210
422087
|
persisted: record !== null
|
|
421211
422088
|
};
|
|
421212
422089
|
}
|
|
@@ -434655,6 +435532,7 @@ var require_server_update_service = __commonJS({
|
|
|
434655
435532
|
var index_js_1 = require_server_root();
|
|
434656
435533
|
var update_availability_emitter_js_1 = require_update_availability_emitter();
|
|
434657
435534
|
var system_ensure_prebuilds_js_1 = require_system_ensure_prebuilds();
|
|
435535
|
+
var system_apply_closure_patches_js_1 = require_system_apply_closure_patches();
|
|
434658
435536
|
var system_exec_npm_js_1 = require_system_exec_npm();
|
|
434659
435537
|
var ServerUpdateService = class extends index_js_1.RootUpdateService {
|
|
434660
435538
|
updateAvailability;
|
|
@@ -434688,6 +435566,11 @@ var require_server_update_service = __commonJS({
|
|
|
434688
435566
|
// native-prebuild validator refuses the swap (toolchain-less packaged
|
|
434689
435567
|
// desktop). No-op on docker where the install already carried it.
|
|
434690
435568
|
ensureNativePrebuilds: options.ensureNativePrebuilds ?? (0, system_ensure_prebuilds_js_1.buildSystemEnsureNativePrebuilds)(options.logger),
|
|
435569
|
+
// Apply the closure patches ourselves. npm 12 blocks the root package's
|
|
435570
|
+
// postinstall by default, and a silently-unpatched closure is refused by
|
|
435571
|
+
// the validator — an update that can never apply. Idempotent, so this
|
|
435572
|
+
// costs nothing where npm did run the lifecycle.
|
|
435573
|
+
applyClosurePatches: options.applyClosurePatches ?? (0, system_apply_closure_patches_js_1.buildSystemApplyClosurePatches)(options.logger),
|
|
434691
435574
|
env: options.env,
|
|
434692
435575
|
now: options.now
|
|
434693
435576
|
});
|