@camstack/addon-post-analysis 1.2.232 → 1.2.234
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/{dist-Dbf6ceXh.js → dist-DTRcLvW5.js} +18 -2
- package/dist/{dist-yyQ1H5yE.mjs → dist-Du1qDTXV.mjs} +18 -2
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-w7xIpvHc.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-D-bBcfRY.mjs} +3 -3
- package/dist/pipeline-analytics/{hostInit-2-KE2jBo.mjs → hostInit-C9lFCeZi.mjs} +3 -3
- package/dist/pipeline-analytics/index.js +68 -116
- package/dist/pipeline-analytics/index.mjs +68 -116
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/package.json +1 -1
|
@@ -7610,7 +7610,23 @@ var EncodeProfileSchema = object({
|
|
|
7610
7610
|
"zerolatency",
|
|
7611
7611
|
"film",
|
|
7612
7612
|
"animation"
|
|
7613
|
-
]).optional()
|
|
7613
|
+
]).optional(),
|
|
7614
|
+
/**
|
|
7615
|
+
* ONE slice per access unit.
|
|
7616
|
+
*
|
|
7617
|
+
* `-tune zerolatency` turns on x264's sliced threads, and a frame then leaves
|
|
7618
|
+
* the encoder as five NAL slices that share one RTP timestamp and carry one
|
|
7619
|
+
* marker bit. A libwebrtc depacketiser sees five frame-starts and one
|
|
7620
|
+
* frame-end per frame: the first pictures render and the video then freezes
|
|
7621
|
+
* for good while the audio, on its own plane, plays on. Measured on this hub
|
|
7622
|
+
* 2026-09-13 against the Echo, and reduced to one slice by this flag alone.
|
|
7623
|
+
*
|
|
7624
|
+
* A NAMED field and not a raw flag, because {@link EgressEncodeSchema} omits
|
|
7625
|
+
* `outputArgs` on purpose: an opaque array is part of the sharing key, so two
|
|
7626
|
+
* consumers meaning the same thing spelled differently would stop sharing one
|
|
7627
|
+
* child. Absent means "whatever the encoder does" — today's behaviour.
|
|
7628
|
+
*/
|
|
7629
|
+
singleSlicePerFrame: boolean().optional()
|
|
7614
7630
|
}),
|
|
7615
7631
|
audio: union([literal("passthrough"), object({
|
|
7616
7632
|
codec: _enum([
|
|
@@ -7660,7 +7676,7 @@ var BASE_LIVE_EGRESS_PROFILE = {
|
|
|
7660
7676
|
audio: "passthrough"
|
|
7661
7677
|
};
|
|
7662
7678
|
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
7663
|
-
({ ...BASE_LIVE_EGRESS_PROFILE });
|
|
7679
|
+
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
7664
7680
|
/**
|
|
7665
7681
|
* Deep wiring healthcheck — snapshot of active reachability probes across
|
|
7666
7682
|
* every declared capability + widget of every installed plugin, on every
|
|
@@ -7579,7 +7579,23 @@ var EncodeProfileSchema = object({
|
|
|
7579
7579
|
"zerolatency",
|
|
7580
7580
|
"film",
|
|
7581
7581
|
"animation"
|
|
7582
|
-
]).optional()
|
|
7582
|
+
]).optional(),
|
|
7583
|
+
/**
|
|
7584
|
+
* ONE slice per access unit.
|
|
7585
|
+
*
|
|
7586
|
+
* `-tune zerolatency` turns on x264's sliced threads, and a frame then leaves
|
|
7587
|
+
* the encoder as five NAL slices that share one RTP timestamp and carry one
|
|
7588
|
+
* marker bit. A libwebrtc depacketiser sees five frame-starts and one
|
|
7589
|
+
* frame-end per frame: the first pictures render and the video then freezes
|
|
7590
|
+
* for good while the audio, on its own plane, plays on. Measured on this hub
|
|
7591
|
+
* 2026-09-13 against the Echo, and reduced to one slice by this flag alone.
|
|
7592
|
+
*
|
|
7593
|
+
* A NAMED field and not a raw flag, because {@link EgressEncodeSchema} omits
|
|
7594
|
+
* `outputArgs` on purpose: an opaque array is part of the sharing key, so two
|
|
7595
|
+
* consumers meaning the same thing spelled differently would stop sharing one
|
|
7596
|
+
* child. Absent means "whatever the encoder does" — today's behaviour.
|
|
7597
|
+
*/
|
|
7598
|
+
singleSlicePerFrame: boolean().optional()
|
|
7583
7599
|
}),
|
|
7584
7600
|
audio: union([literal("passthrough"), object({
|
|
7585
7601
|
codec: _enum([
|
|
@@ -7629,7 +7645,7 @@ var BASE_LIVE_EGRESS_PROFILE = {
|
|
|
7629
7645
|
audio: "passthrough"
|
|
7630
7646
|
};
|
|
7631
7647
|
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
7632
|
-
({ ...BASE_LIVE_EGRESS_PROFILE });
|
|
7648
|
+
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
7633
7649
|
/**
|
|
7634
7650
|
* Deep wiring healthcheck — snapshot of active reachability probes across
|
|
7635
7651
|
* every declared capability + widget of every installed plugin, on every
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-DTRcLvW5.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
node_fs = require_dist.__toESM(node_fs);
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Dt as parseProcStatus, H as PoolMemoryWatchdog, Pt as resolvePoolMemoryPolicy, Ut as BaseAddon, ft as embeddingEncoderCapability, vt as hfModelUrl } from "../dist-
|
|
1
|
+
import { Dt as parseProcStatus, H as PoolMemoryWatchdog, Pt as resolvePoolMemoryPolicy, Ut as BaseAddon, ft as embeddingEncoderCapability, vt as hfModelUrl } from "../dist-Du1qDTXV.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -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.104",
|
|
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.188",
|
|
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.153",
|
|
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.188",
|
|
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.104",
|
|
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.153",
|
|
85
85
|
scope: "default",
|
|
86
86
|
shareConfig: {
|
|
87
87
|
singleton: !0,
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-DTRcLvW5.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
node_fs = require_dist.__toESM(node_fs, 1);
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -43287,6 +43287,10 @@ function trackColumnsFor(projection, needsPositions = false) {
|
|
|
43287
43287
|
* whatever order the engine felt like and a cursor that cannot resume.
|
|
43288
43288
|
*/
|
|
43289
43289
|
var RECENT_IDS_COLUMNS = ["lastSeen"];
|
|
43290
|
+
/** How many track ids one filter pass may collect per tier. Bounded for the
|
|
43291
|
+
* same reason every bulk read here is: an unbounded scan of this table is
|
|
43292
|
+
* what D447 measured holding the settings thread for seconds. */
|
|
43293
|
+
var TRACK_MATCH_SCAN_LIMIT = 2e4;
|
|
43290
43294
|
/** Spreadable `columns` for a store query — omitted entirely for `full`. */
|
|
43291
43295
|
function projectionArg(projection, needsPositions = false) {
|
|
43292
43296
|
const columns = trackColumnsFor(projection, needsPositions);
|
|
@@ -44374,6 +44378,42 @@ var TrackStore = class {
|
|
|
44374
44378
|
* current subject out from under it. The orphan audit's grace window would
|
|
44375
44379
|
* hide this for an hour and then stop hiding it.
|
|
44376
44380
|
*/
|
|
44381
|
+
/**
|
|
44382
|
+
* Track ids whose CLASS, sub-class or instance matches any of `terms`.
|
|
44383
|
+
*
|
|
44384
|
+
* The summaries' filter asks its question here rather than on a copy: a
|
|
44385
|
+
* label is a fact about the TRACK, it is decided while the track lives and
|
|
44386
|
+
* can still be re-decided afterwards (class voting, a late face match, an
|
|
44387
|
+
* operator enrolling a face and renaming that person). A copy stamped onto
|
|
44388
|
+
* the summary would answer with whatever was true at one instant and never
|
|
44389
|
+
* learn — which is the whole reason this lookup exists instead.
|
|
44390
|
+
*
|
|
44391
|
+
* Three queries because the filter compiler has no OR across fields, and one
|
|
44392
|
+
* term can be any of the three tiers: `animal` is a class, `dog` is a
|
|
44393
|
+
* sub-class, `Roberta` is an instance. Bounded, like every other bulk read
|
|
44394
|
+
* here.
|
|
44395
|
+
*/
|
|
44396
|
+
async trackIdsMatching(terms) {
|
|
44397
|
+
const wanted = terms.filter((t) => t.length > 0);
|
|
44398
|
+
if (wanted.length === 0) return [];
|
|
44399
|
+
const ids = /* @__PURE__ */ new Set();
|
|
44400
|
+
for (const field of [
|
|
44401
|
+
"className",
|
|
44402
|
+
"label",
|
|
44403
|
+
"subLabel"
|
|
44404
|
+
]) {
|
|
44405
|
+
const rows = await this.store.query.query({
|
|
44406
|
+
collection: TRACKS_COLLECTION,
|
|
44407
|
+
filter: {
|
|
44408
|
+
whereIn: { [field]: [...wanted] },
|
|
44409
|
+
limit: TRACK_MATCH_SCAN_LIMIT
|
|
44410
|
+
},
|
|
44411
|
+
columns: ["id"]
|
|
44412
|
+
});
|
|
44413
|
+
for (const row of rows) ids.add(row.id);
|
|
44414
|
+
}
|
|
44415
|
+
return [...ids];
|
|
44416
|
+
}
|
|
44377
44417
|
async existingTrackIds(trackIds) {
|
|
44378
44418
|
const PAGE = 500;
|
|
44379
44419
|
const found = /* @__PURE__ */ new Set();
|
|
@@ -61476,30 +61516,7 @@ var SUMMARY_MEMBERS_COLUMNS = [
|
|
|
61476
61516
|
{
|
|
61477
61517
|
name: "className",
|
|
61478
61518
|
type: "TEXT"
|
|
61479
|
-
})
|
|
61480
|
-
(
|
|
61481
|
-
/**
|
|
61482
|
-
* The member's tier-1 label (`dog`, `van`) and tier-2 instance (a name, a
|
|
61483
|
-
* plate), STAMPED AT SEAL.
|
|
61484
|
-
*
|
|
61485
|
-
* Not at the join, and the timing is the whole point: recognition lands
|
|
61486
|
-
* during a track's life, almost always after it joined, so a label written at
|
|
61487
|
-
* the join would be empty on exactly the members worth naming. At the seal
|
|
61488
|
-
* every member's track has closed, so its label is final — there is nothing
|
|
61489
|
-
* left to change it.
|
|
61490
|
-
*
|
|
61491
|
-
* They are COLUMNS because a filter has to be able to ask for them: "show me
|
|
61492
|
-
* the arrivals with a dog" is a query over members, and answering it from the
|
|
61493
|
-
* tracks would mean reading every track of every summary in the window.
|
|
61494
|
-
*/
|
|
61495
|
-
{
|
|
61496
|
-
name: "label",
|
|
61497
|
-
type: "TEXT"
|
|
61498
|
-
}),
|
|
61499
|
-
{
|
|
61500
|
-
name: "subLabel",
|
|
61501
|
-
type: "TEXT"
|
|
61502
|
-
}
|
|
61519
|
+
})
|
|
61503
61520
|
];
|
|
61504
61521
|
var SUMMARY_MEMBERS_INDEXES = [
|
|
61505
61522
|
{
|
|
@@ -61527,16 +61544,6 @@ var SUMMARY_MEMBERS_INDEXES = [
|
|
|
61527
61544
|
function readRole(raw) {
|
|
61528
61545
|
return raw === "primary" || raw === "sibling" || raw === "child" ? raw : null;
|
|
61529
61546
|
}
|
|
61530
|
-
/** The two stamped labels, present only when they hold something. An empty
|
|
61531
|
-
* string is not a label and must never reach a filter as one. */
|
|
61532
|
-
function labelFields(data) {
|
|
61533
|
-
const label = data["label"];
|
|
61534
|
-
const subLabel = data["subLabel"];
|
|
61535
|
-
return {
|
|
61536
|
-
...typeof label === "string" && label.length > 0 ? { label } : {},
|
|
61537
|
-
...typeof subLabel === "string" && subLabel.length > 0 ? { subLabel } : {}
|
|
61538
|
-
};
|
|
61539
|
-
}
|
|
61540
61547
|
function readClassName(raw) {
|
|
61541
61548
|
return typeof raw === "string" && raw.length > 0 ? raw : null;
|
|
61542
61549
|
}
|
|
@@ -61592,10 +61599,12 @@ var SummaryStore = class {
|
|
|
61592
61599
|
store;
|
|
61593
61600
|
logger;
|
|
61594
61601
|
onEvict;
|
|
61602
|
+
trackIdsMatching;
|
|
61595
61603
|
constructor(deps) {
|
|
61596
61604
|
this.store = deps.store;
|
|
61597
61605
|
this.logger = deps.logger;
|
|
61598
61606
|
this.onEvict = deps.onEvict;
|
|
61607
|
+
this.trackIdsMatching = deps.trackIdsMatching;
|
|
61599
61608
|
}
|
|
61600
61609
|
static async declare(store) {
|
|
61601
61610
|
await Promise.all([store.declareCollection.mutate({
|
|
@@ -61650,8 +61659,7 @@ var SummaryStore = class {
|
|
|
61650
61659
|
deviceId: num$1(r.data["deviceId"]),
|
|
61651
61660
|
joinedAt: num$1(r.data["timestamp"]),
|
|
61652
61661
|
role: readRole(r.data["role"]),
|
|
61653
|
-
className: readClassName(r.data["className"])
|
|
61654
|
-
...labelFields(r.data)
|
|
61662
|
+
className: readClassName(r.data["className"])
|
|
61655
61663
|
}));
|
|
61656
61664
|
}
|
|
61657
61665
|
/**
|
|
@@ -61839,23 +61847,6 @@ var SummaryStore = class {
|
|
|
61839
61847
|
memberCount: leaving.length
|
|
61840
61848
|
};
|
|
61841
61849
|
}
|
|
61842
|
-
/** Stamp a member's final labels. Best-effort and loud: a missing stamp
|
|
61843
|
-
* costs a filter a match, never a membership. */
|
|
61844
|
-
async stampMemberLabels(summaryIdValue, trackId, labels) {
|
|
61845
|
-
try {
|
|
61846
|
-
await this.store.update.mutate({
|
|
61847
|
-
collection: SUMMARY_MEMBERS_COLLECTION$1,
|
|
61848
|
-
id: memberRowId(summaryIdValue, trackId),
|
|
61849
|
-
data: { ...labels }
|
|
61850
|
-
});
|
|
61851
|
-
} catch (err) {
|
|
61852
|
-
this.logger.warn("summary: could not stamp a member label", { meta: {
|
|
61853
|
-
summaryId: summaryIdValue,
|
|
61854
|
-
trackId,
|
|
61855
|
-
error: String(err)
|
|
61856
|
-
} });
|
|
61857
|
-
}
|
|
61858
|
-
}
|
|
61859
61850
|
/**
|
|
61860
61851
|
* Put every OTHER member back to `sibling` after a new primary took the role.
|
|
61861
61852
|
*
|
|
@@ -62061,29 +62052,36 @@ var SummaryStore = class {
|
|
|
62061
62052
|
/**
|
|
62062
62053
|
* The summaries whose MEMBERS match any of `classes`, or `null` for no filter.
|
|
62063
62054
|
*
|
|
62064
|
-
*
|
|
62065
|
-
*
|
|
62066
|
-
*
|
|
62067
|
-
*
|
|
62055
|
+
* TRACKS first, then the members that name them, then the summaries. The
|
|
62056
|
+
* label is a fact about the track and it is asked of the track — a summary
|
|
62057
|
+
* that stored its own copy would answer with whatever was true when it
|
|
62058
|
+
* sealed, and would never learn that a face was enrolled and a person named
|
|
62059
|
+
* an hour later. The operator's rule: *a summary keeps the minimum
|
|
62060
|
+
* information necessary*, and a duplicated label is not the minimum, it is a
|
|
62061
|
+
* second truth with an expiry date.
|
|
62068
62062
|
*
|
|
62069
|
-
*
|
|
62070
|
-
*
|
|
62071
|
-
*
|
|
62072
|
-
* which — that is the whole point of the operator's example.
|
|
62063
|
+
* Narrows before the page is cut. Filtering the other way round — a page of
|
|
62064
|
+
* summaries, then their members — returns a short or empty page while matches
|
|
62065
|
+
* sit further down the list, and the operator reads that as "there were none".
|
|
62073
62066
|
*/
|
|
62074
62067
|
async summaryIdsMatching(classes) {
|
|
62075
62068
|
const wanted = (classes ?? []).filter((t) => t.length > 0);
|
|
62076
62069
|
if (wanted.length === 0) return null;
|
|
62070
|
+
const matchTracks = this.trackIdsMatching;
|
|
62071
|
+
if (matchTracks === void 0) {
|
|
62072
|
+
this.logger.warn("summary filter: no track matcher wired — refusing to answer unfiltered", { meta: { classes: wanted.length } });
|
|
62073
|
+
return /* @__PURE__ */ new Set();
|
|
62074
|
+
}
|
|
62075
|
+
const trackIds = await matchTracks(wanted);
|
|
62076
|
+
if (trackIds.length === 0) return /* @__PURE__ */ new Set();
|
|
62077
62077
|
const ids = /* @__PURE__ */ new Set();
|
|
62078
|
-
|
|
62079
|
-
|
|
62080
|
-
|
|
62081
|
-
"subLabel"
|
|
62082
|
-
]) {
|
|
62078
|
+
const PAGE = 500;
|
|
62079
|
+
for (let i = 0; i < trackIds.length; i += PAGE) {
|
|
62080
|
+
const chunk = trackIds.slice(i, i + PAGE);
|
|
62083
62081
|
const rows = await this.store.query.query({
|
|
62084
62082
|
collection: SUMMARY_MEMBERS_COLLECTION$1,
|
|
62085
62083
|
filter: {
|
|
62086
|
-
whereIn: {
|
|
62084
|
+
whereIn: { trackId: [...chunk] },
|
|
62087
62085
|
limit: MEMBER_MATCH_SCAN_LIMIT
|
|
62088
62086
|
}
|
|
62089
62087
|
});
|
|
@@ -62111,8 +62109,7 @@ var SummaryStore = class {
|
|
|
62111
62109
|
deviceId: num$1(r.data["deviceId"]),
|
|
62112
62110
|
joinedAt: num$1(r.data["timestamp"]),
|
|
62113
62111
|
role: readRole(r.data["role"]),
|
|
62114
|
-
className: readClassName(r.data["className"])
|
|
62115
|
-
...labelFields(r.data)
|
|
62112
|
+
className: readClassName(r.data["className"])
|
|
62116
62113
|
};
|
|
62117
62114
|
const bucket = out.get(summaryIdValue);
|
|
62118
62115
|
if (bucket === void 0) out.set(summaryIdValue, [member]);
|
|
@@ -72846,7 +72843,6 @@ var SummarySealer = class {
|
|
|
72846
72843
|
}
|
|
72847
72844
|
if (await this.isGroupFinished(summary, members) !== true) return;
|
|
72848
72845
|
const sealedAt = this.deps.now();
|
|
72849
|
-
await this.stampLabels(summary, members);
|
|
72850
72846
|
try {
|
|
72851
72847
|
if (await this.deps.summaries.seal(summary, sealedAt)) {
|
|
72852
72848
|
const members = this.forgetGroup(deviceId, summaryId);
|
|
@@ -72879,37 +72875,6 @@ var SummarySealer = class {
|
|
|
72879
72875
|
if (members === void 0) groups.set(summaryIdValue, new Set([trackId]));
|
|
72880
72876
|
else members.add(trackId);
|
|
72881
72877
|
}
|
|
72882
|
-
/**
|
|
72883
|
-
* Write each member's final label onto its row.
|
|
72884
|
-
*
|
|
72885
|
-
* At the seal every member's track has closed, so what the pipeline decided
|
|
72886
|
-
* about it is final — this is the first and last moment the stamp can be
|
|
72887
|
-
* both complete and correct.
|
|
72888
|
-
*/
|
|
72889
|
-
async stampLabels(summary, members) {
|
|
72890
|
-
const read = this.deps.labelsFor;
|
|
72891
|
-
if (read === void 0 || members.length === 0) return;
|
|
72892
|
-
try {
|
|
72893
|
-
const labels = await read(members);
|
|
72894
|
-
for (const [trackId, value] of labels) {
|
|
72895
|
-
const label = value.label;
|
|
72896
|
-
const subLabel = value.subLabel;
|
|
72897
|
-
if ((label === void 0 || label.length === 0) && (subLabel === void 0 || subLabel.length === 0)) continue;
|
|
72898
|
-
await this.deps.summaries.stampMemberLabels(summary.id, trackId, {
|
|
72899
|
-
...label !== void 0 && label.length > 0 ? { label } : {},
|
|
72900
|
-
...subLabel !== void 0 && subLabel.length > 0 ? { subLabel } : {}
|
|
72901
|
-
});
|
|
72902
|
-
}
|
|
72903
|
-
} catch (err) {
|
|
72904
|
-
this.deps.logger.warn("summary: could not stamp member labels — the seal stands", {
|
|
72905
|
-
tags: { deviceId: summary.deviceId },
|
|
72906
|
-
meta: {
|
|
72907
|
-
summaryId: summary.id,
|
|
72908
|
-
error: errMsg(err)
|
|
72909
|
-
}
|
|
72910
|
-
});
|
|
72911
|
-
}
|
|
72912
|
-
}
|
|
72913
72878
|
/** Follows a split in the mirror, so the frame path scores each half on its
|
|
72914
72879
|
* own members from the very next frame. */
|
|
72915
72880
|
moveMirrorMembers(deviceId, fromId, toId, trackIds) {
|
|
@@ -75853,6 +75818,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
75853
75818
|
logger: logger.child("SensorEventStore")
|
|
75854
75819
|
});
|
|
75855
75820
|
this.summaryStore = new SummaryStore({
|
|
75821
|
+
trackIdsMatching: async (terms) => await this.trackStore?.trackIdsMatching(terms) ?? [],
|
|
75856
75822
|
store: api.settingsStore,
|
|
75857
75823
|
logger: this.ctx.logger.child("summary"),
|
|
75858
75824
|
onEvict: async (ids) => {
|
|
@@ -75868,20 +75834,6 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
75868
75834
|
for (const entry of this.stationaryRegistry?.list(deviceId) ?? []) if (entry.sourceTrackId !== void 0) ids.add(entry.sourceTrackId);
|
|
75869
75835
|
return ids;
|
|
75870
75836
|
},
|
|
75871
|
-
labelsFor: async (trackIds) => {
|
|
75872
|
-
const out = /* @__PURE__ */ new Map();
|
|
75873
|
-
const tracks = await this.trackStore?.getPersistedByTrackIds(trackIds) ?? [];
|
|
75874
|
-
for (const track of tracks) {
|
|
75875
|
-
const label = track.label;
|
|
75876
|
-
const subLabel = track.subLabel;
|
|
75877
|
-
if (label === void 0 && subLabel === void 0) continue;
|
|
75878
|
-
out.set(track.trackId, {
|
|
75879
|
-
...label !== void 0 ? { label } : {},
|
|
75880
|
-
...subLabel !== void 0 ? { subLabel } : {}
|
|
75881
|
-
});
|
|
75882
|
-
}
|
|
75883
|
-
return out;
|
|
75884
|
-
},
|
|
75885
75837
|
now: () => Date.now(),
|
|
75886
75838
|
logger: this.ctx.logger.child("summary-sealer"),
|
|
75887
75839
|
frameSize: (deviceId) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as TimelapseRuleSchema, $t as boolean, A as NcConditionDescriptorSchema, At as plateGalleryCapability, B as NcTaxonomySchema, Bt as videoclipsCapability, C as MOTION_CLOSE_AFTER_MS, Ct as isSourceCap, D as NC_DEFAULT_SNOOZE_MINUTES, E as NC_CONDITION_CATALOG, Et as notificationRulesCapability, F as NcScheduleSchema, Ft as sceneMonitorCapability, Gt as DeviceType, Ht as errMsg$1, I as NcSnoozeInputSchema, It as storageOccupancyCapability, J as SCENE_DIVERGED, Jt as isDeviceScopedCap, K as SCENE_DEFAULT_ANCHOR_THRESHOLD, Kt as createEvent, L as NcSnoozeSchema, Lt as subKindsOf, M as NcRulePatchSchema, Mt as readTimelapseGeneratedAt, N as NcRuleSchema, Nt as resolveLocationMode, Ot as pickClusterStepModels, P as NcRuleTargetSchema, Q as TimelapseRulePatchSchema, Qt as array, R as NcSnoozeSuppressedSchema, Rt as systemEventFilterApplies, St as isScheduleActive, T as NC_ALARM_SYSTEM_EVENT_KINDS, Tt as mayWriteToLocation, U as RECORDING_EXPORT_MAX_READ_BYTES, Ut as BaseAddon, V as OpsLogEntrySchema, Vt as zoneAnalyticsCapability, W as RetrainStatusSchema, Wt as CamProfileSchema, X as TIMELAPSE_DENSE_FLOOR_SEC, Xt as sleep$1, Y as SceneMonitorSchema, Yt as nodePin, Z as TimelapseRuleInputSchema, Zt as _enum, _ as FULL_IMAGE_BBOX, _t as failureContributionCapability, a as CLUSTER_MODEL_SCOPED_STEPS, an as record, at as audioMetricsCapability, b as MAX_ARCHIVED_DEBUG_NOTES, bt as isEventOwnerType, cn as EventCategory, ct as cosineSimilarity$1, dt as deriveRecordingMode, en as discriminatedUnion, et as TrackSourceSchema, f as DeclaredDevices, g as FIRST_LEVEL_MACRO_CLASSES, gt as faceGalleryCapability, h as EVENT_PAD_MS, ht as evictionPolicyOfLocation, i as BirthDecisionRecordSchema, in as partialRecord, it as assertTimelapseCadences, j as NcRuleInputSchema, jt as readDeviceStateFrom, k as NC_TAXONOMY, kt as pipelineAnalyticsCapability, lt as customAction, m as EVENT_OWNER_TYPES, mt as evaluateSensorEdge, n as ArchivedDebugNoteSchema, nn as number, nt as addonWidgetsSourceCapability, o as COCO_TO_MACRO, on as string, ot as audioModeOf, p as EVENT_KIND_BY_CAP, pt as encodeVectorBase64, q as SCENE_DEFAULT_UNCOVERED_POLICY, qt as hydrateSchema, r as BaseDevice, rn as object, rt as alarmPanelCapability, s as DEFAULT_EVENT_COLOR, sn as unknown, st as buildEventKindDescriptor, t as AUDIO_MACRO_LABELS, tn as literal, tt as VISIT_MERGE_GAP_MS, u as DETECTION_MACRO_CLASSES, ut as defineCustomActions, v as FailureCounters, w as MediaFileKindEnum, wt as kebabToCamel, x as MAX_BIRTH_DECISION_RECORDS, xt as isMediaOwnerType, y as LabelAttributionSchema, yt as isDetectionMacroClass, z as NcSystemEventKindSchema, zt as vectorDimFromBase64 } from "../dist-
|
|
1
|
+
import { $ as TimelapseRuleSchema, $t as boolean, A as NcConditionDescriptorSchema, At as plateGalleryCapability, B as NcTaxonomySchema, Bt as videoclipsCapability, C as MOTION_CLOSE_AFTER_MS, Ct as isSourceCap, D as NC_DEFAULT_SNOOZE_MINUTES, E as NC_CONDITION_CATALOG, Et as notificationRulesCapability, F as NcScheduleSchema, Ft as sceneMonitorCapability, Gt as DeviceType, Ht as errMsg$1, I as NcSnoozeInputSchema, It as storageOccupancyCapability, J as SCENE_DIVERGED, Jt as isDeviceScopedCap, K as SCENE_DEFAULT_ANCHOR_THRESHOLD, Kt as createEvent, L as NcSnoozeSchema, Lt as subKindsOf, M as NcRulePatchSchema, Mt as readTimelapseGeneratedAt, N as NcRuleSchema, Nt as resolveLocationMode, Ot as pickClusterStepModels, P as NcRuleTargetSchema, Q as TimelapseRulePatchSchema, Qt as array, R as NcSnoozeSuppressedSchema, Rt as systemEventFilterApplies, St as isScheduleActive, T as NC_ALARM_SYSTEM_EVENT_KINDS, Tt as mayWriteToLocation, U as RECORDING_EXPORT_MAX_READ_BYTES, Ut as BaseAddon, V as OpsLogEntrySchema, Vt as zoneAnalyticsCapability, W as RetrainStatusSchema, Wt as CamProfileSchema, X as TIMELAPSE_DENSE_FLOOR_SEC, Xt as sleep$1, Y as SceneMonitorSchema, Yt as nodePin, Z as TimelapseRuleInputSchema, Zt as _enum, _ as FULL_IMAGE_BBOX, _t as failureContributionCapability, a as CLUSTER_MODEL_SCOPED_STEPS, an as record, at as audioMetricsCapability, b as MAX_ARCHIVED_DEBUG_NOTES, bt as isEventOwnerType, cn as EventCategory, ct as cosineSimilarity$1, dt as deriveRecordingMode, en as discriminatedUnion, et as TrackSourceSchema, f as DeclaredDevices, g as FIRST_LEVEL_MACRO_CLASSES, gt as faceGalleryCapability, h as EVENT_PAD_MS, ht as evictionPolicyOfLocation, i as BirthDecisionRecordSchema, in as partialRecord, it as assertTimelapseCadences, j as NcRuleInputSchema, jt as readDeviceStateFrom, k as NC_TAXONOMY, kt as pipelineAnalyticsCapability, lt as customAction, m as EVENT_OWNER_TYPES, mt as evaluateSensorEdge, n as ArchivedDebugNoteSchema, nn as number, nt as addonWidgetsSourceCapability, o as COCO_TO_MACRO, on as string, ot as audioModeOf, p as EVENT_KIND_BY_CAP, pt as encodeVectorBase64, q as SCENE_DEFAULT_UNCOVERED_POLICY, qt as hydrateSchema, r as BaseDevice, rn as object, rt as alarmPanelCapability, s as DEFAULT_EVENT_COLOR, sn as unknown, st as buildEventKindDescriptor, t as AUDIO_MACRO_LABELS, tn as literal, tt as VISIT_MERGE_GAP_MS, u as DETECTION_MACRO_CLASSES, ut as defineCustomActions, v as FailureCounters, w as MediaFileKindEnum, wt as kebabToCamel, x as MAX_BIRTH_DECISION_RECORDS, xt as isMediaOwnerType, y as LabelAttributionSchema, yt as isDetectionMacroClass, z as NcSystemEventKindSchema, zt as vectorDimFromBase64 } from "../dist-Du1qDTXV.mjs";
|
|
2
2
|
import { t as __exportAll } from "../embedding-encoder/index.mjs";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import { promises } from "node:fs";
|
|
@@ -43262,6 +43262,10 @@ function trackColumnsFor(projection, needsPositions = false) {
|
|
|
43262
43262
|
* whatever order the engine felt like and a cursor that cannot resume.
|
|
43263
43263
|
*/
|
|
43264
43264
|
var RECENT_IDS_COLUMNS = ["lastSeen"];
|
|
43265
|
+
/** How many track ids one filter pass may collect per tier. Bounded for the
|
|
43266
|
+
* same reason every bulk read here is: an unbounded scan of this table is
|
|
43267
|
+
* what D447 measured holding the settings thread for seconds. */
|
|
43268
|
+
var TRACK_MATCH_SCAN_LIMIT = 2e4;
|
|
43265
43269
|
/** Spreadable `columns` for a store query — omitted entirely for `full`. */
|
|
43266
43270
|
function projectionArg(projection, needsPositions = false) {
|
|
43267
43271
|
const columns = trackColumnsFor(projection, needsPositions);
|
|
@@ -44349,6 +44353,42 @@ var TrackStore = class {
|
|
|
44349
44353
|
* current subject out from under it. The orphan audit's grace window would
|
|
44350
44354
|
* hide this for an hour and then stop hiding it.
|
|
44351
44355
|
*/
|
|
44356
|
+
/**
|
|
44357
|
+
* Track ids whose CLASS, sub-class or instance matches any of `terms`.
|
|
44358
|
+
*
|
|
44359
|
+
* The summaries' filter asks its question here rather than on a copy: a
|
|
44360
|
+
* label is a fact about the TRACK, it is decided while the track lives and
|
|
44361
|
+
* can still be re-decided afterwards (class voting, a late face match, an
|
|
44362
|
+
* operator enrolling a face and renaming that person). A copy stamped onto
|
|
44363
|
+
* the summary would answer with whatever was true at one instant and never
|
|
44364
|
+
* learn — which is the whole reason this lookup exists instead.
|
|
44365
|
+
*
|
|
44366
|
+
* Three queries because the filter compiler has no OR across fields, and one
|
|
44367
|
+
* term can be any of the three tiers: `animal` is a class, `dog` is a
|
|
44368
|
+
* sub-class, `Roberta` is an instance. Bounded, like every other bulk read
|
|
44369
|
+
* here.
|
|
44370
|
+
*/
|
|
44371
|
+
async trackIdsMatching(terms) {
|
|
44372
|
+
const wanted = terms.filter((t) => t.length > 0);
|
|
44373
|
+
if (wanted.length === 0) return [];
|
|
44374
|
+
const ids = /* @__PURE__ */ new Set();
|
|
44375
|
+
for (const field of [
|
|
44376
|
+
"className",
|
|
44377
|
+
"label",
|
|
44378
|
+
"subLabel"
|
|
44379
|
+
]) {
|
|
44380
|
+
const rows = await this.store.query.query({
|
|
44381
|
+
collection: TRACKS_COLLECTION,
|
|
44382
|
+
filter: {
|
|
44383
|
+
whereIn: { [field]: [...wanted] },
|
|
44384
|
+
limit: TRACK_MATCH_SCAN_LIMIT
|
|
44385
|
+
},
|
|
44386
|
+
columns: ["id"]
|
|
44387
|
+
});
|
|
44388
|
+
for (const row of rows) ids.add(row.id);
|
|
44389
|
+
}
|
|
44390
|
+
return [...ids];
|
|
44391
|
+
}
|
|
44352
44392
|
async existingTrackIds(trackIds) {
|
|
44353
44393
|
const PAGE = 500;
|
|
44354
44394
|
const found = /* @__PURE__ */ new Set();
|
|
@@ -61402,30 +61442,7 @@ var SUMMARY_MEMBERS_COLUMNS = [
|
|
|
61402
61442
|
{
|
|
61403
61443
|
name: "className",
|
|
61404
61444
|
type: "TEXT"
|
|
61405
|
-
})
|
|
61406
|
-
(
|
|
61407
|
-
/**
|
|
61408
|
-
* The member's tier-1 label (`dog`, `van`) and tier-2 instance (a name, a
|
|
61409
|
-
* plate), STAMPED AT SEAL.
|
|
61410
|
-
*
|
|
61411
|
-
* Not at the join, and the timing is the whole point: recognition lands
|
|
61412
|
-
* during a track's life, almost always after it joined, so a label written at
|
|
61413
|
-
* the join would be empty on exactly the members worth naming. At the seal
|
|
61414
|
-
* every member's track has closed, so its label is final — there is nothing
|
|
61415
|
-
* left to change it.
|
|
61416
|
-
*
|
|
61417
|
-
* They are COLUMNS because a filter has to be able to ask for them: "show me
|
|
61418
|
-
* the arrivals with a dog" is a query over members, and answering it from the
|
|
61419
|
-
* tracks would mean reading every track of every summary in the window.
|
|
61420
|
-
*/
|
|
61421
|
-
{
|
|
61422
|
-
name: "label",
|
|
61423
|
-
type: "TEXT"
|
|
61424
|
-
}),
|
|
61425
|
-
{
|
|
61426
|
-
name: "subLabel",
|
|
61427
|
-
type: "TEXT"
|
|
61428
|
-
}
|
|
61445
|
+
})
|
|
61429
61446
|
];
|
|
61430
61447
|
var SUMMARY_MEMBERS_INDEXES = [
|
|
61431
61448
|
{
|
|
@@ -61453,16 +61470,6 @@ var SUMMARY_MEMBERS_INDEXES = [
|
|
|
61453
61470
|
function readRole(raw) {
|
|
61454
61471
|
return raw === "primary" || raw === "sibling" || raw === "child" ? raw : null;
|
|
61455
61472
|
}
|
|
61456
|
-
/** The two stamped labels, present only when they hold something. An empty
|
|
61457
|
-
* string is not a label and must never reach a filter as one. */
|
|
61458
|
-
function labelFields(data) {
|
|
61459
|
-
const label = data["label"];
|
|
61460
|
-
const subLabel = data["subLabel"];
|
|
61461
|
-
return {
|
|
61462
|
-
...typeof label === "string" && label.length > 0 ? { label } : {},
|
|
61463
|
-
...typeof subLabel === "string" && subLabel.length > 0 ? { subLabel } : {}
|
|
61464
|
-
};
|
|
61465
|
-
}
|
|
61466
61473
|
function readClassName(raw) {
|
|
61467
61474
|
return typeof raw === "string" && raw.length > 0 ? raw : null;
|
|
61468
61475
|
}
|
|
@@ -61518,10 +61525,12 @@ var SummaryStore = class {
|
|
|
61518
61525
|
store;
|
|
61519
61526
|
logger;
|
|
61520
61527
|
onEvict;
|
|
61528
|
+
trackIdsMatching;
|
|
61521
61529
|
constructor(deps) {
|
|
61522
61530
|
this.store = deps.store;
|
|
61523
61531
|
this.logger = deps.logger;
|
|
61524
61532
|
this.onEvict = deps.onEvict;
|
|
61533
|
+
this.trackIdsMatching = deps.trackIdsMatching;
|
|
61525
61534
|
}
|
|
61526
61535
|
static async declare(store) {
|
|
61527
61536
|
await Promise.all([store.declareCollection.mutate({
|
|
@@ -61576,8 +61585,7 @@ var SummaryStore = class {
|
|
|
61576
61585
|
deviceId: num$1(r.data["deviceId"]),
|
|
61577
61586
|
joinedAt: num$1(r.data["timestamp"]),
|
|
61578
61587
|
role: readRole(r.data["role"]),
|
|
61579
|
-
className: readClassName(r.data["className"])
|
|
61580
|
-
...labelFields(r.data)
|
|
61588
|
+
className: readClassName(r.data["className"])
|
|
61581
61589
|
}));
|
|
61582
61590
|
}
|
|
61583
61591
|
/**
|
|
@@ -61765,23 +61773,6 @@ var SummaryStore = class {
|
|
|
61765
61773
|
memberCount: leaving.length
|
|
61766
61774
|
};
|
|
61767
61775
|
}
|
|
61768
|
-
/** Stamp a member's final labels. Best-effort and loud: a missing stamp
|
|
61769
|
-
* costs a filter a match, never a membership. */
|
|
61770
|
-
async stampMemberLabels(summaryIdValue, trackId, labels) {
|
|
61771
|
-
try {
|
|
61772
|
-
await this.store.update.mutate({
|
|
61773
|
-
collection: SUMMARY_MEMBERS_COLLECTION$1,
|
|
61774
|
-
id: memberRowId(summaryIdValue, trackId),
|
|
61775
|
-
data: { ...labels }
|
|
61776
|
-
});
|
|
61777
|
-
} catch (err) {
|
|
61778
|
-
this.logger.warn("summary: could not stamp a member label", { meta: {
|
|
61779
|
-
summaryId: summaryIdValue,
|
|
61780
|
-
trackId,
|
|
61781
|
-
error: String(err)
|
|
61782
|
-
} });
|
|
61783
|
-
}
|
|
61784
|
-
}
|
|
61785
61776
|
/**
|
|
61786
61777
|
* Put every OTHER member back to `sibling` after a new primary took the role.
|
|
61787
61778
|
*
|
|
@@ -61987,29 +61978,36 @@ var SummaryStore = class {
|
|
|
61987
61978
|
/**
|
|
61988
61979
|
* The summaries whose MEMBERS match any of `classes`, or `null` for no filter.
|
|
61989
61980
|
*
|
|
61990
|
-
*
|
|
61991
|
-
*
|
|
61992
|
-
*
|
|
61993
|
-
*
|
|
61981
|
+
* TRACKS first, then the members that name them, then the summaries. The
|
|
61982
|
+
* label is a fact about the track and it is asked of the track — a summary
|
|
61983
|
+
* that stored its own copy would answer with whatever was true when it
|
|
61984
|
+
* sealed, and would never learn that a face was enrolled and a person named
|
|
61985
|
+
* an hour later. The operator's rule: *a summary keeps the minimum
|
|
61986
|
+
* information necessary*, and a duplicated label is not the minimum, it is a
|
|
61987
|
+
* second truth with an expiry date.
|
|
61994
61988
|
*
|
|
61995
|
-
*
|
|
61996
|
-
*
|
|
61997
|
-
*
|
|
61998
|
-
* which — that is the whole point of the operator's example.
|
|
61989
|
+
* Narrows before the page is cut. Filtering the other way round — a page of
|
|
61990
|
+
* summaries, then their members — returns a short or empty page while matches
|
|
61991
|
+
* sit further down the list, and the operator reads that as "there were none".
|
|
61999
61992
|
*/
|
|
62000
61993
|
async summaryIdsMatching(classes) {
|
|
62001
61994
|
const wanted = (classes ?? []).filter((t) => t.length > 0);
|
|
62002
61995
|
if (wanted.length === 0) return null;
|
|
61996
|
+
const matchTracks = this.trackIdsMatching;
|
|
61997
|
+
if (matchTracks === void 0) {
|
|
61998
|
+
this.logger.warn("summary filter: no track matcher wired — refusing to answer unfiltered", { meta: { classes: wanted.length } });
|
|
61999
|
+
return /* @__PURE__ */ new Set();
|
|
62000
|
+
}
|
|
62001
|
+
const trackIds = await matchTracks(wanted);
|
|
62002
|
+
if (trackIds.length === 0) return /* @__PURE__ */ new Set();
|
|
62003
62003
|
const ids = /* @__PURE__ */ new Set();
|
|
62004
|
-
|
|
62005
|
-
|
|
62006
|
-
|
|
62007
|
-
"subLabel"
|
|
62008
|
-
]) {
|
|
62004
|
+
const PAGE = 500;
|
|
62005
|
+
for (let i = 0; i < trackIds.length; i += PAGE) {
|
|
62006
|
+
const chunk = trackIds.slice(i, i + PAGE);
|
|
62009
62007
|
const rows = await this.store.query.query({
|
|
62010
62008
|
collection: SUMMARY_MEMBERS_COLLECTION$1,
|
|
62011
62009
|
filter: {
|
|
62012
|
-
whereIn: {
|
|
62010
|
+
whereIn: { trackId: [...chunk] },
|
|
62013
62011
|
limit: MEMBER_MATCH_SCAN_LIMIT
|
|
62014
62012
|
}
|
|
62015
62013
|
});
|
|
@@ -62037,8 +62035,7 @@ var SummaryStore = class {
|
|
|
62037
62035
|
deviceId: num$1(r.data["deviceId"]),
|
|
62038
62036
|
joinedAt: num$1(r.data["timestamp"]),
|
|
62039
62037
|
role: readRole(r.data["role"]),
|
|
62040
|
-
className: readClassName(r.data["className"])
|
|
62041
|
-
...labelFields(r.data)
|
|
62038
|
+
className: readClassName(r.data["className"])
|
|
62042
62039
|
};
|
|
62043
62040
|
const bucket = out.get(summaryIdValue);
|
|
62044
62041
|
if (bucket === void 0) out.set(summaryIdValue, [member]);
|
|
@@ -72772,7 +72769,6 @@ var SummarySealer = class {
|
|
|
72772
72769
|
}
|
|
72773
72770
|
if (await this.isGroupFinished(summary, members) !== true) return;
|
|
72774
72771
|
const sealedAt = this.deps.now();
|
|
72775
|
-
await this.stampLabels(summary, members);
|
|
72776
72772
|
try {
|
|
72777
72773
|
if (await this.deps.summaries.seal(summary, sealedAt)) {
|
|
72778
72774
|
const members = this.forgetGroup(deviceId, summaryId);
|
|
@@ -72805,37 +72801,6 @@ var SummarySealer = class {
|
|
|
72805
72801
|
if (members === void 0) groups.set(summaryIdValue, new Set([trackId]));
|
|
72806
72802
|
else members.add(trackId);
|
|
72807
72803
|
}
|
|
72808
|
-
/**
|
|
72809
|
-
* Write each member's final label onto its row.
|
|
72810
|
-
*
|
|
72811
|
-
* At the seal every member's track has closed, so what the pipeline decided
|
|
72812
|
-
* about it is final — this is the first and last moment the stamp can be
|
|
72813
|
-
* both complete and correct.
|
|
72814
|
-
*/
|
|
72815
|
-
async stampLabels(summary, members) {
|
|
72816
|
-
const read = this.deps.labelsFor;
|
|
72817
|
-
if (read === void 0 || members.length === 0) return;
|
|
72818
|
-
try {
|
|
72819
|
-
const labels = await read(members);
|
|
72820
|
-
for (const [trackId, value] of labels) {
|
|
72821
|
-
const label = value.label;
|
|
72822
|
-
const subLabel = value.subLabel;
|
|
72823
|
-
if ((label === void 0 || label.length === 0) && (subLabel === void 0 || subLabel.length === 0)) continue;
|
|
72824
|
-
await this.deps.summaries.stampMemberLabels(summary.id, trackId, {
|
|
72825
|
-
...label !== void 0 && label.length > 0 ? { label } : {},
|
|
72826
|
-
...subLabel !== void 0 && subLabel.length > 0 ? { subLabel } : {}
|
|
72827
|
-
});
|
|
72828
|
-
}
|
|
72829
|
-
} catch (err) {
|
|
72830
|
-
this.deps.logger.warn("summary: could not stamp member labels — the seal stands", {
|
|
72831
|
-
tags: { deviceId: summary.deviceId },
|
|
72832
|
-
meta: {
|
|
72833
|
-
summaryId: summary.id,
|
|
72834
|
-
error: errMsg(err)
|
|
72835
|
-
}
|
|
72836
|
-
});
|
|
72837
|
-
}
|
|
72838
|
-
}
|
|
72839
72804
|
/** Follows a split in the mirror, so the frame path scores each half on its
|
|
72840
72805
|
* own members from the very next frame. */
|
|
72841
72806
|
moveMirrorMembers(deviceId, fromId, toId, trackIds) {
|
|
@@ -75779,6 +75744,7 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
75779
75744
|
logger: logger.child("SensorEventStore")
|
|
75780
75745
|
});
|
|
75781
75746
|
this.summaryStore = new SummaryStore({
|
|
75747
|
+
trackIdsMatching: async (terms) => await this.trackStore?.trackIdsMatching(terms) ?? [],
|
|
75782
75748
|
store: api.settingsStore,
|
|
75783
75749
|
logger: this.ctx.logger.child("summary"),
|
|
75784
75750
|
onEvict: async (ids) => {
|
|
@@ -75794,20 +75760,6 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
75794
75760
|
for (const entry of this.stationaryRegistry?.list(deviceId) ?? []) if (entry.sourceTrackId !== void 0) ids.add(entry.sourceTrackId);
|
|
75795
75761
|
return ids;
|
|
75796
75762
|
},
|
|
75797
|
-
labelsFor: async (trackIds) => {
|
|
75798
|
-
const out = /* @__PURE__ */ new Map();
|
|
75799
|
-
const tracks = await this.trackStore?.getPersistedByTrackIds(trackIds) ?? [];
|
|
75800
|
-
for (const track of tracks) {
|
|
75801
|
-
const label = track.label;
|
|
75802
|
-
const subLabel = track.subLabel;
|
|
75803
|
-
if (label === void 0 && subLabel === void 0) continue;
|
|
75804
|
-
out.set(track.trackId, {
|
|
75805
|
-
...label !== void 0 ? { label } : {},
|
|
75806
|
-
...subLabel !== void 0 ? { subLabel } : {}
|
|
75807
|
-
});
|
|
75808
|
-
}
|
|
75809
|
-
return out;
|
|
75810
|
-
},
|
|
75811
75763
|
now: () => Date.now(),
|
|
75812
75764
|
logger: this.ctx.logger.child("summary-sealer"),
|
|
75813
75765
|
frameSize: (deviceId) => {
|
|
@@ -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-D-bBcfRY.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.234",
|
|
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",
|