camstack 1.2.146 → 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.
|
@@ -14522,7 +14522,7 @@ function date4(params) {
|
|
|
14522
14522
|
// ../../node_modules/zod/v4/classic/external.js
|
|
14523
14523
|
config(en_default());
|
|
14524
14524
|
|
|
14525
|
-
// ../types/dist/sleep-
|
|
14525
|
+
// ../types/dist/sleep-DEuj7E3j.mjs
|
|
14526
14526
|
var AUDIO_CHUNK_FORMATS = [
|
|
14527
14527
|
"f32le",
|
|
14528
14528
|
"pcmu",
|
|
@@ -18788,6 +18788,39 @@ var cameraPipelineConfigCapability = {
|
|
|
18788
18788
|
exposesDeviceSettings: true,
|
|
18789
18789
|
methods: {}
|
|
18790
18790
|
};
|
|
18791
|
+
var StreamSignalSchema = external_exports.object({
|
|
18792
|
+
/** Stable id chosen by the provider, e.g. `'motion'`, `'person'`, `'tamper'`. */
|
|
18793
|
+
code: external_exports.string().min(1),
|
|
18794
|
+
/** What an operator reads in the picker. The provider's own wording. */
|
|
18795
|
+
label: external_exports.string().min(1),
|
|
18796
|
+
/**
|
|
18797
|
+
* Whether the provider recommends this signal ON when a camera is first set
|
|
18798
|
+
* up. A provider knows which of its signals are cheap and reliable; an
|
|
18799
|
+
* operator should not have to discover that by trial. Reolink recommends
|
|
18800
|
+
* both of its own.
|
|
18801
|
+
*/
|
|
18802
|
+
recommended: external_exports.boolean()
|
|
18803
|
+
});
|
|
18804
|
+
var StreamSignalsStatusSchema = external_exports.object({
|
|
18805
|
+
signals: external_exports.array(StreamSignalSchema),
|
|
18806
|
+
lastFetchedAt: external_exports.number()
|
|
18807
|
+
});
|
|
18808
|
+
var streamSignalsCapability = {
|
|
18809
|
+
name: "stream-signals",
|
|
18810
|
+
scope: "device",
|
|
18811
|
+
deviceNative: true,
|
|
18812
|
+
mode: "singleton",
|
|
18813
|
+
deviceTypes: Object.values(DeviceType),
|
|
18814
|
+
runtimeState: StreamSignalsStatusSchema,
|
|
18815
|
+
methods: {
|
|
18816
|
+
/**
|
|
18817
|
+
* What this device can emit. Empty is a valid and common answer — most
|
|
18818
|
+
* cameras have nothing to offer here, and an empty list is what makes the
|
|
18819
|
+
* broker's picker show nothing rather than a false choice.
|
|
18820
|
+
*/
|
|
18821
|
+
listSignals: method(external_exports.void(), external_exports.array(StreamSignalSchema).readonly())
|
|
18822
|
+
}
|
|
18823
|
+
};
|
|
18791
18824
|
var StreamFormatSchema = external_exports.enum([
|
|
18792
18825
|
"webrtc",
|
|
18793
18826
|
"hls",
|
|
@@ -19140,6 +19173,46 @@ var streamBrokerCapability = {
|
|
|
19140
19173
|
mode: "singleton",
|
|
19141
19174
|
exposesDeviceSettings: true,
|
|
19142
19175
|
methods: {
|
|
19176
|
+
/**
|
|
19177
|
+
* A device reporting that one of ITS OWN signals just fired.
|
|
19178
|
+
*
|
|
19179
|
+
* The provider calls this; nothing polls. The broker then decides whether
|
|
19180
|
+
* to wake the source, and the decision has two terms that must BOTH hold:
|
|
19181
|
+
*
|
|
19182
|
+
* - the signal is ENABLED for this camera (the operator's per-camera
|
|
19183
|
+
* choice — a camera may declare a signal the operator does not want
|
|
19184
|
+
* waking anything), and
|
|
19185
|
+
* - a consumer is actually attached and waiting on the prestream. Waking
|
|
19186
|
+
* a camera nobody is watching is the one thing a battery camera must
|
|
19187
|
+
* never do, and a signal arriving with no consumer is exactly that.
|
|
19188
|
+
*
|
|
19189
|
+
* Reported, never inferred: a signal that fires while the stream is
|
|
19190
|
+
* already up refreshes the hold instead of starting a second one, which is
|
|
19191
|
+
* what makes continuous motion keep a camera awake without stacking
|
|
19192
|
+
* timers.
|
|
19193
|
+
*
|
|
19194
|
+
* `code` is the provider's own, from `streamSignals.listSignals`. An
|
|
19195
|
+
* unknown code is REFUSED rather than treated as a wildcard wake — a
|
|
19196
|
+
* provider and an operator disagreeing about a name must not become a
|
|
19197
|
+
* camera that wakes for everything.
|
|
19198
|
+
*/
|
|
19199
|
+
reportStreamSignal: method(external_exports.object({
|
|
19200
|
+
deviceId: external_exports.number().int().nonnegative(),
|
|
19201
|
+
/** The provider's signal code. */
|
|
19202
|
+
code: external_exports.string().min(1),
|
|
19203
|
+
/** Ms epoch. Absent ⇒ now. */
|
|
19204
|
+
at: external_exports.number().optional()
|
|
19205
|
+
}), external_exports.object({
|
|
19206
|
+
/** Whether the broker acted on it, and if not, why. */
|
|
19207
|
+
accepted: external_exports.boolean(),
|
|
19208
|
+
reason: external_exports.enum([
|
|
19209
|
+
"woke",
|
|
19210
|
+
"hold-extended",
|
|
19211
|
+
"not-enabled",
|
|
19212
|
+
"no-consumer",
|
|
19213
|
+
"unknown-code"
|
|
19214
|
+
])
|
|
19215
|
+
}), { kind: "mutation" }),
|
|
19143
19216
|
publishCameraStream: method(external_exports.object({
|
|
19144
19217
|
deviceId: external_exports.number().int().nonnegative(),
|
|
19145
19218
|
camStreamId: external_exports.string().min(1),
|
|
@@ -19617,6 +19690,16 @@ var PickStreamRequirementsSchema = external_exports.object({
|
|
|
19617
19690
|
acceptCodecs: external_exports.array(StreamCodecSchema).readonly().optional(),
|
|
19618
19691
|
/** Minimum vertical resolution. Streams shorter than this are dropped. */
|
|
19619
19692
|
minHeight: external_exports.number().int().positive().optional(),
|
|
19693
|
+
/**
|
|
19694
|
+
* Maximum vertical resolution. Streams TALLER than this are dropped.
|
|
19695
|
+
*
|
|
19696
|
+
* A consumer can have a ceiling as real as its floor: Alexa documents
|
|
19697
|
+
* 480p to 1080p, and a 4K stream is as unusable to an Echo as a 360p one.
|
|
19698
|
+
* Without this the ceiling had to be re-implemented by every caller — and
|
|
19699
|
+
* one caller implementing it privately is how a second scoring authority
|
|
19700
|
+
* gets born.
|
|
19701
|
+
*/
|
|
19702
|
+
maxHeight: external_exports.number().int().positive().optional(),
|
|
19620
19703
|
/** Minimum horizontal resolution. */
|
|
19621
19704
|
minWidth: external_exports.number().int().positive().optional(),
|
|
19622
19705
|
/**
|
|
@@ -19633,7 +19716,22 @@ var PickStreamRequirementsSchema = external_exports.object({
|
|
|
19633
19716
|
* transcoded" guard: if the device is already serving the consumer's
|
|
19634
19717
|
* codec end-to-end, there's nothing to optimise.
|
|
19635
19718
|
*/
|
|
19636
|
-
requireSiblingCodec: external_exports.array(StreamCodecSchema).readonly().optional()
|
|
19719
|
+
requireSiblingCodec: external_exports.array(StreamCodecSchema).readonly().optional(),
|
|
19720
|
+
/**
|
|
19721
|
+
* Whether a stream the consumer CANNOT decode may still be picked, on the
|
|
19722
|
+
* understanding that it will be transcoded.
|
|
19723
|
+
*
|
|
19724
|
+
* Default `false` — today's behaviour, and the right one for a bypass
|
|
19725
|
+
* question ("is there a stream I can forward untouched?"). Set `true` to
|
|
19726
|
+
* ask the larger question: "what is the best stream for me, transcoding if
|
|
19727
|
+
* I must?" A stream that satisfies `acceptCodecs` always outranks one that
|
|
19728
|
+
* does not, so a passthrough is never lost to a transcode; the answer says
|
|
19729
|
+
* which it is in {@link PickedCamStreamSchema.transcodes}.
|
|
19730
|
+
*
|
|
19731
|
+
* This is what lets one picker serve both the bypass and the full source
|
|
19732
|
+
* choice, instead of a consumer scoring privately when the bypass misses.
|
|
19733
|
+
*/
|
|
19734
|
+
allowTranscode: external_exports.boolean().optional()
|
|
19637
19735
|
}).readonly();
|
|
19638
19736
|
var PickStreamPreferencesSchema = external_exports.object({
|
|
19639
19737
|
/**
|
|
@@ -19647,12 +19745,32 @@ var PickStreamPreferencesSchema = external_exports.object({
|
|
|
19647
19745
|
* picks the tallest stream; `'lowest'` picks the shortest (used by
|
|
19648
19746
|
* memory-constrained consumers / Apple Home guest sessions).
|
|
19649
19747
|
*/
|
|
19650
|
-
resolutionPreference: external_exports.enum(["highest", "lowest"]).optional()
|
|
19748
|
+
resolutionPreference: external_exports.enum(["highest", "lowest"]).optional(),
|
|
19749
|
+
/**
|
|
19750
|
+
* The height the consumer actually wants to DELIVER.
|
|
19751
|
+
*
|
|
19752
|
+
* Not a constraint — an ordering. With it set, the SMALLEST stream at or
|
|
19753
|
+
* above the target wins, and only if nothing reaches it does the tallest
|
|
19754
|
+
* take over. Pulling 1296 lines to draw 720 on a 1280x800 Echo panel costs
|
|
19755
|
+
* a decode and buys nothing, and `resolutionPreference: 'highest'` cannot
|
|
19756
|
+
* express that: it says "as big as possible", which is a different wish.
|
|
19757
|
+
*
|
|
19758
|
+
* Ignored when absent, so every existing caller keeps its ordering.
|
|
19759
|
+
*/
|
|
19760
|
+
targetHeight: external_exports.number().int().positive().optional()
|
|
19651
19761
|
}).readonly();
|
|
19652
19762
|
var PickedCamStreamSchema = external_exports.object({
|
|
19653
19763
|
camStreamId: external_exports.string(),
|
|
19654
19764
|
codec: external_exports.string().optional(),
|
|
19655
19765
|
resolution: CamStreamResolutionSchema.optional(),
|
|
19766
|
+
/**
|
|
19767
|
+
* Whether serving this stream requires a decode + re-encode.
|
|
19768
|
+
*
|
|
19769
|
+
* `false` is a stream the consumer can take as it stands. Only ever `true`
|
|
19770
|
+
* when the caller asked for it with `allowTranscode`, so a caller that did
|
|
19771
|
+
* not ask cannot be handed a cost it never agreed to pay.
|
|
19772
|
+
*/
|
|
19773
|
+
transcodes: external_exports.boolean(),
|
|
19656
19774
|
/** One-line explanation of why this stream won — for logs / debug UI. */
|
|
19657
19775
|
reason: external_exports.string()
|
|
19658
19776
|
});
|
|
@@ -24463,6 +24581,8 @@ var NcSystemEventKindSchema = external_exports.enum([
|
|
|
24463
24581
|
"device-enabled",
|
|
24464
24582
|
"device-battery-low",
|
|
24465
24583
|
"device-battery-normal",
|
|
24584
|
+
"device-consumable-low",
|
|
24585
|
+
"device-consumable-normal",
|
|
24466
24586
|
"stream-online",
|
|
24467
24587
|
"stream-offline",
|
|
24468
24588
|
"node-online",
|
|
@@ -24481,6 +24601,7 @@ var NcSystemEventKindSchema = external_exports.enum([
|
|
|
24481
24601
|
"addon-updated",
|
|
24482
24602
|
"server-updated",
|
|
24483
24603
|
"export-completed",
|
|
24604
|
+
"backup-completed",
|
|
24484
24605
|
"camera-online",
|
|
24485
24606
|
"camera-offline",
|
|
24486
24607
|
"camera-disabled",
|
|
@@ -32245,10 +32366,28 @@ var webrtcSessionCapability = {
|
|
|
32245
32366
|
getSessionState: method(external_exports.object({
|
|
32246
32367
|
deviceId: external_exports.number().int().nonnegative(),
|
|
32247
32368
|
sessionId: external_exports.string()
|
|
32248
|
-
}), external_exports.object({
|
|
32249
|
-
|
|
32250
|
-
|
|
32251
|
-
|
|
32369
|
+
}), external_exports.object({
|
|
32370
|
+
pendingRenegotiation: external_exports.object({
|
|
32371
|
+
target: WebrtcStreamTargetSchema,
|
|
32372
|
+
epoch: external_exports.number()
|
|
32373
|
+
}).nullable(),
|
|
32374
|
+
/**
|
|
32375
|
+
* Whether the session still EXISTS.
|
|
32376
|
+
*
|
|
32377
|
+
* A consumer that holds a resource for the life of a session needs to
|
|
32378
|
+
* be able to ask, because a session does not always end the way it
|
|
32379
|
+
* began. Measured on this hub 2026-09-13: an Echo that got stuck never
|
|
32380
|
+
* sent `SessionDisconnected`, so the Alexa exporter's
|
|
32381
|
+
* `releaseEgressTranscode` never ran, and a 2304x1296 HEVC to 720p
|
|
32382
|
+
* H.264 transcode kept running for NOBODY for more than twenty
|
|
32383
|
+
* minutes. The WebRTC session had logged `WebRTC session closed`
|
|
32384
|
+
* minutes earlier — the broker knew; the holder had no way to ask.
|
|
32385
|
+
*
|
|
32386
|
+
* `false` for a session id the provider has never heard of, which is
|
|
32387
|
+
* the same answer as "it ended": either way nothing is holding it up.
|
|
32388
|
+
*/
|
|
32389
|
+
alive: external_exports.boolean()
|
|
32390
|
+
}))
|
|
32252
32391
|
},
|
|
32253
32392
|
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
32254
32393
|
mount: { kind: "server-provided" }
|
|
@@ -46536,6 +46675,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
46536
46675
|
addonId: null,
|
|
46537
46676
|
access: "create"
|
|
46538
46677
|
},
|
|
46678
|
+
"streamBroker.reportStreamSignal": {
|
|
46679
|
+
capName: "stream-broker",
|
|
46680
|
+
capScope: "system",
|
|
46681
|
+
addonId: null,
|
|
46682
|
+
access: "create"
|
|
46683
|
+
},
|
|
46539
46684
|
"streamBroker.restartProfile": {
|
|
46540
46685
|
capName: "stream-broker",
|
|
46541
46686
|
capScope: "system",
|
|
@@ -46620,6 +46765,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
46620
46765
|
addonId: null,
|
|
46621
46766
|
access: "create"
|
|
46622
46767
|
},
|
|
46768
|
+
"streamSignals.listSignals": {
|
|
46769
|
+
capName: "stream-signals",
|
|
46770
|
+
capScope: "device",
|
|
46771
|
+
addonId: null,
|
|
46772
|
+
access: "view"
|
|
46773
|
+
},
|
|
46623
46774
|
"switch.setState": {
|
|
46624
46775
|
capName: "switch",
|
|
46625
46776
|
capScope: "device",
|
|
@@ -48992,6 +49143,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
|
|
|
48992
49143
|
form: "single",
|
|
48993
49144
|
optional: false
|
|
48994
49145
|
}],
|
|
49146
|
+
"streamBroker.reportStreamSignal": [{
|
|
49147
|
+
name: "deviceId",
|
|
49148
|
+
form: "single",
|
|
49149
|
+
optional: false
|
|
49150
|
+
}],
|
|
48995
49151
|
"streamBroker.restartProfile": [{
|
|
48996
49152
|
name: "deviceId",
|
|
48997
49153
|
form: "single",
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runDiscover
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-IGFZA22D.js";
|
|
5
5
|
import "./chunk-LMMQX4CK.js";
|
|
6
6
|
|
|
7
7
|
// src/cli.ts
|
|
@@ -38,7 +38,7 @@ async function runServe(args) {
|
|
|
38
38
|
...typeof values.data === "string" ? { data: values.data } : {}
|
|
39
39
|
};
|
|
40
40
|
Object.assign(process.env, buildServeEnv(opts));
|
|
41
|
-
await import("./launcher-
|
|
41
|
+
await import("./launcher-26BZ4JHD.js");
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// src/commands/agent.ts
|
|
@@ -83,7 +83,7 @@ async function runAgent(args) {
|
|
|
83
83
|
...typeof values.port === "string" ? { port: values.port } : {}
|
|
84
84
|
};
|
|
85
85
|
Object.assign(process.env, buildAgentEnv(opts));
|
|
86
|
-
await import("./launcher-
|
|
86
|
+
await import("./launcher-26BZ4JHD.js");
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
// src/commands/setup.ts
|
|
@@ -1140,7 +1140,7 @@ function isUnknown(_value) {
|
|
|
1140
1140
|
return true;
|
|
1141
1141
|
}
|
|
1142
1142
|
async function resolveServerInteractive(presetNamespace) {
|
|
1143
|
-
const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-
|
|
1143
|
+
const { discoverNodes, resolveHubFromDiscovered, filterHubNodes, DEFAULT_HUB_HTTPS_PORT } = await import("./discover-ZCOCQKSU.js");
|
|
1144
1144
|
if (presetNamespace) {
|
|
1145
1145
|
const spinner4 = clack.spinner();
|
|
1146
1146
|
spinner4.start(`Discovering hub on LAN (namespace "${presetNamespace}")`);
|
|
@@ -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_DUSfUAgz = __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";
|
|
@@ -29446,6 +29447,39 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
29446
29447
|
exposesDeviceSettings: true,
|
|
29447
29448
|
methods: {}
|
|
29448
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
|
+
};
|
|
29449
29483
|
var StreamFormatSchema = zod.z.enum([
|
|
29450
29484
|
"webrtc",
|
|
29451
29485
|
"hls",
|
|
@@ -29798,6 +29832,46 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
29798
29832
|
mode: "singleton",
|
|
29799
29833
|
exposesDeviceSettings: true,
|
|
29800
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" }),
|
|
29801
29875
|
publishCameraStream: method(zod.z.object({
|
|
29802
29876
|
deviceId: zod.z.number().int().nonnegative(),
|
|
29803
29877
|
camStreamId: zod.z.string().min(1),
|
|
@@ -30275,6 +30349,16 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
30275
30349
|
acceptCodecs: zod.z.array(StreamCodecSchema).readonly().optional(),
|
|
30276
30350
|
/** Minimum vertical resolution. Streams shorter than this are dropped. */
|
|
30277
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(),
|
|
30278
30362
|
/** Minimum horizontal resolution. */
|
|
30279
30363
|
minWidth: zod.z.number().int().positive().optional(),
|
|
30280
30364
|
/**
|
|
@@ -30291,7 +30375,22 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
30291
30375
|
* transcoded" guard: if the device is already serving the consumer's
|
|
30292
30376
|
* codec end-to-end, there's nothing to optimise.
|
|
30293
30377
|
*/
|
|
30294
|
-
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()
|
|
30295
30394
|
}).readonly();
|
|
30296
30395
|
var PickStreamPreferencesSchema = zod.z.object({
|
|
30297
30396
|
/**
|
|
@@ -30305,12 +30404,32 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
30305
30404
|
* picks the tallest stream; `'lowest'` picks the shortest (used by
|
|
30306
30405
|
* memory-constrained consumers / Apple Home guest sessions).
|
|
30307
30406
|
*/
|
|
30308
|
-
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()
|
|
30309
30420
|
}).readonly();
|
|
30310
30421
|
var PickedCamStreamSchema = zod.z.object({
|
|
30311
30422
|
camStreamId: zod.z.string(),
|
|
30312
30423
|
codec: zod.z.string().optional(),
|
|
30313
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(),
|
|
30314
30433
|
/** One-line explanation of why this stream won — for logs / debug UI. */
|
|
30315
30434
|
reason: zod.z.string()
|
|
30316
30435
|
});
|
|
@@ -35224,6 +35343,8 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
35224
35343
|
"device-enabled",
|
|
35225
35344
|
"device-battery-low",
|
|
35226
35345
|
"device-battery-normal",
|
|
35346
|
+
"device-consumable-low",
|
|
35347
|
+
"device-consumable-normal",
|
|
35227
35348
|
"stream-online",
|
|
35228
35349
|
"stream-offline",
|
|
35229
35350
|
"node-online",
|
|
@@ -35242,6 +35363,7 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
35242
35363
|
"addon-updated",
|
|
35243
35364
|
"server-updated",
|
|
35244
35365
|
"export-completed",
|
|
35366
|
+
"backup-completed",
|
|
35245
35367
|
"camera-online",
|
|
35246
35368
|
"camera-offline",
|
|
35247
35369
|
"camera-disabled",
|
|
@@ -42830,10 +42952,28 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
42830
42952
|
getSessionState: method(zod.z.object({
|
|
42831
42953
|
deviceId: zod.z.number().int().nonnegative(),
|
|
42832
42954
|
sessionId: zod.z.string()
|
|
42833
|
-
}), zod.z.object({
|
|
42834
|
-
|
|
42835
|
-
|
|
42836
|
-
|
|
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
|
+
}))
|
|
42837
42977
|
},
|
|
42838
42978
|
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
42839
42979
|
mount: { kind: "server-provided" }
|
|
@@ -52506,6 +52646,7 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
52506
52646
|
streamBrokerCapability,
|
|
52507
52647
|
streamCatalogCapability,
|
|
52508
52648
|
streamParamsCapability,
|
|
52649
|
+
streamSignalsCapability,
|
|
52509
52650
|
switchCapability,
|
|
52510
52651
|
systemCapability,
|
|
52511
52652
|
tamperCapability,
|
|
@@ -57948,6 +58089,12 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
57948
58089
|
addonId: null,
|
|
57949
58090
|
access: "create"
|
|
57950
58091
|
},
|
|
58092
|
+
"streamBroker.reportStreamSignal": {
|
|
58093
|
+
capName: "stream-broker",
|
|
58094
|
+
capScope: "system",
|
|
58095
|
+
addonId: null,
|
|
58096
|
+
access: "create"
|
|
58097
|
+
},
|
|
57951
58098
|
"streamBroker.restartProfile": {
|
|
57952
58099
|
capName: "stream-broker",
|
|
57953
58100
|
capScope: "system",
|
|
@@ -58032,6 +58179,12 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
58032
58179
|
addonId: null,
|
|
58033
58180
|
access: "create"
|
|
58034
58181
|
},
|
|
58182
|
+
"streamSignals.listSignals": {
|
|
58183
|
+
capName: "stream-signals",
|
|
58184
|
+
capScope: "device",
|
|
58185
|
+
addonId: null,
|
|
58186
|
+
access: "view"
|
|
58187
|
+
},
|
|
58035
58188
|
"switch.setState": {
|
|
58036
58189
|
capName: "switch",
|
|
58037
58190
|
capScope: "device",
|
|
@@ -60404,6 +60557,11 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
60404
60557
|
form: "single",
|
|
60405
60558
|
optional: false
|
|
60406
60559
|
}],
|
|
60560
|
+
"streamBroker.reportStreamSignal": [{
|
|
60561
|
+
name: "deviceId",
|
|
60562
|
+
form: "single",
|
|
60563
|
+
optional: false
|
|
60564
|
+
}],
|
|
60407
60565
|
"streamBroker.restartProfile": [{
|
|
60408
60566
|
name: "deviceId",
|
|
60409
60567
|
form: "single",
|
|
@@ -60855,6 +61013,10 @@ var require_dist_DUSfUAgz = __commonJS({
|
|
|
60855
61013
|
durability: "restored",
|
|
60856
61014
|
volatileFields: ["lastFetchedAt"]
|
|
60857
61015
|
},
|
|
61016
|
+
"stream-signals": {
|
|
61017
|
+
durability: "session",
|
|
61018
|
+
volatileFields: []
|
|
61019
|
+
},
|
|
60858
61020
|
"switch": {
|
|
60859
61021
|
durability: "restored",
|
|
60860
61022
|
volatileFields: ["lastChangedAt"]
|
|
@@ -62139,7 +62301,7 @@ var require_alerts_addon = __commonJS({
|
|
|
62139
62301
|
[Symbol.toStringTag]: { value: "Module" }
|
|
62140
62302
|
});
|
|
62141
62303
|
require_chunk_Cek0wNdY();
|
|
62142
|
-
var require_dist10 =
|
|
62304
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
62143
62305
|
function selectExpired(alerts, cutoffMs) {
|
|
62144
62306
|
return alerts.filter((a) => a.createdAt < cutoffMs).sort((a, b) => a.createdAt - b.createdAt).map((a) => a.id);
|
|
62145
62307
|
}
|
|
@@ -62958,7 +63120,7 @@ var require_console_logging = __commonJS({
|
|
|
62958
63120
|
[Symbol.toStringTag]: { value: "Module" }
|
|
62959
63121
|
});
|
|
62960
63122
|
require_chunk_Cek0wNdY();
|
|
62961
|
-
var require_dist10 =
|
|
63123
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
62962
63124
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
62963
63125
|
var LEVEL_RANK = {
|
|
62964
63126
|
debug: 0,
|
|
@@ -63052,7 +63214,7 @@ var require_core_blocks_addon = __commonJS({
|
|
|
63052
63214
|
"use strict";
|
|
63053
63215
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
63054
63216
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
63055
|
-
var require_dist10 =
|
|
63217
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
63056
63218
|
var node_crypto = __require("crypto");
|
|
63057
63219
|
var node_fs_promises = __require("fs/promises");
|
|
63058
63220
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -63949,11 +64111,11 @@ var require_core_blocks = __commonJS({
|
|
|
63949
64111
|
}
|
|
63950
64112
|
});
|
|
63951
64113
|
|
|
63952
|
-
// ../system/dist/retired-settings-keys-
|
|
63953
|
-
var
|
|
63954
|
-
"../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) {
|
|
63955
64117
|
"use strict";
|
|
63956
|
-
var require_dist10 =
|
|
64118
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
63957
64119
|
function settingsStoreIsAuthoritativeHere(env) {
|
|
63958
64120
|
const raw = (env["CAMSTACK_ROLE"] ?? "").trim().toLowerCase();
|
|
63959
64121
|
return raw === "" || raw === "hub";
|
|
@@ -66190,8 +66352,8 @@ var require_device_manager_addon = __commonJS({
|
|
|
66190
66352
|
[Symbol.toStringTag]: { value: "Module" }
|
|
66191
66353
|
});
|
|
66192
66354
|
require_chunk_Cek0wNdY();
|
|
66193
|
-
var require_dist10 =
|
|
66194
|
-
var require_retired_settings_keys =
|
|
66355
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
66356
|
+
var require_retired_settings_keys = require_retired_settings_keys_FLZlwa2U();
|
|
66195
66357
|
var node_crypto = __require("crypto");
|
|
66196
66358
|
var _camstack_types_node = require_node();
|
|
66197
66359
|
var JOB_HISTORY = 20;
|
|
@@ -71816,7 +71978,7 @@ var require_hub_forwarder = __commonJS({
|
|
|
71816
71978
|
[Symbol.toStringTag]: { value: "Module" }
|
|
71817
71979
|
});
|
|
71818
71980
|
require_chunk_Cek0wNdY();
|
|
71819
|
-
var require_dist10 =
|
|
71981
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
71820
71982
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
71821
71983
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
71822
71984
|
var HubForwarderDestination = class {
|
|
@@ -71953,7 +72115,7 @@ var require_liveness_monitor_addon = __commonJS({
|
|
|
71953
72115
|
"use strict";
|
|
71954
72116
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
71955
72117
|
require_chunk_Cek0wNdY();
|
|
71956
|
-
var require_dist10 =
|
|
72118
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
71957
72119
|
var NO_DEVICES = "liveness:no-devices";
|
|
71958
72120
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
71959
72121
|
var NO_FOOTAGE_PREFIX = "liveness:no-footage:";
|
|
@@ -72149,7 +72311,7 @@ var require_local_auth_addon = __commonJS({
|
|
|
72149
72311
|
[Symbol.toStringTag]: { value: "Module" }
|
|
72150
72312
|
});
|
|
72151
72313
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
72152
|
-
var require_dist10 =
|
|
72314
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
72153
72315
|
var node_crypto = __require("crypto");
|
|
72154
72316
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
72155
72317
|
var crypto$1 = __require("crypto");
|
|
@@ -79962,7 +80124,7 @@ var require_loki_logging = __commonJS({
|
|
|
79962
80124
|
[Symbol.toStringTag]: { value: "Module" }
|
|
79963
80125
|
});
|
|
79964
80126
|
require_chunk_Cek0wNdY();
|
|
79965
|
-
var require_dist10 =
|
|
80127
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
79966
80128
|
function sanitizeLabelName(raw) {
|
|
79967
80129
|
const replaced = raw.replaceAll(/[^a-zA-Z0-9_]/g, "_");
|
|
79968
80130
|
return /^[a-zA-Z_]/.test(replaced) ? replaced : `_${replaced}`;
|
|
@@ -80549,7 +80711,7 @@ var require_native_metrics_addon = __commonJS({
|
|
|
80549
80711
|
[Symbol.toStringTag]: { value: "Module" }
|
|
80550
80712
|
});
|
|
80551
80713
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
80552
|
-
var require_dist10 =
|
|
80714
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
80553
80715
|
var node_fs_promises = __require("fs/promises");
|
|
80554
80716
|
var node_fs = __require("fs");
|
|
80555
80717
|
node_fs = require_chunk.__toESM(node_fs);
|
|
@@ -83302,7 +83464,7 @@ var require_filesystem_storage_addon = __commonJS({
|
|
|
83302
83464
|
[Symbol.toStringTag]: { value: "Module" }
|
|
83303
83465
|
});
|
|
83304
83466
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
83305
|
-
var require_dist10 =
|
|
83467
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
83306
83468
|
var node_crypto = __require("crypto");
|
|
83307
83469
|
var node_fs_promises = __require("fs/promises");
|
|
83308
83470
|
var node_path = __require("path");
|
|
@@ -84529,8 +84691,8 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
84529
84691
|
[Symbol.toStringTag]: { value: "Module" }
|
|
84530
84692
|
});
|
|
84531
84693
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
84532
|
-
var require_dist10 =
|
|
84533
|
-
var require_retired_settings_keys =
|
|
84694
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
84695
|
+
var require_retired_settings_keys = require_retired_settings_keys_FLZlwa2U();
|
|
84534
84696
|
var require_wal_checkpoint_policy = require_wal_checkpoint_policy_CCJZngds();
|
|
84535
84697
|
var node_crypto = __require("crypto");
|
|
84536
84698
|
var node_path = __require("path");
|
|
@@ -87317,7 +87479,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
87317
87479
|
[Symbol.toStringTag]: { value: "Module" }
|
|
87318
87480
|
});
|
|
87319
87481
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
87320
|
-
var require_dist10 =
|
|
87482
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
87321
87483
|
var require_hub_cap_forward = require_hub_cap_forward_DmHNjbB0();
|
|
87322
87484
|
var zod = require_zod();
|
|
87323
87485
|
var node_crypto = __require("crypto");
|
|
@@ -91044,7 +91206,7 @@ var require_system_config_addon = __commonJS({
|
|
|
91044
91206
|
[Symbol.toStringTag]: { value: "Module" }
|
|
91045
91207
|
});
|
|
91046
91208
|
require_chunk_Cek0wNdY();
|
|
91047
|
-
var require_dist10 =
|
|
91209
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
91048
91210
|
var SECTION_TITLES = {
|
|
91049
91211
|
server: "Server",
|
|
91050
91212
|
auth: "Authentication"
|
|
@@ -109105,7 +109267,7 @@ var require_winston_logging = __commonJS({
|
|
|
109105
109267
|
[Symbol.toStringTag]: { value: "Module" }
|
|
109106
109268
|
});
|
|
109107
109269
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
109108
|
-
var require_dist10 =
|
|
109270
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
109109
109271
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
109110
109272
|
var node_path = __require("path");
|
|
109111
109273
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -110974,9 +111136,9 @@ ${(0, node_fs.readFileSync)(ca.caCertPath, "utf-8").trimEnd()}
|
|
|
110974
111136
|
}
|
|
110975
111137
|
});
|
|
110976
111138
|
|
|
110977
|
-
// ../types/dist/event-category-
|
|
110978
|
-
var
|
|
110979
|
-
"../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) {
|
|
110980
111142
|
"use strict";
|
|
110981
111143
|
var EventCategory = /* @__PURE__ */ (function(EventCategory2) {
|
|
110982
111144
|
EventCategory2["SystemBoot"] = "system.boot";
|
|
@@ -111116,6 +111278,7 @@ var require_event_category_yW4s1MGD = __commonJS({
|
|
|
111116
111278
|
EventCategory2["LocalNetworkChanged"] = "network.local.changed";
|
|
111117
111279
|
EventCategory2["MeshNetworkChanged"] = "network.mesh.changed";
|
|
111118
111280
|
EventCategory2["BackupCompleted"] = "backup.completed";
|
|
111281
|
+
EventCategory2["BackupRunCompleted"] = "backup.run-completed";
|
|
111119
111282
|
EventCategory2["BackupRestored"] = "backup.restored";
|
|
111120
111283
|
EventCategory2["NotificationDispatched"] = "notification.dispatched";
|
|
111121
111284
|
EventCategory2["NotificationFailed"] = "notification.failed";
|
|
@@ -111142,11 +111305,11 @@ var require_event_category_yW4s1MGD = __commonJS({
|
|
|
111142
111305
|
}
|
|
111143
111306
|
});
|
|
111144
111307
|
|
|
111145
|
-
// ../types/dist/sleep-
|
|
111146
|
-
var
|
|
111147
|
-
"../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) {
|
|
111148
111311
|
"use strict";
|
|
111149
|
-
var require_event_category =
|
|
111312
|
+
var require_event_category = require_event_category_BVfsrBYA();
|
|
111150
111313
|
var zod = require_zod();
|
|
111151
111314
|
var AUDIO_CHUNK_FORMATS = [
|
|
111152
111315
|
"f32le",
|
|
@@ -113641,6 +113804,7 @@ var require_sleep_DXsYD0RX = __commonJS({
|
|
|
113641
113804
|
smoke: createSliceHandle(stateSource, binding.deviceId, "smoke"),
|
|
113642
113805
|
streamCatalog: createSliceHandle(stateSource, binding.deviceId, "stream-catalog"),
|
|
113643
113806
|
streamParams: createSliceHandle(stateSource, binding.deviceId, "stream-params"),
|
|
113807
|
+
streamSignals: createSliceHandle(stateSource, binding.deviceId, "stream-signals"),
|
|
113644
113808
|
switch: createSliceHandle(stateSource, binding.deviceId, "switch"),
|
|
113645
113809
|
tamper: createSliceHandle(stateSource, binding.deviceId, "tamper"),
|
|
113646
113810
|
temperatureSensor: createSliceHandle(stateSource, binding.deviceId, "temperature-sensor"),
|
|
@@ -114055,6 +114219,7 @@ var require_sleep_DXsYD0RX = __commonJS({
|
|
|
114055
114219
|
getConfigSchema: (input) => dispatch("stream-params", "streamParams", "getConfigSchema", "query", input),
|
|
114056
114220
|
getStatus: (input) => dispatch("stream-params", "streamParams", "getStatus", "query", input)
|
|
114057
114221
|
},
|
|
114222
|
+
streamSignals: { listSignals: (input) => dispatch("stream-signals", "streamSignals", "listSignals", "query", input) },
|
|
114058
114223
|
switch: {
|
|
114059
114224
|
setState: (input) => dispatch("switch", "switch", "setState", "mutation", input),
|
|
114060
114225
|
getStatus: (input) => dispatch("switch", "switch", "getStatus", "query", input)
|
|
@@ -114264,6 +114429,7 @@ var require_sleep_DXsYD0RX = __commonJS({
|
|
|
114264
114429
|
},
|
|
114265
114430
|
recordingExport: { listExports: (input) => dispatchSystem("recordingExport", "listExports", "query", input) },
|
|
114266
114431
|
streamBroker: {
|
|
114432
|
+
reportStreamSignal: (input) => dispatchSystem("streamBroker", "reportStreamSignal", "mutation", input),
|
|
114267
114433
|
publishCameraStream: (input) => dispatchSystem("streamBroker", "publishCameraStream", "mutation", input),
|
|
114268
114434
|
retractCameraStream: (input) => dispatchSystem("streamBroker", "retractCameraStream", "mutation", input),
|
|
114269
114435
|
assignProfile: (input) => dispatchSystem("streamBroker", "assignProfile", "mutation", input),
|
|
@@ -114350,6 +114516,7 @@ var require_sleep_DXsYD0RX = __commonJS({
|
|
|
114350
114516
|
"snapshot",
|
|
114351
114517
|
"stream-catalog",
|
|
114352
114518
|
"stream-params",
|
|
114519
|
+
"stream-signals",
|
|
114353
114520
|
"switch",
|
|
114354
114521
|
"tamper",
|
|
114355
114522
|
"temperature-sensor",
|
|
@@ -114977,8 +115144,8 @@ var require_addon = __commonJS({
|
|
|
114977
115144
|
"../types/dist/addon.js"(exports) {
|
|
114978
115145
|
"use strict";
|
|
114979
115146
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
114980
|
-
var require_sleep =
|
|
114981
|
-
var require_event_category =
|
|
115147
|
+
var require_sleep = require_sleep_D7dV_FZB();
|
|
115148
|
+
var require_event_category = require_event_category_BVfsrBYA();
|
|
114982
115149
|
var require_err_msg = require_err_msg_COpsHMw2();
|
|
114983
115150
|
var CAP_INPUT_DEFAULTS = Object.freeze({
|
|
114984
115151
|
"addons": { "getLogs": { "limit": 100 } },
|
|
@@ -131387,11 +131554,11 @@ var require_manifest_system_deps_CrSP0Kkp = __commonJS({
|
|
|
131387
131554
|
}
|
|
131388
131555
|
});
|
|
131389
131556
|
|
|
131390
|
-
// ../system/dist/custom-action-registry-
|
|
131391
|
-
var
|
|
131392
|
-
"../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) {
|
|
131393
131560
|
"use strict";
|
|
131394
|
-
var require_dist10 =
|
|
131561
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
131395
131562
|
var CustomActionRegistry = class {
|
|
131396
131563
|
byAddon = /* @__PURE__ */ new Map();
|
|
131397
131564
|
registerAddon(addonId, catalog, handler) {
|
|
@@ -135205,7 +135372,7 @@ var require_dist3 = __commonJS({
|
|
|
135205
135372
|
"use strict";
|
|
135206
135373
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
135207
135374
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
135208
|
-
var require_dist10 =
|
|
135375
|
+
var require_dist10 = require_dist_CEIkHEdy();
|
|
135209
135376
|
var require_builtins_alerts_alerts_addon = require_alerts_addon();
|
|
135210
135377
|
require_alerts();
|
|
135211
135378
|
var require_formatter = require_formatter_DqAKDlvN();
|
|
@@ -135234,7 +135401,7 @@ var require_dist3 = __commonJS({
|
|
|
135234
135401
|
var require_tls$1 = require_tls_BFs4PzoW();
|
|
135235
135402
|
var require_manifest_system_deps = require_manifest_system_deps_CrSP0Kkp();
|
|
135236
135403
|
var require_resource_monitor = require_resource_monitor_LVE1BoLs();
|
|
135237
|
-
var require_custom_action_registry =
|
|
135404
|
+
var require_custom_action_registry = require_custom_action_registry_YHpAdksL();
|
|
135238
135405
|
var zod = require_zod();
|
|
135239
135406
|
var node_crypto = __require("crypto");
|
|
135240
135407
|
var _camstack_types_node = require_node();
|
|
@@ -216323,7 +216490,7 @@ var require_enums = __commonJS({
|
|
|
216323
216490
|
"../types/dist/enums.js"(exports) {
|
|
216324
216491
|
"use strict";
|
|
216325
216492
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
216326
|
-
var require_event_category =
|
|
216493
|
+
var require_event_category = require_event_category_BVfsrBYA();
|
|
216327
216494
|
var EventSourceType = /* @__PURE__ */ (function(EventSourceType2) {
|
|
216328
216495
|
EventSourceType2["Addon"] = "addon";
|
|
216329
216496
|
EventSourceType2["Core"] = "core";
|
|
@@ -216343,8 +216510,8 @@ var require_dist4 = __commonJS({
|
|
|
216343
216510
|
"../types/dist/index.js"(exports) {
|
|
216344
216511
|
"use strict";
|
|
216345
216512
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
216346
|
-
var require_sleep =
|
|
216347
|
-
var require_event_category =
|
|
216513
|
+
var require_sleep = require_sleep_D7dV_FZB();
|
|
216514
|
+
var require_event_category = require_event_category_BVfsrBYA();
|
|
216348
216515
|
var require_canonical_hash = require_canonical_hash_9lydiEzx();
|
|
216349
216516
|
var require_enums2 = require_enums();
|
|
216350
216517
|
var require_err_msg = require_err_msg_COpsHMw2();
|
|
@@ -216586,6 +216753,50 @@ var require_dist4 = __commonJS({
|
|
|
216586
216753
|
audio: "passthrough"
|
|
216587
216754
|
};
|
|
216588
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
|
+
}
|
|
216589
216800
|
var BASE_LIVE_EGRESS_PROFILE = {
|
|
216590
216801
|
video: {
|
|
216591
216802
|
codec: "h264",
|
|
@@ -219104,22 +219315,10 @@ var require_dist4 = __commonJS({
|
|
|
219104
219315
|
}
|
|
219105
219316
|
function pickClosestResolution(entries2, target) {
|
|
219106
219317
|
const targetPixels = target.width * target.height;
|
|
219107
|
-
|
|
219108
|
-
|
|
219109
|
-
|
|
219110
|
-
|
|
219111
|
-
const pixels = e.resolution.width * e.resolution.height;
|
|
219112
|
-
if (pixels >= targetPixels) {
|
|
219113
|
-
if (!bestAbove || pixels < bestAbove.pixels) bestAbove = {
|
|
219114
|
-
entry: e,
|
|
219115
|
-
pixels
|
|
219116
|
-
};
|
|
219117
|
-
} else if (!bestBelow || pixels > bestBelow.pixels) bestBelow = {
|
|
219118
|
-
entry: e,
|
|
219119
|
-
pixels
|
|
219120
|
-
};
|
|
219121
|
-
}
|
|
219122
|
-
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;
|
|
219123
219322
|
}
|
|
219124
219323
|
var FORMAT_KEYS = [
|
|
219125
219324
|
"onnx",
|
|
@@ -221981,6 +222180,39 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
221981
222180
|
exposesDeviceSettings: true,
|
|
221982
222181
|
methods: {}
|
|
221983
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
|
+
};
|
|
221984
222216
|
var StreamFormatSchema = zod.z.enum([
|
|
221985
222217
|
"webrtc",
|
|
221986
222218
|
"hls",
|
|
@@ -222333,6 +222565,46 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222333
222565
|
mode: "singleton",
|
|
222334
222566
|
exposesDeviceSettings: true,
|
|
222335
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" }),
|
|
222336
222608
|
publishCameraStream: require_sleep.method(zod.z.object({
|
|
222337
222609
|
deviceId: zod.z.number().int().nonnegative(),
|
|
222338
222610
|
camStreamId: zod.z.string().min(1),
|
|
@@ -222810,6 +223082,16 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222810
223082
|
acceptCodecs: zod.z.array(StreamCodecSchema).readonly().optional(),
|
|
222811
223083
|
/** Minimum vertical resolution. Streams shorter than this are dropped. */
|
|
222812
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(),
|
|
222813
223095
|
/** Minimum horizontal resolution. */
|
|
222814
223096
|
minWidth: zod.z.number().int().positive().optional(),
|
|
222815
223097
|
/**
|
|
@@ -222826,7 +223108,22 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222826
223108
|
* transcoded" guard: if the device is already serving the consumer's
|
|
222827
223109
|
* codec end-to-end, there's nothing to optimise.
|
|
222828
223110
|
*/
|
|
222829
|
-
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()
|
|
222830
223127
|
}).readonly();
|
|
222831
223128
|
var PickStreamPreferencesSchema = zod.z.object({
|
|
222832
223129
|
/**
|
|
@@ -222840,12 +223137,32 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
222840
223137
|
* picks the tallest stream; `'lowest'` picks the shortest (used by
|
|
222841
223138
|
* memory-constrained consumers / Apple Home guest sessions).
|
|
222842
223139
|
*/
|
|
222843
|
-
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()
|
|
222844
223153
|
}).readonly();
|
|
222845
223154
|
var PickedCamStreamSchema = zod.z.object({
|
|
222846
223155
|
camStreamId: zod.z.string(),
|
|
222847
223156
|
codec: zod.z.string().optional(),
|
|
222848
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(),
|
|
222849
223166
|
/** One-line explanation of why this stream won — for logs / debug UI. */
|
|
222850
223167
|
reason: zod.z.string()
|
|
222851
223168
|
});
|
|
@@ -228224,6 +228541,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
228224
228541
|
"device-enabled",
|
|
228225
228542
|
"device-battery-low",
|
|
228226
228543
|
"device-battery-normal",
|
|
228544
|
+
"device-consumable-low",
|
|
228545
|
+
"device-consumable-normal",
|
|
228227
228546
|
"stream-online",
|
|
228228
228547
|
"stream-offline",
|
|
228229
228548
|
"node-online",
|
|
@@ -228242,6 +228561,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
228242
228561
|
"addon-updated",
|
|
228243
228562
|
"server-updated",
|
|
228244
228563
|
"export-completed",
|
|
228564
|
+
"backup-completed",
|
|
228245
228565
|
"camera-online",
|
|
228246
228566
|
"camera-offline",
|
|
228247
228567
|
"camera-disabled",
|
|
@@ -229103,10 +229423,22 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
229103
229423
|
value: "server-updated",
|
|
229104
229424
|
label: "Server updated"
|
|
229105
229425
|
},
|
|
229426
|
+
{
|
|
229427
|
+
value: "device-consumable-low",
|
|
229428
|
+
label: "Consumable low"
|
|
229429
|
+
},
|
|
229430
|
+
{
|
|
229431
|
+
value: "device-consumable-normal",
|
|
229432
|
+
label: "Consumable replaced"
|
|
229433
|
+
},
|
|
229106
229434
|
{
|
|
229107
229435
|
value: "export-completed",
|
|
229108
229436
|
label: "Export completed"
|
|
229109
229437
|
},
|
|
229438
|
+
{
|
|
229439
|
+
value: "backup-completed",
|
|
229440
|
+
label: "Backup completed"
|
|
229441
|
+
},
|
|
229110
229442
|
{
|
|
229111
229443
|
value: "alarm-arming",
|
|
229112
229444
|
label: "Alarm arming (exit delay)"
|
|
@@ -236491,10 +236823,28 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
236491
236823
|
getSessionState: require_sleep.method(zod.z.object({
|
|
236492
236824
|
deviceId: zod.z.number().int().nonnegative(),
|
|
236493
236825
|
sessionId: zod.z.string()
|
|
236494
|
-
}), zod.z.object({
|
|
236495
|
-
|
|
236496
|
-
|
|
236497
|
-
|
|
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
|
+
}))
|
|
236498
236848
|
},
|
|
236499
236849
|
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
236500
236850
|
mount: { kind: "server-provided" }
|
|
@@ -246161,6 +246511,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
246161
246511
|
smoke: smokeCapability,
|
|
246162
246512
|
streamCatalog: streamCatalogCapability,
|
|
246163
246513
|
streamParams: streamParamsCapability,
|
|
246514
|
+
streamSignals: streamSignalsCapability,
|
|
246164
246515
|
switch: switchCapability,
|
|
246165
246516
|
tamper: tamperCapability,
|
|
246166
246517
|
temperatureSensor: temperatureSensorCapability,
|
|
@@ -248898,6 +249249,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
248898
249249
|
streamBroker: "stream-broker",
|
|
248899
249250
|
streamCatalog: "stream-catalog",
|
|
248900
249251
|
streamParams: "stream-params",
|
|
249252
|
+
streamSignals: "stream-signals",
|
|
248901
249253
|
switch: "switch",
|
|
248902
249254
|
system: "system",
|
|
248903
249255
|
tamper: "tamper",
|
|
@@ -249458,6 +249810,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
249458
249810
|
key: "streamParams",
|
|
249459
249811
|
name: "stream-params"
|
|
249460
249812
|
},
|
|
249813
|
+
{
|
|
249814
|
+
key: "streamSignals",
|
|
249815
|
+
name: "stream-signals"
|
|
249816
|
+
},
|
|
249461
249817
|
{
|
|
249462
249818
|
key: "switch",
|
|
249463
249819
|
name: "switch"
|
|
@@ -249682,6 +250038,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
249682
250038
|
streamBrokerCapability,
|
|
249683
250039
|
streamCatalogCapability,
|
|
249684
250040
|
streamParamsCapability,
|
|
250041
|
+
streamSignalsCapability,
|
|
249685
250042
|
switchCapability,
|
|
249686
250043
|
systemCapability,
|
|
249687
250044
|
tamperCapability,
|
|
@@ -255124,6 +255481,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
255124
255481
|
addonId: null,
|
|
255125
255482
|
access: "create"
|
|
255126
255483
|
},
|
|
255484
|
+
"streamBroker.reportStreamSignal": {
|
|
255485
|
+
capName: "stream-broker",
|
|
255486
|
+
capScope: "system",
|
|
255487
|
+
addonId: null,
|
|
255488
|
+
access: "create"
|
|
255489
|
+
},
|
|
255127
255490
|
"streamBroker.restartProfile": {
|
|
255128
255491
|
capName: "stream-broker",
|
|
255129
255492
|
capScope: "system",
|
|
@@ -255208,6 +255571,12 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
255208
255571
|
addonId: null,
|
|
255209
255572
|
access: "create"
|
|
255210
255573
|
},
|
|
255574
|
+
"streamSignals.listSignals": {
|
|
255575
|
+
capName: "stream-signals",
|
|
255576
|
+
capScope: "device",
|
|
255577
|
+
addonId: null,
|
|
255578
|
+
access: "view"
|
|
255579
|
+
},
|
|
255211
255580
|
"switch.setState": {
|
|
255212
255581
|
capName: "switch",
|
|
255213
255582
|
capScope: "device",
|
|
@@ -256011,6 +256380,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
256011
256380
|
"stream-broker",
|
|
256012
256381
|
"stream-catalog",
|
|
256013
256382
|
"stream-params",
|
|
256383
|
+
"stream-signals",
|
|
256014
256384
|
"switch",
|
|
256015
256385
|
"system",
|
|
256016
256386
|
"terminal-session",
|
|
@@ -256077,6 +256447,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
256077
256447
|
"snapshot",
|
|
256078
256448
|
"stream-catalog",
|
|
256079
256449
|
"stream-params",
|
|
256450
|
+
"stream-signals",
|
|
256080
256451
|
"switch",
|
|
256081
256452
|
"update",
|
|
256082
256453
|
"vacuum-control",
|
|
@@ -257844,6 +258215,11 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
257844
258215
|
form: "single",
|
|
257845
258216
|
optional: false
|
|
257846
258217
|
}],
|
|
258218
|
+
"streamBroker.reportStreamSignal": [{
|
|
258219
|
+
name: "deviceId",
|
|
258220
|
+
form: "single",
|
|
258221
|
+
optional: false
|
|
258222
|
+
}],
|
|
257847
258223
|
"streamBroker.restartProfile": [{
|
|
257848
258224
|
name: "deviceId",
|
|
257849
258225
|
form: "single",
|
|
@@ -258201,6 +258577,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
258201
258577
|
"streamBroker.produceEventMedia",
|
|
258202
258578
|
"streamBroker.publishCameraStream",
|
|
258203
258579
|
"streamBroker.renderPreBufferClip",
|
|
258580
|
+
"streamBroker.reportStreamSignal",
|
|
258204
258581
|
"streamBroker.restartProfile",
|
|
258205
258582
|
"streamBroker.retractCameraStream",
|
|
258206
258583
|
"streamBroker.setDeviceAudioMute",
|
|
@@ -258450,6 +258827,10 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
258450
258827
|
durability: "restored",
|
|
258451
258828
|
volatileFields: ["lastFetchedAt"]
|
|
258452
258829
|
},
|
|
258830
|
+
"stream-signals": {
|
|
258831
|
+
durability: "session",
|
|
258832
|
+
volatileFields: []
|
|
258833
|
+
},
|
|
258453
258834
|
"switch": {
|
|
258454
258835
|
durability: "restored",
|
|
258455
258836
|
volatileFields: ["lastChangedAt"]
|
|
@@ -262908,6 +263289,8 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
262908
263289
|
exports.StreamProfileOptionsSchema = StreamProfileOptionsSchema;
|
|
262909
263290
|
exports.StreamProfilePatchSchema = StreamProfilePatchSchema;
|
|
262910
263291
|
exports.StreamProfileSchema = StreamProfileSchema;
|
|
263292
|
+
exports.StreamSignalSchema = StreamSignalSchema;
|
|
263293
|
+
exports.StreamSignalsStatusSchema = StreamSignalsStatusSchema;
|
|
262911
263294
|
exports.StreamSourceEntrySchema = require_sleep.StreamSourceEntrySchema;
|
|
262912
263295
|
exports.StreamSourceSchema = require_sleep.StreamSourceSchema;
|
|
262913
263296
|
exports.SubscribeAudioChunksInputSchema = require_sleep.SubscribeAudioChunksInputSchema;
|
|
@@ -263093,12 +263476,14 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
263093
263476
|
exports.clusterModelSettingKey = clusterModelSettingKey;
|
|
263094
263477
|
exports.clusterStepSettingFieldsFor = clusterStepSettingFieldsFor;
|
|
263095
263478
|
exports.clusterStepSettingKey = clusterStepSettingKey;
|
|
263479
|
+
exports.codecIsAccepted = codecIsAccepted;
|
|
263096
263480
|
exports.collectHydratedFieldEntries = require_sleep.collectHydratedFieldEntries;
|
|
263097
263481
|
exports.collectHydratedFieldValues = require_sleep.collectHydratedFieldValues;
|
|
263098
263482
|
exports.collectSecretConfigKeys = collectSecretConfigKeys;
|
|
263099
263483
|
exports.colorCapability = colorCapability;
|
|
263100
263484
|
exports.colorForKind = colorForKind;
|
|
263101
263485
|
exports.commitWatchdogRestart = commitWatchdogRestart;
|
|
263486
|
+
exports.compareToTarget = compareToTarget;
|
|
263102
263487
|
exports.compileExpression = compileExpression;
|
|
263103
263488
|
exports.compileExpressionSafe = compileExpressionSafe;
|
|
263104
263489
|
exports.composeSwitchedOff = composeSwitchedOff;
|
|
@@ -263357,6 +263742,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
263357
263742
|
exports.ptzAutotrackCapability = ptzAutotrackCapability;
|
|
263358
263743
|
exports.ptzCapability = ptzCapability;
|
|
263359
263744
|
exports.pythonScriptForBackend = pythonScriptForBackend;
|
|
263745
|
+
exports.rankStreams = rankStreams;
|
|
263360
263746
|
exports.readClusterStepModels = readClusterStepModels;
|
|
263361
263747
|
exports.readClusterStepSettings = readClusterStepSettings;
|
|
263362
263748
|
exports.readDetailCropConvention = readDetailCropConvention;
|
|
@@ -263441,6 +263827,7 @@ ${recipe.triggers.map((t, i) => emitTrigger(t, i)).join("\n\n")}
|
|
|
263441
263827
|
exports.streamParamsCapability = streamParamsCapability;
|
|
263442
263828
|
exports.streamPixels = streamPixels;
|
|
263443
263829
|
exports.streamQualityLabel = streamQualityLabel;
|
|
263830
|
+
exports.streamSignalsCapability = streamSignalsCapability;
|
|
263444
263831
|
exports.stripRetiredBandPreBufferSec = stripRetiredBandPreBufferSec;
|
|
263445
263832
|
exports.strippedOfLegacyReadOnly = strippedOfLegacyReadOnly;
|
|
263446
263833
|
exports.subKindsOf = subKindsOf;
|