@camstack/addon-post-analysis 1.2.176 → 1.2.178
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/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-CKnFcMxC.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-MvTzBID6.mjs} +3 -3
- package/dist/pipeline-analytics/{hostInit-BwoPUMSb.mjs → hostInit-DhLjhqAY.mjs} +3 -3
- package/dist/pipeline-analytics/index.js +80 -14
- package/dist/pipeline-analytics/index.mjs +80 -14
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import "./dist-CYZr2fwk.mjs";
|
|
|
3
3
|
var e = {
|
|
4
4
|
"@camstack/sdk": {
|
|
5
5
|
name: "@camstack/sdk",
|
|
6
|
-
version: "1.2.
|
|
6
|
+
version: "1.2.66",
|
|
7
7
|
scope: ["default"],
|
|
8
8
|
loaded: !1,
|
|
9
9
|
from: "addon_pipeline_analytics_widgets",
|
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.2.
|
|
21
|
+
version: "1.2.146",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_pipeline_analytics_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.2.
|
|
36
|
+
version: "1.2.112",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_pipeline_analytics_widgets",
|
|
@@ -36,7 +36,7 @@ async function r() {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"@camstack/types": {
|
|
39
|
-
version: "1.2.
|
|
39
|
+
version: "1.2.146",
|
|
40
40
|
scope: "default",
|
|
41
41
|
shareConfig: {
|
|
42
42
|
singleton: !0,
|
|
@@ -45,7 +45,7 @@ async function r() {
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"@camstack/sdk": {
|
|
48
|
-
version: "1.2.
|
|
48
|
+
version: "1.2.66",
|
|
49
49
|
scope: "default",
|
|
50
50
|
shareConfig: {
|
|
51
51
|
singleton: !0,
|
|
@@ -81,7 +81,7 @@ async function r() {
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"@camstack/ui-library": {
|
|
84
|
-
version: "1.2.
|
|
84
|
+
version: "1.2.112",
|
|
85
85
|
scope: "default",
|
|
86
86
|
shareConfig: {
|
|
87
87
|
singleton: !0,
|
|
@@ -35839,16 +35839,43 @@ function positionsIntersectZone(positions, frameWidth, frameHeight, zone) {
|
|
|
35839
35839
|
}, zone.points)) return true;
|
|
35840
35840
|
return false;
|
|
35841
35841
|
}
|
|
35842
|
+
//#endregion
|
|
35843
|
+
//#region src/pipeline-analytics/track-lifecycle.ts
|
|
35844
|
+
/** Minimum confidence increase (vs last emit) that counts as a material
|
|
35845
|
+
* improvement. */
|
|
35846
|
+
var UPDATE_MIN_CONF_DELTA = .1;
|
|
35847
|
+
/** Debounce floor between two `update` emits for the same track (ms). */
|
|
35848
|
+
var UPDATE_MIN_INTERVAL_MS = 4e3;
|
|
35849
|
+
/** Minimum fractional bbox-area growth (vs last emit) counted as a
|
|
35850
|
+
* materially larger representative crop (e.g. 0.15 = 15% bigger). */
|
|
35851
|
+
var UPDATE_MIN_CROP_AREA_GROWTH = .15;
|
|
35852
|
+
/**
|
|
35853
|
+
* The label a `phase:'update'` SIGNAL and PAYLOAD carry, resolved from its
|
|
35854
|
+
* two possible sources in order: this frame's tiered patch (the frame path
|
|
35855
|
+
* wrote a label this very frame), then the track ROW's stored display label
|
|
35856
|
+
* (`subLabel ?? label`, as `trackStore.peekActive` exposes it).
|
|
35857
|
+
*
|
|
35858
|
+
* The fallback is not a nicety. The face recognizer assigns an identity over
|
|
35859
|
+
* the async detail plane and writes it to the row (`applyLabelCandidate`) —
|
|
35860
|
+
* never into a frame patch — so a signal reading only the patch can never
|
|
35861
|
+
* fire the identity trigger for a recognised face. Measured on the live hub
|
|
35862
|
+
* (2026-09-05, device 590): six of six face identities reached Home
|
|
35863
|
+
* Assistant only on the `end` event at track close + sweep (~lastSeen+33 s),
|
|
35864
|
+
* zero during the track's life, while the subject was still on camera.
|
|
35865
|
+
*/
|
|
35866
|
+
function resolveLifecycleUpdateLabel(labelPatch, storedDisplayLabel) {
|
|
35867
|
+
return patchDisplayLabel(labelPatch) ?? storedDisplayLabel;
|
|
35868
|
+
}
|
|
35842
35869
|
var DEFAULT_UPDATE_GATE_CONFIG = {
|
|
35843
|
-
minConfDelta:
|
|
35844
|
-
minIntervalMs:
|
|
35845
|
-
minCropAreaGrowth:
|
|
35870
|
+
minConfDelta: UPDATE_MIN_CONF_DELTA,
|
|
35871
|
+
minIntervalMs: UPDATE_MIN_INTERVAL_MS,
|
|
35872
|
+
minCropAreaGrowth: UPDATE_MIN_CROP_AREA_GROWTH
|
|
35846
35873
|
};
|
|
35847
35874
|
/**
|
|
35848
35875
|
* Decide whether a `phase:'update'` event should fire this frame.
|
|
35849
35876
|
*
|
|
35850
35877
|
* Priority of triggers: newly-resolved identity/plate > confidence
|
|
35851
|
-
* improvement > materially larger crop. All triggers are debounced by
|
|
35878
|
+
* improvement > newly-entered zone > materially larger crop. All triggers are debounced by
|
|
35852
35879
|
* `minIntervalMs` relative to the last emit. Deltas are measured against
|
|
35853
35880
|
* the LAST-EMITTED memory, so a run of sub-threshold new-bests accumulates
|
|
35854
35881
|
* and fires once it crosses `minConfDelta`.
|
|
@@ -35856,22 +35883,32 @@ var DEFAULT_UPDATE_GATE_CONFIG = {
|
|
|
35856
35883
|
function evaluateTrackLifecycleUpdate(signal, memory, config) {
|
|
35857
35884
|
const identityTrigger = signal.label !== void 0 && signal.label !== "" && (memory === void 0 || memory.lastLabel !== signal.label);
|
|
35858
35885
|
const confidenceTrigger = signal.isNewBest && (memory === void 0 || signal.confidence - memory.lastConfidence >= config.minConfDelta);
|
|
35886
|
+
const zoneTrigger = signal.zonesVisitedCount !== void 0 && memory?.lastZonesVisitedCount !== void 0 && signal.zonesVisitedCount > memory.lastZonesVisitedCount;
|
|
35859
35887
|
const cropTrigger = signal.bboxArea !== void 0 && memory?.lastBboxArea !== void 0 && memory.lastBboxArea > 0 && signal.bboxArea >= memory.lastBboxArea * (1 + config.minCropAreaGrowth);
|
|
35860
|
-
const reason = identityTrigger ? "identity" : confidenceTrigger ? "confidence" : cropTrigger ? "crop" : void 0;
|
|
35861
|
-
const keptMemory = memory
|
|
35888
|
+
const reason = identityTrigger ? "identity" : confidenceTrigger ? "confidence" : zoneTrigger ? "zone" : cropTrigger ? "crop" : void 0;
|
|
35889
|
+
const keptMemory = memory === void 0 ? {
|
|
35862
35890
|
lastConfidence: signal.confidence,
|
|
35863
|
-
lastEmitAt: signal.now
|
|
35864
|
-
|
|
35891
|
+
lastEmitAt: signal.now,
|
|
35892
|
+
...signal.zonesVisitedCount !== void 0 ? { lastZonesVisitedCount: signal.zonesVisitedCount } : {}
|
|
35893
|
+
} : memory.lastZonesVisitedCount === void 0 && signal.zonesVisitedCount !== void 0 ? {
|
|
35894
|
+
...memory,
|
|
35895
|
+
lastZonesVisitedCount: signal.zonesVisitedCount
|
|
35896
|
+
} : memory;
|
|
35865
35897
|
if (reason === void 0) return {
|
|
35866
35898
|
emit: false,
|
|
35867
35899
|
memory: keptMemory
|
|
35868
35900
|
};
|
|
35869
35901
|
if (memory !== void 0 && signal.now - memory.lastEmitAt < config.minIntervalMs) return {
|
|
35870
35902
|
emit: false,
|
|
35871
|
-
|
|
35903
|
+
suppressed: reason,
|
|
35904
|
+
memory: {
|
|
35905
|
+
...keptMemory,
|
|
35906
|
+
suppressedSinceEmit: (keptMemory.suppressedSinceEmit ?? 0) + 1
|
|
35907
|
+
}
|
|
35872
35908
|
};
|
|
35873
35909
|
const nextLabel = signal.label ?? memory?.lastLabel;
|
|
35874
35910
|
const nextBboxArea = signal.bboxArea ?? memory?.lastBboxArea;
|
|
35911
|
+
const nextZonesCount = signal.zonesVisitedCount ?? memory?.lastZonesVisitedCount;
|
|
35875
35912
|
return {
|
|
35876
35913
|
emit: true,
|
|
35877
35914
|
reason,
|
|
@@ -35879,7 +35916,8 @@ function evaluateTrackLifecycleUpdate(signal, memory, config) {
|
|
|
35879
35916
|
lastConfidence: memory === void 0 ? signal.confidence : Math.max(memory.lastConfidence, signal.confidence),
|
|
35880
35917
|
lastEmitAt: signal.now,
|
|
35881
35918
|
...nextLabel !== void 0 ? { lastLabel: nextLabel } : {},
|
|
35882
|
-
...nextBboxArea !== void 0 ? { lastBboxArea: nextBboxArea } : {}
|
|
35919
|
+
...nextBboxArea !== void 0 ? { lastBboxArea: nextBboxArea } : {},
|
|
35920
|
+
...nextZonesCount !== void 0 ? { lastZonesVisitedCount: nextZonesCount } : {}
|
|
35883
35921
|
}
|
|
35884
35922
|
};
|
|
35885
35923
|
}
|
|
@@ -39921,7 +39959,8 @@ var TrackStore = class {
|
|
|
39921
39959
|
* Cheap read of an active track's promotion-relevant fields WITHOUT the deep
|
|
39922
39960
|
* clone `getActiveByTrack` does — the returned `positions` is the live
|
|
39923
39961
|
* internal array (read-only; callers must not mutate). Feeds the per-frame
|
|
39924
|
-
* stationary-promotion check
|
|
39962
|
+
* stationary-promotion check AND the lifecycle update gate, both called at
|
|
39963
|
+
* inference fps. Null if unknown/expired.
|
|
39925
39964
|
*/
|
|
39926
39965
|
peekActive(trackId) {
|
|
39927
39966
|
const t = this.active.get(trackId);
|
|
@@ -39929,6 +39968,7 @@ var TrackStore = class {
|
|
|
39929
39968
|
return {
|
|
39930
39969
|
firstSeen: t.firstSeen,
|
|
39931
39970
|
positions: t.positions,
|
|
39971
|
+
zonesVisitedCount: t.zonesVisited.length,
|
|
39932
39972
|
...displayLabel(t) !== void 0 ? { label: displayLabel(t) } : {}
|
|
39933
39973
|
};
|
|
39934
39974
|
}
|
|
@@ -71158,15 +71198,41 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
71158
71198
|
*/
|
|
71159
71199
|
maybeEmitTrackLifecycleUpdate(deviceId, t, timestamp, isNewBest) {
|
|
71160
71200
|
const memory = this.residents.lifecycleUpdateMem(t.trackId);
|
|
71201
|
+
/**
|
|
71202
|
+
* The signal's label reads the frame patch AND the track row: the face
|
|
71203
|
+
* recognizer writes a recognised identity to the ROW over the async
|
|
71204
|
+
* detail plane, never into a frame patch, and a patch-only read left the
|
|
71205
|
+
* identity trigger unable to fire for a face — every face name reached
|
|
71206
|
+
* the export surfaces only on the `end` event, ~30 s after the subject
|
|
71207
|
+
* left the frame (measured live 2026-09-05).
|
|
71208
|
+
*/
|
|
71209
|
+
const peeked = this.trackStore?.peekActive(t.trackId);
|
|
71210
|
+
const label = resolveLifecycleUpdateLabel(t.labelPatch, peeked?.label);
|
|
71161
71211
|
const decision = evaluateTrackLifecycleUpdate({
|
|
71162
71212
|
isNewBest,
|
|
71163
71213
|
confidence: t.confidence,
|
|
71164
71214
|
now: timestamp,
|
|
71165
|
-
...
|
|
71215
|
+
...label !== void 0 ? { label } : {},
|
|
71216
|
+
...peeked !== null && peeked !== void 0 ? { zonesVisitedCount: peeked.zonesVisitedCount } : {},
|
|
71166
71217
|
bboxArea: t.bbox.w * t.bbox.h
|
|
71167
71218
|
}, memory, DEFAULT_UPDATE_GATE_CONFIG);
|
|
71168
71219
|
this.residents.setLifecycleUpdateMem(deviceId, t.trackId, decision.memory);
|
|
71169
|
-
if (!decision.emit)
|
|
71220
|
+
if (!decision.emit) {
|
|
71221
|
+
/**
|
|
71222
|
+
* Dropped for cadence (debounce) — counted, never silent. The count
|
|
71223
|
+
* since the last emit rides the memory and this line; a throttle
|
|
71224
|
+
* with no ledger is how a 30 s delivery delay stayed invisible.
|
|
71225
|
+
*/
|
|
71226
|
+
if (decision.suppressed !== void 0) this.ctx.logger.debug("lifecycle update suppressed (debounce)", {
|
|
71227
|
+
tags: { deviceId },
|
|
71228
|
+
meta: {
|
|
71229
|
+
trackId: t.trackId,
|
|
71230
|
+
reason: decision.suppressed,
|
|
71231
|
+
suppressedSinceEmit: decision.memory.suppressedSinceEmit ?? 0
|
|
71232
|
+
}
|
|
71233
|
+
});
|
|
71234
|
+
return;
|
|
71235
|
+
}
|
|
71170
71236
|
const track = this.trackStore?.getActiveByTrack(t.trackId);
|
|
71171
71237
|
const keyFrameMediaKey = this.residents.keyFrameKey(t.trackId);
|
|
71172
71238
|
const payload = buildTrackLifecyclePayload({
|
|
@@ -71178,7 +71244,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
71178
71244
|
bestConfidence: t.confidence,
|
|
71179
71245
|
firstSeen: track?.firstSeen ?? timestamp,
|
|
71180
71246
|
lastSeen: track?.lastSeen ?? timestamp,
|
|
71181
|
-
...
|
|
71247
|
+
...label !== void 0 ? { label } : {},
|
|
71182
71248
|
...t.plateText !== void 0 ? { plateText: t.plateText } : {},
|
|
71183
71249
|
...track?.zonesVisited !== void 0 ? { zonesVisited: track.zonesVisited } : {},
|
|
71184
71250
|
...track?.totalDistance !== void 0 ? { totalDistance: track.totalDistance } : {},
|
|
@@ -35814,16 +35814,43 @@ function positionsIntersectZone(positions, frameWidth, frameHeight, zone) {
|
|
|
35814
35814
|
}, zone.points)) return true;
|
|
35815
35815
|
return false;
|
|
35816
35816
|
}
|
|
35817
|
+
//#endregion
|
|
35818
|
+
//#region src/pipeline-analytics/track-lifecycle.ts
|
|
35819
|
+
/** Minimum confidence increase (vs last emit) that counts as a material
|
|
35820
|
+
* improvement. */
|
|
35821
|
+
var UPDATE_MIN_CONF_DELTA = .1;
|
|
35822
|
+
/** Debounce floor between two `update` emits for the same track (ms). */
|
|
35823
|
+
var UPDATE_MIN_INTERVAL_MS = 4e3;
|
|
35824
|
+
/** Minimum fractional bbox-area growth (vs last emit) counted as a
|
|
35825
|
+
* materially larger representative crop (e.g. 0.15 = 15% bigger). */
|
|
35826
|
+
var UPDATE_MIN_CROP_AREA_GROWTH = .15;
|
|
35827
|
+
/**
|
|
35828
|
+
* The label a `phase:'update'` SIGNAL and PAYLOAD carry, resolved from its
|
|
35829
|
+
* two possible sources in order: this frame's tiered patch (the frame path
|
|
35830
|
+
* wrote a label this very frame), then the track ROW's stored display label
|
|
35831
|
+
* (`subLabel ?? label`, as `trackStore.peekActive` exposes it).
|
|
35832
|
+
*
|
|
35833
|
+
* The fallback is not a nicety. The face recognizer assigns an identity over
|
|
35834
|
+
* the async detail plane and writes it to the row (`applyLabelCandidate`) —
|
|
35835
|
+
* never into a frame patch — so a signal reading only the patch can never
|
|
35836
|
+
* fire the identity trigger for a recognised face. Measured on the live hub
|
|
35837
|
+
* (2026-09-05, device 590): six of six face identities reached Home
|
|
35838
|
+
* Assistant only on the `end` event at track close + sweep (~lastSeen+33 s),
|
|
35839
|
+
* zero during the track's life, while the subject was still on camera.
|
|
35840
|
+
*/
|
|
35841
|
+
function resolveLifecycleUpdateLabel(labelPatch, storedDisplayLabel) {
|
|
35842
|
+
return patchDisplayLabel(labelPatch) ?? storedDisplayLabel;
|
|
35843
|
+
}
|
|
35817
35844
|
var DEFAULT_UPDATE_GATE_CONFIG = {
|
|
35818
|
-
minConfDelta:
|
|
35819
|
-
minIntervalMs:
|
|
35820
|
-
minCropAreaGrowth:
|
|
35845
|
+
minConfDelta: UPDATE_MIN_CONF_DELTA,
|
|
35846
|
+
minIntervalMs: UPDATE_MIN_INTERVAL_MS,
|
|
35847
|
+
minCropAreaGrowth: UPDATE_MIN_CROP_AREA_GROWTH
|
|
35821
35848
|
};
|
|
35822
35849
|
/**
|
|
35823
35850
|
* Decide whether a `phase:'update'` event should fire this frame.
|
|
35824
35851
|
*
|
|
35825
35852
|
* Priority of triggers: newly-resolved identity/plate > confidence
|
|
35826
|
-
* improvement > materially larger crop. All triggers are debounced by
|
|
35853
|
+
* improvement > newly-entered zone > materially larger crop. All triggers are debounced by
|
|
35827
35854
|
* `minIntervalMs` relative to the last emit. Deltas are measured against
|
|
35828
35855
|
* the LAST-EMITTED memory, so a run of sub-threshold new-bests accumulates
|
|
35829
35856
|
* and fires once it crosses `minConfDelta`.
|
|
@@ -35831,22 +35858,32 @@ var DEFAULT_UPDATE_GATE_CONFIG = {
|
|
|
35831
35858
|
function evaluateTrackLifecycleUpdate(signal, memory, config) {
|
|
35832
35859
|
const identityTrigger = signal.label !== void 0 && signal.label !== "" && (memory === void 0 || memory.lastLabel !== signal.label);
|
|
35833
35860
|
const confidenceTrigger = signal.isNewBest && (memory === void 0 || signal.confidence - memory.lastConfidence >= config.minConfDelta);
|
|
35861
|
+
const zoneTrigger = signal.zonesVisitedCount !== void 0 && memory?.lastZonesVisitedCount !== void 0 && signal.zonesVisitedCount > memory.lastZonesVisitedCount;
|
|
35834
35862
|
const cropTrigger = signal.bboxArea !== void 0 && memory?.lastBboxArea !== void 0 && memory.lastBboxArea > 0 && signal.bboxArea >= memory.lastBboxArea * (1 + config.minCropAreaGrowth);
|
|
35835
|
-
const reason = identityTrigger ? "identity" : confidenceTrigger ? "confidence" : cropTrigger ? "crop" : void 0;
|
|
35836
|
-
const keptMemory = memory
|
|
35863
|
+
const reason = identityTrigger ? "identity" : confidenceTrigger ? "confidence" : zoneTrigger ? "zone" : cropTrigger ? "crop" : void 0;
|
|
35864
|
+
const keptMemory = memory === void 0 ? {
|
|
35837
35865
|
lastConfidence: signal.confidence,
|
|
35838
|
-
lastEmitAt: signal.now
|
|
35839
|
-
|
|
35866
|
+
lastEmitAt: signal.now,
|
|
35867
|
+
...signal.zonesVisitedCount !== void 0 ? { lastZonesVisitedCount: signal.zonesVisitedCount } : {}
|
|
35868
|
+
} : memory.lastZonesVisitedCount === void 0 && signal.zonesVisitedCount !== void 0 ? {
|
|
35869
|
+
...memory,
|
|
35870
|
+
lastZonesVisitedCount: signal.zonesVisitedCount
|
|
35871
|
+
} : memory;
|
|
35840
35872
|
if (reason === void 0) return {
|
|
35841
35873
|
emit: false,
|
|
35842
35874
|
memory: keptMemory
|
|
35843
35875
|
};
|
|
35844
35876
|
if (memory !== void 0 && signal.now - memory.lastEmitAt < config.minIntervalMs) return {
|
|
35845
35877
|
emit: false,
|
|
35846
|
-
|
|
35878
|
+
suppressed: reason,
|
|
35879
|
+
memory: {
|
|
35880
|
+
...keptMemory,
|
|
35881
|
+
suppressedSinceEmit: (keptMemory.suppressedSinceEmit ?? 0) + 1
|
|
35882
|
+
}
|
|
35847
35883
|
};
|
|
35848
35884
|
const nextLabel = signal.label ?? memory?.lastLabel;
|
|
35849
35885
|
const nextBboxArea = signal.bboxArea ?? memory?.lastBboxArea;
|
|
35886
|
+
const nextZonesCount = signal.zonesVisitedCount ?? memory?.lastZonesVisitedCount;
|
|
35850
35887
|
return {
|
|
35851
35888
|
emit: true,
|
|
35852
35889
|
reason,
|
|
@@ -35854,7 +35891,8 @@ function evaluateTrackLifecycleUpdate(signal, memory, config) {
|
|
|
35854
35891
|
lastConfidence: memory === void 0 ? signal.confidence : Math.max(memory.lastConfidence, signal.confidence),
|
|
35855
35892
|
lastEmitAt: signal.now,
|
|
35856
35893
|
...nextLabel !== void 0 ? { lastLabel: nextLabel } : {},
|
|
35857
|
-
...nextBboxArea !== void 0 ? { lastBboxArea: nextBboxArea } : {}
|
|
35894
|
+
...nextBboxArea !== void 0 ? { lastBboxArea: nextBboxArea } : {},
|
|
35895
|
+
...nextZonesCount !== void 0 ? { lastZonesVisitedCount: nextZonesCount } : {}
|
|
35858
35896
|
}
|
|
35859
35897
|
};
|
|
35860
35898
|
}
|
|
@@ -39896,7 +39934,8 @@ var TrackStore = class {
|
|
|
39896
39934
|
* Cheap read of an active track's promotion-relevant fields WITHOUT the deep
|
|
39897
39935
|
* clone `getActiveByTrack` does — the returned `positions` is the live
|
|
39898
39936
|
* internal array (read-only; callers must not mutate). Feeds the per-frame
|
|
39899
|
-
* stationary-promotion check
|
|
39937
|
+
* stationary-promotion check AND the lifecycle update gate, both called at
|
|
39938
|
+
* inference fps. Null if unknown/expired.
|
|
39900
39939
|
*/
|
|
39901
39940
|
peekActive(trackId) {
|
|
39902
39941
|
const t = this.active.get(trackId);
|
|
@@ -39904,6 +39943,7 @@ var TrackStore = class {
|
|
|
39904
39943
|
return {
|
|
39905
39944
|
firstSeen: t.firstSeen,
|
|
39906
39945
|
positions: t.positions,
|
|
39946
|
+
zonesVisitedCount: t.zonesVisited.length,
|
|
39907
39947
|
...displayLabel(t) !== void 0 ? { label: displayLabel(t) } : {}
|
|
39908
39948
|
};
|
|
39909
39949
|
}
|
|
@@ -71084,15 +71124,41 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
71084
71124
|
*/
|
|
71085
71125
|
maybeEmitTrackLifecycleUpdate(deviceId, t, timestamp, isNewBest) {
|
|
71086
71126
|
const memory = this.residents.lifecycleUpdateMem(t.trackId);
|
|
71127
|
+
/**
|
|
71128
|
+
* The signal's label reads the frame patch AND the track row: the face
|
|
71129
|
+
* recognizer writes a recognised identity to the ROW over the async
|
|
71130
|
+
* detail plane, never into a frame patch, and a patch-only read left the
|
|
71131
|
+
* identity trigger unable to fire for a face — every face name reached
|
|
71132
|
+
* the export surfaces only on the `end` event, ~30 s after the subject
|
|
71133
|
+
* left the frame (measured live 2026-09-05).
|
|
71134
|
+
*/
|
|
71135
|
+
const peeked = this.trackStore?.peekActive(t.trackId);
|
|
71136
|
+
const label = resolveLifecycleUpdateLabel(t.labelPatch, peeked?.label);
|
|
71087
71137
|
const decision = evaluateTrackLifecycleUpdate({
|
|
71088
71138
|
isNewBest,
|
|
71089
71139
|
confidence: t.confidence,
|
|
71090
71140
|
now: timestamp,
|
|
71091
|
-
...
|
|
71141
|
+
...label !== void 0 ? { label } : {},
|
|
71142
|
+
...peeked !== null && peeked !== void 0 ? { zonesVisitedCount: peeked.zonesVisitedCount } : {},
|
|
71092
71143
|
bboxArea: t.bbox.w * t.bbox.h
|
|
71093
71144
|
}, memory, DEFAULT_UPDATE_GATE_CONFIG);
|
|
71094
71145
|
this.residents.setLifecycleUpdateMem(deviceId, t.trackId, decision.memory);
|
|
71095
|
-
if (!decision.emit)
|
|
71146
|
+
if (!decision.emit) {
|
|
71147
|
+
/**
|
|
71148
|
+
* Dropped for cadence (debounce) — counted, never silent. The count
|
|
71149
|
+
* since the last emit rides the memory and this line; a throttle
|
|
71150
|
+
* with no ledger is how a 30 s delivery delay stayed invisible.
|
|
71151
|
+
*/
|
|
71152
|
+
if (decision.suppressed !== void 0) this.ctx.logger.debug("lifecycle update suppressed (debounce)", {
|
|
71153
|
+
tags: { deviceId },
|
|
71154
|
+
meta: {
|
|
71155
|
+
trackId: t.trackId,
|
|
71156
|
+
reason: decision.suppressed,
|
|
71157
|
+
suppressedSinceEmit: decision.memory.suppressedSinceEmit ?? 0
|
|
71158
|
+
}
|
|
71159
|
+
});
|
|
71160
|
+
return;
|
|
71161
|
+
}
|
|
71096
71162
|
const track = this.trackStore?.getActiveByTrack(t.trackId);
|
|
71097
71163
|
const keyFrameMediaKey = this.residents.keyFrameKey(t.trackId);
|
|
71098
71164
|
const payload = buildTrackLifecyclePayload({
|
|
@@ -71104,7 +71170,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
71104
71170
|
bestConfidence: t.confidence,
|
|
71105
71171
|
firstSeen: track?.firstSeen ?? timestamp,
|
|
71106
71172
|
lastSeen: track?.lastSeen ?? timestamp,
|
|
71107
|
-
...
|
|
71173
|
+
...label !== void 0 ? { label } : {},
|
|
71108
71174
|
...t.plateText !== void 0 ? { plateText: t.plateText } : {},
|
|
71109
71175
|
...track?.zonesVisited !== void 0 ? { zonesVisited: track.zonesVisited } : {},
|
|
71110
71176
|
...track?.totalDistance !== void 0 ? { totalDistance: track.totalDistance } : {},
|
|
@@ -30,7 +30,7 @@ async function d(e) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async function f() {
|
|
33
|
-
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-
|
|
33
|
+
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-MvTzBID6.mjs")).catch((e) => {
|
|
34
34
|
throw l = void 0, e;
|
|
35
35
|
}), l;
|
|
36
36
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-post-analysis",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.178",
|
|
4
4
|
"description": "Post-Analysis bundle — enrichment, embedding-encoder, pipeline-analytics. Multi-entry npm package shipping addons that consume pipeline output.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|