@matter/protocol 0.16.0-alpha.0-20250913-0bc2515df → 0.16.0-alpha.0-20250920-809524dba

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 (245) hide show
  1. package/dist/cjs/bdx/BdxClient.d.ts +31 -0
  2. package/dist/cjs/bdx/BdxClient.d.ts.map +1 -0
  3. package/dist/cjs/bdx/BdxClient.js +57 -0
  4. package/dist/cjs/bdx/BdxClient.js.map +6 -0
  5. package/dist/cjs/bdx/BdxError.d.ts +21 -0
  6. package/dist/cjs/bdx/BdxError.d.ts.map +1 -0
  7. package/dist/cjs/bdx/BdxError.js +54 -0
  8. package/dist/cjs/bdx/BdxError.js.map +6 -0
  9. package/dist/cjs/bdx/BdxMessenger.d.ts +77 -0
  10. package/dist/cjs/bdx/BdxMessenger.d.ts.map +1 -0
  11. package/dist/cjs/bdx/BdxMessenger.js +245 -0
  12. package/dist/cjs/bdx/BdxMessenger.js.map +6 -0
  13. package/dist/cjs/bdx/BdxProtocol.d.ts +25 -0
  14. package/dist/cjs/bdx/BdxProtocol.d.ts.map +1 -0
  15. package/dist/cjs/bdx/BdxProtocol.js +102 -0
  16. package/dist/cjs/bdx/BdxProtocol.js.map +6 -0
  17. package/dist/cjs/bdx/BdxSession.d.ts +36 -0
  18. package/dist/cjs/bdx/BdxSession.d.ts.map +1 -0
  19. package/dist/cjs/bdx/BdxSession.js +153 -0
  20. package/dist/cjs/bdx/BdxSession.js.map +6 -0
  21. package/dist/cjs/bdx/BdxSessionConfiguration.d.ts +61 -0
  22. package/dist/cjs/bdx/BdxSessionConfiguration.d.ts.map +1 -0
  23. package/dist/cjs/bdx/BdxSessionConfiguration.js +95 -0
  24. package/dist/cjs/bdx/BdxSessionConfiguration.js.map +6 -0
  25. package/dist/cjs/bdx/FileDesignator.d.ts +21 -0
  26. package/dist/cjs/bdx/FileDesignator.d.ts.map +1 -0
  27. package/dist/cjs/bdx/FileDesignator.js +62 -0
  28. package/dist/cjs/bdx/FileDesignator.js.map +6 -0
  29. package/dist/cjs/bdx/PersistedFileDesignator.d.ts +16 -0
  30. package/dist/cjs/bdx/PersistedFileDesignator.d.ts.map +1 -0
  31. package/dist/cjs/bdx/PersistedFileDesignator.js +57 -0
  32. package/dist/cjs/bdx/PersistedFileDesignator.js.map +6 -0
  33. package/dist/cjs/bdx/bdx-session-initiator.d.ts +14 -0
  34. package/dist/cjs/bdx/bdx-session-initiator.d.ts.map +1 -0
  35. package/dist/cjs/bdx/bdx-session-initiator.js +218 -0
  36. package/dist/cjs/bdx/bdx-session-initiator.js.map +6 -0
  37. package/dist/cjs/bdx/flow/DrivenSendingFlow.d.ts +15 -0
  38. package/dist/cjs/bdx/flow/DrivenSendingFlow.d.ts.map +1 -0
  39. package/dist/cjs/bdx/flow/DrivenSendingFlow.js +49 -0
  40. package/dist/cjs/bdx/flow/DrivenSendingFlow.js.map +6 -0
  41. package/dist/cjs/bdx/flow/DrivingReceivingFlow.d.ts +15 -0
  42. package/dist/cjs/bdx/flow/DrivingReceivingFlow.d.ts.map +1 -0
  43. package/dist/cjs/bdx/flow/DrivingReceivingFlow.js +47 -0
  44. package/dist/cjs/bdx/flow/DrivingReceivingFlow.js.map +6 -0
  45. package/dist/cjs/bdx/flow/Flow.d.ts +48 -0
  46. package/dist/cjs/bdx/flow/Flow.d.ts.map +1 -0
  47. package/dist/cjs/bdx/flow/Flow.js +112 -0
  48. package/dist/cjs/bdx/flow/Flow.js.map +6 -0
  49. package/dist/cjs/bdx/flow/FollowingReceivingFlow.d.ts +16 -0
  50. package/dist/cjs/bdx/flow/FollowingReceivingFlow.d.ts.map +1 -0
  51. package/dist/cjs/bdx/flow/FollowingReceivingFlow.js +60 -0
  52. package/dist/cjs/bdx/flow/FollowingReceivingFlow.js.map +6 -0
  53. package/dist/cjs/bdx/flow/FollowingSendingFlow.d.ts +15 -0
  54. package/dist/cjs/bdx/flow/FollowingSendingFlow.d.ts.map +1 -0
  55. package/dist/cjs/bdx/flow/FollowingSendingFlow.js +49 -0
  56. package/dist/cjs/bdx/flow/FollowingSendingFlow.js.map +6 -0
  57. package/dist/cjs/bdx/flow/InboundFlow.d.ts +26 -0
  58. package/dist/cjs/bdx/flow/InboundFlow.d.ts.map +1 -0
  59. package/dist/cjs/bdx/flow/InboundFlow.js +101 -0
  60. package/dist/cjs/bdx/flow/InboundFlow.js.map +6 -0
  61. package/dist/cjs/bdx/flow/OutboundFlow.d.ts +31 -0
  62. package/dist/cjs/bdx/flow/OutboundFlow.d.ts.map +1 -0
  63. package/dist/cjs/bdx/flow/OutboundFlow.js +124 -0
  64. package/dist/cjs/bdx/flow/OutboundFlow.js.map +6 -0
  65. package/dist/cjs/bdx/index.d.ts +16 -0
  66. package/dist/cjs/bdx/index.d.ts.map +1 -0
  67. package/dist/cjs/bdx/index.js +33 -0
  68. package/dist/cjs/bdx/index.js.map +6 -0
  69. package/dist/cjs/bdx/schema/BdxAcceptMessagesSchema.d.ts +50 -0
  70. package/dist/cjs/bdx/schema/BdxAcceptMessagesSchema.d.ts.map +1 -0
  71. package/dist/cjs/bdx/schema/BdxAcceptMessagesSchema.js +125 -0
  72. package/dist/cjs/bdx/schema/BdxAcceptMessagesSchema.js.map +6 -0
  73. package/dist/cjs/bdx/schema/BdxBlockMessagesSchema.d.ts +53 -0
  74. package/dist/cjs/bdx/schema/BdxBlockMessagesSchema.d.ts.map +1 -0
  75. package/dist/cjs/bdx/schema/BdxBlockMessagesSchema.js +92 -0
  76. package/dist/cjs/bdx/schema/BdxBlockMessagesSchema.js.map +6 -0
  77. package/dist/cjs/bdx/schema/BdxInitMessagesSchema.d.ts +117 -0
  78. package/dist/cjs/bdx/schema/BdxInitMessagesSchema.d.ts.map +1 -0
  79. package/dist/cjs/bdx/schema/BdxInitMessagesSchema.js +153 -0
  80. package/dist/cjs/bdx/schema/BdxInitMessagesSchema.js.map +6 -0
  81. package/dist/cjs/bdx/schema/BdxMessage.d.ts +23 -0
  82. package/dist/cjs/bdx/schema/BdxMessage.d.ts.map +1 -0
  83. package/dist/cjs/bdx/schema/BdxMessage.js +75 -0
  84. package/dist/cjs/bdx/schema/BdxMessage.js.map +6 -0
  85. package/dist/cjs/bdx/schema/BdxStatusMessageSchema.d.ts +12 -0
  86. package/dist/cjs/bdx/schema/BdxStatusMessageSchema.d.ts.map +1 -0
  87. package/dist/cjs/bdx/schema/BdxStatusMessageSchema.js +35 -0
  88. package/dist/cjs/bdx/schema/BdxStatusMessageSchema.js.map +6 -0
  89. package/dist/cjs/bdx/schema/index.d.ts +11 -0
  90. package/dist/cjs/bdx/schema/index.d.ts.map +1 -0
  91. package/dist/cjs/bdx/schema/index.js +28 -0
  92. package/dist/cjs/bdx/schema/index.js.map +6 -0
  93. package/dist/cjs/index.d.ts +1 -0
  94. package/dist/cjs/index.d.ts.map +1 -1
  95. package/dist/cjs/index.js +1 -0
  96. package/dist/cjs/index.js.map +1 -1
  97. package/dist/cjs/mdns/MdnsClient.js +2 -2
  98. package/dist/cjs/mdns/MdnsClient.js.map +1 -1
  99. package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
  100. package/dist/cjs/protocol/ExchangeManager.js +4 -2
  101. package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
  102. package/dist/cjs/protocol/MessageExchange.d.ts +2 -0
  103. package/dist/cjs/protocol/MessageExchange.d.ts.map +1 -1
  104. package/dist/cjs/protocol/MessageExchange.js +14 -8
  105. package/dist/cjs/protocol/MessageExchange.js.map +2 -2
  106. package/dist/cjs/protocol/ProtocolStatusMessage.d.ts +1 -1
  107. package/dist/cjs/protocol/ProtocolStatusMessage.d.ts.map +1 -1
  108. package/dist/cjs/protocol/ProtocolStatusMessage.js.map +1 -1
  109. package/dist/esm/bdx/BdxClient.d.ts +31 -0
  110. package/dist/esm/bdx/BdxClient.d.ts.map +1 -0
  111. package/dist/esm/bdx/BdxClient.js +37 -0
  112. package/dist/esm/bdx/BdxClient.js.map +6 -0
  113. package/dist/esm/bdx/BdxError.d.ts +21 -0
  114. package/dist/esm/bdx/BdxError.d.ts.map +1 -0
  115. package/dist/esm/bdx/BdxError.js +34 -0
  116. package/dist/esm/bdx/BdxError.js.map +6 -0
  117. package/dist/esm/bdx/BdxMessenger.d.ts +77 -0
  118. package/dist/esm/bdx/BdxMessenger.d.ts.map +1 -0
  119. package/dist/esm/bdx/BdxMessenger.js +233 -0
  120. package/dist/esm/bdx/BdxMessenger.js.map +6 -0
  121. package/dist/esm/bdx/BdxProtocol.d.ts +25 -0
  122. package/dist/esm/bdx/BdxProtocol.d.ts.map +1 -0
  123. package/dist/esm/bdx/BdxProtocol.js +82 -0
  124. package/dist/esm/bdx/BdxProtocol.js.map +6 -0
  125. package/dist/esm/bdx/BdxSession.d.ts +36 -0
  126. package/dist/esm/bdx/BdxSession.d.ts.map +1 -0
  127. package/dist/esm/bdx/BdxSession.js +133 -0
  128. package/dist/esm/bdx/BdxSession.js.map +6 -0
  129. package/dist/esm/bdx/BdxSessionConfiguration.d.ts +61 -0
  130. package/dist/esm/bdx/BdxSessionConfiguration.d.ts.map +1 -0
  131. package/dist/esm/bdx/BdxSessionConfiguration.js +75 -0
  132. package/dist/esm/bdx/BdxSessionConfiguration.js.map +6 -0
  133. package/dist/esm/bdx/FileDesignator.d.ts +21 -0
  134. package/dist/esm/bdx/FileDesignator.d.ts.map +1 -0
  135. package/dist/esm/bdx/FileDesignator.js +42 -0
  136. package/dist/esm/bdx/FileDesignator.js.map +6 -0
  137. package/dist/esm/bdx/PersistedFileDesignator.d.ts +16 -0
  138. package/dist/esm/bdx/PersistedFileDesignator.d.ts.map +1 -0
  139. package/dist/esm/bdx/PersistedFileDesignator.js +37 -0
  140. package/dist/esm/bdx/PersistedFileDesignator.js.map +6 -0
  141. package/dist/esm/bdx/bdx-session-initiator.d.ts +14 -0
  142. package/dist/esm/bdx/bdx-session-initiator.d.ts.map +1 -0
  143. package/dist/esm/bdx/bdx-session-initiator.js +198 -0
  144. package/dist/esm/bdx/bdx-session-initiator.js.map +6 -0
  145. package/dist/esm/bdx/flow/DrivenSendingFlow.d.ts +15 -0
  146. package/dist/esm/bdx/flow/DrivenSendingFlow.d.ts.map +1 -0
  147. package/dist/esm/bdx/flow/DrivenSendingFlow.js +29 -0
  148. package/dist/esm/bdx/flow/DrivenSendingFlow.js.map +6 -0
  149. package/dist/esm/bdx/flow/DrivingReceivingFlow.d.ts +15 -0
  150. package/dist/esm/bdx/flow/DrivingReceivingFlow.d.ts.map +1 -0
  151. package/dist/esm/bdx/flow/DrivingReceivingFlow.js +27 -0
  152. package/dist/esm/bdx/flow/DrivingReceivingFlow.js.map +6 -0
  153. package/dist/esm/bdx/flow/Flow.d.ts +48 -0
  154. package/dist/esm/bdx/flow/Flow.d.ts.map +1 -0
  155. package/dist/esm/bdx/flow/Flow.js +92 -0
  156. package/dist/esm/bdx/flow/Flow.js.map +6 -0
  157. package/dist/esm/bdx/flow/FollowingReceivingFlow.d.ts +16 -0
  158. package/dist/esm/bdx/flow/FollowingReceivingFlow.d.ts.map +1 -0
  159. package/dist/esm/bdx/flow/FollowingReceivingFlow.js +40 -0
  160. package/dist/esm/bdx/flow/FollowingReceivingFlow.js.map +6 -0
  161. package/dist/esm/bdx/flow/FollowingSendingFlow.d.ts +15 -0
  162. package/dist/esm/bdx/flow/FollowingSendingFlow.d.ts.map +1 -0
  163. package/dist/esm/bdx/flow/FollowingSendingFlow.js +29 -0
  164. package/dist/esm/bdx/flow/FollowingSendingFlow.js.map +6 -0
  165. package/dist/esm/bdx/flow/InboundFlow.d.ts +26 -0
  166. package/dist/esm/bdx/flow/InboundFlow.d.ts.map +1 -0
  167. package/dist/esm/bdx/flow/InboundFlow.js +81 -0
  168. package/dist/esm/bdx/flow/InboundFlow.js.map +6 -0
  169. package/dist/esm/bdx/flow/OutboundFlow.d.ts +31 -0
  170. package/dist/esm/bdx/flow/OutboundFlow.d.ts.map +1 -0
  171. package/dist/esm/bdx/flow/OutboundFlow.js +104 -0
  172. package/dist/esm/bdx/flow/OutboundFlow.js.map +6 -0
  173. package/dist/esm/bdx/index.d.ts +16 -0
  174. package/dist/esm/bdx/index.d.ts.map +1 -0
  175. package/dist/esm/bdx/index.js +16 -0
  176. package/dist/esm/bdx/index.js.map +6 -0
  177. package/dist/esm/bdx/schema/BdxAcceptMessagesSchema.d.ts +50 -0
  178. package/dist/esm/bdx/schema/BdxAcceptMessagesSchema.d.ts.map +1 -0
  179. package/dist/esm/bdx/schema/BdxAcceptMessagesSchema.js +109 -0
  180. package/dist/esm/bdx/schema/BdxAcceptMessagesSchema.js.map +6 -0
  181. package/dist/esm/bdx/schema/BdxBlockMessagesSchema.d.ts +53 -0
  182. package/dist/esm/bdx/schema/BdxBlockMessagesSchema.d.ts.map +1 -0
  183. package/dist/esm/bdx/schema/BdxBlockMessagesSchema.js +72 -0
  184. package/dist/esm/bdx/schema/BdxBlockMessagesSchema.js.map +6 -0
  185. package/dist/esm/bdx/schema/BdxInitMessagesSchema.d.ts +117 -0
  186. package/dist/esm/bdx/schema/BdxInitMessagesSchema.d.ts.map +1 -0
  187. package/dist/esm/bdx/schema/BdxInitMessagesSchema.js +133 -0
  188. package/dist/esm/bdx/schema/BdxInitMessagesSchema.js.map +6 -0
  189. package/dist/esm/bdx/schema/BdxMessage.d.ts +23 -0
  190. package/dist/esm/bdx/schema/BdxMessage.d.ts.map +1 -0
  191. package/dist/esm/bdx/schema/BdxMessage.js +62 -0
  192. package/dist/esm/bdx/schema/BdxMessage.js.map +6 -0
  193. package/dist/esm/bdx/schema/BdxStatusMessageSchema.d.ts +12 -0
  194. package/dist/esm/bdx/schema/BdxStatusMessageSchema.d.ts.map +1 -0
  195. package/dist/esm/bdx/schema/BdxStatusMessageSchema.js +15 -0
  196. package/dist/esm/bdx/schema/BdxStatusMessageSchema.js.map +6 -0
  197. package/dist/esm/bdx/schema/index.d.ts +11 -0
  198. package/dist/esm/bdx/schema/index.d.ts.map +1 -0
  199. package/dist/esm/bdx/schema/index.js +11 -0
  200. package/dist/esm/bdx/schema/index.js.map +6 -0
  201. package/dist/esm/index.d.ts +1 -0
  202. package/dist/esm/index.d.ts.map +1 -1
  203. package/dist/esm/index.js +1 -0
  204. package/dist/esm/index.js.map +1 -1
  205. package/dist/esm/mdns/MdnsClient.js +2 -2
  206. package/dist/esm/mdns/MdnsClient.js.map +1 -1
  207. package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
  208. package/dist/esm/protocol/ExchangeManager.js +4 -2
  209. package/dist/esm/protocol/ExchangeManager.js.map +1 -1
  210. package/dist/esm/protocol/MessageExchange.d.ts +2 -0
  211. package/dist/esm/protocol/MessageExchange.d.ts.map +1 -1
  212. package/dist/esm/protocol/MessageExchange.js +14 -8
  213. package/dist/esm/protocol/MessageExchange.js.map +2 -2
  214. package/dist/esm/protocol/ProtocolStatusMessage.d.ts +1 -1
  215. package/dist/esm/protocol/ProtocolStatusMessage.d.ts.map +1 -1
  216. package/dist/esm/protocol/ProtocolStatusMessage.js.map +1 -1
  217. package/package.json +6 -6
  218. package/src/bdx/BdxClient.ts +47 -0
  219. package/src/bdx/BdxError.ts +39 -0
  220. package/src/bdx/BdxMessenger.ts +291 -0
  221. package/src/bdx/BdxProtocol.ts +93 -0
  222. package/src/bdx/BdxSession.ts +174 -0
  223. package/src/bdx/BdxSessionConfiguration.ts +134 -0
  224. package/src/bdx/FileDesignator.ts +49 -0
  225. package/src/bdx/PersistedFileDesignator.ts +40 -0
  226. package/src/bdx/bdx-session-initiator.ts +246 -0
  227. package/src/bdx/flow/DrivenSendingFlow.ts +40 -0
  228. package/src/bdx/flow/DrivingReceivingFlow.ts +39 -0
  229. package/src/bdx/flow/Flow.ts +124 -0
  230. package/src/bdx/flow/FollowingReceivingFlow.ts +53 -0
  231. package/src/bdx/flow/FollowingSendingFlow.ts +38 -0
  232. package/src/bdx/flow/InboundFlow.ts +104 -0
  233. package/src/bdx/flow/OutboundFlow.ts +124 -0
  234. package/src/bdx/index.ts +16 -0
  235. package/src/bdx/schema/BdxAcceptMessagesSchema.ts +159 -0
  236. package/src/bdx/schema/BdxBlockMessagesSchema.ts +99 -0
  237. package/src/bdx/schema/BdxInitMessagesSchema.ts +213 -0
  238. package/src/bdx/schema/BdxMessage.ts +70 -0
  239. package/src/bdx/schema/BdxStatusMessageSchema.ts +14 -0
  240. package/src/bdx/schema/index.ts +11 -0
  241. package/src/index.ts +1 -0
  242. package/src/mdns/MdnsClient.ts +2 -2
  243. package/src/protocol/ExchangeManager.ts +2 -0
  244. package/src/protocol/MessageExchange.ts +17 -6
  245. package/src/protocol/ProtocolStatusMessage.ts +1 -1
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { Bytes, InternalError, MaybePromise } from "#general";
8
+ import { BdxMessageType, BdxStatusCode } from "#types";
9
+ import { BdxError } from "../BdxError.js";
10
+ import { Flow } from "./Flow.js";
11
+
12
+ /**
13
+ * Base class for inbound BDX transfer flows where data is received from the peer and written to our node.
14
+ */
15
+ export abstract class InboundFlow extends Flow {
16
+ #closeStreams?: (error?: unknown) => Promise<void>;
17
+ #writeController?: ReadableStreamDefaultController<Bytes>;
18
+ #writePromise?: MaybePromise<void>;
19
+
20
+ /**
21
+ * Returns initialized streams for the transfer and initializes the #closeStream class function
22
+ */
23
+ protected async initTransfer() {
24
+ // Create a ReadableStream that we can write to and start to write the data into the blob
25
+ let writeController!: ReadableStreamDefaultController<Bytes>; // variable is set on creation of the ReadableStream
26
+ const stream = new ReadableStream<Bytes>({
27
+ start: controller => {
28
+ writeController = controller;
29
+ },
30
+ });
31
+ const { fileDesignator } = this.transferParameters;
32
+ const writePromise = fileDesignator.writeFromStream(stream);
33
+
34
+ // Method to be used by main close() method to make sure all streams are correctly closed or cancelled
35
+ this.#closeStreams = async (error?: unknown) => {
36
+ if (writeController !== undefined) {
37
+ if (error != undefined) {
38
+ // When this is called, we are either done successfully or failed, error the write controller in error case
39
+ writeController.error(error);
40
+ try {
41
+ await writePromise;
42
+ } catch {
43
+ // Ignore the error because we generated it
44
+ }
45
+ }
46
+ }
47
+ // When writing and errored the stream might stay locked, so we cannot cancel it without an exception
48
+ if (!stream.locked) {
49
+ await stream.cancel();
50
+ }
51
+ };
52
+
53
+ this.#writeController = writeController;
54
+ this.#writePromise = writePromise;
55
+ }
56
+
57
+ protected get stream() {
58
+ if (!this.#writeController || !this.#writePromise) {
59
+ throw new InternalError("Transfer not initialized. Call initTransfer() before starting the transfer.");
60
+ }
61
+ return { writeController: this.#writeController, writePromise: this.#writePromise };
62
+ }
63
+
64
+ protected async finalizeTransfer() {
65
+ const { writePromise } = this.stream;
66
+ const blockCounter = this.finalBlockCounter;
67
+ await writePromise;
68
+ await this.messenger.sendBlockAckEof({ blockCounter });
69
+ }
70
+
71
+ protected writeDataChunk(
72
+ writeController: ReadableStreamDefaultController<Bytes>,
73
+ data: Bytes,
74
+ messageType: BdxMessageType,
75
+ ) {
76
+ // Enqueue the received data chunk into the writing stream
77
+ writeController.enqueue(data);
78
+ if (this.bytesLeft !== undefined) {
79
+ this.bytesLeft -= data.byteLength;
80
+ }
81
+
82
+ let done = false;
83
+
84
+ // Last block received
85
+ if (messageType === BdxMessageType.BlockEof) {
86
+ if (this.bytesLeft !== undefined && this.bytesLeft !== 0) {
87
+ throw new BdxError(
88
+ `Received BlockEof with ${this.bytesLeft}bytes left, but no more data available`,
89
+ this.bytesLeft > 0 ? BdxStatusCode.LengthTooShort : BdxStatusCode.LengthTooLarge,
90
+ );
91
+ }
92
+
93
+ done = true;
94
+ writeController.close();
95
+ }
96
+
97
+ return done;
98
+ }
99
+
100
+ override async close(error?: unknown) {
101
+ await super.close(error);
102
+ await this.#closeStreams?.(error);
103
+ }
104
+ }
@@ -0,0 +1,124 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { BytesStreamReader, InternalError } from "#general";
8
+ import { BdxStatusCode } from "#types";
9
+ import { BdxError } from "../BdxError.js";
10
+ import { Flow } from "./Flow.js";
11
+
12
+ /**
13
+ * Base class for outbound BDX transfer flows where data is read from our node and sent to the peer.
14
+ */
15
+ export abstract class OutboundFlow extends Flow {
16
+ #closeStreams?: (error?: unknown) => Promise<void>;
17
+ #iterator?: AsyncGenerator<Uint8Array<ArrayBufferLike>, void, unknown>;
18
+ #streamReader?: BytesStreamReader;
19
+
20
+ protected get stream() {
21
+ if (this.#iterator === undefined || this.#streamReader === undefined) {
22
+ throw new InternalError("Read stream not initialized");
23
+ }
24
+ return { iterator: this.#iterator, streamReader: this.#streamReader };
25
+ }
26
+
27
+ /**
28
+ * Returns initialized streams for the transfer and initializes the #closeStream class function
29
+ */
30
+ protected async initTransfer() {
31
+ const { blockSize } = this.transferParameters;
32
+
33
+ const blob = await this.transferParameters.fileDesignator.openBlob();
34
+ const blobSize = blob.size;
35
+
36
+ // Get the full or relevant part of the stream by startOffset and length
37
+ const { startOffset = 0, dataLength = blobSize } = this.transferParameters;
38
+
39
+ const dataBlob =
40
+ startOffset > 0 || dataLength !== blobSize ? blob.slice(startOffset, startOffset + dataLength) : blob;
41
+
42
+ const stream = dataBlob.stream();
43
+
44
+ const reader = stream.getReader();
45
+ // Method to be used by main close() method to make sure all streams are correctly closed or cancelled
46
+ this.#closeStreams = async (_error?: unknown) => {
47
+ if (stream.locked) {
48
+ reader?.releaseLock();
49
+ try {
50
+ await reader?.cancel();
51
+ } catch (error) {
52
+ // A TypeError is expected when the stream is already cancelled, so we ignore it
53
+ if (!(error instanceof TypeError)) {
54
+ throw error;
55
+ }
56
+ }
57
+ }
58
+ await stream.cancel();
59
+ };
60
+
61
+ const streamReader = new BytesStreamReader(reader);
62
+ this.#iterator = streamReader.read(blockSize);
63
+ this.#streamReader = streamReader;
64
+ }
65
+
66
+ /**
67
+ * Reads one data chunk from the reader and does some basic checks.
68
+ */
69
+ protected async readDataChunk(reader: AsyncGenerator<Uint8Array<ArrayBufferLike>, void, unknown>) {
70
+ const { blockSize, dataLength } = this.transferParameters;
71
+ let { value, done = false } = await reader.next();
72
+ if (value === undefined) {
73
+ // Done needs to be true when value is undefined or there is something broken
74
+ if (!done) {
75
+ throw new BdxError(
76
+ `Data length too short, expected ${blockSize}bytes, but got less`,
77
+ BdxStatusCode.LengthTooShort,
78
+ );
79
+ }
80
+ value = new Uint8Array(); // Simulate an empty value when we reached the end of the stream
81
+ } else if (value.byteLength < blockSize) {
82
+ // When we get less data than blocksize it is the last block, so validate that
83
+ ({ done = false } = await reader.next());
84
+ if (!done) {
85
+ throw new BdxError(
86
+ `Data length too short, expected ${blockSize}bytes, but got less`,
87
+ BdxStatusCode.LengthTooShort,
88
+ );
89
+ }
90
+ }
91
+
92
+ if (this.bytesLeft !== undefined && dataLength !== undefined) {
93
+ this.bytesLeft -= value.byteLength;
94
+ if (this.bytesLeft < 0) {
95
+ throw new BdxError(
96
+ `Data length exceeded, expected ${dataLength}bytes, but got ${-this.bytesLeft}bytes more`,
97
+ BdxStatusCode.LengthTooLarge,
98
+ );
99
+ }
100
+ if (done && this.bytesLeft > 0) {
101
+ throw new BdxError(
102
+ `Data length too short, expected ${dataLength}bytes, but got ${this.bytesLeft}bytes less`,
103
+ BdxStatusCode.LengthTooShort,
104
+ );
105
+ }
106
+ if (this.bytesLeft === 0) {
107
+ done = true;
108
+ }
109
+ }
110
+
111
+ return { data: value, done };
112
+ }
113
+
114
+ protected async finalizeTransfer() {
115
+ const blockCounter = this.finalBlockCounter;
116
+ const { blockCounter: ackedBlockCounter } = await this.messenger.readBlockAckEof();
117
+ this.validateCounter(ackedBlockCounter, blockCounter);
118
+ }
119
+
120
+ override async close(error?: unknown) {
121
+ await super.close(error);
122
+ await this.#closeStreams?.(error);
123
+ }
124
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ export * from "./BdxClient.js";
8
+ export * from "./BdxError.js";
9
+ export * from "./BdxMessenger.js";
10
+ export * from "./BdxProtocol.js";
11
+ export * from "./BdxSession.js";
12
+ export * from "./BdxSessionConfiguration.js";
13
+ export * from "./FileDesignator.js";
14
+ export * from "./flow/Flow.js";
15
+ export * from "./PersistedFileDesignator.js";
16
+ export * from "./schema/index.js";
@@ -0,0 +1,159 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { Bytes, DataReader, DataWriter, Endian } from "#general";
8
+ import { BdxStatusCode, Schema, TypeFromPartialBitSchema } from "#types";
9
+ import { BdxError } from "../BdxError.js";
10
+ import {
11
+ BDX_VERSION,
12
+ BdxRangeControlSchema,
13
+ BdxTransferControlBitmap,
14
+ BdxTransferControlSchema,
15
+ } from "./BdxInitMessagesSchema.js";
16
+
17
+ /** @see {@link MatterSpecification.v141.Core}, section 11.22.5.2 */
18
+ export interface BdxSendAccept {
19
+ /**
20
+ * Transfer control details
21
+ * TC
22
+ * 1 octet
23
+ */
24
+ transferControl: TypeFromPartialBitSchema<typeof BdxTransferControlBitmap>;
25
+
26
+ /**
27
+ * Specifies the maximum data size (in bytes) of the block that the Initiator supports, exclusive of block header
28
+ * fields, such as a block counter.
29
+ * MBS, 2 octets
30
+ */
31
+ maxBlockSize: number;
32
+
33
+ /**
34
+ * Allows the Initiator to send additional application-specific information about the file to be transferred
35
+ * MD, Variable length, TLV
36
+ */
37
+ metaData?: Bytes;
38
+ }
39
+
40
+ /** @see {@link MatterSpecification.v141.Core}, section 11.22.5.3 */
41
+ export interface BdxReceiveAccept extends BdxSendAccept {
42
+ /**
43
+ * Specifies a predetermined definite length for the transfer
44
+ * DEFLEN, 4/8 octets
45
+ */
46
+ length?: number | bigint;
47
+ }
48
+
49
+ /** Schema for BDX SendAccept message */
50
+ export class BdxSendAcceptMessageSchema<M extends BdxSendAccept> extends Schema<M> {
51
+ encodeInternal(message: M) {
52
+ this.validate(message);
53
+ const { transferControl, maxBlockSize, metaData } = message;
54
+
55
+ const writer = new DataWriter(Endian.Little);
56
+ writer.writeUInt8(BdxTransferControlSchema.encode(transferControl));
57
+ writer.writeUInt16(maxBlockSize);
58
+
59
+ if (metaData && metaData.byteLength > 0) {
60
+ writer.writeByteArray(metaData);
61
+ }
62
+
63
+ return writer.toByteArray();
64
+ }
65
+
66
+ decodeInternal(bytes: Bytes): M {
67
+ const reader = new DataReader(bytes, Endian.Little);
68
+ const transferControl = BdxTransferControlSchema.decode(reader.readUInt8());
69
+ const maxBlockSize = reader.readUInt16();
70
+
71
+ const metaData = reader.remainingBytesCount > 0 ? reader.remainingBytes : undefined;
72
+
73
+ const result = {
74
+ transferControl,
75
+ maxBlockSize,
76
+ metaData,
77
+ } as M;
78
+ this.validate(result);
79
+ return result;
80
+ }
81
+
82
+ override validate({ transferControl, maxBlockSize }: M) {
83
+ if (transferControl.version !== BDX_VERSION) {
84
+ throw new BdxError(
85
+ `Unsupported BDX version: ${transferControl.version}`,
86
+ BdxStatusCode.VersionNotSupported,
87
+ );
88
+ }
89
+ if (!transferControl.senderDrive && !transferControl.receiverDrive && !transferControl.asynchronousTransfer) {
90
+ throw new BdxError(
91
+ "BDX transfer control need to specify at least one of sender drive, receiver drive or asynchronousTransfer",
92
+ BdxStatusCode.BadMessageContent,
93
+ );
94
+ }
95
+ if (maxBlockSize < 1 || maxBlockSize > 0xffff) {
96
+ throw new BdxError("Max Block Size must be between 1 and 65535bytes", BdxStatusCode.BadMessageContent);
97
+ }
98
+ }
99
+ }
100
+ export const BdxSendAcceptMessage = new BdxSendAcceptMessageSchema();
101
+
102
+ /** Schema for Bdx ReceiveAccept message */
103
+ export class BdxReceiveAcceptMessageSchema extends BdxSendAcceptMessageSchema<BdxReceiveAccept> {
104
+ override encodeInternal(message: BdxReceiveAccept) {
105
+ this.validate(message);
106
+ const { transferControl, maxBlockSize, metaData, length } = message;
107
+
108
+ const rangeControl = {
109
+ definiteLength: length !== undefined && length !== 0,
110
+ wideRange: typeof length === "bigint",
111
+ };
112
+
113
+ const writer = new DataWriter(Endian.Little);
114
+ writer.writeUInt8(BdxTransferControlSchema.encode(transferControl));
115
+ writer.writeUInt8(BdxRangeControlSchema.encode(rangeControl));
116
+ writer.writeUInt16(maxBlockSize);
117
+
118
+ if (length !== undefined && length !== 0) {
119
+ if (rangeControl.wideRange) {
120
+ writer.writeUInt64(length);
121
+ } else {
122
+ writer.writeUInt32(length);
123
+ }
124
+ }
125
+
126
+ if (metaData && metaData.byteLength > 0) {
127
+ writer.writeByteArray(metaData);
128
+ }
129
+
130
+ return writer.toByteArray();
131
+ }
132
+
133
+ override decodeInternal(bytes: Bytes): BdxReceiveAccept {
134
+ const reader = new DataReader(bytes, Endian.Little);
135
+ const transferControl = BdxTransferControlSchema.decode(reader.readUInt8());
136
+ const rangeControl = BdxRangeControlSchema.decode(reader.readUInt8());
137
+ const maxBlockSize = reader.readUInt16();
138
+
139
+ let length = rangeControl.definiteLength
140
+ ? rangeControl.wideRange
141
+ ? reader.readUInt64()
142
+ : reader.readUInt32()
143
+ : undefined;
144
+ if (length === 0) {
145
+ length = undefined; // 0 also means indefinite length
146
+ }
147
+ const metaData = reader.remainingBytesCount > 0 ? reader.remainingBytes : undefined;
148
+
149
+ const result = {
150
+ transferControl,
151
+ maxBlockSize,
152
+ metaData,
153
+ length,
154
+ };
155
+ this.validate(result);
156
+ return result;
157
+ }
158
+ }
159
+ export const BdxReceiveAcceptMessage = new BdxReceiveAcceptMessageSchema();
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { Bytes, DataReader, DataWriter, Endian } from "#general";
8
+ import { Schema } from "#types";
9
+
10
+ interface BdxCounterOnly {
11
+ blockCounter: number;
12
+ }
13
+
14
+ /** @see {@link MatterSpecification.v141.Core}, section 11.22.6.2 */
15
+ export interface BdxBlockQuery extends BdxCounterOnly {}
16
+
17
+ /** @see {@link MatterSpecification.v141.Core}, section 11.22.6.6 */
18
+ export interface BdxBlockAck extends BdxCounterOnly {}
19
+
20
+ /** @see {@link MatterSpecification.v141.Core}, section 11.22.6.7 */
21
+ export interface BdxBlockAckEof extends BdxCounterOnly {}
22
+
23
+ /** @see {@link MatterSpecification.v141.Core}, section 11.22.6.3 */
24
+ export interface BdxBlockQueryWithSkip extends BdxCounterOnly {
25
+ bytesToSkip: number | bigint;
26
+ }
27
+
28
+ /** @see {@link MatterSpecification.v141.Core}, section 11.22.6.4 */
29
+ export interface BdxBlock extends BdxCounterOnly {
30
+ data: Bytes;
31
+ }
32
+
33
+ /** @see {@link MatterSpecification.v141.Core}, section 11.22.6.5 */
34
+ export interface BdxBlockEof extends BdxBlock {}
35
+
36
+ /** Schema for BDX messages that only contain a block counter: BlockQuery, BlockAck, BlockAckEof. */
37
+ export class BdxCounterOnlyMessageSchema extends Schema<BdxCounterOnly> {
38
+ encodeInternal(message: BdxCounterOnly) {
39
+ const { blockCounter } = message;
40
+
41
+ const writer = new DataWriter(Endian.Little);
42
+ writer.writeUInt32(blockCounter);
43
+ return writer.toByteArray();
44
+ }
45
+
46
+ decodeInternal(bytes: Bytes): BdxCounterOnly {
47
+ const reader = new DataReader(bytes, Endian.Little);
48
+ return {
49
+ blockCounter: reader.readUInt32(),
50
+ };
51
+ }
52
+ }
53
+ const BdxCounterOnlyMessage = new BdxCounterOnlyMessageSchema();
54
+ export const BdxBlockQueryMessage = BdxCounterOnlyMessage;
55
+ export const BdxBlockAckMessage = BdxCounterOnlyMessage;
56
+ export const BdxBlockAckEofMessage = BdxCounterOnlyMessage;
57
+
58
+ /** Schema for BDX BlockQueryWithSkip message. */
59
+ export class BdxBlockQueryWithSkipMessageSchema extends Schema<BdxBlockQueryWithSkip> {
60
+ encodeInternal(message: BdxBlockQueryWithSkip) {
61
+ const { blockCounter, bytesToSkip } = message;
62
+
63
+ const writer = new DataWriter(Endian.Little);
64
+ writer.writeUInt32(blockCounter);
65
+ writer.writeUInt64(bytesToSkip);
66
+ return writer.toByteArray();
67
+ }
68
+
69
+ decodeInternal(bytes: Bytes): BdxBlockQueryWithSkip {
70
+ const reader = new DataReader(bytes, Endian.Little);
71
+ return {
72
+ blockCounter: reader.readUInt32(),
73
+ bytesToSkip: reader.readUInt64(),
74
+ };
75
+ }
76
+ }
77
+ export const BdxBlockQueryWithSkipMessage = new BdxBlockQueryWithSkipMessageSchema();
78
+
79
+ /** Schema for BDX Block and BlockEof message that contain Block data. */
80
+ export class BdxBlockMessageSchema extends Schema<BdxBlock> {
81
+ encodeInternal(message: BdxBlock) {
82
+ const { blockCounter, data } = message;
83
+
84
+ const writer = new DataWriter(Endian.Little);
85
+ writer.writeUInt32(blockCounter);
86
+ writer.writeByteArray(data);
87
+ return writer.toByteArray();
88
+ }
89
+
90
+ decodeInternal(bytes: Bytes): BdxBlock {
91
+ const reader = new DataReader(bytes, Endian.Little);
92
+ return {
93
+ blockCounter: reader.readUInt32(),
94
+ data: reader.remainingBytes,
95
+ };
96
+ }
97
+ }
98
+ export const BdxBlockMessage = new BdxBlockMessageSchema();
99
+ export const BdxBlockEofMessage = BdxBlockMessage;