@matter/protocol 0.15.1 → 0.15.2-alpha.0-20250703-2e16aba2b

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 (149) hide show
  1. package/dist/cjs/action/Val.d.ts +4 -0
  2. package/dist/cjs/action/Val.d.ts.map +1 -1
  3. package/dist/cjs/action/Val.js.map +1 -1
  4. package/dist/cjs/action/client/ClientInteraction.d.ts +10 -8
  5. package/dist/cjs/action/client/ClientInteraction.d.ts.map +1 -1
  6. package/dist/cjs/action/client/ClientInteraction.js +152 -80
  7. package/dist/cjs/action/client/ClientInteraction.js.map +1 -1
  8. package/dist/cjs/action/client/ClientSubscription.d.ts +17 -0
  9. package/dist/cjs/action/client/ClientSubscription.d.ts.map +1 -0
  10. package/dist/cjs/action/client/ClientSubscription.js +22 -0
  11. package/dist/cjs/action/client/ClientSubscription.js.map +6 -0
  12. package/dist/cjs/action/client/ClientSubscriptionHandler.d.ts +20 -0
  13. package/dist/cjs/action/client/ClientSubscriptionHandler.d.ts.map +1 -0
  14. package/dist/cjs/action/client/ClientSubscriptionHandler.js +117 -0
  15. package/dist/cjs/action/client/ClientSubscriptionHandler.js.map +6 -0
  16. package/dist/cjs/action/client/ClientSubscriptions.d.ts +45 -0
  17. package/dist/cjs/action/client/ClientSubscriptions.d.ts.map +1 -0
  18. package/dist/cjs/action/client/ClientSubscriptions.js +141 -0
  19. package/dist/cjs/action/client/ClientSubscriptions.js.map +6 -0
  20. package/dist/cjs/action/client/InputChunk.d.ts +12 -0
  21. package/dist/cjs/action/client/InputChunk.d.ts.map +1 -0
  22. package/dist/cjs/action/client/InputChunk.js +89 -0
  23. package/dist/cjs/action/client/InputChunk.js.map +6 -0
  24. package/dist/cjs/action/client/ReadScope.d.ts +26 -0
  25. package/dist/cjs/action/client/ReadScope.d.ts.map +1 -0
  26. package/dist/cjs/action/client/ReadScope.js +87 -0
  27. package/dist/cjs/action/client/ReadScope.js.map +6 -0
  28. package/dist/cjs/action/client/index.d.ts +5 -0
  29. package/dist/cjs/action/client/index.d.ts.map +1 -1
  30. package/dist/cjs/action/client/index.js +5 -0
  31. package/dist/cjs/action/client/index.js.map +1 -1
  32. package/dist/cjs/action/request/Read.d.ts +0 -4
  33. package/dist/cjs/action/request/Read.d.ts.map +1 -1
  34. package/dist/cjs/action/request/Read.js.map +1 -1
  35. package/dist/cjs/action/request/Subscribe.d.ts +14 -1
  36. package/dist/cjs/action/request/Subscribe.d.ts.map +1 -1
  37. package/dist/cjs/action/request/Subscribe.js +2 -2
  38. package/dist/cjs/action/request/Subscribe.js.map +1 -1
  39. package/dist/cjs/action/response/SubscribeResult.d.ts +3 -5
  40. package/dist/cjs/action/response/SubscribeResult.d.ts.map +1 -1
  41. package/dist/cjs/common/FailsafeContext.d.ts.map +1 -1
  42. package/dist/cjs/common/FailsafeContext.js +0 -1
  43. package/dist/cjs/common/FailsafeContext.js.map +1 -1
  44. package/dist/cjs/fabric/FabricAuthority.d.ts +6 -1
  45. package/dist/cjs/fabric/FabricAuthority.d.ts.map +1 -1
  46. package/dist/cjs/fabric/FabricAuthority.js +16 -0
  47. package/dist/cjs/fabric/FabricAuthority.js.map +1 -1
  48. package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
  49. package/dist/cjs/interaction/InteractionClient.js +8 -4
  50. package/dist/cjs/interaction/InteractionClient.js.map +1 -1
  51. package/dist/cjs/interaction/InteractionMessenger.d.ts +20 -16
  52. package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
  53. package/dist/cjs/interaction/InteractionMessenger.js +18 -10
  54. package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
  55. package/dist/cjs/mdns/MdnsScanner.d.ts +5 -6
  56. package/dist/cjs/mdns/MdnsScanner.d.ts.map +1 -1
  57. package/dist/cjs/mdns/MdnsScanner.js.map +1 -1
  58. package/dist/cjs/protocol/DeviceCommissioner.d.ts +1 -1
  59. package/dist/cjs/protocol/DeviceCommissioner.d.ts.map +1 -1
  60. package/dist/cjs/protocol/DeviceCommissioner.js +2 -5
  61. package/dist/cjs/protocol/DeviceCommissioner.js.map +1 -1
  62. package/dist/cjs/securechannel/SecureChannelMessenger.d.ts +3 -0
  63. package/dist/cjs/securechannel/SecureChannelMessenger.d.ts.map +1 -1
  64. package/dist/cjs/securechannel/SecureChannelMessenger.js +4 -0
  65. package/dist/cjs/securechannel/SecureChannelMessenger.js.map +1 -1
  66. package/dist/esm/action/Val.d.ts +4 -0
  67. package/dist/esm/action/Val.d.ts.map +1 -1
  68. package/dist/esm/action/Val.js.map +1 -1
  69. package/dist/esm/action/client/ClientInteraction.d.ts +10 -8
  70. package/dist/esm/action/client/ClientInteraction.d.ts.map +1 -1
  71. package/dist/esm/action/client/ClientInteraction.js +154 -82
  72. package/dist/esm/action/client/ClientInteraction.js.map +1 -1
  73. package/dist/esm/action/client/ClientSubscription.d.ts +17 -0
  74. package/dist/esm/action/client/ClientSubscription.d.ts.map +1 -0
  75. package/dist/esm/action/client/ClientSubscription.js +6 -0
  76. package/dist/esm/action/client/ClientSubscription.js.map +6 -0
  77. package/dist/esm/action/client/ClientSubscriptionHandler.d.ts +20 -0
  78. package/dist/esm/action/client/ClientSubscriptionHandler.d.ts.map +1 -0
  79. package/dist/esm/action/client/ClientSubscriptionHandler.js +97 -0
  80. package/dist/esm/action/client/ClientSubscriptionHandler.js.map +6 -0
  81. package/dist/esm/action/client/ClientSubscriptions.d.ts +45 -0
  82. package/dist/esm/action/client/ClientSubscriptions.d.ts.map +1 -0
  83. package/dist/esm/action/client/ClientSubscriptions.js +129 -0
  84. package/dist/esm/action/client/ClientSubscriptions.js.map +6 -0
  85. package/dist/esm/action/client/InputChunk.d.ts +12 -0
  86. package/dist/esm/action/client/InputChunk.d.ts.map +1 -0
  87. package/dist/esm/action/client/InputChunk.js +69 -0
  88. package/dist/esm/action/client/InputChunk.js.map +6 -0
  89. package/dist/esm/action/client/ReadScope.d.ts +26 -0
  90. package/dist/esm/action/client/ReadScope.d.ts.map +1 -0
  91. package/dist/esm/action/client/ReadScope.js +67 -0
  92. package/dist/esm/action/client/ReadScope.js.map +6 -0
  93. package/dist/esm/action/client/index.d.ts +5 -0
  94. package/dist/esm/action/client/index.d.ts.map +1 -1
  95. package/dist/esm/action/client/index.js +5 -0
  96. package/dist/esm/action/client/index.js.map +1 -1
  97. package/dist/esm/action/request/Read.d.ts +0 -4
  98. package/dist/esm/action/request/Read.d.ts.map +1 -1
  99. package/dist/esm/action/request/Read.js.map +1 -1
  100. package/dist/esm/action/request/Subscribe.d.ts +14 -1
  101. package/dist/esm/action/request/Subscribe.d.ts.map +1 -1
  102. package/dist/esm/action/request/Subscribe.js +2 -2
  103. package/dist/esm/action/request/Subscribe.js.map +1 -1
  104. package/dist/esm/action/response/SubscribeResult.d.ts +3 -5
  105. package/dist/esm/action/response/SubscribeResult.d.ts.map +1 -1
  106. package/dist/esm/common/FailsafeContext.d.ts.map +1 -1
  107. package/dist/esm/common/FailsafeContext.js +0 -1
  108. package/dist/esm/common/FailsafeContext.js.map +1 -1
  109. package/dist/esm/fabric/FabricAuthority.d.ts +6 -1
  110. package/dist/esm/fabric/FabricAuthority.d.ts.map +1 -1
  111. package/dist/esm/fabric/FabricAuthority.js +25 -1
  112. package/dist/esm/fabric/FabricAuthority.js.map +1 -1
  113. package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
  114. package/dist/esm/interaction/InteractionClient.js +8 -4
  115. package/dist/esm/interaction/InteractionClient.js.map +1 -1
  116. package/dist/esm/interaction/InteractionMessenger.d.ts +20 -16
  117. package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
  118. package/dist/esm/interaction/InteractionMessenger.js +18 -10
  119. package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
  120. package/dist/esm/mdns/MdnsScanner.d.ts +5 -6
  121. package/dist/esm/mdns/MdnsScanner.d.ts.map +1 -1
  122. package/dist/esm/mdns/MdnsScanner.js.map +1 -1
  123. package/dist/esm/protocol/DeviceCommissioner.d.ts +1 -1
  124. package/dist/esm/protocol/DeviceCommissioner.d.ts.map +1 -1
  125. package/dist/esm/protocol/DeviceCommissioner.js +2 -5
  126. package/dist/esm/protocol/DeviceCommissioner.js.map +1 -1
  127. package/dist/esm/securechannel/SecureChannelMessenger.d.ts +3 -0
  128. package/dist/esm/securechannel/SecureChannelMessenger.d.ts.map +1 -1
  129. package/dist/esm/securechannel/SecureChannelMessenger.js +4 -0
  130. package/dist/esm/securechannel/SecureChannelMessenger.js.map +1 -1
  131. package/package.json +6 -6
  132. package/src/action/Val.ts +5 -0
  133. package/src/action/client/ClientInteraction.ts +178 -90
  134. package/src/action/client/ClientSubscription.ts +18 -0
  135. package/src/action/client/ClientSubscriptionHandler.ts +137 -0
  136. package/src/action/client/ClientSubscriptions.ts +172 -0
  137. package/src/action/client/InputChunk.ts +79 -0
  138. package/src/action/client/ReadScope.ts +107 -0
  139. package/src/action/client/index.ts +5 -0
  140. package/src/action/request/Read.ts +0 -5
  141. package/src/action/request/Subscribe.ts +17 -3
  142. package/src/action/response/SubscribeResult.ts +3 -4
  143. package/src/common/FailsafeContext.ts +0 -1
  144. package/src/fabric/FabricAuthority.ts +29 -1
  145. package/src/interaction/InteractionClient.ts +8 -4
  146. package/src/interaction/InteractionMessenger.ts +18 -11
  147. package/src/mdns/MdnsScanner.ts +5 -6
  148. package/src/protocol/DeviceCommissioner.ts +2 -7
  149. package/src/securechannel/SecureChannelMessenger.ts +4 -0
@@ -3,20 +3,31 @@
3
3
  * Copyright 2022-2025 Matter.js Authors
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { Environmental, NotImplementedError } from "#general";
7
- import { InteractionClientMessenger } from "#interaction/InteractionMessenger.js";
8
- import { SubscriptionClient } from "#interaction/SubscriptionClient.js";
6
+ import { BasicSet, Environmental, ImplementationError } from "#general";
7
+ import { InteractionClientMessenger, MessageType } from "#interaction/InteractionMessenger.js";
9
8
  import { InteractionQueue } from "#peer/InteractionQueue.js";
10
9
  import { ExchangeProvider } from "#protocol/ExchangeProvider.js";
10
+ import { TlvSubscribeResponse } from "#types";
11
+ import { ClientSubscriptions } from "./ClientSubscriptions.js";
12
+ import { InputChunk } from "./InputChunk.js";
13
+ const DEFAULT_MIN_INTERVAL_FLOOR_SECONDS = 1;
11
14
  class ClientInteraction {
12
15
  #exchanges;
13
16
  #subscriptions;
14
17
  #queue;
18
+ #interactions = new BasicSet();
19
+ #closed = false;
15
20
  constructor(context) {
16
21
  this.#exchanges = context.exchanges;
17
22
  this.#subscriptions = context.subscriptions;
18
23
  this.#queue = context.queue;
19
24
  }
25
+ async close() {
26
+ this.#closed = true;
27
+ while (this.#interactions.size) {
28
+ await this.#interactions.deleted;
29
+ }
30
+ }
20
31
  get subscriptions() {
21
32
  return this.#subscriptions;
22
33
  }
@@ -26,100 +37,161 @@ class ClientInteraction {
26
37
  static [Environmental.create](env) {
27
38
  const instance = new ClientInteraction({
28
39
  exchanges: env.get(ExchangeProvider),
29
- subscriptions: env.get(SubscriptionClient),
40
+ subscriptions: env.get(ClientSubscriptions),
30
41
  queue: env.get(InteractionQueue)
31
42
  });
32
43
  env.set(ClientInteraction, instance);
33
44
  return instance;
34
45
  }
35
- read(_request, _session) {
36
- throw new NotImplementedError();
46
+ async *read(request, _session) {
47
+ try {
48
+ this.#begin(request);
49
+ const messenger = await InteractionClientMessenger.create(this.#exchanges);
50
+ await messenger.sendReadRequest(request);
51
+ for await (const report of messenger.readDataReports()) {
52
+ yield InputChunk(report);
53
+ }
54
+ } finally {
55
+ this.#end(request);
56
+ }
37
57
  }
38
58
  async write(request, _session) {
39
- const messenger = await InteractionClientMessenger.create(this.#exchanges);
40
- const response = await messenger.sendWriteCommand(request);
41
- if (request.suppressResponse) {
42
- return void 0;
43
- }
44
- if (!response || !response.writeResponses?.length) {
45
- return new Array();
46
- } else {
47
- return response.writeResponses.map(
48
- ({
49
- path: { nodeId, endpointId, clusterId, attributeId, listIndex },
50
- status: { status, clusterStatus }
51
- }) => ({
52
- kind: "attr-status",
53
- path: {
54
- nodeId,
55
- endpointId,
56
- clusterId,
57
- attributeId,
58
- listIndex
59
- },
60
- status,
61
- clusterStatus
62
- })
63
- );
59
+ let messenger;
60
+ try {
61
+ this.#begin(request);
62
+ messenger = await InteractionClientMessenger.create(this.#exchanges);
63
+ const response = await messenger.sendWriteCommand(request);
64
+ if (request.suppressResponse) {
65
+ return void 0;
66
+ }
67
+ if (!response || !response.writeResponses?.length) {
68
+ return new Array();
69
+ } else {
70
+ return response.writeResponses.map(
71
+ ({
72
+ path: { nodeId, endpointId, clusterId, attributeId, listIndex },
73
+ status: { status, clusterStatus }
74
+ }) => ({
75
+ kind: "attr-status",
76
+ path: {
77
+ nodeId,
78
+ endpointId,
79
+ clusterId,
80
+ attributeId,
81
+ listIndex
82
+ },
83
+ status,
84
+ clusterStatus
85
+ })
86
+ );
87
+ }
88
+ } finally {
89
+ await messenger?.close();
90
+ this.#end(request);
64
91
  }
65
92
  }
66
93
  async *invoke(request, _session) {
67
- const messenger = await InteractionClientMessenger.create(this.#exchanges);
68
- const result = await messenger.sendInvokeCommand(request);
69
- if (!request.suppressResponse) {
70
- if (result && result.invokeResponses?.length) {
71
- const chunk = result.invokeResponses.map((response) => {
72
- if (response.command !== void 0) {
73
- const {
74
- commandPath: { endpointId, clusterId, commandId },
75
- commandRef,
76
- commandFields
77
- } = response.command;
78
- const res = {
79
- kind: "cmd-response",
80
- path: {
81
- endpointId,
82
- clusterId,
83
- commandId
84
- },
85
- commandRef,
86
- data: commandFields
87
- // TODO add decoding
88
- };
89
- return res;
90
- } else if (response.status !== void 0) {
91
- const {
92
- commandPath: { endpointId, clusterId, commandId },
93
- commandRef,
94
- status: { status, clusterStatus }
95
- } = response.status;
96
- const res = {
97
- kind: "cmd-status",
98
- path: {
99
- endpointId,
100
- clusterId,
101
- commandId
102
- },
103
- commandRef,
104
- status,
105
- clusterStatus
106
- };
107
- return res;
108
- } else {
109
- return void 0;
110
- }
111
- }).filter((r) => r !== void 0);
112
- yield chunk;
113
- } else {
114
- yield [];
94
+ let messenger;
95
+ try {
96
+ this.#begin(request);
97
+ messenger = await InteractionClientMessenger.create(this.#exchanges);
98
+ const result = await messenger.sendInvokeCommand(request);
99
+ if (!request.suppressResponse) {
100
+ if (result && result.invokeResponses?.length) {
101
+ const chunk = result.invokeResponses.map((response) => {
102
+ if (response.command !== void 0) {
103
+ const {
104
+ commandPath: { endpointId, clusterId, commandId },
105
+ commandRef,
106
+ commandFields
107
+ } = response.command;
108
+ const res = {
109
+ kind: "cmd-response",
110
+ path: {
111
+ endpointId,
112
+ clusterId,
113
+ commandId
114
+ },
115
+ commandRef,
116
+ data: commandFields
117
+ // TODO add decoding
118
+ };
119
+ return res;
120
+ } else if (response.status !== void 0) {
121
+ const {
122
+ commandPath: { endpointId, clusterId, commandId },
123
+ commandRef,
124
+ status: { status, clusterStatus }
125
+ } = response.status;
126
+ const res = {
127
+ kind: "cmd-status",
128
+ path: {
129
+ endpointId,
130
+ clusterId,
131
+ commandId
132
+ },
133
+ commandRef,
134
+ status,
135
+ clusterStatus
136
+ };
137
+ return res;
138
+ } else {
139
+ return void 0;
140
+ }
141
+ }).filter((r) => r !== void 0);
142
+ yield chunk;
143
+ } else {
144
+ yield [];
145
+ }
115
146
  }
147
+ } finally {
148
+ await messenger?.close();
149
+ this.#end(request);
116
150
  }
117
151
  }
118
- subscribe(_request, _session) {
119
- throw new NotImplementedError();
152
+ async subscribe(request, _session) {
153
+ let messenger;
154
+ try {
155
+ this.#begin(request);
156
+ messenger = await InteractionClientMessenger.create(this.#exchanges);
157
+ await messenger.sendSubscribeRequest({
158
+ ...request,
159
+ minIntervalFloorSeconds: DEFAULT_MIN_INTERVAL_FLOOR_SECONDS,
160
+ maxIntervalCeilingSeconds: DEFAULT_MIN_INTERVAL_FLOOR_SECONDS
161
+ });
162
+ await this.#handleSubscriptionResponse(request, readChunks(messenger));
163
+ const responseMessage = await messenger.nextMessage(MessageType.SubscribeResponse);
164
+ const response = TlvSubscribeResponse.decode(responseMessage.payload);
165
+ return this.#subscriptions.add(request, response);
166
+ } finally {
167
+ await messenger?.close();
168
+ this.#end(request);
169
+ }
170
+ }
171
+ async #handleSubscriptionResponse(request, result) {
172
+ if (request.updated) {
173
+ await request.updated(result);
174
+ } else {
175
+ for await (const _chunk of result) ;
176
+ }
177
+ }
178
+ #begin(request) {
179
+ if (this.#closed) {
180
+ throw new ImplementationError("Client interaction unavailable after close");
181
+ }
182
+ this.#interactions.add(request);
183
+ }
184
+ #end(request) {
185
+ this.#interactions.delete(request);
186
+ }
187
+ }
188
+ async function* readChunks(messenger) {
189
+ for await (const report of messenger.readDataReports()) {
190
+ yield InputChunk(report);
120
191
  }
121
192
  }
122
193
  export {
123
- ClientInteraction
194
+ ClientInteraction,
195
+ DEFAULT_MIN_INTERVAL_FLOOR_SECONDS
124
196
  };
125
197
  //# sourceMappingURL=ClientInteraction.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/action/client/ClientInteraction.ts"],
4
- "mappings": "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",
4
+ "mappings": "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",
5
5
  "names": []
6
6
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { Subscribe } from "#action/request/Subscribe.js";
7
+ import { ActiveSubscription } from "#action/response/SubscribeResult.js";
8
+ /**
9
+ * The client view of an established Matter subscription.
10
+ */
11
+ export interface ClientSubscription extends ActiveSubscription {
12
+ request: Subscribe;
13
+ timeoutAtMs?: number;
14
+ isClosed: boolean;
15
+ isReading: boolean;
16
+ }
17
+ //# sourceMappingURL=ClientSubscription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientSubscription.d.ts","sourceRoot":"","sources":["../../../../src/action/client/ClientSubscription.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,kBAAkB;IAC1D,OAAO,EAAE,SAAS,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACtB"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ //# sourceMappingURL=ClientSubscription.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/action/client/ClientSubscription.ts"],
4
+ "mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;",
5
+ "names": []
6
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { MessageExchange } from "#protocol/MessageExchange.js";
7
+ import { ProtocolHandler } from "#protocol/ProtocolHandler.js";
8
+ import { ClientSubscriptions } from "./ClientSubscriptions.js";
9
+ /**
10
+ * A protocol handler that informs {@link ClientSubscriptions} of new exchanges.
11
+ */
12
+ export declare class ClientSubscriptionHandler implements ProtocolHandler {
13
+ #private;
14
+ id: number;
15
+ requiresSecureSession: boolean;
16
+ constructor(subscriptions: ClientSubscriptions);
17
+ onNewExchange(exchange: MessageExchange): Promise<void>;
18
+ close(): Promise<void>;
19
+ }
20
+ //# sourceMappingURL=ClientSubscriptionHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientSubscriptionHandler.d.ts","sourceRoot":"","sources":["../../../../src/action/client/ClientSubscriptionHandler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAG/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAK/D;;GAEG;AACH,qBAAa,yBAA0B,YAAW,eAAe;;IAC7D,EAAE,SAA2B;IAC7B,qBAAqB,UAAQ;gBAIjB,aAAa,EAAE,mBAAmB;IAIxC,aAAa,CAAC,QAAQ,EAAE,eAAe;IAuDvC,KAAK;CACd"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { DecodedDataReport } from "#interaction/DecodedDataReport.js";
7
+ import { IncomingInteractionClientMessenger } from "#interaction/InteractionMessenger.js";
8
+ import { INTERACTION_PROTOCOL_ID, Status } from "#types";
9
+ import { Diagnostic, InternalError, Logger } from "@matter/general";
10
+ import { InputChunk } from "./InputChunk.js";
11
+ const logger = Logger.get("ClientSubscriptionHandler");
12
+ class ClientSubscriptionHandler {
13
+ id = INTERACTION_PROTOCOL_ID;
14
+ requiresSecureSession = true;
15
+ #subscriptions;
16
+ constructor(subscriptions) {
17
+ this.#subscriptions = subscriptions;
18
+ }
19
+ async onNewExchange(exchange) {
20
+ const messenger = new IncomingInteractionClientMessenger(exchange);
21
+ const reports = messenger.readDataReports();
22
+ const initialIteration = await reports.next();
23
+ if (initialIteration.done) {
24
+ throw new InternalError("Exchange initiated with no initial message");
25
+ }
26
+ const initialReport = initialIteration.value;
27
+ const { subscriptionId } = initialReport;
28
+ if (subscriptionId === void 0) {
29
+ logger.debug("Ignoring unsolicited data report with no subscription ID");
30
+ await sendInvalid(messenger, void 0);
31
+ return;
32
+ }
33
+ const subscription = this.#subscriptions.get(subscriptionId);
34
+ if (subscription === void 0) {
35
+ logger.debug("Ignoring data report for unknown subscription ID", Diagnostic.strong(subscriptionId));
36
+ await sendInvalid(messenger, subscriptionId);
37
+ return;
38
+ }
39
+ if (!initialReport.attributeReports?.length && !initialReport.eventReports?.length) {
40
+ subscription.timeoutAtMs = void 0;
41
+ this.#subscriptions.resetTimer();
42
+ await exchange.close();
43
+ return;
44
+ }
45
+ try {
46
+ subscription.isReading = true;
47
+ if (subscription.request.updated) {
48
+ await subscription.request.updated(processReports(initialReport, reports, messenger));
49
+ } else {
50
+ for await (const _chunk of reports) ;
51
+ }
52
+ } finally {
53
+ subscription.isReading = false;
54
+ subscription.timeoutAtMs = void 0;
55
+ this.#subscriptions.resetTimer();
56
+ await exchange.close();
57
+ }
58
+ }
59
+ async close() {
60
+ }
61
+ }
62
+ async function sendInvalid(messenger, subscriptionId) {
63
+ await messenger.sendStatus(Status.InvalidSubscription, {
64
+ multipleMessageInteraction: true,
65
+ logContext: {
66
+ subId: subscriptionId
67
+ }
68
+ });
69
+ await messenger.close();
70
+ }
71
+ async function* processReports(initialReport, otherReports, messenger) {
72
+ yield InputChunk(initialReport);
73
+ const { subscriptionId } = initialReport;
74
+ for await (const report of otherReports) {
75
+ const decoded = DecodedDataReport(report);
76
+ if (decoded.subscriptionId === void 0) {
77
+ logger.debug(
78
+ "Ignoring data report for incorrect subscription id",
79
+ Diagnostic.strong(decoded.subscriptionId)
80
+ );
81
+ await sendInvalid(messenger, decoded.subscriptionId);
82
+ }
83
+ if (decoded.subscriptionId !== subscriptionId) {
84
+ logger.debug(
85
+ "Ignoring data report for incorrect subscription id",
86
+ Diagnostic.strong(decoded.subscriptionId)
87
+ );
88
+ await sendInvalid(messenger, decoded.subscriptionId);
89
+ continue;
90
+ }
91
+ yield InputChunk(report);
92
+ }
93
+ }
94
+ export {
95
+ ClientSubscriptionHandler
96
+ };
97
+ //# sourceMappingURL=ClientSubscriptionHandler.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/action/client/ClientSubscriptionHandler.ts"],
4
+ "mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,SAAS,yBAAyB;AAClC,SAAS,0CAA0C;AAInD,SAAqB,yBAAyB,cAAc;AAC5D,SAAS,YAAY,eAAe,cAAc;AAElD,SAAS,kBAAkB;AAE3B,MAAM,SAAS,OAAO,IAAI,2BAA2B;AAK9C,MAAM,0BAAqD;AAAA,EAC9D,KAAK;AAAA,EACL,wBAAwB;AAAA,EAExB;AAAA,EAEA,YAAY,eAAoC;AAC5C,SAAK,iBAAiB;AAAA,EAC1B;AAAA,EAEA,MAAM,cAAc,UAA2B;AAC3C,UAAM,YAAY,IAAI,mCAAmC,QAAQ;AAEjE,UAAM,UAAU,UAAU,gBAAgB;AAE1C,UAAM,mBAAmB,MAAM,QAAQ,KAAK;AAC5C,QAAI,iBAAiB,MAAM;AACvB,YAAM,IAAI,cAAc,4CAA4C;AAAA,IACxE;AACA,UAAM,gBAAgB,iBAAiB;AAGvC,UAAM,EAAE,eAAe,IAAI;AAC3B,QAAI,mBAAmB,QAAW;AAC9B,aAAO,MAAM,0DAA0D;AACvE,YAAM,YAAY,WAAW,MAAS;AACtC;AAAA,IACJ;AAGA,UAAM,eAAe,KAAK,eAAe,IAAI,cAAc;AAC3D,QAAI,iBAAiB,QAAW;AAC5B,aAAO,MAAM,oDAAoD,WAAW,OAAO,cAAc,CAAC;AAClG,YAAM,YAAY,WAAW,cAAc;AAC3C;AAAA,IACJ;AAGA,QAAI,CAAC,cAAc,kBAAkB,UAAU,CAAC,cAAc,cAAc,QAAQ;AAChF,mBAAa,cAAc;AAC3B,WAAK,eAAe,WAAW;AAC/B,YAAM,SAAS,MAAM;AACrB;AAAA,IACJ;AAGA,QAAI;AACA,mBAAa,YAAY;AAEzB,UAAI,aAAa,QAAQ,SAAS;AAC9B,cAAM,aAAa,QAAQ,QAAQ,eAAe,eAAe,SAAS,SAAS,CAAC;AAAA,MACxF,OAAO;AAIH,yBAAiB,UAAU,QAAQ;AAAA,MACvC;AAAA,IACJ,UAAE;AACE,mBAAa,YAAY;AACzB,mBAAa,cAAc;AAC3B,WAAK,eAAe,WAAW;AAC/B,YAAM,SAAS,MAAM;AAAA,IACzB;AAAA,EACJ;AAAA,EAEA,MAAM,QAAQ;AAAA,EAAC;AACnB;AAEA,eAAe,YAAY,WAA+C,gBAAiC;AACvG,QAAM,UAAU,WAAW,OAAO,qBAAqB;AAAA,IACnD,4BAA4B;AAAA,IAC5B,YAAY;AAAA,MACR,OAAO;AAAA,IACX;AAAA,EACJ,CAAC;AACD,QAAM,UAAU,MAAM;AAC1B;AAOA,gBAAgB,eACZ,eACA,cACA,WACU;AACV,QAAM,WAAW,aAAa;AAE9B,QAAM,EAAE,eAAe,IAAI;AAE3B,mBAAiB,UAAU,cAAc;AACrC,UAAM,UAAU,kBAAkB,MAAM;AAExC,QAAI,QAAQ,mBAAmB,QAAW;AACtC,aAAO;AAAA,QACH;AAAA,QACA,WAAW,OAAO,QAAQ,cAAc;AAAA,MAC5C;AACA,YAAM,YAAY,WAAW,QAAQ,cAAc;AAAA,IACvD;AAEA,QAAI,QAAQ,mBAAmB,gBAAgB;AAC3C,aAAO;AAAA,QACH;AAAA,QACA,WAAW,OAAO,QAAQ,cAAc;AAAA,MAC5C;AACA,YAAM,YAAY,WAAW,QAAQ,cAAc;AACnD;AAAA,IACJ;AAEA,UAAM,WAAW,MAAM;AAAA,EAC3B;AACJ;",
5
+ "names": []
6
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { Subscribe } from "#action/request/Subscribe.js";
7
+ import { ReadResult } from "#action/response/ReadResult.js";
8
+ import { ActiveSubscription } from "#action/response/SubscribeResult.js";
9
+ import { Environment, Environmental } from "#general";
10
+ import { SubscriptionId } from "#interaction/Subscription.js";
11
+ import { SubscribeResponse } from "#types";
12
+ import { ClientSubscription } from "./ClientSubscription.js";
13
+ /**
14
+ * A managed set of {@link ClientSubscription} instances.
15
+ */
16
+ export declare class ClientSubscriptions {
17
+ #private;
18
+ static [Environmental.create](env: Environment): ClientSubscriptions;
19
+ /**
20
+ * Register an active subscription.
21
+ */
22
+ add(request: Subscribe, response: SubscribeResponse): ActiveSubscription;
23
+ /**
24
+ * Retrieve a subscription by ID.
25
+ */
26
+ get(id: SubscriptionId): ClientSubscription | undefined;
27
+ /**
28
+ * Iterate over active subscriptions.
29
+ */
30
+ [Symbol.iterator](): SetIterator<ClientSubscription>;
31
+ /**
32
+ * Terminate all subscriptions.
33
+ */
34
+ close(): Promise<void>;
35
+ /**
36
+ * Restart the timeout timer for the current set of active subscriptions.
37
+ */
38
+ resetTimer(): void;
39
+ }
40
+ export declare namespace ClientSubscriptions {
41
+ interface Listener {
42
+ (reports: AsyncIterable<ReadResult.Chunk>): Promise<void>;
43
+ }
44
+ }
45
+ //# sourceMappingURL=ClientSubscriptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientSubscriptions.d.ts","sourceRoot":"","sources":["../../../../src/action/client/ClientSubscriptions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAIH,WAAW,EACX,aAAa,EAKhB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAI7D;;GAEG;AACH,qBAAa,mBAAmB;;IAK5B,MAAM,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,WAAW;IAM9C;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,iBAAiB,GAAG,kBAAkB;IAgBxE;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,cAAc;IAItB;;OAEG;IACH,CAAC,MAAM,CAAC,QAAQ,CAAC;IAIjB;;OAEG;IACG,KAAK;IAUX;;OAEG;IACH,UAAU;CAwEb;AAMD,yBAAiB,mBAAmB,CAAC;IACjC,UAAiB,QAAQ;QACrB,CAAC,OAAO,EAAE,aAAa,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7D;CACJ"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import {
7
+ BasicSet,
8
+ CanceledError,
9
+ Diagnostic,
10
+ Environmental,
11
+ Logger,
12
+ Time,
13
+ TimeoutError
14
+ } from "#general";
15
+ const logger = Logger.get("ClientSubscriptions");
16
+ class ClientSubscriptions {
17
+ #subscriptions = new BasicSet();
18
+ #timeout;
19
+ #nextTimeoutAt;
20
+ static [Environmental.create](env) {
21
+ const instance = new ClientSubscriptions();
22
+ env.set(ClientSubscriptions, instance);
23
+ return instance;
24
+ }
25
+ /**
26
+ * Register an active subscription.
27
+ */
28
+ add(request, response) {
29
+ const subscription = {
30
+ ...response,
31
+ request,
32
+ close: () => this.#closeOne(subscription, new CanceledError()),
33
+ timeoutAtMs: void 0,
34
+ isClosed: false,
35
+ isReading: true
36
+ };
37
+ this.#subscriptions.add(subscription);
38
+ this.resetTimer();
39
+ return subscription;
40
+ }
41
+ /**
42
+ * Retrieve a subscription by ID.
43
+ */
44
+ get(id) {
45
+ return this.#subscriptions.get("subscriptionId", id);
46
+ }
47
+ /**
48
+ * Iterate over active subscriptions.
49
+ */
50
+ [Symbol.iterator]() {
51
+ return this.#subscriptions[Symbol.iterator]();
52
+ }
53
+ /**
54
+ * Terminate all subscriptions.
55
+ */
56
+ async close() {
57
+ if (this.#timeout) {
58
+ this.#timeout.stop();
59
+ this.#timeout = void 0;
60
+ }
61
+ for (const subscription of this.#subscriptions) {
62
+ subscription.close();
63
+ }
64
+ }
65
+ /**
66
+ * Restart the timeout timer for the current set of active subscriptions.
67
+ */
68
+ resetTimer() {
69
+ const now = Time.nowMs();
70
+ let nextTimeoutAt;
71
+ for (const subscription of this.#subscriptions) {
72
+ if (subscription.isReading) {
73
+ continue;
74
+ }
75
+ let { timeoutAtMs } = subscription;
76
+ if (timeoutAtMs === void 0) {
77
+ timeoutAtMs = subscription.timeoutAtMs = timeoutFor(subscription);
78
+ } else if (timeoutAtMs < now) {
79
+ this.#timeOut(subscription);
80
+ continue;
81
+ }
82
+ if (nextTimeoutAt === void 0 || nextTimeoutAt > timeoutAtMs) {
83
+ nextTimeoutAt = timeoutAtMs;
84
+ }
85
+ }
86
+ if (nextTimeoutAt === void 0) {
87
+ this.#nextTimeoutAt = void 0;
88
+ this.#timeout?.stop();
89
+ return;
90
+ }
91
+ if (nextTimeoutAt !== this.#nextTimeoutAt) {
92
+ this.#nextTimeoutAt = nextTimeoutAt;
93
+ if (this.#timeout) {
94
+ this.#timeout?.stop();
95
+ this.#timeout.intervalMs = nextTimeoutAt - now;
96
+ } else {
97
+ this.#timeout = Time.getTimer("SubscriptionTimeout", nextTimeoutAt - now, this.resetTimer.bind(this));
98
+ }
99
+ }
100
+ }
101
+ #closeOne(subscription, cause) {
102
+ if (subscription.isClosed) {
103
+ return;
104
+ }
105
+ subscription.isClosed = true;
106
+ this.#subscriptions.delete(subscription);
107
+ try {
108
+ subscription.request.closed?.(cause);
109
+ } catch (e) {
110
+ logger.error("Error canceling subscription", Diagnostic.strong(subscription.subscriptionId), e);
111
+ }
112
+ }
113
+ #timeOut(registration) {
114
+ logger.info(
115
+ "Subscription",
116
+ Diagnostic.strong(registration.subscriptionId),
117
+ "timed out after",
118
+ Diagnostic.strong(`${timeoutFor(registration)}ms`)
119
+ );
120
+ this.#closeOne(registration, new TimeoutError());
121
+ }
122
+ }
123
+ function timeoutFor(subscription) {
124
+ return subscription.maxInterval * 1e3 + (subscription.request.maxPeerResponseTime ?? 0);
125
+ }
126
+ export {
127
+ ClientSubscriptions
128
+ };
129
+ //# sourceMappingURL=ClientSubscriptions.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/action/client/ClientSubscriptions.ts"],
4
+ "mappings": "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",
5
+ "names": []
6
+ }