@matter/node 0.17.9-alpha.0-20260805-cb9a8ce7b → 0.17.9

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.
Files changed (65) hide show
  1. package/dist/cjs/behavior/state/managed/Datasource.d.ts +2 -1
  2. package/dist/cjs/behavior/state/managed/Datasource.d.ts.map +1 -1
  3. package/dist/cjs/behavior/state/managed/Datasource.js +1 -1
  4. package/dist/cjs/behavior/state/managed/Datasource.js.map +1 -1
  5. package/dist/cjs/behavior/state/managed/ManagedReference.d.ts +0 -5
  6. package/dist/cjs/behavior/state/managed/ManagedReference.d.ts.map +1 -1
  7. package/dist/cjs/behavior/state/managed/ManagedReference.js +19 -67
  8. package/dist/cjs/behavior/state/managed/ManagedReference.js.map +1 -1
  9. package/dist/cjs/behavior/state/managed/MemberKeys.d.ts +25 -0
  10. package/dist/cjs/behavior/state/managed/MemberKeys.d.ts.map +1 -0
  11. package/dist/cjs/behavior/state/managed/MemberKeys.js +47 -0
  12. package/dist/cjs/behavior/state/managed/MemberKeys.js.map +6 -0
  13. package/dist/cjs/behavior/state/managed/NameResolver.d.ts.map +1 -1
  14. package/dist/cjs/behavior/state/managed/NameResolver.js +2 -4
  15. package/dist/cjs/behavior/state/managed/NameResolver.js.map +1 -1
  16. package/dist/cjs/behavior/state/managed/ValReference.d.ts +7 -1
  17. package/dist/cjs/behavior/state/managed/ValReference.d.ts.map +1 -1
  18. package/dist/cjs/behavior/state/managed/values/StructManager.d.ts.map +1 -1
  19. package/dist/cjs/behavior/state/managed/values/StructManager.js +19 -20
  20. package/dist/cjs/behavior/state/managed/values/StructManager.js.map +1 -1
  21. package/dist/cjs/behavior/supervision/RootSupervisor.d.ts +2 -1
  22. package/dist/cjs/behavior/supervision/RootSupervisor.d.ts.map +1 -1
  23. package/dist/cjs/behavior/supervision/RootSupervisor.js +3 -9
  24. package/dist/cjs/behavior/supervision/RootSupervisor.js.map +1 -1
  25. package/dist/cjs/node/client/ClientStructure.d.ts +2 -1
  26. package/dist/cjs/node/client/ClientStructure.d.ts.map +1 -1
  27. package/dist/cjs/node/client/ClientStructure.js +2 -1
  28. package/dist/cjs/node/client/ClientStructure.js.map +1 -1
  29. package/dist/esm/behavior/state/managed/Datasource.d.ts +2 -1
  30. package/dist/esm/behavior/state/managed/Datasource.d.ts.map +1 -1
  31. package/dist/esm/behavior/state/managed/Datasource.js +1 -1
  32. package/dist/esm/behavior/state/managed/Datasource.js.map +1 -1
  33. package/dist/esm/behavior/state/managed/ManagedReference.d.ts +0 -5
  34. package/dist/esm/behavior/state/managed/ManagedReference.d.ts.map +1 -1
  35. package/dist/esm/behavior/state/managed/ManagedReference.js +19 -67
  36. package/dist/esm/behavior/state/managed/ManagedReference.js.map +1 -1
  37. package/dist/esm/behavior/state/managed/MemberKeys.d.ts +25 -0
  38. package/dist/esm/behavior/state/managed/MemberKeys.d.ts.map +1 -0
  39. package/dist/esm/behavior/state/managed/MemberKeys.js +27 -0
  40. package/dist/esm/behavior/state/managed/MemberKeys.js.map +6 -0
  41. package/dist/esm/behavior/state/managed/NameResolver.d.ts.map +1 -1
  42. package/dist/esm/behavior/state/managed/NameResolver.js +2 -4
  43. package/dist/esm/behavior/state/managed/NameResolver.js.map +1 -1
  44. package/dist/esm/behavior/state/managed/ValReference.d.ts +7 -1
  45. package/dist/esm/behavior/state/managed/ValReference.d.ts.map +1 -1
  46. package/dist/esm/behavior/state/managed/values/StructManager.d.ts.map +1 -1
  47. package/dist/esm/behavior/state/managed/values/StructManager.js +19 -20
  48. package/dist/esm/behavior/state/managed/values/StructManager.js.map +1 -1
  49. package/dist/esm/behavior/supervision/RootSupervisor.d.ts +2 -1
  50. package/dist/esm/behavior/supervision/RootSupervisor.d.ts.map +1 -1
  51. package/dist/esm/behavior/supervision/RootSupervisor.js +3 -9
  52. package/dist/esm/behavior/supervision/RootSupervisor.js.map +1 -1
  53. package/dist/esm/node/client/ClientStructure.d.ts +2 -1
  54. package/dist/esm/node/client/ClientStructure.d.ts.map +1 -1
  55. package/dist/esm/node/client/ClientStructure.js +2 -1
  56. package/dist/esm/node/client/ClientStructure.js.map +1 -1
  57. package/package.json +6 -6
  58. package/src/behavior/state/managed/Datasource.ts +3 -3
  59. package/src/behavior/state/managed/ManagedReference.ts +23 -68
  60. package/src/behavior/state/managed/MemberKeys.ts +55 -0
  61. package/src/behavior/state/managed/NameResolver.ts +2 -4
  62. package/src/behavior/state/managed/ValReference.ts +8 -1
  63. package/src/behavior/state/managed/values/StructManager.ts +20 -23
  64. package/src/behavior/supervision/RootSupervisor.ts +4 -9
  65. package/src/node/client/ClientStructure.ts +5 -3
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2026 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import type { Val } from "@matter/protocol";
8
+ import type { ValReference } from "./ValReference.js";
9
+
10
+ /**
11
+ * The slot a member occupies in a container keyed by {@link ValReference.primaryKey}.
12
+ *
13
+ * The persisted key set ({@link RootSupervisor.persistentKeys}) and a datasource container's own keys must both
14
+ * derive from this function — if they diverge, attributes silently stop persisting.
15
+ */
16
+ export function memberKeyFor(
17
+ primaryKey: ValReference.PrimaryKey,
18
+ name: string | number,
19
+ id: number | undefined,
20
+ ): string | number {
21
+ return primaryKey === "id" ? (id ?? name) : name;
22
+ }
23
+
24
+ /**
25
+ * The key under the other keying convention, if distinct from {@link memberKeyFor}'s — whether a reader may fall
26
+ * back to it is the reader's policy.
27
+ */
28
+ export function memberFallbackKeyFor(
29
+ primaryKey: ValReference.PrimaryKey,
30
+ name: string | number,
31
+ id: number | undefined,
32
+ ): string | number | undefined {
33
+ const key = memberKeyFor(primaryKey, name, id);
34
+ return primaryKey === "id" ? (key === name ? undefined : name) : id;
35
+ }
36
+
37
+ /**
38
+ * Read a member from container at key, falling back to fallbackKey; a caller passes `undefined` for fallbackKey
39
+ * when it must not tolerate the fallback slot.
40
+ */
41
+ export function memberValueOf(
42
+ container: Val.Struct,
43
+ key: string | number,
44
+ fallbackKey: string | number | undefined,
45
+ ): Val | undefined {
46
+ if (key in container) {
47
+ return container[key];
48
+ }
49
+
50
+ if (fallbackKey !== undefined && fallbackKey in container) {
51
+ return container[fallbackKey];
52
+ }
53
+
54
+ return undefined;
55
+ }
@@ -9,6 +9,7 @@ import type { Schema } from "@matter/model";
9
9
  import { ClusterModel, Model, ValueModel, type FieldValue } from "@matter/model";
10
10
  import { Val } from "@matter/protocol";
11
11
  import { Internal } from "./Internal.js";
12
+ import { memberValueOf } from "./MemberKeys.js";
12
13
 
13
14
  /**
14
15
  * Obtain a function that returns a visible property by name from the ownership hierarchy of a managed value.
@@ -70,10 +71,7 @@ export function NameResolver(
70
71
  if (struct === undefined || struct === null) {
71
72
  return undefined;
72
73
  }
73
- if (id in struct) {
74
- return struct[id];
75
- }
76
- return struct[name];
74
+ return memberValueOf(struct, id, name);
77
75
  };
78
76
  }
79
77
 
@@ -56,7 +56,7 @@ export interface ValReference<T extends Val = Val> {
56
56
  * How this container keys its own members. Only a datasource root may key by element ID; every nested container
57
57
  * keys by property name (list entries, by index).
58
58
  */
59
- readonly primaryKey: "id" | "name";
59
+ readonly primaryKey: ValReference.PrimaryKey;
60
60
 
61
61
  /**
62
62
  * The managed value that owns the reference.
@@ -78,3 +78,10 @@ export interface ValReference<T extends Val = Val> {
78
78
  */
79
79
  supervisionConfig?: Supervision.Config;
80
80
  }
81
+
82
+ export namespace ValReference {
83
+ /**
84
+ * How a container keys its own members.
85
+ */
86
+ export type PrimaryKey = "id" | "name";
87
+ }
@@ -14,6 +14,7 @@ import type { ValueSupervisor } from "../../../supervision/ValueSupervisor.js";
14
14
  import { Instrumentation } from "../Instrumentation.js";
15
15
  import { Internal } from "../Internal.js";
16
16
  import { ManagedReference } from "../ManagedReference.js";
17
+ import { memberFallbackKeyFor, memberKeyFor, memberValueOf } from "../MemberKeys.js";
17
18
  import { NameResolver } from "../NameResolver.js";
18
19
  import type { ValReference } from "../ValReference.js";
19
20
  import { PrimitiveManager } from "./PrimitiveManager.js";
@@ -193,17 +194,14 @@ function configureProperty(supervisor: RootSupervisor, schema: ValueModel) {
193
194
 
194
195
  // We allow attribute/field name or id as key. If name is present id is ignored
195
196
  const pk = this[Internal.reference].primaryKey;
196
- let key = ManagedReference.keyFor(this[Internal.reference], name, id);
197
+ let key = memberKeyFor(pk, name, id);
197
198
  let storedKey: undefined | number | string;
198
199
  if (key in this[Internal.reference].value) {
199
200
  storedKey = key;
200
- } else if (pk === "id") {
201
- if (name in this[Internal.reference].value) {
202
- storedKey = name;
203
- }
204
- } else if (id !== undefined) {
205
- if (id in this[Internal.reference].value) {
206
- storedKey = id;
201
+ } else {
202
+ const fallbackKey = memberFallbackKeyFor(pk, name, id);
203
+ if (fallbackKey !== undefined && fallbackKey in this[Internal.reference].value) {
204
+ storedKey = fallbackKey;
207
205
  }
208
206
  }
209
207
 
@@ -295,17 +293,12 @@ function configureProperty(supervisor: RootSupervisor, schema: ValueModel) {
295
293
  }
296
294
  }
297
295
 
298
- const key = ManagedReference.keyFor(this[Internal.reference], name, id);
299
- if (key in struct) {
300
- return struct[key];
301
- }
302
-
303
- const key2 = this[Internal.reference].primaryKey === "id" ? name : id;
304
- if (key2 !== undefined && key2 in struct) {
305
- return struct[key2];
306
- }
307
-
308
- return undefined;
296
+ const primaryKey = this[Internal.reference].primaryKey;
297
+ return memberValueOf(
298
+ struct,
299
+ memberKeyFor(primaryKey, name, id),
300
+ memberFallbackKeyFor(primaryKey, name, id),
301
+ );
309
302
  }
310
303
  };
311
304
  } else {
@@ -338,7 +331,8 @@ function configureProperty(supervisor: RootSupervisor, schema: ValueModel) {
338
331
 
339
332
  // Obtain the value. Normally just struct[key] except in the case of Val.Dynamic
340
333
  const struct = this[Internal.reference].value;
341
- const key = ManagedReference.keyFor(this[Internal.reference], name, id);
334
+ const primaryKey = this[Internal.reference].primaryKey;
335
+ const key = memberKeyFor(primaryKey, name, id);
342
336
  if ((struct as Val.Dynamic)[Val.properties]) {
343
337
  const properties = (struct as Val.Dynamic)[Val.properties](
344
338
  this[Internal.reference].rootOwner,
@@ -351,10 +345,13 @@ function configureProperty(supervisor: RootSupervisor, schema: ValueModel) {
351
345
  }
352
346
  } else if (key in struct) {
353
347
  value = struct[key];
354
- } else if (id !== undefined && key !== id && id in struct) {
348
+ } else if (primaryKey === "name") {
355
349
  // A value decoded without a schema — an unknown cluster or attribute, including one a later model
356
- // learns about — keys its members by TLV tag number, so a name-keyed container accepts the ID too
357
- value = struct[id];
350
+ // learns about — keys its members by TLV tag number, so a name-keyed container accepts the ID too.
351
+ const fallbackKey = memberFallbackKeyFor(primaryKey, name, id);
352
+ if (fallbackKey !== undefined && fallbackKey in struct) {
353
+ value = struct[fallbackKey];
354
+ }
358
355
  }
359
356
 
360
357
  // Note that we only mask values that are unreadable. This is appropriate when the parent object is
@@ -20,6 +20,8 @@ import {
20
20
  } from "@matter/model";
21
21
  import { AccessControl, Val } from "@matter/protocol";
22
22
  import { AttributeId } from "@matter/types";
23
+ import { memberKeyFor } from "../state/managed/MemberKeys.js";
24
+ import type { ValReference } from "../state/managed/ValReference.js";
23
25
  import { ValueCaster } from "../state/managed/values/ValueCaster.js";
24
26
  import { ValueManager } from "../state/managed/values/ValueManager.js";
25
27
  import { ValuePatcher } from "../state/managed/values/ValuePatcher.js";
@@ -155,7 +157,7 @@ export class RootSupervisor implements ValueSupervisor {
155
157
  /**
156
158
  * Retrieve names or IDs of fields configured as non-volatile.
157
159
  */
158
- persistentKeys(key: "id" | "name" = "name") {
160
+ persistentKeys(primaryKey: ValReference.PrimaryKey = "name") {
159
161
  const persistent = new Set<string>();
160
162
 
161
163
  for (const member of this.#members) {
@@ -166,14 +168,7 @@ export class RootSupervisor implements ValueSupervisor {
166
168
  (member.tag === ElementTag.Attribute &&
167
169
  (member.effectiveAccess.writable || member.effectiveAccess.fabricScoped))
168
170
  ) {
169
- if (key === "id") {
170
- const id = member.effectiveId;
171
- if (id !== undefined) {
172
- persistent.add(id.toString());
173
- continue;
174
- }
175
- }
176
- persistent.add(member.propertyName);
171
+ persistent.add(String(memberKeyFor(primaryKey, member.propertyName, member.effectiveId)));
177
172
  }
178
173
  }
179
174
  return persistent;
@@ -7,6 +7,8 @@
7
7
  import { ClusterBehavior } from "#behavior/cluster/ClusterBehavior.js";
8
8
  import type { ClusterBehaviorType } from "#behavior/cluster/ClusterBehaviorType.js";
9
9
  import { Datasource } from "#behavior/state/managed/Datasource.js";
10
+ import { memberValueOf } from "#behavior/state/managed/MemberKeys.js";
11
+ import type { ValReference } from "#behavior/state/managed/ValReference.js";
10
12
  import { Endpoint } from "#endpoint/Endpoint.js";
11
13
  import { EndpointType } from "#endpoint/type/EndpointType.js";
12
14
  import { RootEndpoint } from "#endpoints/root";
@@ -62,13 +64,13 @@ const SERVER_LIST_ATTR_NAME = "serverList";
62
64
  const PARTS_LIST_ATTR_NAME = "partsList";
63
65
 
64
66
  /**
65
- * Read a value from store initial values using either numeric attribute ID or property name.
67
+ * Read a value from store initial values, preferring the numeric attribute ID slot over the property name slot.
66
68
  */
67
69
  function getStoreValue(values: Record<string | number, unknown> | undefined, id: number, name: string): unknown {
68
70
  if (values === undefined) {
69
71
  return undefined;
70
72
  }
71
- return id in values ? values[id] : values[name];
73
+ return memberValueOf(values, id, name);
72
74
  }
73
75
 
74
76
  /**
@@ -1178,7 +1180,7 @@ export namespace ClientStructure {
1178
1180
  export type StoreFactory = (
1179
1181
  endpoint: Endpoint,
1180
1182
  behaviorId: string,
1181
- primaryKey: "id" | "name",
1183
+ primaryKey: ValReference.PrimaryKey,
1182
1184
  ) => Datasource.ExternallyMutableStore;
1183
1185
 
1184
1186
  export interface Options {