Skip to content

Commit f2714b6

Browse files
Add cjs build alongside esm (#51)
- Introduced cjs build alongside (not bundled, unlike other Foundation projects) - Drop dapjs fork (on GitHub) by adding import workaround until they have exports support (which we can do a PR for soon) - Reluctantly use node10 module resolution to sidestep an issue with nrf-intel-hex (likely also fixed by introducing exports there) - Using NodeNext with `type: module` in this package causes the ESM build to fail with errors about MemoryMap being a namespace not a type. I think this is what the `MemoryMap.default` cludges we've had to remove were addressing. - I still don't entirely understand it. If you hack in `type: module` and the obvious `exports` into `nrf-intel-hex` then it builds cleanly so I think that's the best route forward but we'll need this in the interim. We've verified that the built package can be consumed by our Vite builds, Vitest tests (which use Node) and a Webpack 5 project that mirrors code.org's configuration. Because this cjs build depends on nrf-intel-hex we're also going to modernise microbit-fs to have a CJS build that doesn't bundle nrf-intel-hex.
1 parent bb2eb6b commit f2714b6

File tree

8 files changed

+208
-144
lines changed

8 files changed

+208
-144
lines changed

.npmignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@ examples/
2222
## this is generated by `npm pack`
2323
*.tgz
2424
package
25+
26+
dist/
27+
vite.config.*

lib/usb-device-wrapper.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@
33
*
44
* SPDX-License-Identifier: MIT
55
*/
6-
import { CortexM, DAPLink, WebUSB } from "dapjs";
6+
import * as dapjs from "dapjs";
7+
// dapjs import faff needed for use from Node such as Vitest https://github.com/ARMmbed/dapjs/issues/118
8+
import type { CortexM, DAPLink, WebUSB } from "dapjs";
9+
const {
10+
CortexM: CortexMValue,
11+
DAPLink: DAPLinkValue,
12+
WebUSB: WebUSBValue,
13+
} = dapjs;
714
import { Logging } from "./logging.js";
815
import {
916
ApReg,
@@ -38,9 +45,9 @@ export class DAPWrapper {
3845
public device: USBDevice,
3946
private logging: Logging,
4047
) {
41-
this.transport = new WebUSB(this.device);
42-
this.daplink = new DAPLink(this.transport);
43-
this.cortexM = new CortexM(this.transport);
48+
this.transport = new WebUSBValue(this.device);
49+
this.daplink = new DAPLinkValue(this.transport);
50+
this.cortexM = new CortexMValue(this.transport);
4451
}
4552

4653
/**
@@ -82,9 +89,9 @@ export class DAPWrapper {
8289
if (this.initialConnectionComplete) {
8390
await this.disconnectAsync();
8491

85-
this.transport = new WebUSB(this.device);
86-
this.daplink = new DAPLink(this.transport);
87-
this.cortexM = new CortexM(this.transport);
92+
this.transport = new WebUSBValue(this.device);
93+
this.daplink = new DAPLinkValue(this.transport);
94+
this.cortexM = new CortexMValue(this.transport);
8895
} else {
8996
this.initialConnectionComplete = true;
9097
}
@@ -153,13 +160,13 @@ export class DAPWrapper {
153160
// Changing the baud rate causes a micro:bit reset, so only do it if necessary
154161
await this.daplink.setSerialBaudrate(115200);
155162
}
156-
this.daplink.addListener(DAPLink.EVENT_SERIAL_DATA, listener);
163+
this.daplink.addListener(DAPLinkValue.EVENT_SERIAL_DATA, listener);
157164
await this.daplink.startSerialRead(1);
158165
}
159166

160167
stopSerial(listener: (data: string) => void): void {
161168
this.daplink.stopSerialRead();
162-
this.daplink.removeListener(DAPLink.EVENT_SERIAL_DATA, listener);
169+
this.daplink.removeListener(DAPLinkValue.EVENT_SERIAL_DATA, listener);
163170
}
164171

165172
async disconnectAsync(): Promise<void> {

lib/usb-partial-flashing.ts

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@
4444
* Latest Microsoft implementation is here:
4545
* https://github.com/microsoft/pxt-microbit/blob/master/editor/flash.ts
4646
*/
47-
import { DAPLink } from "dapjs";
47+
48+
// dapjs import faff needed for Vitest https://github.com/ARMmbed/dapjs/issues/118
49+
import * as dapjs from "dapjs";
50+
const { DAPLink: DAPLinkValue } = dapjs;
4851
import { Logging } from "./logging.js";
4952
import { withTimeout, TimeoutError } from "./async-util.js";
5053
import { DAPWrapper } from "./usb-device-wrapper.js";
@@ -55,8 +58,8 @@ import {
5558
pageAlignBlocks,
5659
read32FromUInt8Array,
5760
} from "./usb-partial-flashing-utils.js";
58-
import MemoryMap from "nrf-intel-hex";
5961
import { BoardVersion } from "./device.js";
62+
import MemoryMap from "nrf-intel-hex";
6063

6164
type ProgressCallback = (n: number, partial: boolean) => void;
6265

@@ -205,7 +208,7 @@ export class PartialFlashing {
205208
// Falls back to a full flash if partial flashing fails.
206209
// Drawn from https://github.com/microsoft/pxt-microbit/blob/dec5b8ce72d5c2b4b0b20aafefce7474a6f0c7b2/editor/extension.tsx#L335
207210
private async partialFlashAsync(
208-
data: string | Uint8Array | MemoryMap.default,
211+
data: string | Uint8Array | MemoryMap,
209212
updateProgress: ProgressCallback,
210213
): Promise<boolean> {
211214
const flashBytes = this.convertDataToPaddedBytes(data);
@@ -251,15 +254,15 @@ export class PartialFlashing {
251254

252255
// Perform full flash of micro:bit's ROM using daplink.
253256
async fullFlashAsync(
254-
data: string | Uint8Array | MemoryMap.default,
257+
data: string | Uint8Array | MemoryMap,
255258
updateProgress: ProgressCallback,
256259
) {
257260
this.log("Full flash");
258261

259262
const fullFlashProgress = (progress: number) => {
260263
updateProgress(progress, false);
261264
};
262-
this.dapwrapper.daplink.on(DAPLink.EVENT_PROGRESS, fullFlashProgress);
265+
this.dapwrapper.daplink.on(DAPLinkValue.EVENT_PROGRESS, fullFlashProgress);
263266
try {
264267
data = this.convertDataToHexString(data);
265268
await this.dapwrapper.transport.open();
@@ -270,7 +273,7 @@ export class PartialFlashing {
270273
});
271274
} finally {
272275
this.dapwrapper.daplink.removeListener(
273-
DAPLink.EVENT_PROGRESS,
276+
DAPLinkValue.EVENT_PROGRESS,
274277
fullFlashProgress,
275278
);
276279
}
@@ -279,7 +282,7 @@ export class PartialFlashing {
279282
// Flash the micro:bit's ROM with the provided image, resetting the micro:bit first.
280283
// Drawn from https://github.com/microsoft/pxt-microbit/blob/dec5b8ce72d5c2b4b0b20aafefce7474a6f0c7b2/editor/extension.tsx#L439
281284
async flashAsync(
282-
data: string | Uint8Array | MemoryMap.default,
285+
data: string | Uint8Array | MemoryMap,
283286
updateProgress: ProgressCallback,
284287
): Promise<boolean> {
285288
let resetPromise = (async () => {
@@ -321,7 +324,7 @@ export class PartialFlashing {
321324
}
322325

323326
private convertDataToHexString(
324-
data: string | Uint8Array | MemoryMap.default,
327+
data: string | Uint8Array | MemoryMap,
325328
): string {
326329
if (typeof data === "string") {
327330
return data;
@@ -333,7 +336,7 @@ export class PartialFlashing {
333336
}
334337

335338
private convertDataToPaddedBytes(
336-
data: string | Uint8Array | MemoryMap.default,
339+
data: string | Uint8Array | MemoryMap,
337340
): Uint8Array {
338341
if (data instanceof Uint8Array) {
339342
return data;
@@ -345,26 +348,15 @@ export class PartialFlashing {
345348
}
346349

347350
private hexStringToPaddedBytes(hex: string): Uint8Array {
348-
// Cludge for a packaging issue
349-
const fromHex: (
350-
hexText: string,
351-
maxBlockSize?: number,
352-
) => MemoryMap.default =
353-
(MemoryMap as any).fromHex ?? MemoryMap.default.fromHex;
354-
355-
return this.memoryMapToPaddedBytes(fromHex(hex));
351+
const m = MemoryMap.fromHex(hex);
352+
return this.memoryMapToPaddedBytes(m);
356353
}
357354

358355
private paddedBytesToHexString(data: Uint8Array): string {
359-
// Cludge for a packaging issue
360-
const fromPaddedUint8Array: (data: Uint8Array) => MemoryMap.default =
361-
(MemoryMap as any).fromPaddedUint8Array ??
362-
MemoryMap.default.fromPaddedUint8Array;
363-
364-
return fromPaddedUint8Array(data).asHexString();
356+
return MemoryMap.fromPaddedUint8Array(data).asHexString();
365357
}
366358

367-
private memoryMapToPaddedBytes(memoryMap: MemoryMap.default): Uint8Array {
359+
private memoryMapToPaddedBytes(memoryMap: MemoryMap): Uint8Array {
368360
const flashSize = {
369361
V1: 256 * 1024,
370362
V2: 512 * 1024,

0 commit comments

Comments
 (0)