@camstack/types 1.2.144 → 1.2.145

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.
@@ -66,11 +66,34 @@ export interface ContainerChildRef {
66
66
  */
67
67
  readonly entityId?: string;
68
68
  readonly type: string;
69
+ /**
70
+ * The child's `DeviceRole`, when the provider stamped one. Ranked BEFORE
71
+ * `type` — see {@link CONTAINER_CHILD_ROLE_PRIORITY}. Absent is normal and
72
+ * simply defers to type priority.
73
+ */
74
+ readonly role?: string;
75
+ /** The child's operator-facing name, used only for the namesake tiebreak. */
76
+ readonly name?: string;
69
77
  }
78
+ /**
79
+ * Roles that say what a container IS, most→least defining. Consulted BEFORE
80
+ * type priority, because `DeviceType` cannot tell them apart: Home Assistant
81
+ * maps a door contact, a battery level, a temperature reading and a "last seen"
82
+ * timestamp all to `DeviceType.Sensor`. Measured on container 4127 — children
83
+ * `battery-sensor`, `temperature-sensor`, `datetime-sensor`, `contact-sensor`
84
+ * and a role-less `button` — the type list ranked `button` above `sensor` and
85
+ * the container stood for its "Identifica" button instead of the door contact
86
+ * it is named after.
87
+ *
88
+ * Only STATE-DEFINING roles belong here. A diagnostic reading (battery,
89
+ * temperature, humidity, signal, last-seen) is never what a container is, so
90
+ * they are deliberately absent and fall through to type priority.
91
+ */
92
+ export declare const CONTAINER_CHILD_ROLE_PRIORITY: readonly string[];
70
93
  /**
71
94
  * The child a container stands for: the operator's pick when it still exists,
72
95
  * else the highest-priority type. `null` for a childless container — a caller
73
96
  * must decide what an empty container means for it, rather than being handed a
74
97
  * child that is not there.
75
98
  */
76
- export declare function resolveContainerPrimaryChild(children: readonly ContainerChildRef[], overrideEntityId: string | null | undefined): ContainerChildRef | null;
99
+ export declare function resolveContainerPrimaryChild(children: readonly ContainerChildRef[], overrideEntityId: string | null | undefined, containerName?: string): ContainerChildRef | null;
package/dist/index.js CHANGED
@@ -35551,6 +35551,39 @@ var CONTAINER_CHILD_PRIORITY = [
35551
35551
  "image",
35552
35552
  "sensor"
35553
35553
  ];
35554
+ /**
35555
+ * Roles that say what a container IS, most→least defining. Consulted BEFORE
35556
+ * type priority, because `DeviceType` cannot tell them apart: Home Assistant
35557
+ * maps a door contact, a battery level, a temperature reading and a "last seen"
35558
+ * timestamp all to `DeviceType.Sensor`. Measured on container 4127 — children
35559
+ * `battery-sensor`, `temperature-sensor`, `datetime-sensor`, `contact-sensor`
35560
+ * and a role-less `button` — the type list ranked `button` above `sensor` and
35561
+ * the container stood for its "Identifica" button instead of the door contact
35562
+ * it is named after.
35563
+ *
35564
+ * Only STATE-DEFINING roles belong here. A diagnostic reading (battery,
35565
+ * temperature, humidity, signal, last-seen) is never what a container is, so
35566
+ * they are deliberately absent and fall through to type priority.
35567
+ */
35568
+ var CONTAINER_CHILD_ROLE_PRIORITY = [
35569
+ "contact-sensor",
35570
+ "motion-sensor",
35571
+ "occupancy-sensor",
35572
+ "smoke-sensor",
35573
+ "co-sensor",
35574
+ "gas-sensor",
35575
+ "leak-sensor",
35576
+ "vibration-sensor",
35577
+ "tamper-sensor",
35578
+ "sound-sensor",
35579
+ "binary-sensor",
35580
+ "binary-helper"
35581
+ ];
35582
+ function roleRank(role) {
35583
+ if (role === void 0) return CONTAINER_CHILD_ROLE_PRIORITY.length;
35584
+ const i = CONTAINER_CHILD_ROLE_PRIORITY.indexOf(role);
35585
+ return i === -1 ? CONTAINER_CHILD_ROLE_PRIORITY.length : i;
35586
+ }
35554
35587
  function rank(type) {
35555
35588
  const i = CONTAINER_CHILD_PRIORITY.indexOf(type);
35556
35589
  return i === -1 ? CONTAINER_CHILD_PRIORITY.length : i;
@@ -35561,12 +35594,13 @@ function rank(type) {
35561
35594
  * must decide what an empty container means for it, rather than being handed a
35562
35595
  * child that is not there.
35563
35596
  */
35564
- function resolveContainerPrimaryChild(children, overrideEntityId) {
35597
+ function resolveContainerPrimaryChild(children, overrideEntityId, containerName) {
35565
35598
  if (overrideEntityId !== void 0 && overrideEntityId !== null) {
35566
35599
  const picked = children.find((c) => c.stableId === overrideEntityId) ?? children.find((c) => c.entityId !== void 0 && c.entityId === overrideEntityId);
35567
35600
  if (picked !== void 0) return picked;
35568
35601
  }
35569
- return [...children].toSorted((a, b) => rank(a.type) - rank(b.type))[0] ?? null;
35602
+ const namesake = (c) => containerName !== void 0 && containerName.length > 0 && c.name !== void 0 && c.name.toLowerCase() === containerName.toLowerCase() ? 0 : 1;
35603
+ return [...children].toSorted((a, b) => roleRank(a.role) - roleRank(b.role) || namesake(a) - namesake(b) || rank(a.type) - rank(b.type))[0] ?? null;
35570
35604
  }
35571
35605
  //#endregion
35572
35606
  //#region src/device/accessory.ts
package/dist/index.mjs CHANGED
@@ -35543,6 +35543,39 @@ var CONTAINER_CHILD_PRIORITY = [
35543
35543
  "image",
35544
35544
  "sensor"
35545
35545
  ];
35546
+ /**
35547
+ * Roles that say what a container IS, most→least defining. Consulted BEFORE
35548
+ * type priority, because `DeviceType` cannot tell them apart: Home Assistant
35549
+ * maps a door contact, a battery level, a temperature reading and a "last seen"
35550
+ * timestamp all to `DeviceType.Sensor`. Measured on container 4127 — children
35551
+ * `battery-sensor`, `temperature-sensor`, `datetime-sensor`, `contact-sensor`
35552
+ * and a role-less `button` — the type list ranked `button` above `sensor` and
35553
+ * the container stood for its "Identifica" button instead of the door contact
35554
+ * it is named after.
35555
+ *
35556
+ * Only STATE-DEFINING roles belong here. A diagnostic reading (battery,
35557
+ * temperature, humidity, signal, last-seen) is never what a container is, so
35558
+ * they are deliberately absent and fall through to type priority.
35559
+ */
35560
+ var CONTAINER_CHILD_ROLE_PRIORITY = [
35561
+ "contact-sensor",
35562
+ "motion-sensor",
35563
+ "occupancy-sensor",
35564
+ "smoke-sensor",
35565
+ "co-sensor",
35566
+ "gas-sensor",
35567
+ "leak-sensor",
35568
+ "vibration-sensor",
35569
+ "tamper-sensor",
35570
+ "sound-sensor",
35571
+ "binary-sensor",
35572
+ "binary-helper"
35573
+ ];
35574
+ function roleRank(role) {
35575
+ if (role === void 0) return CONTAINER_CHILD_ROLE_PRIORITY.length;
35576
+ const i = CONTAINER_CHILD_ROLE_PRIORITY.indexOf(role);
35577
+ return i === -1 ? CONTAINER_CHILD_ROLE_PRIORITY.length : i;
35578
+ }
35546
35579
  function rank(type) {
35547
35580
  const i = CONTAINER_CHILD_PRIORITY.indexOf(type);
35548
35581
  return i === -1 ? CONTAINER_CHILD_PRIORITY.length : i;
@@ -35553,12 +35586,13 @@ function rank(type) {
35553
35586
  * must decide what an empty container means for it, rather than being handed a
35554
35587
  * child that is not there.
35555
35588
  */
35556
- function resolveContainerPrimaryChild(children, overrideEntityId) {
35589
+ function resolveContainerPrimaryChild(children, overrideEntityId, containerName) {
35557
35590
  if (overrideEntityId !== void 0 && overrideEntityId !== null) {
35558
35591
  const picked = children.find((c) => c.stableId === overrideEntityId) ?? children.find((c) => c.entityId !== void 0 && c.entityId === overrideEntityId);
35559
35592
  if (picked !== void 0) return picked;
35560
35593
  }
35561
- return [...children].toSorted((a, b) => rank(a.type) - rank(b.type))[0] ?? null;
35594
+ const namesake = (c) => containerName !== void 0 && containerName.length > 0 && c.name !== void 0 && c.name.toLowerCase() === containerName.toLowerCase() ? 0 : 1;
35595
+ return [...children].toSorted((a, b) => roleRank(a.role) - roleRank(b.role) || namesake(a) - namesake(b) || rank(a.type) - rank(b.type))[0] ?? null;
35562
35596
  }
35563
35597
  //#endregion
35564
35598
  //#region src/device/accessory.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.144",
3
+ "version": "1.2.145",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",