@matter/node 0.16.0-alpha.0-20251018-dd1ea6a8a → 0.16.0-alpha.0-20251020-3f6e46245

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 (127) hide show
  1. package/dist/cjs/behavior/Behavior.d.ts +1 -1
  2. package/dist/cjs/behavior/Behavior.d.ts.map +1 -1
  3. package/dist/cjs/behavior/Behavior.js +29 -3
  4. package/dist/cjs/behavior/Behavior.js.map +1 -1
  5. package/dist/cjs/behavior/cluster/ClusterBehavior.d.ts +1 -1
  6. package/dist/cjs/behavior/cluster/ClusterBehavior.d.ts.map +1 -1
  7. package/dist/cjs/behavior/cluster/ClusterBehaviorUtil.d.ts.map +1 -1
  8. package/dist/cjs/behavior/cluster/ClusterBehaviorUtil.js +2 -4
  9. package/dist/cjs/behavior/cluster/ClusterBehaviorUtil.js.map +1 -1
  10. package/dist/cjs/behavior/supervision/RootSupervisor.d.ts.map +1 -1
  11. package/dist/cjs/behavior/supervision/RootSupervisor.js +2 -1
  12. package/dist/cjs/behavior/supervision/RootSupervisor.js.map +1 -1
  13. package/dist/cjs/behavior/system/commissioning/CommissioningClient.d.ts +35 -11
  14. package/dist/cjs/behavior/system/commissioning/CommissioningClient.d.ts.map +1 -1
  15. package/dist/cjs/behavior/system/commissioning/CommissioningClient.js +147 -138
  16. package/dist/cjs/behavior/system/commissioning/CommissioningClient.js.map +2 -2
  17. package/dist/cjs/behavior/system/commissioning/CommissioningServer.d.ts +0 -7
  18. package/dist/cjs/behavior/system/commissioning/CommissioningServer.d.ts.map +1 -1
  19. package/dist/cjs/behavior/system/commissioning/CommissioningServer.js +23 -27
  20. package/dist/cjs/behavior/system/commissioning/CommissioningServer.js.map +1 -1
  21. package/dist/cjs/behavior/system/commissioning/RemoteDescriptor.js +4 -4
  22. package/dist/cjs/behavior/system/commissioning/RemoteDescriptor.js.map +1 -1
  23. package/dist/cjs/behavior/system/network/NetworkClient.d.ts.map +1 -1
  24. package/dist/cjs/behavior/system/network/NetworkClient.js +7 -2
  25. package/dist/cjs/behavior/system/network/NetworkClient.js.map +1 -1
  26. package/dist/cjs/behavior/system/network/NetworkServer.js +1 -1
  27. package/dist/cjs/behavior/system/network/NetworkServer.js.map +1 -1
  28. package/dist/cjs/behaviors/access-control/AccessControlServer.d.ts.map +1 -1
  29. package/dist/cjs/behaviors/access-control/AccessControlServer.js +2 -9
  30. package/dist/cjs/behaviors/access-control/AccessControlServer.js.map +1 -1
  31. package/dist/cjs/behaviors/general-commissioning/GeneralCommissioningServer.js +1 -1
  32. package/dist/cjs/behaviors/general-commissioning/GeneralCommissioningServer.js.map +1 -1
  33. package/dist/cjs/node/ClientGroup.d.ts +18 -0
  34. package/dist/cjs/node/ClientGroup.d.ts.map +1 -0
  35. package/dist/cjs/node/ClientGroup.js +53 -0
  36. package/dist/cjs/node/ClientGroup.js.map +6 -0
  37. package/dist/cjs/node/ClientNode.d.ts +3 -0
  38. package/dist/cjs/node/ClientNode.d.ts.map +1 -1
  39. package/dist/cjs/node/ClientNode.js +8 -2
  40. package/dist/cjs/node/ClientNode.js.map +1 -1
  41. package/dist/cjs/node/client/ClientGroupInteraction.d.ts +22 -0
  42. package/dist/cjs/node/client/ClientGroupInteraction.d.ts.map +1 -0
  43. package/dist/cjs/node/client/ClientGroupInteraction.js +67 -0
  44. package/dist/cjs/node/client/ClientGroupInteraction.js.map +6 -0
  45. package/dist/cjs/node/client/ClientNodeFactory.d.ts +2 -1
  46. package/dist/cjs/node/client/ClientNodeFactory.d.ts.map +1 -1
  47. package/dist/cjs/node/client/ClientNodeFactory.js.map +1 -1
  48. package/dist/cjs/node/client/Peers.d.ts.map +1 -1
  49. package/dist/cjs/node/client/Peers.js +21 -8
  50. package/dist/cjs/node/client/Peers.js.map +1 -1
  51. package/dist/cjs/storage/client/ClientNodeStores.d.ts +2 -0
  52. package/dist/cjs/storage/client/ClientNodeStores.d.ts.map +1 -1
  53. package/dist/cjs/storage/client/ClientNodeStores.js +19 -0
  54. package/dist/cjs/storage/client/ClientNodeStores.js.map +1 -1
  55. package/dist/esm/behavior/Behavior.d.ts +1 -1
  56. package/dist/esm/behavior/Behavior.d.ts.map +1 -1
  57. package/dist/esm/behavior/Behavior.js +29 -3
  58. package/dist/esm/behavior/Behavior.js.map +1 -1
  59. package/dist/esm/behavior/cluster/ClusterBehavior.d.ts +1 -1
  60. package/dist/esm/behavior/cluster/ClusterBehavior.d.ts.map +1 -1
  61. package/dist/esm/behavior/cluster/ClusterBehaviorUtil.d.ts.map +1 -1
  62. package/dist/esm/behavior/cluster/ClusterBehaviorUtil.js +3 -4
  63. package/dist/esm/behavior/cluster/ClusterBehaviorUtil.js.map +1 -1
  64. package/dist/esm/behavior/supervision/RootSupervisor.d.ts.map +1 -1
  65. package/dist/esm/behavior/supervision/RootSupervisor.js +3 -1
  66. package/dist/esm/behavior/supervision/RootSupervisor.js.map +1 -1
  67. package/dist/esm/behavior/system/commissioning/CommissioningClient.d.ts +35 -11
  68. package/dist/esm/behavior/system/commissioning/CommissioningClient.d.ts.map +1 -1
  69. package/dist/esm/behavior/system/commissioning/CommissioningClient.js +167 -141
  70. package/dist/esm/behavior/system/commissioning/CommissioningClient.js.map +2 -2
  71. package/dist/esm/behavior/system/commissioning/CommissioningServer.d.ts +0 -7
  72. package/dist/esm/behavior/system/commissioning/CommissioningServer.d.ts.map +1 -1
  73. package/dist/esm/behavior/system/commissioning/CommissioningServer.js +23 -27
  74. package/dist/esm/behavior/system/commissioning/CommissioningServer.js.map +1 -1
  75. package/dist/esm/behavior/system/commissioning/RemoteDescriptor.js +4 -4
  76. package/dist/esm/behavior/system/commissioning/RemoteDescriptor.js.map +1 -1
  77. package/dist/esm/behavior/system/network/NetworkClient.d.ts.map +1 -1
  78. package/dist/esm/behavior/system/network/NetworkClient.js +7 -2
  79. package/dist/esm/behavior/system/network/NetworkClient.js.map +1 -1
  80. package/dist/esm/behavior/system/network/NetworkServer.js +1 -1
  81. package/dist/esm/behavior/system/network/NetworkServer.js.map +1 -1
  82. package/dist/esm/behaviors/access-control/AccessControlServer.d.ts.map +1 -1
  83. package/dist/esm/behaviors/access-control/AccessControlServer.js +2 -9
  84. package/dist/esm/behaviors/access-control/AccessControlServer.js.map +1 -1
  85. package/dist/esm/behaviors/general-commissioning/GeneralCommissioningServer.js +1 -1
  86. package/dist/esm/behaviors/general-commissioning/GeneralCommissioningServer.js.map +1 -1
  87. package/dist/esm/node/ClientGroup.d.ts +18 -0
  88. package/dist/esm/node/ClientGroup.d.ts.map +1 -0
  89. package/dist/esm/node/ClientGroup.js +33 -0
  90. package/dist/esm/node/ClientGroup.js.map +6 -0
  91. package/dist/esm/node/ClientNode.d.ts +3 -0
  92. package/dist/esm/node/ClientNode.d.ts.map +1 -1
  93. package/dist/esm/node/ClientNode.js +8 -2
  94. package/dist/esm/node/ClientNode.js.map +1 -1
  95. package/dist/esm/node/client/ClientGroupInteraction.d.ts +22 -0
  96. package/dist/esm/node/client/ClientGroupInteraction.d.ts.map +1 -0
  97. package/dist/esm/node/client/ClientGroupInteraction.js +47 -0
  98. package/dist/esm/node/client/ClientGroupInteraction.js.map +6 -0
  99. package/dist/esm/node/client/ClientNodeFactory.d.ts +2 -1
  100. package/dist/esm/node/client/ClientNodeFactory.d.ts.map +1 -1
  101. package/dist/esm/node/client/ClientNodeFactory.js.map +1 -1
  102. package/dist/esm/node/client/Peers.d.ts.map +1 -1
  103. package/dist/esm/node/client/Peers.js +21 -8
  104. package/dist/esm/node/client/Peers.js.map +1 -1
  105. package/dist/esm/storage/client/ClientNodeStores.d.ts +2 -0
  106. package/dist/esm/storage/client/ClientNodeStores.d.ts.map +1 -1
  107. package/dist/esm/storage/client/ClientNodeStores.js +20 -1
  108. package/dist/esm/storage/client/ClientNodeStores.js.map +1 -1
  109. package/package.json +7 -7
  110. package/src/behavior/Behavior.ts +42 -4
  111. package/src/behavior/cluster/ClusterBehavior.ts +1 -1
  112. package/src/behavior/cluster/ClusterBehaviorUtil.ts +7 -7
  113. package/src/behavior/supervision/RootSupervisor.ts +4 -2
  114. package/src/behavior/system/commissioning/CommissioningClient.ts +113 -73
  115. package/src/behavior/system/commissioning/CommissioningServer.ts +25 -30
  116. package/src/behavior/system/commissioning/RemoteDescriptor.ts +4 -4
  117. package/src/behavior/system/network/NetworkClient.ts +8 -2
  118. package/src/behavior/system/network/NetworkServer.ts +1 -1
  119. package/src/behaviors/access-control/AccessControlServer.ts +1 -8
  120. package/src/behaviors/general-commissioning/GeneralCommissioningServer.ts +1 -1
  121. package/src/node/ClientGroup.ts +36 -0
  122. package/src/node/ClientNode.ts +10 -2
  123. package/src/node/client/ClientEndpointInitializer.ts +1 -1
  124. package/src/node/client/ClientGroupInteraction.ts +70 -0
  125. package/src/node/client/ClientNodeFactory.ts +2 -1
  126. package/src/node/client/Peers.ts +23 -8
  127. package/src/storage/client/ClientNodeStores.ts +25 -1
@@ -99,7 +99,7 @@ export class GeneralCommissioningServer extends GeneralCommissioningBehavior {
99
99
  sessions: this.env.get(SessionManager),
100
100
  expiryLength: Seconds(expiryLengthSeconds),
101
101
  maxCumulativeFailsafe: Seconds(this.state.basicCommissioningInfo.maxCumulativeFailsafeSeconds),
102
- associatedFabric: session.fabric,
102
+ session,
103
103
  });
104
104
 
105
105
  // Note - this used to be async and wait for construction internally. However that leads to race
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { ActionContext } from "#behavior/context/ActionContext.js";
7
+ import { Interactable } from "#protocol";
8
+ import { ServerNodeStore } from "#storage/index.js";
9
+ import { ClientNode } from "./ClientNode.js";
10
+ import { ClientGroupInteraction } from "./client/ClientGroupInteraction.js";
11
+
12
+ export class ClientGroup extends ClientNode {
13
+ #interaction?: ClientGroupInteraction;
14
+
15
+ override get isGroup() {
16
+ return true;
17
+ }
18
+
19
+ override get interaction(): Interactable<ActionContext> {
20
+ if (this.#interaction === undefined) {
21
+ this.#interaction = new ClientGroupInteraction(this);
22
+ }
23
+
24
+ return this.#interaction;
25
+ }
26
+
27
+ protected override get store() {
28
+ return this.env.get(ServerNodeStore).clientStores.storeForGroup(this);
29
+ }
30
+ }
31
+
32
+ export namespace ClientGroup {
33
+ export function is(value: unknown): value is ClientGroup {
34
+ return value instanceof ClientGroup;
35
+ }
36
+ }
@@ -53,6 +53,10 @@ export class ClientNode extends Node<ClientNode.RootEndpoint> {
53
53
  this.#matter = options.matter ?? Matter;
54
54
  }
55
55
 
56
+ get isGroup() {
57
+ return false;
58
+ }
59
+
56
60
  /**
57
61
  * Model of Matter semantics understood by this node.
58
62
  *
@@ -66,8 +70,12 @@ export class ClientNode extends Node<ClientNode.RootEndpoint> {
66
70
  return new ClientNodeEndpoints(this);
67
71
  }
68
72
 
73
+ protected get store() {
74
+ return this.env.get(ServerNodeStore).clientStores.storeForNode(this);
75
+ }
76
+
69
77
  override initialize() {
70
- const store = this.env.get(ServerNodeStore).clientStores.storeForNode(this);
78
+ const store = this.store;
71
79
 
72
80
  this.env.set(ClientNodeStore, store);
73
81
 
@@ -202,7 +210,7 @@ export class ClientNode extends Node<ClientNode.RootEndpoint> {
202
210
 
203
211
  // During early initialization commissioning state may not be loaded, so check directly in storage too
204
212
  if (!address) {
205
- address = this.env.get(ClientNodeStore).storeForEndpoint(this).peerAddress as PeerAddress | undefined;
213
+ address = this.store.storeForEndpoint(this).peerAddress as PeerAddress | undefined;
206
214
  }
207
215
 
208
216
  // Use the peer address as a log identifier if present
@@ -49,7 +49,7 @@ export class ClientEndpointInitializer extends EndpointInitializer {
49
49
  }
50
50
 
51
51
  override createBacking(endpoint: Endpoint, type: Behavior.Type): BehaviorBacking {
52
- // Non-cluster behaviors are local operation the same server behaviors
52
+ // Non-cluster behaviors are local, operating the same server behaviors
53
53
  if ((type as ClusterBehavior.Type).cluster === undefined) {
54
54
  const store = this.structure.storeForLocal(endpoint, type);
55
55
  return new ServerBehaviorBacking(endpoint, type, store, endpoint.behaviors.optionsFor(type));
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import type { ActionContext } from "#behavior/index.js";
8
+ import { ImplementationError } from "#general";
9
+ import {
10
+ ClientInvoke,
11
+ DecodedInvokeResult,
12
+ Read,
13
+ ReadResult,
14
+ Subscribe,
15
+ SubscribeResult,
16
+ Write,
17
+ WriteResult,
18
+ } from "#protocol";
19
+ import { ClientNodeInteraction } from "./ClientNodeInteraction.js";
20
+
21
+ export class InvalidGroupOperationError extends ImplementationError {}
22
+
23
+ export class ClientGroupInteraction extends ClientNodeInteraction {
24
+ /** Groups do not support reading or subscribing to attributes */
25
+ override read(_request: Read, _context?: ActionContext): ReadResult {
26
+ throw new InvalidGroupOperationError("Groups do not support reading attributes");
27
+ }
28
+
29
+ /** Groups do not support reading or subscribing to attributes */
30
+ override async subscribe(_request: Subscribe, _context?: ActionContext): SubscribeResult {
31
+ throw new InvalidGroupOperationError("Groups do not support subscribing to attributes");
32
+ }
33
+
34
+ override async write<T extends Write>(
35
+ request: T,
36
+ context?: ActionContext,
37
+ ): WriteResult<T & { suppressResponse: true }> {
38
+ if (request.timedRequest) {
39
+ throw new InvalidGroupOperationError("Timed requests are not supported for group address writes.");
40
+ }
41
+
42
+ if (request.suppressResponse === false) {
43
+ // If flag was explicitly set to false, we cannot comply
44
+ throw new InvalidGroupOperationError("Writing attributes on a group address can not return a response.");
45
+ }
46
+
47
+ if (
48
+ request.writeRequests.some(
49
+ ({ path: { endpointId, clusterId, attributeId } }) =>
50
+ endpointId !== undefined || clusterId === undefined || attributeId === undefined,
51
+ )
52
+ ) {
53
+ throw new InvalidGroupOperationError("Not all attribute write paths are valid for group address writes.");
54
+ }
55
+
56
+ // Writing to a group does not yield a response
57
+ return super.write({ ...request, suppressResponse: true }, context);
58
+ }
59
+
60
+ override invoke(request: ClientInvoke, context?: ActionContext): DecodedInvokeResult {
61
+ if (request.invokeRequests.some(({ commandPath: { endpointId } }) => endpointId !== undefined)) {
62
+ throw new InvalidGroupOperationError("Invoking a concrete command on a group address is not supported.");
63
+ }
64
+ if (request.timedRequest) {
65
+ throw new InvalidGroupOperationError("Timed requests are not supported for group address invokes.");
66
+ }
67
+
68
+ return super.invoke(request, context);
69
+ }
70
+ }
@@ -7,6 +7,7 @@
7
7
  import type { RemoteDescriptor } from "#behavior/system/commissioning/RemoteDescriptor.js";
8
8
  import type { ImmutableSet } from "#general";
9
9
  import type { ClientNode } from "#node/ClientNode.js";
10
+ import type { PeerAddress } from "#protocol";
10
11
 
11
12
  /**
12
13
  * Create a new client node.
@@ -16,6 +17,6 @@ import type { ClientNode } from "#node/ClientNode.js";
16
17
  */
17
18
  export abstract class ClientNodeFactory {
18
19
  abstract find(descriptor: RemoteDescriptor): ClientNode | undefined;
19
- abstract create(options: ClientNode.Options): ClientNode;
20
+ abstract create(options: ClientNode.Options, peerAddress?: PeerAddress): ClientNode;
20
21
  abstract nodes: ImmutableSet<ClientNode>;
21
22
  }
@@ -11,6 +11,7 @@ import { Discovery } from "#behavior/system/controller/discovery/Discovery.js";
11
11
  import { InstanceDiscovery } from "#behavior/system/controller/discovery/InstanceDiscovery.js";
12
12
  import { EndpointContainer } from "#endpoint/properties/EndpointContainer.js";
13
13
  import { CancelablePromise, Duration, ImplementationError, Logger, Minutes, Seconds, Time, Timestamp } from "#general";
14
+ import { ClientGroup } from "#node/ClientGroup.js";
14
15
  import { InteractionServer } from "#node/index.js";
15
16
  import { FabricManager, PeerAddress, PeerAddressStore } from "#protocol";
16
17
  import { ServerNodeStore } from "#storage/server/ServerNodeStore.js";
@@ -58,6 +59,7 @@ export class Peers extends EndpointContainer<ClientNode> {
58
59
  const factory = this.owner.env.get(ClientNodeFactory);
59
60
 
60
61
  const clientStores = this.owner.env.get(ServerNodeStore).clientStores;
62
+ // Group nodes have an in-memory only store, so all nodes restored here are ClientNode
61
63
  for (const id of clientStores.knownIds) {
62
64
  this.add(
63
65
  factory.create({
@@ -131,7 +133,7 @@ export class Peers extends EndpointContainer<ClientNode> {
131
133
  if (!node) {
132
134
  // We do not have that node till now, also not persisted, so create it
133
135
  const factory = this.owner.env.get(ClientNodeFactory);
134
- node = factory.create(options);
136
+ node = factory.create(options, peerAddress);
135
137
  await node.construction;
136
138
  this.add(node);
137
139
 
@@ -278,20 +280,33 @@ export class Peers extends EndpointContainer<ClientNode> {
278
280
 
279
281
  class Factory extends ClientNodeFactory {
280
282
  #owner: Peers;
283
+ #groupIdCounter = 0;
281
284
 
282
285
  constructor(owner: Peers) {
283
286
  super();
284
287
  this.#owner = owner;
285
288
  }
286
289
 
287
- create(options: ClientNode.Options) {
288
- if (options.id === undefined) {
289
- options.id = this.#owner.owner.env.get(ServerNodeStore).clientStores.allocateId();
290
+ create(options: ClientNode.Options, peerAddress?: PeerAddress) {
291
+ let node: ClientNode;
292
+ if (peerAddress !== undefined && PeerAddress.isGroup(peerAddress)) {
293
+ if (options.id === undefined) {
294
+ options.id = `group${++this.#groupIdCounter}`;
295
+ }
296
+ node = new ClientGroup({
297
+ ...options,
298
+ owner: this.#owner.owner,
299
+ });
300
+ } else {
301
+ if (options.id === undefined) {
302
+ options.id = this.#owner.owner.env.get(ServerNodeStore).clientStores.allocateId();
303
+ }
304
+ node = new ClientNode({
305
+ ...options,
306
+ owner: this.#owner.owner,
307
+ });
290
308
  }
291
- const node = new ClientNode({
292
- ...options,
293
- owner: this.#owner.owner,
294
- });
309
+
295
310
  node.construction.start();
296
311
  return node;
297
312
  }
@@ -4,7 +4,8 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- import { Construction, MatterAggregateError, StorageContext } from "#general";
7
+ import { Construction, MatterAggregateError, StorageBackendMemory, StorageContext, StorageManager } from "#general";
8
+ import type { ClientGroup } from "#node/ClientGroup.js";
8
9
  import type { ClientNode } from "#node/ClientNode.js";
9
10
  import type { Node } from "#node/Node.js";
10
11
  import { ClientNodeStore } from "./ClientNodeStore.js";
@@ -86,6 +87,17 @@ export class ClientNodeStores {
86
87
  return this.#createNodeStore(node.id);
87
88
  }
88
89
 
90
+ storeForGroup(node: ClientGroup): ClientNodeStore {
91
+ this.#construction.assert();
92
+
93
+ const store = this.#stores[node.id];
94
+ if (store) {
95
+ return store;
96
+ }
97
+
98
+ return this.#createGroupStore(node.id);
99
+ }
100
+
89
101
  /**
90
102
  * List all nodes present.
91
103
  */
@@ -99,6 +111,18 @@ export class ClientNodeStores {
99
111
  await this.construction;
100
112
  }
101
113
 
114
+ /**
115
+ * Group stores are always created with a memory backend as they are transient.
116
+ */
117
+ #createGroupStore(id: string) {
118
+ const manager = new StorageManager(new StorageBackendMemory());
119
+ manager.initialize();
120
+ const store = new ClientNodeStore(id, manager.createContext(id));
121
+ store.construction.start();
122
+ this.#stores[id] = store;
123
+ return store;
124
+ }
125
+
102
126
  #createNodeStore(id: string) {
103
127
  const store = new ClientNodeStore(id, this.#storage.createContext(id));
104
128
  store.construction.start();