@microbit/microbit-connection 0.0.0-alpha.32 → 0.0.0-alpha.35

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 (231) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +89 -6
  3. package/build/cjs/accelerometer-service.js +106 -0
  4. package/build/cjs/accelerometer-service.js.map +1 -0
  5. package/build/cjs/accelerometer.js +16 -0
  6. package/build/cjs/accelerometer.js.map +1 -0
  7. package/build/cjs/async-util.js +27 -0
  8. package/build/cjs/async-util.js.map +1 -0
  9. package/build/cjs/bluetooth-device-wrapper.js +467 -0
  10. package/build/cjs/bluetooth-device-wrapper.js.map +1 -0
  11. package/build/cjs/bluetooth-profile.js +86 -0
  12. package/build/cjs/bluetooth-profile.js.map +1 -0
  13. package/build/cjs/bluetooth.d.ts +108 -0
  14. package/build/cjs/bluetooth.js +272 -0
  15. package/build/cjs/bluetooth.js.map +1 -0
  16. package/build/cjs/board-id.js +81 -0
  17. package/build/cjs/board-id.js.map +1 -0
  18. package/build/cjs/board-serial-info.js +51 -0
  19. package/build/cjs/board-serial-info.js.map +1 -0
  20. package/build/cjs/button-service.js +80 -0
  21. package/build/cjs/button-service.js.map +1 -0
  22. package/build/cjs/buttons.js +22 -0
  23. package/build/cjs/buttons.js.map +1 -0
  24. package/build/cjs/constants.js +73 -0
  25. package/build/cjs/constants.js.map +1 -0
  26. package/build/{device.d.ts → cjs/device.d.ts} +6 -33
  27. package/build/cjs/device.js +133 -0
  28. package/build/cjs/device.js.map +1 -0
  29. package/build/{events.d.ts → cjs/events.d.ts} +1 -2
  30. package/build/cjs/events.js +109 -0
  31. package/build/cjs/events.js.map +1 -0
  32. package/build/cjs/hex-flash-data-source.js +26 -0
  33. package/build/cjs/hex-flash-data-source.js.map +1 -0
  34. package/build/cjs/index.d.ts +17 -0
  35. package/build/cjs/index.js +35 -0
  36. package/build/cjs/index.js.map +1 -0
  37. package/build/cjs/led-service.js +120 -0
  38. package/build/{led-service.js.map → cjs/led-service.js.map} +1 -1
  39. package/build/cjs/led.js +3 -0
  40. package/build/cjs/led.js.map +1 -0
  41. package/build/{logging.d.ts → cjs/logging.d.ts} +3 -3
  42. package/build/cjs/logging.js +16 -0
  43. package/build/cjs/logging.js.map +1 -0
  44. package/build/cjs/magnetometer-service.js +129 -0
  45. package/build/cjs/magnetometer-service.js.map +1 -0
  46. package/build/cjs/magnetometer.js +16 -0
  47. package/build/cjs/magnetometer.js.map +1 -0
  48. package/build/cjs/package.json +1 -0
  49. package/build/cjs/promise-queue.js +78 -0
  50. package/build/cjs/promise-queue.js.map +1 -0
  51. package/build/cjs/serial-events.d.ts +20 -0
  52. package/build/cjs/serial-events.js +69 -0
  53. package/build/cjs/serial-events.js.map +1 -0
  54. package/build/cjs/service-events.js +39 -0
  55. package/build/cjs/service-events.js.map +1 -0
  56. package/build/cjs/setupTests.js.map +1 -0
  57. package/build/cjs/uart-service.js +76 -0
  58. package/build/cjs/uart-service.js.map +1 -0
  59. package/build/cjs/uart.js +16 -0
  60. package/build/cjs/uart.js.map +1 -0
  61. package/build/{usb-device-wrapper.d.ts → cjs/usb-device-wrapper.d.ts} +1 -6
  62. package/build/cjs/usb-device-wrapper.js +412 -0
  63. package/build/cjs/usb-device-wrapper.js.map +1 -0
  64. package/build/cjs/usb-partial-flashing-utils.js +133 -0
  65. package/build/cjs/usb-partial-flashing-utils.js.map +1 -0
  66. package/build/{usb-partial-flashing.d.ts → cjs/usb-partial-flashing.d.ts} +3 -3
  67. package/build/cjs/usb-partial-flashing.js +341 -0
  68. package/build/cjs/usb-partial-flashing.js.map +1 -0
  69. package/build/cjs/usb-radio-bridge.d.ts +24 -0
  70. package/build/cjs/usb-radio-bridge.js +513 -0
  71. package/build/cjs/usb-radio-bridge.js.map +1 -0
  72. package/build/cjs/usb-serial-protocol.js +183 -0
  73. package/build/cjs/usb-serial-protocol.js.map +1 -0
  74. package/build/cjs/usb.d.ts +40 -0
  75. package/build/cjs/usb.js +525 -0
  76. package/build/cjs/usb.js.map +1 -0
  77. package/build/esm/accelerometer-service.d.ts +18 -0
  78. package/build/esm/accelerometer-service.js.map +1 -0
  79. package/build/esm/accelerometer.d.ts +9 -0
  80. package/build/esm/accelerometer.js.map +1 -0
  81. package/build/esm/async-util.d.ts +13 -0
  82. package/build/esm/async-util.js.map +1 -0
  83. package/build/esm/bluetooth-device-wrapper.d.ts +63 -0
  84. package/build/esm/bluetooth-device-wrapper.js.map +1 -0
  85. package/build/esm/bluetooth-profile.d.ts +139 -0
  86. package/build/esm/bluetooth-profile.js.map +1 -0
  87. package/build/esm/bluetooth.d.ts +108 -0
  88. package/build/{bluetooth.js → esm/bluetooth.js} +6 -2
  89. package/build/esm/bluetooth.js.map +1 -0
  90. package/build/esm/board-id.d.ts +36 -0
  91. package/build/esm/board-id.js.map +1 -0
  92. package/build/esm/board-serial-info.d.ts +14 -0
  93. package/build/esm/board-serial-info.js.map +1 -0
  94. package/build/esm/button-service.d.ts +13 -0
  95. package/build/esm/button-service.js.map +1 -0
  96. package/build/esm/buttons.d.ts +10 -0
  97. package/build/esm/buttons.js.map +1 -0
  98. package/build/esm/constants.d.ts +48 -0
  99. package/build/esm/constants.js.map +1 -0
  100. package/build/esm/device.d.ts +181 -0
  101. package/build/{device.js → esm/device.js} +1 -63
  102. package/build/esm/device.js.map +1 -0
  103. package/build/esm/events.d.ts +110 -0
  104. package/build/esm/events.js.map +1 -0
  105. package/build/esm/hex-flash-data-source.d.ts +7 -0
  106. package/build/esm/hex-flash-data-source.js.map +1 -0
  107. package/build/esm/index.d.ts +17 -0
  108. package/build/esm/index.js +12 -0
  109. package/build/esm/index.js.map +1 -0
  110. package/build/esm/led-service.d.ts +20 -0
  111. package/build/esm/led-service.js.map +1 -0
  112. package/build/esm/led.d.ts +6 -0
  113. package/build/esm/led.js.map +1 -0
  114. package/build/esm/logging.d.ts +21 -0
  115. package/build/esm/logging.js.map +1 -0
  116. package/build/esm/magnetometer-service.d.ts +22 -0
  117. package/build/esm/magnetometer-service.js.map +1 -0
  118. package/build/esm/magnetometer.d.ts +9 -0
  119. package/build/esm/magnetometer.js.map +1 -0
  120. package/build/esm/package.json +1 -0
  121. package/build/esm/promise-queue.d.ts +27 -0
  122. package/build/esm/promise-queue.js.map +1 -0
  123. package/build/esm/serial-events.d.ts +20 -0
  124. package/build/esm/serial-events.js +61 -0
  125. package/build/esm/serial-events.js.map +1 -0
  126. package/build/esm/service-events.d.ts +17 -0
  127. package/build/esm/service-events.js.map +1 -0
  128. package/build/esm/setupTests.d.ts +6 -0
  129. package/build/{setupTests.js.map → esm/setupTests.js.map} +1 -1
  130. package/build/esm/uart-service.d.ts +13 -0
  131. package/build/esm/uart-service.js.map +1 -0
  132. package/build/esm/uart.d.ts +4 -0
  133. package/build/esm/uart.js.map +1 -0
  134. package/build/esm/usb-device-wrapper.d.ts +47 -0
  135. package/build/{usb-device-wrapper.js → esm/usb-device-wrapper.js} +10 -9
  136. package/build/esm/usb-device-wrapper.js.map +1 -0
  137. package/build/esm/usb-partial-flashing-utils.d.ts +17 -0
  138. package/build/esm/usb-partial-flashing-utils.js.map +1 -0
  139. package/build/esm/usb-partial-flashing.d.ts +69 -0
  140. package/build/{usb-partial-flashing.js → esm/usb-partial-flashing.js} +8 -10
  141. package/build/esm/usb-partial-flashing.js.map +1 -0
  142. package/build/esm/usb-radio-bridge.d.ts +24 -0
  143. package/build/{usb-radio-bridge.js → esm/usb-radio-bridge.js} +5 -1
  144. package/build/esm/usb-radio-bridge.js.map +1 -0
  145. package/build/esm/usb-serial-protocol.d.ts +66 -0
  146. package/build/esm/usb-serial-protocol.js.map +1 -0
  147. package/build/esm/usb.d.ts +40 -0
  148. package/build/{usb.js → esm/usb.js} +7 -2
  149. package/build/esm/usb.js.map +1 -0
  150. package/package.json +19 -6
  151. package/typedoc.json +14 -0
  152. package/build/accelerometer-service.js.map +0 -1
  153. package/build/accelerometer.js.map +0 -1
  154. package/build/async-util.js.map +0 -1
  155. package/build/bluetooth-device-wrapper.js.map +0 -1
  156. package/build/bluetooth-profile.js.map +0 -1
  157. package/build/bluetooth.d.ts +0 -61
  158. package/build/bluetooth.js.map +0 -1
  159. package/build/board-id.js.map +0 -1
  160. package/build/board-serial-info.js.map +0 -1
  161. package/build/button-service.js.map +0 -1
  162. package/build/buttons.js.map +0 -1
  163. package/build/constants.js.map +0 -1
  164. package/build/device.js.map +0 -1
  165. package/build/events.js.map +0 -1
  166. package/build/hex-flash-data-source.js.map +0 -1
  167. package/build/index.d.ts +0 -13
  168. package/build/index.js +0 -10
  169. package/build/index.js.map +0 -1
  170. package/build/led.js.map +0 -1
  171. package/build/logging.js.map +0 -1
  172. package/build/magnetometer-service.js.map +0 -1
  173. package/build/magnetometer.js.map +0 -1
  174. package/build/promise-queue.js.map +0 -1
  175. package/build/service-events.js.map +0 -1
  176. package/build/uart-service.js.map +0 -1
  177. package/build/uart.js.map +0 -1
  178. package/build/usb-device-wrapper.js.map +0 -1
  179. package/build/usb-partial-flashing-utils.js.map +0 -1
  180. package/build/usb-partial-flashing.js.map +0 -1
  181. package/build/usb-radio-bridge.d.ts +0 -41
  182. package/build/usb-radio-bridge.js.map +0 -1
  183. package/build/usb-serial-protocol.js.map +0 -1
  184. package/build/usb.d.ts +0 -58
  185. package/build/usb.js.map +0 -1
  186. package/vite.config.ts +0 -34
  187. /package/build/{accelerometer-service.d.ts → cjs/accelerometer-service.d.ts} +0 -0
  188. /package/build/{accelerometer.d.ts → cjs/accelerometer.d.ts} +0 -0
  189. /package/build/{async-util.d.ts → cjs/async-util.d.ts} +0 -0
  190. /package/build/{bluetooth-device-wrapper.d.ts → cjs/bluetooth-device-wrapper.d.ts} +0 -0
  191. /package/build/{bluetooth-profile.d.ts → cjs/bluetooth-profile.d.ts} +0 -0
  192. /package/build/{board-id.d.ts → cjs/board-id.d.ts} +0 -0
  193. /package/build/{board-serial-info.d.ts → cjs/board-serial-info.d.ts} +0 -0
  194. /package/build/{button-service.d.ts → cjs/button-service.d.ts} +0 -0
  195. /package/build/{buttons.d.ts → cjs/buttons.d.ts} +0 -0
  196. /package/build/{constants.d.ts → cjs/constants.d.ts} +0 -0
  197. /package/build/{hex-flash-data-source.d.ts → cjs/hex-flash-data-source.d.ts} +0 -0
  198. /package/build/{led-service.d.ts → cjs/led-service.d.ts} +0 -0
  199. /package/build/{led.d.ts → cjs/led.d.ts} +0 -0
  200. /package/build/{magnetometer-service.d.ts → cjs/magnetometer-service.d.ts} +0 -0
  201. /package/build/{magnetometer.d.ts → cjs/magnetometer.d.ts} +0 -0
  202. /package/build/{promise-queue.d.ts → cjs/promise-queue.d.ts} +0 -0
  203. /package/build/{service-events.d.ts → cjs/service-events.d.ts} +0 -0
  204. /package/build/{setupTests.d.ts → cjs/setupTests.d.ts} +0 -0
  205. /package/build/{uart-service.d.ts → cjs/uart-service.d.ts} +0 -0
  206. /package/build/{uart.d.ts → cjs/uart.d.ts} +0 -0
  207. /package/build/{usb-partial-flashing-utils.d.ts → cjs/usb-partial-flashing-utils.d.ts} +0 -0
  208. /package/build/{usb-serial-protocol.d.ts → cjs/usb-serial-protocol.d.ts} +0 -0
  209. /package/build/{accelerometer-service.js → esm/accelerometer-service.js} +0 -0
  210. /package/build/{accelerometer.js → esm/accelerometer.js} +0 -0
  211. /package/build/{async-util.js → esm/async-util.js} +0 -0
  212. /package/build/{bluetooth-device-wrapper.js → esm/bluetooth-device-wrapper.js} +0 -0
  213. /package/build/{bluetooth-profile.js → esm/bluetooth-profile.js} +0 -0
  214. /package/build/{board-id.js → esm/board-id.js} +0 -0
  215. /package/build/{board-serial-info.js → esm/board-serial-info.js} +0 -0
  216. /package/build/{button-service.js → esm/button-service.js} +0 -0
  217. /package/build/{buttons.js → esm/buttons.js} +0 -0
  218. /package/build/{constants.js → esm/constants.js} +0 -0
  219. /package/build/{events.js → esm/events.js} +0 -0
  220. /package/build/{hex-flash-data-source.js → esm/hex-flash-data-source.js} +0 -0
  221. /package/build/{led-service.js → esm/led-service.js} +0 -0
  222. /package/build/{led.js → esm/led.js} +0 -0
  223. /package/build/{logging.js → esm/logging.js} +0 -0
  224. /package/build/{magnetometer-service.js → esm/magnetometer-service.js} +0 -0
  225. /package/build/{magnetometer.js → esm/magnetometer.js} +0 -0
  226. /package/build/{promise-queue.js → esm/promise-queue.js} +0 -0
  227. /package/build/{service-events.js → esm/service-events.js} +0 -0
  228. /package/build/{uart-service.js → esm/uart-service.js} +0 -0
  229. /package/build/{uart.js → esm/uart.js} +0 -0
  230. /package/build/{usb-partial-flashing-utils.js → esm/usb-partial-flashing-utils.js} +0 -0
  231. /package/build/{usb-serial-protocol.js → esm/usb-serial-protocol.js} +0 -0
@@ -0,0 +1,513 @@
1
+ "use strict";
2
+ /**
3
+ * (c) 2023, Center for Computational Thinking and Design at Aarhus University and contributors
4
+ *
5
+ * SPDX-License-Identifier: MIT
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || function (mod) {
24
+ if (mod && mod.__esModule) return mod;
25
+ var result = {};
26
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
27
+ __setModuleDefault(result, mod);
28
+ return result;
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.createRadioBridgeConnection = void 0;
32
+ const accelerometer_js_1 = require("./accelerometer.js");
33
+ const buttons_js_1 = require("./buttons.js");
34
+ const device_js_1 = require("./device.js");
35
+ const events_js_1 = require("./events.js");
36
+ const logging_js_1 = require("./logging.js");
37
+ const protocol = __importStar(require("./usb-serial-protocol.js"));
38
+ const connectTimeoutDuration = 10000;
39
+ class BridgeError extends Error {
40
+ }
41
+ class RemoteError extends Error {
42
+ }
43
+ /**
44
+ * A radio bridge connection factory.
45
+ */
46
+ const createRadioBridgeConnection = (delegate, options) => new MicrobitRadioBridgeConnectionImpl(delegate, options);
47
+ exports.createRadioBridgeConnection = createRadioBridgeConnection;
48
+ /**
49
+ * Wraps around a USB connection to implement a subset of services over a serial protocol.
50
+ *
51
+ * When it connects/disconnects it affects the delegate connection.
52
+ */
53
+ class MicrobitRadioBridgeConnectionImpl extends events_js_1.TypedEventTarget {
54
+ constructor(delegate, options) {
55
+ super();
56
+ Object.defineProperty(this, "delegate", {
57
+ enumerable: true,
58
+ configurable: true,
59
+ writable: true,
60
+ value: delegate
61
+ });
62
+ Object.defineProperty(this, "status", {
63
+ enumerable: true,
64
+ configurable: true,
65
+ writable: true,
66
+ value: void 0
67
+ });
68
+ Object.defineProperty(this, "logging", {
69
+ enumerable: true,
70
+ configurable: true,
71
+ writable: true,
72
+ value: void 0
73
+ });
74
+ Object.defineProperty(this, "serialSession", {
75
+ enumerable: true,
76
+ configurable: true,
77
+ writable: true,
78
+ value: void 0
79
+ });
80
+ Object.defineProperty(this, "remoteDeviceId", {
81
+ enumerable: true,
82
+ configurable: true,
83
+ writable: true,
84
+ value: void 0
85
+ });
86
+ Object.defineProperty(this, "disconnectPromise", {
87
+ enumerable: true,
88
+ configurable: true,
89
+ writable: true,
90
+ value: void 0
91
+ });
92
+ Object.defineProperty(this, "serialSessionOpen", {
93
+ enumerable: true,
94
+ configurable: true,
95
+ writable: true,
96
+ value: false
97
+ });
98
+ Object.defineProperty(this, "ignoreDelegateStatus", {
99
+ enumerable: true,
100
+ configurable: true,
101
+ writable: true,
102
+ value: false
103
+ });
104
+ Object.defineProperty(this, "delegateStatusListener", {
105
+ enumerable: true,
106
+ configurable: true,
107
+ writable: true,
108
+ value: (e) => {
109
+ if (this.ignoreDelegateStatus) {
110
+ return;
111
+ }
112
+ const currentStatus = this.status;
113
+ if (e.status !== device_js_1.ConnectionStatus.CONNECTED) {
114
+ this.setStatus(e.status);
115
+ this.serialSession?.dispose();
116
+ }
117
+ else {
118
+ this.status = device_js_1.ConnectionStatus.DISCONNECTED;
119
+ if (currentStatus === device_js_1.ConnectionStatus.DISCONNECTED &&
120
+ this.serialSessionOpen) {
121
+ this.serialSession?.connect();
122
+ }
123
+ }
124
+ }
125
+ });
126
+ this.logging = options?.logging ?? new logging_js_1.NullLogging();
127
+ this.status = this.statusFromDelegate();
128
+ }
129
+ getBoardVersion() {
130
+ return this.delegate.getBoardVersion();
131
+ }
132
+ serialWrite(data) {
133
+ return this.delegate.serialWrite(data);
134
+ }
135
+ async initialize() {
136
+ await this.delegate.initialize();
137
+ this.setStatus(this.statusFromDelegate());
138
+ this.delegate.addEventListener("status", this.delegateStatusListener);
139
+ }
140
+ dispose() {
141
+ this.delegate.removeEventListener("status", this.delegateStatusListener);
142
+ this.delegate.dispose();
143
+ }
144
+ clearDevice() {
145
+ this.delegate.clearDevice();
146
+ }
147
+ setRemoteDeviceId(remoteDeviceId) {
148
+ this.remoteDeviceId = remoteDeviceId;
149
+ }
150
+ async connect() {
151
+ if (this.disconnectPromise) {
152
+ await this.disconnectPromise;
153
+ }
154
+ // TODO: previously this skipped overlapping connect attempts but that seems awkward
155
+ // can we... just not do that? or wait?
156
+ if (this.remoteDeviceId === undefined) {
157
+ throw new BridgeError(`Missing remote micro:bit ID`);
158
+ }
159
+ this.logging.event({
160
+ type: "Connect",
161
+ message: "Serial connect start",
162
+ });
163
+ this.ignoreDelegateStatus = false;
164
+ await this.delegate.connect();
165
+ try {
166
+ this.serialSession = new RadioBridgeSerialSession(this.logging, this.remoteDeviceId, this.delegate, this.dispatchTypedEvent.bind(this), {
167
+ onConnecting: () => this.setStatus(device_js_1.ConnectionStatus.CONNECTING),
168
+ onReconnecting: () => {
169
+ // Leave serial connection running in case the remote device comes back.
170
+ if (this.status !== device_js_1.ConnectionStatus.RECONNECTING) {
171
+ this.setStatus(device_js_1.ConnectionStatus.RECONNECTING);
172
+ }
173
+ },
174
+ onRestartConnection: () => {
175
+ // So that serial session does not get repetitively disposed in
176
+ // delegate status listener when delegate is disconnected for restarting connection
177
+ this.ignoreDelegateStatus = true;
178
+ },
179
+ onFail: () => {
180
+ if (this.status !== device_js_1.ConnectionStatus.DISCONNECTED) {
181
+ this.setStatus(device_js_1.ConnectionStatus.DISCONNECTED);
182
+ }
183
+ this.ignoreDelegateStatus = false;
184
+ this.serialSessionOpen = false;
185
+ },
186
+ onSuccess: () => {
187
+ if (this.status !== device_js_1.ConnectionStatus.CONNECTED) {
188
+ this.setStatus(device_js_1.ConnectionStatus.CONNECTED);
189
+ }
190
+ this.ignoreDelegateStatus = false;
191
+ this.serialSessionOpen = true;
192
+ },
193
+ });
194
+ await this.serialSession.connect();
195
+ this.logging.event({
196
+ type: "Connect",
197
+ message: "Serial connect success",
198
+ });
199
+ return this.status;
200
+ }
201
+ catch (e) {
202
+ this.serialSessionOpen = false;
203
+ this.logging.error("Failed to initialise serial protocol", e);
204
+ this.logging.event({
205
+ type: "Connect",
206
+ message: "Serial connect failed",
207
+ });
208
+ throw e;
209
+ }
210
+ }
211
+ async disconnect() {
212
+ if (this.disconnectPromise) {
213
+ return this.disconnectPromise;
214
+ }
215
+ this.serialSessionOpen = false;
216
+ this.disconnectPromise = (async () => {
217
+ await this.serialSession?.dispose(true);
218
+ this.disconnectPromise = undefined;
219
+ })();
220
+ }
221
+ log(v) {
222
+ this.logging.log(v);
223
+ }
224
+ setStatus(status) {
225
+ this.status = status;
226
+ this.log("Radio connection status " + status);
227
+ this.dispatchTypedEvent("status", new device_js_1.ConnectionStatusEvent(status));
228
+ }
229
+ statusFromDelegate() {
230
+ return this.delegate.status == device_js_1.ConnectionStatus.CONNECTED
231
+ ? device_js_1.ConnectionStatus.DISCONNECTED
232
+ : this.delegate.status;
233
+ }
234
+ }
235
+ /**
236
+ * Wraps a connected delegate for a single session from attempted serial handshake to error/dispose.
237
+ */
238
+ class RadioBridgeSerialSession {
239
+ processButton(button, type, sensorData) {
240
+ if (sensorData[button] !== this.previousButtonState[button]) {
241
+ this.previousButtonState[button] = sensorData[button];
242
+ this.dispatchTypedEvent(type, new buttons_js_1.ButtonEvent(type, sensorData[button] ? buttons_js_1.ButtonState.ShortPress : buttons_js_1.ButtonState.NotPressed));
243
+ }
244
+ }
245
+ constructor(logging, remoteDeviceId, delegate, dispatchTypedEvent, callbacks) {
246
+ Object.defineProperty(this, "logging", {
247
+ enumerable: true,
248
+ configurable: true,
249
+ writable: true,
250
+ value: logging
251
+ });
252
+ Object.defineProperty(this, "remoteDeviceId", {
253
+ enumerable: true,
254
+ configurable: true,
255
+ writable: true,
256
+ value: remoteDeviceId
257
+ });
258
+ Object.defineProperty(this, "delegate", {
259
+ enumerable: true,
260
+ configurable: true,
261
+ writable: true,
262
+ value: delegate
263
+ });
264
+ Object.defineProperty(this, "dispatchTypedEvent", {
265
+ enumerable: true,
266
+ configurable: true,
267
+ writable: true,
268
+ value: dispatchTypedEvent
269
+ });
270
+ Object.defineProperty(this, "callbacks", {
271
+ enumerable: true,
272
+ configurable: true,
273
+ writable: true,
274
+ value: callbacks
275
+ });
276
+ Object.defineProperty(this, "unprocessedData", {
277
+ enumerable: true,
278
+ configurable: true,
279
+ writable: true,
280
+ value: ""
281
+ });
282
+ Object.defineProperty(this, "previousButtonState", {
283
+ enumerable: true,
284
+ configurable: true,
285
+ writable: true,
286
+ value: { buttonA: 0, buttonB: 0 }
287
+ });
288
+ Object.defineProperty(this, "onPeriodicMessageReceived", {
289
+ enumerable: true,
290
+ configurable: true,
291
+ writable: true,
292
+ value: void 0
293
+ });
294
+ Object.defineProperty(this, "lastReceivedMessageTimestamp", {
295
+ enumerable: true,
296
+ configurable: true,
297
+ writable: true,
298
+ value: void 0
299
+ });
300
+ Object.defineProperty(this, "connectionCheckIntervalId", {
301
+ enumerable: true,
302
+ configurable: true,
303
+ writable: true,
304
+ value: void 0
305
+ });
306
+ Object.defineProperty(this, "isRestartingConnection", {
307
+ enumerable: true,
308
+ configurable: true,
309
+ writable: true,
310
+ value: false
311
+ });
312
+ Object.defineProperty(this, "serialErrorListener", {
313
+ enumerable: true,
314
+ configurable: true,
315
+ writable: true,
316
+ value: (event) => {
317
+ this.logging.error("Serial error", event.error);
318
+ void this.dispose();
319
+ }
320
+ });
321
+ Object.defineProperty(this, "serialDataListener", {
322
+ enumerable: true,
323
+ configurable: true,
324
+ writable: true,
325
+ value: (event) => {
326
+ const { data } = event;
327
+ const messages = protocol.splitMessages(this.unprocessedData + data);
328
+ this.unprocessedData = messages.remainingInput;
329
+ messages.messages.forEach(async (msg) => {
330
+ this.lastReceivedMessageTimestamp = Date.now();
331
+ // Messages are either periodic sensor data or command/response
332
+ const sensorData = protocol.processPeriodicMessage(msg);
333
+ if (sensorData) {
334
+ this.onPeriodicMessageReceived?.();
335
+ this.dispatchTypedEvent("accelerometerdatachanged", new accelerometer_js_1.AccelerometerDataEvent({
336
+ x: sensorData.accelerometerX,
337
+ y: sensorData.accelerometerY,
338
+ z: sensorData.accelerometerZ,
339
+ }));
340
+ this.processButton("buttonA", "buttonachanged", sensorData);
341
+ this.processButton("buttonB", "buttonbchanged", sensorData);
342
+ }
343
+ else {
344
+ const messageResponse = protocol.processResponseMessage(msg);
345
+ if (!messageResponse) {
346
+ return;
347
+ }
348
+ const responseResolve = this.responseMap.get(messageResponse.messageId);
349
+ if (responseResolve) {
350
+ this.responseMap.delete(messageResponse.messageId);
351
+ responseResolve(messageResponse);
352
+ }
353
+ }
354
+ });
355
+ }
356
+ });
357
+ Object.defineProperty(this, "responseMap", {
358
+ enumerable: true,
359
+ configurable: true,
360
+ writable: true,
361
+ value: new Map()
362
+ });
363
+ }
364
+ async connect() {
365
+ this.delegate.addEventListener("serialdata", this.serialDataListener);
366
+ this.delegate.addEventListener("serialerror", this.serialErrorListener);
367
+ try {
368
+ if (this.isRestartingConnection) {
369
+ this.callbacks.onReconnecting();
370
+ }
371
+ else {
372
+ this.callbacks.onConnecting();
373
+ }
374
+ await this.handshake();
375
+ this.logging.log(`Serial: using remote device id ${this.remoteDeviceId}`);
376
+ const remoteMbIdCommand = protocol.generateCmdRemoteMbId(this.remoteDeviceId);
377
+ const remoteMbIdResponse = await this.sendCmdWaitResponse(remoteMbIdCommand);
378
+ if (remoteMbIdResponse.type === protocol.ResponseTypes.Error ||
379
+ remoteMbIdResponse.value !== this.remoteDeviceId) {
380
+ throw new BridgeError(`Failed to set remote micro:bit ID. Expected ${this.remoteDeviceId}, got ${remoteMbIdResponse.value}`);
381
+ }
382
+ // Request the micro:bit to start sending the periodic messages
383
+ const startCmd = protocol.generateCmdStart({
384
+ accelerometer: true,
385
+ buttons: true,
386
+ });
387
+ const periodicMessagePromise = new Promise((resolve, reject) => {
388
+ this.onPeriodicMessageReceived = resolve;
389
+ setTimeout(() => {
390
+ this.onPeriodicMessageReceived = undefined;
391
+ reject(new Error("Failed to receive data from remote micro:bit"));
392
+ }, 500);
393
+ });
394
+ const startCmdResponse = await this.sendCmdWaitResponse(startCmd);
395
+ if (startCmdResponse.type === protocol.ResponseTypes.Error) {
396
+ throw new RemoteError(`Failed to start streaming sensors data. Error response received: ${startCmdResponse.message}`);
397
+ }
398
+ // TODO: in the first-time connection case we used to move the error/disconnect to the background here, why? timing?
399
+ await periodicMessagePromise;
400
+ this.isRestartingConnection = false;
401
+ await this.startConnectionCheck();
402
+ this.callbacks.onSuccess();
403
+ }
404
+ catch (e) {
405
+ this.callbacks.onFail();
406
+ await this.dispose();
407
+ }
408
+ }
409
+ async dispose(disconnect = false) {
410
+ this.stopConnectionCheck();
411
+ try {
412
+ await this.sendCmdWaitResponse(protocol.generateCmdStop());
413
+ }
414
+ catch (e) {
415
+ // If this fails the remote micro:bit has already gone away.
416
+ }
417
+ this.responseMap.clear();
418
+ this.delegate.removeEventListener("serialdata", this.serialDataListener);
419
+ this.delegate.removeEventListener("serialerror", this.serialErrorListener);
420
+ if (disconnect) {
421
+ await this.delegate.disconnect();
422
+ }
423
+ await this.delegate.softwareReset();
424
+ }
425
+ async sendCmdWaitResponse(cmd) {
426
+ const responsePromise = new Promise((resolve, reject) => {
427
+ this.responseMap.set(cmd.messageId, resolve);
428
+ setTimeout(() => {
429
+ this.responseMap.delete(cmd.messageId);
430
+ reject(new Error(`Timeout waiting for response ${cmd.messageId}`));
431
+ }, 1_000);
432
+ });
433
+ await this.delegate.serialWrite(cmd.message);
434
+ return responsePromise;
435
+ }
436
+ async startConnectionCheck() {
437
+ // Check for connection lost
438
+ if (this.connectionCheckIntervalId === undefined) {
439
+ this.connectionCheckIntervalId = setInterval(async () => {
440
+ if (this.lastReceivedMessageTimestamp &&
441
+ Date.now() - this.lastReceivedMessageTimestamp <= 1_000) {
442
+ this.callbacks.onSuccess();
443
+ }
444
+ if (this.lastReceivedMessageTimestamp &&
445
+ Date.now() - this.lastReceivedMessageTimestamp > 1_000) {
446
+ this.logging.event({
447
+ type: "Serial",
448
+ message: "Serial connection lost...attempt to reconnect",
449
+ });
450
+ this.callbacks.onReconnecting();
451
+ }
452
+ if (this.lastReceivedMessageTimestamp &&
453
+ Date.now() - this.lastReceivedMessageTimestamp >
454
+ connectTimeoutDuration) {
455
+ await this.restartConnection();
456
+ }
457
+ }, 1000);
458
+ }
459
+ }
460
+ async restartConnection() {
461
+ this.isRestartingConnection = true;
462
+ this.logging.event({
463
+ type: "Serial",
464
+ message: "Serial connection lost...restart connection",
465
+ });
466
+ this.callbacks.onRestartConnection();
467
+ await this.dispose(true);
468
+ await this.delegate.connect();
469
+ await this.connect();
470
+ }
471
+ stopConnectionCheck() {
472
+ clearInterval(this.connectionCheckIntervalId);
473
+ this.connectionCheckIntervalId = undefined;
474
+ this.lastReceivedMessageTimestamp = undefined;
475
+ }
476
+ async handshake() {
477
+ // There is an issue where we cannot read data out from the micro:bit serial
478
+ // buffer until the buffer has been filled.
479
+ // As a workaround we can spam the micro:bit with handshake messages until
480
+ // enough responses have been queued in the buffer to fill it and the data
481
+ // starts to flow.
482
+ this.logging.log("Serial handshake");
483
+ const handshakeResult = await new Promise(async (resolve, reject) => {
484
+ const attempts = 20;
485
+ let attemptCounter = 0;
486
+ let failureCounter = 0;
487
+ let resolved = false;
488
+ while (attemptCounter < 20 && !resolved) {
489
+ attemptCounter++;
490
+ this.sendCmdWaitResponse(protocol.generateCmdHandshake())
491
+ .then((value) => {
492
+ if (!resolved) {
493
+ resolved = true;
494
+ resolve(value);
495
+ }
496
+ })
497
+ .catch(() => {
498
+ // We expect some to time out, likely well after the handshake is completed.
499
+ if (!resolved) {
500
+ if (++failureCounter === attempts) {
501
+ reject(new BridgeError("Handshake not completed"));
502
+ }
503
+ }
504
+ });
505
+ await new Promise((resolve) => setTimeout(resolve, 100));
506
+ }
507
+ });
508
+ if (handshakeResult.value !== protocol.version) {
509
+ throw new BridgeError(`Handshake failed. Unexpected protocol version ${protocol.version}`);
510
+ }
511
+ }
512
+ }
513
+ //# sourceMappingURL=usb-radio-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usb-radio-bridge.js","sourceRoot":"","sources":["../../lib/usb-radio-bridge.ts"],"names":[],"mappings":"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"}