@camstack/types 1.2.241 → 1.2.242
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/device/container-primary-child.d.ts +0 -6
- package/dist/index.js +28 -1
- package/dist/index.mjs +28 -1
- package/package.json +1 -1
|
@@ -90,10 +90,4 @@ export interface ContainerChildRef {
|
|
|
90
90
|
* they are deliberately absent and fall through to type priority.
|
|
91
91
|
*/
|
|
92
92
|
export declare const CONTAINER_CHILD_ROLE_PRIORITY: readonly string[];
|
|
93
|
-
/**
|
|
94
|
-
* The child a container stands for: the operator's pick when it still exists,
|
|
95
|
-
* else the highest-priority type. `null` for a childless container — a caller
|
|
96
|
-
* must decide what an empty container means for it, rather than being handed a
|
|
97
|
-
* child that is not there.
|
|
98
|
-
*/
|
|
99
93
|
export declare function resolveContainerPrimaryChild(children: readonly ContainerChildRef[], overrideEntityId: string | null | undefined, containerName?: string): ContainerChildRef | null;
|
package/dist/index.js
CHANGED
|
@@ -42717,12 +42717,39 @@ function rank(type) {
|
|
|
42717
42717
|
* must decide what an empty container means for it, rather than being handed a
|
|
42718
42718
|
* child that is not there.
|
|
42719
42719
|
*/
|
|
42720
|
+
/**
|
|
42721
|
+
* Two names for the same thing, compared the way an integration writes them.
|
|
42722
|
+
*
|
|
42723
|
+
* An exact case-insensitive match was not enough, and the failure was total
|
|
42724
|
+
* rather than marginal. An ESPHome shutter arrives as a container named
|
|
42725
|
+
* `Tapparella-Cucina` whose children include the COVER, named `Tapparella
|
|
42726
|
+
* cucina`, and a device-presence entity carrying the slug verbatim,
|
|
42727
|
+
* `tapparella-cucina`. The slug matched the container exactly and the cover
|
|
42728
|
+
* did not, so the namesake tie-break handed the container to a connectivity
|
|
42729
|
+
* indicator — and the viewer's accessory panel, which correctly shows only
|
|
42730
|
+
* children with an actuating control, then rendered NOTHING. The operator saw
|
|
42731
|
+
* no shutters at all on cucina, studio and both veranda cameras (2026-09-22).
|
|
42732
|
+
*
|
|
42733
|
+
* `Markise` was the control case that proved the mechanism: there the cover
|
|
42734
|
+
* really is called exactly like its container, so it won and appeared.
|
|
42735
|
+
*
|
|
42736
|
+
* Separators are therefore normalised — `-`, `_` and whitespace are the same
|
|
42737
|
+
* character for this comparison, and runs of them collapse. The two candidates
|
|
42738
|
+
* then tie on the namesake and the decision falls through to `rank(type)`,
|
|
42739
|
+
* where `cover` is eighth and a `presence` entity is not listed at all. The
|
|
42740
|
+
* criterion keeps doing its job for a container whose child IS the namesake;
|
|
42741
|
+
* it stops being decided by which integration used a hyphen.
|
|
42742
|
+
*/
|
|
42743
|
+
function sameName(childName, containerName) {
|
|
42744
|
+
const flatten = (v) => v.toLowerCase().replace(/[-_\s]+/g, " ").trim();
|
|
42745
|
+
return flatten(childName) === flatten(containerName);
|
|
42746
|
+
}
|
|
42720
42747
|
function resolveContainerPrimaryChild(children, overrideEntityId, containerName) {
|
|
42721
42748
|
if (overrideEntityId !== void 0 && overrideEntityId !== null) {
|
|
42722
42749
|
const picked = children.find((c) => c.stableId === overrideEntityId) ?? children.find((c) => c.entityId !== void 0 && c.entityId === overrideEntityId);
|
|
42723
42750
|
if (picked !== void 0) return picked;
|
|
42724
42751
|
}
|
|
42725
|
-
const namesake = (c) => containerName !== void 0 && containerName.length > 0 && c.name !== void 0 && c.name
|
|
42752
|
+
const namesake = (c) => containerName !== void 0 && containerName.length > 0 && c.name !== void 0 && sameName(c.name, containerName) ? 0 : 1;
|
|
42726
42753
|
return [...children].toSorted((a, b) => roleRank(a.role) - roleRank(b.role) || namesake(a) - namesake(b) || rank(a.type) - rank(b.type))[0] ?? null;
|
|
42727
42754
|
}
|
|
42728
42755
|
//#endregion
|
package/dist/index.mjs
CHANGED
|
@@ -42716,12 +42716,39 @@ function rank(type) {
|
|
|
42716
42716
|
* must decide what an empty container means for it, rather than being handed a
|
|
42717
42717
|
* child that is not there.
|
|
42718
42718
|
*/
|
|
42719
|
+
/**
|
|
42720
|
+
* Two names for the same thing, compared the way an integration writes them.
|
|
42721
|
+
*
|
|
42722
|
+
* An exact case-insensitive match was not enough, and the failure was total
|
|
42723
|
+
* rather than marginal. An ESPHome shutter arrives as a container named
|
|
42724
|
+
* `Tapparella-Cucina` whose children include the COVER, named `Tapparella
|
|
42725
|
+
* cucina`, and a device-presence entity carrying the slug verbatim,
|
|
42726
|
+
* `tapparella-cucina`. The slug matched the container exactly and the cover
|
|
42727
|
+
* did not, so the namesake tie-break handed the container to a connectivity
|
|
42728
|
+
* indicator — and the viewer's accessory panel, which correctly shows only
|
|
42729
|
+
* children with an actuating control, then rendered NOTHING. The operator saw
|
|
42730
|
+
* no shutters at all on cucina, studio and both veranda cameras (2026-09-22).
|
|
42731
|
+
*
|
|
42732
|
+
* `Markise` was the control case that proved the mechanism: there the cover
|
|
42733
|
+
* really is called exactly like its container, so it won and appeared.
|
|
42734
|
+
*
|
|
42735
|
+
* Separators are therefore normalised — `-`, `_` and whitespace are the same
|
|
42736
|
+
* character for this comparison, and runs of them collapse. The two candidates
|
|
42737
|
+
* then tie on the namesake and the decision falls through to `rank(type)`,
|
|
42738
|
+
* where `cover` is eighth and a `presence` entity is not listed at all. The
|
|
42739
|
+
* criterion keeps doing its job for a container whose child IS the namesake;
|
|
42740
|
+
* it stops being decided by which integration used a hyphen.
|
|
42741
|
+
*/
|
|
42742
|
+
function sameName(childName, containerName) {
|
|
42743
|
+
const flatten = (v) => v.toLowerCase().replace(/[-_\s]+/g, " ").trim();
|
|
42744
|
+
return flatten(childName) === flatten(containerName);
|
|
42745
|
+
}
|
|
42719
42746
|
function resolveContainerPrimaryChild(children, overrideEntityId, containerName) {
|
|
42720
42747
|
if (overrideEntityId !== void 0 && overrideEntityId !== null) {
|
|
42721
42748
|
const picked = children.find((c) => c.stableId === overrideEntityId) ?? children.find((c) => c.entityId !== void 0 && c.entityId === overrideEntityId);
|
|
42722
42749
|
if (picked !== void 0) return picked;
|
|
42723
42750
|
}
|
|
42724
|
-
const namesake = (c) => containerName !== void 0 && containerName.length > 0 && c.name !== void 0 && c.name
|
|
42751
|
+
const namesake = (c) => containerName !== void 0 && containerName.length > 0 && c.name !== void 0 && sameName(c.name, containerName) ? 0 : 1;
|
|
42725
42752
|
return [...children].toSorted((a, b) => roleRank(a.role) - roleRank(b.role) || namesake(a) - namesake(b) || rank(a.type) - rank(b.type))[0] ?? null;
|
|
42726
42753
|
}
|
|
42727
42754
|
//#endregion
|