@camstack/addon-pipeline 1.2.315 → 1.2.316
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/audio-analyzer/index.js +2 -2
- package/dist/audio-analyzer/index.mjs +2 -2
- package/dist/{default-detection-model-BTlf5MpT.mjs → default-detection-model-Ct7dlbBe.mjs} +1 -1
- package/dist/{default-detection-model-CteW4o8U.js → default-detection-model-DD9hOZ4u.js} +1 -1
- package/dist/detection-pipeline/index.js +4 -4
- package/dist/detection-pipeline/index.mjs +4 -4
- package/dist/{dist-sCjZdzKn.js → dist-BB9ZzZuv.js} +168 -89
- package/dist/{dist-C8W_MWSz.mjs → dist-D1CYfnNk.mjs} +168 -89
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-CnLKPz1A.mjs → node-CQWOX--t.mjs} +1 -1
- package/dist/{node-D4xdwpPU.js → node-bfUE4LH0.js} +1 -1
- package/dist/pipeline-runner/index.js +3 -3
- package/dist/pipeline-runner/index.mjs +3 -3
- package/dist/{process-memory-DqTBUteS.mjs → process-memory-Dh7ICwL3.mjs} +1 -1
- package/dist/{process-memory-CMnhjGyE.js → process-memory-MNz63KR5.js} +1 -1
- package/dist/recorder/index.js +108 -108
- package/dist/recorder/index.mjs +108 -108
- package/dist/{segment-demux-js-CCSsDyMw.mjs → segment-demux-js-Be5IUrly.mjs} +1 -1
- package/dist/{segment-demux-js-DGpdNqsG.js → segment-demux-js-CFIkvV42.js} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BOKNSh-e.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Cjam0v1J.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D6PDbSB9.mjs +26 -0
- package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DddXyc17.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DHNf76xj.mjs} +1 -1
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-BkvtmJ2D.mjs → hostInit-CEJvMnrH.mjs} +2 -2
- package/dist/stream-broker/index.js +6 -6
- package/dist/stream-broker/index.mjs +6 -6
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BTvQXobK.mjs +0 -26
package/dist/recorder/index.js
CHANGED
|
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
7
|
-
const require_node = require("../node-
|
|
6
|
+
const require_dist = require("../dist-BB9ZzZuv.js");
|
|
7
|
+
const require_node = require("../node-bfUE4LH0.js");
|
|
8
8
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
9
9
|
const require_restream_intent = require("../restream-intent-7uDNqMKs.js");
|
|
10
10
|
const require_retire_root_keys = require("../retire-root-keys-Csb8z2f3.js");
|
|
@@ -19,32 +19,32 @@ let node_v8 = require("node:v8");
|
|
|
19
19
|
node_v8 = require_chunk.__toESM(node_v8);
|
|
20
20
|
//#region src/recorder/event-capture.ts
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* The recorder's motion subscription: bus → `onTrigger(deviceId, atMs)`.
|
|
23
23
|
*
|
|
24
|
-
* ##
|
|
24
|
+
* ## What is NOT here any more (2026-08-29)
|
|
25
25
|
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* `EventMap.prune()`
|
|
30
|
-
*
|
|
26
|
+
* Until 2026-08-29 this file also built an `EventMarker` per event and
|
|
27
|
+
* pushed it into a per-device `EventMap` — playback annotations in RAM, with
|
|
28
|
+
* the provider's raw `regions` payload inside. `EventMap.events()` and
|
|
29
|
+
* `EventMap.prune()` had **no caller in the whole repo**: the
|
|
30
|
+
* map was only written, and grew with the runner's uptime.
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
* timeline
|
|
34
|
-
* `pipelineAnalytics` (`getMotionEvents`/`getObjectEvents`/`getAudioEvents`),
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* runner.
|
|
40
|
-
*
|
|
41
|
-
*
|
|
32
|
+
* It was deleted, not wired, and the reason is in its own header: the
|
|
33
|
+
* timeline the operator sees comes from the durable rows of
|
|
34
|
+
* `pipelineAnalytics` (`getMotionEvents`/`getObjectEvents`/`getAudioEvents`), the
|
|
35
|
+
* markers were not exposed on any cap (`recording.getPlaybackManifest`
|
|
36
|
+
* returns only playlist URLs) and ADR-0194 had already explicitly refused
|
|
37
|
+
* to build the trigger reconcile on top of it, because an
|
|
38
|
+
* in-RAM structure survives neither the loss of the event nor the respawn of the
|
|
39
|
+
* runner. A reader never existed and none was planned: keeping it
|
|
40
|
+
* would have been "a leftover that describes the right design", i.e. a check
|
|
41
|
+
* that checks nothing.
|
|
42
42
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
43
|
+
* What remains is the only thing anyone really read: the rising edge of
|
|
44
|
+
* the motion that opens a window of the `events` band (B3).
|
|
45
45
|
*/
|
|
46
|
-
/**
|
|
47
|
-
*
|
|
46
|
+
/** Only the `detected: true` edge is a trigger. The falling edge opens
|
|
47
|
+
* nothing — the window is closed by the post-buffer, not by the event. */
|
|
48
48
|
function isMotionTrigger(data) {
|
|
49
49
|
return data.detected;
|
|
50
50
|
}
|
|
@@ -542,40 +542,40 @@ var MfraTableStore = class {
|
|
|
542
542
|
//#endregion
|
|
543
543
|
//#region src/recorder/object-trigger.ts
|
|
544
544
|
/**
|
|
545
|
-
*
|
|
546
|
-
*
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
* ##
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
* `EventCategory.PipelineAnalyticsDetectionEvent`
|
|
562
|
-
*
|
|
563
|
-
* (`className`, `source`, `confidence`, `zones`), motion
|
|
564
|
-
* audio
|
|
565
|
-
* `malformed`
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
* (`malformed-object`),
|
|
575
|
-
*/
|
|
576
|
-
/**
|
|
545
|
+
* The gate between `pipeline-analytics.detection-event` and "open a
|
|
546
|
+
* recording window".
|
|
547
|
+
*
|
|
548
|
+
* Sibling of `recorder/event-capture.ts` and for the same reason: the qualification
|
|
549
|
+
* has branches, and a branch that discards work without saying so is indistinguishable from a
|
|
550
|
+
* function that was never wired. Every negative verdict NAMES the reason, and the caller
|
|
551
|
+
* logs it.
|
|
552
|
+
*
|
|
553
|
+
* Pure: no bus, no clock, no config. The choice of WHICH classes to
|
|
554
|
+
* listen to belongs to the band (`bandTriggerSources`); here we only decide whether
|
|
555
|
+
* the event is a usable detection and which macro class it is.
|
|
556
|
+
*
|
|
557
|
+
* ## Why the shape is DISCRIMINATED on `kind` (2026-08-29)
|
|
558
|
+
*
|
|
559
|
+
* Until 2026-08-29 this file declared ONE flat shape — that
|
|
560
|
+
* of the `object` event — and demanded it from EVERY payload of the topic. But
|
|
561
|
+
* `EventCategory.PipelineAnalyticsDetectionEvent` is a topic shared by three
|
|
562
|
+
* emitters in `addon-post-analysis/src/pipeline-analytics/index.ts`: object
|
|
563
|
+
* (`className`, `source`, `confidence`, `zones`), motion and audio — and motion and
|
|
564
|
+
* audio do not carry `className`, because they have none. The measured result:
|
|
565
|
+
* `malformed` on **394 sampled rows out of 394**, at 3.3–3.9 events/s, for
|
|
566
|
+
* weeks. `malformed` means "the emitter has drifted" and was
|
|
567
|
+
* instead the normal traffic of the topic; the only bucket that could signal
|
|
568
|
+
* a real protocol break was saturated at 100% with healthy events, hence
|
|
569
|
+
* useless — and it was read as "the object trigger never worked".
|
|
570
|
+
*
|
|
571
|
+
* So: first the common ENVELOPE is validated (`deviceId`, `kind`, `timestamp`),
|
|
572
|
+
* then we discriminate on `kind`, and only the `object` branch demands the fields
|
|
573
|
+
* of the object. An `object` without `className` remains a defect and has its own name
|
|
574
|
+
* (`malformed-object`), distinct from an unreadable envelope.
|
|
575
|
+
*/
|
|
576
|
+
/** The `kind` of the only branch of the topic that can open a window. */
|
|
577
577
|
var OBJECT_EVENT_KIND = "object";
|
|
578
|
-
/** Type guard,
|
|
578
|
+
/** Type guard, not cast: `event.data` is `unknown` until it passes through here. */
|
|
579
579
|
function isDetectionEventEnvelope(value) {
|
|
580
580
|
if (typeof value !== "object" || value === null) return false;
|
|
581
581
|
if (!("deviceId" in value) || typeof value.deviceId !== "number") return false;
|
|
@@ -585,7 +585,7 @@ function isDetectionEventEnvelope(value) {
|
|
|
585
585
|
if (!Number.isFinite(value.timestamp) || value.timestamp <= 0) return false;
|
|
586
586
|
return true;
|
|
587
587
|
}
|
|
588
|
-
/**
|
|
588
|
+
/** The fields that ONLY the object branch carries. Called after the envelope. */
|
|
589
589
|
function isObjectDetectionEventData(value) {
|
|
590
590
|
if (!("className" in value) || typeof value.className !== "string") return false;
|
|
591
591
|
if ("source" in value && value.source !== void 0 && typeof value.source !== "string") return false;
|
|
@@ -622,9 +622,9 @@ function qualifyObjectTrigger(data) {
|
|
|
622
622
|
}
|
|
623
623
|
//#endregion
|
|
624
624
|
//#region src/recorder/object-trigger-health.ts
|
|
625
|
-
/**
|
|
626
|
-
*
|
|
627
|
-
*
|
|
625
|
+
/** Width of the aggregation window. One minute: short enough for
|
|
626
|
+
* the line to arrive within the first minute of a broken deploy, long enough
|
|
627
|
+
* for the sample to be significant at 4 events/s. */
|
|
628
628
|
var OBJECT_TRIGGER_HEALTH_WINDOW_MS = 6e4;
|
|
629
629
|
function emptyTally$2() {
|
|
630
630
|
return {
|
|
@@ -660,10 +660,10 @@ var ObjectTriggerHealth = class {
|
|
|
660
660
|
this.minSample = minSample;
|
|
661
661
|
}
|
|
662
662
|
/**
|
|
663
|
-
*
|
|
664
|
-
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
663
|
+
* Records a verdict and, if the window closed with this event,
|
|
664
|
+
* returns the reports to print (and reopens the window). No timer:
|
|
665
|
+
* the feed runs at ~4/s, so the close always arrives in time, and a
|
|
666
|
+
* window that does not close is a window in which nothing happened.
|
|
667
667
|
*/
|
|
668
668
|
record(verdict, nowMs) {
|
|
669
669
|
const reports = this.windowStartMs !== null && nowMs - this.windowStartMs >= this.windowMs ? this.drain(nowMs) : [];
|
|
@@ -694,7 +694,7 @@ var ObjectTriggerHealth = class {
|
|
|
694
694
|
this.buckets.set(key, fresh);
|
|
695
695
|
return fresh;
|
|
696
696
|
}
|
|
697
|
-
/**
|
|
697
|
+
/** Closes the window and returns one report per non-empty bucket. */
|
|
698
698
|
drain(nowMs) {
|
|
699
699
|
const windowMs = this.windowStartMs === null ? 0 : nowMs - this.windowStartMs;
|
|
700
700
|
const out = [];
|
|
@@ -3227,29 +3227,29 @@ var macrotask$2 = () => new Promise((resolve) => {
|
|
|
3227
3227
|
//#endregion
|
|
3228
3228
|
//#region src/recorder/sensor-trigger.ts
|
|
3229
3229
|
/**
|
|
3230
|
-
*
|
|
3231
|
-
*
|
|
3232
|
-
*
|
|
3233
|
-
* -
|
|
3234
|
-
*
|
|
3235
|
-
* (`@camstack/types`) —
|
|
3236
|
-
*
|
|
3237
|
-
* -
|
|
3238
|
-
*
|
|
3239
|
-
*
|
|
3240
|
-
*
|
|
3241
|
-
*
|
|
3242
|
-
*
|
|
3243
|
-
*
|
|
3244
|
-
*
|
|
3245
|
-
*
|
|
3246
|
-
*
|
|
3247
|
-
*
|
|
3230
|
+
* From `DeviceStateChanged` to "which cameras must record".
|
|
3231
|
+
*
|
|
3232
|
+
* Two responsibilities, both in RAM and neither durable:
|
|
3233
|
+
* - the edge MEMORY, per `(deviceId, capName)`, which makes `false→true`
|
|
3234
|
+
* distinguishable from a re-emission. The predicate is `evaluateSensorEdge`
|
|
3235
|
+
* (`@camstack/types`) — the same `SOURCE_CAP_ACTIVE_FIELD` table as the
|
|
3236
|
+
* composite doorbell and the camera-sensors bridge, not a copy;
|
|
3237
|
+
* - the INVERSE INDEX source→cameras, a mirrored state refreshed OFF
|
|
3238
|
+
* the event path (D49): `setBindings` is called at boot from the
|
|
3239
|
+
* already-read configs and on every `onConfigChanged`, which is an RPC. A
|
|
3240
|
+
* fallible read on the trigger path could answer "nobody listens"
|
|
3241
|
+
* and lose the episode, which is the failure D49 is written against.
|
|
3242
|
+
*
|
|
3243
|
+
* The order of the checks is deliberate: `DeviceStateChanged` travels at bus
|
|
3244
|
+
* rate across the whole fleet (battery, every camera's native `motion`,
|
|
3245
|
+
* connectivity). The inverse index is an allocation-free `Map.get` and goes
|
|
3246
|
+
* first; the edge — which reads two tables and the slice — comes after. It is the same
|
|
3247
|
+
* choice post-analysis makes for its subscription: *"the
|
|
3248
3248
|
* EVENT_KIND_BY_CAP gate runs FIRST so non-sensor cap churn exits before any
|
|
3249
3249
|
* async work"*.
|
|
3250
3250
|
*
|
|
3251
|
-
*
|
|
3252
|
-
*
|
|
3251
|
+
* Pure with respect to the world: no bus, no logger, no clock of its own.
|
|
3252
|
+
* The caller logs the verdict — a branch that lights nothing SAYS so.
|
|
3253
3253
|
*/
|
|
3254
3254
|
/**
|
|
3255
3255
|
* Type GUARD, not a cast: `event.data` is `unknown`, and a version-skewed
|
|
@@ -3298,7 +3298,7 @@ function buildSensorTriggerBindings(configs) {
|
|
|
3298
3298
|
return index;
|
|
3299
3299
|
}
|
|
3300
3300
|
var SensorTriggerRouter = class {
|
|
3301
|
-
/** sourceDeviceId →
|
|
3301
|
+
/** sourceDeviceId → cameras whose config names it. */
|
|
3302
3302
|
bindings = /* @__PURE__ */ new Map();
|
|
3303
3303
|
/** Ultimo booleano osservato, per `${deviceId}:${capName}`. */
|
|
3304
3304
|
lastValues = /* @__PURE__ */ new Map();
|
|
@@ -3311,15 +3311,15 @@ var SensorTriggerRouter = class {
|
|
|
3311
3311
|
this.freshnessMs = options.firstSightingFreshnessMs ?? 3e4;
|
|
3312
3312
|
}
|
|
3313
3313
|
/**
|
|
3314
|
-
*
|
|
3315
|
-
*
|
|
3316
|
-
*
|
|
3317
|
-
*
|
|
3314
|
+
* Replaces the inverse index. Does NOT touch `lastValues`: a sensor removed and
|
|
3315
|
+
* put back into a band must find its previous level again, otherwise
|
|
3316
|
+
* the first slice after the return would be a "first observation" and a
|
|
3317
|
+
* contact left open the whole time would become a rising edge.
|
|
3318
3318
|
*/
|
|
3319
3319
|
setBindings(bindings) {
|
|
3320
3320
|
this.bindings = bindings;
|
|
3321
3321
|
}
|
|
3322
|
-
/**
|
|
3322
|
+
/** Which sources the index holds now — for the log line at boot. */
|
|
3323
3323
|
listenedSourceIds() {
|
|
3324
3324
|
return [...this.bindings.keys()];
|
|
3325
3325
|
}
|
|
@@ -14538,10 +14538,10 @@ function eventsBandCanEverDemand(band) {
|
|
|
14538
14538
|
return bandTriggerSources(band).length > 0 && resolveBandBufferMs(band).postMs > 0;
|
|
14539
14539
|
}
|
|
14540
14540
|
/**
|
|
14541
|
-
*
|
|
14542
|
-
*
|
|
14543
|
-
*
|
|
14544
|
-
*
|
|
14541
|
+
* The key under which a source keeps its windows. It is also the string
|
|
14542
|
+
* that appears in the logs — four sources opening the same window without
|
|
14543
|
+
* saying who did it make it impossible to answer "why does this camera
|
|
14544
|
+
* record so much" — so it is readable by design.
|
|
14545
14545
|
*/
|
|
14546
14546
|
function triggerKey(source) {
|
|
14547
14547
|
switch (source.kind) {
|
|
@@ -14556,18 +14556,18 @@ function triggerKey(source) {
|
|
|
14556
14556
|
* band never allocates a new one per call. */
|
|
14557
14557
|
var SIGNAL_SOURCES = Object.freeze([{ kind: "signal" }]);
|
|
14558
14558
|
/**
|
|
14559
|
-
*
|
|
14560
|
-
*
|
|
14559
|
+
* THE sources this band listens to — the only place where a band's `triggers`
|
|
14560
|
+
* become `TriggerSource[]`.
|
|
14561
14561
|
*
|
|
14562
|
-
*
|
|
14562
|
+
* Before there were FIVE copies of the same motion/audio if-ladder
|
|
14563
14563
|
* (`eventsBandCanEverDemand`, `eventsBandDemanded`, `segmentRetainedForEvents`,
|
|
14564
|
-
* `segmentMissedByMs`, `eventsWindowCloseMs`),
|
|
14565
|
-
*
|
|
14566
|
-
* (`reportUnrecordable`,
|
|
14564
|
+
* `segmentMissedByMs`, `eventsWindowCloseMs`), which with four sources
|
|
14565
|
+
* would have become five four-branch ladders. `RecordingController`
|
|
14566
|
+
* (`reportUnrecordable`, the durable reconciliation) reads the same list.
|
|
14567
14567
|
*
|
|
14568
|
-
*
|
|
14569
|
-
*
|
|
14570
|
-
*
|
|
14568
|
+
* A key in {@link UNFED_TRIGGER_KEYS} produces no sources: the band that
|
|
14569
|
+
* listens only to it "can never demand", and that is how the recorder
|
|
14570
|
+
* reports it instead of staying silent.
|
|
14571
14571
|
*/
|
|
14572
14572
|
function bandTriggerSources(band) {
|
|
14573
14573
|
if (band.deviceSignal === true) return SIGNAL_SOURCES;
|
|
@@ -21145,15 +21145,15 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
21145
21145
|
eventUnsub = null;
|
|
21146
21146
|
/**
|
|
21147
21147
|
* Unsubscribe handle for the `PipelineAudioInferenceResult` audio-level
|
|
21148
|
-
* subscription — the feed `audioThresholdDbfs` was missing (D62,
|
|
21149
|
-
* of `docs/design/plans/2026-08-26-
|
|
21148
|
+
* subscription — the feed `audioThresholdDbfs` was missing (D62, Track 0
|
|
21149
|
+
* of `docs/design/plans/2026-08-26-detection-triggers-and-sensors.md`). Kept
|
|
21150
21150
|
* separate from `eventUnsub` (a distinct bus category) but guarded and torn
|
|
21151
21151
|
* down the same way, idempotent re-entry included.
|
|
21152
21152
|
*/
|
|
21153
21153
|
audioTriggerUnsub = null;
|
|
21154
21154
|
/**
|
|
21155
21155
|
* Unsubscribe handle for the `PipelineAnalyticsDetectionEvent` subscription —
|
|
21156
|
-
* the feed behind `RecordingTriggers.objectClasses` (
|
|
21156
|
+
* the feed behind `RecordingTriggers.objectClasses` (Track A of the same
|
|
21157
21157
|
* plan). Same guard/teardown discipline as the two above.
|
|
21158
21158
|
*/
|
|
21159
21159
|
detectionTriggerUnsub = null;
|
|
@@ -21167,7 +21167,7 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
21167
21167
|
detectionTriggerHealth = new ObjectTriggerHealth();
|
|
21168
21168
|
/**
|
|
21169
21169
|
* Unsubscribe handle for the `DeviceStateChanged` subscription — the feed
|
|
21170
|
-
* behind `RecordingTriggers.sensorDeviceIds` (
|
|
21170
|
+
* behind `RecordingTriggers.sensorDeviceIds` (Track B).
|
|
21171
21171
|
*/
|
|
21172
21172
|
sensorTriggerUnsub = null;
|
|
21173
21173
|
/**
|