@camstack/types 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/addon.d.ts +2 -0
- package/dist/addon.js +6 -3
- package/dist/addon.mjs +5 -4
- package/dist/capabilities/addon-settings.cap.d.ts +10 -0
- package/dist/capabilities/core-blocks.cap.d.ts +2 -0
- package/dist/capabilities/device-manager.cap.d.ts +78 -0
- package/dist/capabilities/device-removal-hook.cap.d.ts +93 -0
- package/dist/capabilities/index.d.ts +6 -3
- package/dist/capabilities/keychain.cap.d.ts +11 -0
- package/dist/capabilities/local-network.cap.d.ts +62 -2
- package/dist/client.js +3 -0
- package/dist/client.mjs +3 -0
- package/dist/{composition-DCYnv4I6.js → composition-DIp0uE_b.js} +1 -1
- package/dist/{composition-C-WpVYTX.mjs → composition-EQ9Ok0Ee.mjs} +1 -1
- package/dist/device/device-removal-reconcile.d.ts +49 -0
- package/dist/device/device-type.d.ts +16 -0
- package/dist/{err-msg-DX6i_MY4.mjs → err-msg-DLerKiVO.mjs} +16 -0
- package/dist/{err-msg-Dx2Kor0g.js → err-msg-Ls8Q6dHO.js} +16 -0
- package/dist/generated/addon-api.d.ts +51 -0
- package/dist/generated/capability-router-map.d.ts +5 -2
- package/dist/generated/collection-array-methods.d.ts +1 -1
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/method-device-selectors.d.ts +2 -2
- package/dist/generated/system-proxy.d.ts +2 -2
- package/dist/i18n/camstack-error.d.ts +31 -0
- package/dist/i18n/translation.d.ts +39 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +498 -25
- package/dist/index.mjs +470 -26
- package/dist/interfaces/addon.d.ts +11 -0
- package/dist/interfaces/config-ui.d.ts +20 -0
- package/dist/keychain/secrets-access.d.ts +12 -0
- package/dist/node.js +2 -2
- package/dist/node.mjs +2 -2
- package/dist/pipeline/face-rescore-schedule.d.ts +35 -0
- package/dist/{sleep-DAX0-2v9.mjs → sleep-DRqxtc0C.mjs} +62 -1
- package/dist/{sleep-DnQ5WsMI.js → sleep-rqlHXgwb.js} +91 -0
- package/dist/system/server-name.d.ts +7 -1
- package/dist/types/clip-model.d.ts +2 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_sleep = require("./sleep-
|
|
2
|
+
const require_sleep = require("./sleep-rqlHXgwb.js");
|
|
3
3
|
const require_event_category = require("./event-category-T43rdQWR.js");
|
|
4
|
-
const require_composition = require("./composition-
|
|
4
|
+
const require_composition = require("./composition-DIp0uE_b.js");
|
|
5
5
|
const require_node_color = require("./node-color.js");
|
|
6
|
-
const require_err_msg = require("./err-msg-
|
|
6
|
+
const require_err_msg = require("./err-msg-Ls8Q6dHO.js");
|
|
7
7
|
const require_enums = require("./enums.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
//#region src/media/media-owner-key.ts
|
|
@@ -2601,12 +2601,12 @@ function toStreamSourceEntry(stream) {
|
|
|
2601
2601
|
function isString(v) {
|
|
2602
2602
|
return typeof v === "string";
|
|
2603
2603
|
}
|
|
2604
|
-
function isRecord$
|
|
2604
|
+
function isRecord$3(v) {
|
|
2605
2605
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2606
2606
|
}
|
|
2607
2607
|
function parseStreamEntry(v) {
|
|
2608
2608
|
if (isString(v) && v.trim()) return { url: v };
|
|
2609
|
-
if (isRecord$
|
|
2609
|
+
if (isRecord$3(v) && isString(v["url"]) && v["url"].trim()) return {
|
|
2610
2610
|
url: v["url"],
|
|
2611
2611
|
label: isString(v["label"]) ? v["label"] : void 0
|
|
2612
2612
|
};
|
|
@@ -3247,20 +3247,20 @@ var SURVIVING_TRIGGER_KEYS = [
|
|
|
3247
3247
|
"objectClasses",
|
|
3248
3248
|
"sensorDeviceIds"
|
|
3249
3249
|
];
|
|
3250
|
-
function isRecord$
|
|
3250
|
+
function isRecord$2(value) {
|
|
3251
3251
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3252
3252
|
}
|
|
3253
3253
|
function listensToLegacySignal(band) {
|
|
3254
|
-
return isRecord$
|
|
3254
|
+
return isRecord$2(band) && isRecord$2(band.triggers) && band.triggers.deviceSignal === true;
|
|
3255
3255
|
}
|
|
3256
3256
|
function hasSurvivingTrigger(band) {
|
|
3257
3257
|
const triggers = band.triggers;
|
|
3258
|
-
if (!isRecord$
|
|
3258
|
+
if (!isRecord$2(triggers)) return false;
|
|
3259
3259
|
return SURVIVING_TRIGGER_KEYS.some((key) => triggers[key] !== void 0);
|
|
3260
3260
|
}
|
|
3261
3261
|
function withoutLegacySignal(band) {
|
|
3262
3262
|
const triggers = band.triggers;
|
|
3263
|
-
if (!isRecord$
|
|
3263
|
+
if (!isRecord$2(triggers)) return band;
|
|
3264
3264
|
const { deviceSignal: _retired, ...rest } = triggers;
|
|
3265
3265
|
return {
|
|
3266
3266
|
...band,
|
|
@@ -3290,11 +3290,11 @@ function migrateLegacyDeviceSignalConfig(raw) {
|
|
|
3290
3290
|
migrated: false,
|
|
3291
3291
|
strippedOnly: false
|
|
3292
3292
|
};
|
|
3293
|
-
if (!isRecord$
|
|
3293
|
+
if (!isRecord$2(raw) || !Array.isArray(raw.bands)) return unchanged;
|
|
3294
3294
|
if (!raw.bands.some(listensToLegacySignal)) return unchanged;
|
|
3295
3295
|
const kept = [];
|
|
3296
3296
|
for (const band of raw.bands) {
|
|
3297
|
-
if (!listensToLegacySignal(band) || !isRecord$
|
|
3297
|
+
if (!listensToLegacySignal(band) || !isRecord$2(band)) {
|
|
3298
3298
|
kept.push(band);
|
|
3299
3299
|
continue;
|
|
3300
3300
|
}
|
|
@@ -5660,11 +5660,12 @@ function describeModelVariant(models, modelId) {
|
|
|
5660
5660
|
* for a user-supplied CLIP model: its registry row carries the same block.
|
|
5661
5661
|
*/
|
|
5662
5662
|
/**
|
|
5663
|
-
* `object-clip` (the historical MobileCLIP index, 512-d) or
|
|
5664
5663
|
* `object-clip-<model>`. Lower-case and dash-only so the sqlite-vec table name
|
|
5665
5664
|
* derived from it (`vec_` + non-word → `_`) cannot collide with another index's.
|
|
5665
|
+
* The bare `object-clip` — the retired MobileCLIP index — is NOT accepted (D871):
|
|
5666
|
+
* a model that names it is a catalog defect, not a model.
|
|
5666
5667
|
*/
|
|
5667
|
-
var CLIP_VECTOR_INDEX_PATTERN = /^object-clip
|
|
5668
|
+
var CLIP_VECTOR_INDEX_PATTERN = /^object-clip-[a-z0-9][a-z0-9-]*$/;
|
|
5668
5669
|
var ClipModelMetaSchema = zod.z.object({
|
|
5669
5670
|
/** The paired text encoder's catalog id (the embedding-encoder's text catalog). */
|
|
5670
5671
|
textModelId: zod.z.string().min(1),
|
|
@@ -5673,9 +5674,8 @@ var ClipModelMetaSchema = zod.z.object({
|
|
|
5673
5674
|
/**
|
|
5674
5675
|
* The `vector-store` index this model's vectors live in. ONE feature space
|
|
5675
5676
|
* per index: two models share an index only when their vectors are ranked
|
|
5676
|
-
* against each other, which for CLIP means never across families.
|
|
5677
|
-
*
|
|
5678
|
-
* `modelId`); any other model gets its own.
|
|
5677
|
+
* against each other, which for CLIP means never across families. Every
|
|
5678
|
+
* model gets its own.
|
|
5679
5679
|
*/
|
|
5680
5680
|
vectorIndex: zod.z.string().regex(CLIP_VECTOR_INDEX_PATTERN),
|
|
5681
5681
|
/**
|
|
@@ -8000,7 +8000,9 @@ var ConfigTabDeclarationSchema = zod.z.object({
|
|
|
8000
8000
|
var ConfigSectionWithValuesSchema = zod.z.object({
|
|
8001
8001
|
id: zod.z.string(),
|
|
8002
8002
|
title: zod.z.string(),
|
|
8003
|
+
titleKey: zod.z.string().optional(),
|
|
8003
8004
|
description: zod.z.string().optional(),
|
|
8005
|
+
descriptionKey: zod.z.string().optional(),
|
|
8004
8006
|
style: zod.z.enum(["card", "accordion"]).optional(),
|
|
8005
8007
|
defaultCollapsed: zod.z.boolean().optional(),
|
|
8006
8008
|
columns: zod.z.union([
|
|
@@ -13996,6 +13998,16 @@ var keychainCapability = {
|
|
|
13996
13998
|
kind: "mutation",
|
|
13997
13999
|
auth: "admin"
|
|
13998
14000
|
}),
|
|
14001
|
+
/**
|
|
14002
|
+
* Delete every value scoped `device/<deviceId>`, whatever its owner (D864).
|
|
14003
|
+
* Reserved to `device-manager`, on the device-removed path: a driver's
|
|
14004
|
+
* device-scoped secret is not anybody's once the device is gone. Answers the
|
|
14005
|
+
* refs removed (never values).
|
|
14006
|
+
*/
|
|
14007
|
+
deleteDeviceScope: require_sleep.method(zod.z.object({ deviceId: zod.z.number().int() }), zod.z.object({ refs: zod.z.array(zod.z.string()).readonly() }), {
|
|
14008
|
+
kind: "mutation",
|
|
14009
|
+
auth: "admin"
|
|
14010
|
+
}),
|
|
13999
14011
|
/** The caller's own refs, metadata only. */
|
|
14000
14012
|
listMeta: require_sleep.method(zod.z.object({}), zod.z.array(KeychainSecretMetaSchema).readonly(), { auth: "admin" }),
|
|
14001
14013
|
/** Whether values can be served — the save path refuses a write while locked. */
|
|
@@ -36374,6 +36386,42 @@ var DeviceRegisterPayloadSchema = zod.z.object({
|
|
|
36374
36386
|
* omits it and the keyword backstop applies. */
|
|
36375
36387
|
secretConfigPaths: zod.z.array(zod.z.string()).optional()
|
|
36376
36388
|
});
|
|
36389
|
+
/** One deleted device, kept by device-manager so an addon that missed the
|
|
36390
|
+
* deletion can still learn of it (D865). Written by the delete path ONLY. */
|
|
36391
|
+
var DeviceTombstoneSchema = zod.z.object({
|
|
36392
|
+
deviceId: zod.z.number().int().positive(),
|
|
36393
|
+
/** Epoch ms the device was deleted. */
|
|
36394
|
+
deletedAt: zod.z.number(),
|
|
36395
|
+
/** The addon that owned the device when it was deleted. */
|
|
36396
|
+
providerAddonId: zod.z.string()
|
|
36397
|
+
});
|
|
36398
|
+
/** How long a tombstone stays readable. Past it, a device that was deleted
|
|
36399
|
+
* and never cleaned is only reachable by the admin "clean data of deleted
|
|
36400
|
+
* devices" action. */
|
|
36401
|
+
var DEVICE_TOMBSTONE_RETENTION_MS = 2160 * 60 * 60 * 1e3;
|
|
36402
|
+
/** Data held for one device that device-manager no longer knows. */
|
|
36403
|
+
var OrphanDeviceDataSchema = zod.z.object({
|
|
36404
|
+
deviceId: zod.z.number().int().positive(),
|
|
36405
|
+
/** Rows/files per store (`<addonId>:<store>`). */
|
|
36406
|
+
stores: zod.z.record(zod.z.string(), zod.z.number().int().nonnegative())
|
|
36407
|
+
});
|
|
36408
|
+
var CleanupDeletedDevicesResultSchema = zod.z.object({
|
|
36409
|
+
/**
|
|
36410
|
+
* `skipped` — the absence check could not be trusted (a device-list read
|
|
36411
|
+
* failed or the two reads disagreed); nothing was listed or deleted.
|
|
36412
|
+
* `dry-run` — `devices` is what a confirmed run would delete.
|
|
36413
|
+
* `cleaned` — `devices` is what was deleted.
|
|
36414
|
+
*/
|
|
36415
|
+
status: zod.z.enum([
|
|
36416
|
+
"skipped",
|
|
36417
|
+
"dry-run",
|
|
36418
|
+
"cleaned"
|
|
36419
|
+
]),
|
|
36420
|
+
reason: zod.z.string().nullable(),
|
|
36421
|
+
devices: zod.z.array(OrphanDeviceDataSchema),
|
|
36422
|
+
/** Implementers that could not be asked (their stores are not in `devices`). */
|
|
36423
|
+
unreachable: zod.z.array(zod.z.string())
|
|
36424
|
+
});
|
|
36377
36425
|
var DeviceRemovePayloadSchema = zod.z.object({ deviceId: zod.z.number() });
|
|
36378
36426
|
var DevicePersistConfigPayloadSchema = zod.z.object({
|
|
36379
36427
|
deviceId: zod.z.number(),
|
|
@@ -36970,6 +37018,27 @@ var deviceManagerCapability = {
|
|
|
36970
37018
|
kind: "mutation",
|
|
36971
37019
|
auth: "admin"
|
|
36972
37020
|
}),
|
|
37021
|
+
/**
|
|
37022
|
+
* The tombstones of devices deleted at or after `sinceMs` (D865). The
|
|
37023
|
+
* reconcile feed of every `device-removal-hook` implementer: an addon that
|
|
37024
|
+
* was down when a device was deleted asks here at start and periodically.
|
|
37025
|
+
* A tombstone exists only for a DELETE — never for a device that is merely
|
|
37026
|
+
* unregistered, offline or whose provider is restarting. Tombstones older
|
|
37027
|
+
* than `DEVICE_TOMBSTONE_RETENTION_MS` are gone.
|
|
37028
|
+
*/
|
|
37029
|
+
listDeletedSince: require_sleep.method(zod.z.object({ sinceMs: zod.z.number() }), zod.z.array(DeviceTombstoneSchema).readonly(), { auth: "admin" }),
|
|
37030
|
+
/**
|
|
37031
|
+
* Admin-triggered clean-up of data that belongs to devices deleted BEFORE
|
|
37032
|
+
* tombstones existed (D865). Asks every `device-removal-hook` implementer
|
|
37033
|
+
* which device ids it holds data for, keeps those absent from the device
|
|
37034
|
+
* list — confirmed by TWO reads of the list, skipped if either fails — and
|
|
37035
|
+
* with `confirm: false` only reports the counts per store. `confirm: true`
|
|
37036
|
+
* deletes. Never runs on its own.
|
|
37037
|
+
*/
|
|
37038
|
+
cleanupDeletedDevicesData: require_sleep.method(zod.z.object({ confirm: zod.z.boolean() }), CleanupDeletedDevicesResultSchema, {
|
|
37039
|
+
kind: "mutation",
|
|
37040
|
+
auth: "admin"
|
|
37041
|
+
}),
|
|
36973
37042
|
/** Cascade-delete every top-level device whose `integrationId` matches.
|
|
36974
37043
|
* Children cascade automatically via the per-parent remove path.
|
|
36975
37044
|
* Idempotent: a device whose `integrationId` was never set never matches.
|
|
@@ -37997,6 +38066,87 @@ var embeddingEncoderCapability = {
|
|
|
37997
38066
|
}
|
|
37998
38067
|
};
|
|
37999
38068
|
//#endregion
|
|
38069
|
+
//#region src/capabilities/device-removal-hook.cap.ts
|
|
38070
|
+
/**
|
|
38071
|
+
* `device-removal-hook` — the reliable way an addon learns a device was DELETED,
|
|
38072
|
+
* so it can delete what it keeps for that device (D865).
|
|
38073
|
+
*
|
|
38074
|
+
* ## Why an event was not enough
|
|
38075
|
+
*
|
|
38076
|
+
* `DeviceUnregistered` is telemetry and may be dropped (D8, D11). An addon that
|
|
38077
|
+
* hung its per-device clean-up on it left durable garbage whenever the event was
|
|
38078
|
+
* lost, the addon was down, or it was restarting at that moment — footage,
|
|
38079
|
+
* analytics rows and settings of device 4483 outlived the device. Loss of this
|
|
38080
|
+
* signal corrupts durable state, so it travels by RPC with a recorded fact
|
|
38081
|
+
* behind it (D8: "if loss would corrupt durable state, use RPC plus a reconcile").
|
|
38082
|
+
*
|
|
38083
|
+
* ## The three pieces
|
|
38084
|
+
*
|
|
38085
|
+
* 1. device-manager records a TOMBSTONE per deleted device
|
|
38086
|
+
* (`deviceManager.listDeletedSince`). The tombstone is written by the delete
|
|
38087
|
+
* path only — a device that is unregistered, offline or whose provider is
|
|
38088
|
+
* restarting is NOT deleted and gets none.
|
|
38089
|
+
* 2. After a delete, device-manager calls `onDeviceRemoved` on EVERY provider of
|
|
38090
|
+
* this collection, one by one, with bounded retries, logged.
|
|
38091
|
+
* 3. An implementer that was down asks `deviceManager.listDeletedSince` at start
|
|
38092
|
+
* (and periodically) and runs its own `onDeviceRemoved` for each tombstone it
|
|
38093
|
+
* may have missed. Reconcile is driven by tombstones, never by "the device is
|
|
38094
|
+
* not in the current list": a failed or partial list read must not destroy data.
|
|
38095
|
+
*
|
|
38096
|
+
* ## Contract for an implementer
|
|
38097
|
+
*
|
|
38098
|
+
* - **Idempotent.** It is called again by a retry, by a reconcile and by the
|
|
38099
|
+
* admin cleanup of data that predates tombstones. A device with nothing left
|
|
38100
|
+
* answers zero counts.
|
|
38101
|
+
* - **One key per store** in `counts`, deleted rows/files per store, so the log
|
|
38102
|
+
* line and the admin dry run can say where the data was.
|
|
38103
|
+
* - **Training datasets are NOT device data** and are never deleted by a hook.
|
|
38104
|
+
* - **Per-device SETTINGS are not hooked.** Configuration lives in the standard
|
|
38105
|
+
* per-device store (`ctx.settings.*DeviceStore`), which device-manager clears
|
|
38106
|
+
* for every addon centrally at delete time. This hook is for device DATA
|
|
38107
|
+
* that is not settings: footage, event media, analytics rows, history.
|
|
38108
|
+
* - A provider that cannot tell is allowed to throw; the caller retries it.
|
|
38109
|
+
*
|
|
38110
|
+
* `listDeviceData` is the read side of the admin "Clean data of deleted devices"
|
|
38111
|
+
* action: which device ids this addon holds data for, and how much per store. It
|
|
38112
|
+
* never deletes. device-manager decides which of those ids are absent from the
|
|
38113
|
+
* fleet, from TWO consistent reads of the device list (D49).
|
|
38114
|
+
*/
|
|
38115
|
+
/** What a hook is told about the deletion. */
|
|
38116
|
+
var DeviceRemovedInputSchema = zod.z.object({
|
|
38117
|
+
deviceId: zod.z.number().int().positive(),
|
|
38118
|
+
/** Epoch ms the device was deleted (the tombstone's `deletedAt`). */
|
|
38119
|
+
deletedAt: zod.z.number(),
|
|
38120
|
+
/** The addon that owned the device, as device-manager last knew it. */
|
|
38121
|
+
providerAddonId: zod.z.string()
|
|
38122
|
+
});
|
|
38123
|
+
/** Rows/files/refs deleted, per store this implementer owns. */
|
|
38124
|
+
var DeviceRemovedResultSchema = zod.z.object({ counts: zod.z.record(zod.z.string(), zod.z.number().int().nonnegative()) });
|
|
38125
|
+
/** One (store, device) pair an implementer holds data for. */
|
|
38126
|
+
var DeviceDataEntrySchema = zod.z.object({
|
|
38127
|
+
store: zod.z.string(),
|
|
38128
|
+
deviceId: zod.z.number().int().positive(),
|
|
38129
|
+
/** Rows (or files) held for the device in the store. */
|
|
38130
|
+
count: zod.z.number().int().nonnegative()
|
|
38131
|
+
});
|
|
38132
|
+
var deviceRemovalHookCapability = {
|
|
38133
|
+
name: "device-removal-hook",
|
|
38134
|
+
scope: "system",
|
|
38135
|
+
mode: "collection",
|
|
38136
|
+
internal: true,
|
|
38137
|
+
methods: {
|
|
38138
|
+
/** Delete everything this addon keeps for the deleted device. Idempotent. */
|
|
38139
|
+
onDeviceRemoved: require_sleep.method(DeviceRemovedInputSchema, DeviceRemovedResultSchema, {
|
|
38140
|
+
kind: "mutation",
|
|
38141
|
+
auth: "admin"
|
|
38142
|
+
}),
|
|
38143
|
+
/** Which devices this addon holds data for, per store. Reads only. */
|
|
38144
|
+
listDeviceData: require_sleep.method(zod.z.void(), zod.z.array(DeviceDataEntrySchema).readonly(), { auth: "admin" })
|
|
38145
|
+
},
|
|
38146
|
+
/** In-process only — enumerated through `addons.listCapabilityProviders`. */
|
|
38147
|
+
mount: { kind: "skip" }
|
|
38148
|
+
};
|
|
38149
|
+
//#endregion
|
|
38000
38150
|
//#region src/capabilities/failure-contribution.cap.ts
|
|
38001
38151
|
/**
|
|
38002
38152
|
* `failure-contribution` — the capability an addon reports its OWN losses
|
|
@@ -62449,7 +62599,19 @@ var TlsStatusSchema = zod.z.object({
|
|
|
62449
62599
|
sans: zod.z.array(zod.z.string()),
|
|
62450
62600
|
caCertPem: zod.z.string().nullable(),
|
|
62451
62601
|
reissueError: zod.z.string().nullable(),
|
|
62452
|
-
restartRequired: zod.z.boolean()
|
|
62602
|
+
restartRequired: zod.z.boolean(),
|
|
62603
|
+
/** An uploaded certificate is served but no CA is kept for it and it is not publicly signed (D873). */
|
|
62604
|
+
caMissing: zod.z.boolean(),
|
|
62605
|
+
/** Does the hub's own generated CA carry a critical name constraint? `null` while it has none. */
|
|
62606
|
+
localCaConstrained: zod.z.boolean().nullable(),
|
|
62607
|
+
/** ISO time the generated CA was replaced by a constrained one; devices must re-download it. */
|
|
62608
|
+
caReplacedAt: zod.z.string().nullable(),
|
|
62609
|
+
/** The uploaded certificate kept on disk, selectable again after "Revert to generated". */
|
|
62610
|
+
storedUpload: zod.z.object({
|
|
62611
|
+
leafFingerprintSha256: zod.z.string(),
|
|
62612
|
+
validTo: zod.z.string(),
|
|
62613
|
+
hasCa: zod.z.boolean()
|
|
62614
|
+
}).nullable()
|
|
62453
62615
|
});
|
|
62454
62616
|
var localNetworkCapability = {
|
|
62455
62617
|
name: "local-network",
|
|
@@ -62643,7 +62805,10 @@ var localNetworkCapability = {
|
|
|
62643
62805
|
kind: "mutation",
|
|
62644
62806
|
auth: "admin"
|
|
62645
62807
|
}),
|
|
62646
|
-
/**
|
|
62808
|
+
/**
|
|
62809
|
+
* Replace the served material with operator-supplied PEMs. A certificate that does not lead
|
|
62810
|
+
* to a public CA must come with its CA certificate, validated and kept for Download CA (D873).
|
|
62811
|
+
*/
|
|
62647
62812
|
uploadCertificate: require_sleep.method(zod.z.object({
|
|
62648
62813
|
certPem: zod.z.string().min(1),
|
|
62649
62814
|
keyPem: zod.z.string().min(1),
|
|
@@ -62654,7 +62819,14 @@ var localNetworkCapability = {
|
|
|
62654
62819
|
}),
|
|
62655
62820
|
/** The local CA PEM, or empty when there is none to download. */
|
|
62656
62821
|
downloadCa: require_sleep.method(zod.z.void(), zod.z.object({ pem: zod.z.string() })),
|
|
62657
|
-
/**
|
|
62822
|
+
/**
|
|
62823
|
+
* Serve the kept upload again after "Revert to generated" (D873). Refused when none is kept.
|
|
62824
|
+
*/
|
|
62825
|
+
useStoredUploadedCertificate: require_sleep.method(zod.z.void(), TlsStatusSchema, {
|
|
62826
|
+
kind: "mutation",
|
|
62827
|
+
auth: "admin"
|
|
62828
|
+
}),
|
|
62829
|
+
/** Return to the generated local CA. The uploaded certificate stays stored (D873). */
|
|
62658
62830
|
revertToGeneratedCertificate: require_sleep.method(zod.z.void(), TlsStatusSchema, {
|
|
62659
62831
|
kind: "mutation",
|
|
62660
62832
|
auth: "admin"
|
|
@@ -70244,10 +70416,20 @@ var ServerNameInfoSchema = zod.z.object({
|
|
|
70244
70416
|
/** `true` when nobody named the hub: `name` is the machine hostname. */
|
|
70245
70417
|
isDefault: zod.z.boolean()
|
|
70246
70418
|
});
|
|
70247
|
-
/**
|
|
70419
|
+
/** What an unset name shows when the hostname says nothing about the hub. */
|
|
70420
|
+
var SERVER_NAME_FALLBACK = "CamStack";
|
|
70421
|
+
/** A container id: Docker's default hostname (12 hex chars, or the full 64). */
|
|
70422
|
+
var CONTAINER_ID_PATTERN = /^(?:[0-9a-f]{12}|[0-9a-f]{64})$/;
|
|
70423
|
+
/**
|
|
70424
|
+
* The hostname without its domain (`nas.lan.example` becomes `nas`). A hostname
|
|
70425
|
+
* that names nothing (empty, `localhost`, a container id) yields
|
|
70426
|
+
* {@link SERVER_NAME_FALLBACK}.
|
|
70427
|
+
*/
|
|
70248
70428
|
function shortHostname(hostname) {
|
|
70249
70429
|
const first = hostname.trim().split(".")[0] ?? "";
|
|
70250
|
-
|
|
70430
|
+
if (first.length === 0 || first.toLowerCase() === "localhost") return SERVER_NAME_FALLBACK;
|
|
70431
|
+
if (CONTAINER_ID_PATTERN.test(first)) return SERVER_NAME_FALLBACK;
|
|
70432
|
+
return first;
|
|
70251
70433
|
}
|
|
70252
70434
|
/**
|
|
70253
70435
|
* Resolve a stored value (whatever the row held, `undefined` when unset) and the
|
|
@@ -78125,6 +78307,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
78125
78307
|
addonId: null,
|
|
78126
78308
|
access: "create"
|
|
78127
78309
|
},
|
|
78310
|
+
"deviceManager.cleanupDeletedDevicesData": {
|
|
78311
|
+
capName: "device-manager",
|
|
78312
|
+
capScope: "system",
|
|
78313
|
+
addonId: null,
|
|
78314
|
+
access: "create"
|
|
78315
|
+
},
|
|
78128
78316
|
"deviceManager.createDevice": {
|
|
78129
78317
|
capName: "device-manager",
|
|
78130
78318
|
capScope: "system",
|
|
@@ -78305,6 +78493,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
78305
78493
|
addonId: null,
|
|
78306
78494
|
access: "view"
|
|
78307
78495
|
},
|
|
78496
|
+
"deviceManager.listDeletedSince": {
|
|
78497
|
+
capName: "device-manager",
|
|
78498
|
+
capScope: "system",
|
|
78499
|
+
addonId: null,
|
|
78500
|
+
access: "view"
|
|
78501
|
+
},
|
|
78308
78502
|
"deviceManager.listDeviceIdsByCaps": {
|
|
78309
78503
|
capName: "device-manager",
|
|
78310
78504
|
capScope: "system",
|
|
@@ -78713,6 +78907,18 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
78713
78907
|
addonId: null,
|
|
78714
78908
|
access: "create"
|
|
78715
78909
|
},
|
|
78910
|
+
"deviceRemovalHook.listDeviceData": {
|
|
78911
|
+
capName: "device-removal-hook",
|
|
78912
|
+
capScope: "system",
|
|
78913
|
+
addonId: null,
|
|
78914
|
+
access: "view"
|
|
78915
|
+
},
|
|
78916
|
+
"deviceRemovalHook.onDeviceRemoved": {
|
|
78917
|
+
capName: "device-removal-hook",
|
|
78918
|
+
capScope: "system",
|
|
78919
|
+
addonId: null,
|
|
78920
|
+
access: "create"
|
|
78921
|
+
},
|
|
78716
78922
|
"deviceState.claimFields": {
|
|
78717
78923
|
capName: "device-state",
|
|
78718
78924
|
capScope: "system",
|
|
@@ -79145,6 +79351,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
79145
79351
|
addonId: null,
|
|
79146
79352
|
access: "delete"
|
|
79147
79353
|
},
|
|
79354
|
+
"keychain.deleteDeviceScope": {
|
|
79355
|
+
capName: "keychain",
|
|
79356
|
+
capScope: "system",
|
|
79357
|
+
addonId: null,
|
|
79358
|
+
access: "delete"
|
|
79359
|
+
},
|
|
79148
79360
|
"keychain.getState": {
|
|
79149
79361
|
capName: "keychain",
|
|
79150
79362
|
capScope: "system",
|
|
@@ -79583,6 +79795,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
79583
79795
|
addonId: null,
|
|
79584
79796
|
access: "create"
|
|
79585
79797
|
},
|
|
79798
|
+
"localNetwork.useStoredUploadedCertificate": {
|
|
79799
|
+
capName: "local-network",
|
|
79800
|
+
capScope: "system",
|
|
79801
|
+
addonId: null,
|
|
79802
|
+
access: "create"
|
|
79803
|
+
},
|
|
79586
79804
|
"lockControl.getStatus": {
|
|
79587
79805
|
capName: "lock-control",
|
|
79588
79806
|
capScope: "device",
|
|
@@ -84438,6 +84656,7 @@ var KNOWN_CAP_NAMES = [
|
|
|
84438
84656
|
"device-manager",
|
|
84439
84657
|
"device-ops",
|
|
84440
84658
|
"device-provider",
|
|
84659
|
+
"device-removal-hook",
|
|
84441
84660
|
"device-state",
|
|
84442
84661
|
"device-status",
|
|
84443
84662
|
"doorbell",
|
|
@@ -84676,6 +84895,7 @@ var SYSTEM_CAP_NAMES = [
|
|
|
84676
84895
|
"device-history",
|
|
84677
84896
|
"device-manager",
|
|
84678
84897
|
"device-provider",
|
|
84898
|
+
"device-removal-hook",
|
|
84679
84899
|
"device-state",
|
|
84680
84900
|
"embedding-encoder",
|
|
84681
84901
|
"face-gallery",
|
|
@@ -85484,7 +85704,7 @@ function resolveDeviceProfile(features) {
|
|
|
85484
85704
|
//#endregion
|
|
85485
85705
|
//#region src/device/path-util.ts
|
|
85486
85706
|
/** Returns true when `x` is a non-null, non-array plain object. */
|
|
85487
|
-
function isRecord(x) {
|
|
85707
|
+
function isRecord$1(x) {
|
|
85488
85708
|
return x !== null && typeof x === "object" && !Array.isArray(x);
|
|
85489
85709
|
}
|
|
85490
85710
|
/** Read a dot-path (`a.b.c`) out of an object. Returns `undefined` for any
|
|
@@ -85493,7 +85713,7 @@ function getByPath(obj, path) {
|
|
|
85493
85713
|
const parts = path.split(".");
|
|
85494
85714
|
let cur = obj;
|
|
85495
85715
|
for (const part of parts) {
|
|
85496
|
-
if (!isRecord(cur)) return void 0;
|
|
85716
|
+
if (!isRecord$1(cur)) return void 0;
|
|
85497
85717
|
cur = cur[part];
|
|
85498
85718
|
}
|
|
85499
85719
|
return cur;
|
|
@@ -85515,7 +85735,7 @@ function setByPath(obj, path, value) {
|
|
|
85515
85735
|
const head = path.slice(0, dotIndex);
|
|
85516
85736
|
const tail = path.slice(dotIndex + 1);
|
|
85517
85737
|
const child = obj[head];
|
|
85518
|
-
const childObj = isRecord(child) ? child : {};
|
|
85738
|
+
const childObj = isRecord$1(child) ? child : {};
|
|
85519
85739
|
return {
|
|
85520
85740
|
...obj,
|
|
85521
85741
|
[head]: setByPath(childObj, tail, value)
|
|
@@ -86708,6 +86928,7 @@ var CAPABILITY_NAMES = {
|
|
|
86708
86928
|
deviceManager: "device-manager",
|
|
86709
86929
|
deviceOps: "device-ops",
|
|
86710
86930
|
deviceProvider: "device-provider",
|
|
86931
|
+
deviceRemovalHook: "device-removal-hook",
|
|
86711
86932
|
deviceState: "device-state",
|
|
86712
86933
|
deviceStatus: "device-status",
|
|
86713
86934
|
doorbell: "doorbell",
|
|
@@ -87058,6 +87279,10 @@ var CAPABILITY_ROUTER_KEYS = [
|
|
|
87058
87279
|
key: "deviceProvider",
|
|
87059
87280
|
name: "device-provider"
|
|
87060
87281
|
},
|
|
87282
|
+
{
|
|
87283
|
+
key: "deviceRemovalHook",
|
|
87284
|
+
name: "device-removal-hook"
|
|
87285
|
+
},
|
|
87061
87286
|
{
|
|
87062
87287
|
key: "deviceState",
|
|
87063
87288
|
name: "device-state"
|
|
@@ -87587,6 +87812,7 @@ var ALL_CAPABILITY_DEFINITIONS = [
|
|
|
87587
87812
|
deviceManagerCapability,
|
|
87588
87813
|
require_sleep.deviceOpsCapability,
|
|
87589
87814
|
deviceProviderCapability,
|
|
87815
|
+
deviceRemovalHookCapability,
|
|
87590
87816
|
deviceStateCapability,
|
|
87591
87817
|
deviceStatusCapability,
|
|
87592
87818
|
doorbellCapability,
|
|
@@ -88482,6 +88708,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
|
|
|
88482
88708
|
form: "single",
|
|
88483
88709
|
optional: false
|
|
88484
88710
|
}],
|
|
88711
|
+
"deviceRemovalHook.onDeviceRemoved": [{
|
|
88712
|
+
name: "deviceId",
|
|
88713
|
+
form: "single",
|
|
88714
|
+
optional: false
|
|
88715
|
+
}],
|
|
88485
88716
|
"deviceState.claimFields": [{
|
|
88486
88717
|
name: "deviceId",
|
|
88487
88718
|
form: "single",
|
|
@@ -88671,6 +88902,11 @@ var METHOD_DEVICE_SELECTORS = Object.freeze({
|
|
|
88671
88902
|
form: "single",
|
|
88672
88903
|
optional: false
|
|
88673
88904
|
}],
|
|
88905
|
+
"keychain.deleteDeviceScope": [{
|
|
88906
|
+
name: "deviceId",
|
|
88907
|
+
form: "single",
|
|
88908
|
+
optional: false
|
|
88909
|
+
}],
|
|
88674
88910
|
"lawnMowerControl.dock": [{
|
|
88675
88911
|
name: "deviceId",
|
|
88676
88912
|
form: "single",
|
|
@@ -90425,6 +90661,7 @@ var SYSTEM_SCOPE_DEVICE_METHODS = [
|
|
|
90425
90661
|
"deviceManager.updateConfig",
|
|
90426
90662
|
"deviceManager.updateDeviceField",
|
|
90427
90663
|
"deviceManager.updateDeviceFieldsBatch",
|
|
90664
|
+
"deviceRemovalHook.onDeviceRemoved",
|
|
90428
90665
|
"deviceState.claimFields",
|
|
90429
90666
|
"deviceState.getCapSlice",
|
|
90430
90667
|
"deviceState.getNativeCapSlice",
|
|
@@ -90434,6 +90671,7 @@ var SYSTEM_SCOPE_DEVICE_METHODS = [
|
|
|
90434
90671
|
"deviceState.setCapSlice",
|
|
90435
90672
|
"faceGallery.getFaceByTrack",
|
|
90436
90673
|
"faceGallery.listRecentFaces",
|
|
90674
|
+
"keychain.deleteDeviceScope",
|
|
90437
90675
|
"networkQuality.getDeviceStats",
|
|
90438
90676
|
"networkQuality.reportClientStats",
|
|
90439
90677
|
"notificationRules.getAlarmSensors",
|
|
@@ -91633,6 +91871,8 @@ function createSystemProxy(api) {
|
|
|
91633
91871
|
getChildren: (input) => dispatch("deviceManager", "getChildren", "query", input),
|
|
91634
91872
|
getChildrenBatch: (input) => dispatch("deviceManager", "getChildrenBatch", "query", input),
|
|
91635
91873
|
getLinkedDevicesBatch: (input) => dispatch("deviceManager", "getLinkedDevicesBatch", "query", input),
|
|
91874
|
+
listDeletedSince: (input) => dispatch("deviceManager", "listDeletedSince", "query", input),
|
|
91875
|
+
cleanupDeletedDevicesData: (input) => dispatch("deviceManager", "cleanupDeletedDevicesData", "mutation", input),
|
|
91636
91876
|
removeByIntegration: (input) => dispatch("deviceManager", "removeByIntegration", "mutation", input),
|
|
91637
91877
|
getBindingsBatch: (input) => dispatch("deviceManager", "getBindingsBatch", "query", input),
|
|
91638
91878
|
getAllBindings: (input) => dispatch("deviceManager", "getAllBindings", "query", input),
|
|
@@ -91765,6 +92005,7 @@ function createSystemProxy(api) {
|
|
|
91765
92005
|
regenerateCertificate: (input) => dispatch("localNetwork", "regenerateCertificate", "mutation", input),
|
|
91766
92006
|
uploadCertificate: (input) => dispatch("localNetwork", "uploadCertificate", "mutation", input),
|
|
91767
92007
|
downloadCa: (input) => dispatch("localNetwork", "downloadCa", "query", input),
|
|
92008
|
+
useStoredUploadedCertificate: (input) => dispatch("localNetwork", "useStoredUploadedCertificate", "mutation", input),
|
|
91768
92009
|
revertToGeneratedCertificate: (input) => dispatch("localNetwork", "revertToGeneratedCertificate", "mutation", input)
|
|
91769
92010
|
},
|
|
91770
92011
|
meshNetwork: {
|
|
@@ -96537,6 +96778,91 @@ function eventKindLabel(kind, locale) {
|
|
|
96537
96778
|
return isEventKindLabelKey(key) ? EVENT_KIND_LABELS[key][locale] : kind;
|
|
96538
96779
|
}
|
|
96539
96780
|
//#endregion
|
|
96781
|
+
//#region src/i18n/translation.ts
|
|
96782
|
+
/**
|
|
96783
|
+
* Server-side translation primitives (D863) - pure, zod only.
|
|
96784
|
+
*
|
|
96785
|
+
* A catalog is a FLAT `Record<key, string>` per (namespace, language). A
|
|
96786
|
+
* reference is `"<namespace>:<key>"`; the English text always travels next to
|
|
96787
|
+
* it (`label` beside `labelKey`), so a missing key or an unknown language is
|
|
96788
|
+
* the English text, never a blank or a raw key.
|
|
96789
|
+
*/
|
|
96790
|
+
/** The languages a catalog may be written in. English is the mandatory base. */
|
|
96791
|
+
var CatalogLangSchema = AppPageLangSchema;
|
|
96792
|
+
var CATALOG_LANGS = CatalogLangSchema.options;
|
|
96793
|
+
var DEFAULT_CATALOG_LANG = "en";
|
|
96794
|
+
/** One catalog file: flat key to text. A file of any other shape is rejected whole. */
|
|
96795
|
+
var CatalogFileSchema = zod.z.record(zod.z.string().min(1), zod.z.string());
|
|
96796
|
+
/** Fills `{name}` placeholders; an unknown placeholder is left as written. */
|
|
96797
|
+
function interpolate(template, params) {
|
|
96798
|
+
if (params === void 0) return template;
|
|
96799
|
+
return template.replace(/\{(\w+)\}/g, (whole, name) => {
|
|
96800
|
+
const value = params[name];
|
|
96801
|
+
return value === void 0 ? whole : String(value);
|
|
96802
|
+
});
|
|
96803
|
+
}
|
|
96804
|
+
/** Splits `"ns:key"`; `null` when the reference has no namespace. */
|
|
96805
|
+
function splitTranslationRef(ref) {
|
|
96806
|
+
const at = ref.indexOf(":");
|
|
96807
|
+
if (at <= 0 || at === ref.length - 1) return null;
|
|
96808
|
+
return {
|
|
96809
|
+
ns: ref.slice(0, at),
|
|
96810
|
+
key: ref.slice(at + 1)
|
|
96811
|
+
};
|
|
96812
|
+
}
|
|
96813
|
+
function isRecord(value) {
|
|
96814
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
96815
|
+
}
|
|
96816
|
+
var KEYED_TEXTS = [
|
|
96817
|
+
{
|
|
96818
|
+
keyField: "labelKey",
|
|
96819
|
+
textField: "label"
|
|
96820
|
+
},
|
|
96821
|
+
{
|
|
96822
|
+
keyField: "descriptionKey",
|
|
96823
|
+
textField: "description"
|
|
96824
|
+
},
|
|
96825
|
+
{
|
|
96826
|
+
keyField: "titleKey",
|
|
96827
|
+
textField: "title"
|
|
96828
|
+
}
|
|
96829
|
+
];
|
|
96830
|
+
/**
|
|
96831
|
+
* Returns `value` with every `labelKey` / `descriptionKey` / `titleKey` that
|
|
96832
|
+
* the catalog can resolve replaced into `label` / `description` / `title`.
|
|
96833
|
+
* Pure: the input is never mutated; a subtree with nothing to change is
|
|
96834
|
+
* returned as the SAME object. A key the catalog does not hold keeps the
|
|
96835
|
+
* English text that sits next to it.
|
|
96836
|
+
*/
|
|
96837
|
+
function localizeConfigTree(value, lookup) {
|
|
96838
|
+
if (Array.isArray(value)) {
|
|
96839
|
+
let changed = false;
|
|
96840
|
+
const next = value.map((item) => {
|
|
96841
|
+
const out = localizeConfigTree(item, lookup);
|
|
96842
|
+
if (out !== item) changed = true;
|
|
96843
|
+
return out;
|
|
96844
|
+
});
|
|
96845
|
+
return changed ? next : value;
|
|
96846
|
+
}
|
|
96847
|
+
if (!isRecord(value)) return value;
|
|
96848
|
+
const patch = {};
|
|
96849
|
+
for (const [k, v] of Object.entries(value)) {
|
|
96850
|
+
const out = localizeConfigTree(v, lookup);
|
|
96851
|
+
if (out !== v) patch[k] = out;
|
|
96852
|
+
}
|
|
96853
|
+
for (const { keyField, textField } of KEYED_TEXTS) {
|
|
96854
|
+
const ref = value[keyField];
|
|
96855
|
+
if (typeof ref !== "string") continue;
|
|
96856
|
+
const parts = splitTranslationRef(ref);
|
|
96857
|
+
const text = parts === null ? void 0 : lookup(parts.ns, parts.key);
|
|
96858
|
+
if (text !== void 0) patch[textField] = text;
|
|
96859
|
+
}
|
|
96860
|
+
return Object.keys(patch).length === 0 ? value : {
|
|
96861
|
+
...value,
|
|
96862
|
+
...patch
|
|
96863
|
+
};
|
|
96864
|
+
}
|
|
96865
|
+
//#endregion
|
|
96540
96866
|
//#region src/notification/timelapse-rule.ts
|
|
96541
96867
|
/**
|
|
96542
96868
|
* TimelapseRule — the STANDALONE scheduled timelapse producer's rule model.
|
|
@@ -96946,7 +97272,11 @@ var REMOVED_MODEL_IDS = {
|
|
|
96946
97272
|
"face-embedding": ["arcface-r100", "inception-resnet-v1"],
|
|
96947
97273
|
"plate-detection": ["yolov8n-plate"],
|
|
96948
97274
|
"plate-ocr": ["vgg-english-g2"],
|
|
96949
|
-
"clip-embedding": [
|
|
97275
|
+
"clip-embedding": [
|
|
97276
|
+
"mobileclip-s0",
|
|
97277
|
+
"mobileclip-s1",
|
|
97278
|
+
"mobileclip-s2"
|
|
97279
|
+
],
|
|
96950
97280
|
"package-detection": ["yolov8n-package"],
|
|
96951
97281
|
"bird-classifier": ["bird-classifier-aiy-edgetpu", "bird-nabirds-404"],
|
|
96952
97282
|
"animal-classifier": ["animals-10"],
|
|
@@ -98809,6 +99139,48 @@ function slideInsideFrame(rect, frameWidth, frameHeight) {
|
|
|
98809
99139
|
};
|
|
98810
99140
|
}
|
|
98811
99141
|
//#endregion
|
|
99142
|
+
//#region src/pipeline/face-rescore-schedule.ts
|
|
99143
|
+
/**
|
|
99144
|
+
* The cadence of the automatic whole-archive face rescore (D866).
|
|
99145
|
+
*
|
|
99146
|
+
* One cluster-wide knob in `pipeline-orchestrator`'s GLOBAL settings, read by
|
|
99147
|
+
* `pipeline-analytics` over the hub-routed `addon-settings` cap on every tick.
|
|
99148
|
+
* It lives here for the same reason the detail-crop convention does: the
|
|
99149
|
+
* writer (orchestrator) and the reader (analytics) are different addons, they
|
|
99150
|
+
* never import each other, and a key copied by hand is how a setting silently
|
|
99151
|
+
* stops arriving.
|
|
99152
|
+
*/
|
|
99153
|
+
var FACE_RESCORE_SECTION_ID = "face-rescore";
|
|
99154
|
+
var FACE_RESCORE_INTERVAL_KEY = "faceRescoreIntervalMinutes";
|
|
99155
|
+
/** Slider bounds. `0` is "disabled"; anything in 1..9 is raised to `min`. */
|
|
99156
|
+
var FACE_RESCORE_INTERVAL_FIELD = {
|
|
99157
|
+
min: 0,
|
|
99158
|
+
max: 1440,
|
|
99159
|
+
step: 5,
|
|
99160
|
+
default: 60
|
|
99161
|
+
};
|
|
99162
|
+
/** The smallest period that actually runs; below it (but above 0) is clamped up. */
|
|
99163
|
+
var FACE_RESCORE_INTERVAL_MIN_RUNNING = 10;
|
|
99164
|
+
/**
|
|
99165
|
+
* Narrow a stored value to minutes. `0` ⇒ disabled; a positive value under
|
|
99166
|
+
* {@link FACE_RESCORE_INTERVAL_MIN_RUNNING} is raised to it; junk or absent ⇒
|
|
99167
|
+
* the default (an unreadable setting must not switch the job off nor storm it).
|
|
99168
|
+
*/
|
|
99169
|
+
function readFaceRescoreIntervalMinutes(value) {
|
|
99170
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return FACE_RESCORE_INTERVAL_FIELD.default;
|
|
99171
|
+
if (value === 0) return 0;
|
|
99172
|
+
return Math.min(FACE_RESCORE_INTERVAL_FIELD.max, Math.max(10, Math.floor(value)));
|
|
99173
|
+
}
|
|
99174
|
+
/** The interval out of a hydrated payload; a `null` view (mid-boot) is the default. */
|
|
99175
|
+
function pickFaceRescoreIntervalMinutes(view) {
|
|
99176
|
+
if (view === null) return FACE_RESCORE_INTERVAL_FIELD.default;
|
|
99177
|
+
for (const section of view.sections) for (const entry of section.fields) {
|
|
99178
|
+
if (typeof entry !== "object" || entry === null || !("key" in entry)) continue;
|
|
99179
|
+
if (entry.key === "faceRescoreIntervalMinutes") return readFaceRescoreIntervalMinutes("value" in entry ? entry.value : void 0);
|
|
99180
|
+
}
|
|
99181
|
+
return FACE_RESCORE_INTERVAL_FIELD.default;
|
|
99182
|
+
}
|
|
99183
|
+
//#endregion
|
|
98812
99184
|
//#region src/pipeline/native-lease.ts
|
|
98813
99185
|
/**
|
|
98814
99186
|
* THE native-frame **lease** knobs — hold depth, RAM budget, demand window and
|
|
@@ -100644,6 +101016,78 @@ function enumerateInferenceDevices(hw) {
|
|
|
100644
101016
|
return out;
|
|
100645
101017
|
}
|
|
100646
101018
|
//#endregion
|
|
101019
|
+
//#region src/device/device-removal-reconcile.ts
|
|
101020
|
+
/** How often an implementer re-asks for tombstones after its start-up pass. */
|
|
101021
|
+
var REMOVAL_RECONCILE_INTERVAL_MS = 360 * 60 * 1e3;
|
|
101022
|
+
/** One reconcile pass over every tombstone inside the retention window. */
|
|
101023
|
+
async function reconcileRemovedDevices(opts) {
|
|
101024
|
+
const now = opts.now ?? (() => Date.now());
|
|
101025
|
+
const api = opts.api;
|
|
101026
|
+
if (api === void 0) {
|
|
101027
|
+
opts.logger.warn("device removal reconcile skipped — no device-manager api");
|
|
101028
|
+
return {
|
|
101029
|
+
read: false,
|
|
101030
|
+
applied: 0,
|
|
101031
|
+
failed: 0
|
|
101032
|
+
};
|
|
101033
|
+
}
|
|
101034
|
+
let tombstones;
|
|
101035
|
+
try {
|
|
101036
|
+
tombstones = await api.deviceManager.listDeletedSince.query({ sinceMs: now() - DEVICE_TOMBSTONE_RETENTION_MS });
|
|
101037
|
+
} catch (err) {
|
|
101038
|
+
opts.logger.warn("device removal reconcile skipped — tombstones unreadable, nothing deleted", { meta: { error: require_err_msg.errMsg(err) } });
|
|
101039
|
+
return {
|
|
101040
|
+
read: false,
|
|
101041
|
+
applied: 0,
|
|
101042
|
+
failed: 0
|
|
101043
|
+
};
|
|
101044
|
+
}
|
|
101045
|
+
let applied = 0;
|
|
101046
|
+
let failed = 0;
|
|
101047
|
+
for (const tombstone of tombstones) try {
|
|
101048
|
+
const result = await opts.remove(tombstone);
|
|
101049
|
+
applied += 1;
|
|
101050
|
+
if (Object.values(result.counts).reduce((sum, n) => sum + n, 0) > 0) opts.logger.info("device removal reconcile cleaned a missed deletion", {
|
|
101051
|
+
tags: { deviceId: tombstone.deviceId },
|
|
101052
|
+
meta: {
|
|
101053
|
+
counts: result.counts,
|
|
101054
|
+
deletedAt: tombstone.deletedAt
|
|
101055
|
+
}
|
|
101056
|
+
});
|
|
101057
|
+
} catch (err) {
|
|
101058
|
+
failed += 1;
|
|
101059
|
+
opts.logger.warn("device removal reconcile failed for a device — retried next pass", {
|
|
101060
|
+
tags: { deviceId: tombstone.deviceId },
|
|
101061
|
+
meta: { error: require_err_msg.errMsg(err) }
|
|
101062
|
+
});
|
|
101063
|
+
}
|
|
101064
|
+
return {
|
|
101065
|
+
read: true,
|
|
101066
|
+
applied,
|
|
101067
|
+
failed
|
|
101068
|
+
};
|
|
101069
|
+
}
|
|
101070
|
+
/**
|
|
101071
|
+
* Run the reconcile now and then periodically. Returns the disposer. The timer
|
|
101072
|
+
* is unref'd and a pass never overlaps the previous one.
|
|
101073
|
+
*/
|
|
101074
|
+
function armRemovalReconcile(opts) {
|
|
101075
|
+
let running = false;
|
|
101076
|
+
const pass = () => {
|
|
101077
|
+
if (running) return;
|
|
101078
|
+
running = true;
|
|
101079
|
+
reconcileRemovedDevices(opts).catch((err) => {
|
|
101080
|
+
opts.logger.warn("device removal reconcile pass crashed", { meta: { error: require_err_msg.errMsg(err) } });
|
|
101081
|
+
}).finally(() => {
|
|
101082
|
+
running = false;
|
|
101083
|
+
});
|
|
101084
|
+
};
|
|
101085
|
+
pass();
|
|
101086
|
+
const timer = setInterval(pass, REMOVAL_RECONCILE_INTERVAL_MS);
|
|
101087
|
+
timer.unref?.();
|
|
101088
|
+
return () => clearInterval(timer);
|
|
101089
|
+
}
|
|
101090
|
+
//#endregion
|
|
100647
101091
|
exports.ACCESSORY_LABEL = ACCESSORY_LABEL;
|
|
100648
101092
|
exports.ACCESS_ROLES = ACCESS_ROLES;
|
|
100649
101093
|
exports.AGENT_MDNS_QUERY_NAME = AGENT_MDNS_QUERY_NAME;
|
|
@@ -100823,6 +101267,7 @@ exports.CAPABILITY_ROUTER_KEYS = CAPABILITY_ROUTER_KEYS;
|
|
|
100823
101267
|
exports.CAP_NAMES_WITH_STATUS = CAP_NAMES_WITH_STATUS;
|
|
100824
101268
|
exports.CAP_NODE_PIN_CONTEXT_KEY = require_sleep.CAP_NODE_PIN_CONTEXT_KEY;
|
|
100825
101269
|
exports.CAP_PROVIDER_KIND_MAP = CAP_PROVIDER_KIND_MAP;
|
|
101270
|
+
exports.CATALOG_LANGS = CATALOG_LANGS;
|
|
100826
101271
|
exports.CLASS_MAP_MACRO_TARGETS = CLASS_MAP_MACRO_TARGETS;
|
|
100827
101272
|
exports.CLIP_BROKER_PACED_RATES = CLIP_BROKER_PACED_RATES;
|
|
100828
101273
|
exports.CLIP_PLAYBACK_OPTIONS = CLIP_PLAYBACK_OPTIONS;
|
|
@@ -100911,15 +101356,19 @@ exports.CameraSwitchIdSchema = CameraSwitchIdSchema;
|
|
|
100911
101356
|
exports.CameraSwitchSchema = CameraSwitchSchema;
|
|
100912
101357
|
exports.CameraSwitchUnavailableReasonSchema = CameraSwitchUnavailableReasonSchema;
|
|
100913
101358
|
exports.CameraSwitchWarningSchema = CameraSwitchWarningSchema;
|
|
101359
|
+
exports.CamstackError = require_sleep.CamstackError;
|
|
100914
101360
|
exports.CandidateQueryFilterSchema = CandidateQueryFilterSchema;
|
|
100915
101361
|
exports.CapScopeSchema = CapScopeSchema;
|
|
100916
101362
|
exports.CapabilityBindingsSchema = CapabilityBindingsSchema;
|
|
100917
101363
|
exports.CapacityFallbackSchema = CapacityFallbackSchema;
|
|
100918
101364
|
exports.CapacitySourceSchema = CapacitySourceSchema;
|
|
100919
101365
|
exports.CarbonMonoxideStatusSchema = CarbonMonoxideStatusSchema;
|
|
101366
|
+
exports.CatalogFileSchema = CatalogFileSchema;
|
|
101367
|
+
exports.CatalogLangSchema = CatalogLangSchema;
|
|
100920
101368
|
exports.ChargingStatus = require_err_msg.ChargingStatus;
|
|
100921
101369
|
exports.ClaimOutcomeSchema = ClaimOutcomeSchema;
|
|
100922
101370
|
exports.ClaimsListingSchema = ClaimsListingSchema;
|
|
101371
|
+
exports.CleanupDeletedDevicesResultSchema = CleanupDeletedDevicesResultSchema;
|
|
100923
101372
|
exports.ClearTrackRelationInputSchema = ClearTrackRelationInputSchema;
|
|
100924
101373
|
exports.ClearTrackRelationResultSchema = ClearTrackRelationResultSchema;
|
|
100925
101374
|
exports.ClientNetworkStatsSchema = ClientNetworkStatsSchema;
|
|
@@ -101044,6 +101493,7 @@ exports.DEFAULT_ADDON_PLACEMENT = DEFAULT_ADDON_PLACEMENT;
|
|
|
101044
101493
|
exports.DEFAULT_AUDIO_ANALYZER_CONFIG = DEFAULT_AUDIO_ANALYZER_CONFIG;
|
|
101045
101494
|
exports.DEFAULT_CAMERA_FPS = DEFAULT_CAMERA_FPS;
|
|
101046
101495
|
exports.DEFAULT_CAMERA_SENSOR_MODE = DEFAULT_CAMERA_SENSOR_MODE;
|
|
101496
|
+
exports.DEFAULT_CATALOG_LANG = DEFAULT_CATALOG_LANG;
|
|
101047
101497
|
exports.DEFAULT_CLUSTER_STEP_MODELS = DEFAULT_CLUSTER_STEP_MODELS;
|
|
101048
101498
|
exports.DEFAULT_CLUSTER_STEP_SETTINGS = DEFAULT_CLUSTER_STEP_SETTINGS;
|
|
101049
101499
|
exports.DEFAULT_CORE_BLOCK_ENTRY = DEFAULT_CORE_BLOCK_ENTRY;
|
|
@@ -101098,6 +101548,7 @@ exports.DEVICE_SETTINGS_CONTRIBUTION_METHODS = require_sleep.DEVICE_SETTINGS_CON
|
|
|
101098
101548
|
exports.DEVICE_SIGNATURE_MESSAGE_VERSION = DEVICE_SIGNATURE_MESSAGE_VERSION;
|
|
101099
101549
|
exports.DEVICE_STATE_READERS = DEVICE_STATE_READERS;
|
|
101100
101550
|
exports.DEVICE_STATUS_METHOD = require_sleep.DEVICE_STATUS_METHOD;
|
|
101551
|
+
exports.DEVICE_TOMBSTONE_RETENTION_MS = DEVICE_TOMBSTONE_RETENTION_MS;
|
|
101101
101552
|
exports.DEVICE_TYPE_CONTROL_KIND = DEVICE_TYPE_CONTROL_KIND;
|
|
101102
101553
|
exports.DEVICE_TYPE_DO_CAPS = DEVICE_TYPE_DO_CAPS;
|
|
101103
101554
|
exports.DEVICE_TYPE_INFO = DEVICE_TYPE_INFO;
|
|
@@ -101132,6 +101583,7 @@ exports.DeviceCodeSeveritySchema = DeviceCodeSeveritySchema;
|
|
|
101132
101583
|
exports.DeviceConfig = DeviceConfig;
|
|
101133
101584
|
exports.DeviceCredentialSchema = DeviceCredentialSchema;
|
|
101134
101585
|
exports.DeviceCredentialStatusSchema = DeviceCredentialStatusSchema;
|
|
101586
|
+
exports.DeviceDataEntrySchema = DeviceDataEntrySchema;
|
|
101135
101587
|
exports.DeviceDiscoveryStatusSchema = DeviceDiscoveryStatusSchema;
|
|
101136
101588
|
exports.DeviceEnrollProofSchema = DeviceEnrollProofSchema;
|
|
101137
101589
|
exports.DeviceExportExposeInputSchema = ExposeInputSchema;
|
|
@@ -101151,12 +101603,15 @@ exports.DeviceProofInputSchema = DeviceProofInputSchema;
|
|
|
101151
101603
|
exports.DeviceRecommendationSchema = DeviceRecommendationSchema;
|
|
101152
101604
|
exports.DeviceRefusalReasonSchema = DeviceRefusalReasonSchema;
|
|
101153
101605
|
exports.DeviceRefusalSchema = DeviceRefusalSchema;
|
|
101606
|
+
exports.DeviceRemovedInputSchema = DeviceRemovedInputSchema;
|
|
101607
|
+
exports.DeviceRemovedResultSchema = DeviceRemovedResultSchema;
|
|
101154
101608
|
exports.DeviceRestoreRetryScheduler = DeviceRestoreRetryScheduler;
|
|
101155
101609
|
exports.DeviceRole = require_err_msg.DeviceRole;
|
|
101156
101610
|
exports.DeviceRuntimeState = DeviceRuntimeState;
|
|
101157
101611
|
exports.DeviceSelectorSchema = DeviceSelectorSchema;
|
|
101158
101612
|
exports.DeviceSignaturePurposeSchema = DeviceSignaturePurposeSchema;
|
|
101159
101613
|
exports.DeviceStatusSchema = DeviceStatusSchema;
|
|
101614
|
+
exports.DeviceTombstoneSchema = DeviceTombstoneSchema;
|
|
101160
101615
|
exports.DeviceType = require_err_msg.DeviceType;
|
|
101161
101616
|
exports.DiagnosticIdSchema = DiagnosticIdSchema;
|
|
101162
101617
|
exports.DiagnosticWindowPatchSchema = DiagnosticWindowPatchSchema;
|
|
@@ -101211,6 +101666,8 @@ exports.EnrichedWidgetMetadataSchema = EnrichedWidgetMetadataSchema;
|
|
|
101211
101666
|
exports.EnrollSelfInputSchema = EnrollSelfInputSchema;
|
|
101212
101667
|
exports.EnumSensorDateTimeFormatSchema = EnumSensorDateTimeFormatSchema;
|
|
101213
101668
|
exports.EnumSensorStatusSchema = EnumSensorStatusSchema;
|
|
101669
|
+
exports.ErrorCodeSchema = require_sleep.ErrorCodeSchema;
|
|
101670
|
+
exports.ErrorI18nPayloadSchema = require_sleep.ErrorI18nPayloadSchema;
|
|
101214
101671
|
exports.EventCategory = require_event_category.EventCategory;
|
|
101215
101672
|
exports.EventDensityBucketSchema = EventDensityBucketSchema;
|
|
101216
101673
|
exports.EventDensityForDeviceSchema = EventDensityForDeviceSchema;
|
|
@@ -101267,6 +101724,10 @@ exports.ExtensionSourceHealthSchema = ExtensionSourceHealthSchema;
|
|
|
101267
101724
|
exports.ExtensionSourceSchema = ExtensionSourceSchema;
|
|
101268
101725
|
exports.ExternalIdentityKeySchema = ExternalIdentityKeySchema;
|
|
101269
101726
|
exports.ExternalIdentitySchema = ExternalIdentitySchema;
|
|
101727
|
+
exports.FACE_RESCORE_INTERVAL_FIELD = FACE_RESCORE_INTERVAL_FIELD;
|
|
101728
|
+
exports.FACE_RESCORE_INTERVAL_KEY = FACE_RESCORE_INTERVAL_KEY;
|
|
101729
|
+
exports.FACE_RESCORE_INTERVAL_MIN_RUNNING = FACE_RESCORE_INTERVAL_MIN_RUNNING;
|
|
101730
|
+
exports.FACE_RESCORE_SECTION_ID = FACE_RESCORE_SECTION_ID;
|
|
101270
101731
|
exports.FEEDER_EXAMPLE_ADDON_ID = FEEDER_EXAMPLE_ADDON_ID;
|
|
101271
101732
|
exports.FEEDER_EXAMPLE_HA_DEVICE_ID = FEEDER_EXAMPLE_HA_DEVICE_ID;
|
|
101272
101733
|
exports.FFMPEG_PATH_ENV = require_composition.FFMPEG_PATH_ENV;
|
|
@@ -101843,6 +102304,7 @@ exports.OpsLogOpSchema = OpsLogOpSchema;
|
|
|
101843
102304
|
exports.OpsLogQueryInputSchema = OpsLogQueryInputSchema;
|
|
101844
102305
|
exports.OpsLogReasonSchema = OpsLogReasonSchema;
|
|
101845
102306
|
exports.OrchestratorMetricsSchema = OrchestratorMetricsSchema;
|
|
102307
|
+
exports.OrphanDeviceDataSchema = OrphanDeviceDataSchema;
|
|
101846
102308
|
exports.OsdNamedTemplateSchema = OsdNamedTemplateSchema;
|
|
101847
102309
|
exports.OsdOverlayKindEnum = OsdOverlayKindEnum;
|
|
101848
102310
|
exports.OsdOverlayPatchSchema = OsdOverlayPatchSchema;
|
|
@@ -101950,6 +102412,7 @@ exports.RECORDING_SOURCE_CAMSTACK = RECORDING_SOURCE_CAMSTACK;
|
|
|
101950
102412
|
exports.RECORDING_SOURCE_CAMSTACK_ADDON = RECORDING_SOURCE_CAMSTACK_ADDON;
|
|
101951
102413
|
exports.RECORDING_TIMELINE_BATCH_MAX = RECORDING_TIMELINE_BATCH_MAX;
|
|
101952
102414
|
exports.REDACTED_SECRET = require_sleep.REDACTED_SECRET;
|
|
102415
|
+
exports.REMOVAL_RECONCILE_INTERVAL_MS = REMOVAL_RECONCILE_INTERVAL_MS;
|
|
101953
102416
|
exports.REMOVED_MODEL_IDS = REMOVED_MODEL_IDS;
|
|
101954
102417
|
exports.RESERVED_BINDING_NAMES = require_composition.RESERVED_BINDING_NAMES;
|
|
101955
102418
|
exports.RESERVED_COLLECTION_SOURCES = RESERVED_COLLECTION_SOURCES;
|
|
@@ -102458,6 +102921,7 @@ exports.applyModeDeviceListEdit = applyModeDeviceListEdit;
|
|
|
102458
102921
|
exports.applyModelBoundSettings = applyModelBoundSettings;
|
|
102459
102922
|
exports.applyNonBlockingEdit = applyNonBlockingEdit;
|
|
102460
102923
|
exports.applySecureOnArmEdit = applySecureOnArmEdit;
|
|
102924
|
+
exports.armRemovalReconcile = armRemovalReconcile;
|
|
102461
102925
|
exports.arrayItemFieldPath = require_sleep.arrayItemFieldPath;
|
|
102462
102926
|
exports.asBoolean = require_sleep.asBoolean;
|
|
102463
102927
|
exports.asJsonArray = require_sleep.asJsonArray;
|
|
@@ -102663,6 +103127,7 @@ exports.deviceMatchesProfile = deviceMatchesProfile;
|
|
|
102663
103127
|
exports.deviceOpsCapability = require_sleep.deviceOpsCapability;
|
|
102664
103128
|
exports.deviceProviderCapability = deviceProviderCapability;
|
|
102665
103129
|
exports.deviceRefusalFromMessage = deviceRefusalFromMessage;
|
|
103130
|
+
exports.deviceRemovalHookCapability = deviceRemovalHookCapability;
|
|
102666
103131
|
exports.deviceSelectorMatches = deviceSelectorMatches;
|
|
102667
103132
|
exports.deviceStateCapability = deviceStateCapability;
|
|
102668
103133
|
exports.deviceStatusCapability = deviceStatusCapability;
|
|
@@ -102781,6 +103246,7 @@ exports.inferModelProvider = inferModelProvider;
|
|
|
102781
103246
|
exports.initialPoolMemoryState = initialPoolMemoryState;
|
|
102782
103247
|
exports.integrationsCapability = integrationsCapability;
|
|
102783
103248
|
exports.intercomCapability = intercomCapability;
|
|
103249
|
+
exports.interpolate = interpolate;
|
|
102784
103250
|
exports.interpretStoredClusterModel = interpretStoredClusterModel;
|
|
102785
103251
|
exports.invalidClusterStepModelEntries = invalidClusterStepModelEntries;
|
|
102786
103252
|
exports.invertPresetFeature = invertPresetFeature;
|
|
@@ -102873,6 +103339,7 @@ exports.llmCapability = llmCapability;
|
|
|
102873
103339
|
exports.llmRuntimeCapability = llmRuntimeCapability;
|
|
102874
103340
|
exports.loadContributionCapability = loadContributionCapability;
|
|
102875
103341
|
exports.localNetworkCapability = localNetworkCapability;
|
|
103342
|
+
exports.localizeConfigTree = localizeConfigTree;
|
|
102876
103343
|
exports.locationIconKey = locationIconKey;
|
|
102877
103344
|
exports.locationSimilarity = locationSimilarity;
|
|
102878
103345
|
exports.lockControlCapability = lockControlCapability;
|
|
@@ -102980,6 +103447,7 @@ exports.pickAppLinkHub = pickAppLinkHub;
|
|
|
102980
103447
|
exports.pickClusterStepModels = pickClusterStepModels;
|
|
102981
103448
|
exports.pickClusterStepSettings = pickClusterStepSettings;
|
|
102982
103449
|
exports.pickDetailCropConvention = pickDetailCropConvention;
|
|
103450
|
+
exports.pickFaceRescoreIntervalMinutes = pickFaceRescoreIntervalMinutes;
|
|
102983
103451
|
exports.pickInvalidClusterStepModels = pickInvalidClusterStepModels;
|
|
102984
103452
|
exports.pickNativeLeaseOverride = pickNativeLeaseOverride;
|
|
102985
103453
|
exports.pickPreferredRtspEntry = pickPreferredRtspEntry;
|
|
@@ -103016,6 +103484,8 @@ exports.readClusterStepModels = readClusterStepModels;
|
|
|
103016
103484
|
exports.readClusterStepSettings = readClusterStepSettings;
|
|
103017
103485
|
exports.readDetailCropConvention = readDetailCropConvention;
|
|
103018
103486
|
exports.readDeviceStateFrom = readDeviceStateFrom;
|
|
103487
|
+
exports.readErrorI18n = require_sleep.readErrorI18n;
|
|
103488
|
+
exports.readFaceRescoreIntervalMinutes = readFaceRescoreIntervalMinutes;
|
|
103019
103489
|
exports.readHubMotionDetected = readHubMotionDetected;
|
|
103020
103490
|
exports.readHubMotionStatus = readHubMotionStatus;
|
|
103021
103491
|
exports.readMotionTriggeredBy = readMotionTriggeredBy;
|
|
@@ -103027,6 +103497,7 @@ exports.readinessKey = require_sleep.readinessKey;
|
|
|
103027
103497
|
exports.rebootCapability = rebootCapability;
|
|
103028
103498
|
exports.recommendNode = recommendNode;
|
|
103029
103499
|
exports.reconcileBlockDevices = reconcileBlockDevices;
|
|
103500
|
+
exports.reconcileRemovedDevices = reconcileRemovedDevices;
|
|
103030
103501
|
exports.recordingArchiveCapability = recordingArchiveCapability;
|
|
103031
103502
|
exports.recordingCapability = recordingCapability;
|
|
103032
103503
|
exports.recordingExportCapability = recordingExportCapability;
|
|
@@ -103146,6 +103617,7 @@ exports.sliceChangedAt = require_composition.sliceChangedAt;
|
|
|
103146
103617
|
exports.smokeCapability = smokeCapability;
|
|
103147
103618
|
exports.smtpProviderCapability = smtpProviderCapability;
|
|
103148
103619
|
exports.snapshotCapability = snapshotCapability;
|
|
103620
|
+
exports.splitTranslationRef = splitTranslationRef;
|
|
103149
103621
|
exports.ssoBridgeCapability = ssoBridgeCapability;
|
|
103150
103622
|
exports.startReachabilityPoll = startReachabilityPoll;
|
|
103151
103623
|
exports.stateLabel = stateLabel;
|
|
@@ -103221,6 +103693,7 @@ exports.unitsForDimension = unitsForDimension;
|
|
|
103221
103693
|
exports.unreachableExtensionSlotRow = unreachableExtensionSlotRow;
|
|
103222
103694
|
exports.unwrapSchema = unwrapSchema;
|
|
103223
103695
|
exports.updateCapability = updateCapability;
|
|
103696
|
+
exports.userError = require_sleep.userError;
|
|
103224
103697
|
exports.userManagementCapability = userManagementCapability;
|
|
103225
103698
|
exports.userPasskeysCapability = userPasskeysCapability;
|
|
103226
103699
|
exports.vacuumControlCapability = vacuumControlCapability;
|