@microbit/microbit-connection 0.0.0-alpha.3 → 0.0.0-alpha.30

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 (64) hide show
  1. package/build/accelerometer-service.d.ts +8 -9
  2. package/build/accelerometer-service.js +24 -43
  3. package/build/accelerometer-service.js.map +1 -1
  4. package/build/bluetooth-device-wrapper.d.ts +27 -26
  5. package/build/bluetooth-device-wrapper.js +137 -89
  6. package/build/bluetooth-device-wrapper.js.map +1 -1
  7. package/build/bluetooth.d.ts +14 -11
  8. package/build/bluetooth.js +70 -91
  9. package/build/bluetooth.js.map +1 -1
  10. package/build/board-id.d.ts +1 -0
  11. package/build/board-id.js +8 -0
  12. package/build/board-id.js.map +1 -1
  13. package/build/button-service.d.ts +13 -0
  14. package/build/button-service.js +76 -0
  15. package/build/button-service.js.map +1 -0
  16. package/build/buttons.d.ts +10 -0
  17. package/build/buttons.js +18 -0
  18. package/build/buttons.js.map +1 -0
  19. package/build/constants.d.ts +1 -0
  20. package/build/constants.js +1 -0
  21. package/build/constants.js.map +1 -1
  22. package/build/device.d.ts +30 -39
  23. package/build/device.js +12 -3
  24. package/build/device.js.map +1 -1
  25. package/build/events.d.ts +11 -1
  26. package/build/events.js +86 -1
  27. package/build/events.js.map +1 -1
  28. package/build/hex-flash-data-source.d.ts +6 -8
  29. package/build/hex-flash-data-source.js +16 -45
  30. package/build/hex-flash-data-source.js.map +1 -1
  31. package/build/index.d.ts +10 -5
  32. package/build/index.js +7 -4
  33. package/build/index.js.map +1 -1
  34. package/build/led-service.d.ts +20 -0
  35. package/build/led-service.js +116 -0
  36. package/build/led-service.js.map +1 -0
  37. package/build/led.d.ts +6 -0
  38. package/build/led.js +2 -0
  39. package/build/led.js.map +1 -0
  40. package/build/logging.js +3 -1
  41. package/build/logging.js.map +1 -1
  42. package/build/promise-queue.d.ts +27 -0
  43. package/build/promise-queue.js +74 -0
  44. package/build/promise-queue.js.map +1 -0
  45. package/build/service-events.d.ts +3 -0
  46. package/build/service-events.js +12 -0
  47. package/build/service-events.js.map +1 -1
  48. package/build/usb-device-wrapper.d.ts +7 -1
  49. package/build/usb-device-wrapper.js +40 -3
  50. package/build/usb-device-wrapper.js.map +1 -1
  51. package/build/usb-partial-flashing.d.ts +11 -5
  52. package/build/usb-partial-flashing.js +53 -10
  53. package/build/usb-partial-flashing.js.map +1 -1
  54. package/build/usb-radio-bridge.d.ts +31 -18
  55. package/build/usb-radio-bridge.js +351 -187
  56. package/build/usb-radio-bridge.js.map +1 -1
  57. package/build/usb.d.ts +14 -17
  58. package/build/usb.js +111 -47
  59. package/build/usb.js.map +1 -1
  60. package/package.json +5 -3
  61. package/vite.config.ts +9 -7
  62. package/build/bluetooth-utils.d.ts +0 -5
  63. package/build/bluetooth-utils.js +0 -14
  64. package/build/bluetooth-utils.js.map +0 -1
package/build/device.d.ts CHANGED
@@ -4,7 +4,6 @@
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
6
  import { TypedEventTarget } from "./events.js";
7
- import { BoardId } from "./board-id.js";
8
7
  /**
9
8
  * Specific identified error types.
10
9
  *
@@ -67,7 +66,7 @@ export declare enum ConnectionStatus {
67
66
  * Determining whether the connection type is supported requires
68
67
  * initialize() to complete.
69
68
  */
70
- SUPPORT_NOT_KNOWN = 0,
69
+ SUPPORT_NOT_KNOWN = "SUPPORT_NOT_KNOWN",
71
70
  /**
72
71
  * Not supported.
73
72
  */
@@ -78,41 +77,46 @@ export declare enum ConnectionStatus {
78
77
  * This will be the case even when a device is physically connected
79
78
  * but has not been connected via the browser security UI.
80
79
  */
81
- NO_AUTHORIZED_DEVICE = "NO_DEVICE",
80
+ NO_AUTHORIZED_DEVICE = "NO_AUTHORIZED_DEVICE",
82
81
  /**
83
82
  * Authorized device available but we haven't connected to it.
84
83
  */
85
- NOT_CONNECTED = "NOT_CONNECTED",
84
+ DISCONNECTED = "DISCONNECTED",
86
85
  /**
87
86
  * Connected.
88
87
  */
89
- CONNECTED = "CONNECTED"
90
- }
91
- export declare class FlashDataError extends Error {
88
+ CONNECTED = "CONNECTED",
89
+ /**
90
+ * Connecting.
91
+ */
92
+ CONNECTING = "CONNECTING",
93
+ /**
94
+ * Reconnecting. When there is unexpected disruption in the connection,
95
+ * a reconnection is attempted.
96
+ */
97
+ RECONNECTING = "RECONNECTING"
92
98
  }
93
- export interface FlashDataSource {
99
+ export interface FlashOptions {
94
100
  /**
95
- * For now we only support partially flashing contiguous data.
96
- * This can be generated from microbit-fs directly (via getIntelHexBytes())
97
- * or from an existing Intel Hex via slicePad.
98
- *
99
- * This interface is quite confusing and worth revisiting.
101
+ * True to use a partial flash where possible, false to force a full flash.
102
+ */
103
+ partial: boolean;
104
+ /**
105
+ * A progress callback. Called with undefined when the process is complete or has failed.
100
106
  *
101
- * @param boardId the id of the board.
102
- * @throws FlashDataError if we cannot generate hex data.
107
+ * Requesting a partial flash doesn't guarantee one is performed. Partial flashes are avoided
108
+ * if too many blocks have changed and failed partial flashes are retried as full flashes.
109
+ * The partial parameter reports the flash type currently in progress.
103
110
  */
104
- partialFlashData(boardId: BoardId): Promise<Uint8Array>;
111
+ progress: (percentage: number | undefined, partial: boolean) => void;
105
112
  /**
106
- * @param boardId the id of the board.
107
- * @returns A board-specific (non-universal) Intel Hex file for the given board id.
108
- * @throws FlashDataError if we cannot generate hex data.
113
+ * Smallest possible progress increment to limit callback rate.
109
114
  */
110
- fullFlashData(boardId: BoardId): Promise<string>;
115
+ minimumProgressIncrement?: number;
111
116
  }
112
- export interface ConnectOptions {
113
- serial?: boolean;
114
- name?: string;
117
+ export declare class FlashDataError extends Error {
115
118
  }
119
+ export type FlashDataSource = (boardVersion: BoardVersion) => Promise<string | Uint8Array>;
116
120
  export type BoardVersion = "V1" | "V2";
117
121
  export declare class ConnectionStatusEvent extends Event {
118
122
  readonly status: ConnectionStatus;
@@ -146,7 +150,7 @@ export declare class DeviceConnectionEventMap {
146
150
  "status": ConnectionStatusEvent;
147
151
  "serialdata": SerialDataEvent;
148
152
  "serialreset": Event;
149
- "serialerror": Event;
153
+ "serialerror": SerialErrorEvent;
150
154
  "flash": Event;
151
155
  "beforerequestdevice": Event;
152
156
  "afterrequestdevice": Event;
@@ -168,7 +172,7 @@ export interface DeviceConnection extends TypedEventTarget<DeviceConnectionEvent
168
172
  *
169
173
  * @returns the final connection status.
170
174
  */
171
- connect(options?: ConnectOptions): Promise<ConnectionStatus>;
175
+ connect(): Promise<ConnectionStatus>;
172
176
  /**
173
177
  * Get the board version.
174
178
  *
@@ -181,20 +185,7 @@ export interface DeviceConnection extends TypedEventTarget<DeviceConnectionEvent
181
185
  * @param dataSource The data to use.
182
186
  * @param options Flash options and progress callback.
183
187
  */
184
- flash?(dataSource: FlashDataSource, options: {
185
- /**
186
- * True to use a partial flash where possible, false to force a full flash.
187
- */
188
- partial: boolean;
189
- /**
190
- * A progress callback. Called with undefined when the process is complete or has failed.
191
- *
192
- * Requesting a partial flash doesn't guarantee one is performed. Partial flashes are avoided
193
- * if too many blocks have changed and failed partial flashes are retried as full flashes.
194
- * The partial parameter reports the flash type currently in progress.
195
- */
196
- progress: (percentage: number | undefined, partial: boolean) => void;
197
- }): Promise<void>;
188
+ flash?(dataSource: FlashDataSource, options: {}): Promise<void>;
198
189
  /**
199
190
  * Disconnect from the device.
200
191
  */
package/build/device.js CHANGED
@@ -28,7 +28,7 @@ export var ConnectionStatus;
28
28
  * Determining whether the connection type is supported requires
29
29
  * initialize() to complete.
30
30
  */
31
- ConnectionStatus[ConnectionStatus["SUPPORT_NOT_KNOWN"] = 0] = "SUPPORT_NOT_KNOWN";
31
+ ConnectionStatus["SUPPORT_NOT_KNOWN"] = "SUPPORT_NOT_KNOWN";
32
32
  /**
33
33
  * Not supported.
34
34
  */
@@ -39,15 +39,24 @@ export var ConnectionStatus;
39
39
  * This will be the case even when a device is physically connected
40
40
  * but has not been connected via the browser security UI.
41
41
  */
42
- ConnectionStatus["NO_AUTHORIZED_DEVICE"] = "NO_DEVICE";
42
+ ConnectionStatus["NO_AUTHORIZED_DEVICE"] = "NO_AUTHORIZED_DEVICE";
43
43
  /**
44
44
  * Authorized device available but we haven't connected to it.
45
45
  */
46
- ConnectionStatus["NOT_CONNECTED"] = "NOT_CONNECTED";
46
+ ConnectionStatus["DISCONNECTED"] = "DISCONNECTED";
47
47
  /**
48
48
  * Connected.
49
49
  */
50
50
  ConnectionStatus["CONNECTED"] = "CONNECTED";
51
+ /**
52
+ * Connecting.
53
+ */
54
+ ConnectionStatus["CONNECTING"] = "CONNECTING";
55
+ /**
56
+ * Reconnecting. When there is unexpected disruption in the connection,
57
+ * a reconnection is attempted.
58
+ */
59
+ ConnectionStatus["RECONNECTING"] = "RECONNECTING";
51
60
  })(ConnectionStatus || (ConnectionStatus = {}));
52
61
  export class FlashDataError extends Error {
53
62
  }
@@ -1 +1 @@
1
- {"version":3,"file":"device.js","sourceRoot":"","sources":["../lib/device.ts"],"names":[],"mappings":"AA+CA;;;;;;;;GAQG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAEpC,YAAY,EAAE,IAAI,EAAE,OAAO,EAA+C;QACxE,KAAK,CAAC,OAAO,CAAC,CAAC;QAFjB;;;;;WAAsB;QAGpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,gBAyBX;AAzBD,WAAY,gBAAgB;IAC1B;;;OAGG;IACH,iFAAiB,CAAA;IACjB;;OAEG;IACH,mDAA+B,CAAA;IAC/B;;;;;OAKG;IACH,sDAAkC,CAAA;IAClC;;OAEG;IACH,mDAA+B,CAAA;IAC/B;;OAEG;IACH,2CAAuB,CAAA;AACzB,CAAC,EAzBW,gBAAgB,KAAhB,gBAAgB,QAyB3B;AAED,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AA+B5C,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C,YAA4B,MAAwB;QAClD,KAAK,CAAC,QAAQ,CAAC,CAAC;QADN;;;;mBAAgB,MAAM;WAAkB;IAEpD,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAA4B,IAAY;QACtC,KAAK,CAAC,YAAY,CAAC,CAAC;QADV;;;;mBAAgB,IAAI;WAAQ;IAExC,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC;QACE,KAAK,CAAC,aAAa,CAAC,CAAC;IACvB,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YAA4B,KAAc;QACxC,KAAK,CAAC,aAAa,CAAC,CAAC;QADX;;;;mBAAgB,KAAK;WAAS;IAE1C,CAAC;CACF;AAED,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC;QACE,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C;QACE,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C;QACE,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAA4B,YAAoB;QAC9C,KAAK,CAAC,iBAAiB,CAAC,CAAC;QADf;;;;mBAAgB,YAAY;WAAQ;IAEhD,CAAC;CACF;AAED,MAAM,OAAO,wBAAwB;IAArC;QACE,4BAAA,QAAQ;;;;;WAAwB;QAChC,4BAAA,YAAY;;;;;WAAkB;QAC9B,4BAAA,aAAa;;;;;WAAQ;QACrB,4BAAA,aAAa;;;;;WAAQ;QACrB,4BAAA,OAAO;;;;;WAAQ;QACf,4BAAA,qBAAqB;;;;;WAAQ;QAC7B,4BAAA,oBAAoB;;;;;WAAQ;QAC5B,4BAAA,iBAAiB;;;;;WAAuB;IAC1C,CAAC;CAAA"}
1
+ {"version":3,"file":"device.js","sourceRoot":"","sources":["../lib/device.ts"],"names":[],"mappings":"AA8CA;;;;;;;;GAQG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAEpC,YAAY,EAAE,IAAI,EAAE,OAAO,EAA+C;QACxE,KAAK,CAAC,OAAO,CAAC,CAAC;QAFjB;;;;;WAAsB;QAGpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,gBAkCX;AAlCD,WAAY,gBAAgB;IAC1B;;;OAGG;IACH,2DAAuC,CAAA;IACvC;;OAEG;IACH,mDAA+B,CAAA;IAC/B;;;;;OAKG;IACH,iEAA6C,CAAA;IAC7C;;OAEG;IACH,iDAA6B,CAAA;IAC7B;;OAEG;IACH,2CAAuB,CAAA;IACvB;;OAEG;IACH,6CAAyB,CAAA;IACzB;;;OAGG;IACH,iDAA6B,CAAA;AAC/B,CAAC,EAlCW,gBAAgB,KAAhB,gBAAgB,QAkC3B;AAqBD,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AAQ5C,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C,YAA4B,MAAwB;QAClD,KAAK,CAAC,QAAQ,CAAC,CAAC;QADN;;;;mBAAgB,MAAM;WAAkB;IAEpD,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAA4B,IAAY;QACtC,KAAK,CAAC,YAAY,CAAC,CAAC;QADV;;;;mBAAgB,IAAI;WAAQ;IAExC,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC;QACE,KAAK,CAAC,aAAa,CAAC,CAAC;IACvB,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YAA4B,KAAc;QACxC,KAAK,CAAC,aAAa,CAAC,CAAC;QADX;;;;mBAAgB,KAAK;WAAS;IAE1C,CAAC;CACF;AAED,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC;QACE,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C;QACE,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C;QACE,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAA4B,YAAoB;QAC9C,KAAK,CAAC,iBAAiB,CAAC,CAAC;QADf;;;;mBAAgB,YAAY;WAAQ;IAEhD,CAAC;CACF;AAED,MAAM,OAAO,wBAAwB;IAArC;QACE,4BAAA,QAAQ;;;;;WAAwB;QAChC,4BAAA,YAAY;;;;;WAAkB;QAC9B,4BAAA,aAAa;;;;;WAAQ;QACrB,4BAAA,aAAa;;;;;WAAmB;QAChC,4BAAA,OAAO;;;;;WAAQ;QACf,4BAAA,qBAAqB;;;;;WAAQ;QAC7B,4BAAA,oBAAoB;;;;;WAAQ;QAC5B,4BAAA,iBAAiB;;;;;WAAuB;IAC1C,CAAC;CAAA"}
package/build/events.d.ts CHANGED
@@ -90,7 +90,17 @@ export interface TypedEventTarget<M extends ValueIsEvent<M>> {
90
90
  */
91
91
  dispatchEvent: (event: Event) => boolean;
92
92
  }
93
- export declare class TypedEventTarget<M extends ValueIsEvent<M>> extends EventTarget {
93
+ export declare class TrackingEventTarget extends EventTarget {
94
+ private activeEventTracking;
95
+ addEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void;
96
+ removeEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;
97
+ dispatchEvent(event: Event): boolean;
98
+ private filterRegistrations;
99
+ protected eventActivated(type: string): void;
100
+ protected eventDeactivated(type: string): void;
101
+ protected getActiveEvents(): string[];
102
+ }
103
+ export declare class TypedEventTarget<M extends ValueIsEvent<M>> extends TrackingEventTarget {
94
104
  /**
95
105
  * Dispatches a synthetic event event to target and returns true if either
96
106
  * event's cancelable attribute value is false or its preventDefault() method
package/build/events.js CHANGED
@@ -5,8 +5,65 @@
5
5
  *
6
6
  * https://github.com/DerZade/typescript-event-target/blob/master/src/TypedEventTarget.ts
7
7
  */
8
+ // We've added this in to keep track of what events are active.
9
+ // Having done this it's questionable whether it's worth the reimplementation
10
+ // just to use an EventTarget API.
11
+ export class TrackingEventTarget extends EventTarget {
12
+ constructor() {
13
+ super(...arguments);
14
+ Object.defineProperty(this, "activeEventTracking", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: new Map()
19
+ });
20
+ }
21
+ addEventListener(type, callback, options) {
22
+ if (callback !== null) {
23
+ const registrations = this.activeEventTracking.get(type) ?? [];
24
+ const wasEmpty = registrations.length === 0;
25
+ const registration = new Registration(callback, options ?? false);
26
+ if (!registrations.find((r) => r.eq(registration))) {
27
+ registrations.push(registration);
28
+ this.activeEventTracking.set(type, registrations);
29
+ if (wasEmpty) {
30
+ this.eventActivated(type);
31
+ }
32
+ }
33
+ }
34
+ super.addEventListener(type, callback, options);
35
+ }
36
+ removeEventListener(type, callback, options) {
37
+ if (callback !== null) {
38
+ const registration = new Registration(callback, options ?? false);
39
+ this.filterRegistrations(type, (r) => !r.eq(registration));
40
+ }
41
+ super.removeEventListener(type, callback, options);
42
+ }
43
+ dispatchEvent(event) {
44
+ const result = super.dispatchEvent(event);
45
+ this.filterRegistrations(event.type, (r) => !r.isOnce());
46
+ return result;
47
+ }
48
+ filterRegistrations(type, predicate) {
49
+ let registrations = this.activeEventTracking.get(type) ?? [];
50
+ registrations = registrations.filter(predicate);
51
+ if (registrations.length === 0) {
52
+ this.activeEventTracking.delete(type);
53
+ this.eventDeactivated(type);
54
+ }
55
+ else {
56
+ this.activeEventTracking.set(type, registrations);
57
+ }
58
+ }
59
+ eventActivated(type) { }
60
+ eventDeactivated(type) { }
61
+ getActiveEvents() {
62
+ return [...this.activeEventTracking.keys()];
63
+ }
64
+ }
8
65
  // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
9
- export class TypedEventTarget extends EventTarget {
66
+ export class TypedEventTarget extends TrackingEventTarget {
10
67
  /**
11
68
  * Dispatches a synthetic event event to target and returns true if either
12
69
  * event's cancelable attribute value is false or its preventDefault() method
@@ -16,4 +73,32 @@ export class TypedEventTarget extends EventTarget {
16
73
  return super.dispatchEvent(event);
17
74
  }
18
75
  }
76
+ class Registration {
77
+ constructor(callback, options) {
78
+ Object.defineProperty(this, "callback", {
79
+ enumerable: true,
80
+ configurable: true,
81
+ writable: true,
82
+ value: callback
83
+ });
84
+ Object.defineProperty(this, "options", {
85
+ enumerable: true,
86
+ configurable: true,
87
+ writable: true,
88
+ value: options
89
+ });
90
+ }
91
+ isOnce() {
92
+ return typeof this.options === "object" && this.options.once === true;
93
+ }
94
+ eq(other) {
95
+ return (other.callback === this.callback &&
96
+ eqUseCapture(this.options, other.options));
97
+ }
98
+ }
99
+ const eqUseCapture = (left, right) => {
100
+ const leftValue = typeof left === "boolean" ? left : left.capture ?? false;
101
+ const rightValue = typeof right === "boolean" ? right : right.capture ?? false;
102
+ return leftValue === rightValue;
103
+ };
19
104
  //# sourceMappingURL=events.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../lib/events.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAyGH,4EAA4E;AAC5E,MAAM,OAAO,gBAA4C,SAAQ,WAAW;IAC1E;;;;OAIG;IACI,kBAAkB,CAAoB,KAAQ,EAAE,KAAW;QAChE,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;CACF"}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../lib/events.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,7 @@
1
- import { BoardId } from "./board-id.js";
2
1
  import { FlashDataSource } from "./device.js";
3
- export declare class HexFlashDataSource implements FlashDataSource {
4
- private hex;
5
- constructor(hex: string);
6
- partialFlashData(boardId: BoardId): Promise<Uint8Array>;
7
- fullFlashData(boardId: BoardId): Promise<string>;
8
- private matchingPart;
9
- }
2
+ /**
3
+ * A flash data source that converts universal hex files as needed.
4
+ *
5
+ * @param universalHex A hex file, potentially universal.
6
+ */
7
+ export declare const createUniversalHexFlashDataSource: (universalHex: string) => FlashDataSource;
@@ -1,51 +1,22 @@
1
- import MemoryMap from "nrf-intel-hex";
2
- import { FlashDataError as FlashDataError } from "./device.js";
1
+ import { BoardId } from "./board-id.js";
2
+ import { FlashDataError as FlashDataError, } from "./device.js";
3
3
  import { isUniversalHex, separateUniversalHex, } from "@microbit/microbit-universal-hex";
4
- export class HexFlashDataSource {
5
- constructor(hex) {
6
- Object.defineProperty(this, "hex", {
7
- enumerable: true,
8
- configurable: true,
9
- writable: true,
10
- value: hex
11
- });
12
- }
13
- partialFlashData(boardId) {
14
- // Perhaps this would make more sense if we returned a MemoryMap?
15
- // Then the partial flashing code could be given everything including UICR without
16
- // passing a very large Uint8Array.
17
- // Or use MM inside PF and return a (partial) hex string in the microbit-fs case?
18
- const part = this.matchingPart(boardId);
19
- // Cludge for a packaging issue
20
- const fromHex = MemoryMap.fromHex ?? MemoryMap.default.fromHex;
21
- const hex = fromHex(part);
22
- const keys = Array.from(hex.keys()).filter((k) => k < 0x10000000);
23
- const lastKey = keys[keys.length - 1];
24
- if (lastKey === undefined) {
25
- throw new FlashDataError("Empty hex");
26
- }
27
- const lastPart = hex.get(lastKey);
28
- if (!lastPart) {
29
- throw new FlashDataError("Empty hex");
30
- }
31
- const length = lastKey + lastPart.length;
32
- const data = hex.slicePad(0, length, 0);
33
- return Promise.resolve(data);
34
- }
35
- fullFlashData(boardId) {
36
- const part = this.matchingPart(boardId);
37
- return Promise.resolve(part);
38
- }
39
- matchingPart(boardId) {
40
- if (isUniversalHex(this.hex)) {
41
- const parts = separateUniversalHex(this.hex);
42
- const matching = parts.find((p) => p.boardId == boardId.normalize().id);
4
+ /**
5
+ * A flash data source that converts universal hex files as needed.
6
+ *
7
+ * @param universalHex A hex file, potentially universal.
8
+ */
9
+ export const createUniversalHexFlashDataSource = (universalHex) => {
10
+ return (boardVersion) => {
11
+ if (isUniversalHex(universalHex)) {
12
+ const parts = separateUniversalHex(universalHex);
13
+ const matching = parts.find((p) => p.boardId == BoardId.forVersion(boardVersion).id);
43
14
  if (!matching) {
44
15
  throw new FlashDataError("No matching part");
45
16
  }
46
- return matching.hex;
17
+ return Promise.resolve(matching.hex);
47
18
  }
48
- return this.hex;
49
- }
50
- }
19
+ return Promise.resolve(universalHex);
20
+ };
21
+ };
51
22
  //# sourceMappingURL=hex-flash-data-source.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hex-flash-data-source.js","sourceRoot":"","sources":["../lib/hex-flash-data-source.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,eAAe,CAAC;AAEtC,OAAO,EAAmB,cAAc,IAAI,cAAc,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EACL,cAAc,EACd,oBAAoB,GACrB,MAAM,kCAAkC,CAAC;AAE1C,MAAM,OAAO,kBAAkB;IAC7B,YAAoB,GAAW;QAAnB;;;;mBAAQ,GAAG;WAAQ;IAAG,CAAC;IAEnC,gBAAgB,CAAC,OAAgB;QAC/B,iEAAiE;QACjE,kFAAkF;QAClF,mCAAmC;QAEnC,iFAAiF;QAEjF,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAExC,+BAA+B;QAC/B,MAAM,OAAO,GAIV,SAAiB,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC;QAE1D,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACtC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,IAAI,cAAc,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC;QACD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,cAAc,CAAC,WAAW,CAAC,CAAC;QACxC,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC;QACzC,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACxC,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,aAAa,CAAC,OAAgB;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAEO,YAAY,CAAC,OAAgB;QACnC,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7C,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;YACxE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,cAAc,CAAC,kBAAkB,CAAC,CAAC;YAC/C,CAAC;YACD,OAAO,QAAQ,CAAC,GAAG,CAAC;QACtB,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;CACF"}
1
+ {"version":3,"file":"hex-flash-data-source.js","sourceRoot":"","sources":["../lib/hex-flash-data-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EACL,cAAc,IAAI,cAAc,GAGjC,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,cAAc,EACd,oBAAoB,GACrB,MAAM,kCAAkC,CAAC;AAE1C;;;;GAIG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAC/C,YAAoB,EACH,EAAE;IACnB,OAAO,CAAC,YAA0B,EAAE,EAAE;QACpC,IAAI,cAAc,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;YACjD,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CACzB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,CACxD,CAAC;YACF,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,cAAc,CAAC,kBAAkB,CAAC,CAAC;YAC/C,CAAC;YACD,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACvC,CAAC,CAAC;AACJ,CAAC,CAAC"}
package/build/index.d.ts CHANGED
@@ -1,7 +1,12 @@
1
- import { MicrobitWebUSBConnection } from "./usb.js";
1
+ import { AccelerometerData, AccelerometerDataEvent } from "./accelerometer.js";
2
2
  import { MicrobitWebBluetoothConnection } from "./bluetooth.js";
3
3
  import { BoardId } from "./board-id.js";
4
- import { DeviceConnection, AfterRequestDevice, BeforeRequestDevice, BoardVersion, ConnectOptions, ConnectionStatus, ConnectionStatusEvent, DeviceError, DeviceErrorCode, DeviceConnectionEventMap, FlashDataError, FlashDataSource, FlashEvent, SerialDataEvent, SerialErrorEvent, SerialResetEvent } from "./device.js";
5
- import { HexFlashDataSource } from "./hex-flash-data-source.js";
6
- export { MicrobitWebUSBConnection, MicrobitWebBluetoothConnection, BoardId, HexFlashDataSource, AfterRequestDevice, BeforeRequestDevice, ConnectionStatus, ConnectionStatusEvent, DeviceConnectionEventMap, DeviceError, FlashDataError, FlashEvent, SerialDataEvent, SerialErrorEvent, SerialResetEvent, };
7
- export type { DeviceConnection, BoardVersion, ConnectOptions, DeviceErrorCode, FlashDataSource, };
4
+ import { ButtonEvent, ButtonEventType, ButtonState } from "./buttons.js";
5
+ import { AfterRequestDevice, BeforeRequestDevice, BoardVersion, ConnectionStatus, ConnectionStatusEvent, DeviceConnection, DeviceConnectionEventMap, DeviceError, DeviceErrorCode, FlashDataError, FlashDataSource, FlashEvent, SerialDataEvent, SerialErrorEvent, SerialResetEvent } from "./device.js";
6
+ import { TypedEventTarget } from "./events.js";
7
+ import { createUniversalHexFlashDataSource } from "./hex-flash-data-source.js";
8
+ import { ServiceConnectionEventMap } from "./service-events.js";
9
+ import { MicrobitRadioBridgeConnection } from "./usb-radio-bridge.js";
10
+ import { MicrobitWebUSBConnection } from "./usb.js";
11
+ export { AfterRequestDevice, BeforeRequestDevice, BoardId, ConnectionStatus, ConnectionStatusEvent, createUniversalHexFlashDataSource, DeviceConnectionEventMap, DeviceError, FlashDataError, FlashEvent, MicrobitRadioBridgeConnection, MicrobitWebBluetoothConnection, MicrobitWebUSBConnection, SerialDataEvent, SerialErrorEvent, SerialResetEvent, ServiceConnectionEventMap, TypedEventTarget, };
12
+ export type { AccelerometerData, AccelerometerDataEvent, BoardVersion, ButtonEvent, ButtonEventType, ButtonState, DeviceConnection, DeviceErrorCode, FlashDataSource, };
package/build/index.js CHANGED
@@ -1,7 +1,10 @@
1
- import { MicrobitWebUSBConnection } from "./usb.js";
2
1
  import { MicrobitWebBluetoothConnection } from "./bluetooth.js";
3
2
  import { BoardId } from "./board-id.js";
4
- import { AfterRequestDevice, BeforeRequestDevice, ConnectionStatus, ConnectionStatusEvent, DeviceError, DeviceConnectionEventMap, FlashDataError, FlashEvent, SerialDataEvent, SerialErrorEvent, SerialResetEvent, } from "./device.js";
5
- import { HexFlashDataSource } from "./hex-flash-data-source.js";
6
- export { MicrobitWebUSBConnection, MicrobitWebBluetoothConnection, BoardId, HexFlashDataSource, AfterRequestDevice, BeforeRequestDevice, ConnectionStatus, ConnectionStatusEvent, DeviceConnectionEventMap, DeviceError, FlashDataError, FlashEvent, SerialDataEvent, SerialErrorEvent, SerialResetEvent, };
3
+ import { AfterRequestDevice, BeforeRequestDevice, ConnectionStatus, ConnectionStatusEvent, DeviceConnectionEventMap, DeviceError, FlashDataError, FlashEvent, SerialDataEvent, SerialErrorEvent, SerialResetEvent, } from "./device.js";
4
+ import { TypedEventTarget } from "./events.js";
5
+ import { createUniversalHexFlashDataSource } from "./hex-flash-data-source.js";
6
+ import { ServiceConnectionEventMap } from "./service-events.js";
7
+ import { MicrobitRadioBridgeConnection } from "./usb-radio-bridge.js";
8
+ import { MicrobitWebUSBConnection } from "./usb.js";
9
+ export { AfterRequestDevice, BeforeRequestDevice, BoardId, ConnectionStatus, ConnectionStatusEvent, createUniversalHexFlashDataSource, DeviceConnectionEventMap, DeviceError, FlashDataError, FlashEvent, MicrobitRadioBridgeConnection, MicrobitWebBluetoothConnection, MicrobitWebUSBConnection, SerialDataEvent, SerialErrorEvent, SerialResetEvent, ServiceConnectionEventMap, TypedEventTarget, };
7
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAEL,kBAAkB,EAClB,mBAAmB,EAGnB,gBAAgB,EAChB,qBAAqB,EACrB,WAAW,EAEX,wBAAwB,EACxB,cAAc,EAEd,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EACL,wBAAwB,EACxB,8BAA8B,EAC9B,OAAO,EACP,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,WAAW,EACX,cAAc,EACd,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,gBAAgB,GACjB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EAEnB,gBAAgB,EAChB,qBAAqB,EAErB,wBAAwB,EACxB,WAAW,EAEX,cAAc,EAEd,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAEpD,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,OAAO,EACP,gBAAgB,EAChB,qBAAqB,EACrB,iCAAiC,EACjC,wBAAwB,EACxB,WAAW,EACX,cAAc,EACd,UAAU,EACV,6BAA6B,EAC7B,8BAA8B,EAC9B,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,gBAAgB,GACjB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { Service } from "./bluetooth-device-wrapper.js";
2
+ import { LedMatrix } from "./led.js";
3
+ import { TypedServiceEvent, TypedServiceEventDispatcher } from "./service-events.js";
4
+ export declare class LedService implements Service {
5
+ private matrixStateCharacteristic;
6
+ private scrollingDelayCharacteristic;
7
+ private textCharactertistic;
8
+ private queueGattOperation;
9
+ constructor(matrixStateCharacteristic: BluetoothRemoteGATTCharacteristic, scrollingDelayCharacteristic: BluetoothRemoteGATTCharacteristic, textCharactertistic: BluetoothRemoteGATTCharacteristic, queueGattOperation: <R>(action: () => Promise<R>) => Promise<R>);
10
+ static createService(gattServer: BluetoothRemoteGATTServer, dispatcher: TypedServiceEventDispatcher, queueGattOperation: <R>(action: () => Promise<R>) => Promise<R>, listenerInit: boolean): Promise<LedService | undefined>;
11
+ getLedMatrix(): Promise<LedMatrix>;
12
+ setLedMatrix(value: LedMatrix): Promise<void>;
13
+ private dataViewToLedMatrix;
14
+ private ledMatrixToDataView;
15
+ setText(text: string): Promise<void>;
16
+ setScrollingDelay(value: number): Promise<void>;
17
+ getScrollingDelay(): Promise<number>;
18
+ startNotifications(type: TypedServiceEvent): Promise<void>;
19
+ stopNotifications(type: TypedServiceEvent): Promise<void>;
20
+ }
@@ -0,0 +1,116 @@
1
+ import { profile } from "./bluetooth-profile.js";
2
+ import { BackgroundErrorEvent, DeviceError } from "./device.js";
3
+ const createLedMatrix = () => {
4
+ return [
5
+ [false, false, false, false, false],
6
+ [false, false, false, false, false],
7
+ [false, false, false, false, false],
8
+ [false, false, false, false, false],
9
+ [false, false, false, false, false],
10
+ ];
11
+ };
12
+ export class LedService {
13
+ constructor(matrixStateCharacteristic, scrollingDelayCharacteristic, textCharactertistic, queueGattOperation) {
14
+ Object.defineProperty(this, "matrixStateCharacteristic", {
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true,
18
+ value: matrixStateCharacteristic
19
+ });
20
+ Object.defineProperty(this, "scrollingDelayCharacteristic", {
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true,
24
+ value: scrollingDelayCharacteristic
25
+ });
26
+ Object.defineProperty(this, "textCharactertistic", {
27
+ enumerable: true,
28
+ configurable: true,
29
+ writable: true,
30
+ value: textCharactertistic
31
+ });
32
+ Object.defineProperty(this, "queueGattOperation", {
33
+ enumerable: true,
34
+ configurable: true,
35
+ writable: true,
36
+ value: queueGattOperation
37
+ });
38
+ }
39
+ static async createService(gattServer, dispatcher, queueGattOperation, listenerInit) {
40
+ let ledService;
41
+ try {
42
+ ledService = await gattServer.getPrimaryService(profile.led.id);
43
+ }
44
+ catch (err) {
45
+ if (listenerInit) {
46
+ dispatcher("backgrounderror", new BackgroundErrorEvent(err));
47
+ return;
48
+ }
49
+ else {
50
+ throw new DeviceError({
51
+ code: "service-missing",
52
+ message: err,
53
+ });
54
+ }
55
+ }
56
+ const matrixStateCharacteristic = await ledService.getCharacteristic(profile.led.characteristics.matrixState.id);
57
+ const scrollingDelayCharacteristic = await ledService.getCharacteristic(profile.led.characteristics.scrollingDelay.id);
58
+ const textCharacteristic = await ledService.getCharacteristic(profile.led.characteristics.text.id);
59
+ return new LedService(matrixStateCharacteristic, scrollingDelayCharacteristic, textCharacteristic, queueGattOperation);
60
+ }
61
+ async getLedMatrix() {
62
+ const dataView = await this.queueGattOperation(() => this.matrixStateCharacteristic.readValue());
63
+ return this.dataViewToLedMatrix(dataView);
64
+ }
65
+ async setLedMatrix(value) {
66
+ const dataView = this.ledMatrixToDataView(value);
67
+ return this.queueGattOperation(() => this.matrixStateCharacteristic.writeValue(dataView));
68
+ }
69
+ dataViewToLedMatrix(dataView) {
70
+ if (dataView.byteLength !== 5) {
71
+ throw new Error("Unexpected LED matrix byte length");
72
+ }
73
+ const matrix = createLedMatrix();
74
+ for (let row = 0; row < 5; ++row) {
75
+ const rowByte = dataView.getUint8(row);
76
+ for (let column = 0; column < 5; ++column) {
77
+ const columnMask = 0x1 << (4 - column);
78
+ matrix[row][column] = (rowByte & columnMask) != 0;
79
+ }
80
+ }
81
+ return matrix;
82
+ }
83
+ ledMatrixToDataView(matrix) {
84
+ const dataView = new DataView(new ArrayBuffer(5));
85
+ for (let row = 0; row < 5; ++row) {
86
+ let rowByte = 0;
87
+ for (let column = 0; column < 5; ++column) {
88
+ const columnMask = 0x1 << (4 - column);
89
+ if (matrix[row][column]) {
90
+ rowByte |= columnMask;
91
+ }
92
+ }
93
+ dataView.setUint8(row, rowByte);
94
+ }
95
+ return dataView;
96
+ }
97
+ async setText(text) {
98
+ const bytes = new TextEncoder().encode(text);
99
+ if (bytes.length > 20) {
100
+ throw new Error("Text must be <= 20 bytes when encoded as UTF-8");
101
+ }
102
+ return this.queueGattOperation(() => this.textCharactertistic.writeValue(bytes));
103
+ }
104
+ async setScrollingDelay(value) {
105
+ const dataView = new DataView(new ArrayBuffer(2));
106
+ dataView.setUint16(0, value, true);
107
+ return this.queueGattOperation(() => this.scrollingDelayCharacteristic.writeValue(dataView));
108
+ }
109
+ async getScrollingDelay() {
110
+ const dataView = await this.queueGattOperation(() => this.scrollingDelayCharacteristic.readValue());
111
+ return dataView.getUint16(0, true);
112
+ }
113
+ async startNotifications(type) { }
114
+ async stopNotifications(type) { }
115
+ }
116
+ //# sourceMappingURL=led-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"led-service.js","sourceRoot":"","sources":["../lib/led-service.ts"],"names":[],"mappings":"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"}
package/build/led.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ type FixedArray<T, L extends number> = T[] & {
2
+ length: L;
3
+ };
4
+ type LedRow = FixedArray<boolean, 5>;
5
+ export type LedMatrix = FixedArray<LedRow, 5>;
6
+ export {};
package/build/led.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=led.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"led.js","sourceRoot":"","sources":["../lib/led.ts"],"names":[],"mappings":""}
package/build/logging.js CHANGED
@@ -1,5 +1,7 @@
1
1
  export class NullLogging {
2
- event(_event) { }
2
+ event(_event) {
3
+ console.log(_event);
4
+ }
3
5
  error(_m, _e) {
4
6
  console.error(_m, _e);
5
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"logging.js","sourceRoot":"","sources":["../lib/logging.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,WAAW;IACtB,KAAK,CAAC,MAAa,IAAS,CAAC;IAC7B,KAAK,CAAC,EAAU,EAAE,EAAW;QAC3B,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,GAAG,CAAC,EAAO;QACT,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;CACF"}
1
+ {"version":3,"file":"logging.js","sourceRoot":"","sources":["../lib/logging.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,WAAW;IACtB,KAAK,CAAC,MAAa;QACjB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;IACD,KAAK,CAAC,EAAU,EAAE,EAAW;QAC3B,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,GAAG,CAAC,EAAO;QACT,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;CACF"}