@matter/node 0.16.0-alpha.0-20250926-3a74283f6 → 0.16.0-alpha.0-20250930-05e6cc3f8

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 (53) hide show
  1. package/dist/cjs/behavior/system/commissioning/CommissioningServer.d.ts.map +1 -1
  2. package/dist/cjs/behavior/system/commissioning/CommissioningServer.js +2 -0
  3. package/dist/cjs/behavior/system/commissioning/CommissioningServer.js.map +1 -1
  4. package/dist/cjs/behavior/system/network/ServerNetworkRuntime.d.ts +2 -3
  5. package/dist/cjs/behavior/system/network/ServerNetworkRuntime.d.ts.map +1 -1
  6. package/dist/cjs/behavior/system/network/ServerNetworkRuntime.js +8 -27
  7. package/dist/cjs/behavior/system/network/ServerNetworkRuntime.js.map +1 -1
  8. package/dist/cjs/behavior/system/subscriptions/SubscriptionsServer.d.ts +3 -3
  9. package/dist/cjs/behavior/system/subscriptions/SubscriptionsServer.d.ts.map +1 -1
  10. package/dist/cjs/behavior/system/subscriptions/SubscriptionsServer.js +8 -3
  11. package/dist/cjs/behavior/system/subscriptions/SubscriptionsServer.js.map +1 -1
  12. package/dist/cjs/endpoint/properties/Endpoints.d.ts +24 -0
  13. package/dist/cjs/endpoint/properties/Endpoints.d.ts.map +1 -0
  14. package/dist/cjs/endpoint/properties/Endpoints.js +85 -0
  15. package/dist/cjs/endpoint/properties/Endpoints.js.map +6 -0
  16. package/dist/cjs/endpoint/properties/index.d.ts +1 -0
  17. package/dist/cjs/endpoint/properties/index.d.ts.map +1 -1
  18. package/dist/cjs/endpoint/properties/index.js +1 -0
  19. package/dist/cjs/endpoint/properties/index.js.map +1 -1
  20. package/dist/cjs/node/Node.d.ts +9 -1
  21. package/dist/cjs/node/Node.d.ts.map +1 -1
  22. package/dist/cjs/node/Node.js +10 -0
  23. package/dist/cjs/node/Node.js.map +1 -1
  24. package/dist/esm/behavior/system/commissioning/CommissioningServer.d.ts.map +1 -1
  25. package/dist/esm/behavior/system/commissioning/CommissioningServer.js +2 -0
  26. package/dist/esm/behavior/system/commissioning/CommissioningServer.js.map +1 -1
  27. package/dist/esm/behavior/system/network/ServerNetworkRuntime.d.ts +2 -3
  28. package/dist/esm/behavior/system/network/ServerNetworkRuntime.d.ts.map +1 -1
  29. package/dist/esm/behavior/system/network/ServerNetworkRuntime.js +8 -28
  30. package/dist/esm/behavior/system/network/ServerNetworkRuntime.js.map +1 -1
  31. package/dist/esm/behavior/system/subscriptions/SubscriptionsServer.d.ts +3 -3
  32. package/dist/esm/behavior/system/subscriptions/SubscriptionsServer.d.ts.map +1 -1
  33. package/dist/esm/behavior/system/subscriptions/SubscriptionsServer.js +8 -3
  34. package/dist/esm/behavior/system/subscriptions/SubscriptionsServer.js.map +1 -1
  35. package/dist/esm/endpoint/properties/Endpoints.d.ts +24 -0
  36. package/dist/esm/endpoint/properties/Endpoints.d.ts.map +1 -0
  37. package/dist/esm/endpoint/properties/Endpoints.js +65 -0
  38. package/dist/esm/endpoint/properties/Endpoints.js.map +6 -0
  39. package/dist/esm/endpoint/properties/index.d.ts +1 -0
  40. package/dist/esm/endpoint/properties/index.d.ts.map +1 -1
  41. package/dist/esm/endpoint/properties/index.js +1 -0
  42. package/dist/esm/endpoint/properties/index.js.map +1 -1
  43. package/dist/esm/node/Node.d.ts +9 -1
  44. package/dist/esm/node/Node.d.ts.map +1 -1
  45. package/dist/esm/node/Node.js +10 -0
  46. package/dist/esm/node/Node.js.map +1 -1
  47. package/package.json +7 -7
  48. package/src/behavior/system/commissioning/CommissioningServer.ts +4 -0
  49. package/src/behavior/system/network/ServerNetworkRuntime.ts +14 -40
  50. package/src/behavior/system/subscriptions/SubscriptionsServer.ts +7 -3
  51. package/src/endpoint/properties/Endpoints.ts +83 -0
  52. package/src/endpoint/properties/index.ts +1 -0
  53. package/src/node/Node.ts +12 -0
@@ -4,9 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- import { SubscriptionsBehavior } from "#behavior/system/subscriptions/SubscriptionsServer.js";
8
7
  import {
9
- Construction,
10
8
  Crypto,
11
9
  InterfaceType,
12
10
  Logger,
@@ -65,7 +63,6 @@ export class ServerNetworkRuntime extends NetworkRuntime {
65
63
  #bleTransport?: TransportInterface;
66
64
  #ipv6UdpInterface?: UdpInterface;
67
65
  #observers = new ObserverGroup(this);
68
- #formerSubscriptionsHandled = false;
69
66
  #groupNetworking?: ServerGroupNetworking;
70
67
 
71
68
  override get owner() {
@@ -205,7 +202,7 @@ export class ServerNetworkRuntime extends NetworkRuntime {
205
202
  /**
206
203
  * When the first Fabric gets added we need to enable MDNS broadcasting.
207
204
  */
208
- enableMdnsAdvertising() {
205
+ ensureMdnsAdvertiser() {
209
206
  const device = this.owner.env.get(DeviceAdvertiser);
210
207
  const mdnsAdvertiser = this.mdnsAdvertiser;
211
208
  if (!device.hasAdvertiser(mdnsAdvertiser)) {
@@ -222,7 +219,7 @@ export class ServerNetworkRuntime extends NetworkRuntime {
222
219
  endUncommissionedMode() {
223
220
  // Ensure MDNS broadcasting are active when the first fabric is added. It might not be active initially if the
224
221
  // node was not on an IP network prior to commissioning
225
- this.enableMdnsAdvertising();
222
+ this.ensureMdnsAdvertiser();
226
223
 
227
224
  if (this.#bleAdvertiser) {
228
225
  this.owner.env.runtime.add(this.#deleteAdvertiser(this.#bleAdvertiser));
@@ -254,14 +251,16 @@ export class ServerNetworkRuntime extends NetworkRuntime {
254
251
  const { owner } = this;
255
252
  const { env } = owner;
256
253
 
257
- // Ensure MdnsService is fully constructed
258
- await env.load(MdnsService);
259
-
260
- const advertiser = env.get(DeviceAdvertiser);
261
254
  // Configure network
262
255
  const interfaces = env.get(TransportInterfaceSet);
263
256
  await this.addTransports(interfaces);
264
257
  env.set(NetInterfaceSet, interfaces);
258
+
259
+ // Initialize MDNS
260
+ const mdns = await owner.env.load(MdnsService);
261
+
262
+ const advertiser = env.get(DeviceAdvertiser);
263
+
265
264
  await this.addBroadcasters(advertiser);
266
265
 
267
266
  await owner.act("start-network", agent => agent.load(ProductDescriptionServer));
@@ -291,29 +290,16 @@ export class ServerNetworkRuntime extends NetworkRuntime {
291
290
 
292
291
  // Enable MDNS broadcasting if there are fabrics present
293
292
  if (this.owner.stateOf(CommissioningServer).commissioned) {
294
- this.enableMdnsAdvertising();
293
+ this.ensureMdnsAdvertiser();
295
294
  }
296
295
 
297
- await this.owner.act(agent => this.owner.lifecycle.online.emit(agent.context));
298
- }
299
-
300
- override async [Construction.construct]() {
301
- await super[Construction.construct]();
302
-
303
- // Initialize MDNS
304
- const mdns = await this.owner.env.load(MdnsService);
305
-
306
296
  // Initialize ScannerSet
307
297
  this.owner.env.get(ScannerSet).add(mdns.client);
308
- this.owner.env.set(PeerAddressStore, new NodePeerAddressStore(this.owner));
309
- await this.owner.env.load(PeerSet);
310
-
311
- // Restore previous subscriptions
312
- //
313
- // TODO - move to SubscriptionsBehavior, and rename to SubscriptionsServer?
314
- if (!this.#formerSubscriptionsHandled) {
315
- await this.#reestablishFormerSubscriptions();
316
- }
298
+
299
+ env.set(PeerAddressStore, new NodePeerAddressStore(owner));
300
+ await env.load(PeerSet);
301
+
302
+ await this.owner.act(agent => this.owner.lifecycle.online.emit(agent.context));
317
303
  }
318
304
 
319
305
  protected override async stop() {
@@ -349,18 +335,6 @@ export class ServerNetworkRuntime extends NetworkRuntime {
349
335
  this.owner.env.maybeGet(InteractionServer)?.blockNewActivity();
350
336
  }
351
337
 
352
- async #reestablishFormerSubscriptions() {
353
- const { env } = this.owner;
354
- if (!env.has(InteractionServer)) {
355
- return;
356
- }
357
- this.#formerSubscriptionsHandled = true;
358
-
359
- await this.owner.act(agent =>
360
- agent.get(SubscriptionsBehavior).reestablishFormerSubscriptions(env.get(InteractionServer)),
361
- );
362
- }
363
-
364
338
  async #initializeGroupNetworking() {
365
339
  if (this.#groupNetworking) {
366
340
  logger.warn("Group networking already initialized, skipping.");
@@ -49,7 +49,7 @@ export class SubscriptionsBehavior extends Behavior {
49
49
  this.reactTo(sessions.events.subscriptionAdded, this.#addSubscription, { lock: true });
50
50
  }
51
51
 
52
- static override schema = new DatatypeModel(
52
+ static override readonly schema = new DatatypeModel(
53
53
  {
54
54
  name: "SubscriptionState",
55
55
  type: "struct",
@@ -59,6 +59,8 @@ export class SubscriptionsBehavior extends Behavior {
59
59
  name: "subscriptions",
60
60
  type: "list",
61
61
  quality: "N",
62
+ conformance: "M",
63
+ default: [],
62
64
  },
63
65
  FieldElement(
64
66
  {
@@ -197,13 +199,14 @@ export class SubscriptionsBehavior extends Behavior {
197
199
  await this.context.transaction.commit();
198
200
  }
199
201
 
200
- async reestablishFormerSubscriptions(interactionServer: InteractionServer) {
202
+ async reestablishFormerSubscriptions() {
201
203
  if (this.state.persistenceEnabled === false) return;
202
204
 
203
205
  // get and clear former subscriptions
204
206
  const { formerSubscriptions } = this.internal;
205
207
 
206
208
  if (!formerSubscriptions.length) {
209
+ logger.info("No former subscriptions to re-establish");
207
210
  return;
208
211
  } else {
209
212
  this.internal.formerSubscriptions = [];
@@ -211,6 +214,7 @@ export class SubscriptionsBehavior extends Behavior {
211
214
  }
212
215
  const peers = this.env.get(PeerSet);
213
216
  const sessions = this.env.get(SessionManager);
217
+ const interactionServer = this.env.get(InteractionServer);
214
218
 
215
219
  const peerStopList = new PeerAddressSet();
216
220
 
@@ -291,7 +295,7 @@ export namespace SubscriptionsBehavior {
291
295
  * List of subscriptions. This list is collected automatically.
292
296
  * The state value should not be initialized by the developer.
293
297
  */
294
- subscriptions!: PeerSubscription[];
298
+ subscriptions: PeerSubscription[] = [];
295
299
  }
296
300
 
297
301
  export class Internal {
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { IndexBehavior } from "#behavior/system/index/IndexBehavior.js";
8
+ import type { Endpoint } from "#endpoint/Endpoint.js";
9
+ import { EndpointType } from "#endpoint/type/EndpointType.js";
10
+ import type { ImmutableSet } from "#general";
11
+ import { Node } from "#node/Node.js";
12
+ import { StatusResponse } from "#types";
13
+
14
+ /**
15
+ * Access to all endpoints on a node, including the root endpoint.
16
+ */
17
+ export class Endpoints implements ImmutableSet<Endpoint> {
18
+ #node: Node;
19
+
20
+ constructor(node: Node) {
21
+ this.#node = node;
22
+ }
23
+
24
+ has(endpoint: Endpoint | number): boolean {
25
+ if (endpoint === this.#node || endpoint === 0) {
26
+ return true;
27
+ }
28
+
29
+ if (typeof endpoint === "number") {
30
+ return endpoint in this.#index;
31
+ }
32
+
33
+ return endpoint.lifecycle.hasNumber && endpoint.number in this.#index;
34
+ }
35
+
36
+ get size(): number {
37
+ return this.#list.length + 1;
38
+ }
39
+
40
+ map<R>(mapper: (item: Endpoint<EndpointType.Empty>) => R): R[] {
41
+ return this.#list.map(mapper);
42
+ }
43
+
44
+ find(predicate: (item: Endpoint) => boolean | undefined): Endpoint | undefined {
45
+ return this.#list.find(predicate);
46
+ }
47
+
48
+ filter(predicate: (item: Endpoint) => boolean | undefined): Endpoint[] {
49
+ return this.#list.filter(predicate);
50
+ }
51
+
52
+ [Symbol.iterator]() {
53
+ return this.#list[Symbol.iterator]();
54
+ }
55
+
56
+ for(number: number): Endpoint {
57
+ if (number === 0) {
58
+ return this.#node;
59
+ }
60
+
61
+ const endpoint = this.#index[number];
62
+ if (endpoint === undefined) {
63
+ throw new StatusResponse.NotFoundError(`Endpoint ${number} does not exist`);
64
+ }
65
+ return endpoint;
66
+ }
67
+
68
+ /**
69
+ * Object mapping EndpointNumber -> Endpoint.
70
+ *
71
+ * Note that this does not include endpoint 0, but we have that in #node.
72
+ */
73
+ get #index() {
74
+ return this.#node.behaviors.internalsOf(IndexBehavior).partsByNumber;
75
+ }
76
+
77
+ /**
78
+ * Full list of endpoints. Includes endpoint 0.
79
+ */
80
+ get #list() {
81
+ return [this.#node, ...Object.values(this.#index)];
82
+ }
83
+ }
@@ -9,5 +9,6 @@ export * from "./Commands.js";
9
9
  export * from "./EndpointContainer.js";
10
10
  export * from "./EndpointInitializer.js";
11
11
  export * from "./EndpointLifecycle.js";
12
+ export * from "./Endpoints.js";
12
13
  export * from "./Parts.js";
13
14
  export * from "./SupportedBehaviors.js";
package/src/node/Node.ts CHANGED
@@ -11,6 +11,7 @@ import { NetworkBehavior } from "#behavior/system/network/NetworkBehavior.js";
11
11
  import { NetworkRuntime } from "#behavior/system/network/NetworkRuntime.js";
12
12
  import { PartsBehavior } from "#behavior/system/parts/PartsBehavior.js";
13
13
  import { Endpoint } from "#endpoint/Endpoint.js";
14
+ import { Endpoints } from "#endpoint/properties/Endpoints.js";
14
15
  import { EndpointType } from "#endpoint/type/EndpointType.js";
15
16
  import { MutableEndpoint } from "#endpoint/type/MutableEndpoint.js";
16
17
  import {
@@ -24,6 +25,7 @@ import {
24
25
  RuntimeService,
25
26
  } from "#general";
26
27
  import { Interactable } from "#protocol";
28
+ import type { EndpointNumber } from "#types";
27
29
  import { RootEndpoint } from "../endpoints/root.js";
28
30
  import { NodeLifecycle } from "./NodeLifecycle.js";
29
31
  import { ProtocolService } from "./server/ProtocolService.js";
@@ -148,6 +150,16 @@ export abstract class Node<T extends Node.CommonRootEndpoint = Node.CommonRootEn
148
150
  await this.lifecycle.mutex.produce(this.cancelWithMutex.bind(this));
149
151
  }
150
152
 
153
+ /**
154
+ * All endpoints owned by the node.
155
+ *
156
+ * Normally you access endpoints via {@link parts} but you can use this property access endpoints directly by
157
+ * {@link EndpointNumber}.
158
+ */
159
+ get endpoints(): Endpoints {
160
+ return new Endpoints(this);
161
+ }
162
+
151
163
  protected async cancelWithMutex() {
152
164
  if (!this.#runtime) {
153
165
  return;