@camstack/addon-post-analysis 1.2.126 → 1.2.127
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/index.js +122 -22
- package/dist/pipeline-analytics/index.mjs +122 -22
- package/package.json +1 -1
|
@@ -46374,6 +46374,50 @@ var AUDIO_COLUMNS = [
|
|
|
46374
46374
|
type: "JSON"
|
|
46375
46375
|
}
|
|
46376
46376
|
];
|
|
46377
|
+
/**
|
|
46378
|
+
* The columns `slimMotion` reads. `id` is the primary key — always returned,
|
|
46379
|
+
* never part of a projection.
|
|
46380
|
+
*
|
|
46381
|
+
* What it leaves behind is the point: `regions` is a JSON array with one entry
|
|
46382
|
+
* per motion rectangle, and it is the only reason a motion row is not tiny.
|
|
46383
|
+
* `frameWidth` / `frameHeight` go with it — they exist to interpret `regions`
|
|
46384
|
+
* and mean nothing without it.
|
|
46385
|
+
*/
|
|
46386
|
+
var SLIM_MOTION_COLUMNS = [
|
|
46387
|
+
"deviceId",
|
|
46388
|
+
"timestamp",
|
|
46389
|
+
"regionCount"
|
|
46390
|
+
];
|
|
46391
|
+
/**
|
|
46392
|
+
* The columns `slimObject` reads — and ONLY those.
|
|
46393
|
+
*
|
|
46394
|
+
* Four JSON columns are dropped (`bbox`, `zones`, `labelMeta`, `subLabelMeta`)
|
|
46395
|
+
* plus the numbers that only exist to argue about a value after the fact
|
|
46396
|
+
* (`confidence`, `labelScore`, `subLabelScore`) and the frame geometry that,
|
|
46397
|
+
* like motion's, is meaningless without the box it describes.
|
|
46398
|
+
*
|
|
46399
|
+
* `label` / `subLabel` stay because the timeline renders `subLabel ?? label`,
|
|
46400
|
+
* which cannot be evaluated from half a row. `frameId` / `trackId` /
|
|
46401
|
+
* `importance` stay because they are the grouping and sort keys the events page
|
|
46402
|
+
* needs — all three are light.
|
|
46403
|
+
*
|
|
46404
|
+
* ⚠ `slimObject` calls `readTieredLabelColumns`, which reads all SIX tiered
|
|
46405
|
+
* columns and returns the four unprojected ones as `undefined`. That is
|
|
46406
|
+
* harmless here only because `slimObject` uses exactly `label` and `subLabel`
|
|
46407
|
+
* from what it gets back. If it ever starts reading a score, this list is the
|
|
46408
|
+
* thing that has to learn about it — the failure would otherwise be a score
|
|
46409
|
+
* that reads as absent on every slim row.
|
|
46410
|
+
*/
|
|
46411
|
+
var SLIM_OBJECT_COLUMNS = [
|
|
46412
|
+
"deviceId",
|
|
46413
|
+
"timestamp",
|
|
46414
|
+
"className",
|
|
46415
|
+
"frameId",
|
|
46416
|
+
"trackId",
|
|
46417
|
+
"importance",
|
|
46418
|
+
"label",
|
|
46419
|
+
"subLabel"
|
|
46420
|
+
];
|
|
46377
46421
|
var COMMON_INDEXES = (prefix) => [{
|
|
46378
46422
|
name: `idx_${prefix}_device_ts`,
|
|
46379
46423
|
columns: ["deviceId", "timestamp"]
|
|
@@ -46557,6 +46601,19 @@ var EventStore = class {
|
|
|
46557
46601
|
filter
|
|
46558
46602
|
})]);
|
|
46559
46603
|
}
|
|
46604
|
+
/**
|
|
46605
|
+
* Spreadable `columns` for a slim read — omitted entirely for `full`.
|
|
46606
|
+
*
|
|
46607
|
+
* The projection is decided in ONE place per collection ({@link
|
|
46608
|
+
* SLIM_MOTION_COLUMNS} / {@link SLIM_OBJECT_COLUMNS}) because a projection is
|
|
46609
|
+
* a promise between the SELECT and the mapper: the day they disagree nothing
|
|
46610
|
+
* fails. SQLite returns the row without the column, `slimObject` reads
|
|
46611
|
+
* `data['className']`, gets `undefined`, and hands back an event whose class
|
|
46612
|
+
* is missing — indistinguishable from a row that never had one.
|
|
46613
|
+
*/
|
|
46614
|
+
slimColumns(projection, columns) {
|
|
46615
|
+
return projection === "slim" ? { columns } : {};
|
|
46616
|
+
}
|
|
46560
46617
|
buildFilter(q) {
|
|
46561
46618
|
const filter = {
|
|
46562
46619
|
where: { deviceId: q.deviceId },
|
|
@@ -46572,7 +46629,8 @@ var EventStore = class {
|
|
|
46572
46629
|
async queryMotion(q) {
|
|
46573
46630
|
const rows = await this.store.query.query({
|
|
46574
46631
|
collection: MOTION_EVENTS_COLLECTION,
|
|
46575
|
-
filter: this.buildFilter(q)
|
|
46632
|
+
filter: this.buildFilter(q),
|
|
46633
|
+
...this.slimColumns(q.projection, SLIM_MOTION_COLUMNS)
|
|
46576
46634
|
});
|
|
46577
46635
|
if (q.projection === "slim") return rows.map((r) => slimMotion(r.id, stripNulls$1(r.data)));
|
|
46578
46636
|
return rows.map((r) => {
|
|
@@ -46642,7 +46700,8 @@ var EventStore = class {
|
|
|
46642
46700
|
}
|
|
46643
46701
|
const rows = await this.store.query.query({
|
|
46644
46702
|
collection: OBJECT_EVENTS_COLLECTION,
|
|
46645
|
-
filter
|
|
46703
|
+
filter,
|
|
46704
|
+
...this.slimColumns(q.projection, SLIM_OBJECT_COLUMNS)
|
|
46646
46705
|
});
|
|
46647
46706
|
if (q.projection === "slim") return rows.map((r) => slimObject(r.id, stripNulls$1(r.data)));
|
|
46648
46707
|
return rows.map((r) => {
|
|
@@ -49301,6 +49360,16 @@ function trackColumnsFor(projection, needsPositions = false) {
|
|
|
49301
49360
|
if (projection !== "slim") return void 0;
|
|
49302
49361
|
return needsPositions ? [...SLIM_TRACK_COLUMN_NAMES, "positions"] : SLIM_TRACK_COLUMN_NAMES;
|
|
49303
49362
|
}
|
|
49363
|
+
/**
|
|
49364
|
+
* The SELECT list for an IDS-ONLY recent page: the primary key (free, always
|
|
49365
|
+
* returned) plus `lastSeen`.
|
|
49366
|
+
*
|
|
49367
|
+
* `lastSeen` is not an optimisation to shave off later — {@link
|
|
49368
|
+
* TrackStore.recentPage} orders on it, windows on it and breaks
|
|
49369
|
+
* same-millisecond ties with it. Reading ids without it would produce a page in
|
|
49370
|
+
* whatever order the engine felt like and a cursor that cannot resume.
|
|
49371
|
+
*/
|
|
49372
|
+
var RECENT_IDS_COLUMNS = ["lastSeen"];
|
|
49304
49373
|
/** Spreadable `columns` for a store query — omitted entirely for `full`. */
|
|
49305
49374
|
function projectionArg(projection, needsPositions = false) {
|
|
49306
49375
|
const columns = trackColumnsFor(projection, needsPositions);
|
|
@@ -50555,10 +50624,48 @@ var TrackStore = class {
|
|
|
50555
50624
|
* Errors propagate (no partial merges): a failed device query fails the
|
|
50556
50625
|
* page rather than silently returning an incomplete window.
|
|
50557
50626
|
*/
|
|
50627
|
+
/**
|
|
50628
|
+
* A page of RECENT track ids, and nothing else.
|
|
50629
|
+
*
|
|
50630
|
+
* Two callers only ever wanted the strings — `collectLiveTrackIds` (the
|
|
50631
|
+
* orphan audit's live set) and `listTrackIdPage` (the embedding rebuild's
|
|
50632
|
+
* cursor walk) — and both were reading whole tracks to build them. This reads
|
|
50633
|
+
* the primary key plus `lastSeen`, which is not a saving to be traded away:
|
|
50634
|
+
* the cursor, the descending order and the same-millisecond tie-break are all
|
|
50635
|
+
* defined on `lastSeen`, so a page without it would be unordered and
|
|
50636
|
+
* unresumable.
|
|
50637
|
+
*
|
|
50638
|
+
* It shares {@link recentPage} with {@link queryRecent} rather than repeating
|
|
50639
|
+
* the window/cursor arithmetic. Two copies of a paging rule is how one of
|
|
50640
|
+
* them learns about a new bound and the other does not.
|
|
50641
|
+
*/
|
|
50642
|
+
async queryRecentIds(params) {
|
|
50643
|
+
const { page, nextCursor } = await this.recentPage(params, RECENT_IDS_COLUMNS);
|
|
50644
|
+
return {
|
|
50645
|
+
trackIds: page.map((r) => r.id),
|
|
50646
|
+
nextCursor
|
|
50647
|
+
};
|
|
50648
|
+
}
|
|
50558
50649
|
async queryRecent(params) {
|
|
50650
|
+
const { page, nextCursor } = await this.recentPage(params, trackColumnsFor(params.projection));
|
|
50651
|
+
return {
|
|
50652
|
+
tracks: page.map((r) => this.rowToTrack(r.id, r.data, params.projection)),
|
|
50653
|
+
nextCursor
|
|
50654
|
+
};
|
|
50655
|
+
}
|
|
50656
|
+
/**
|
|
50657
|
+
* The window, cursor and fan-out arithmetic behind every "recent tracks"
|
|
50658
|
+
* read — shared so the SELECT list is the only thing a caller varies.
|
|
50659
|
+
*
|
|
50660
|
+
* `columns` is passed straight through to the engine (`undefined` = the whole
|
|
50661
|
+
* row). Everything else here is projection-agnostic on purpose: which rows a
|
|
50662
|
+
* page contains, and in what order, must not depend on how much of each row
|
|
50663
|
+
* the caller asked to read.
|
|
50664
|
+
*/
|
|
50665
|
+
async recentPage(params, columns) {
|
|
50559
50666
|
const deviceIds = [...new Set(params.deviceIds)];
|
|
50560
50667
|
if (deviceIds.length === 0) return {
|
|
50561
|
-
|
|
50668
|
+
page: [],
|
|
50562
50669
|
nextCursor: null
|
|
50563
50670
|
};
|
|
50564
50671
|
const requested = Math.min(Math.max(params.limit ?? RECENT_DEFAULT_LIMIT, 1), RECENT_MAX_LIMIT);
|
|
@@ -50582,7 +50689,7 @@ var TrackStore = class {
|
|
|
50582
50689
|
const winHi = params.until ?? Number.MAX_SAFE_INTEGER;
|
|
50583
50690
|
const hi = cursor !== null ? Math.min(cursor.lastSeen, winHi) : winHi;
|
|
50584
50691
|
if (hi < lo) return {
|
|
50585
|
-
|
|
50692
|
+
page: [],
|
|
50586
50693
|
nextCursor: null
|
|
50587
50694
|
};
|
|
50588
50695
|
const stationaryExclusion = params.excludeStationaryPromotions === true ? { whereNot: { closedReason: "stationary-promotion" } } : {};
|
|
@@ -50598,7 +50705,7 @@ var TrackStore = class {
|
|
|
50598
50705
|
},
|
|
50599
50706
|
...pageLimit !== void 0 ? { limit: pageLimit } : {}
|
|
50600
50707
|
},
|
|
50601
|
-
...
|
|
50708
|
+
...columns === void 0 ? {} : { columns }
|
|
50602
50709
|
});
|
|
50603
50710
|
const perDevice = await Promise.all(deviceIds.map(async (deviceId) => {
|
|
50604
50711
|
if (cursor === null || cursor.lastSeen > hi) return fetchRange(deviceId, [lo, hi], limit + 1);
|
|
@@ -50622,10 +50729,9 @@ var TrackStore = class {
|
|
|
50622
50729
|
}
|
|
50623
50730
|
candidates.sort(compareRecentDesc);
|
|
50624
50731
|
const page = candidates.slice(0, limit);
|
|
50625
|
-
const tracks = page.map((r) => this.rowToTrack(r.id, r.data, params.projection));
|
|
50626
50732
|
const last = page[page.length - 1];
|
|
50627
50733
|
return {
|
|
50628
|
-
|
|
50734
|
+
page,
|
|
50629
50735
|
nextCursor: candidates.length > limit && last !== void 0 ? encodeRecentCursor({
|
|
50630
50736
|
lastSeen: last.lastSeen,
|
|
50631
50737
|
trackId: last.id
|
|
@@ -64417,11 +64523,11 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
64417
64523
|
const trackStore = this.trackStore;
|
|
64418
64524
|
if (!trackStore) return live;
|
|
64419
64525
|
for (const deviceId of deviceIds) {
|
|
64420
|
-
const page = await trackStore.
|
|
64526
|
+
const page = await trackStore.queryRecentIds({
|
|
64421
64527
|
deviceIds: [deviceId],
|
|
64422
64528
|
limit: EMBEDDING_ORPHAN_SCAN_LIMIT
|
|
64423
64529
|
});
|
|
64424
|
-
for (const
|
|
64530
|
+
for (const trackId of page.trackIds) live.add(trackId);
|
|
64425
64531
|
}
|
|
64426
64532
|
return live;
|
|
64427
64533
|
}
|
|
@@ -64744,19 +64850,13 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends require_dist.B
|
|
|
64744
64850
|
logger: this.ctx.logger
|
|
64745
64851
|
}));
|
|
64746
64852
|
const deps = {
|
|
64747
|
-
listTrackIdPage: async (cursor) => {
|
|
64748
|
-
|
|
64749
|
-
|
|
64750
|
-
|
|
64751
|
-
|
|
64752
|
-
|
|
64753
|
-
|
|
64754
|
-
});
|
|
64755
|
-
return {
|
|
64756
|
-
trackIds: page.tracks.map((t) => t.trackId),
|
|
64757
|
-
nextCursor: page.nextCursor
|
|
64758
|
-
};
|
|
64759
|
-
},
|
|
64853
|
+
listTrackIdPage: async (cursor) => trackStore.queryRecentIds({
|
|
64854
|
+
deviceIds,
|
|
64855
|
+
...input.since !== void 0 ? { since: input.since } : {},
|
|
64856
|
+
...input.until !== void 0 ? { until: input.until } : {},
|
|
64857
|
+
...cursor !== null ? { cursor } : {},
|
|
64858
|
+
limit: REBUILD_PAGE_SIZE
|
|
64859
|
+
}),
|
|
64760
64860
|
loadSource: (trackId) => loadRebuildSource({
|
|
64761
64861
|
media: mediaStore,
|
|
64762
64862
|
events: eventStore
|
|
@@ -46311,6 +46311,50 @@ var AUDIO_COLUMNS = [
|
|
|
46311
46311
|
type: "JSON"
|
|
46312
46312
|
}
|
|
46313
46313
|
];
|
|
46314
|
+
/**
|
|
46315
|
+
* The columns `slimMotion` reads. `id` is the primary key — always returned,
|
|
46316
|
+
* never part of a projection.
|
|
46317
|
+
*
|
|
46318
|
+
* What it leaves behind is the point: `regions` is a JSON array with one entry
|
|
46319
|
+
* per motion rectangle, and it is the only reason a motion row is not tiny.
|
|
46320
|
+
* `frameWidth` / `frameHeight` go with it — they exist to interpret `regions`
|
|
46321
|
+
* and mean nothing without it.
|
|
46322
|
+
*/
|
|
46323
|
+
var SLIM_MOTION_COLUMNS = [
|
|
46324
|
+
"deviceId",
|
|
46325
|
+
"timestamp",
|
|
46326
|
+
"regionCount"
|
|
46327
|
+
];
|
|
46328
|
+
/**
|
|
46329
|
+
* The columns `slimObject` reads — and ONLY those.
|
|
46330
|
+
*
|
|
46331
|
+
* Four JSON columns are dropped (`bbox`, `zones`, `labelMeta`, `subLabelMeta`)
|
|
46332
|
+
* plus the numbers that only exist to argue about a value after the fact
|
|
46333
|
+
* (`confidence`, `labelScore`, `subLabelScore`) and the frame geometry that,
|
|
46334
|
+
* like motion's, is meaningless without the box it describes.
|
|
46335
|
+
*
|
|
46336
|
+
* `label` / `subLabel` stay because the timeline renders `subLabel ?? label`,
|
|
46337
|
+
* which cannot be evaluated from half a row. `frameId` / `trackId` /
|
|
46338
|
+
* `importance` stay because they are the grouping and sort keys the events page
|
|
46339
|
+
* needs — all three are light.
|
|
46340
|
+
*
|
|
46341
|
+
* ⚠ `slimObject` calls `readTieredLabelColumns`, which reads all SIX tiered
|
|
46342
|
+
* columns and returns the four unprojected ones as `undefined`. That is
|
|
46343
|
+
* harmless here only because `slimObject` uses exactly `label` and `subLabel`
|
|
46344
|
+
* from what it gets back. If it ever starts reading a score, this list is the
|
|
46345
|
+
* thing that has to learn about it — the failure would otherwise be a score
|
|
46346
|
+
* that reads as absent on every slim row.
|
|
46347
|
+
*/
|
|
46348
|
+
var SLIM_OBJECT_COLUMNS = [
|
|
46349
|
+
"deviceId",
|
|
46350
|
+
"timestamp",
|
|
46351
|
+
"className",
|
|
46352
|
+
"frameId",
|
|
46353
|
+
"trackId",
|
|
46354
|
+
"importance",
|
|
46355
|
+
"label",
|
|
46356
|
+
"subLabel"
|
|
46357
|
+
];
|
|
46314
46358
|
var COMMON_INDEXES = (prefix) => [{
|
|
46315
46359
|
name: `idx_${prefix}_device_ts`,
|
|
46316
46360
|
columns: ["deviceId", "timestamp"]
|
|
@@ -46494,6 +46538,19 @@ var EventStore = class {
|
|
|
46494
46538
|
filter
|
|
46495
46539
|
})]);
|
|
46496
46540
|
}
|
|
46541
|
+
/**
|
|
46542
|
+
* Spreadable `columns` for a slim read — omitted entirely for `full`.
|
|
46543
|
+
*
|
|
46544
|
+
* The projection is decided in ONE place per collection ({@link
|
|
46545
|
+
* SLIM_MOTION_COLUMNS} / {@link SLIM_OBJECT_COLUMNS}) because a projection is
|
|
46546
|
+
* a promise between the SELECT and the mapper: the day they disagree nothing
|
|
46547
|
+
* fails. SQLite returns the row without the column, `slimObject` reads
|
|
46548
|
+
* `data['className']`, gets `undefined`, and hands back an event whose class
|
|
46549
|
+
* is missing — indistinguishable from a row that never had one.
|
|
46550
|
+
*/
|
|
46551
|
+
slimColumns(projection, columns) {
|
|
46552
|
+
return projection === "slim" ? { columns } : {};
|
|
46553
|
+
}
|
|
46497
46554
|
buildFilter(q) {
|
|
46498
46555
|
const filter = {
|
|
46499
46556
|
where: { deviceId: q.deviceId },
|
|
@@ -46509,7 +46566,8 @@ var EventStore = class {
|
|
|
46509
46566
|
async queryMotion(q) {
|
|
46510
46567
|
const rows = await this.store.query.query({
|
|
46511
46568
|
collection: MOTION_EVENTS_COLLECTION,
|
|
46512
|
-
filter: this.buildFilter(q)
|
|
46569
|
+
filter: this.buildFilter(q),
|
|
46570
|
+
...this.slimColumns(q.projection, SLIM_MOTION_COLUMNS)
|
|
46513
46571
|
});
|
|
46514
46572
|
if (q.projection === "slim") return rows.map((r) => slimMotion(r.id, stripNulls$1(r.data)));
|
|
46515
46573
|
return rows.map((r) => {
|
|
@@ -46579,7 +46637,8 @@ var EventStore = class {
|
|
|
46579
46637
|
}
|
|
46580
46638
|
const rows = await this.store.query.query({
|
|
46581
46639
|
collection: OBJECT_EVENTS_COLLECTION,
|
|
46582
|
-
filter
|
|
46640
|
+
filter,
|
|
46641
|
+
...this.slimColumns(q.projection, SLIM_OBJECT_COLUMNS)
|
|
46583
46642
|
});
|
|
46584
46643
|
if (q.projection === "slim") return rows.map((r) => slimObject(r.id, stripNulls$1(r.data)));
|
|
46585
46644
|
return rows.map((r) => {
|
|
@@ -49238,6 +49297,16 @@ function trackColumnsFor(projection, needsPositions = false) {
|
|
|
49238
49297
|
if (projection !== "slim") return void 0;
|
|
49239
49298
|
return needsPositions ? [...SLIM_TRACK_COLUMN_NAMES, "positions"] : SLIM_TRACK_COLUMN_NAMES;
|
|
49240
49299
|
}
|
|
49300
|
+
/**
|
|
49301
|
+
* The SELECT list for an IDS-ONLY recent page: the primary key (free, always
|
|
49302
|
+
* returned) plus `lastSeen`.
|
|
49303
|
+
*
|
|
49304
|
+
* `lastSeen` is not an optimisation to shave off later — {@link
|
|
49305
|
+
* TrackStore.recentPage} orders on it, windows on it and breaks
|
|
49306
|
+
* same-millisecond ties with it. Reading ids without it would produce a page in
|
|
49307
|
+
* whatever order the engine felt like and a cursor that cannot resume.
|
|
49308
|
+
*/
|
|
49309
|
+
var RECENT_IDS_COLUMNS = ["lastSeen"];
|
|
49241
49310
|
/** Spreadable `columns` for a store query — omitted entirely for `full`. */
|
|
49242
49311
|
function projectionArg(projection, needsPositions = false) {
|
|
49243
49312
|
const columns = trackColumnsFor(projection, needsPositions);
|
|
@@ -50492,10 +50561,48 @@ var TrackStore = class {
|
|
|
50492
50561
|
* Errors propagate (no partial merges): a failed device query fails the
|
|
50493
50562
|
* page rather than silently returning an incomplete window.
|
|
50494
50563
|
*/
|
|
50564
|
+
/**
|
|
50565
|
+
* A page of RECENT track ids, and nothing else.
|
|
50566
|
+
*
|
|
50567
|
+
* Two callers only ever wanted the strings — `collectLiveTrackIds` (the
|
|
50568
|
+
* orphan audit's live set) and `listTrackIdPage` (the embedding rebuild's
|
|
50569
|
+
* cursor walk) — and both were reading whole tracks to build them. This reads
|
|
50570
|
+
* the primary key plus `lastSeen`, which is not a saving to be traded away:
|
|
50571
|
+
* the cursor, the descending order and the same-millisecond tie-break are all
|
|
50572
|
+
* defined on `lastSeen`, so a page without it would be unordered and
|
|
50573
|
+
* unresumable.
|
|
50574
|
+
*
|
|
50575
|
+
* It shares {@link recentPage} with {@link queryRecent} rather than repeating
|
|
50576
|
+
* the window/cursor arithmetic. Two copies of a paging rule is how one of
|
|
50577
|
+
* them learns about a new bound and the other does not.
|
|
50578
|
+
*/
|
|
50579
|
+
async queryRecentIds(params) {
|
|
50580
|
+
const { page, nextCursor } = await this.recentPage(params, RECENT_IDS_COLUMNS);
|
|
50581
|
+
return {
|
|
50582
|
+
trackIds: page.map((r) => r.id),
|
|
50583
|
+
nextCursor
|
|
50584
|
+
};
|
|
50585
|
+
}
|
|
50495
50586
|
async queryRecent(params) {
|
|
50587
|
+
const { page, nextCursor } = await this.recentPage(params, trackColumnsFor(params.projection));
|
|
50588
|
+
return {
|
|
50589
|
+
tracks: page.map((r) => this.rowToTrack(r.id, r.data, params.projection)),
|
|
50590
|
+
nextCursor
|
|
50591
|
+
};
|
|
50592
|
+
}
|
|
50593
|
+
/**
|
|
50594
|
+
* The window, cursor and fan-out arithmetic behind every "recent tracks"
|
|
50595
|
+
* read — shared so the SELECT list is the only thing a caller varies.
|
|
50596
|
+
*
|
|
50597
|
+
* `columns` is passed straight through to the engine (`undefined` = the whole
|
|
50598
|
+
* row). Everything else here is projection-agnostic on purpose: which rows a
|
|
50599
|
+
* page contains, and in what order, must not depend on how much of each row
|
|
50600
|
+
* the caller asked to read.
|
|
50601
|
+
*/
|
|
50602
|
+
async recentPage(params, columns) {
|
|
50496
50603
|
const deviceIds = [...new Set(params.deviceIds)];
|
|
50497
50604
|
if (deviceIds.length === 0) return {
|
|
50498
|
-
|
|
50605
|
+
page: [],
|
|
50499
50606
|
nextCursor: null
|
|
50500
50607
|
};
|
|
50501
50608
|
const requested = Math.min(Math.max(params.limit ?? RECENT_DEFAULT_LIMIT, 1), RECENT_MAX_LIMIT);
|
|
@@ -50519,7 +50626,7 @@ var TrackStore = class {
|
|
|
50519
50626
|
const winHi = params.until ?? Number.MAX_SAFE_INTEGER;
|
|
50520
50627
|
const hi = cursor !== null ? Math.min(cursor.lastSeen, winHi) : winHi;
|
|
50521
50628
|
if (hi < lo) return {
|
|
50522
|
-
|
|
50629
|
+
page: [],
|
|
50523
50630
|
nextCursor: null
|
|
50524
50631
|
};
|
|
50525
50632
|
const stationaryExclusion = params.excludeStationaryPromotions === true ? { whereNot: { closedReason: "stationary-promotion" } } : {};
|
|
@@ -50535,7 +50642,7 @@ var TrackStore = class {
|
|
|
50535
50642
|
},
|
|
50536
50643
|
...pageLimit !== void 0 ? { limit: pageLimit } : {}
|
|
50537
50644
|
},
|
|
50538
|
-
...
|
|
50645
|
+
...columns === void 0 ? {} : { columns }
|
|
50539
50646
|
});
|
|
50540
50647
|
const perDevice = await Promise.all(deviceIds.map(async (deviceId) => {
|
|
50541
50648
|
if (cursor === null || cursor.lastSeen > hi) return fetchRange(deviceId, [lo, hi], limit + 1);
|
|
@@ -50559,10 +50666,9 @@ var TrackStore = class {
|
|
|
50559
50666
|
}
|
|
50560
50667
|
candidates.sort(compareRecentDesc);
|
|
50561
50668
|
const page = candidates.slice(0, limit);
|
|
50562
|
-
const tracks = page.map((r) => this.rowToTrack(r.id, r.data, params.projection));
|
|
50563
50669
|
const last = page[page.length - 1];
|
|
50564
50670
|
return {
|
|
50565
|
-
|
|
50671
|
+
page,
|
|
50566
50672
|
nextCursor: candidates.length > limit && last !== void 0 ? encodeRecentCursor({
|
|
50567
50673
|
lastSeen: last.lastSeen,
|
|
50568
50674
|
trackId: last.id
|
|
@@ -64354,11 +64460,11 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
64354
64460
|
const trackStore = this.trackStore;
|
|
64355
64461
|
if (!trackStore) return live;
|
|
64356
64462
|
for (const deviceId of deviceIds) {
|
|
64357
|
-
const page = await trackStore.
|
|
64463
|
+
const page = await trackStore.queryRecentIds({
|
|
64358
64464
|
deviceIds: [deviceId],
|
|
64359
64465
|
limit: EMBEDDING_ORPHAN_SCAN_LIMIT
|
|
64360
64466
|
});
|
|
64361
|
-
for (const
|
|
64467
|
+
for (const trackId of page.trackIds) live.add(trackId);
|
|
64362
64468
|
}
|
|
64363
64469
|
return live;
|
|
64364
64470
|
}
|
|
@@ -64681,19 +64787,13 @@ var PipelineAnalyticsAddon = class PipelineAnalyticsAddon extends BaseAddon {
|
|
|
64681
64787
|
logger: this.ctx.logger
|
|
64682
64788
|
}));
|
|
64683
64789
|
const deps = {
|
|
64684
|
-
listTrackIdPage: async (cursor) => {
|
|
64685
|
-
|
|
64686
|
-
|
|
64687
|
-
|
|
64688
|
-
|
|
64689
|
-
|
|
64690
|
-
|
|
64691
|
-
});
|
|
64692
|
-
return {
|
|
64693
|
-
trackIds: page.tracks.map((t) => t.trackId),
|
|
64694
|
-
nextCursor: page.nextCursor
|
|
64695
|
-
};
|
|
64696
|
-
},
|
|
64790
|
+
listTrackIdPage: async (cursor) => trackStore.queryRecentIds({
|
|
64791
|
+
deviceIds,
|
|
64792
|
+
...input.since !== void 0 ? { since: input.since } : {},
|
|
64793
|
+
...input.until !== void 0 ? { until: input.until } : {},
|
|
64794
|
+
...cursor !== null ? { cursor } : {},
|
|
64795
|
+
limit: REBUILD_PAGE_SIZE
|
|
64796
|
+
}),
|
|
64697
64797
|
loadSource: (trackId) => loadRebuildSource({
|
|
64698
64798
|
media: mediaStore,
|
|
64699
64799
|
events: eventStore
|
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.127",
|
|
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",
|