@project-chip/matter.js 0.16.0-alpha.0-20250912-0d12bf718 → 0.16.0-alpha.0-20250916-d577beb1d
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/CommissioningController.d.ts +2 -1
- package/dist/cjs/CommissioningController.d.ts.map +1 -1
- package/dist/cjs/CommissioningController.js +10 -10
- package/dist/cjs/CommissioningController.js.map +1 -1
- package/dist/cjs/device/Endpoint.d.ts +42 -1
- package/dist/cjs/device/Endpoint.d.ts.map +1 -1
- package/dist/cjs/device/Endpoint.js +73 -14
- package/dist/cjs/device/Endpoint.js.map +1 -1
- package/dist/cjs/device/EndpointPropertiesProxy.d.ts +33 -0
- package/dist/cjs/device/EndpointPropertiesProxy.d.ts.map +1 -0
- package/dist/cjs/device/EndpointPropertiesProxy.js +109 -0
- package/dist/cjs/device/EndpointPropertiesProxy.js.map +6 -0
- package/dist/cjs/device/PairedNode.d.ts +43 -2
- package/dist/cjs/device/PairedNode.d.ts.map +1 -1
- package/dist/cjs/device/PairedNode.js +44 -4
- package/dist/cjs/device/PairedNode.js.map +1 -1
- package/dist/esm/CommissioningController.d.ts +2 -1
- package/dist/esm/CommissioningController.d.ts.map +1 -1
- package/dist/esm/CommissioningController.js +10 -11
- package/dist/esm/CommissioningController.js.map +1 -1
- package/dist/esm/device/Endpoint.d.ts +42 -1
- package/dist/esm/device/Endpoint.d.ts.map +1 -1
- package/dist/esm/device/Endpoint.js +73 -14
- package/dist/esm/device/Endpoint.js.map +1 -1
- package/dist/esm/device/EndpointPropertiesProxy.d.ts +33 -0
- package/dist/esm/device/EndpointPropertiesProxy.d.ts.map +1 -0
- package/dist/esm/device/EndpointPropertiesProxy.js +89 -0
- package/dist/esm/device/EndpointPropertiesProxy.js.map +6 -0
- package/dist/esm/device/PairedNode.d.ts +43 -2
- package/dist/esm/device/PairedNode.d.ts.map +1 -1
- package/dist/esm/device/PairedNode.js +44 -4
- package/dist/esm/device/PairedNode.js.map +1 -1
- package/package.json +8 -8
- package/src/CommissioningController.ts +11 -11
- package/src/device/Endpoint.ts +82 -15
- package/src/device/EndpointPropertiesProxy.ts +114 -0
- package/src/device/PairedNode.ts +53 -6
package/src/device/Endpoint.ts
CHANGED
|
@@ -10,7 +10,8 @@ import {
|
|
|
10
10
|
FixedLabelCluster,
|
|
11
11
|
UserLabelCluster,
|
|
12
12
|
} from "#clusters";
|
|
13
|
-
import { AtLeastOne, Diagnostic, ImplementationError, InternalError, NotImplementedError } from "#general";
|
|
13
|
+
import { AtLeastOne, Diagnostic, Immutable, ImplementationError, InternalError, NotImplementedError } from "#general";
|
|
14
|
+
import { Behavior, Commands as BehaviorCommands } from "#node";
|
|
14
15
|
import { ClusterClientObj, SupportedAttributeClient, UnknownSupportedAttributeClient } from "#protocol";
|
|
15
16
|
import {
|
|
16
17
|
Attributes,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
import { ClusterServer } from "../cluster/server/ClusterServer.js";
|
|
29
30
|
import { ClusterServerObj, asClusterServerInternal } from "../cluster/server/ClusterServerTypes.js";
|
|
30
31
|
import { DeviceTypeDefinition } from "./DeviceTypes.js";
|
|
32
|
+
import { EndpointPropertiesProxy } from "./EndpointPropertiesProxy.js";
|
|
31
33
|
|
|
32
34
|
export interface EndpointOptions {
|
|
33
35
|
endpointId?: EndpointNumber;
|
|
@@ -37,13 +39,15 @@ export interface EndpointOptions {
|
|
|
37
39
|
export class Endpoint {
|
|
38
40
|
private readonly clusterServers = new Map<ClusterId, ClusterServerObj>();
|
|
39
41
|
private readonly clusterClients = new Map<ClusterId, ClusterClientObj>();
|
|
40
|
-
private readonly childEndpoints
|
|
42
|
+
private readonly childEndpoints = new Map<number, Endpoint>();
|
|
41
43
|
number: EndpointNumber | undefined;
|
|
42
44
|
uniqueStorageKey: string | undefined;
|
|
43
45
|
name = "";
|
|
44
46
|
private structureChangedCallback: () => void = () => {
|
|
45
47
|
/** noop until officially set **/
|
|
46
48
|
};
|
|
49
|
+
#stateProxy?: EndpointPropertiesProxy.State;
|
|
50
|
+
#commandsProxy?: EndpointPropertiesProxy.Commands;
|
|
47
51
|
|
|
48
52
|
/**
|
|
49
53
|
* Create a new Endpoint instance.
|
|
@@ -65,13 +69,74 @@ export class Endpoint {
|
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Access to cached cluster state values using endpoint.state.clusterNameOrId.attributeNameOrId
|
|
74
|
+
* Returns immutable cached attribute values from cluster clients
|
|
75
|
+
*/
|
|
76
|
+
get state() {
|
|
77
|
+
if (this.#stateProxy === undefined) {
|
|
78
|
+
this.#stateProxy = EndpointPropertiesProxy.state(this.clusterClients);
|
|
79
|
+
}
|
|
80
|
+
return this.#stateProxy;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Access to cluster commands using endpoint.commands.clusterNameOrId.commandName
|
|
85
|
+
* Returns async functions that can be called to invoke commands on cluster clients
|
|
86
|
+
*/
|
|
87
|
+
get commands() {
|
|
88
|
+
if (this.#commandsProxy === undefined) {
|
|
89
|
+
this.#commandsProxy = EndpointPropertiesProxy.commands(this.clusterClients);
|
|
90
|
+
}
|
|
91
|
+
return this.#commandsProxy;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Access to typed cached cluster state values
|
|
96
|
+
* Returns immutable cached attribute values from cluster clients
|
|
97
|
+
*/
|
|
98
|
+
stateOf<T extends Behavior.Type>(type: T) {
|
|
99
|
+
this.#clusterClientForBehaviorType(type); // just use to verify the existence of the cluster
|
|
100
|
+
|
|
101
|
+
return this.state[type.name] as Immutable<Behavior.StateOf<T>>;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Access to typed cluster commands
|
|
106
|
+
* Returns async functions that can be called to invoke commands on cluster clients
|
|
107
|
+
*/
|
|
108
|
+
commandsOf<T extends Behavior.Type>(type: T) {
|
|
109
|
+
return this.#clusterClientForBehaviorType(type).commands as BehaviorCommands.OfBehavior<T>;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#clusterClientForBehaviorType<T extends Behavior.Type>(type: T): ClusterClientObj {
|
|
113
|
+
const clusterId = type.schema?.tag === "cluster" ? (type.schema.id as ClusterId) : undefined;
|
|
114
|
+
if (clusterId === undefined) {
|
|
115
|
+
throw new ImplementationError(`Behavior ${type.id} is not backed by a cluster`);
|
|
116
|
+
}
|
|
117
|
+
const clusterClient = this.clusterClients.get(clusterId);
|
|
118
|
+
if (!clusterClient) {
|
|
119
|
+
throw new ImplementationError(
|
|
120
|
+
`Cluster ${type.id} (0x${clusterId.toString(16)}) is not present on endpoint ${this.number}`,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
return clusterClient;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Get all child endpoints aka parts */
|
|
127
|
+
get parts() {
|
|
128
|
+
return this.childEndpoints;
|
|
129
|
+
}
|
|
130
|
+
|
|
68
131
|
get deviceType(): DeviceTypeId {
|
|
69
132
|
return this.deviceTypes[0].code;
|
|
70
133
|
}
|
|
71
134
|
|
|
72
135
|
setStructureChangedCallback(callback: () => void) {
|
|
73
136
|
this.structureChangedCallback = callback;
|
|
74
|
-
|
|
137
|
+
for (const endpoint of this.childEndpoints.values()) {
|
|
138
|
+
endpoint.setStructureChangedCallback(callback);
|
|
139
|
+
}
|
|
75
140
|
}
|
|
76
141
|
|
|
77
142
|
removeFromStructure() {
|
|
@@ -79,7 +144,9 @@ export class Endpoint {
|
|
|
79
144
|
this.structureChangedCallback = () => {
|
|
80
145
|
/** noop **/
|
|
81
146
|
};
|
|
82
|
-
|
|
147
|
+
for (const endpoint of this.childEndpoints.values()) {
|
|
148
|
+
endpoint.removeFromStructure();
|
|
149
|
+
}
|
|
83
150
|
}
|
|
84
151
|
|
|
85
152
|
close() {
|
|
@@ -217,34 +284,34 @@ export class Endpoint {
|
|
|
217
284
|
|
|
218
285
|
addChildEndpoint(endpoint: Endpoint): void {
|
|
219
286
|
if (!(endpoint instanceof Endpoint)) {
|
|
220
|
-
throw new
|
|
287
|
+
throw new InternalError("Only supported EndpointInterface implementation is Endpoint");
|
|
221
288
|
}
|
|
289
|
+
const id = endpoint.getNumber();
|
|
222
290
|
|
|
223
|
-
if (
|
|
224
|
-
throw new ImplementationError(
|
|
225
|
-
`Endpoint with id ${endpoint.number} already exists as child from ${this.number}.`,
|
|
226
|
-
);
|
|
291
|
+
if (this.childEndpoints.has(id)) {
|
|
292
|
+
throw new ImplementationError(`Endpoint with id ${id} already exists as child from ${this.number}.`);
|
|
227
293
|
}
|
|
228
294
|
|
|
229
|
-
this.childEndpoints.
|
|
295
|
+
this.childEndpoints.set(id, endpoint);
|
|
230
296
|
endpoint.setStructureChangedCallback(this.structureChangedCallback);
|
|
231
297
|
this.structureChangedCallback(); // Inform parent about structure change
|
|
232
298
|
}
|
|
233
299
|
|
|
234
300
|
getChildEndpoint(id: EndpointNumber): Endpoint | undefined {
|
|
235
|
-
return this.childEndpoints.
|
|
301
|
+
return this.childEndpoints.get(id);
|
|
236
302
|
}
|
|
237
303
|
|
|
238
304
|
getChildEndpoints(): Endpoint[] {
|
|
239
|
-
return this.childEndpoints;
|
|
305
|
+
return Array.from(this.childEndpoints.values());
|
|
240
306
|
}
|
|
241
307
|
|
|
242
308
|
protected removeChildEndpoint(endpoint: Endpoint): void {
|
|
243
|
-
const
|
|
244
|
-
|
|
309
|
+
const id = endpoint.getNumber();
|
|
310
|
+
const knownEndpoint = this.childEndpoints.get(id);
|
|
311
|
+
if (knownEndpoint === undefined) {
|
|
245
312
|
throw new ImplementationError(`Provided endpoint for deletion does not exist as child endpoint.`);
|
|
246
313
|
}
|
|
247
|
-
this.childEndpoints.
|
|
314
|
+
this.childEndpoints.delete(id);
|
|
248
315
|
endpoint.removeFromStructure();
|
|
249
316
|
this.structureChangedCallback(); // Inform parent about structure change
|
|
250
317
|
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Immutable } from "#general";
|
|
8
|
+
import { ClusterClientObj } from "#protocol";
|
|
9
|
+
import { AttributeId, ClusterId, CommandId } from "#types";
|
|
10
|
+
|
|
11
|
+
enum EndpointPropertiesProxyType {
|
|
12
|
+
State = "state",
|
|
13
|
+
Commands = "commands",
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Factory for creating proxy-based access to cached cluster state values for legacy Endpoint.
|
|
18
|
+
* This enables ClientNode-style state access patterns.
|
|
19
|
+
*/
|
|
20
|
+
export class EndpointPropertiesProxy {
|
|
21
|
+
#clusterClients: Map<ClusterId, ClusterClientObj>;
|
|
22
|
+
#nameIdMap?: Map<string, ClusterId>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create a state proxy that allows access via cluster names/IDs
|
|
26
|
+
*/
|
|
27
|
+
static state(clusterClients: Map<ClusterId, ClusterClientObj>) {
|
|
28
|
+
return new EndpointPropertiesProxy(clusterClients).#proxy(
|
|
29
|
+
EndpointPropertiesProxyType.State,
|
|
30
|
+
) as EndpointPropertiesProxy.State;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Create a commands proxy that allows access via cluster names/IDs
|
|
35
|
+
*/
|
|
36
|
+
static commands(clusterClients: Map<ClusterId, ClusterClientObj>) {
|
|
37
|
+
return new EndpointPropertiesProxy(clusterClients).#proxy(
|
|
38
|
+
EndpointPropertiesProxyType.Commands,
|
|
39
|
+
) as EndpointPropertiesProxy.Commands;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
constructor(clusterClients: Map<ClusterId, ClusterClientObj>) {
|
|
43
|
+
this.#clusterClients = clusterClients;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#proxy(type: EndpointPropertiesProxyType) {
|
|
47
|
+
return new Proxy(
|
|
48
|
+
{},
|
|
49
|
+
{
|
|
50
|
+
get: (_target, prop) => {
|
|
51
|
+
if (typeof prop !== "string") {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Try to find cluster by name first, then by id
|
|
56
|
+
let clusterId = this.#clusterIdForName(prop);
|
|
57
|
+
if (clusterId === undefined) {
|
|
58
|
+
const id = parseInt(prop, 10);
|
|
59
|
+
clusterId = Number.isFinite(id) ? ClusterId(id) : undefined;
|
|
60
|
+
}
|
|
61
|
+
if (clusterId !== undefined) {
|
|
62
|
+
const clusterClient = this.#clusterClients.get(clusterId);
|
|
63
|
+
|
|
64
|
+
if (clusterClient !== undefined) {
|
|
65
|
+
switch (type) {
|
|
66
|
+
case EndpointPropertiesProxyType.Commands:
|
|
67
|
+
return clusterClient.commands;
|
|
68
|
+
case EndpointPropertiesProxyType.State:
|
|
69
|
+
return this.#createClusterStateProxy(clusterClient);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
#createClusterStateProxy(clusterClient: ClusterClientObj): Immutable<Record<string | AttributeId, any>> {
|
|
80
|
+
return new Proxy(
|
|
81
|
+
{},
|
|
82
|
+
{
|
|
83
|
+
get: (_target, prop) => {
|
|
84
|
+
if (typeof prop !== "string") {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return clusterClient.attributes[prop]?.getLocal();
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
) as Immutable<Record<string | AttributeId, any>>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
#clusterIdForName(name: string): ClusterId | undefined {
|
|
95
|
+
// Initialize map if not done yet or cluster structure changed
|
|
96
|
+
if (this.#nameIdMap === undefined || this.#nameIdMap.size !== this.#clusterClients.size) {
|
|
97
|
+
this.#nameIdMap = new Map<string, ClusterId>();
|
|
98
|
+
for (const [id, client] of this.#clusterClients) {
|
|
99
|
+
this.#nameIdMap.set(client.name.toLowerCase(), id);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return this.#nameIdMap.get(name.toLowerCase());
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export namespace EndpointPropertiesProxy {
|
|
107
|
+
export type State = Immutable<{
|
|
108
|
+
[key: string | ClusterId]: Record<string | AttributeId, any> | undefined;
|
|
109
|
+
}>;
|
|
110
|
+
|
|
111
|
+
export type Commands = Immutable<{
|
|
112
|
+
[key: string | ClusterId]: Record<string | CommandId, (data: any) => Promise<unknown>> | undefined;
|
|
113
|
+
}>;
|
|
114
|
+
}
|
package/src/device/PairedNode.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
Time,
|
|
25
25
|
Timer,
|
|
26
26
|
} from "#general";
|
|
27
|
+
import { Behavior, Commands } from "#node";
|
|
27
28
|
import {
|
|
28
29
|
AttributeClientValues,
|
|
29
30
|
ChannelStatusResponseError,
|
|
@@ -70,6 +71,7 @@ import {
|
|
|
70
71
|
getDeviceTypeDefinitionFromModelByCode,
|
|
71
72
|
} from "./DeviceTypes.js";
|
|
72
73
|
import { Endpoint } from "./Endpoint.js";
|
|
74
|
+
import { EndpointPropertiesProxy } from "./EndpointPropertiesProxy.js";
|
|
73
75
|
import { asClusterClientInternal, isClusterClient } from "./TypeHelpers.js";
|
|
74
76
|
|
|
75
77
|
const logger = Logger.get("PairedNode");
|
|
@@ -235,7 +237,7 @@ interface SubscriptionHandlerCallbacks {
|
|
|
235
237
|
* the CommissioningController on commissioning or when connecting.
|
|
236
238
|
*/
|
|
237
239
|
export class PairedNode {
|
|
238
|
-
readonly #endpoints = new Map<
|
|
240
|
+
readonly #endpoints = new Map<number, Endpoint>();
|
|
239
241
|
#interactionClient: InteractionClient;
|
|
240
242
|
#reconnectDelayTimer?: Timer;
|
|
241
243
|
#newChannelReconnectDelayTimer = Time.getTimer(
|
|
@@ -395,7 +397,7 @@ export class PairedNode {
|
|
|
395
397
|
if (
|
|
396
398
|
session.isInitiator || // If we initiated the session we do not need to react on it
|
|
397
399
|
session.peerNodeId !== this.nodeId || // no session for this node
|
|
398
|
-
this.
|
|
400
|
+
this.connectionState !== NodeStates.WaitingForDeviceDiscovery
|
|
399
401
|
) {
|
|
400
402
|
return;
|
|
401
403
|
}
|
|
@@ -412,7 +414,7 @@ export class PairedNode {
|
|
|
412
414
|
// This kicks of the remote initialization and automatic reconnection handling if it can not be connected
|
|
413
415
|
this.#initialize().catch(error => {
|
|
414
416
|
logger.info(`Node ${nodeId}: Error during remote initialization`, error);
|
|
415
|
-
if (this.
|
|
417
|
+
if (this.connectionState !== NodeStates.Disconnected) {
|
|
416
418
|
this.#setConnectionState(NodeStates.WaitingForDeviceDiscovery);
|
|
417
419
|
this.#scheduleReconnect();
|
|
418
420
|
}
|
|
@@ -430,7 +432,7 @@ export class PairedNode {
|
|
|
430
432
|
}
|
|
431
433
|
|
|
432
434
|
/** Returns the Node connection state. */
|
|
433
|
-
get
|
|
435
|
+
get connectionState() {
|
|
434
436
|
return this.#connectionState;
|
|
435
437
|
}
|
|
436
438
|
|
|
@@ -955,7 +957,7 @@ export class PairedNode {
|
|
|
955
957
|
}
|
|
956
958
|
|
|
957
959
|
#scheduleReconnect(delay?: Duration) {
|
|
958
|
-
if (this.
|
|
960
|
+
if (this.connectionState !== NodeStates.WaitingForDeviceDiscovery) {
|
|
959
961
|
this.#setConnectionState(NodeStates.Reconnecting);
|
|
960
962
|
}
|
|
961
963
|
|
|
@@ -988,7 +990,7 @@ export class PairedNode {
|
|
|
988
990
|
|
|
989
991
|
if (updateStructure) {
|
|
990
992
|
// Find out what we need to remove or retain
|
|
991
|
-
const endpointsToRemove = new Set<
|
|
993
|
+
const endpointsToRemove = new Set<number>(this.#endpoints.keys());
|
|
992
994
|
for (const [endpointId] of Object.entries(allData)) {
|
|
993
995
|
const endpointIdNumber = EndpointNumber(parseInt(endpointId));
|
|
994
996
|
if (this.#endpoints.has(endpointIdNumber)) {
|
|
@@ -1198,6 +1200,11 @@ export class PairedNode {
|
|
|
1198
1200
|
}
|
|
1199
1201
|
}
|
|
1200
1202
|
|
|
1203
|
+
/** Returns all parts (endpoints) known for the Root Endpoint of this node. */
|
|
1204
|
+
get parts() {
|
|
1205
|
+
return this.getRootEndpoint()?.parts ?? new Map<number, Endpoint>();
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1201
1208
|
/** Returns the functional devices/endpoints (the "childs" of the Root Endpoint) known for this node. */
|
|
1202
1209
|
getDevices(): Endpoint[] {
|
|
1203
1210
|
return this.#endpoints.get(EndpointNumber(0))?.getChildEndpoints() ?? [];
|
|
@@ -1432,4 +1439,44 @@ export class PairedNode {
|
|
|
1432
1439
|
],
|
|
1433
1440
|
});
|
|
1434
1441
|
}
|
|
1442
|
+
|
|
1443
|
+
/**
|
|
1444
|
+
* Access to cached cluster state values of the root endpoint using node.state.clusterNameOrId.attributeNameOrId
|
|
1445
|
+
* Returns immutable cached attribute values from cluster clients
|
|
1446
|
+
*/
|
|
1447
|
+
get state() {
|
|
1448
|
+
return this.getRootEndpoint()?.state ?? ({} as EndpointPropertiesProxy.State);
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
/**
|
|
1452
|
+
* Access to cluster commands of the root endpoint using node.commands.clusterNameOrId.commandName
|
|
1453
|
+
* Returns async functions that can be called to invoke commands on cluster clients
|
|
1454
|
+
*/
|
|
1455
|
+
get commands() {
|
|
1456
|
+
return this.getRootEndpoint()?.commands ?? ({} as EndpointPropertiesProxy.Commands);
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
/**
|
|
1460
|
+
* Access to typed cached cluster state values of the root endpoint
|
|
1461
|
+
* Returns immutable cached attribute values from cluster clients
|
|
1462
|
+
*/
|
|
1463
|
+
stateOf<T extends Behavior.Type>(type: T) {
|
|
1464
|
+
const root = this.getRootEndpoint();
|
|
1465
|
+
if (root === undefined) {
|
|
1466
|
+
throw new ImplementationError(`Root endpoint for node ${this.nodeId} not found.`);
|
|
1467
|
+
}
|
|
1468
|
+
return root.stateOf(type);
|
|
1469
|
+
}
|
|
1470
|
+
|
|
1471
|
+
/**
|
|
1472
|
+
* Access to typed cluster commands of the root endpoint
|
|
1473
|
+
* Returns async functions that can be called to invoke commands on cluster clients
|
|
1474
|
+
*/
|
|
1475
|
+
commandsOf<T extends Behavior.Type>(type: T): Commands.OfBehavior<T> {
|
|
1476
|
+
const root = this.getRootEndpoint();
|
|
1477
|
+
if (root === undefined) {
|
|
1478
|
+
throw new ImplementationError(`Root endpoint for node ${this.nodeId} not found.`);
|
|
1479
|
+
}
|
|
1480
|
+
return root.commandsOf(type);
|
|
1481
|
+
}
|
|
1435
1482
|
}
|