@camstack/system 1.2.321 → 1.2.323
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/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/addon.d.ts +13 -1
- package/dist/builtins/camera-grid/index.js +46 -12
- package/dist/builtins/camera-grid/index.mjs +46 -12
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/composition-api.d.ts +4 -2
- package/dist/builtins/core-blocks/core-blocks.addon.js +6 -4
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +6 -4
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/doorbell/doorbell-composition-migration.d.ts +1 -13
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +6 -64
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +5 -63
- 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/snapshot/index.js +18 -5
- package/dist/builtins/snapshot/index.mjs +18 -5
- package/dist/builtins/snapshot/snapshot.addon.d.ts +3 -0
- 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/{composition-sources-iDqQVPng.mjs → composition-sources-CeAPNF5Q.mjs} +1 -1
- package/dist/{composition-sources-gGrw35Lt.js → composition-sources-DkVxrXLm.js} +1 -1
- package/dist/{dist-BVHQ6TX1.mjs → dist-Bs6UyVGd.mjs} +2020 -1479
- package/dist/{dist-BMDYmNV3.js → dist-Bup0sTZb.js} +2043 -1490
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{retired-settings-keys-FhjpCM5N.js → retired-settings-keys-Db0P4Yvn.js} +1 -1
- package/dist/{retired-settings-keys-BlQLUReM.mjs → retired-settings-keys-LROp1DXx.mjs} +1 -1
- package/package.json +1 -1
|
@@ -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-Bup0sTZb.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 { Kn as errMsg, R as addonPagesCapability, _r as EventCategory, qn as BaseAddon } from "../../dist-Bs6UyVGd.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-Bup0sTZb.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 { B as addonWidgetsCapability,
|
|
1
|
+
import { B as addonWidgetsCapability, Kn as errMsg, _r as EventCategory, qn as BaseAddon } from "../../dist-Bs6UyVGd.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-Bup0sTZb.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 { Kn as errMsg, V as alertsCapability, _r as EventCategory, n as AlertSchema, qn as BaseAddon, rr as createEvent } from "../../dist-Bs6UyVGd.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-Bup0sTZb.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 { Kn as errMsg, W as bareAddonId, _ as FIRST_LEVEL_MACRO_CLASSES, _r as EventCategory, lr as isEvent, qn as BaseAddon, rn as ptzAutotrackCapability } from "../../dist-Bs6UyVGd.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-Bup0sTZb.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, U as backupCapability, _r as EventCategory, qn as BaseAddon, vn as storageOccupancyCapability } from "../../dist-Bs6UyVGd.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";
|
|
@@ -26,7 +26,13 @@ export declare class CameraGridAddon extends BaseAddon<CameraGridAddonConfig> {
|
|
|
26
26
|
private activity;
|
|
27
27
|
private snapshots;
|
|
28
28
|
private frameSampler;
|
|
29
|
+
/** The node's pinned ffmpeg (D540). `null` until init resolved it — a
|
|
30
|
+
* composition then refuses by name; there is no PATH default. */
|
|
29
31
|
private ffmpegBinaryPath;
|
|
32
|
+
/** The node's pinned build, remembered only on success (D540). */
|
|
33
|
+
private readonly pinnedFfmpeg;
|
|
34
|
+
/** A resolution in flight, so a reconcile pass never starts a second. */
|
|
35
|
+
private ffmpegResolving;
|
|
30
36
|
private integrationId;
|
|
31
37
|
constructor();
|
|
32
38
|
protected onInitialize(): Promise<AddonInitResult>;
|
|
@@ -147,7 +153,13 @@ export declare class CameraGridAddon extends BaseAddon<CameraGridAddonConfig> {
|
|
|
147
153
|
private instanceForDevice;
|
|
148
154
|
private gridViewFor;
|
|
149
155
|
private saveGridLayout;
|
|
150
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Resolve the pinned build, single-flighted, and hand it to the frame sampler.
|
|
158
|
+
* Never throws: a failure is an ERROR and leaves the binary unknown, so the
|
|
159
|
+
* next pass that wants a composition asks again. Never PATH: the host's
|
|
160
|
+
* ffmpeg is not ours (`packages/types/src/deps/ffmpeg-binary-source.ts`).
|
|
161
|
+
*/
|
|
162
|
+
private resolveFfmpeg;
|
|
151
163
|
/**
|
|
152
164
|
* The integration page: a list of grids, with a NAME.
|
|
153
165
|
*
|
|
@@ -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-Bup0sTZb.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");
|
|
@@ -2982,7 +2982,13 @@ var CameraGridAddon = class extends require_dist.BaseAddon {
|
|
|
2982
2982
|
activity = null;
|
|
2983
2983
|
snapshots = null;
|
|
2984
2984
|
frameSampler = null;
|
|
2985
|
-
|
|
2985
|
+
/** The node's pinned ffmpeg (D540). `null` until init resolved it — a
|
|
2986
|
+
* composition then refuses by name; there is no PATH default. */
|
|
2987
|
+
ffmpegBinaryPath = null;
|
|
2988
|
+
/** The node's pinned build, remembered only on success (D540). */
|
|
2989
|
+
pinnedFfmpeg = require_dist.memoizePinnedFfmpeg(() => this.ctx.deps.ensureFfmpeg());
|
|
2990
|
+
/** A resolution in flight, so a reconcile pass never starts a second. */
|
|
2991
|
+
ffmpegResolving = null;
|
|
2986
2992
|
integrationId;
|
|
2987
2993
|
constructor() {
|
|
2988
2994
|
super({ ...DEFAULTS });
|
|
@@ -2991,17 +2997,13 @@ var CameraGridAddon = class extends require_dist.BaseAddon {
|
|
|
2991
2997
|
this.replaceTombstones(this.config.cameraGridTombstones);
|
|
2992
2998
|
await this.normalizeRows();
|
|
2993
2999
|
if (require_dist.declarationOwnerNodeId(this.ctx.kernel.localNodeId) === "hub") {
|
|
2994
|
-
|
|
3000
|
+
await this.resolveFfmpeg();
|
|
2995
3001
|
const relay = new GridStreamRelay({
|
|
2996
3002
|
logger: this.ctx.logger.child("relay"),
|
|
2997
3003
|
sessionFor: (request) => this.sessionFor(request)
|
|
2998
3004
|
});
|
|
2999
3005
|
await relay.start();
|
|
3000
3006
|
this.relay = relay;
|
|
3001
|
-
this.frameSampler = new GridFrameSampler({
|
|
3002
|
-
binaryPath: this.ffmpegBinaryPath,
|
|
3003
|
-
logger: this.ctx.logger.child("snapshot")
|
|
3004
|
-
});
|
|
3005
3007
|
this.snapshots = new GridSnapshotSource({
|
|
3006
3008
|
logger: this.ctx.logger.child("snapshot"),
|
|
3007
3009
|
sessionsFor: (deviceId) => this.sessionsForDevice(deviceId),
|
|
@@ -3341,7 +3343,19 @@ var CameraGridAddon = class extends require_dist.BaseAddon {
|
|
|
3341
3343
|
continue;
|
|
3342
3344
|
}
|
|
3343
3345
|
if (this.sessions.has(key)) continue;
|
|
3344
|
-
|
|
3346
|
+
const binaryPath = this.ffmpegBinaryPath;
|
|
3347
|
+
if (binaryPath === null) {
|
|
3348
|
+
this.ctx.logger.error("camera-grid: composition refused — no pinned ffmpeg on this node (D540)", {
|
|
3349
|
+
tags: { deviceId },
|
|
3350
|
+
meta: {
|
|
3351
|
+
instanceId,
|
|
3352
|
+
profile
|
|
3353
|
+
}
|
|
3354
|
+
});
|
|
3355
|
+
this.resolveFfmpeg();
|
|
3356
|
+
continue;
|
|
3357
|
+
}
|
|
3358
|
+
this.sessions.set(key, new GridSessionEntry(instanceId, profile, this.makeSession(instanceId, deviceId, profile, binaryPath)));
|
|
3345
3359
|
}
|
|
3346
3360
|
}
|
|
3347
3361
|
/**
|
|
@@ -3371,9 +3385,9 @@ var CameraGridAddon = class extends require_dist.BaseAddon {
|
|
|
3371
3385
|
}
|
|
3372
3386
|
return names;
|
|
3373
3387
|
}
|
|
3374
|
-
makeSession(instanceId, deviceId, profile) {
|
|
3388
|
+
makeSession(instanceId, deviceId, profile, binaryPath) {
|
|
3375
3389
|
const childContext = {
|
|
3376
|
-
binaryPath
|
|
3390
|
+
binaryPath,
|
|
3377
3391
|
logger: this.ctx.logger,
|
|
3378
3392
|
deviceId,
|
|
3379
3393
|
resolveSourceNames: (deviceIds) => this.sourceNames(deviceIds)
|
|
@@ -3590,8 +3604,28 @@ var CameraGridAddon = class extends require_dist.BaseAddon {
|
|
|
3590
3604
|
if (!view) throw new Error("camera-grid: the grid vanished while it was being saved");
|
|
3591
3605
|
return view;
|
|
3592
3606
|
}
|
|
3593
|
-
|
|
3594
|
-
|
|
3607
|
+
/**
|
|
3608
|
+
* Resolve the pinned build, single-flighted, and hand it to the frame sampler.
|
|
3609
|
+
* Never throws: a failure is an ERROR and leaves the binary unknown, so the
|
|
3610
|
+
* next pass that wants a composition asks again. Never PATH: the host's
|
|
3611
|
+
* ffmpeg is not ours (`packages/types/src/deps/ffmpeg-binary-source.ts`).
|
|
3612
|
+
*/
|
|
3613
|
+
resolveFfmpeg() {
|
|
3614
|
+
if (this.ffmpegBinaryPath !== null) return Promise.resolve();
|
|
3615
|
+
if (this.ffmpegResolving !== null) return this.ffmpegResolving;
|
|
3616
|
+
const attempt = this.pinnedFfmpeg().then((binaryPath) => {
|
|
3617
|
+
this.ffmpegBinaryPath = binaryPath;
|
|
3618
|
+
this.frameSampler = new GridFrameSampler({
|
|
3619
|
+
binaryPath,
|
|
3620
|
+
logger: this.ctx.logger.child("snapshot")
|
|
3621
|
+
});
|
|
3622
|
+
}).catch((err) => {
|
|
3623
|
+
this.ctx.logger.error("camera-grid: the pinned ffmpeg could not be resolved — compositions refuse until it is (D540)", { meta: { error: require_dist.errMsg(err) } });
|
|
3624
|
+
}).finally(() => {
|
|
3625
|
+
this.ffmpegResolving = null;
|
|
3626
|
+
});
|
|
3627
|
+
this.ffmpegResolving = attempt;
|
|
3628
|
+
return attempt;
|
|
3595
3629
|
}
|
|
3596
3630
|
/**
|
|
3597
3631
|
* The integration page: a list of grids, with a NAME.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gn as
|
|
1
|
+
import { Gn as DeviceType, Kn as errMsg, Kt as memoizePinnedFfmpeg, T as MOTION_CLOSE_AFTER_MS, Un as DeviceFeature, Y as cameraGridLayoutCapability, Yt as motionCapability, _r as EventCategory, bn as streamCatalogCapability, h as DeclaredDevices, hn as snapshotCapability, i as BaseDevice, jn as buildFfmpegArgs, m as DERIVED_CAMERA_SILENCED_CAP_NAMES, qn as BaseAddon, rr as createEvent, sr as hydrateSchema, st as declarationOwnerNodeId } from "../../dist-Bs6UyVGd.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { FfmpegProcess } from "@camstack/types/node";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -2977,7 +2977,13 @@ var CameraGridAddon = class extends BaseAddon {
|
|
|
2977
2977
|
activity = null;
|
|
2978
2978
|
snapshots = null;
|
|
2979
2979
|
frameSampler = null;
|
|
2980
|
-
|
|
2980
|
+
/** The node's pinned ffmpeg (D540). `null` until init resolved it — a
|
|
2981
|
+
* composition then refuses by name; there is no PATH default. */
|
|
2982
|
+
ffmpegBinaryPath = null;
|
|
2983
|
+
/** The node's pinned build, remembered only on success (D540). */
|
|
2984
|
+
pinnedFfmpeg = memoizePinnedFfmpeg(() => this.ctx.deps.ensureFfmpeg());
|
|
2985
|
+
/** A resolution in flight, so a reconcile pass never starts a second. */
|
|
2986
|
+
ffmpegResolving = null;
|
|
2981
2987
|
integrationId;
|
|
2982
2988
|
constructor() {
|
|
2983
2989
|
super({ ...DEFAULTS });
|
|
@@ -2986,17 +2992,13 @@ var CameraGridAddon = class extends BaseAddon {
|
|
|
2986
2992
|
this.replaceTombstones(this.config.cameraGridTombstones);
|
|
2987
2993
|
await this.normalizeRows();
|
|
2988
2994
|
if (declarationOwnerNodeId(this.ctx.kernel.localNodeId) === "hub") {
|
|
2989
|
-
|
|
2995
|
+
await this.resolveFfmpeg();
|
|
2990
2996
|
const relay = new GridStreamRelay({
|
|
2991
2997
|
logger: this.ctx.logger.child("relay"),
|
|
2992
2998
|
sessionFor: (request) => this.sessionFor(request)
|
|
2993
2999
|
});
|
|
2994
3000
|
await relay.start();
|
|
2995
3001
|
this.relay = relay;
|
|
2996
|
-
this.frameSampler = new GridFrameSampler({
|
|
2997
|
-
binaryPath: this.ffmpegBinaryPath,
|
|
2998
|
-
logger: this.ctx.logger.child("snapshot")
|
|
2999
|
-
});
|
|
3000
3002
|
this.snapshots = new GridSnapshotSource({
|
|
3001
3003
|
logger: this.ctx.logger.child("snapshot"),
|
|
3002
3004
|
sessionsFor: (deviceId) => this.sessionsForDevice(deviceId),
|
|
@@ -3336,7 +3338,19 @@ var CameraGridAddon = class extends BaseAddon {
|
|
|
3336
3338
|
continue;
|
|
3337
3339
|
}
|
|
3338
3340
|
if (this.sessions.has(key)) continue;
|
|
3339
|
-
|
|
3341
|
+
const binaryPath = this.ffmpegBinaryPath;
|
|
3342
|
+
if (binaryPath === null) {
|
|
3343
|
+
this.ctx.logger.error("camera-grid: composition refused — no pinned ffmpeg on this node (D540)", {
|
|
3344
|
+
tags: { deviceId },
|
|
3345
|
+
meta: {
|
|
3346
|
+
instanceId,
|
|
3347
|
+
profile
|
|
3348
|
+
}
|
|
3349
|
+
});
|
|
3350
|
+
this.resolveFfmpeg();
|
|
3351
|
+
continue;
|
|
3352
|
+
}
|
|
3353
|
+
this.sessions.set(key, new GridSessionEntry(instanceId, profile, this.makeSession(instanceId, deviceId, profile, binaryPath)));
|
|
3340
3354
|
}
|
|
3341
3355
|
}
|
|
3342
3356
|
/**
|
|
@@ -3366,9 +3380,9 @@ var CameraGridAddon = class extends BaseAddon {
|
|
|
3366
3380
|
}
|
|
3367
3381
|
return names;
|
|
3368
3382
|
}
|
|
3369
|
-
makeSession(instanceId, deviceId, profile) {
|
|
3383
|
+
makeSession(instanceId, deviceId, profile, binaryPath) {
|
|
3370
3384
|
const childContext = {
|
|
3371
|
-
binaryPath
|
|
3385
|
+
binaryPath,
|
|
3372
3386
|
logger: this.ctx.logger,
|
|
3373
3387
|
deviceId,
|
|
3374
3388
|
resolveSourceNames: (deviceIds) => this.sourceNames(deviceIds)
|
|
@@ -3585,8 +3599,28 @@ var CameraGridAddon = class extends BaseAddon {
|
|
|
3585
3599
|
if (!view) throw new Error("camera-grid: the grid vanished while it was being saved");
|
|
3586
3600
|
return view;
|
|
3587
3601
|
}
|
|
3588
|
-
|
|
3589
|
-
|
|
3602
|
+
/**
|
|
3603
|
+
* Resolve the pinned build, single-flighted, and hand it to the frame sampler.
|
|
3604
|
+
* Never throws: a failure is an ERROR and leaves the binary unknown, so the
|
|
3605
|
+
* next pass that wants a composition asks again. Never PATH: the host's
|
|
3606
|
+
* ffmpeg is not ours (`packages/types/src/deps/ffmpeg-binary-source.ts`).
|
|
3607
|
+
*/
|
|
3608
|
+
resolveFfmpeg() {
|
|
3609
|
+
if (this.ffmpegBinaryPath !== null) return Promise.resolve();
|
|
3610
|
+
if (this.ffmpegResolving !== null) return this.ffmpegResolving;
|
|
3611
|
+
const attempt = this.pinnedFfmpeg().then((binaryPath) => {
|
|
3612
|
+
this.ffmpegBinaryPath = binaryPath;
|
|
3613
|
+
this.frameSampler = new GridFrameSampler({
|
|
3614
|
+
binaryPath,
|
|
3615
|
+
logger: this.ctx.logger.child("snapshot")
|
|
3616
|
+
});
|
|
3617
|
+
}).catch((err) => {
|
|
3618
|
+
this.ctx.logger.error("camera-grid: the pinned ffmpeg could not be resolved — compositions refuse until it is (D540)", { meta: { error: errMsg(err) } });
|
|
3619
|
+
}).finally(() => {
|
|
3620
|
+
this.ffmpegResolving = null;
|
|
3621
|
+
});
|
|
3622
|
+
this.ffmpegResolving = attempt;
|
|
3623
|
+
return attempt;
|
|
3590
3624
|
}
|
|
3591
3625
|
/**
|
|
3592
3626
|
* The integration page: a list of grids, with a NAME.
|
|
@@ -3,9 +3,9 @@ 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-Bup0sTZb.js");
|
|
7
7
|
const require_device_state_changed = require("../../device-state-changed-Bk7cvTnz.js");
|
|
8
|
-
const require_composition_sources = require("../../composition-sources-
|
|
8
|
+
const require_composition_sources = require("../../composition-sources-DkVxrXLm.js");
|
|
9
9
|
//#region src/builtins/composer/composed-device.ts
|
|
10
10
|
/**
|
|
11
11
|
* A composed device: an ordinary `BaseDevice` whose caps are served by the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Fn as compositionFeatureEnabled, Gn as DeviceType, Hn as toExpressionValue, In as compositionItemFieldPath, K as buildCapabilityLookup, Kn as errMsg, Ln as compositionSliceKey, Mn as cloneStatefulExpressionMemory, Nn as composedDeviceRef, On as COMPOSER_ADDON_ID, Pn as composedDeviceStableId, Q as compositionFieldKey, Rn as compositionSourceKey, Z as composerCapability, _r as EventCategory, c as COMPOSED_ITEM_FIXED_FIELDS, en as planComposition, h as DeclaredDevices, i as BaseDevice, qn as BaseAddon, rr as createEvent, t as ALL_CAPABILITY_DEFINITIONS, xt as evaluateCompositionField, zn as createStatefulExpressionMemory } from "../../dist-Bs6UyVGd.mjs";
|
|
2
2
|
import { n as parseDeviceStateChanged, t as isRecord$2 } from "../../device-state-changed-DoBbkyEI.mjs";
|
|
3
|
-
import { n as normalizedNativeOwner } from "../../composition-sources-
|
|
3
|
+
import { n as normalizedNativeOwner } from "../../composition-sources-CeAPNF5Q.mjs";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/builtins/composer/composed-device.ts
|
|
6
6
|
/**
|
|
@@ -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-Bup0sTZb.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 { Vt as logDestinationCapability, qn as BaseAddon } from "../../dist-Bs6UyVGd.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,4 +1,4 @@
|
|
|
1
|
-
import { CapabilityLookup, CompositionBlockPatch, CompositionBlockState, CompositionSourceRef, CoreBlock, ICoreBlocksProvider, IScopedLogger } from '@camstack/types';
|
|
1
|
+
import { CapabilityDefinition, CapabilityLookup, CompositionBlockPatch, CompositionBlockState, CompositionSourceRef, CoreBlock, ICoreBlocksProvider, IScopedLogger } from '@camstack/types';
|
|
2
2
|
import { NamedCompositionInput } from './core-block-store.js';
|
|
3
3
|
import { CompositionDescriptions } from './composition-sources.js';
|
|
4
4
|
export interface CompositionStoreView {
|
|
@@ -17,8 +17,10 @@ export interface CompositionApiDeps {
|
|
|
17
17
|
readonly composerStates: (blockIds: readonly string[]) => Promise<readonly CompositionBlockState[]>;
|
|
18
18
|
readonly convergeSoon: () => void;
|
|
19
19
|
readonly logger: IScopedLogger;
|
|
20
|
+
/** Every capability definition — the listing is derived from them, never from the registry's live state. */
|
|
21
|
+
readonly capabilityDefinitions: readonly CapabilityDefinition[];
|
|
20
22
|
}
|
|
21
|
-
export type CompositionApi = Pick<ICoreBlocksProvider, 'createComposition' | 'updateComposition' | 'getComposition' | 'listCompositions' | 'validateComposition' | 'getCustomization'>;
|
|
23
|
+
export type CompositionApi = Pick<ICoreBlocksProvider, 'createComposition' | 'updateComposition' | 'getComposition' | 'listCompositions' | 'validateComposition' | 'getCustomization' | 'listComposableCaps'>;
|
|
22
24
|
/**
|
|
23
25
|
* Every write runs validate-then-persist on ONE chain. Validation awaits a
|
|
24
26
|
* source read before the save lands; two unserialized saves (A reads B, B
|
|
@@ -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-Bup0sTZb.js");
|
|
4
|
+
const require_composition_sources = require("../../composition-sources-DkVxrXLm.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");
|
|
@@ -1407,7 +1407,8 @@ function buildCompositionApi(deps) {
|
|
|
1407
1407
|
}
|
|
1408
1408
|
};
|
|
1409
1409
|
},
|
|
1410
|
-
validateComposition: async ({ composition, blockId }) => validateAgainstStore(deps, composition, blockId ?? null)
|
|
1410
|
+
validateComposition: async ({ composition, blockId }) => validateAgainstStore(deps, composition, blockId ?? null),
|
|
1411
|
+
listComposableCaps: async ({ deviceType }) => ({ caps: [...require_dist.describeComposableCaps(deps.capabilityDefinitions, deviceType)] })
|
|
1411
1412
|
};
|
|
1412
1413
|
}
|
|
1413
1414
|
//#endregion
|
|
@@ -1705,7 +1706,8 @@ var CoreBlocksAddon = class extends require_dist.BaseAddon {
|
|
|
1705
1706
|
lookupCap: require_dist.buildCapabilityLookup(require_dist.ALL_CAPABILITY_DEFINITIONS),
|
|
1706
1707
|
composerStates: async (blockIds) => (await requireApi().composer.getStates.query({ blockIds: [...blockIds] })).states,
|
|
1707
1708
|
convergeSoon: () => this.convergeSoon(),
|
|
1708
|
-
logger: this.ctx.logger.child("compositions")
|
|
1709
|
+
logger: this.ctx.logger.child("compositions"),
|
|
1710
|
+
capabilityDefinitions: require_dist.ALL_CAPABILITY_DEFINITIONS
|
|
1709
1711
|
});
|
|
1710
1712
|
}
|
|
1711
1713
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { t as describeCompositionSources } from "../../composition-sources-
|
|
1
|
+
import { $ as compositionSourceRefs, Cn as validateComposition, K as buildCapabilityLookup, Kn as errMsg, Nn as composedDeviceRef, Rn as compositionSourceKey, an as replacedFieldKeys, d as CORE_BLOCK_ADDON_PREFIX, dt as describeComposableCaps, en as planComposition, et as coreBlockAddonId, f as CoreBlockSchema, h as DeclaredDevices, it as coreBlocksCapability, l as COMPOSER_RUNNER_ID, nt as coreBlockIdFromAddonId, qn as BaseAddon, rt as coreBlockSourceKind, t as ALL_CAPABILITY_DEFINITIONS, tt as coreBlockComposition, u as CORE_BLOCKS_ADDON_ID } from "../../dist-Bs6UyVGd.mjs";
|
|
2
|
+
import { t as describeCompositionSources } from "../../composition-sources-CeAPNF5Q.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";
|
|
@@ -1403,7 +1403,8 @@ function buildCompositionApi(deps) {
|
|
|
1403
1403
|
}
|
|
1404
1404
|
};
|
|
1405
1405
|
},
|
|
1406
|
-
validateComposition: async ({ composition, blockId }) => validateAgainstStore(deps, composition, blockId ?? null)
|
|
1406
|
+
validateComposition: async ({ composition, blockId }) => validateAgainstStore(deps, composition, blockId ?? null),
|
|
1407
|
+
listComposableCaps: async ({ deviceType }) => ({ caps: [...describeComposableCaps(deps.capabilityDefinitions, deviceType)] })
|
|
1407
1408
|
};
|
|
1408
1409
|
}
|
|
1409
1410
|
//#endregion
|
|
@@ -1701,7 +1702,8 @@ var CoreBlocksAddon = class extends BaseAddon {
|
|
|
1701
1702
|
lookupCap: buildCapabilityLookup(ALL_CAPABILITY_DEFINITIONS),
|
|
1702
1703
|
composerStates: async (blockIds) => (await requireApi().composer.getStates.query({ blockIds: [...blockIds] })).states,
|
|
1703
1704
|
convergeSoon: () => this.convergeSoon(),
|
|
1704
|
-
logger: this.ctx.logger.child("compositions")
|
|
1705
|
+
logger: this.ctx.logger.child("compositions"),
|
|
1706
|
+
capabilityDefinitions: ALL_CAPABILITY_DEFINITIONS
|
|
1705
1707
|
});
|
|
1706
1708
|
}
|
|
1707
1709
|
};
|
|
@@ -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-Bup0sTZb.js");
|
|
7
|
+
const require_retired_settings_keys = require("../../retired-settings-keys-Db0P4Yvn.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");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-
|
|
1
|
+
import { $n as WELL_KNOWN_TAB_MAP, $t as parseStreamParamsFormPatch, Bt as locationIconKey, Ct as expandContainer, Dt as formatMinutes, Gn as DeviceType, It as legacyAutoLinkIds, J as buildStreamParamsConfigSchema, Kn as errMsg, S as LocationIconIdSchema, Un as DeviceFeature, Wn as DeviceRole, Xt as normalizeUnit, _r as EventCategory, at as createDeviceExtensionProvider, bt as enumerateSchemaFields, cr as isDeviceConfigCap, ft as deviceExtensionCapability, g as DeviceStatusSchema, gr as sleep$1, ht as deviceStatusCapability, j as STREAM_PROFILE_META, ln as runtimeStatePolicyFor, lt as defineExtensionSlotProvider, mn as siteZoneKey, mt as deviceStateCapability, o as CAMERA_SWITCH_ORDER, p as DAY_NAMES, pt as deviceManagerCapability, qn as BaseAddon, s as CAP_NAMES_WITH_STATUS, t as ALL_CAPABILITY_DEFINITIONS, v as FieldClaimModeSchema, w as MINUTES_PER_DAY, y as FieldClaimSchema, yt as enumerateItemArrayFields } from "../../dist-Bs6UyVGd.mjs";
|
|
2
|
+
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-LROp1DXx.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { canonicalDeviceFingerprint } from "@camstack/types/node";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DeviceType, ICoreBlocksProvider, IScopedLogger } from '@camstack/types';
|
|
2
2
|
import { BindingEntryView } from './binding-mirror.js';
|
|
3
3
|
import { DoorbellSource } from './doorbell-settings.js';
|
|
4
4
|
export declare const DOORBELL_COMPOSITION_MIGRATION_STATE_KEY = "doorbell-source-composition-migration-v1";
|
|
@@ -32,17 +32,6 @@ export interface DoorbellCompositionMigrationDeps {
|
|
|
32
32
|
readonly isComplete: () => Promise<boolean>;
|
|
33
33
|
readonly markComplete: () => Promise<void>;
|
|
34
34
|
}
|
|
35
|
-
interface DoorbellFeatureSource {
|
|
36
|
-
readonly source: CompositionSourceRef;
|
|
37
|
-
readonly cap: string;
|
|
38
|
-
readonly activeField: string;
|
|
39
|
-
readonly changedAtField: string;
|
|
40
|
-
}
|
|
41
|
-
export declare function buildDoorbellCompositionFeature(input: {
|
|
42
|
-
readonly camera: CompositionSourceRef;
|
|
43
|
-
readonly sources: readonly DoorbellFeatureSource[];
|
|
44
|
-
readonly enabled: boolean;
|
|
45
|
-
}): CompositionFieldsFeature;
|
|
46
35
|
export declare class DoorbellCompositionMigration {
|
|
47
36
|
private readonly deps;
|
|
48
37
|
private rerunRequested;
|
|
@@ -56,4 +45,3 @@ export declare class DoorbellCompositionMigration {
|
|
|
56
45
|
private runAttempt;
|
|
57
46
|
private warnCamera;
|
|
58
47
|
}
|
|
59
|
-
export {};
|
|
@@ -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-Bup0sTZb.js");
|
|
7
7
|
const require_device_state_changed = require("../../device-state-changed-Bk7cvTnz.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
@@ -612,50 +612,6 @@ var DOORBELL_COMPOSITION_MIGRATION_CALLER = {
|
|
|
612
612
|
userId: "system:doorbell-source-migration",
|
|
613
613
|
isAdmin: true
|
|
614
614
|
};
|
|
615
|
-
function buildDoorbellCompositionFeature(input) {
|
|
616
|
-
const sources = [...input.sources].toSorted((a, b) => `${a.source.addonId}/${a.source.stableId}#${a.cap}`.localeCompare(`${b.source.addonId}/${b.source.stableId}#${b.cap}`));
|
|
617
|
-
if (sources.length === 0) throw new Error("doorbell composition needs at least one source");
|
|
618
|
-
const edgeBindings = {};
|
|
619
|
-
sources.forEach((entry, index) => {
|
|
620
|
-
edgeBindings[`active${index}`] = {
|
|
621
|
-
kind: "from",
|
|
622
|
-
source: entry.source,
|
|
623
|
-
cap: entry.cap,
|
|
624
|
-
fieldPath: entry.activeField
|
|
625
|
-
};
|
|
626
|
-
edgeBindings[`changed${index}`] = {
|
|
627
|
-
kind: "from",
|
|
628
|
-
source: entry.source,
|
|
629
|
-
cap: entry.cap,
|
|
630
|
-
fieldPath: entry.changedAtField
|
|
631
|
-
};
|
|
632
|
-
});
|
|
633
|
-
return {
|
|
634
|
-
kind: "fields",
|
|
635
|
-
cap: "doorbell",
|
|
636
|
-
enabled: input.enabled,
|
|
637
|
-
fields: {
|
|
638
|
-
lastPressedAt: {
|
|
639
|
-
kind: "expression",
|
|
640
|
-
expr: `latest(${sources.map((_, index) => `rose(active${index}, changed${index}, 2000)`).join(", ")})`,
|
|
641
|
-
bindings: edgeBindings
|
|
642
|
-
},
|
|
643
|
-
pressCountSinceStart: {
|
|
644
|
-
kind: "expression",
|
|
645
|
-
expr: "count(lastPressedAt)",
|
|
646
|
-
bindings: { lastPressedAt: {
|
|
647
|
-
kind: "from",
|
|
648
|
-
source: {
|
|
649
|
-
addonId: input.camera.addonId,
|
|
650
|
-
stableId: input.camera.stableId
|
|
651
|
-
},
|
|
652
|
-
cap: "doorbell",
|
|
653
|
-
fieldPath: "lastPressedAt"
|
|
654
|
-
} }
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
615
|
function isRecord(value) {
|
|
660
616
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
661
617
|
}
|
|
@@ -671,32 +627,18 @@ function withoutEnabled(feature) {
|
|
|
671
627
|
const { enabled: _enabled, ...rest } = feature;
|
|
672
628
|
return rest;
|
|
673
629
|
}
|
|
674
|
-
function bindingHasCap(entries, cap) {
|
|
675
|
-
return entries.some((entry) => entry.capName === cap);
|
|
676
|
-
}
|
|
677
630
|
function migrationSources(camera, configured, devicesById, bindingsById) {
|
|
678
631
|
const sources = [];
|
|
679
632
|
for (const configuredSource of configured) {
|
|
680
633
|
const device = devicesById.get(configuredSource.deviceId);
|
|
681
634
|
const entries = bindingsById.get(configuredSource.deviceId);
|
|
682
635
|
if (device === void 0 || entries === void 0) throw new Error(`source device ${configuredSource.deviceId} could not be resolved and read`);
|
|
683
|
-
const
|
|
636
|
+
const found = require_dist.doorbellFeatureSources({
|
|
684
637
|
addonId: device.addonId,
|
|
685
638
|
stableId: device.stableId
|
|
686
|
-
};
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
for (const cap of supportedCaps) {
|
|
690
|
-
const activeField = require_dist.SOURCE_CAP_ACTIVE_FIELD[cap];
|
|
691
|
-
const changedAtField = require_dist.SOURCE_CAP_CHANGED_AT_FIELD[cap];
|
|
692
|
-
if (activeField === void 0 || changedAtField === void 0) throw new Error(`source capability ${cap} has no transition field mapping`);
|
|
693
|
-
sources.push({
|
|
694
|
-
source: ref,
|
|
695
|
-
cap,
|
|
696
|
-
activeField,
|
|
697
|
-
changedAtField
|
|
698
|
-
});
|
|
699
|
-
}
|
|
639
|
+
}, entries.map((entry) => entry.capName));
|
|
640
|
+
if (found.length === 0) throw new Error(`source device ${configuredSource.deviceId} has no supported source capability`);
|
|
641
|
+
sources.push(...found);
|
|
700
642
|
}
|
|
701
643
|
if (sources.length === 0) throw new Error(`camera ${camera.id} has no resolvable doorbell sources`);
|
|
702
644
|
return sources;
|
|
@@ -803,7 +745,7 @@ var DoorbellCompositionMigration = class {
|
|
|
803
745
|
const composerBound = composerIsBound(entries);
|
|
804
746
|
const crashRecovery = !wrapperActive && composerBound && existingDoorbell?.kind === "fields" && existingDoorbell.enabled === true;
|
|
805
747
|
const enabled = wrapperActive || crashRecovery;
|
|
806
|
-
const canonical = buildDoorbellCompositionFeature({
|
|
748
|
+
const canonical = require_dist.buildDoorbellCompositionFeature({
|
|
807
749
|
camera: cameraRef,
|
|
808
750
|
sources,
|
|
809
751
|
enabled
|