@camstack/types 1.2.158 → 1.2.160
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon.js +1 -1
- package/dist/addon.mjs +1 -1
- package/dist/capabilities/pipeline-orchestrator.cap.d.ts +8 -1
- package/dist/capabilities/recording.cap.d.ts +9 -3
- package/dist/generated/device-scoped-caps.d.ts +1 -1
- package/dist/index.js +209 -66
- package/dist/index.mjs +208 -67
- package/dist/interfaces/recording-config.d.ts +85 -28
- package/dist/{sleep-IaOr7P-z.mjs → sleep-Cfij6Jj9.mjs} +2 -1
- package/dist/{sleep-BGiOgxye.js → sleep-DDIFZGbc.js} +2 -1
- package/dist/types/detection.d.ts +70 -0
- package/package.json +1 -1
package/dist/addon.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_event_category = require("./event-category-b8kBSOTT.js");
|
|
3
|
-
const require_sleep = require("./sleep-
|
|
3
|
+
const require_sleep = require("./sleep-DDIFZGbc.js");
|
|
4
4
|
const require_err_msg = require("./err-msg-COpsHMw2.js");
|
|
5
5
|
//#region src/generated/cap-input-defaults.ts
|
|
6
6
|
/**
|
package/dist/addon.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as EventCategory } from "./event-category-zAv7pMUz.mjs";
|
|
2
|
-
import { D as adminUiCapability, E as DeviceType, G as scopeKey, H as ReadinessTimeoutError, M as expandCapMethods, R as nodePin, S as DEVICE_CHILDREN_BATCH_MAX, V as ReadinessRegistry, _t as DATAPLANE_SECRET_HEADER, a as asJsonObject, b as deviceOpsCapability, bt as BaseAddon, d as BOOT_RECOVERY_BACKOFF_MS, f as DEVICE_SCOPED_CAPS, h as createEventBusSliceSource, m as createDeviceProxy, p as isDeviceScopedCap, s as asString, t as sleep, u as parseJsonUnknown, wt as emitReadiness, x as viewerUiCapability, xt as normalizeAddonInitResult, yt as DisposerChain, z as readNodePin } from "./sleep-
|
|
2
|
+
import { D as adminUiCapability, E as DeviceType, G as scopeKey, H as ReadinessTimeoutError, M as expandCapMethods, R as nodePin, S as DEVICE_CHILDREN_BATCH_MAX, V as ReadinessRegistry, _t as DATAPLANE_SECRET_HEADER, a as asJsonObject, b as deviceOpsCapability, bt as BaseAddon, d as BOOT_RECOVERY_BACKOFF_MS, f as DEVICE_SCOPED_CAPS, h as createEventBusSliceSource, m as createDeviceProxy, p as isDeviceScopedCap, s as asString, t as sleep, u as parseJsonUnknown, wt as emitReadiness, x as viewerUiCapability, xt as normalizeAddonInitResult, yt as DisposerChain, z as readNodePin } from "./sleep-Cfij6Jj9.mjs";
|
|
3
3
|
import { t as errMsg } from "./err-msg-IQTHeDzc.mjs";
|
|
4
4
|
//#region src/generated/cap-input-defaults.ts
|
|
5
5
|
/**
|
|
@@ -320,11 +320,14 @@ declare const CameraAudioStatusSchema: z.ZodObject<{
|
|
|
320
320
|
nodeId: z.ZodString;
|
|
321
321
|
enabled: z.ZodBoolean;
|
|
322
322
|
}, z.core.$strip>;
|
|
323
|
-
/** Recording mode
|
|
323
|
+
/** Recording mode — THE one definition, shared with the `recording` cap. A
|
|
324
|
+
* copy of the list is how `on-device-decision` could have reached the recorder
|
|
325
|
+
* and not this status block. */
|
|
324
326
|
declare const CameraRecordingModeSchema: z.ZodEnum<{
|
|
325
327
|
off: "off";
|
|
326
328
|
events: "events";
|
|
327
329
|
continuous: "continuous";
|
|
330
|
+
"on-device-decision": "on-device-decision";
|
|
328
331
|
}>;
|
|
329
332
|
/** Recording block — null when no recording cap is active for this device. */
|
|
330
333
|
declare const CameraRecordingStatusSchema: z.ZodObject<{
|
|
@@ -332,6 +335,7 @@ declare const CameraRecordingStatusSchema: z.ZodObject<{
|
|
|
332
335
|
off: "off";
|
|
333
336
|
events: "events";
|
|
334
337
|
continuous: "continuous";
|
|
338
|
+
"on-device-decision": "on-device-decision";
|
|
335
339
|
}>;
|
|
336
340
|
active: z.ZodBoolean;
|
|
337
341
|
storageBytes: z.ZodNumber;
|
|
@@ -501,6 +505,7 @@ declare const CameraStatusSchema: z.ZodObject<{
|
|
|
501
505
|
off: "off";
|
|
502
506
|
events: "events";
|
|
503
507
|
continuous: "continuous";
|
|
508
|
+
"on-device-decision": "on-device-decision";
|
|
504
509
|
}>;
|
|
505
510
|
active: z.ZodBoolean;
|
|
506
511
|
storageBytes: z.ZodNumber;
|
|
@@ -1470,6 +1475,7 @@ export declare const pipelineOrchestratorCapability: {
|
|
|
1470
1475
|
off: "off";
|
|
1471
1476
|
events: "events";
|
|
1472
1477
|
continuous: "continuous";
|
|
1478
|
+
"on-device-decision": "on-device-decision";
|
|
1473
1479
|
}>;
|
|
1474
1480
|
active: z.ZodBoolean;
|
|
1475
1481
|
storageBytes: z.ZodNumber;
|
|
@@ -1605,6 +1611,7 @@ export declare const pipelineOrchestratorCapability: {
|
|
|
1605
1611
|
off: "off";
|
|
1606
1612
|
events: "events";
|
|
1607
1613
|
continuous: "continuous";
|
|
1614
|
+
"on-device-decision": "on-device-decision";
|
|
1608
1615
|
}>;
|
|
1609
1616
|
active: z.ZodBoolean;
|
|
1610
1617
|
storageBytes: z.ZodNumber;
|
|
@@ -17,6 +17,7 @@ export declare const RecordingStatusSchema: z.ZodObject<{
|
|
|
17
17
|
off: "off";
|
|
18
18
|
events: "events";
|
|
19
19
|
continuous: "continuous";
|
|
20
|
+
"on-device-decision": "on-device-decision";
|
|
20
21
|
}>;
|
|
21
22
|
nodeId: z.ZodString;
|
|
22
23
|
storageBytes: z.ZodNumber;
|
|
@@ -338,6 +339,7 @@ export declare const recordingCapability: {
|
|
|
338
339
|
off: "off";
|
|
339
340
|
events: "events";
|
|
340
341
|
continuous: "continuous";
|
|
342
|
+
"on-device-decision": "on-device-decision";
|
|
341
343
|
}>;
|
|
342
344
|
nodeId: z.ZodString;
|
|
343
345
|
storageBytes: z.ZodNumber;
|
|
@@ -462,6 +464,7 @@ export declare const recordingCapability: {
|
|
|
462
464
|
off: "off";
|
|
463
465
|
events: "events";
|
|
464
466
|
continuous: "continuous";
|
|
467
|
+
"on-device-decision": "on-device-decision";
|
|
465
468
|
}>>;
|
|
466
469
|
profiles: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
467
470
|
high: "high";
|
|
@@ -486,11 +489,11 @@ export declare const recordingCapability: {
|
|
|
486
489
|
animal: "animal";
|
|
487
490
|
}>>>;
|
|
488
491
|
sensorDeviceIds: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
489
|
-
deviceSignal: z.ZodOptional<z.ZodBoolean>;
|
|
490
492
|
}, z.core.$strip>>;
|
|
491
493
|
preBufferSec: z.ZodOptional<z.ZodNumber>;
|
|
492
494
|
postBufferSec: z.ZodOptional<z.ZodNumber>;
|
|
493
495
|
}, z.core.$strip>>>;
|
|
496
|
+
deviceDecision: z.ZodOptional<z.ZodBoolean>;
|
|
494
497
|
retention: z.ZodOptional<z.ZodObject<{
|
|
495
498
|
maxAgeDays: z.ZodOptional<z.ZodNumber>;
|
|
496
499
|
maxSizeGb: z.ZodOptional<z.ZodNumber>;
|
|
@@ -564,6 +567,7 @@ export declare const recordingCapability: {
|
|
|
564
567
|
off: "off";
|
|
565
568
|
events: "events";
|
|
566
569
|
continuous: "continuous";
|
|
570
|
+
"on-device-decision": "on-device-decision";
|
|
567
571
|
}>>;
|
|
568
572
|
profiles: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
569
573
|
high: "high";
|
|
@@ -588,11 +592,11 @@ export declare const recordingCapability: {
|
|
|
588
592
|
animal: "animal";
|
|
589
593
|
}>>>;
|
|
590
594
|
sensorDeviceIds: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
591
|
-
deviceSignal: z.ZodOptional<z.ZodBoolean>;
|
|
592
595
|
}, z.core.$strip>>;
|
|
593
596
|
preBufferSec: z.ZodOptional<z.ZodNumber>;
|
|
594
597
|
postBufferSec: z.ZodOptional<z.ZodNumber>;
|
|
595
598
|
}, z.core.$strip>>>;
|
|
599
|
+
deviceDecision: z.ZodOptional<z.ZodBoolean>;
|
|
596
600
|
retention: z.ZodOptional<z.ZodObject<{
|
|
597
601
|
maxAgeDays: z.ZodOptional<z.ZodNumber>;
|
|
598
602
|
maxSizeGb: z.ZodOptional<z.ZodNumber>;
|
|
@@ -604,6 +608,7 @@ export declare const recordingCapability: {
|
|
|
604
608
|
off: "off";
|
|
605
609
|
events: "events";
|
|
606
610
|
continuous: "continuous";
|
|
611
|
+
"on-device-decision": "on-device-decision";
|
|
607
612
|
}>>;
|
|
608
613
|
profiles: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
609
614
|
high: "high";
|
|
@@ -628,11 +633,11 @@ export declare const recordingCapability: {
|
|
|
628
633
|
animal: "animal";
|
|
629
634
|
}>>>;
|
|
630
635
|
sensorDeviceIds: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
631
|
-
deviceSignal: z.ZodOptional<z.ZodBoolean>;
|
|
632
636
|
}, z.core.$strip>>;
|
|
633
637
|
preBufferSec: z.ZodOptional<z.ZodNumber>;
|
|
634
638
|
postBufferSec: z.ZodOptional<z.ZodNumber>;
|
|
635
639
|
}, z.core.$strip>>>;
|
|
640
|
+
deviceDecision: z.ZodOptional<z.ZodBoolean>;
|
|
636
641
|
retention: z.ZodOptional<z.ZodObject<{
|
|
637
642
|
maxAgeDays: z.ZodOptional<z.ZodNumber>;
|
|
638
643
|
maxSizeGb: z.ZodOptional<z.ZodNumber>;
|
|
@@ -649,6 +654,7 @@ export declare const recordingCapability: {
|
|
|
649
654
|
off: "off";
|
|
650
655
|
events: "events";
|
|
651
656
|
continuous: "continuous";
|
|
657
|
+
"on-device-decision": "on-device-decision";
|
|
652
658
|
}>;
|
|
653
659
|
nodeId: z.ZodString;
|
|
654
660
|
storageBytes: z.ZodNumber;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* can answer "may a rule actuate this?" without importing the schema barrel
|
|
6
6
|
* (~144MB RSS per runner, D28).
|
|
7
7
|
*
|
|
8
|
-
* Coverage:
|
|
8
|
+
* Coverage: 83 device-scoped capabilities.
|
|
9
9
|
*/
|
|
10
10
|
export declare const DEVICE_SCOPED_CAPS: ReadonlySet<string>;
|
|
11
11
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_event_category = require("./event-category-b8kBSOTT.js");
|
|
3
|
-
const require_sleep = require("./sleep-
|
|
3
|
+
const require_sleep = require("./sleep-DDIFZGbc.js");
|
|
4
4
|
const require_canonical_hash = require("./canonical-hash-DNV8S5ET.js");
|
|
5
5
|
const require_enums = require("./enums.js");
|
|
6
6
|
const require_err_msg = require("./err-msg-COpsHMw2.js");
|
|
@@ -1228,21 +1228,21 @@ function schemaDeclaresAnyField(schema) {
|
|
|
1228
1228
|
for (const section of sectionsOf(schema)) if (fieldsOf(section).length > 0) return true;
|
|
1229
1229
|
return false;
|
|
1230
1230
|
}
|
|
1231
|
-
function isRecord$
|
|
1231
|
+
function isRecord$3(value) {
|
|
1232
1232
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1233
1233
|
}
|
|
1234
1234
|
function sectionsOf(schema) {
|
|
1235
|
-
if (!isRecord$
|
|
1235
|
+
if (!isRecord$3(schema)) return [];
|
|
1236
1236
|
const sections = schema["sections"];
|
|
1237
1237
|
return Array.isArray(sections) ? sections : [];
|
|
1238
1238
|
}
|
|
1239
1239
|
function fieldsOf(node) {
|
|
1240
|
-
if (!isRecord$
|
|
1240
|
+
if (!isRecord$3(node)) return [];
|
|
1241
1241
|
const fields = node["fields"];
|
|
1242
1242
|
return Array.isArray(fields) ? fields : [];
|
|
1243
1243
|
}
|
|
1244
1244
|
function walkField(field, out) {
|
|
1245
|
-
if (!isRecord$
|
|
1245
|
+
if (!isRecord$3(field)) return;
|
|
1246
1246
|
const type = field["type"];
|
|
1247
1247
|
const key = field["key"];
|
|
1248
1248
|
if ((type === "password" || field["secret"] === true) && typeof key === "string" && key.length > 0) out.add(key);
|
|
@@ -1327,12 +1327,12 @@ function toStreamSourceEntry(stream) {
|
|
|
1327
1327
|
function isString(v) {
|
|
1328
1328
|
return typeof v === "string";
|
|
1329
1329
|
}
|
|
1330
|
-
function isRecord$
|
|
1330
|
+
function isRecord$2(v) {
|
|
1331
1331
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
1332
1332
|
}
|
|
1333
1333
|
function parseStreamEntry(v) {
|
|
1334
1334
|
if (isString(v) && v.trim()) return { url: v };
|
|
1335
|
-
if (isRecord$
|
|
1335
|
+
if (isRecord$2(v) && isString(v["url"]) && v["url"].trim()) return {
|
|
1336
1336
|
url: v["url"],
|
|
1337
1337
|
label: isString(v["label"]) ? v["label"] : void 0
|
|
1338
1338
|
};
|
|
@@ -1972,17 +1972,29 @@ var HHMM = /^([01]\d|2[0-3]):[0-5]\d$/;
|
|
|
1972
1972
|
/**
|
|
1973
1973
|
* DERIVED per-camera storage summary — the single field cheap consumers read
|
|
1974
1974
|
* (the viewer's status dot, the camera list) instead of walking `bands`:
|
|
1975
|
-
* - `off`
|
|
1976
|
-
* - `events`
|
|
1977
|
-
* - `continuous`
|
|
1978
|
-
*
|
|
1979
|
-
*
|
|
1980
|
-
*
|
|
1975
|
+
* - `off` — no band covers the camera (or it is disabled).
|
|
1976
|
+
* - `events` — every band records around triggers only.
|
|
1977
|
+
* - `continuous` — at least one band records continuously.
|
|
1978
|
+
* - `on-device-decision`— the DEVICE decides: recording runs for as long as the
|
|
1979
|
+
* camera raises its own `recording-signal` level (a robot that cleans). There
|
|
1980
|
+
* is no schedule to author, because there is no hour to program — see
|
|
1981
|
+
* {@link RecordingConfigSchema}`.deviceDecision`.
|
|
1982
|
+
*
|
|
1983
|
+
* NEVER authored: the recorder stamps it from the authoritative intent
|
|
1984
|
+
* (`bands` + `deviceDecision`) on every save (`activeModeForConfig`). Writing it
|
|
1985
|
+
* has no effect.
|
|
1986
|
+
*
|
|
1987
|
+
* `on-device-decision` is named for WHO decides, not for how the recording is
|
|
1988
|
+
* requested. `on-demand` was rejected: in this repo's vocabulary a "demand" is
|
|
1989
|
+
* something the operator makes (the live gate is the recorder's own "demand
|
|
1990
|
+
* window"), and a knob whose name suggests the operator starts it while the
|
|
1991
|
+
* device actually does is the D62 shape — a control nobody can predict.
|
|
1981
1992
|
*/
|
|
1982
1993
|
var RecordingStorageModeSchema = zod.z.enum([
|
|
1983
1994
|
"off",
|
|
1984
1995
|
"events",
|
|
1985
|
-
"continuous"
|
|
1996
|
+
"continuous",
|
|
1997
|
+
"on-device-decision"
|
|
1986
1998
|
]);
|
|
1987
1999
|
/**
|
|
1988
2000
|
* Le macro classi che possono aprire una finestra di registrazione — le stesse
|
|
@@ -2041,22 +2053,7 @@ var RecordingTriggersSchema = zod.z.object({
|
|
|
2041
2053
|
* il livello: un contatto trovato già aperto al riavvio del runner non fa
|
|
2042
2054
|
* registrare.
|
|
2043
2055
|
*/
|
|
2044
|
-
sensorDeviceIds: zod.z.array(zod.z.number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
|
|
2045
|
-
/**
|
|
2046
|
-
* La camera registra per tutta la durata del SEGNALE che lei stessa
|
|
2047
|
-
* pubblica — la cap `recording-signal` (`active: true` mentre il device è in
|
|
2048
|
-
* funzione: un robot che pulisce). È un LIVELLO, non un fronte: la finestra
|
|
2049
|
-
* resta aperta finché il segnale è alto e si chiude `postBufferSec` dopo la
|
|
2050
|
-
* caduta, così una pulizia di quaranta minuti è UNA clip.
|
|
2051
|
-
*
|
|
2052
|
-
* Non nomina un device: il segnale è della camera stessa, tenuto fresco dal
|
|
2053
|
-
* suo provider (D224); il recorder lo ascolta su `DeviceStateChanged` e lo
|
|
2054
|
-
* riconcilia leggendo la slice via RPC, con un tetto oltre il quale un
|
|
2055
|
-
* segnale mai abbassato (un evento perso) non può tenere aperta una
|
|
2056
|
-
* registrazione (D11). Vedi `recorder/addon/band-decision.ts`
|
|
2057
|
-
* (`holdTrigger` / `releaseTrigger`).
|
|
2058
|
-
*/
|
|
2059
|
-
deviceSignal: zod.z.boolean().optional()
|
|
2056
|
+
sensorDeviceIds: zod.z.array(zod.z.number().int().positive()).min(1).max(16).refine(noDuplicates, { message: "sensorDeviceIds must not repeat a device" }).optional()
|
|
2060
2057
|
});
|
|
2061
2058
|
/**
|
|
2062
2059
|
* Mode of a single recording band — the recorder per-band vocabulary.
|
|
@@ -2086,6 +2083,24 @@ var RecordingBandSchema = zod.z.object({
|
|
|
2086
2083
|
end: zod.z.string().regex(HHMM),
|
|
2087
2084
|
mode: RecordingBandModeSchema,
|
|
2088
2085
|
triggers: RecordingBandTriggersSchema.optional(),
|
|
2086
|
+
/**
|
|
2087
|
+
* RETIRED (D381). A band no longer carries a pre-buffer of its own.
|
|
2088
|
+
*
|
|
2089
|
+
* It was the retroactive KEEP bound — which already-written segments survive
|
|
2090
|
+
* a trigger — and it had to be at least as wide as the widest pre-roll the
|
|
2091
|
+
* broker could serve, or the gate would delete the seconds the ring had just
|
|
2092
|
+
* handed the writer. That "at least as wide as" is the tell: it was a second
|
|
2093
|
+
* expression of the broker's retention, in different units, in a different
|
|
2094
|
+
* addon, with an invariant the operator had to maintain by hand. The keep
|
|
2095
|
+
* bound is now derived from the one prebuffer ceiling and there is nothing
|
|
2096
|
+
* left to configure here.
|
|
2097
|
+
*
|
|
2098
|
+
* The key survives in the SHAPE so a config written before that record still
|
|
2099
|
+
* parses and can be migrated deliberately — `RecordingBandSchema` is not
|
|
2100
|
+
* strict, so simply deleting it would strip an operator's value in silence on
|
|
2101
|
+
* the next save (the failure D380 came one commit from shipping). Nothing
|
|
2102
|
+
* reads it: {@link stripRetiredBandPreBufferSec} removes it on load.
|
|
2103
|
+
*/
|
|
2089
2104
|
preBufferSec: zod.z.number().min(0).optional(),
|
|
2090
2105
|
postBufferSec: zod.z.number().min(0).optional()
|
|
2091
2106
|
});
|
|
@@ -2103,29 +2118,56 @@ var RecordingBandSchema = zod.z.object({
|
|
|
2103
2118
|
* `postBufferSec` must therefore exceed one segment length plus the attach
|
|
2104
2119
|
* latency (ffmpeg spawn + RTSP dial), or the window closes before the first
|
|
2105
2120
|
* segment is ever finalized and the camera records nothing anyway. At the 10 s
|
|
2106
|
-
* default segment length, 30 s leaves room for two full segments.
|
|
2107
|
-
*
|
|
2108
|
-
*
|
|
2109
|
-
*
|
|
2110
|
-
*
|
|
2111
|
-
*
|
|
2112
|
-
*
|
|
2113
|
-
*
|
|
2114
|
-
*
|
|
2115
|
-
*
|
|
2116
|
-
*
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
* `
|
|
2121
|
-
*
|
|
2122
|
-
*
|
|
2123
|
-
*
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2121
|
+
* default segment length, 30 s leaves room for two full segments.
|
|
2122
|
+
*
|
|
2123
|
+
* ## There is no `preBufferSec` here any more (D381)
|
|
2124
|
+
*
|
|
2125
|
+
* There used to be, at 15 s, and its whole justification was that it had to
|
|
2126
|
+
* cover the widest pre-roll the broker could serve. A number whose only
|
|
2127
|
+
* correct value is another subsystem's ceiling is not a setting; it is that
|
|
2128
|
+
* ceiling, restated where it can drift. The keep bound is derived from the
|
|
2129
|
+
* prebuffer ceiling directly now, in `band-decision.ts`, so an operator
|
|
2130
|
+
* raising the prebuffer cannot walk past the gate at all rather than merely
|
|
2131
|
+
* being warned not to.
|
|
2132
|
+
*/
|
|
2133
|
+
var DEFAULT_EVENTS_BAND_BUFFER_SEC = { postBufferSec: 30 };
|
|
2134
|
+
/**
|
|
2135
|
+
* Drop the RETIRED band `preBufferSec` from a persisted recording config.
|
|
2136
|
+
*
|
|
2137
|
+
* Explicit, and it reports what it removed, because the alternative is a
|
|
2138
|
+
* silent strip: `RecordingBandSchema` is a plain `z.object`, so the key
|
|
2139
|
+
* survives a parse and disappears on the next save with no line anywhere. An
|
|
2140
|
+
* operator who had typed a number would find it gone and nothing would say
|
|
2141
|
+
* when or why.
|
|
2142
|
+
*
|
|
2143
|
+
* Nothing is carried forward: the value it held was always required to be at
|
|
2144
|
+
* least the broker's widest pre-roll, and the gate is now derived from exactly
|
|
2145
|
+
* that ceiling. Every configuration that was legal therefore keeps a keep-gate
|
|
2146
|
+
* at least as wide as the one it had — including an explicit `0`, which widens.
|
|
2147
|
+
* That is deliberate and it is the only behaviour change: a band that kept
|
|
2148
|
+
* nothing before its trigger now keeps up to the prebuffer ceiling of
|
|
2149
|
+
* already-written footage, which is media that exists either way.
|
|
2150
|
+
*/
|
|
2151
|
+
function stripRetiredBandPreBufferSec(config) {
|
|
2152
|
+
const strippedBands = [];
|
|
2153
|
+
const bands = config.bands.map((band, index) => {
|
|
2154
|
+
if (band.preBufferSec === void 0) return band;
|
|
2155
|
+
strippedBands.push(index);
|
|
2156
|
+
const { preBufferSec: _retired, ...rest } = band;
|
|
2157
|
+
return rest;
|
|
2158
|
+
});
|
|
2159
|
+
if (strippedBands.length === 0) return {
|
|
2160
|
+
config,
|
|
2161
|
+
strippedBands
|
|
2162
|
+
};
|
|
2163
|
+
return {
|
|
2164
|
+
config: {
|
|
2165
|
+
...config,
|
|
2166
|
+
bands
|
|
2167
|
+
},
|
|
2168
|
+
strippedBands
|
|
2169
|
+
};
|
|
2170
|
+
}
|
|
2129
2171
|
/**
|
|
2130
2172
|
* Adjacent recorded ranges closer than this belong to the SAME videoclip visit.
|
|
2131
2173
|
*
|
|
@@ -2187,8 +2229,29 @@ var RecordingConfigSchema = zod.z.object({
|
|
|
2187
2229
|
* "off" is the absence of a covering band, never a band value.
|
|
2188
2230
|
*/
|
|
2189
2231
|
bands: zod.z.array(RecordingBandSchema).default([]),
|
|
2232
|
+
/**
|
|
2233
|
+
* THE device-decided intent: record for as long as the camera itself raises
|
|
2234
|
+
* `recording-signal` (`active: true` while the device is in function — a
|
|
2235
|
+
* robot that cleans). AUTHORED, unlike `mode`, and the only authored
|
|
2236
|
+
* recording intent that is not a band.
|
|
2237
|
+
*
|
|
2238
|
+
* It carries NO schedule on purpose. A band is an HOUR, and this feature has
|
|
2239
|
+
* no hour to program: the device decides. What it costs the operator is one
|
|
2240
|
+
* flag — "this camera can record on its own" — and what it buys is the same
|
|
2241
|
+
* hold/release the recorder already implements (D371, `holdTrigger` /
|
|
2242
|
+
* `releaseTrigger`): the window opens on the rise, stays open for the whole
|
|
2243
|
+
* job however long it is, and closes one pad after the fall.
|
|
2244
|
+
*
|
|
2245
|
+
* EXCLUSIVE with `bands` (below): two authorities deciding when the same
|
|
2246
|
+
* camera records is the D62 failure. `off` remains `enabled: false`, so an
|
|
2247
|
+
* operator switching this camera off is REPORTED off, never as broken.
|
|
2248
|
+
*/
|
|
2249
|
+
deviceDecision: zod.z.boolean().optional(),
|
|
2190
2250
|
retention: RecordingRetentionSchema.optional()
|
|
2191
|
-
}).strict()
|
|
2251
|
+
}).strict().refine((config) => config.deviceDecision !== true || config.bands.length === 0, {
|
|
2252
|
+
message: "deviceDecision is a whole-config mode and carries no schedule: it cannot be combined with bands",
|
|
2253
|
+
path: ["bands"]
|
|
2254
|
+
});
|
|
2192
2255
|
/**
|
|
2193
2256
|
* Derive the {@link RecordingStorageModeSchema} summary from the authoritative
|
|
2194
2257
|
* bands: `continuous` when any band records continuously, `events` when a band
|
|
@@ -2201,7 +2264,9 @@ var RecordingConfigSchema = zod.z.object({
|
|
|
2201
2264
|
* bug this field was added to fix.
|
|
2202
2265
|
*/
|
|
2203
2266
|
function deriveRecordingMode(config) {
|
|
2204
|
-
if (!config.enabled
|
|
2267
|
+
if (!config.enabled) return "off";
|
|
2268
|
+
if (config.deviceDecision === true) return "on-device-decision";
|
|
2269
|
+
if (config.bands.length === 0) return "off";
|
|
2205
2270
|
if (config.bands.some((band) => band.mode === "continuous")) return "continuous";
|
|
2206
2271
|
return "events";
|
|
2207
2272
|
}
|
|
@@ -2229,6 +2294,85 @@ function resolveRecordingProfiles(assigned, override) {
|
|
|
2229
2294
|
const preferred = assigned.filter((profile) => DEFAULT_RECORDING_PROFILES.includes(profile));
|
|
2230
2295
|
return preferred.length > 0 ? preferred : [...assigned];
|
|
2231
2296
|
}
|
|
2297
|
+
/** Trigger keys that survive D380 — a band carrying one of these is a real band. */
|
|
2298
|
+
var SURVIVING_TRIGGER_KEYS = [
|
|
2299
|
+
"motion",
|
|
2300
|
+
"audioThresholdDbfs",
|
|
2301
|
+
"objectClasses",
|
|
2302
|
+
"sensorDeviceIds"
|
|
2303
|
+
];
|
|
2304
|
+
function isRecord$1(value) {
|
|
2305
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2306
|
+
}
|
|
2307
|
+
function listensToLegacySignal(band) {
|
|
2308
|
+
return isRecord$1(band) && isRecord$1(band.triggers) && band.triggers.deviceSignal === true;
|
|
2309
|
+
}
|
|
2310
|
+
function hasSurvivingTrigger(band) {
|
|
2311
|
+
const triggers = band.triggers;
|
|
2312
|
+
if (!isRecord$1(triggers)) return false;
|
|
2313
|
+
return SURVIVING_TRIGGER_KEYS.some((key) => triggers[key] !== void 0);
|
|
2314
|
+
}
|
|
2315
|
+
function withoutLegacySignal(band) {
|
|
2316
|
+
const triggers = band.triggers;
|
|
2317
|
+
if (!isRecord$1(triggers)) return band;
|
|
2318
|
+
const { deviceSignal: _retired, ...rest } = triggers;
|
|
2319
|
+
return {
|
|
2320
|
+
...band,
|
|
2321
|
+
triggers: rest
|
|
2322
|
+
};
|
|
2323
|
+
}
|
|
2324
|
+
/**
|
|
2325
|
+
* Turn a config stored under D371 (`bands[].triggers.deviceSignal: true`) into
|
|
2326
|
+
* a D380 one (`deviceDecision: true`, no bands). Pure, total and IDEMPOTENT —
|
|
2327
|
+
* a row with no legacy key comes back as the SAME reference, `migrated: false`.
|
|
2328
|
+
*
|
|
2329
|
+
* ## Why the schema cannot be left to do this
|
|
2330
|
+
*
|
|
2331
|
+
* `RecordingTriggersSchema` is a non-strict `z.object`, so the retired key is
|
|
2332
|
+
* SILENTLY STRIPPED on read. The camera whose only trigger it was would parse
|
|
2333
|
+
* cleanly into an `events` band that lists nothing — "enabled, and records
|
|
2334
|
+
* nothing, forever", the exact shape `eventsBandCanEverDemand` exists to shout
|
|
2335
|
+
* about, reached without a single line in the log. On the reference hub that is
|
|
2336
|
+
* camera 4374, the one camera an operator had configured by hand.
|
|
2337
|
+
*
|
|
2338
|
+
* `enabled` is carried through untouched: a camera the operator had switched
|
|
2339
|
+
* OFF comes out of a migration still off (D62).
|
|
2340
|
+
*/
|
|
2341
|
+
function migrateLegacyDeviceSignalConfig(raw) {
|
|
2342
|
+
const unchanged = {
|
|
2343
|
+
value: raw,
|
|
2344
|
+
migrated: false,
|
|
2345
|
+
strippedOnly: false
|
|
2346
|
+
};
|
|
2347
|
+
if (!isRecord$1(raw) || !Array.isArray(raw.bands)) return unchanged;
|
|
2348
|
+
if (!raw.bands.some(listensToLegacySignal)) return unchanged;
|
|
2349
|
+
const kept = [];
|
|
2350
|
+
for (const band of raw.bands) {
|
|
2351
|
+
if (!listensToLegacySignal(band) || !isRecord$1(band)) {
|
|
2352
|
+
kept.push(band);
|
|
2353
|
+
continue;
|
|
2354
|
+
}
|
|
2355
|
+
if (hasSurvivingTrigger(band)) kept.push(withoutLegacySignal(band));
|
|
2356
|
+
}
|
|
2357
|
+
if (kept.length > 0) return {
|
|
2358
|
+
value: {
|
|
2359
|
+
...raw,
|
|
2360
|
+
bands: kept
|
|
2361
|
+
},
|
|
2362
|
+
migrated: false,
|
|
2363
|
+
strippedOnly: true
|
|
2364
|
+
};
|
|
2365
|
+
const { mode: _derived, ...rest } = raw;
|
|
2366
|
+
return {
|
|
2367
|
+
value: {
|
|
2368
|
+
...rest,
|
|
2369
|
+
bands: [],
|
|
2370
|
+
deviceDecision: true
|
|
2371
|
+
},
|
|
2372
|
+
migrated: true,
|
|
2373
|
+
strippedOnly: false
|
|
2374
|
+
};
|
|
2375
|
+
}
|
|
2232
2376
|
//#endregion
|
|
2233
2377
|
//#region src/interfaces/relocate.ts
|
|
2234
2378
|
/**
|
|
@@ -21503,12 +21647,10 @@ var CameraAudioStatusSchema = zod.z.object({
|
|
|
21503
21647
|
nodeId: zod.z.string(),
|
|
21504
21648
|
enabled: zod.z.boolean()
|
|
21505
21649
|
});
|
|
21506
|
-
/** Recording mode
|
|
21507
|
-
|
|
21508
|
-
|
|
21509
|
-
|
|
21510
|
-
"events"
|
|
21511
|
-
]);
|
|
21650
|
+
/** Recording mode — THE one definition, shared with the `recording` cap. A
|
|
21651
|
+
* copy of the list is how `on-device-decision` could have reached the recorder
|
|
21652
|
+
* and not this status block. */
|
|
21653
|
+
var CameraRecordingModeSchema = RecordingStorageModeSchema;
|
|
21512
21654
|
/** Recording block — null when no recording cap is active for this device. */
|
|
21513
21655
|
var CameraRecordingStatusSchema = zod.z.object({
|
|
21514
21656
|
mode: CameraRecordingModeSchema,
|
|
@@ -32115,11 +32257,10 @@ var rebootCapability = {
|
|
|
32115
32257
|
var RecordingStatusSchema = zod.z.object({
|
|
32116
32258
|
deviceId: zod.z.number(),
|
|
32117
32259
|
enabled: zod.z.boolean(),
|
|
32118
|
-
|
|
32119
|
-
|
|
32120
|
-
|
|
32121
|
-
|
|
32122
|
-
]),
|
|
32260
|
+
/** THE derived storage mode, from the one definition
|
|
32261
|
+
* (`deriveRecordingMode`) — never a second enum. A duplicated list is how
|
|
32262
|
+
* `on-device-decision` could have reached the recorder and not the status. */
|
|
32263
|
+
activeMode: RecordingStorageModeSchema,
|
|
32123
32264
|
nodeId: zod.z.string(),
|
|
32124
32265
|
storageBytes: zod.z.number()
|
|
32125
32266
|
});
|
|
@@ -55284,6 +55425,7 @@ exports.meshNetworkCapability = meshNetworkCapability;
|
|
|
55284
55425
|
exports.method = require_sleep.method;
|
|
55285
55426
|
exports.methodAccessForHttpMethod = methodAccessForHttpMethod;
|
|
55286
55427
|
exports.metricsProviderCapability = metricsProviderCapability;
|
|
55428
|
+
exports.migrateLegacyDeviceSignalConfig = migrateLegacyDeviceSignalConfig;
|
|
55287
55429
|
exports.modelConvertCapability = modelConvertCapability;
|
|
55288
55430
|
exports.modelDistributorCapability = modelDistributorCapability;
|
|
55289
55431
|
exports.modelFormatForRuntime = modelFormatForRuntime;
|
|
@@ -55431,6 +55573,7 @@ exports.streamCatalogCapability = streamCatalogCapability;
|
|
|
55431
55573
|
exports.streamParamsCapability = streamParamsCapability;
|
|
55432
55574
|
exports.streamPixels = streamPixels;
|
|
55433
55575
|
exports.streamQualityLabel = streamQualityLabel;
|
|
55576
|
+
exports.stripRetiredBandPreBufferSec = stripRetiredBandPreBufferSec;
|
|
55434
55577
|
exports.subKindsOf = subKindsOf;
|
|
55435
55578
|
exports.summarisePrivacyAudio = summarisePrivacyAudio;
|
|
55436
55579
|
exports.summarizeEffectiveScope = summarizeEffectiveScope;
|