@camstack/addon-pipeline 1.2.373 → 1.2.375
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 +3 -3
- package/dist/audio-analyzer/index.mjs +3 -3
- package/dist/{custom-model-catalog-UaaDgBow.mjs → custom-model-catalog-DF5qs8u4.mjs} +2 -2
- package/dist/{custom-model-catalog-M-ECFeNJ.js → custom-model-catalog-gbLoUFki.js} +2 -2
- package/dist/detection-pipeline/index.js +4 -4
- package/dist/detection-pipeline/index.mjs +4 -4
- package/dist/{dist-QBVFmPYQ.js → dist-C0Mg8e3I.js} +924 -50
- package/dist/{dist-BT3uSeR7.mjs → dist-QyeZXkAO.mjs} +919 -51
- package/dist/{model-catalogs-C42Mo0jo.js → model-catalogs-BTuX-P0k.js} +1 -1
- package/dist/{model-catalogs-ChW0i2P6.mjs → model-catalogs-CIE4Dz4x.mjs} +1 -1
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-B6ev-Hqa.js → node-CifGKjsd.js} +1 -1
- package/dist/{node-BVRFl1hZ.mjs → node-ndjp9DQO.mjs} +1 -1
- package/dist/pipeline-runner/index.js +3 -3
- package/dist/pipeline-runner/index.mjs +3 -3
- package/dist/{process-memory-Cdf2A2qg.js → process-memory-BMfSP5-i.js} +1 -1
- package/dist/{process-memory-DdeedEgU.mjs → process-memory-CaMI-Ry2.mjs} +1 -1
- package/dist/recorder/index.js +265 -94
- package/dist/recorder/index.mjs +263 -92
- package/dist/{segment-demux-js-8CfbEFeD.mjs → segment-demux-js-CLXBgUTo.mjs} +1 -1
- package/dist/{segment-demux-js-Dp0OI-2n.js → segment-demux-js-LhwVw18z.js} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Dl3wrJnM.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-B4MD_B4k.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BvMrdOCD.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-JVFs9LgI.mjs +26 -0
- 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-Bq36nWMP.mjs → hostInit-DBDp5YHD.mjs} +2 -2
- package/dist/stream-broker/index.js +1229 -288
- package/dist/stream-broker/index.mjs +1229 -288
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +5 -1
- package/dist/retire-root-keys-Csb8z2f3.js +0 -338
- package/dist/retire-root-keys-DZvlso2l.mjs +0 -327
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-C3ssSNKh.mjs +0 -26
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BFRtKBOe.mjs +0 -26
|
@@ -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-C0Mg8e3I.js");
|
|
6
6
|
const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Mn as BaseAddon, St as evaluateZoneRules, Un as hydrateSchema, Wt as motionDetectionCapability, kn as DeviceType } from "../dist-
|
|
1
|
+
import { Mn as BaseAddon, St as evaluateZoneRules, Un as hydrateSchema, Wt as motionDetectionCapability, kn as DeviceType } from "../dist-QyeZXkAO.mjs";
|
|
2
2
|
import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { An as errMsg, Cn as Fmp4BoxSplitter, Dn as isSoftwareDecode, wn as buildFfmpegArgs } from "./dist-
|
|
1
|
+
import { An as errMsg, Cn as Fmp4BoxSplitter, Dn as isSoftwareDecode, wn as buildFfmpegArgs } from "./dist-QyeZXkAO.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { realpathSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -3,9 +3,9 @@ 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-
|
|
8
|
-
const require_custom_model_catalog = require("../custom-model-catalog-
|
|
6
|
+
const require_dist = require("../dist-C0Mg8e3I.js");
|
|
7
|
+
const require_node = require("../node-CifGKjsd.js");
|
|
8
|
+
const require_custom_model_catalog = require("../custom-model-catalog-gbLoUFki.js");
|
|
9
9
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
10
10
|
const require_lazy_sharp = require("../lazy-sharp-BuwKlQLR.js");
|
|
11
11
|
const require_restream_intent = require("../restream-intent-7uDNqMKs.js");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-
|
|
3
|
-
import { a as stepsForElectedPool, b as getStepDefinition, d as rootObjectGate, f as localFrameRegistry, h as resolveFrameViewGeometry, i as placeDetailStep, l as resolveDefaultDetectionModel, m as createSessionDecodeCoordinator, p as isSessionDecodeReadGone, s as resolveDeviceEngine, t as CustomModelCatalog, u as macroGateVerdict, y as getStep } from "../custom-model-catalog-
|
|
1
|
+
import { A as NativeLeaseAdmissionSchema, An as errMsg, Bn as defineCustomActions, E as FailureCounters, Et as failureContributionCapability, Ft as loadContributionCapability, In as MODEL_FORMATS, Jt as pickDetailCropConvention, M as NodeBenchRunnerInputSchema, Mn as BaseAddon, P as PIPELINE_RAMP, Pt as linkedStepOf, Rn as createEvent, V as ROOT_SUPPLIABLE_STEP_IDS, Y as allowedSuppliedEffect, Yn as nodePin, Yt as pickNativeLeaseOverride, Zt as pipelineRunnerCapability, _ as DEFAULT_DETAIL_CROP_CONVENTION, a as BackgroundRunRegistry, ar as literal, dn as rootSuppliesOf, er as _enum, fr as EventCategory, gt as deriveRootFaceRefineRect, ir as lazy, j as NativeLeaseSettingsSchema, m as CROP_SUPPLY_SOURCES, mt as deriveDetailCropRect, nr as boolean, nt as buildBenchStepTree, or as number, rt as cameraOwnsMotionViaSensor, sn as resolveModelBoundSetting, sr as object, tr as array, un as resolveRootSupply, ur as string, x as DEVICE_RAMP, y as DEFAULT_NATIVE_LEASE_SETTINGS, zn as customAction } from "../dist-QyeZXkAO.mjs";
|
|
2
|
+
import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-ndjp9DQO.mjs";
|
|
3
|
+
import { a as stepsForElectedPool, b as getStepDefinition, d as rootObjectGate, f as localFrameRegistry, h as resolveFrameViewGeometry, i as placeDetailStep, l as resolveDefaultDetectionModel, m as createSessionDecodeCoordinator, p as isSessionDecodeReadGone, s as resolveDeviceEngine, t as CustomModelCatalog, u as macroGateVerdict, y as getStep } from "../custom-model-catalog-DF5qs8u4.mjs";
|
|
4
4
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
5
5
|
import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
|
|
6
6
|
import { c as withDetectionIntent, o as preRollRequestOf, t as DETECTION_PRE_ROLL_REQUEST_MS } from "../restream-intent-DyGmLAU9.mjs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-emK7D4bc.js");
|
|
2
|
-
const require_dist = require("./dist-
|
|
2
|
+
const require_dist = require("./dist-C0Mg8e3I.js");
|
|
3
3
|
let node_fs = require("node:fs");
|
|
4
4
|
node_fs = require_chunk.__toESM(node_fs);
|
|
5
5
|
let node_child_process = require("node:child_process");
|
package/dist/recorder/index.js
CHANGED
|
@@ -3,11 +3,10 @@ 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-C0Mg8e3I.js");
|
|
7
|
+
const require_node = require("../node-CifGKjsd.js");
|
|
8
8
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
9
9
|
const require_restream_intent = require("../restream-intent-7uDNqMKs.js");
|
|
10
|
-
const require_retire_root_keys = require("../retire-root-keys-Csb8z2f3.js");
|
|
11
10
|
let node_crypto = require("node:crypto");
|
|
12
11
|
let node_fs = require("node:fs");
|
|
13
12
|
let node_path = require("node:path");
|
|
@@ -5054,12 +5053,8 @@ var DeviceSettingsConfigsState = class {
|
|
|
5054
5053
|
}
|
|
5055
5054
|
async readAllRaw() {
|
|
5056
5055
|
const out = /* @__PURE__ */ new Map();
|
|
5057
|
-
const
|
|
5058
|
-
const
|
|
5059
|
-
if (list === void 0 && fallback === void 0) throw new Error("the per-device settings cannot list their devices on this view");
|
|
5060
|
-
const ids = list !== void 0 ? await list.call(this.deps.settings) : fallback !== void 0 ? await fallback() : [];
|
|
5061
|
-
const batch = this.deps.settings.readDeviceStoreBatch;
|
|
5062
|
-
const blobs = batch === void 0 ? new Map(await Promise.all(ids.map(async (id) => [id, await this.deps.settings.readDeviceStore(id)]))) : await batch.call(this.deps.settings, ids);
|
|
5056
|
+
const ids = await this.deps.settings.listDeviceStoreIds();
|
|
5057
|
+
const blobs = await this.deps.settings.readDeviceStoreBatch(ids);
|
|
5063
5058
|
for (const [id, blob] of blobs) {
|
|
5064
5059
|
const held = blob[RECORDING_CONFIG_KEY];
|
|
5065
5060
|
if (held !== void 0) out.set(String(id), held);
|
|
@@ -6156,7 +6151,9 @@ Object.freeze({
|
|
|
6156
6151
|
},
|
|
6157
6152
|
"setDeviceConfig": { "config": { "__nested__": { "bands": [] } } }
|
|
6158
6153
|
},
|
|
6154
|
+
"records": { "query": { "limit": 100 } },
|
|
6159
6155
|
"storage": { "upsertLocation": { "isSystem": false } },
|
|
6156
|
+
"storage-admin": { "readRecords": { "limit": 100 } },
|
|
6160
6157
|
"storage-provider": {
|
|
6161
6158
|
"beginDownload": { "location": { "__nested__": { "isSystem": false } } },
|
|
6162
6159
|
"beginUpload": { "location": { "__nested__": { "isSystem": false } } },
|
|
@@ -6591,6 +6588,18 @@ Object.freeze({
|
|
|
6591
6588
|
{
|
|
6592
6589
|
"path": "swingHorizontal",
|
|
6593
6590
|
"valueType": "boolean"
|
|
6591
|
+
},
|
|
6592
|
+
{
|
|
6593
|
+
"path": "minTemp",
|
|
6594
|
+
"valueType": "number"
|
|
6595
|
+
},
|
|
6596
|
+
{
|
|
6597
|
+
"path": "maxTemp",
|
|
6598
|
+
"valueType": "number"
|
|
6599
|
+
},
|
|
6600
|
+
{
|
|
6601
|
+
"path": "tempStep",
|
|
6602
|
+
"valueType": "number"
|
|
6594
6603
|
}
|
|
6595
6604
|
],
|
|
6596
6605
|
"color": [
|
|
@@ -8360,6 +8369,249 @@ function buildExportArgs(input) {
|
|
|
8360
8369
|
outPath
|
|
8361
8370
|
];
|
|
8362
8371
|
}
|
|
8372
|
+
var ROW_MAP_VALUE_COLUMN = "value";
|
|
8373
|
+
var RowMapStore = class RowMapStore {
|
|
8374
|
+
spec;
|
|
8375
|
+
store;
|
|
8376
|
+
logger;
|
|
8377
|
+
constructor(deps) {
|
|
8378
|
+
this.spec = deps.spec;
|
|
8379
|
+
this.store = deps.store;
|
|
8380
|
+
this.logger = deps.logger;
|
|
8381
|
+
}
|
|
8382
|
+
/** The collection this store owns — for the caller's own log lines. */
|
|
8383
|
+
get collection() {
|
|
8384
|
+
return this.spec.collection;
|
|
8385
|
+
}
|
|
8386
|
+
/**
|
|
8387
|
+
* Register the collection. MUST run at boot, before any read or write: the
|
|
8388
|
+
* SQLite backend answers 412 for an undeclared collection.
|
|
8389
|
+
*/
|
|
8390
|
+
static declare(store, spec) {
|
|
8391
|
+
return store.declareCollection.mutate({
|
|
8392
|
+
collection: spec.collection,
|
|
8393
|
+
columns: [
|
|
8394
|
+
{
|
|
8395
|
+
name: "id",
|
|
8396
|
+
type: "TEXT",
|
|
8397
|
+
primaryKey: true,
|
|
8398
|
+
notNull: true
|
|
8399
|
+
},
|
|
8400
|
+
...spec.columns,
|
|
8401
|
+
{
|
|
8402
|
+
name: ROW_MAP_VALUE_COLUMN,
|
|
8403
|
+
type: "JSON",
|
|
8404
|
+
notNull: true
|
|
8405
|
+
}
|
|
8406
|
+
],
|
|
8407
|
+
...spec.indexes !== void 0 ? { indexes: [...spec.indexes] } : {}
|
|
8408
|
+
});
|
|
8409
|
+
}
|
|
8410
|
+
declare() {
|
|
8411
|
+
return RowMapStore.declare(this.store, this.spec);
|
|
8412
|
+
}
|
|
8413
|
+
/** One entry, by key. `null` when absent OR unparseable (which is said aloud). */
|
|
8414
|
+
async read(key) {
|
|
8415
|
+
const raw = await this.store.get.query({
|
|
8416
|
+
collection: this.spec.collection,
|
|
8417
|
+
key
|
|
8418
|
+
});
|
|
8419
|
+
if (!isRecord(raw)) return null;
|
|
8420
|
+
const row = raw;
|
|
8421
|
+
const parsed = this.spec.schema.safeParse(row[ROW_MAP_VALUE_COLUMN]);
|
|
8422
|
+
if (!parsed.success) {
|
|
8423
|
+
this.logger.warn("row-map row skipped as unparseable", {
|
|
8424
|
+
...this.deviceTags(row),
|
|
8425
|
+
meta: {
|
|
8426
|
+
collection: this.spec.collection,
|
|
8427
|
+
key,
|
|
8428
|
+
error: parsed.error.message
|
|
8429
|
+
}
|
|
8430
|
+
});
|
|
8431
|
+
return null;
|
|
8432
|
+
}
|
|
8433
|
+
return parsed.data;
|
|
8434
|
+
}
|
|
8435
|
+
/**
|
|
8436
|
+
* Every entry, keyed. Unparseable rows are skipped — one bad entry costs that
|
|
8437
|
+
* entry, never the map.
|
|
8438
|
+
*/
|
|
8439
|
+
async readAll() {
|
|
8440
|
+
const records = await this.store.query.query({
|
|
8441
|
+
collection: this.spec.collection,
|
|
8442
|
+
filter: { limit: this.spec.loadLimit }
|
|
8443
|
+
});
|
|
8444
|
+
const out = /* @__PURE__ */ new Map();
|
|
8445
|
+
let skipped = 0;
|
|
8446
|
+
for (const record of records) {
|
|
8447
|
+
const parsed = this.spec.schema.safeParse(record.data[ROW_MAP_VALUE_COLUMN]);
|
|
8448
|
+
if (!parsed.success) {
|
|
8449
|
+
skipped += 1;
|
|
8450
|
+
continue;
|
|
8451
|
+
}
|
|
8452
|
+
out.set(record.id, parsed.data);
|
|
8453
|
+
}
|
|
8454
|
+
if (skipped > 0) this.logger.warn("row-map rows skipped as unparseable", { meta: {
|
|
8455
|
+
collection: this.spec.collection,
|
|
8456
|
+
skipped,
|
|
8457
|
+
kept: out.size
|
|
8458
|
+
} });
|
|
8459
|
+
if (records.length >= this.spec.loadLimit) this.logger.warn("row-map read hit its own bound — the map may be truncated", { meta: {
|
|
8460
|
+
collection: this.spec.collection,
|
|
8461
|
+
loadLimit: this.spec.loadLimit
|
|
8462
|
+
} });
|
|
8463
|
+
return out;
|
|
8464
|
+
}
|
|
8465
|
+
/**
|
|
8466
|
+
* Every entry as it was WRITTEN, unvalidated and unparsed — the read a
|
|
8467
|
+
* MIGRATION needs.
|
|
8468
|
+
*
|
|
8469
|
+
* {@link readAll} answers through the CURRENT schema, which is exactly what a
|
|
8470
|
+
* migration must not do: a retired key is stripped by a non-strict `z.object`
|
|
8471
|
+
* before the migration could see it, so the row it is there to rescue looks
|
|
8472
|
+
* like a row that never needed rescuing. Only a migration should call this;
|
|
8473
|
+
* everything else wants the validated read.
|
|
8474
|
+
*/
|
|
8475
|
+
async readAllRaw() {
|
|
8476
|
+
const records = await this.store.query.query({
|
|
8477
|
+
collection: this.spec.collection,
|
|
8478
|
+
filter: { limit: this.spec.loadLimit }
|
|
8479
|
+
});
|
|
8480
|
+
const out = /* @__PURE__ */ new Map();
|
|
8481
|
+
for (const record of records) out.set(record.id, record.data[ROW_MAP_VALUE_COLUMN]);
|
|
8482
|
+
return out;
|
|
8483
|
+
}
|
|
8484
|
+
/** Insert or replace ONE entry. Validates at the boundary. */
|
|
8485
|
+
async write(key, value) {
|
|
8486
|
+
const validated = this.spec.schema.parse(value);
|
|
8487
|
+
const columns = this.spec.project(key, validated);
|
|
8488
|
+
await this.store.set.mutate({
|
|
8489
|
+
collection: this.spec.collection,
|
|
8490
|
+
key,
|
|
8491
|
+
value: {
|
|
8492
|
+
...columns,
|
|
8493
|
+
[ROW_MAP_VALUE_COLUMN]: validated
|
|
8494
|
+
}
|
|
8495
|
+
});
|
|
8496
|
+
}
|
|
8497
|
+
/** Drop ONE entry. Idempotent. */
|
|
8498
|
+
async remove(key) {
|
|
8499
|
+
await this.store.delete.mutate({
|
|
8500
|
+
collection: this.spec.collection,
|
|
8501
|
+
key
|
|
8502
|
+
});
|
|
8503
|
+
}
|
|
8504
|
+
/**
|
|
8505
|
+
* Make the collection hold exactly `next` — the write path for an owner whose
|
|
8506
|
+
* in-memory map IS the authority (a persister handed the complete set).
|
|
8507
|
+
*
|
|
8508
|
+
* Returns how many rows were DELETED, and says so out loud when any were: a
|
|
8509
|
+
* replace that silently drops rows is indistinguishable from one that never
|
|
8510
|
+
* had them. Only an owner holding an authoritative set may call this — a
|
|
8511
|
+
* prune driven by a fallible read is work destroyed (D130, D49).
|
|
8512
|
+
*/
|
|
8513
|
+
async replaceAll(next) {
|
|
8514
|
+
const held = await this.store.query.query({
|
|
8515
|
+
collection: this.spec.collection,
|
|
8516
|
+
filter: { limit: this.spec.loadLimit }
|
|
8517
|
+
});
|
|
8518
|
+
for (const [key, value] of next) await this.write(key, value);
|
|
8519
|
+
const doomed = held.filter((record) => !next.has(record.id));
|
|
8520
|
+
for (const record of doomed) await this.remove(record.id);
|
|
8521
|
+
if (doomed.length > 0) this.logger.warn("row-map replaceAll dropped rows", { meta: {
|
|
8522
|
+
collection: this.spec.collection,
|
|
8523
|
+
dropped: doomed.length,
|
|
8524
|
+
keys: doomed.slice(0, 20).map((r) => r.id),
|
|
8525
|
+
remaining: next.size
|
|
8526
|
+
} });
|
|
8527
|
+
return doomed.length;
|
|
8528
|
+
}
|
|
8529
|
+
/**
|
|
8530
|
+
* The entries matching a projected-column predicate, in the order asked for.
|
|
8531
|
+
*
|
|
8532
|
+
* This is what projecting columns BUYS: "every export for camera 617, newest
|
|
8533
|
+
* first, capped at 50" is an indexed `WHERE` + `ORDER BY` + `LIMIT`, not a
|
|
8534
|
+
* parse of the whole map followed by a filter in JS.
|
|
8535
|
+
*
|
|
8536
|
+
* A `limit` is REQUIRED — `settings-store.query` silently caps an unbounded
|
|
8537
|
+
* read at 2 000 rows and answers as if that were everything.
|
|
8538
|
+
*/
|
|
8539
|
+
async readWhere(filter) {
|
|
8540
|
+
const records = await this.store.query.query({
|
|
8541
|
+
collection: this.spec.collection,
|
|
8542
|
+
filter: {
|
|
8543
|
+
...filter.where !== void 0 ? { where: filter.where } : {},
|
|
8544
|
+
...filter.whereIn !== void 0 ? { whereIn: filter.whereIn } : {},
|
|
8545
|
+
...filter.whereBetween !== void 0 ? { whereBetween: filter.whereBetween } : {},
|
|
8546
|
+
...filter.orderBy !== void 0 ? { orderBy: filter.orderBy } : {},
|
|
8547
|
+
...filter.offset !== void 0 ? { offset: filter.offset } : {},
|
|
8548
|
+
limit: filter.limit ?? this.spec.loadLimit
|
|
8549
|
+
}
|
|
8550
|
+
});
|
|
8551
|
+
const out = [];
|
|
8552
|
+
let skipped = 0;
|
|
8553
|
+
for (const record of records) {
|
|
8554
|
+
const parsed = this.spec.schema.safeParse(record.data[ROW_MAP_VALUE_COLUMN]);
|
|
8555
|
+
if (!parsed.success) {
|
|
8556
|
+
skipped += 1;
|
|
8557
|
+
continue;
|
|
8558
|
+
}
|
|
8559
|
+
out.push({
|
|
8560
|
+
key: record.id,
|
|
8561
|
+
value: parsed.data
|
|
8562
|
+
});
|
|
8563
|
+
}
|
|
8564
|
+
if (skipped > 0) this.logger.warn("row-map rows skipped as unparseable", { meta: {
|
|
8565
|
+
collection: this.spec.collection,
|
|
8566
|
+
skipped,
|
|
8567
|
+
kept: out.length
|
|
8568
|
+
} });
|
|
8569
|
+
return out;
|
|
8570
|
+
}
|
|
8571
|
+
/** How many rows match, without materialising one. */
|
|
8572
|
+
async count(filter) {
|
|
8573
|
+
return this.store.count.query({
|
|
8574
|
+
collection: this.spec.collection,
|
|
8575
|
+
...filter !== void 0 ? { filter: {
|
|
8576
|
+
...filter.where !== void 0 ? { where: filter.where } : {},
|
|
8577
|
+
...filter.whereIn !== void 0 ? { whereIn: filter.whereIn } : {},
|
|
8578
|
+
...filter.whereBetween !== void 0 ? { whereBetween: filter.whereBetween } : {}
|
|
8579
|
+
} } : {}
|
|
8580
|
+
});
|
|
8581
|
+
}
|
|
8582
|
+
/**
|
|
8583
|
+
* Delete every row matching a predicate, in ONE statement. Returns how many
|
|
8584
|
+
* went, and says so — a retention trim that silently drops rows is
|
|
8585
|
+
* indistinguishable from one that had nothing to do.
|
|
8586
|
+
*
|
|
8587
|
+
* The predicate is REQUIRED and the engine REFUSES one that compiles to
|
|
8588
|
+
* nothing: deleting a whole collection is a legitimate intent, but it must be
|
|
8589
|
+
* asked for by name rather than reached through an empty object.
|
|
8590
|
+
*/
|
|
8591
|
+
async deleteWhere(filter) {
|
|
8592
|
+
const { deleted } = await this.store.deleteWhere.mutate({
|
|
8593
|
+
collection: this.spec.collection,
|
|
8594
|
+
filter
|
|
8595
|
+
});
|
|
8596
|
+
if (deleted > 0) this.logger.warn("row-map deleteWhere dropped rows", { meta: {
|
|
8597
|
+
collection: this.spec.collection,
|
|
8598
|
+
deleted,
|
|
8599
|
+
filter
|
|
8600
|
+
} });
|
|
8601
|
+
return deleted;
|
|
8602
|
+
}
|
|
8603
|
+
/** `tags: { deviceId }` off the PROJECTED column, when the spec names one. */
|
|
8604
|
+
deviceTags(row) {
|
|
8605
|
+
const column = this.spec.deviceIdColumn;
|
|
8606
|
+
if (column === void 0) return {};
|
|
8607
|
+
const raw = row[column];
|
|
8608
|
+
return typeof raw === "number" && Number.isInteger(raw) ? { tags: { deviceId: raw } } : {};
|
|
8609
|
+
}
|
|
8610
|
+
};
|
|
8611
|
+
/** A store payload that is a plain object, or `null`. A type guard, not a cast. */
|
|
8612
|
+
function isRecord(value) {
|
|
8613
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
8614
|
+
}
|
|
8363
8615
|
//#endregion
|
|
8364
8616
|
//#region src/recorder/addon/export-store.ts
|
|
8365
8617
|
/**
|
|
@@ -8485,7 +8737,7 @@ var RECORDING_EXPORTS_SPEC = {
|
|
|
8485
8737
|
};
|
|
8486
8738
|
/** Build the handle. `declare()` MUST run once at boot before any read/write. */
|
|
8487
8739
|
function recordingExportsState(store, logger) {
|
|
8488
|
-
return new
|
|
8740
|
+
return new RowMapStore({
|
|
8489
8741
|
spec: RECORDING_EXPORTS_SPEC,
|
|
8490
8742
|
store,
|
|
8491
8743
|
logger
|
|
@@ -14788,40 +15040,8 @@ var LocationRefresher = class {
|
|
|
14788
15040
|
}
|
|
14789
15041
|
}
|
|
14790
15042
|
};
|
|
14791
|
-
//#endregion
|
|
14792
|
-
//#region src/recorder/addon/ops-log-store.ts
|
|
14793
|
-
/**
|
|
14794
|
-
* Recordings ops-log persistence for the recorder addon.
|
|
14795
|
-
*
|
|
14796
|
-
* ONE ROW PER OPERATION in `recorder:ops-log`, through {@link RowMapStore}. The
|
|
14797
|
-
* ring is still bounded — `maxEntries` newest rows survive — but the eviction
|
|
14798
|
-
* is now a single `DELETE … WHERE at BETWEEN`, and a listing is an indexed
|
|
14799
|
-
* `WHERE deviceId … ORDER BY at DESC LIMIT`.
|
|
14800
|
-
*
|
|
14801
|
-
* ## What this replaced
|
|
14802
|
-
*
|
|
14803
|
-
* The ring lived in ONE key of the recorder's `addon-settings` / `root` blob,
|
|
14804
|
-
* as a flat JSON array. On the reference hub it was 147 437 bytes of that row's
|
|
14805
|
-
* 201 833 — so appending one audit line read, parsed, re-serialised and rewrote
|
|
14806
|
-
* ~200 KB, and so did every unrelated reader of that row (`resolveConfig`,
|
|
14807
|
-
* `loadDeviceConfig`, the export progress patch). The ops log is the CHEAPEST
|
|
14808
|
-
* thing in the recorder and it was paying for the most expensive.
|
|
14809
|
-
*
|
|
14810
|
-
* Writes stay BEST-EFFORT: `createRecordingOpsLogSink().append` never throws —
|
|
14811
|
-
* a failed audit write must not fail the operation it records.
|
|
14812
|
-
*/
|
|
14813
|
-
/**
|
|
14814
|
-
* @durable class=audit owner=recorder
|
|
14815
|
-
* write="one row per recordings operation (prune, evict, relocate, export, …), appended
|
|
14816
|
-
* best-effort by `createRecordingOpsLogSink().append` — never read back by the system,
|
|
14817
|
-
* only listed by an operator through the `recording.listOpsLog` cap method"
|
|
14818
|
-
* retention="a bounded ring: every append trims to the newest OPS_LOG_RING_DEFAULT_MAX
|
|
14819
|
-
* (500) rows with one `deleteWhere` on `at`. Rows tied on the cutoff millisecond
|
|
14820
|
-
* survive, so the ring may hold a few MORE than the cap and never fewer."
|
|
14821
|
-
*/
|
|
14822
|
-
var RECORDING_OPS_LOG_COLLECTION = "recorder:ops-log";
|
|
14823
15043
|
var RECORDING_OPS_LOG_SPEC = {
|
|
14824
|
-
collection:
|
|
15044
|
+
collection: "recorder:ops-log",
|
|
14825
15045
|
schema: require_dist.OpsLogEntrySchema,
|
|
14826
15046
|
columns: [{
|
|
14827
15047
|
name: "at",
|
|
@@ -14847,7 +15067,7 @@ var RECORDING_OPS_LOG_SPEC = {
|
|
|
14847
15067
|
};
|
|
14848
15068
|
/** Build the handle. `declare()` MUST run once at boot before any read/write. */
|
|
14849
15069
|
function recordingOpsLogState(store, logger) {
|
|
14850
|
-
return new
|
|
15070
|
+
return new RowMapStore({
|
|
14851
15071
|
spec: RECORDING_OPS_LOG_SPEC,
|
|
14852
15072
|
store,
|
|
14853
15073
|
logger
|
|
@@ -20963,25 +21183,6 @@ var RetentionSweeper = class {
|
|
|
20963
21183
|
}
|
|
20964
21184
|
};
|
|
20965
21185
|
//#endregion
|
|
20966
|
-
//#region src/recorder/addon/retired-root-keys.ts
|
|
20967
|
-
var RECORDER_RETIRED_ROOT_KEYS = [
|
|
20968
|
-
{
|
|
20969
|
-
key: "recordingOpsLog",
|
|
20970
|
-
successor: RECORDING_OPS_LOG_COLLECTION,
|
|
20971
|
-
reason: "the audit ring is one row per operation since the flatten; as a blob it was 147 KB of the 201 KB root row, re-parsed by every unrelated reader of that row"
|
|
20972
|
-
},
|
|
20973
|
-
{
|
|
20974
|
-
key: "recordingExports",
|
|
20975
|
-
successor: RECORDING_EXPORTS_COLLECTION,
|
|
20976
|
-
reason: "one row per export job since the flatten; as a blob a once-a-second progress patch rewrote 201 KB, and an overlapping createExport erased the row (2026-08-14)"
|
|
20977
|
-
},
|
|
20978
|
-
{
|
|
20979
|
-
key: "recordingConfigs",
|
|
20980
|
-
successor: "the recorder per-device settings (key recordingConfig)",
|
|
20981
|
-
reason: "one row per camera since the flatten; as a blob, asking what camera 617 records parsed every camera in the installation"
|
|
20982
|
-
}
|
|
20983
|
-
];
|
|
20984
|
-
//#endregion
|
|
20985
21186
|
//#region src/recorder/addon/heap-delta.ts
|
|
20986
21187
|
/**
|
|
20987
21188
|
* Name the unit of work that grows the recorder's heap.
|
|
@@ -23418,7 +23619,6 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
23418
23619
|
return { providers: [] };
|
|
23419
23620
|
}
|
|
23420
23621
|
await this.declareRowCollections();
|
|
23421
|
-
await this.purgeFlattenedSettingsKeys();
|
|
23422
23622
|
this.segmentHours = new SegmentHourLedger({
|
|
23423
23623
|
store: this.ctx.api.settingsStore,
|
|
23424
23624
|
logger: this.ctx.logger,
|
|
@@ -25248,31 +25448,6 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
25248
25448
|
await this.opsLogStore().declare();
|
|
25249
25449
|
}
|
|
25250
25450
|
/**
|
|
25251
|
-
* Drop the flattened keys from `recorder:addon-settings` / `root`, each gated
|
|
25252
|
-
* on its own successor collection being non-empty.
|
|
25253
|
-
*
|
|
25254
|
-
* `recordingPlacement` is NOT here: it stays a blob key. It is 1.4 KB of
|
|
25255
|
-
* per-(camera, profile) assignments plus a handful of volume ids, written
|
|
25256
|
-
* only when placement changes — and the row has to survive anyway, because it
|
|
25257
|
-
* is where `BaseAddon.resolveConfig` reads the operator's config fields from.
|
|
25258
|
-
* The problem was a 201 KB row, not a blob.
|
|
25259
|
-
*
|
|
25260
|
-
* Best-effort: a purge that throws must not take recording down. The keys are
|
|
25261
|
-
* dead weight, not a fault.
|
|
25262
|
-
*/
|
|
25263
|
-
async purgeFlattenedSettingsKeys() {
|
|
25264
|
-
try {
|
|
25265
|
-
await require_retire_root_keys.retireRootKeys({
|
|
25266
|
-
store: this.ctx.api.settingsStore,
|
|
25267
|
-
addonId: RECORDER_ADDON_ID,
|
|
25268
|
-
logger: this.ctx.logger,
|
|
25269
|
-
specs: RECORDER_RETIRED_ROOT_KEYS
|
|
25270
|
-
});
|
|
25271
|
-
} catch (err) {
|
|
25272
|
-
this.ctx.logger.warn("recorder: retiring the flattened settings keys failed", { meta: { error: require_dist.errMsg(err) } });
|
|
25273
|
-
}
|
|
25274
|
-
}
|
|
25275
|
-
/**
|
|
25276
25451
|
* `ctx.api.settingsStore`, wrapped ONCE through {@link censusStoreClient}.
|
|
25277
25452
|
*
|
|
25278
25453
|
* LAZY (see `calendar` above): `ctx` is not assigned until `initialize()`
|
|
@@ -25291,11 +25466,7 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
25291
25466
|
if (settings === void 0) throw new Error("recorder: device settings are not available");
|
|
25292
25467
|
this.configsState ??= recordingConfigsState({
|
|
25293
25468
|
settings,
|
|
25294
|
-
logger: this.ctx.logger
|
|
25295
|
-
listDeviceIds: async () => (await this.ctx.api.deviceManager.listAll.query({
|
|
25296
|
-
isCamera: true,
|
|
25297
|
-
projection: "slim"
|
|
25298
|
-
})).map((device) => device.id)
|
|
25469
|
+
logger: this.ctx.logger
|
|
25299
25470
|
});
|
|
25300
25471
|
return this.configsState;
|
|
25301
25472
|
}
|