@camstack/system 1.2.303 → 1.2.305
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-runner.js +1 -1
- package/dist/addon-runner.mjs +1 -1
- package/dist/addon-utils.d.ts +1 -1
- package/dist/addon-utils.js +3 -1
- package/dist/addon-utils.mjs +2 -2
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/camera-grid/index.js +1 -1
- package/dist/builtins/camera-grid/index.mjs +1 -1
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-extension-linked-slot.d.ts +8 -0
- package/dist/builtins/device-manager/device-linked-devices.d.ts +34 -0
- package/dist/builtins/device-manager/device-manager.addon.js +188 -22
- package/dist/builtins/device-manager/device-manager.addon.mjs +188 -22
- package/dist/builtins/doorbell/binding-mirror.d.ts +24 -0
- package/dist/builtins/doorbell/doorbell-extension-slot.d.ts +66 -0
- package/dist/builtins/doorbell/virtual-doorbell.addon.d.ts +14 -0
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +307 -38
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +307 -38
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +3 -3
- package/dist/builtins/platform-probe/index.mjs +3 -3
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{child-cap-dispatch-C1c3rWaX.mjs → child-cap-dispatch-BCJjUtXV.mjs} +9 -1
- package/dist/{child-cap-dispatch-De5_HcvR.js → child-cap-dispatch-Be8e2cBP.js} +9 -1
- package/dist/{dist-DzHjDpU7.js → dist-BK4iP6ab.js} +2700 -1583
- package/dist/{dist-FwpS07w3.mjs → dist-Df1NhKxm.mjs} +2677 -1584
- package/dist/download/model-downloader.d.ts +15 -0
- package/dist/{event-loop-stall-monitor-GPrVvx14.mjs → event-loop-stall-monitor-EXjzIxDz.mjs} +25 -3
- package/dist/{event-loop-stall-monitor-CAsHdMwP.js → event-loop-stall-monitor-ey4mbofz.js} +36 -2
- package/dist/index.js +21 -3
- package/dist/index.mjs +21 -3
- package/dist/kernel/config-manager.d.ts +3 -1
- package/dist/{retired-settings-keys-CNcKBSQS.js → retired-settings-keys-DwWMph6F.js} +1 -1
- package/dist/{retired-settings-keys-rDPn2MMp.mjs → retired-settings-keys-dC4ckbXJ.mjs} +1 -1
- package/package.json +7 -1
package/dist/addon-runner.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
2
|
-
const require_child_cap_dispatch = require("./child-cap-dispatch-
|
|
2
|
+
const require_child_cap_dispatch = require("./child-cap-dispatch-Be8e2cBP.js");
|
|
3
3
|
const require_custom_action_registry = require("./custom-action-registry-acBY3mHA.js");
|
|
4
4
|
let node_path = require("node:path");
|
|
5
5
|
node_path = require_chunk.__toESM(node_path);
|
package/dist/addon-runner.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as LocalChildClient, Ct as installManifestNativeDeps, Ht as RUNNER_RSS_BUDGET_ENV, N as createUdsLoggerWithControl, at as getWorkerNativeCapProvider, ct as setWorkerNativeCapsChangeListener, i as installManifestPythonDeps, n as createChildCapDispatch, ot as getWorkerNativeCapSnapshot, pn as emitHeapDiagnosticReport, r as installManifestSystemDeps, s as createUdsAddonContext, tn as startRunnerHeapWatch, ut as validateProviderRegistrations, wt as resolveAddonClass } from "./child-cap-dispatch-
|
|
1
|
+
import { B as LocalChildClient, Ct as installManifestNativeDeps, Ht as RUNNER_RSS_BUDGET_ENV, N as createUdsLoggerWithControl, at as getWorkerNativeCapProvider, ct as setWorkerNativeCapsChangeListener, i as installManifestPythonDeps, n as createChildCapDispatch, ot as getWorkerNativeCapSnapshot, pn as emitHeapDiagnosticReport, r as installManifestSystemDeps, s as createUdsAddonContext, tn as startRunnerHeapWatch, ut as validateProviderRegistrations, wt as resolveAddonClass } from "./child-cap-dispatch-BCJjUtXV.mjs";
|
|
2
2
|
import { t as CustomActionRegistry } from "./custom-action-registry-B4Cf4O_X.mjs";
|
|
3
3
|
import { register } from "node:module";
|
|
4
4
|
import * as path$1 from "node:path";
|
package/dist/addon-utils.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*
|
|
15
15
|
* See memory: camstack_runner_ram_and_build_rootcause.
|
|
16
16
|
*/
|
|
17
|
-
export { downloadFile, ensureModel, isModelDownloaded, deleteModelFromDisk, collectModelFiles, getModelFilePath, type DownloadFileOptions, type DownloadRedirectPolicy, } from './download/model-downloader.js';
|
|
17
|
+
export { downloadFile, ensureModel, isModelDownloaded, deleteModelFromDisk, collectModelFiles, getModelFilePath, isModelDownloadHttpError, ModelDownloadHttpError, type DownloadFileOptions, type DownloadRedirectPolicy, } from './download/model-downloader.js';
|
|
18
18
|
export { ModelDownloadService } from './download/model-download-service.js';
|
|
19
19
|
export { createFileDataPlaneHandler } from './http/file-data-plane.js';
|
|
20
20
|
export { parseRangeHeader, contentTypeFor, type ByteRange, } from './http/authenticated-file-server.js';
|
package/dist/addon-utils.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("./chunk-Cek0wNdY.js");
|
|
3
|
-
const require_event_loop_stall_monitor = require("./event-loop-stall-monitor-
|
|
3
|
+
const require_event_loop_stall_monitor = require("./event-loop-stall-monitor-ey4mbofz.js");
|
|
4
4
|
const require_custom_action_registry = require("./custom-action-registry-acBY3mHA.js");
|
|
5
5
|
const require_snapshot_courtesy = require("./snapshot-courtesy-Cqs7GkOV.js");
|
|
6
6
|
exports.COURTESY_DEFAULT_WIDTH = require_snapshot_courtesy.COURTESY_DEFAULT_WIDTH;
|
|
7
7
|
exports.CustomActionRegistry = require_custom_action_registry.CustomActionRegistry;
|
|
8
|
+
exports.ModelDownloadHttpError = require_event_loop_stall_monitor.ModelDownloadHttpError;
|
|
8
9
|
exports.ModelDownloadService = require_event_loop_stall_monitor.ModelDownloadService;
|
|
9
10
|
exports.STALL_REPORT_MS = require_event_loop_stall_monitor.STALL_REPORT_MS;
|
|
10
11
|
exports.STALL_TICK_MS = require_event_loop_stall_monitor.STALL_TICK_MS;
|
|
@@ -17,6 +18,7 @@ exports.deleteModelFromDisk = require_event_loop_stall_monitor.deleteModelFromDi
|
|
|
17
18
|
exports.downloadFile = require_event_loop_stall_monitor.downloadFile;
|
|
18
19
|
exports.ensureModel = require_event_loop_stall_monitor.ensureModel;
|
|
19
20
|
exports.getModelFilePath = require_event_loop_stall_monitor.getModelFilePath;
|
|
21
|
+
exports.isModelDownloadHttpError = require_event_loop_stall_monitor.isModelDownloadHttpError;
|
|
20
22
|
exports.isModelDownloaded = require_event_loop_stall_monitor.isModelDownloaded;
|
|
21
23
|
exports.parseRangeHeader = require_event_loop_stall_monitor.parseRangeHeader;
|
|
22
24
|
exports.renderCourtesyJpeg = require_snapshot_courtesy.renderCourtesyJpeg;
|
package/dist/addon-utils.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as createFileDataPlaneHandler, c as parseRangeHeader, d as ModelDownloadService, f as
|
|
1
|
+
import { _ as ensureModel, a as createFileDataPlaneHandler, b as isModelDownloadHttpError, c as parseRangeHeader, d as ModelDownloadService, f as ModelDownloadHttpError, h as downloadFile, i as startEventLoopStallMonitor, m as deleteModelFromDisk, n as STALL_TICK_MS, o as contentTypeFor, p as collectModelFiles, r as attributeStall, t as STALL_REPORT_MS, x as isModelDownloaded, y as getModelFilePath } from "./event-loop-stall-monitor-EXjzIxDz.mjs";
|
|
2
2
|
import { t as CustomActionRegistry } from "./custom-action-registry-B4Cf4O_X.mjs";
|
|
3
3
|
import { i as renderCourtesyOverlayJpeg, n as courtesyCacheKey, r as renderCourtesyJpeg, t as COURTESY_DEFAULT_WIDTH } from "./snapshot-courtesy-CZPvteq2.mjs";
|
|
4
|
-
export { COURTESY_DEFAULT_WIDTH, CustomActionRegistry, ModelDownloadService, STALL_REPORT_MS, STALL_TICK_MS, attributeStall, collectModelFiles, contentTypeFor, courtesyCacheKey, createFileDataPlaneHandler, deleteModelFromDisk, downloadFile, ensureModel, getModelFilePath, isModelDownloaded, parseRangeHeader, renderCourtesyJpeg, renderCourtesyOverlayJpeg, startEventLoopStallMonitor };
|
|
4
|
+
export { COURTESY_DEFAULT_WIDTH, CustomActionRegistry, ModelDownloadHttpError, ModelDownloadService, STALL_REPORT_MS, STALL_TICK_MS, attributeStall, collectModelFiles, contentTypeFor, courtesyCacheKey, createFileDataPlaneHandler, deleteModelFromDisk, downloadFile, ensureModel, getModelFilePath, isModelDownloadHttpError, isModelDownloaded, parseRangeHeader, renderCourtesyJpeg, renderCourtesyOverlayJpeg, startEventLoopStallMonitor };
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BK4iP6ab.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { L as addonPagesCapability, Wn as EventCategory, _n as BaseAddon, hn as errMsg } from "../../dist-Df1NhKxm.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BK4iP6ab.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Wn as EventCategory, _n as BaseAddon, hn as errMsg, z as addonWidgetsCapability } from "../../dist-Df1NhKxm.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BK4iP6ab.js");
|
|
7
7
|
//#region src/builtins/alerts/prune-policy.ts
|
|
8
8
|
/**
|
|
9
9
|
* Ids older than `cutoffMs`, oldest first.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as alertsCapability,
|
|
1
|
+
import { An as createEvent, B as alertsCapability, Wn as EventCategory, _n as BaseAddon, hn as errMsg, n as AlertSchema } from "../../dist-Df1NhKxm.mjs";
|
|
2
2
|
//#region src/builtins/alerts/prune-policy.ts
|
|
3
3
|
/**
|
|
4
4
|
* Ids older than `cutoffMs`, oldest first.
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BK4iP6ab.js");
|
|
7
7
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
8
8
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
9
9
|
deadZoneFraction: .5,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { In as isEvent, Kt as ptzAutotrackCapability, U as bareAddonId, Wn as EventCategory, _n as BaseAddon, g as FIRST_LEVEL_MACRO_CLASSES, hn as errMsg } from "../../dist-Df1NhKxm.mjs";
|
|
2
2
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
3
3
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
4
4
|
deadZoneFraction: .5,
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BK4iP6ab.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let buffer = require("buffer");
|
|
9
9
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { H as backupCapability, It as mayWriteToLocation, Wn as EventCategory, _n as BaseAddon, on as storageOccupancyCapability } from "../../dist-Df1NhKxm.mjs";
|
|
2
2
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
3
|
import { Buffer as Buffer$1 } from "buffer";
|
|
4
4
|
import * as fsp from "node:fs/promises";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BK4iP6ab.js");
|
|
7
7
|
let zod = require("zod");
|
|
8
8
|
let _camstack_types_node = require("@camstack/types/node");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $ as declarationOwnerNodeId, An as createEvent, Cn as DeviceType, K as cameraGridLayoutCapability, Pn as hydrateSchema, S as MOTION_CLOSE_AFTER_MS, Wn as EventCategory, _n as BaseAddon, cn as streamCatalogCapability, gn as buildFfmpegArgs, hn as errMsg, i as BaseDevice, m as DeclaredDevices, p as DERIVED_CAMERA_SILENCED_CAP_NAMES, rn as snapshotCapability, xn as DeviceFeature, zt as motionCapability } from "../../dist-Df1NhKxm.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { FfmpegProcess } from "@camstack/types/node";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-BK4iP6ab.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/console-logging/console-destination.ts
|
|
9
9
|
var LEVEL_RANK = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Mt as logDestinationCapability, _n as BaseAddon } from "../../dist-Df1NhKxm.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/console-logging/console-destination.ts
|
|
4
4
|
var LEVEL_RANK = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-BK4iP6ab.js");
|
|
4
4
|
let node_crypto = require("node:crypto");
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
6
6
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { J as coreBlockAddonId, X as coreBlocksCapability, Y as coreBlockIdFromAddonId, c as CORE_BLOCKS_ADDON_ID,
|
|
1
|
+
import { J as coreBlockAddonId, X as coreBlocksCapability, Y as coreBlockIdFromAddonId, _n as BaseAddon, c as CORE_BLOCKS_ADDON_ID, hn as errMsg, l as CORE_BLOCK_ADDON_PREFIX, m as DeclaredDevices, u as CoreBlockSchema } from "../../dist-Df1NhKxm.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IDeviceExtensionProvider } from '@camstack/types';
|
|
2
|
+
import { ProviderContext } from './device-provider-context.js';
|
|
3
|
+
/** The routing prefix of this owner's `slotRef`s. */
|
|
4
|
+
export declare const DEVICE_MANAGER_EXTENSION_SOURCE = "device-manager";
|
|
5
|
+
/** The store the slot reads and writes, named (D62). */
|
|
6
|
+
export declare const LINKED_DEVICES_AUTHORITY = "device-manager:_linkedDeviceIds";
|
|
7
|
+
/** Build the `device-extension` provider the device manager registers. */
|
|
8
|
+
export declare function createDeviceManagerExtensionProvider(pctx: ProviderContext): IDeviceExtensionProvider;
|
|
@@ -96,3 +96,37 @@ export declare function buildLinkedDevicesContribution(pctx: ProviderContext, de
|
|
|
96
96
|
export declare function applyLinkedDevicesPatch(pctx: Pick<ProviderContext, 'settings'>, deviceId: number, patch: Record<string, unknown>): Promise<{
|
|
97
97
|
success: true;
|
|
98
98
|
}>;
|
|
99
|
+
/** The one field a pick is judged by. */
|
|
100
|
+
export interface LinkedPickDevice {
|
|
101
|
+
readonly type: string;
|
|
102
|
+
}
|
|
103
|
+
/** What `refusedLinkedPicks` judges: the write, and what it is judged against. */
|
|
104
|
+
export interface LinkedPicksInput {
|
|
105
|
+
readonly selfId: number;
|
|
106
|
+
readonly picked: readonly number[];
|
|
107
|
+
readonly persisted: readonly number[];
|
|
108
|
+
readonly fleet: ReadonlyMap<number, LinkedPickDevice>;
|
|
109
|
+
}
|
|
110
|
+
/** One refused pick, named — the refusal message is built from these. */
|
|
111
|
+
export interface LinkedPickRefusal {
|
|
112
|
+
readonly deviceId: number;
|
|
113
|
+
readonly reason: 'self' | 'container' | 'unknown';
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Which NEW picks a linked-devices write must refuse: the camera itself, a
|
|
117
|
+
* container (never a pick — its children are, D356 and the file header), and
|
|
118
|
+
* an id no device has.
|
|
119
|
+
*
|
|
120
|
+
* Only ids that are not ALREADY persisted are judged. A list written before
|
|
121
|
+
* this rule existed may hold a container or a device that has since been
|
|
122
|
+
* deleted; the editor shows those as unavailable / missing, and keeping them
|
|
123
|
+
* is not a new link. Removing them is the operator's call, never this
|
|
124
|
+
* function's (a missing source is shown, never silently dropped).
|
|
125
|
+
*
|
|
126
|
+
* Deliberately NOT applied to the settings-section save
|
|
127
|
+
* (`applyLinkedDevicesPatch` via `DEVICE_STORE_SECTIONS`): that surface has
|
|
128
|
+
* never refused, its picker never offers a container, and the Locations page
|
|
129
|
+
* writes the list through it. Slice 1 changes no behaviour on the old path;
|
|
130
|
+
* both paths persist through `applyLinkedDevicesPatch`.
|
|
131
|
+
*/
|
|
132
|
+
export declare function refusedLinkedPicks(params: LinkedPicksInput): readonly LinkedPickRefusal[];
|
|
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
7
|
-
const require_retired_settings_keys = require("../../retired-settings-keys-
|
|
6
|
+
const require_dist = require("../../dist-BK4iP6ab.js");
|
|
7
|
+
const require_retired_settings_keys = require("../../retired-settings-keys-DwWMph6F.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let _camstack_types_node = require("@camstack/types/node");
|
|
10
10
|
//#region src/builtins/device-manager/adoption-job-engine.ts
|
|
@@ -2942,6 +2942,47 @@ async function applyLinkedDevicesPatch(pctx, deviceId, patch) {
|
|
|
2942
2942
|
await pctx.settings.writeDeviceStore(deviceId, next);
|
|
2943
2943
|
return { success: true };
|
|
2944
2944
|
}
|
|
2945
|
+
/**
|
|
2946
|
+
* Which NEW picks a linked-devices write must refuse: the camera itself, a
|
|
2947
|
+
* container (never a pick — its children are, D356 and the file header), and
|
|
2948
|
+
* an id no device has.
|
|
2949
|
+
*
|
|
2950
|
+
* Only ids that are not ALREADY persisted are judged. A list written before
|
|
2951
|
+
* this rule existed may hold a container or a device that has since been
|
|
2952
|
+
* deleted; the editor shows those as unavailable / missing, and keeping them
|
|
2953
|
+
* is not a new link. Removing them is the operator's call, never this
|
|
2954
|
+
* function's (a missing source is shown, never silently dropped).
|
|
2955
|
+
*
|
|
2956
|
+
* Deliberately NOT applied to the settings-section save
|
|
2957
|
+
* (`applyLinkedDevicesPatch` via `DEVICE_STORE_SECTIONS`): that surface has
|
|
2958
|
+
* never refused, its picker never offers a container, and the Locations page
|
|
2959
|
+
* writes the list through it. Slice 1 changes no behaviour on the old path;
|
|
2960
|
+
* both paths persist through `applyLinkedDevicesPatch`.
|
|
2961
|
+
*/
|
|
2962
|
+
function refusedLinkedPicks(params) {
|
|
2963
|
+
const kept = new Set(params.persisted);
|
|
2964
|
+
const out = [];
|
|
2965
|
+
for (const deviceId of params.picked) {
|
|
2966
|
+
if (kept.has(deviceId)) continue;
|
|
2967
|
+
if (deviceId === params.selfId) {
|
|
2968
|
+
out.push({
|
|
2969
|
+
deviceId,
|
|
2970
|
+
reason: "self"
|
|
2971
|
+
});
|
|
2972
|
+
continue;
|
|
2973
|
+
}
|
|
2974
|
+
const device = params.fleet.get(deviceId);
|
|
2975
|
+
if (device === void 0) out.push({
|
|
2976
|
+
deviceId,
|
|
2977
|
+
reason: "unknown"
|
|
2978
|
+
});
|
|
2979
|
+
else if (device.type === require_dist.DeviceType.Container) out.push({
|
|
2980
|
+
deviceId,
|
|
2981
|
+
reason: "container"
|
|
2982
|
+
});
|
|
2983
|
+
}
|
|
2984
|
+
return out;
|
|
2985
|
+
}
|
|
2945
2986
|
//#endregion
|
|
2946
2987
|
//#region src/builtins/device-manager/device-store-sections.ts
|
|
2947
2988
|
/** The device-manager's device-store-backed sections. Add an entry to extend. */
|
|
@@ -3931,6 +3972,124 @@ var DeviceEventPropagator = class {
|
|
|
3931
3972
|
return chain;
|
|
3932
3973
|
}
|
|
3933
3974
|
};
|
|
3975
|
+
//#endregion
|
|
3976
|
+
//#region src/builtins/device-manager/device-extension-linked-slot.ts
|
|
3977
|
+
/** The routing prefix of this owner's `slotRef`s. */
|
|
3978
|
+
var DEVICE_MANAGER_EXTENSION_SOURCE = "device-manager";
|
|
3979
|
+
/** The store the slot reads and writes, named (D62). */
|
|
3980
|
+
var LINKED_DEVICES_AUTHORITY = `device-manager:${LINKED_IDS_CONFIG_KEY}`;
|
|
3981
|
+
/**
|
|
3982
|
+
* The picked ids' ledger rows, in ONE indexed read of the device manager's own
|
|
3983
|
+
* store (`rows.getMany`) — never the whole fleet to label a handful of ids.
|
|
3984
|
+
* An id no device has is absent from the map.
|
|
3985
|
+
*/
|
|
3986
|
+
async function pickedDevices(pctx, ids) {
|
|
3987
|
+
const rows = await pctx.metaStore.rows.getMany(ids);
|
|
3988
|
+
const out = /* @__PURE__ */ new Map();
|
|
3989
|
+
for (const [id, row] of rows) out.set(id, {
|
|
3990
|
+
name: row.meta.name,
|
|
3991
|
+
type: row.meta.type
|
|
3992
|
+
});
|
|
3993
|
+
return out;
|
|
3994
|
+
}
|
|
3995
|
+
/** What a camera's picked id is, said once for the editor. */
|
|
3996
|
+
function sourceOf(deviceId, byId) {
|
|
3997
|
+
const device = byId.get(deviceId);
|
|
3998
|
+
if (device === void 0) return {
|
|
3999
|
+
deviceId,
|
|
4000
|
+
name: null,
|
|
4001
|
+
health: "missing",
|
|
4002
|
+
detail: "No device has this id any more — it links nothing until removed."
|
|
4003
|
+
};
|
|
4004
|
+
if (device.type === require_dist.DeviceType.Container) return {
|
|
4005
|
+
deviceId,
|
|
4006
|
+
name: device.name,
|
|
4007
|
+
health: "unavailable",
|
|
4008
|
+
detail: "A container is never a pick (D356): its children are linked in its place. Pick the children instead."
|
|
4009
|
+
};
|
|
4010
|
+
return {
|
|
4011
|
+
deviceId,
|
|
4012
|
+
name: device.name,
|
|
4013
|
+
health: "ok"
|
|
4014
|
+
};
|
|
4015
|
+
}
|
|
4016
|
+
function describeRefusal(deviceId, reason) {
|
|
4017
|
+
if (reason === "self") return `${deviceId} is the camera itself`;
|
|
4018
|
+
if (reason === "container") return `${deviceId} is a container — pick its children`;
|
|
4019
|
+
return `${deviceId} is not a device`;
|
|
4020
|
+
}
|
|
4021
|
+
async function fleetOf(pctx) {
|
|
4022
|
+
const all = await listAll(pctx, LINK_CANDIDATE_PROJECTION);
|
|
4023
|
+
return new Map(all.map((d) => [d.id, d]));
|
|
4024
|
+
}
|
|
4025
|
+
function candidatesFor(deviceId, byId) {
|
|
4026
|
+
const location = byId.get(deviceId)?.location ?? null;
|
|
4027
|
+
const out = [];
|
|
4028
|
+
for (const device of byId.values()) {
|
|
4029
|
+
if (device.id === deviceId) continue;
|
|
4030
|
+
if (device.parentDeviceId === deviceId) continue;
|
|
4031
|
+
if (device.type === require_dist.DeviceType.Container) continue;
|
|
4032
|
+
const suggested = location !== null && device.location === location;
|
|
4033
|
+
const parent = device.parentDeviceId === null ? void 0 : byId.get(device.parentDeviceId);
|
|
4034
|
+
out.push({
|
|
4035
|
+
deviceId: device.id,
|
|
4036
|
+
name: device.name,
|
|
4037
|
+
type: device.type,
|
|
4038
|
+
location: device.location,
|
|
4039
|
+
parentName: parent?.name ?? null,
|
|
4040
|
+
suggested,
|
|
4041
|
+
reason: suggested ? "same location" : null
|
|
4042
|
+
});
|
|
4043
|
+
}
|
|
4044
|
+
return out.toSorted((a, b) => Number(b.suggested) - Number(a.suggested) || a.name.localeCompare(b.name));
|
|
4045
|
+
}
|
|
4046
|
+
/** Build the `device-extension` provider the device manager registers. */
|
|
4047
|
+
function createDeviceManagerExtensionProvider(pctx) {
|
|
4048
|
+
return require_dist.createDeviceExtensionProvider({
|
|
4049
|
+
source: DEVICE_MANAGER_EXTENSION_SOURCE,
|
|
4050
|
+
label: "Device manager",
|
|
4051
|
+
slots: [require_dist.defineExtensionSlotProvider("linked-devices", {
|
|
4052
|
+
list: async (deviceId) => {
|
|
4053
|
+
const { manualIds } = parseLinkedDevicesConfig(await pctx.settings.readDeviceStore(deviceId));
|
|
4054
|
+
const byId = await pickedDevices(pctx, manualIds);
|
|
4055
|
+
return {
|
|
4056
|
+
authority: LINKED_DEVICES_AUTHORITY,
|
|
4057
|
+
enabled: null,
|
|
4058
|
+
activation: null,
|
|
4059
|
+
value: {
|
|
4060
|
+
slot: "linked-devices",
|
|
4061
|
+
deviceIds: [...manualIds]
|
|
4062
|
+
},
|
|
4063
|
+
sources: manualIds.map((id) => sourceOf(id, byId))
|
|
4064
|
+
};
|
|
4065
|
+
},
|
|
4066
|
+
set: async (deviceId, value) => {
|
|
4067
|
+
const [byId, blob] = await Promise.all([pickedDevices(pctx, value.deviceIds), pctx.settings.readDeviceStore(deviceId)]);
|
|
4068
|
+
const refused = refusedLinkedPicks({
|
|
4069
|
+
selfId: deviceId,
|
|
4070
|
+
picked: value.deviceIds,
|
|
4071
|
+
persisted: parseLinkedDevicesConfig(blob).manualIds,
|
|
4072
|
+
fleet: byId
|
|
4073
|
+
});
|
|
4074
|
+
if (refused.length > 0) {
|
|
4075
|
+
pctx.host.ctx.logger.warn("linked-devices: write refused — nothing persisted", {
|
|
4076
|
+
tags: { deviceId },
|
|
4077
|
+
meta: { refused }
|
|
4078
|
+
});
|
|
4079
|
+
throw new Error(`linked-devices on ${deviceId}: refused — ` + refused.map((r) => describeRefusal(r.deviceId, r.reason)).join("; "));
|
|
4080
|
+
}
|
|
4081
|
+
await applyLinkedDevicesPatch(pctx, deviceId, { [LINKED_IDS_CONFIG_KEY]: value.deviceIds });
|
|
4082
|
+
return {
|
|
4083
|
+
applied: true,
|
|
4084
|
+
reload: "none"
|
|
4085
|
+
};
|
|
4086
|
+
},
|
|
4087
|
+
candidates: async (deviceId) => candidatesFor(deviceId, await fleetOf(pctx))
|
|
4088
|
+
})],
|
|
4089
|
+
hostTypeOf: async (deviceId) => (await pctx.metaStore.resolvePersistedById(deviceId))?.meta.type ?? null,
|
|
4090
|
+
logger: pctx.host.ctx.logger
|
|
4091
|
+
});
|
|
4092
|
+
}
|
|
3934
4093
|
/** A refusal that names a switch the camera does not offer, rather than one it
|
|
3935
4094
|
* could not be asked about. The cap documents rejecting the former; anything
|
|
3936
4095
|
* else is treated as the camera being out of reach, which is the safe reading:
|
|
@@ -8049,28 +8208,35 @@ var DeviceManagerAddon = class extends require_dist.BaseAddon {
|
|
|
8049
8208
|
this.propagator.start();
|
|
8050
8209
|
this.ctx.logger.info("device-event-propagator started");
|
|
8051
8210
|
}
|
|
8052
|
-
return [
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8211
|
+
return [
|
|
8212
|
+
{
|
|
8213
|
+
capability: require_dist.deviceManagerCapability,
|
|
8214
|
+
provider
|
|
8215
|
+
},
|
|
8216
|
+
{
|
|
8217
|
+
capability: require_dist.deviceStateCapability,
|
|
8218
|
+
provider: {
|
|
8219
|
+
getSnapshot: async (input) => {
|
|
8220
|
+
return stateMirror.snapshotForDevice(input.deviceId);
|
|
8221
|
+
},
|
|
8222
|
+
getCapSlice: async (input) => {
|
|
8223
|
+
return stateMirror.capSlice(input.deviceId, input.capName);
|
|
8224
|
+
},
|
|
8225
|
+
getAllSnapshots: async () => {
|
|
8226
|
+
return stateMirror.allSnapshots();
|
|
8227
|
+
},
|
|
8228
|
+
setCapSlice: async (input) => {
|
|
8229
|
+
const { deviceId, capName, slice } = input;
|
|
8230
|
+
if (!await resolvePersistedById(deviceId)) throw new Error(`[device-manager] setCapSlice: unknown device id=${deviceId}`);
|
|
8231
|
+
if (stateMirror.applySingleCapUpdate(deviceId, capName, slice)) stateMirror.scheduleRuntimeStateDiskWrite(deviceId, settings, capName);
|
|
8232
|
+
}
|
|
8071
8233
|
}
|
|
8234
|
+
},
|
|
8235
|
+
{
|
|
8236
|
+
capability: require_dist.deviceExtensionCapability,
|
|
8237
|
+
provider: createDeviceManagerExtensionProvider(pctx)
|
|
8072
8238
|
}
|
|
8073
|
-
|
|
8239
|
+
];
|
|
8074
8240
|
}
|
|
8075
8241
|
async onShutdown() {
|
|
8076
8242
|
this.propagator?.stop();
|