@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.
- package/dist/cjs/behavior/state/managed/Datasource.d.ts +2 -1
- package/dist/cjs/behavior/state/managed/Datasource.d.ts.map +1 -1
- package/dist/cjs/behavior/state/managed/Datasource.js +1 -1
- package/dist/cjs/behavior/state/managed/Datasource.js.map +1 -1
- package/dist/cjs/behavior/state/managed/ManagedReference.d.ts +0 -5
- package/dist/cjs/behavior/state/managed/ManagedReference.d.ts.map +1 -1
- package/dist/cjs/behavior/state/managed/ManagedReference.js +19 -67
- package/dist/cjs/behavior/state/managed/ManagedReference.js.map +1 -1
- package/dist/cjs/behavior/state/managed/MemberKeys.d.ts +25 -0
- package/dist/cjs/behavior/state/managed/MemberKeys.d.ts.map +1 -0
- package/dist/cjs/behavior/state/managed/MemberKeys.js +47 -0
- package/dist/cjs/behavior/state/managed/MemberKeys.js.map +6 -0
- package/dist/cjs/behavior/state/managed/NameResolver.d.ts.map +1 -1
- package/dist/cjs/behavior/state/managed/NameResolver.js +2 -4
- package/dist/cjs/behavior/state/managed/NameResolver.js.map +1 -1
- package/dist/cjs/behavior/state/managed/ValReference.d.ts +7 -1
- package/dist/cjs/behavior/state/managed/ValReference.d.ts.map +1 -1
- package/dist/cjs/behavior/state/managed/values/StructManager.d.ts.map +1 -1
- package/dist/cjs/behavior/state/managed/values/StructManager.js +19 -20
- package/dist/cjs/behavior/state/managed/values/StructManager.js.map +1 -1
- package/dist/cjs/behavior/supervision/RootSupervisor.d.ts +2 -1
- package/dist/cjs/behavior/supervision/RootSupervisor.d.ts.map +1 -1
- package/dist/cjs/behavior/supervision/RootSupervisor.js +3 -9
- package/dist/cjs/behavior/supervision/RootSupervisor.js.map +1 -1
- package/dist/cjs/node/client/ClientStructure.d.ts +2 -1
- package/dist/cjs/node/client/ClientStructure.d.ts.map +1 -1
- package/dist/cjs/node/client/ClientStructure.js +2 -1
- package/dist/cjs/node/client/ClientStructure.js.map +1 -1
- package/dist/esm/behavior/state/managed/Datasource.d.ts +2 -1
- package/dist/esm/behavior/state/managed/Datasource.d.ts.map +1 -1
- package/dist/esm/behavior/state/managed/Datasource.js +1 -1
- package/dist/esm/behavior/state/managed/Datasource.js.map +1 -1
- package/dist/esm/behavior/state/managed/ManagedReference.d.ts +0 -5
- package/dist/esm/behavior/state/managed/ManagedReference.d.ts.map +1 -1
- package/dist/esm/behavior/state/managed/ManagedReference.js +19 -67
- package/dist/esm/behavior/state/managed/ManagedReference.js.map +1 -1
- package/dist/esm/behavior/state/managed/MemberKeys.d.ts +25 -0
- package/dist/esm/behavior/state/managed/MemberKeys.d.ts.map +1 -0
- package/dist/esm/behavior/state/managed/MemberKeys.js +27 -0
- package/dist/esm/behavior/state/managed/MemberKeys.js.map +6 -0
- package/dist/esm/behavior/state/managed/NameResolver.d.ts.map +1 -1
- package/dist/esm/behavior/state/managed/NameResolver.js +2 -4
- package/dist/esm/behavior/state/managed/NameResolver.js.map +1 -1
- package/dist/esm/behavior/state/managed/ValReference.d.ts +7 -1
- package/dist/esm/behavior/state/managed/ValReference.d.ts.map +1 -1
- package/dist/esm/behavior/state/managed/values/StructManager.d.ts.map +1 -1
- package/dist/esm/behavior/state/managed/values/StructManager.js +19 -20
- package/dist/esm/behavior/state/managed/values/StructManager.js.map +1 -1
- package/dist/esm/behavior/supervision/RootSupervisor.d.ts +2 -1
- package/dist/esm/behavior/supervision/RootSupervisor.d.ts.map +1 -1
- package/dist/esm/behavior/supervision/RootSupervisor.js +3 -9
- package/dist/esm/behavior/supervision/RootSupervisor.js.map +1 -1
- package/dist/esm/node/client/ClientStructure.d.ts +2 -1
- package/dist/esm/node/client/ClientStructure.d.ts.map +1 -1
- package/dist/esm/node/client/ClientStructure.js +2 -1
- package/dist/esm/node/client/ClientStructure.js.map +1 -1
- package/package.json +6 -6
- package/src/behavior/state/managed/Datasource.ts +3 -3
- package/src/behavior/state/managed/ManagedReference.ts +23 -68
- package/src/behavior/state/managed/MemberKeys.ts +55 -0
- package/src/behavior/state/managed/NameResolver.ts +2 -4
- package/src/behavior/state/managed/ValReference.ts +8 -1
- package/src/behavior/state/managed/values/StructManager.ts +20 -23
- package/src/behavior/supervision/RootSupervisor.ts +4 -9
- 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
|
-
|
|
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:
|
|
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 =
|
|
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
|
|
201
|
-
|
|
202
|
-
|
|
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
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
|
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:
|
|
1183
|
+
primaryKey: ValReference.PrimaryKey,
|
|
1182
1184
|
) => Datasource.ExternallyMutableStore;
|
|
1183
1185
|
|
|
1184
1186
|
export interface Options {
|