@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.
- package/dist/cjs/action/Val.d.ts +4 -0
- package/dist/cjs/action/Val.d.ts.map +1 -1
- package/dist/cjs/action/Val.js.map +1 -1
- package/dist/cjs/action/client/ClientInteraction.d.ts +10 -8
- package/dist/cjs/action/client/ClientInteraction.d.ts.map +1 -1
- package/dist/cjs/action/client/ClientInteraction.js +152 -80
- package/dist/cjs/action/client/ClientInteraction.js.map +1 -1
- package/dist/cjs/action/client/ClientSubscription.d.ts +17 -0
- package/dist/cjs/action/client/ClientSubscription.d.ts.map +1 -0
- package/dist/cjs/action/client/ClientSubscription.js +22 -0
- package/dist/cjs/action/client/ClientSubscription.js.map +6 -0
- package/dist/cjs/action/client/ClientSubscriptionHandler.d.ts +20 -0
- package/dist/cjs/action/client/ClientSubscriptionHandler.d.ts.map +1 -0
- package/dist/cjs/action/client/ClientSubscriptionHandler.js +117 -0
- package/dist/cjs/action/client/ClientSubscriptionHandler.js.map +6 -0
- package/dist/cjs/action/client/ClientSubscriptions.d.ts +45 -0
- package/dist/cjs/action/client/ClientSubscriptions.d.ts.map +1 -0
- package/dist/cjs/action/client/ClientSubscriptions.js +141 -0
- package/dist/cjs/action/client/ClientSubscriptions.js.map +6 -0
- package/dist/cjs/action/client/InputChunk.d.ts +12 -0
- package/dist/cjs/action/client/InputChunk.d.ts.map +1 -0
- package/dist/cjs/action/client/InputChunk.js +89 -0
- package/dist/cjs/action/client/InputChunk.js.map +6 -0
- package/dist/cjs/action/client/ReadScope.d.ts +26 -0
- package/dist/cjs/action/client/ReadScope.d.ts.map +1 -0
- package/dist/cjs/action/client/ReadScope.js +87 -0
- package/dist/cjs/action/client/ReadScope.js.map +6 -0
- package/dist/cjs/action/client/index.d.ts +5 -0
- package/dist/cjs/action/client/index.d.ts.map +1 -1
- package/dist/cjs/action/client/index.js +5 -0
- package/dist/cjs/action/client/index.js.map +1 -1
- package/dist/cjs/action/request/Read.d.ts +0 -4
- package/dist/cjs/action/request/Read.d.ts.map +1 -1
- package/dist/cjs/action/request/Read.js.map +1 -1
- package/dist/cjs/action/request/Subscribe.d.ts +14 -1
- package/dist/cjs/action/request/Subscribe.d.ts.map +1 -1
- package/dist/cjs/action/request/Subscribe.js +2 -2
- package/dist/cjs/action/request/Subscribe.js.map +1 -1
- package/dist/cjs/action/response/SubscribeResult.d.ts +3 -5
- package/dist/cjs/action/response/SubscribeResult.d.ts.map +1 -1
- package/dist/cjs/common/FailsafeContext.d.ts.map +1 -1
- package/dist/cjs/common/FailsafeContext.js +0 -1
- package/dist/cjs/common/FailsafeContext.js.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.d.ts +6 -1
- package/dist/cjs/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/cjs/fabric/FabricAuthority.js +16 -0
- package/dist/cjs/fabric/FabricAuthority.js.map +1 -1
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +8 -4
- package/dist/cjs/interaction/InteractionClient.js.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts +20 -16
- package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.js +18 -10
- package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
- package/dist/cjs/mdns/MdnsScanner.d.ts +5 -6
- package/dist/cjs/mdns/MdnsScanner.d.ts.map +1 -1
- package/dist/cjs/mdns/MdnsScanner.js.map +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.d.ts +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.d.ts.map +1 -1
- package/dist/cjs/protocol/DeviceCommissioner.js +2 -5
- package/dist/cjs/protocol/DeviceCommissioner.js.map +1 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.d.ts +3 -0
- package/dist/cjs/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.js +4 -0
- package/dist/cjs/securechannel/SecureChannelMessenger.js.map +1 -1
- package/dist/esm/action/Val.d.ts +4 -0
- package/dist/esm/action/Val.d.ts.map +1 -1
- package/dist/esm/action/Val.js.map +1 -1
- package/dist/esm/action/client/ClientInteraction.d.ts +10 -8
- package/dist/esm/action/client/ClientInteraction.d.ts.map +1 -1
- package/dist/esm/action/client/ClientInteraction.js +154 -82
- package/dist/esm/action/client/ClientInteraction.js.map +1 -1
- package/dist/esm/action/client/ClientSubscription.d.ts +17 -0
- package/dist/esm/action/client/ClientSubscription.d.ts.map +1 -0
- package/dist/esm/action/client/ClientSubscription.js +6 -0
- package/dist/esm/action/client/ClientSubscription.js.map +6 -0
- package/dist/esm/action/client/ClientSubscriptionHandler.d.ts +20 -0
- package/dist/esm/action/client/ClientSubscriptionHandler.d.ts.map +1 -0
- package/dist/esm/action/client/ClientSubscriptionHandler.js +97 -0
- package/dist/esm/action/client/ClientSubscriptionHandler.js.map +6 -0
- package/dist/esm/action/client/ClientSubscriptions.d.ts +45 -0
- package/dist/esm/action/client/ClientSubscriptions.d.ts.map +1 -0
- package/dist/esm/action/client/ClientSubscriptions.js +129 -0
- package/dist/esm/action/client/ClientSubscriptions.js.map +6 -0
- package/dist/esm/action/client/InputChunk.d.ts +12 -0
- package/dist/esm/action/client/InputChunk.d.ts.map +1 -0
- package/dist/esm/action/client/InputChunk.js +69 -0
- package/dist/esm/action/client/InputChunk.js.map +6 -0
- package/dist/esm/action/client/ReadScope.d.ts +26 -0
- package/dist/esm/action/client/ReadScope.d.ts.map +1 -0
- package/dist/esm/action/client/ReadScope.js +67 -0
- package/dist/esm/action/client/ReadScope.js.map +6 -0
- package/dist/esm/action/client/index.d.ts +5 -0
- package/dist/esm/action/client/index.d.ts.map +1 -1
- package/dist/esm/action/client/index.js +5 -0
- package/dist/esm/action/client/index.js.map +1 -1
- package/dist/esm/action/request/Read.d.ts +0 -4
- package/dist/esm/action/request/Read.d.ts.map +1 -1
- package/dist/esm/action/request/Read.js.map +1 -1
- package/dist/esm/action/request/Subscribe.d.ts +14 -1
- package/dist/esm/action/request/Subscribe.d.ts.map +1 -1
- package/dist/esm/action/request/Subscribe.js +2 -2
- package/dist/esm/action/request/Subscribe.js.map +1 -1
- package/dist/esm/action/response/SubscribeResult.d.ts +3 -5
- package/dist/esm/action/response/SubscribeResult.d.ts.map +1 -1
- package/dist/esm/common/FailsafeContext.d.ts.map +1 -1
- package/dist/esm/common/FailsafeContext.js +0 -1
- package/dist/esm/common/FailsafeContext.js.map +1 -1
- package/dist/esm/fabric/FabricAuthority.d.ts +6 -1
- package/dist/esm/fabric/FabricAuthority.d.ts.map +1 -1
- package/dist/esm/fabric/FabricAuthority.js +25 -1
- package/dist/esm/fabric/FabricAuthority.js.map +1 -1
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +8 -4
- package/dist/esm/interaction/InteractionClient.js.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts +20 -16
- package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.js +18 -10
- package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
- package/dist/esm/mdns/MdnsScanner.d.ts +5 -6
- package/dist/esm/mdns/MdnsScanner.d.ts.map +1 -1
- package/dist/esm/mdns/MdnsScanner.js.map +1 -1
- package/dist/esm/protocol/DeviceCommissioner.d.ts +1 -1
- package/dist/esm/protocol/DeviceCommissioner.d.ts.map +1 -1
- package/dist/esm/protocol/DeviceCommissioner.js +2 -5
- package/dist/esm/protocol/DeviceCommissioner.js.map +1 -1
- package/dist/esm/securechannel/SecureChannelMessenger.d.ts +3 -0
- package/dist/esm/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelMessenger.js +4 -0
- package/dist/esm/securechannel/SecureChannelMessenger.js.map +1 -1
- package/package.json +6 -6
- package/src/action/Val.ts +5 -0
- package/src/action/client/ClientInteraction.ts +178 -90
- package/src/action/client/ClientSubscription.ts +18 -0
- package/src/action/client/ClientSubscriptionHandler.ts +137 -0
- package/src/action/client/ClientSubscriptions.ts +172 -0
- package/src/action/client/InputChunk.ts +79 -0
- package/src/action/client/ReadScope.ts +107 -0
- package/src/action/client/index.ts +5 -0
- package/src/action/request/Read.ts +0 -5
- package/src/action/request/Subscribe.ts +17 -3
- package/src/action/response/SubscribeResult.ts +3 -4
- package/src/common/FailsafeContext.ts +0 -1
- package/src/fabric/FabricAuthority.ts +29 -1
- package/src/interaction/InteractionClient.ts +8 -4
- package/src/interaction/InteractionMessenger.ts +18 -11
- package/src/mdns/MdnsScanner.ts +5 -6
- package/src/protocol/DeviceCommissioner.ts +2 -7
- 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,
|
|
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(
|
|
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(
|
|
36
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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(
|
|
119
|
-
|
|
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": "AAAA;AAAA;AAAA;AAAA;AAAA;AAeA,
|
|
4
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAeA,SAAS,UAAuB,eAAe,2BAAyC;AACxF,SAAS,4BAA4B,mBAAmB;AACxD,SAAS,wBAAwB;AACjC,SAAS,wBAAwB;AACjC,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AACpC,SAAS,kBAAkB;AAQpB,MAAM,qCAAqC;AAK3C,MAAM,kBAEb;AAAA,EACa;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB,IAAI,SAA4C;AAAA,EACzE,UAAU;AAAA,EAEV,YAAY,SAAmC;AAC3C,SAAK,aAAa,QAAQ;AAC1B,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,SAAS,QAAQ;AAAA,EAC1B;AAAA,EAEA,MAAM,QAAQ;AACV,SAAK,UAAU;AAEf,WAAO,KAAK,cAAc,MAAM;AAC5B,YAAM,KAAK,cAAc;AAAA,IAC7B;AAAA,EACJ;AAAA,EAEA,IAAI,gBAAgB;AAChB,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,QAAQ;AACR,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,QAAQ,cAAc,MAAM,EAAE,KAAkB;AAC5C,UAAM,WAAW,IAAI,kBAAkB;AAAA,MACnC,WAAW,IAAI,IAAI,gBAAgB;AAAA,MACnC,eAAe,IAAI,IAAI,mBAAmB;AAAA,MAC1C,OAAO,IAAI,IAAI,gBAAgB;AAAA,IACnC,CAAC;AACD,QAAI,IAAI,mBAAmB,QAAQ;AACnC,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,KAAK,SAAe,UAAiC;AACxD,QAAI;AACA,WAAK,OAAO,OAAO;AACnB,YAAM,YAAY,MAAM,2BAA2B,OAAO,KAAK,UAAU;AAEzE,YAAM,UAAU,gBAAgB,OAAO;AAEvC,uBAAiB,UAAU,UAAU,gBAAgB,GAAG;AACpD,cAAM,WAAW,MAAM;AAAA,MAC3B;AAAA,IACJ,UAAE;AACE,WAAK,KAAK,OAAO;AAAA,IACrB;AAAA,EACJ;AAAA,EAEA,MAAM,MAAuB,SAAY,UAAqC;AAC1E,QAAI;AACJ,QAAI;AACA,WAAK,OAAO,OAAO;AACnB,kBAAY,MAAM,2BAA2B,OAAO,KAAK,UAAU;AACnE,YAAM,WAAW,MAAM,UAAU,iBAAiB,OAAO;AACzD,UAAI,QAAQ,kBAAkB;AAC1B,eAAO;AAAA,MACX;AACA,UAAI,CAAC,YAAY,CAAC,SAAS,gBAAgB,QAAQ;AAC/C,eAAO,IAAI,MAAmC;AAAA,MAClD,OAAO;AACH,eAAO,SAAS,eAAe;AAAA,UAC3B,CAAC;AAAA,YACG,MAAM,EAAE,QAAQ,YAAY,WAAW,aAAa,UAAU;AAAA,YAC9D,QAAQ,EAAE,QAAQ,cAAc;AAAA,UACpC,OAAO;AAAA,YACH,MAAM;AAAA,YACN,MAAM;AAAA,cACF;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACJ;AAAA,YACA;AAAA,YACA;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,UAAE;AACE,YAAM,WAAW,MAAM;AACvB,WAAK,KAAK,OAAO;AAAA,IACrB;AAAA,EACJ;AAAA,EAEA,OAAO,OAAO,SAAiB,UAAmC;AAC9D,QAAI;AACJ,QAAI;AACA,WAAK,OAAO,OAAO;AACnB,kBAAY,MAAM,2BAA2B,OAAO,KAAK,UAAU;AACnE,YAAM,SAAS,MAAM,UAAU,kBAAkB,OAAO;AACxD,UAAI,CAAC,QAAQ,kBAAkB;AAC3B,YAAI,UAAU,OAAO,iBAAiB,QAAQ;AAC1C,gBAAM,QAA4B,OAAO,gBACpC,IAAI,cAAY;AACb,gBAAI,SAAS,YAAY,QAAW;AAChC,oBAAM;AAAA,gBACF,aAAa,EAAE,YAAY,WAAW,UAAU;AAAA,gBAChD;AAAA,gBACA;AAAA,cACJ,IAAI,SAAS;AACb,oBAAM,MAAoC;AAAA,gBACtC,MAAM;AAAA,gBACN,MAAM;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA;AAAA,gBACJ;AAAA,gBACA;AAAA,gBACA,MAAM;AAAA;AAAA,cACV;AACA,qBAAO;AAAA,YACX,WAAW,SAAS,WAAW,QAAW;AACtC,oBAAM;AAAA,gBACF,aAAa,EAAE,YAAY,WAAW,UAAU;AAAA,gBAChD;AAAA,gBACA,QAAQ,EAAE,QAAQ,cAAc;AAAA,cACpC,IAAI,SAAS;AACb,oBAAM,MAAkC;AAAA,gBACpC,MAAM;AAAA,gBACN,MAAM;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA;AAAA,gBACJ;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACJ;AACA,qBAAO;AAAA,YACX,OAAO;AAEH,qBAAO;AAAA,YACX;AAAA,UACJ,CAAC,EACA,OAAO,OAAK,MAAM,MAAS;AAChC,gBAAM;AAAA,QACV,OAAO;AACH,gBAAM,CAAC;AAAA,QACX;AAAA,MACJ;AAAA,IACJ,UAAE;AACE,YAAM,WAAW,MAAM;AACvB,WAAK,KAAK,OAAO;AAAA,IACrB;AAAA,EACJ;AAAA,EAEA,MAAM,UAAU,SAAoB,UAAsC;AACtE,QAAI;AACJ,QAAI;AACA,WAAK,OAAO,OAAO;AAEnB,kBAAY,MAAM,2BAA2B,OAAO,KAAK,UAAU;AAEnE,YAAM,UAAU,qBAAqB;AAAA,QACjC,GAAG;AAAA,QACH,yBAAyB;AAAA,QACzB,2BAA2B;AAAA,MAC/B,CAAC;AAED,YAAM,KAAK,4BAA4B,SAAS,WAAW,SAAS,CAAC;AAErE,YAAM,kBAAkB,MAAM,UAAU,YAAY,YAAY,iBAAiB;AACjF,YAAM,WAAW,qBAAqB,OAAO,gBAAgB,OAAO;AAEpE,aAAO,KAAK,eAAe,IAAI,SAAS,QAAQ;AAAA,IACpD,UAAE;AACE,YAAM,WAAW,MAAM;AACvB,WAAK,KAAK,OAAO;AAAA,IACrB;AAAA,EACJ;AAAA,EAEA,MAAM,4BAA4B,SAAoB,QAAoB;AACtE,QAAI,QAAQ,SAAS;AACjB,YAAM,QAAQ,QAAQ,MAAM;AAAA,IAChC,OAAO;AAMH,uBAAiB,UAAU,OAAO;AAAA,IACtC;AAAA,EACJ;AAAA,EAEA,OAAO,SAA4C;AAC/C,QAAI,KAAK,SAAS;AACd,YAAM,IAAI,oBAAoB,4CAA4C;AAAA,IAC9E;AACA,SAAK,cAAc,IAAI,OAAO;AAAA,EAClC;AAAA,EAEA,KAAK,SAA4C;AAC7C,SAAK,cAAc,OAAO,OAAO;AAAA,EACrC;AACJ;AAEA,gBAAgB,WAAW,WAAuC;AAC9D,mBAAiB,UAAU,UAAU,gBAAgB,GAAG;AACpD,UAAM,WAAW,MAAM;AAAA,EAC3B;AACJ;",
|
|
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,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": "AAAA;AAAA;AAAA;AAAA;AAAA;AASA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEG;AAKP,MAAM,SAAS,OAAO,IAAI,qBAAqB;AAKxC,MAAM,oBAAoB;AAAA,EAC7B,iBAAiB,IAAI,SAA6B;AAAA,EAClD;AAAA,EACA;AAAA,EAEA,QAAQ,cAAc,MAAM,EAAE,KAAkB;AAC5C,UAAM,WAAW,IAAI,oBAAoB;AACzC,QAAI,IAAI,qBAAqB,QAAQ;AACrC,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAoB,UAAiD;AACrE,UAAM,eAAmC;AAAA,MACrC,GAAG;AAAA,MACH;AAAA,MACA,OAAO,MAAM,KAAK,UAAU,cAAc,IAAI,cAAc,CAAC;AAAA,MAC7D,aAAa;AAAA,MACb,UAAU;AAAA,MACV,WAAW;AAAA,IACf;AAEA,SAAK,eAAe,IAAI,YAAY;AACpC,SAAK,WAAW;AAEhB,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,IAAoB;AACpB,WAAO,KAAK,eAAe,IAAI,kBAAkB,EAAE;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,CAAC,OAAO,QAAQ,IAAI;AAChB,WAAO,KAAK,eAAe,OAAO,QAAQ,EAAE;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ;AACV,QAAI,KAAK,UAAU;AACf,WAAK,SAAS,KAAK;AACnB,WAAK,WAAW;AAAA,IACpB;AACA,eAAW,gBAAgB,KAAK,gBAAgB;AAC5C,mBAAa,MAAM;AAAA,IACvB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa;AACT,UAAM,MAAM,KAAK,MAAM;AACvB,QAAI;AAGJ,eAAW,gBAAgB,KAAK,gBAAgB;AAE5C,UAAI,aAAa,WAAW;AACxB;AAAA,MACJ;AAGA,UAAI,EAAE,YAAY,IAAI;AACtB,UAAI,gBAAgB,QAAW;AAE3B,sBAAc,aAAa,cAAc,WAAW,YAAY;AAAA,MACpE,WAAW,cAAc,KAAK;AAE1B,aAAK,SAAS,YAAY;AAC1B;AAAA,MACJ;AAGA,UAAI,kBAAkB,UAAa,gBAAgB,aAAa;AAC5D,wBAAgB;AAAA,MACpB;AAAA,IACJ;AAGA,QAAI,kBAAkB,QAAW;AAC7B,WAAK,iBAAiB;AACtB,WAAK,UAAU,KAAK;AACpB;AAAA,IACJ;AAGA,QAAI,kBAAkB,KAAK,gBAAgB;AACvC,WAAK,iBAAiB;AACtB,UAAI,KAAK,UAAU;AACf,aAAK,UAAU,KAAK;AACpB,aAAK,SAAS,aAAa,gBAAgB;AAAA,MAC/C,OAAO;AACH,aAAK,WAAW,KAAK,SAAS,uBAAuB,gBAAgB,KAAK,KAAK,WAAW,KAAK,IAAI,CAAC;AAAA,MACxG;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,UAAU,cAAkC,OAAqC;AAC7E,QAAI,aAAa,UAAU;AACvB;AAAA,IACJ;AACA,iBAAa,WAAW;AACxB,SAAK,eAAe,OAAO,YAAY;AAEvC,QAAI;AACA,mBAAa,QAAQ,SAAS,KAAK;AAAA,IACvC,SAAS,GAAG;AACR,aAAO,MAAM,gCAAgC,WAAW,OAAO,aAAa,cAAc,GAAG,CAAC;AAAA,IAClG;AAAA,EACJ;AAAA,EAEA,SAAS,cAAkC;AACvC,WAAO;AAAA,MACH;AAAA,MACA,WAAW,OAAO,aAAa,cAAc;AAAA,MAC7C;AAAA,MACA,WAAW,OAAO,GAAG,WAAW,YAAY,CAAC,IAAI;AAAA,IACrD;AAGA,SAAK,UAAU,cAAc,IAAI,aAAa,CAAC;AAAA,EACnD;AACJ;AAEA,SAAS,WAAW,cAAkC;AAClD,SAAO,aAAa,cAAc,OAAQ,aAAa,QAAQ,uBAAuB;AAC1F;",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|