@camstack/system 1.2.330 → 1.2.331
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/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 +3 -3
- package/dist/builtins/autotrack/index.mjs +3 -3
- 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/composer/composer.addon.js +27 -8
- package/dist/builtins/composer/composer.addon.mjs +21 -3
- 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 +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-bindings-store.d.ts +7 -0
- package/dist/builtins/device-manager/device-manager.addon.d.ts +3 -0
- package/dist/builtins/device-manager/device-manager.addon.js +130 -3
- package/dist/builtins/device-manager/device-manager.addon.mjs +130 -3
- package/dist/builtins/device-manager/stale-wrapper-activations.d.ts +26 -0
- 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 +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- 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/shared/device-state-changed.d.ts +3 -4
- 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-C8uts1P4.js → child-cap-dispatch-93MfsaZL.js} +1 -0
- package/dist/{child-cap-dispatch-C2VINHu1.mjs → child-cap-dispatch-kLIiU1CG.mjs} +1 -0
- package/dist/{composition-sources-2XxNEet3.js → composition-sources-BXZorHDO.js} +1 -1
- package/dist/{composition-sources-Wj2kWund.mjs → composition-sources-aEEer5gE.mjs} +1 -1
- package/dist/{dist-Dp043AI0.mjs → dist-CoG8lY6H.mjs} +222 -374
- package/dist/{dist-Bx4zxM9N.js → dist-DRUzy1SF.js} +221 -421
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{retired-settings-keys-DR2WMe5d.js → retired-settings-keys-BY9H1I2b.js} +1 -1
- package/dist/{retired-settings-keys-Dxf9vELs.mjs → retired-settings-keys-BcJDpASY.mjs} +1 -1
- package/package.json +1 -16
- package/dist/builtins/doorbell/binding-mirror.d.ts +0 -110
- package/dist/builtins/doorbell/doorbell-composition-migration.d.ts +0 -47
- package/dist/builtins/doorbell/doorbell-extension-slot.d.ts +0 -67
- package/dist/builtins/doorbell/doorbell-settings.d.ts +0 -58
- package/dist/builtins/doorbell/index.d.ts +0 -2
- package/dist/builtins/doorbell/index.js +0 -8
- package/dist/builtins/doorbell/index.mjs +0 -2
- package/dist/builtins/doorbell/trigger-engine.d.ts +0 -92
- package/dist/builtins/doorbell/virtual-doorbell.addon.d.ts +0 -218
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +0 -1413
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +0 -1407
- package/dist/device-state-changed-Bk7cvTnz.js +0 -31
- package/dist/device-state-changed-DoBbkyEI.mjs +0 -20
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-93MfsaZL.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 { $t as RUNNER_RSS_BUDGET_ENV, Ft as resolveAddonClass, H as createUdsLoggerWithControl, Pt as installManifestNativeDeps, U as LocalChildClient, _t as getWorkerNativeCapSnapshot, f as installManifestSystemDeps, fn as startRunnerHeapWatch, g as createUdsAddonContext, gt as getWorkerNativeCapProvider, i as killOwnRunnerGroupAfterParentLoss, n as createChildCapDispatch, p as installManifestPythonDeps, u as startRunnerParentDeathWatchdog, wn as emitHeapDiagnosticReport, xt as validateProviderRegistrations, yt as setWorkerNativeCapsChangeListener } from "./child-cap-dispatch-
|
|
1
|
+
import { $t as RUNNER_RSS_BUDGET_ENV, Ft as resolveAddonClass, H as createUdsLoggerWithControl, Pt as installManifestNativeDeps, U as LocalChildClient, _t as getWorkerNativeCapSnapshot, f as installManifestSystemDeps, fn as startRunnerHeapWatch, g as createUdsAddonContext, gt as getWorkerNativeCapProvider, i as killOwnRunnerGroupAfterParentLoss, n as createChildCapDispatch, p as installManifestPythonDeps, u as startRunnerParentDeathWatchdog, wn as emitHeapDiagnosticReport, xt as validateProviderRegistrations, yt as setWorkerNativeCapsChangeListener } from "./child-cap-dispatch-kLIiU1CG.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";
|
|
@@ -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-DRUzy1SF.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 { Hn as errMsg, Un as BaseAddon, V as addonPagesCapability, mr as EventCategory } from "../../dist-CoG8lY6H.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-DRUzy1SF.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 { Hn as errMsg, U as addonWidgetsCapability, Un as BaseAddon, mr as EventCategory } from "../../dist-CoG8lY6H.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-DRUzy1SF.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 {
|
|
1
|
+
import { $n as createEvent, Hn as errMsg, Un as BaseAddon, W as alertsCapability, mr as EventCategory, n as AlertSchema } from "../../dist-CoG8lY6H.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-DRUzy1SF.js");
|
|
7
7
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
8
8
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
9
9
|
deadZoneFraction: .5,
|
|
@@ -33,8 +33,8 @@ var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
|
33
33
|
*
|
|
34
34
|
* ## One switch, not two (D62, D520)
|
|
35
35
|
*
|
|
36
|
-
* Binding this wrapper to a camera chooses the IMPLEMENTATION
|
|
37
|
-
*
|
|
36
|
+
* Binding this wrapper to a camera chooses the IMPLEMENTATION.
|
|
37
|
+
* `setEnabled` is the switch for the function, and
|
|
38
38
|
* it is the cap's own switch: a camera with firmware autotrack uses its native
|
|
39
39
|
* provider for exactly the same method, so the operator never sees two
|
|
40
40
|
* controls that can disagree.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Hn as errMsg, Un as BaseAddon, ar as isEvent, b as FIRST_LEVEL_MACRO_CLASSES, mr as EventCategory, q as bareAddonId, rn as ptzAutotrackCapability } from "../../dist-CoG8lY6H.mjs";
|
|
2
2
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
3
3
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
4
4
|
deadZoneFraction: .5,
|
|
@@ -28,8 +28,8 @@ var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
|
28
28
|
*
|
|
29
29
|
* ## One switch, not two (D62, D520)
|
|
30
30
|
*
|
|
31
|
-
* Binding this wrapper to a camera chooses the IMPLEMENTATION
|
|
32
|
-
*
|
|
31
|
+
* Binding this wrapper to a camera chooses the IMPLEMENTATION.
|
|
32
|
+
* `setEnabled` is the switch for the function, and
|
|
33
33
|
* it is the cap's own switch: a camera with firmware autotrack uses its native
|
|
34
34
|
* provider for exactly the same method, so the operator never sees two
|
|
35
35
|
* controls that can disagree.
|
|
@@ -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-DRUzy1SF.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 { Gt as mayWriteToLocation, K as backupCapability, Un as BaseAddon, m as DATABASE_SNAPSHOT_SUFFIX, mr as EventCategory, or as nodePin, pr as toNodeId, vn as storageOccupancyCapability } from "../../dist-CoG8lY6H.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-DRUzy1SF.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 { $n as createEvent, Hn as errMsg, Kt as memoizePinnedFfmpeg, O as MOTION_CLOSE_AFTER_MS, Un as BaseAddon, Vn as DeviceType, Yt as motionCapability, Z as cameraGridLayoutCapability, _ as DERIVED_CAMERA_SILENCED_CAP_NAMES, bn as streamCatalogCapability, hn as snapshotCapability, i as BaseDevice, kn as buildFfmpegArgs, mr as EventCategory, rr as hydrateSchema, ut as declarationOwnerNodeId, v as DeclaredDevices, zn as DeviceFeature } from "../../dist-CoG8lY6H.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { FfmpegProcess } from "@camstack/types/node";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -3,9 +3,28 @@ 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
|
|
8
|
-
|
|
6
|
+
const require_dist = require("../../dist-DRUzy1SF.js");
|
|
7
|
+
const require_composition_sources = require("../../composition-sources-BXZorHDO.js");
|
|
8
|
+
let zod = require("zod");
|
|
9
|
+
//#region src/builtins/shared/device-state-changed.ts
|
|
10
|
+
/** Structural narrowing helper for untrusted bus payloads. */
|
|
11
|
+
function isRecord$2(value) {
|
|
12
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13
|
+
}
|
|
14
|
+
function parseDeviceStateChanged(data) {
|
|
15
|
+
if (!isRecord$2(data)) return null;
|
|
16
|
+
const deviceId = data["deviceId"];
|
|
17
|
+
const capName = data["capName"];
|
|
18
|
+
const slice = data["slice"];
|
|
19
|
+
if (typeof deviceId !== "number" || typeof capName !== "string") return null;
|
|
20
|
+
if (!isRecord$2(slice)) return null;
|
|
21
|
+
return {
|
|
22
|
+
deviceId,
|
|
23
|
+
capName,
|
|
24
|
+
slice
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
9
28
|
//#region src/builtins/composer/composed-device.ts
|
|
10
29
|
/**
|
|
11
30
|
* A composed device: an ordinary `BaseDevice` whose caps are served by the
|
|
@@ -29,7 +48,7 @@ const require_composition_sources = require("../../composition-sources-2XxNEet3.
|
|
|
29
48
|
* `deviceMeta`: a failed meta read builds a device as `generic`, and the
|
|
30
49
|
* declaration is the authority for what this device is.
|
|
31
50
|
*/
|
|
32
|
-
var COMPOSED_DEVICE_CONFIG_SCHEMA =
|
|
51
|
+
var COMPOSED_DEVICE_CONFIG_SCHEMA = zod.z.object({});
|
|
33
52
|
var ComposedDevice = class extends require_dist.BaseDevice {
|
|
34
53
|
features = [];
|
|
35
54
|
constructor(ctx, type, caps) {
|
|
@@ -3310,7 +3329,7 @@ function entriesOf(request) {
|
|
|
3310
3329
|
}))];
|
|
3311
3330
|
}
|
|
3312
3331
|
function valueAtPath(slice, path) {
|
|
3313
|
-
return path.split(".").reduce((node, segment) =>
|
|
3332
|
+
return path.split(".").reduce((node, segment) => isRecord$2(node) ? node[segment] : void 0, slice);
|
|
3314
3333
|
}
|
|
3315
3334
|
function onlineOf(slice) {
|
|
3316
3335
|
const online = slice["online"];
|
|
@@ -3975,12 +3994,12 @@ var SourceTracker = class {
|
|
|
3975
3994
|
var DECLARED_INTEGRATION_NAME_UNUSED = "Blocks";
|
|
3976
3995
|
/** The owner-only shadow payload is not in the typed catalog: narrowed at the boundary, like `device.state-changed`. */
|
|
3977
3996
|
function parseNativeShadowChanged(data) {
|
|
3978
|
-
if (!
|
|
3997
|
+
if (!isRecord$2(data)) return null;
|
|
3979
3998
|
const deviceId = data["deviceId"];
|
|
3980
3999
|
const capName = data["capName"];
|
|
3981
4000
|
const native = data["native"];
|
|
3982
4001
|
if (typeof deviceId !== "number" || typeof capName !== "string") return null;
|
|
3983
|
-
if (!
|
|
4002
|
+
if (!isRecord$2(native)) return null;
|
|
3984
4003
|
return {
|
|
3985
4004
|
deviceId,
|
|
3986
4005
|
capName,
|
|
@@ -4127,7 +4146,7 @@ var ComposerAddon = class extends require_dist.BaseAddon {
|
|
|
4127
4146
|
newTimer: () => new NodeDeadlineTimer(() => Date.now())
|
|
4128
4147
|
});
|
|
4129
4148
|
this.subscribe({ category: require_dist.EventCategory.DeviceStateChanged }, (event) => {
|
|
4130
|
-
const data =
|
|
4149
|
+
const data = parseDeviceStateChanged(event.data);
|
|
4131
4150
|
if (data !== null) this.composer?.onStateChanged(data).catch((err) => {
|
|
4132
4151
|
this.logEventFailure("device.state-changed", data.deviceId, err);
|
|
4133
4152
|
});
|
|
@@ -1,7 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as
|
|
3
|
-
import { n as normalizedNativeOwner } from "../../composition-sources-Wj2kWund.mjs";
|
|
1
|
+
import { $ as composerCapability, $n as createEvent, An as cloneStatefulExpressionMemory, Fn as compositionSliceKey, Hn as errMsg, In as compositionSourceKey, Ln as createStatefulExpressionMemory, Mn as composedDeviceStableId, Nn as compositionFeatureEnabled, On as COMPOSER_ADDON_ID, Pn as compositionItemFieldPath, Rn as toExpressionValue, St as evaluateCompositionField, Un as BaseAddon, Vn as DeviceType, Y as buildCapabilityLookup, c as COMPOSED_ITEM_FIXED_FIELDS, en as planComposition, et as compositionFieldKey, i as BaseDevice, jn as composedDeviceRef, mr as EventCategory, t as ALL_CAPABILITY_DEFINITIONS, v as DeclaredDevices } from "../../dist-CoG8lY6H.mjs";
|
|
2
|
+
import { n as normalizedNativeOwner } from "../../composition-sources-aEEer5gE.mjs";
|
|
4
3
|
import { z } from "zod";
|
|
4
|
+
//#region src/builtins/shared/device-state-changed.ts
|
|
5
|
+
/** Structural narrowing helper for untrusted bus payloads. */
|
|
6
|
+
function isRecord$2(value) {
|
|
7
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function parseDeviceStateChanged(data) {
|
|
10
|
+
if (!isRecord$2(data)) return null;
|
|
11
|
+
const deviceId = data["deviceId"];
|
|
12
|
+
const capName = data["capName"];
|
|
13
|
+
const slice = data["slice"];
|
|
14
|
+
if (typeof deviceId !== "number" || typeof capName !== "string") return null;
|
|
15
|
+
if (!isRecord$2(slice)) return null;
|
|
16
|
+
return {
|
|
17
|
+
deviceId,
|
|
18
|
+
capName,
|
|
19
|
+
slice
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
5
23
|
//#region src/builtins/composer/composed-device.ts
|
|
6
24
|
/**
|
|
7
25
|
* A composed device: an ordinary `BaseDevice` whose caps are served by the
|
|
@@ -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-DRUzy1SF.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 { Un as BaseAddon, Vt as logDestinationCapability } from "../../dist-CoG8lY6H.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,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
4
|
-
const require_composition_sources = require("../../composition-sources-
|
|
3
|
+
const require_dist = require("../../dist-DRUzy1SF.js");
|
|
4
|
+
const require_composition_sources = require("../../composition-sources-BXZorHDO.js");
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
6
6
|
let _camstack_types_node = require("@camstack/types/node");
|
|
7
7
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as describeCompositionSources } from "../../composition-sources-
|
|
1
|
+
import { Cn as validateComposition, Hn as errMsg, In as compositionSourceKey, Un as BaseAddon, Y as buildCapabilityLookup, an as replacedFieldKeys, at as coreBlockSourceKind, d as CORE_BLOCK_ADDON_PREFIX, en as planComposition, f as CoreBlockSchema, it as coreBlockIdFromAddonId, jn as composedDeviceRef, l as COMPOSER_RUNNER_ID, mt as describeComposableCaps, nt as coreBlockAddonId, ot as coreBlocksCapability, rt as coreBlockComposition, t as ALL_CAPABILITY_DEFINITIONS, tt as compositionSourceRefs, u as CORE_BLOCKS_ADDON_ID, v as DeclaredDevices } from "../../dist-CoG8lY6H.mjs";
|
|
2
|
+
import { t as describeCompositionSources } from "../../composition-sources-aEEer5gE.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { customizationBlockName } from "@camstack/types/node";
|
|
5
5
|
import * as fs from "node:fs/promises";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AddonContext, CapabilityDefinition, DeviceBindingEntry, ICapabilityRegistry } from '@camstack/types';
|
|
2
2
|
import { DeviceBindingsStore } from './device-meta-types.js';
|
|
3
3
|
import { DeviceRow, DeviceRowStore } from './device-row-store.js';
|
|
4
|
+
import { StaleWrapperActivations } from './stale-wrapper-activations.js';
|
|
4
5
|
import { WriteLock } from './write-lock.js';
|
|
5
6
|
/** Push-fed remote native-cap cache shape (numeric deviceId → capName → owner). */
|
|
6
7
|
export type RemoteNativeCaps = Map<number, Map<string, {
|
|
@@ -40,6 +41,12 @@ export interface BindingsDeps {
|
|
|
40
41
|
* whatever toggle happens to be in flight.
|
|
41
42
|
*/
|
|
42
43
|
readonly withAddonStoreWriteLock: WriteLock;
|
|
44
|
+
/**
|
|
45
|
+
* The per-process memory of stored activations that name a RETIRED wrapper
|
|
46
|
+
* (a cap with no `kind: 'wrapper'` any more): each is ignored by step 1 and
|
|
47
|
+
* said once (task 17 review M1, `stale-wrapper-activations.ts`).
|
|
48
|
+
*/
|
|
49
|
+
readonly staleWrapperActivations: StaleWrapperActivations;
|
|
43
50
|
}
|
|
44
51
|
/**
|
|
45
52
|
* Wire the push-fed cross-process native-cap cache (`remoteNativeCaps`).
|
|
@@ -122,6 +122,9 @@ export declare class DeviceManagerAddon extends BaseAddon {
|
|
|
122
122
|
* one key range is the same defect one level up. Handed to both.
|
|
123
123
|
*/
|
|
124
124
|
private readonly addonStoreWriteLock;
|
|
125
|
+
/** Stored activations of RETIRED wrappers, said once per process (task 17 review M1). */
|
|
126
|
+
private staleWrapperActivationsImpl;
|
|
127
|
+
private get staleWrapperActivations();
|
|
125
128
|
/** Build the dependency context the extracted binding resolvers consume. */
|
|
126
129
|
private get bindingsDeps();
|
|
127
130
|
getBindings(input: {
|
|
@@ -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-DRUzy1SF.js");
|
|
7
|
+
const require_retired_settings_keys = require("../../retired-settings-keys-BY9H1I2b.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
10
10
|
let _camstack_types_node = require("@camstack/types/node");
|
|
@@ -1025,6 +1025,118 @@ function mergeAggregates(parts) {
|
|
|
1025
1025
|
return out;
|
|
1026
1026
|
}
|
|
1027
1027
|
//#endregion
|
|
1028
|
+
//#region src/builtins/device-manager/stale-wrapper-activations.ts
|
|
1029
|
+
/**
|
|
1030
|
+
* A stored wrapper activation that names a cap with NO wrapper any more.
|
|
1031
|
+
*
|
|
1032
|
+
* `deviceBindings[device][cap].wrapperAddonId` is the operator's choice of a
|
|
1033
|
+
* wrapper. When a wrapper is RETIRED (the `virtual-doorbell` on `doorbell`,
|
|
1034
|
+
* slice 6, D671), its rows outlive it: nothing deletes them (spec S1 — the
|
|
1035
|
+
* cluster is not written by code), and the admin UI no longer offers a toggle
|
|
1036
|
+
* for a cap that is not a wrapper cap. Routed as before, such a row shadows
|
|
1037
|
+
* the device's native (a composed doorbell) behind an addon that no longer
|
|
1038
|
+
* exists, keeps the cap advertised to HA / HAP / Alexa, and refuses every
|
|
1039
|
+
* call — without a line (task 17 review M1, D391).
|
|
1040
|
+
*
|
|
1041
|
+
* So the row is judged against the cap's DECLARED definition — static at boot,
|
|
1042
|
+
* never the live registry, because a wrapper runner that is still starting must
|
|
1043
|
+
* not read as stale. A string `wrapperAddonId` on a cap that is declared and is
|
|
1044
|
+
* not `kind: 'wrapper'` is treated as ABSENT: the cap resolves to its native
|
|
1045
|
+
* (or to nothing), exactly as if the row were not there. That loses no
|
|
1046
|
+
* doorbell: with a native, the native serves it; without one, the retired
|
|
1047
|
+
* addon could not serve it either. A cap this build does not declare is NOT
|
|
1048
|
+
* judged (unknown is not stale).
|
|
1049
|
+
*
|
|
1050
|
+
* It is said once per (device, cap) per process, by name, with the call that
|
|
1051
|
+
* clears the row. The whole store is checked once per process, read-only, so a
|
|
1052
|
+
* device nobody asks about is still named; a read that fails changes nothing,
|
|
1053
|
+
* says it could not check, and the next answered read checks instead (D49).
|
|
1054
|
+
* Generic on purpose: the next wrapper retirement gets the same backstop.
|
|
1055
|
+
*/
|
|
1056
|
+
var STALE_MESSAGE = "bindings: a stored wrapper activation names a cap with no wrapper — ignored, the cap resolves to its native";
|
|
1057
|
+
var UNCHECKED_MESSAGE = "bindings: could not read the stored wrapper activations — retired-wrapper rows not checked";
|
|
1058
|
+
var RECOVERY = "deviceManager.setWrapperActive({ deviceId, capName, wrapperAddonId, active: false })";
|
|
1059
|
+
/**
|
|
1060
|
+
* Every cap this build declares that is NOT a wrapper cap — built once from
|
|
1061
|
+
* the static table: `getAllBindings` is a scheduled hot path, and step 1 asks
|
|
1062
|
+
* this for every stored string activation (re-review N2).
|
|
1063
|
+
*/
|
|
1064
|
+
var DECLARED_NON_WRAPPER_CAPS = new Set(require_dist.ALL_CAPABILITY_DEFINITIONS.filter((cap) => cap.kind !== "wrapper").map((cap) => cap.name));
|
|
1065
|
+
/** True when `capName` is declared by this build and is NOT a wrapper cap. */
|
|
1066
|
+
function isDeclaredNonWrapperCap(capName) {
|
|
1067
|
+
return DECLARED_NON_WRAPPER_CAPS.has(capName);
|
|
1068
|
+
}
|
|
1069
|
+
function isRecord$1(value) {
|
|
1070
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1071
|
+
}
|
|
1072
|
+
/** A persisted activation of a wrapper on a cap that has none (see module docblock). */
|
|
1073
|
+
function isRetiredWrapperActivation(capName, wrapperAddonId) {
|
|
1074
|
+
return typeof wrapperAddonId === "string" && isDeclaredNonWrapperCap(capName);
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* The per-process memory: which (device, cap) rows have been said, and whether
|
|
1078
|
+
* the whole store has been checked once. Owned by the device-manager instance.
|
|
1079
|
+
*/
|
|
1080
|
+
var StaleWrapperActivations = class {
|
|
1081
|
+
logger;
|
|
1082
|
+
said = /* @__PURE__ */ new Set();
|
|
1083
|
+
checked = false;
|
|
1084
|
+
constructor(logger) {
|
|
1085
|
+
this.logger = logger;
|
|
1086
|
+
}
|
|
1087
|
+
/** Say one row, once per process. */
|
|
1088
|
+
report(deviceId, capName, wrapperAddonId) {
|
|
1089
|
+
const key = `${deviceId}\u0000${capName}`;
|
|
1090
|
+
if (this.said.has(key)) return;
|
|
1091
|
+
this.said.add(key);
|
|
1092
|
+
this.logger.warn(STALE_MESSAGE, {
|
|
1093
|
+
tags: { deviceId },
|
|
1094
|
+
meta: {
|
|
1095
|
+
capName,
|
|
1096
|
+
wrapperAddonId,
|
|
1097
|
+
recovery: RECOVERY
|
|
1098
|
+
}
|
|
1099
|
+
});
|
|
1100
|
+
}
|
|
1101
|
+
/**
|
|
1102
|
+
* Check a store that was already READ (by a bindings pass) — once per
|
|
1103
|
+
* process. It never throws: it runs inside every bindings pass and under the
|
|
1104
|
+
* boot `void` promise, so a corrupt entry (a null device or row, a hand edit,
|
|
1105
|
+
* a partial write) is skipped — a row it cannot read is not one it can judge
|
|
1106
|
+
* (re-review N1).
|
|
1107
|
+
*/
|
|
1108
|
+
checkStore(store) {
|
|
1109
|
+
if (this.checked) return;
|
|
1110
|
+
this.checked = true;
|
|
1111
|
+
const devices = store.deviceBindings;
|
|
1112
|
+
if (!isRecord$1(devices)) return;
|
|
1113
|
+
for (const [deviceKey, perDevice] of Object.entries(devices)) {
|
|
1114
|
+
const deviceId = Number(deviceKey);
|
|
1115
|
+
if (!Number.isInteger(deviceId) || !isRecord$1(perDevice)) continue;
|
|
1116
|
+
for (const [capName, row] of Object.entries(perDevice)) {
|
|
1117
|
+
const wrapperAddonId = isRecord$1(row) ? row["wrapperAddonId"] : void 0;
|
|
1118
|
+
if (typeof wrapperAddonId === "string" && isDeclaredNonWrapperCap(capName)) this.report(deviceId, capName, wrapperAddonId);
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
/** Read the store (read-only) and check it; a failed read changes nothing. */
|
|
1123
|
+
async checkOnce(read) {
|
|
1124
|
+
if (this.checked) return;
|
|
1125
|
+
let store;
|
|
1126
|
+
try {
|
|
1127
|
+
store = await read();
|
|
1128
|
+
} catch (err) {
|
|
1129
|
+
this.logger.warn(UNCHECKED_MESSAGE, { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
try {
|
|
1133
|
+
this.checkStore(store);
|
|
1134
|
+
} catch (err) {
|
|
1135
|
+
this.logger.warn(UNCHECKED_MESSAGE, { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
};
|
|
1139
|
+
//#endregion
|
|
1028
1140
|
//#region src/builtins/device-manager/device-bindings-store.ts
|
|
1029
1141
|
/**
|
|
1030
1142
|
* Wire the push-fed cross-process native-cap cache (`remoteNativeCaps`).
|
|
@@ -1265,6 +1377,7 @@ function collectionBindings(deps, deviceId, deviceType) {
|
|
|
1265
1377
|
}
|
|
1266
1378
|
async function getBindings(deps, input) {
|
|
1267
1379
|
const [row, store] = await Promise.all([deps.rows.get(input.deviceId), readBindingsStore(deps)]);
|
|
1380
|
+
deps.staleWrapperActivations.checkStore(store);
|
|
1268
1381
|
return resolveBindingsForDevice(deps, input.deviceId, row, {
|
|
1269
1382
|
store,
|
|
1270
1383
|
ledgerNonEmpty: onceLedgerNonEmpty(deps)
|
|
@@ -1309,6 +1422,10 @@ async function resolveBindingsForDevice(deps, deviceId, row, pass) {
|
|
|
1309
1422
|
const resolveRemote = (capName) => deps.remoteNativeCaps.get(deviceId)?.get(capName) ?? resolveRemoteNativeCapFromRegistry(deps, capName, deviceId);
|
|
1310
1423
|
for (const [capName, { wrapperAddonId }] of Object.entries(perDevice)) {
|
|
1311
1424
|
if (wrapperAddonId === void 0) continue;
|
|
1425
|
+
if (isRetiredWrapperActivation(capName, wrapperAddonId)) {
|
|
1426
|
+
deps.staleWrapperActivations.report(deviceId, capName, wrapperAddonId);
|
|
1427
|
+
continue;
|
|
1428
|
+
}
|
|
1312
1429
|
const hubLocalNative = deps.capabilityRegistry?.getNativeAddonId(capName, deviceId) ?? null;
|
|
1313
1430
|
const remoteNative = resolveRemote(capName);
|
|
1314
1431
|
const nativeAddonId = hubLocalNative ?? remoteNative?.addonId ?? "";
|
|
@@ -1433,6 +1550,7 @@ async function resolveBindingsForDevice(deps, deviceId, row, pass) {
|
|
|
1433
1550
|
async function getBindingsBatch(deps, input) {
|
|
1434
1551
|
const ids = [...new Set(input.deviceIds)];
|
|
1435
1552
|
const [rows, store] = await Promise.all([deps.rows.getMany(ids), readBindingsStore(deps)]);
|
|
1553
|
+
deps.staleWrapperActivations.checkStore(store);
|
|
1436
1554
|
const pass = {
|
|
1437
1555
|
store,
|
|
1438
1556
|
ledgerNonEmpty: onceLedgerNonEmpty(deps)
|
|
@@ -1463,6 +1581,7 @@ async function getBindingsBatch(deps, input) {
|
|
|
1463
1581
|
*/
|
|
1464
1582
|
async function getAllBindings(deps) {
|
|
1465
1583
|
const [fleet, store] = await Promise.all([deps.rows.listAll(), readBindingsStore(deps)]);
|
|
1584
|
+
deps.staleWrapperActivations.checkStore(store);
|
|
1466
1585
|
const rowById = /* @__PURE__ */ new Map();
|
|
1467
1586
|
const ids = /* @__PURE__ */ new Set();
|
|
1468
1587
|
for (const row of fleet) {
|
|
@@ -9638,6 +9757,12 @@ var DeviceManagerAddon = class extends require_dist.BaseAddon {
|
|
|
9638
9757
|
* one key range is the same defect one level up. Handed to both.
|
|
9639
9758
|
*/
|
|
9640
9759
|
addonStoreWriteLock = createWriteLock();
|
|
9760
|
+
/** Stored activations of RETIRED wrappers, said once per process (task 17 review M1). */
|
|
9761
|
+
staleWrapperActivationsImpl = null;
|
|
9762
|
+
get staleWrapperActivations() {
|
|
9763
|
+
this.staleWrapperActivationsImpl ??= new StaleWrapperActivations(this.ctx.logger);
|
|
9764
|
+
return this.staleWrapperActivationsImpl;
|
|
9765
|
+
}
|
|
9641
9766
|
/** Build the dependency context the extracted binding resolvers consume. */
|
|
9642
9767
|
get bindingsDeps() {
|
|
9643
9768
|
const rows = this.deviceRows;
|
|
@@ -9647,7 +9772,8 @@ var DeviceManagerAddon = class extends require_dist.BaseAddon {
|
|
|
9647
9772
|
capabilityRegistry: this.capabilityRegistry,
|
|
9648
9773
|
remoteNativeCaps: this.remoteNativeCaps,
|
|
9649
9774
|
rows,
|
|
9650
|
-
withAddonStoreWriteLock: this.addonStoreWriteLock
|
|
9775
|
+
withAddonStoreWriteLock: this.addonStoreWriteLock,
|
|
9776
|
+
staleWrapperActivations: this.staleWrapperActivations
|
|
9651
9777
|
};
|
|
9652
9778
|
}
|
|
9653
9779
|
async getBindings(input) {
|
|
@@ -9722,6 +9848,7 @@ var DeviceManagerAddon = class extends require_dist.BaseAddon {
|
|
|
9722
9848
|
const deviceRows = new DeviceRowStore(deviceRowBackendOf(settingsStoreApi), this.ctx.logger.child("rows"));
|
|
9723
9849
|
await deviceRows.declare();
|
|
9724
9850
|
this.deviceRows = deviceRows;
|
|
9851
|
+
this.staleWrapperActivations.checkOnce(() => readBindingsStore(this.bindingsDeps));
|
|
9725
9852
|
try {
|
|
9726
9853
|
await require_retired_settings_keys.purgeRetiredSettingsRows(deviceRows.retiredRowStore(), this.ctx.logger.child("RetiredRows"));
|
|
9727
9854
|
} catch (err) {
|