From 3ab9a5246415f002bc9931f08bd2cb9c9d24c74b Mon Sep 17 00:00:00 2001 From: Grace Date: Wed, 29 Jan 2025 12:01:22 +0000 Subject: [PATCH 1/9] Generate docs using TypeDocs, document usage in README.md --- .gitignore | 1 + README.md | 75 +++++++++++++++++++- package-lock.json | 176 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 4 +- typedoc.json | 13 ++++ 5 files changed, 267 insertions(+), 2 deletions(-) create mode 100644 typedoc.json diff --git a/.gitignore b/.gitignore index eb62582..058d03e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ node_modules dist dist-ssr *.local +docs # Editor directories and files .vscode/* diff --git a/README.md b/README.md index 4baef9f..10d868c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# JavaScript library for micro:bit connections in browsers via USB and Bluetooth +# micro:bit connection library + +This is a JavaScript library for micro:bit connections in browsers via USB and Bluetooth. This project is a work in progress. We are extracting WebUSB and Web Bluetooth code from the [micro:bit Python Editor](https://github.com/microbit-foundation/python-editor-v3/) and other projects. @@ -6,12 +8,83 @@ It is intended to be used by other Micro:bit Educational Foundation projects tha The API is not stable and it's not yet recommended that third parties use this project unless they are happy to update usage as the API evolves. +[Demo site](https://microbit-connection.pages.dev/) for this library. + [Alpha releases are now on NPM](https://www.npmjs.com/package/@microbit/microbit-connection). [This Python Editor PR](https://github.com/microbit-foundation/python-editor-v3/pull/1190) tracks updating the micro:bit Python Editor to use this library. [micro:bit CreateAI](https://github.com/microbit-foundation/ml-trainer/) is already using this library for WebUSB and Web Bluetooth. +## Usage + +### Flash a micro:bit + +Instantiate a WebUSB connection using {@link MicrobitWebUSBConnection} class and use it to connect to a micro:bit. + +```ts +import { MicrobitWebUSBConnection } from "@microbit/microbit-connection"; + +const usb = new MicrobitWebUSBConnection(); +const connectionStatus = await usb.connect(); + +console.log("Connection status: ", connectionStatus); +``` + +{@link ConnectionStatus | Connection status} is `"CONNECTED"` if connection succeeds. + +Create a Universal Hex that supports both V1 and V2 micro:bits using {@link createUniversalHexFlashDataSource} and flash the micro:bit. + +```ts +import { createUniversalHexFlashDataSource } from "@microbit/microbit-connection"; + +const universalHex = createUniversalHexFlashDataSource(text); +await usb.flash(universalHex, { + partial: true, + progress: (percentage: number | undefined) => { + console.log(percentage); + }, +}); +``` + +Alternatively, you can create and flash a hex that supports a specific micro:bit version (V1 or V2) using the [@microbit/microbit-fs library](https://microbit-foundation.github.io/microbit-fs/). Below is an example of creating a hex for V1 and using it to flash the micro:bit. + +```ts +import { MicropythonFsHex } from "@microbit/microbit-fs"; +import { BoardId } from "@microbit/microbit-connection"; + +const boardId = BoardId.forVersion("V1").id; +const micropythonFs = new MicropythonFsHex([{ hex: intelHexString, boardId }]); +const hex = micropythonFs.getIntelHex(boardId); +await usb.flash(async () => hex, { + partial: true, + progress: (percentage: number | undefined) => { + console.log(percentage); + }, +}); +``` + +For more examples of using other methods in the {@link MicrobitWebUSBConnection} class, see our [demo code](https://github.com/microbit-foundation/microbit-connection/blob/main/src/demo.ts) for our [demo site](https://microbit-connection.pages.dev/). + +### Connect via Bluetooth + +By default, the micro:bit's Bluetooth service is not enabled. Visit our [Bluetooth tech site page](https://tech.microbit.org/bluetooth/) to download a hex file that would enable the bluetooth service. + +Instantiate a Bluetooth connection using {@link MicrobitWebBluetoothConnection} class and use it to connect to a micro:bit. + +```ts +import { MicrobitWebBluetoothConnection } from "@microbit/microbit-connection"; + +const bluetooth = new MicrobitWebBluetoothConnection(); +const connectionStatus = await bluetooth.connect(); + +console.log("Connection status: ", connectionStatus); +``` + +{@link ConnectionStatus | Connection status} is `"CONNECTED"` if connection succeeds. + +For more examples of using other methods in the {@link MicrobitWebBluetoothConnection} class, see our [demo code](https://github.com/microbit-foundation/microbit-connection/blob/main/src/demo.ts) for our [demo site](https://microbit-connection.pages.dev/). + ## License This software is under the MIT open source license. diff --git a/package-lock.json b/package-lock.json index b71307e..4f13900 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@types/node": "^20.14.10", "jsdom": "^24.1.0", "prettier": "3.3.2", + "typedoc": "^0.27.6", "typescript": "^5.2.2", "vite": "^5.3.1", "vitest": "^2.0.0" @@ -404,6 +405,17 @@ "node": ">=12" } }, + "node_modules/@gerrit0/mini-shiki": { + "version": "1.27.2", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-1.27.2.tgz", + "integrity": "sha512-GeWyHz8ao2gBiUW4OJnQDxXQnFgZQwwQk05t/CVVgNBN7/rK8XZ7xY6YhLVv9tH3VppWWmr9DCl3MwemB/i+Og==", + "dev": true, + "dependencies": { + "@shikijs/engine-oniguruma": "^1.27.2", + "@shikijs/types": "^1.27.2", + "@shikijs/vscode-textmate": "^10.0.1" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -724,6 +736,32 @@ "win32" ] }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.29.1.tgz", + "integrity": "sha512-gSt2WhLNgEeLstcweQOSp+C+MhOpTsgdNXRqr3zP6M+BUBZ8Md9OU2BYwUYsALBxHza7hwaIWtFHjQ/aOOychw==", + "dev": true, + "dependencies": { + "@shikijs/types": "1.29.1", + "@shikijs/vscode-textmate": "^10.0.1" + } + }, + "node_modules/@shikijs/types": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.29.1.tgz", + "integrity": "sha512-aBqAuhYRp5vSir3Pc9+QPu9WESBOjUo03ao0IHLC4TyTioSsp/SkbAZSrIH4ghYYC1T1KTEpRSBa83bas4RnPA==", + "dev": true, + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.1", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.1.tgz", + "integrity": "sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg==", + "dev": true + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -736,6 +774,15 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/node": { "version": "20.14.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", @@ -752,6 +799,12 @@ "@types/node": "*" } }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, "node_modules/@types/usb": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/usb/-/usb-1.5.4.tgz", @@ -862,6 +915,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -877,6 +936,21 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -1290,6 +1364,15 @@ } } }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/loupe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", @@ -1299,6 +1382,12 @@ "get-func-name": "^2.0.1" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "node_modules/magic-string": { "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", @@ -1308,6 +1397,29 @@ "@jridgewell/sourcemap-codec": "^1.4.15" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -1347,6 +1459,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1541,6 +1668,15 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -1756,6 +1892,28 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "peer": true }, + "node_modules/typedoc": { + "version": "0.27.6", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.27.6.tgz", + "integrity": "sha512-oBFRoh2Px6jFx366db0lLlihcalq/JzyCVp7Vaq1yphL/tbgx2e+bkpkCgJPunaPvPwoTOXSwasfklWHm7GfAw==", + "dev": true, + "dependencies": { + "@gerrit0/mini-shiki": "^1.24.0", + "lunr": "^2.3.9", + "markdown-it": "^14.1.0", + "minimatch": "^9.0.5", + "yaml": "^2.6.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x" + } + }, "node_modules/typescript": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", @@ -1769,6 +1927,12 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -2058,6 +2222,18 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true + }, + "node_modules/yaml": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } } } } diff --git a/package.json b/package.json index 7006f69..dad701c 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,14 @@ "build": "npm run build:lib && npm run build:demo", "ci": "npm run build:lib && npm run test && npx prettier --check lib src", "test": "vitest", - "preview": "vite preview" + "preview": "vite preview", + "docs": "typedoc" }, "devDependencies": { "@types/node": "^20.14.10", "jsdom": "^24.1.0", "prettier": "3.3.2", + "typedoc": "^0.27.6", "typescript": "^5.2.2", "vite": "^5.3.1", "vitest": "^2.0.0" diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..591265d --- /dev/null +++ b/typedoc.json @@ -0,0 +1,13 @@ +{ + "name": "micro:bit connection library", + "navigationLinks": { + "micro:bit tech site": "https://tech.microbit.org", + "GitHub": "https://github.com/microbit-foundation/microbit-connection" + }, + "entryPoints": ["./lib/index.ts"], + "out": "./docs/build", + "readme": "./README.md", + "headings": { + "readme": false + } +} From 52615cd123d989c8b159b73471a56b434981b8eb Mon Sep 17 00:00:00 2001 From: Grace Date: Wed, 29 Jan 2025 12:40:50 +0000 Subject: [PATCH 2/9] Add build-docs workflow --- .github/workflows/build-docs.yml | 38 ++++++++++++++++++++++++++++++++ package-lock.json | 32 +++++++++++++++++++++++++++ package.json | 1 + src/demo.ts | 10 ++++++++- 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build-docs.yml diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml new file mode 100644 index 0000000..4db004a --- /dev/null +++ b/.github/workflows/build-docs.yml @@ -0,0 +1,38 @@ +name: build-docs +on: + release: + types: [created] + push: + branches: + - main + tags: + - "**" +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Pages + uses: actions/configure-pages@v5 + - run: npm ci + - name: Build docs + run: npm run docs + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./docs/build + + deploy: + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/package-lock.json b/package-lock.json index 4f13900..90260ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "@microbit/microbit-connection", "version": "0.0.0", "dependencies": { + "@microbit/microbit-fs": "^0.9.2", "@microbit/microbit-universal-hex": "^0.2.2", "@types/web-bluetooth": "^0.0.20", "crelt": "^1.0.6", @@ -476,6 +477,32 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@microbit/microbit-fs": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@microbit/microbit-fs/-/microbit-fs-0.9.2.tgz", + "integrity": "sha512-DhJD+HFm/aP4F1667uBqrc5Zz39Jlxi01WPqZPyCHeg6UQGRYDcquf5HL1hWTmHEVa0hTMeEqI7SZQOuZmKMEA==", + "dependencies": { + "@microbit/microbit-universal-hex": "0.2.2", + "nrf-intel-hex": "1.3.0", + "text-encoder-lite": "2.0.0" + }, + "engines": { + "node": ">=8.5", + "npm": ">=6.0", + "yarn": "^1.0" + }, + "peerDependencies": { + "tslib": ">=1.9.0" + } + }, + "node_modules/@microbit/microbit-fs/node_modules/nrf-intel-hex": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/nrf-intel-hex/-/nrf-intel-hex-1.3.0.tgz", + "integrity": "sha512-oXwBJxX/0Jc4fe2Jxjv3Mw9/qw9JdToDLvJuozfVx+twpkc2oSUm8W/OODX6W4kmWOaYA11ORpGLfQ8BP7mndw==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@microbit/microbit-universal-hex": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@microbit/microbit-universal-hex/-/microbit-universal-hex-0.2.2.tgz", @@ -1835,6 +1862,11 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/text-encoder-lite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/text-encoder-lite/-/text-encoder-lite-2.0.0.tgz", + "integrity": "sha512-bo08ND8LlBwPeU23EluRUcO3p2Rsb/eN5EIfOVqfRmblNDEVKK5IzM9Qfidvo+odT0hhV8mpXQcP/M5MMzABXw==" + }, "node_modules/tinybench": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", diff --git a/package.json b/package.json index dad701c..c2af76d 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "vitest": "^2.0.0" }, "dependencies": { + "@microbit/microbit-fs": "^0.9.2", "@microbit/microbit-universal-hex": "^0.2.2", "@types/web-bluetooth": "^0.0.20", "crelt": "^1.0.6", diff --git a/src/demo.ts b/src/demo.ts index 76a5656..42daccd 100644 --- a/src/demo.ts +++ b/src/demo.ts @@ -20,6 +20,8 @@ import { MicrobitWebUSBConnection } from "../lib/usb"; import { MicrobitRadioBridgeConnection } from "../lib/usb-radio-bridge"; import "./demo.css"; import { MagnetometerDataEvent } from "../lib/magnetometer"; +import { MicropythonFsHex } from "@microbit/microbit-fs"; +import { BoardId } from "../lib/board-id"; type ConnectionType = "usb" | "bluetooth" | "radio"; @@ -209,9 +211,15 @@ const createFlashSection = (): Section => { const file = (e.currentTarget as HTMLInputElement).files?.item(0); if (file) { const text = await file.text(); + const boardId = BoardId.forVersion("V1").id; + console.log(boardId); + const micropythonFs = new MicropythonFsHex([ + { hex: text, boardId }, + ]); if (connection.flash) { console.time("flash"); - await connection.flash(createUniversalHexFlashDataSource(text), { + const hex = micropythonFs.getIntelHex(boardId); + await connection.flash(async () => hex, { partial: true, progress: (percentage: number | undefined) => { console.log(percentage); From 904f48cef19ed7401ed5c6a7da60e052ad2c6c40 Mon Sep 17 00:00:00 2001 From: Grace Date: Wed, 29 Jan 2025 13:06:37 +0000 Subject: [PATCH 3/9] Revert unintended code changes --- package-lock.json | 208 ---------------------------------------------- package.json | 5 +- src/demo.ts | 10 +-- 3 files changed, 2 insertions(+), 221 deletions(-) diff --git a/package-lock.json b/package-lock.json index 90260ac..b71307e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,6 @@ "name": "@microbit/microbit-connection", "version": "0.0.0", "dependencies": { - "@microbit/microbit-fs": "^0.9.2", "@microbit/microbit-universal-hex": "^0.2.2", "@types/web-bluetooth": "^0.0.20", "crelt": "^1.0.6", @@ -19,7 +18,6 @@ "@types/node": "^20.14.10", "jsdom": "^24.1.0", "prettier": "3.3.2", - "typedoc": "^0.27.6", "typescript": "^5.2.2", "vite": "^5.3.1", "vitest": "^2.0.0" @@ -406,17 +404,6 @@ "node": ">=12" } }, - "node_modules/@gerrit0/mini-shiki": { - "version": "1.27.2", - "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-1.27.2.tgz", - "integrity": "sha512-GeWyHz8ao2gBiUW4OJnQDxXQnFgZQwwQk05t/CVVgNBN7/rK8XZ7xY6YhLVv9tH3VppWWmr9DCl3MwemB/i+Og==", - "dev": true, - "dependencies": { - "@shikijs/engine-oniguruma": "^1.27.2", - "@shikijs/types": "^1.27.2", - "@shikijs/vscode-textmate": "^10.0.1" - } - }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -477,32 +464,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@microbit/microbit-fs": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@microbit/microbit-fs/-/microbit-fs-0.9.2.tgz", - "integrity": "sha512-DhJD+HFm/aP4F1667uBqrc5Zz39Jlxi01WPqZPyCHeg6UQGRYDcquf5HL1hWTmHEVa0hTMeEqI7SZQOuZmKMEA==", - "dependencies": { - "@microbit/microbit-universal-hex": "0.2.2", - "nrf-intel-hex": "1.3.0", - "text-encoder-lite": "2.0.0" - }, - "engines": { - "node": ">=8.5", - "npm": ">=6.0", - "yarn": "^1.0" - }, - "peerDependencies": { - "tslib": ">=1.9.0" - } - }, - "node_modules/@microbit/microbit-fs/node_modules/nrf-intel-hex": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/nrf-intel-hex/-/nrf-intel-hex-1.3.0.tgz", - "integrity": "sha512-oXwBJxX/0Jc4fe2Jxjv3Mw9/qw9JdToDLvJuozfVx+twpkc2oSUm8W/OODX6W4kmWOaYA11ORpGLfQ8BP7mndw==", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@microbit/microbit-universal-hex": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@microbit/microbit-universal-hex/-/microbit-universal-hex-0.2.2.tgz", @@ -763,32 +724,6 @@ "win32" ] }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.29.1.tgz", - "integrity": "sha512-gSt2WhLNgEeLstcweQOSp+C+MhOpTsgdNXRqr3zP6M+BUBZ8Md9OU2BYwUYsALBxHza7hwaIWtFHjQ/aOOychw==", - "dev": true, - "dependencies": { - "@shikijs/types": "1.29.1", - "@shikijs/vscode-textmate": "^10.0.1" - } - }, - "node_modules/@shikijs/types": { - "version": "1.29.1", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.29.1.tgz", - "integrity": "sha512-aBqAuhYRp5vSir3Pc9+QPu9WESBOjUo03ao0IHLC4TyTioSsp/SkbAZSrIH4ghYYC1T1KTEpRSBa83bas4RnPA==", - "dev": true, - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.1", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.1.tgz", - "integrity": "sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg==", - "dev": true - }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -801,15 +736,6 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "dev": true, - "dependencies": { - "@types/unist": "*" - } - }, "node_modules/@types/node": { "version": "20.14.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", @@ -826,12 +752,6 @@ "@types/node": "*" } }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "dev": true - }, "node_modules/@types/usb": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/usb/-/usb-1.5.4.tgz", @@ -942,12 +862,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -963,21 +877,6 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -1391,15 +1290,6 @@ } } }, - "node_modules/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", - "dev": true, - "dependencies": { - "uc.micro": "^2.0.0" - } - }, "node_modules/loupe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", @@ -1409,12 +1299,6 @@ "get-func-name": "^2.0.1" } }, - "node_modules/lunr": { - "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", - "dev": true - }, "node_modules/magic-string": { "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", @@ -1424,29 +1308,6 @@ "@jridgewell/sourcemap-codec": "^1.4.15" } }, - "node_modules/markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.0", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.1.0" - }, - "bin": { - "markdown-it": "bin/markdown-it.mjs" - } - }, - "node_modules/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -1486,21 +1347,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1695,15 +1541,6 @@ "node": ">=6" } }, - "node_modules/punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -1862,11 +1699,6 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/text-encoder-lite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/text-encoder-lite/-/text-encoder-lite-2.0.0.tgz", - "integrity": "sha512-bo08ND8LlBwPeU23EluRUcO3p2Rsb/eN5EIfOVqfRmblNDEVKK5IzM9Qfidvo+odT0hhV8mpXQcP/M5MMzABXw==" - }, "node_modules/tinybench": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", @@ -1924,28 +1756,6 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "peer": true }, - "node_modules/typedoc": { - "version": "0.27.6", - "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.27.6.tgz", - "integrity": "sha512-oBFRoh2Px6jFx366db0lLlihcalq/JzyCVp7Vaq1yphL/tbgx2e+bkpkCgJPunaPvPwoTOXSwasfklWHm7GfAw==", - "dev": true, - "dependencies": { - "@gerrit0/mini-shiki": "^1.24.0", - "lunr": "^2.3.9", - "markdown-it": "^14.1.0", - "minimatch": "^9.0.5", - "yaml": "^2.6.1" - }, - "bin": { - "typedoc": "bin/typedoc" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x" - } - }, "node_modules/typescript": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", @@ -1959,12 +1769,6 @@ "node": ">=14.17" } }, - "node_modules/uc.micro": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -2254,18 +2058,6 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true - }, - "node_modules/yaml": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", - "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", - "dev": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } } } } diff --git a/package.json b/package.json index c2af76d..7006f69 100644 --- a/package.json +++ b/package.json @@ -25,20 +25,17 @@ "build": "npm run build:lib && npm run build:demo", "ci": "npm run build:lib && npm run test && npx prettier --check lib src", "test": "vitest", - "preview": "vite preview", - "docs": "typedoc" + "preview": "vite preview" }, "devDependencies": { "@types/node": "^20.14.10", "jsdom": "^24.1.0", "prettier": "3.3.2", - "typedoc": "^0.27.6", "typescript": "^5.2.2", "vite": "^5.3.1", "vitest": "^2.0.0" }, "dependencies": { - "@microbit/microbit-fs": "^0.9.2", "@microbit/microbit-universal-hex": "^0.2.2", "@types/web-bluetooth": "^0.0.20", "crelt": "^1.0.6", diff --git a/src/demo.ts b/src/demo.ts index 42daccd..76a5656 100644 --- a/src/demo.ts +++ b/src/demo.ts @@ -20,8 +20,6 @@ import { MicrobitWebUSBConnection } from "../lib/usb"; import { MicrobitRadioBridgeConnection } from "../lib/usb-radio-bridge"; import "./demo.css"; import { MagnetometerDataEvent } from "../lib/magnetometer"; -import { MicropythonFsHex } from "@microbit/microbit-fs"; -import { BoardId } from "../lib/board-id"; type ConnectionType = "usb" | "bluetooth" | "radio"; @@ -211,15 +209,9 @@ const createFlashSection = (): Section => { const file = (e.currentTarget as HTMLInputElement).files?.item(0); if (file) { const text = await file.text(); - const boardId = BoardId.forVersion("V1").id; - console.log(boardId); - const micropythonFs = new MicropythonFsHex([ - { hex: text, boardId }, - ]); if (connection.flash) { console.time("flash"); - const hex = micropythonFs.getIntelHex(boardId); - await connection.flash(async () => hex, { + await connection.flash(createUniversalHexFlashDataSource(text), { partial: true, progress: (percentage: number | undefined) => { console.log(percentage); From ff8d07505af73a8a1b62953f609e74fe4dbd32b1 Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Wed, 29 Jan 2025 17:00:02 +0000 Subject: [PATCH 4/9] Docs/build fixes --- README.md | 40 +++++++---- package-lock.json | 176 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 + 3 files changed, 204 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 10d868c..000d029 100644 --- a/README.md +++ b/README.md @@ -33,13 +33,12 @@ console.log("Connection status: ", connectionStatus); {@link ConnectionStatus | Connection status} is `"CONNECTED"` if connection succeeds. -Create a Universal Hex that supports both V1 and V2 micro:bits using {@link createUniversalHexFlashDataSource} and flash the micro:bit. +Flash a universal hex that supports both V1 and V2: ```ts import { createUniversalHexFlashDataSource } from "@microbit/microbit-connection"; -const universalHex = createUniversalHexFlashDataSource(text); -await usb.flash(universalHex, { +await usb.flash(createUniversalHexFlashDataSource(universalHexString), { partial: true, progress: (percentage: number | undefined) => { console.log(percentage); @@ -47,21 +46,34 @@ await usb.flash(universalHex, { }); ``` -Alternatively, you can create and flash a hex that supports a specific micro:bit version (V1 or V2) using the [@microbit/microbit-fs library](https://microbit-foundation.github.io/microbit-fs/). Below is an example of creating a hex for V1 and using it to flash the micro:bit. +This code will also work for non-universal hex files so is a good default for unknown hex files. + +Alternatively, you can create and flash a hex for a specific micro:bit version by providing a function that takes a {@link BoardVersion} and returns a hex. +This can reduce download size or help integrate with APIs that produce a hex for a particular device version. +This example uses the [@microbit/microbit-fs library](https://microbit-foundation.github.io/microbit-fs/) which can return a hex based on board id. ```ts -import { MicropythonFsHex } from "@microbit/microbit-fs"; +import { MicropythonFsHex, microbitBoardId } from "@microbit/microbit-fs"; import { BoardId } from "@microbit/microbit-connection"; -const boardId = BoardId.forVersion("V1").id; -const micropythonFs = new MicropythonFsHex([{ hex: intelHexString, boardId }]); -const hex = micropythonFs.getIntelHex(boardId); -await usb.flash(async () => hex, { - partial: true, - progress: (percentage: number | undefined) => { - console.log(percentage); +const micropythonFs = new MicropythonFsHex([ + { hex: microPythonV1HexFile, boardId: microbitBoardId.V1 }, + { hex: microPythonV2HexFile, boardId: microbitBoardId.V2 }, +]); +// Add files to MicroPython file system here (omitted for simplicity) +// Flash the device +await usb.flash( + async (boardVersion) => { + const boardId = BoardId.forVersion(boardVersion).id; + return micropythonFs.getIntelHex(boardId); }, -}); + { + partial: true, + progress: (percentage: number | undefined) => { + console.log(percentage); + }, + }, +); ``` For more examples of using other methods in the {@link MicrobitWebUSBConnection} class, see our [demo code](https://github.com/microbit-foundation/microbit-connection/blob/main/src/demo.ts) for our [demo site](https://microbit-connection.pages.dev/). @@ -101,7 +113,7 @@ $ npx license-checker --direct --summary --production Omit the flags as desired to obtain more detail. -## Code of Conduct +## Code of conduct Trust, partnership, simplicity and passion are our core values we live and breathe in our daily work life and within our projects. Our open-source diff --git a/package-lock.json b/package-lock.json index b71307e..4f13900 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@types/node": "^20.14.10", "jsdom": "^24.1.0", "prettier": "3.3.2", + "typedoc": "^0.27.6", "typescript": "^5.2.2", "vite": "^5.3.1", "vitest": "^2.0.0" @@ -404,6 +405,17 @@ "node": ">=12" } }, + "node_modules/@gerrit0/mini-shiki": { + "version": "1.27.2", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-1.27.2.tgz", + "integrity": "sha512-GeWyHz8ao2gBiUW4OJnQDxXQnFgZQwwQk05t/CVVgNBN7/rK8XZ7xY6YhLVv9tH3VppWWmr9DCl3MwemB/i+Og==", + "dev": true, + "dependencies": { + "@shikijs/engine-oniguruma": "^1.27.2", + "@shikijs/types": "^1.27.2", + "@shikijs/vscode-textmate": "^10.0.1" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -724,6 +736,32 @@ "win32" ] }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.29.1.tgz", + "integrity": "sha512-gSt2WhLNgEeLstcweQOSp+C+MhOpTsgdNXRqr3zP6M+BUBZ8Md9OU2BYwUYsALBxHza7hwaIWtFHjQ/aOOychw==", + "dev": true, + "dependencies": { + "@shikijs/types": "1.29.1", + "@shikijs/vscode-textmate": "^10.0.1" + } + }, + "node_modules/@shikijs/types": { + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.29.1.tgz", + "integrity": "sha512-aBqAuhYRp5vSir3Pc9+QPu9WESBOjUo03ao0IHLC4TyTioSsp/SkbAZSrIH4ghYYC1T1KTEpRSBa83bas4RnPA==", + "dev": true, + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.1", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.1.tgz", + "integrity": "sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg==", + "dev": true + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -736,6 +774,15 @@ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/node": { "version": "20.14.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", @@ -752,6 +799,12 @@ "@types/node": "*" } }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true + }, "node_modules/@types/usb": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/usb/-/usb-1.5.4.tgz", @@ -862,6 +915,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -877,6 +936,21 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -1290,6 +1364,15 @@ } } }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "dependencies": { + "uc.micro": "^2.0.0" + } + }, "node_modules/loupe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", @@ -1299,6 +1382,12 @@ "get-func-name": "^2.0.1" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "node_modules/magic-string": { "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", @@ -1308,6 +1397,29 @@ "@jridgewell/sourcemap-codec": "^1.4.15" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -1347,6 +1459,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1541,6 +1668,15 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -1756,6 +1892,28 @@ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "peer": true }, + "node_modules/typedoc": { + "version": "0.27.6", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.27.6.tgz", + "integrity": "sha512-oBFRoh2Px6jFx366db0lLlihcalq/JzyCVp7Vaq1yphL/tbgx2e+bkpkCgJPunaPvPwoTOXSwasfklWHm7GfAw==", + "dev": true, + "dependencies": { + "@gerrit0/mini-shiki": "^1.24.0", + "lunr": "^2.3.9", + "markdown-it": "^14.1.0", + "minimatch": "^9.0.5", + "yaml": "^2.6.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x" + } + }, "node_modules/typescript": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", @@ -1769,6 +1927,12 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -2058,6 +2222,18 @@ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true + }, + "node_modules/yaml": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } } } } diff --git a/package.json b/package.json index 7006f69..d182b03 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "build:lib": "npm run build:esm && npm run build:cjs", "build:demo": "vite build --mode=demo", "build": "npm run build:lib && npm run build:demo", + "docs": "typedoc", "ci": "npm run build:lib && npm run test && npx prettier --check lib src", "test": "vitest", "preview": "vite preview" @@ -31,6 +32,7 @@ "@types/node": "^20.14.10", "jsdom": "^24.1.0", "prettier": "3.3.2", + "typedoc": "^0.27.6", "typescript": "^5.2.2", "vite": "^5.3.1", "vitest": "^2.0.0" From 56f7b138f936126da4fc4989419a38f73cbdab0c Mon Sep 17 00:00:00 2001 From: Grace Date: Wed, 29 Jan 2025 17:16:10 +0000 Subject: [PATCH 5/9] Fix relevant warnings from typedoc re missing exports --- lib/bluetooth.ts | 2 +- lib/index.ts | 29 ++++++++++++++++++++++++++--- lib/logging.ts | 6 +++--- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib/bluetooth.ts b/lib/bluetooth.ts index 1a98759..e0398f1 100644 --- a/lib/bluetooth.ts +++ b/lib/bluetooth.ts @@ -49,7 +49,7 @@ export class MicrobitWebBluetoothConnection private device: BluetoothDevice | undefined; private logging: Logging; - connection: BluetoothDeviceWrapper | undefined; + private connection: BluetoothDeviceWrapper | undefined; private availabilityListener = (e: Event) => { // TODO: is this called? is `value` correct? diff --git a/lib/index.ts b/lib/index.ts index c07bb62..115d080 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,9 +1,13 @@ import { AccelerometerData, AccelerometerDataEvent } from "./accelerometer.js"; -import { MicrobitWebBluetoothConnection } from "./bluetooth.js"; +import { + MicrobitWebBluetoothConnection, + MicrobitWebBluetoothConnectionOptions, +} from "./bluetooth.js"; import { BoardId } from "./board-id.js"; import { ButtonEvent, ButtonEventType, ButtonState } from "./buttons.js"; import { AfterRequestDevice, + BackgroundErrorEvent, BeforeRequestDevice, BoardVersion, ConnectionStatus, @@ -15,19 +19,30 @@ import { FlashDataError, FlashDataSource, FlashEvent, + FlashOptions, SerialDataEvent, SerialErrorEvent, SerialResetEvent, } from "./device.js"; import { TypedEventTarget } from "./events.js"; import { createUniversalHexFlashDataSource } from "./hex-flash-data-source.js"; +import { LedMatrix } from "./led.js"; +import { Logging, LoggingEvent } from "./logging.js"; import { MagnetometerData, MagnetometerDataEvent } from "./magnetometer.js"; import { ServiceConnectionEventMap } from "./service-events.js"; -import { MicrobitRadioBridgeConnection } from "./usb-radio-bridge.js"; -import { MicrobitWebUSBConnection } from "./usb.js"; +import { UARTDataEvent } from "./uart.js"; +import { + MicrobitRadioBridgeConnection, + MicrobitRadioBridgeConnectionOptions, +} from "./usb-radio-bridge.js"; +import { + MicrobitWebUSBConnection, + MicrobitWebUSBConnectionOptions, +} from "./usb.js"; export { AfterRequestDevice, + BackgroundErrorEvent, BeforeRequestDevice, BoardId, ConnectionStatus, @@ -45,6 +60,7 @@ export { SerialResetEvent, ServiceConnectionEventMap, TypedEventTarget, + UARTDataEvent, }; export type { @@ -57,6 +73,13 @@ export type { DeviceConnection, DeviceErrorCode, FlashDataSource, + FlashOptions, + LedMatrix, + Logging, + LoggingEvent, MagnetometerData, MagnetometerDataEvent, + MicrobitRadioBridgeConnectionOptions, + MicrobitWebBluetoothConnectionOptions, + MicrobitWebUSBConnectionOptions, }; diff --git a/lib/logging.ts b/lib/logging.ts index c81d118..ab0c5f8 100644 --- a/lib/logging.ts +++ b/lib/logging.ts @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: MIT */ -export interface Event { +export interface LoggingEvent { type: string; message?: string; value?: number; @@ -11,13 +11,13 @@ export interface Event { } export interface Logging { - event(event: Event): void; + event(event: LoggingEvent): void; error(message: string, e: unknown): void; log(e: any): void; } export class NullLogging implements Logging { - event(_event: Event): void { + event(_event: LoggingEvent): void { console.log(_event); } error(_m: string, _e: unknown): void { From 98f2c156570482dca264b50476532a7e0243553f Mon Sep 17 00:00:00 2001 From: Grace Date: Wed, 29 Jan 2025 17:21:21 +0000 Subject: [PATCH 6/9] Build docs all the time, but only deploy if creating tag --- .github/workflows/build-docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 4db004a..ffdc2a6 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -24,6 +24,7 @@ jobs: path: ./docs/build deploy: + if: ${{ startsWith(github.ref, 'refs/tags/') }} permissions: pages: write id-token: write From bcf43895d71ac4c749b485ec23c5ae78ac87ce96 Mon Sep 17 00:00:00 2001 From: Grace Date: Wed, 29 Jan 2025 17:24:20 +0000 Subject: [PATCH 7/9] Build doc always --- .github/workflows/build-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index ffdc2a6..444fd0e 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -4,7 +4,7 @@ on: types: [created] push: branches: - - main + - "**" tags: - "**" jobs: From 18119d9e34431a698f6b817ec6998319edbeef7c Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Wed, 29 Jan 2025 17:29:13 +0000 Subject: [PATCH 8/9] Tidy, reference docs site --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 000d029..68a147c 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,19 @@ # micro:bit connection library -This is a JavaScript library for micro:bit connections in browsers via USB and Bluetooth. - -This project is a work in progress. We are extracting WebUSB and Web Bluetooth code from the [micro:bit Python Editor](https://github.com/microbit-foundation/python-editor-v3/) and other projects. +[This documentation is best viewed on the documentation site](https://microbit-foundation.github.io/microbit-connection/). -It is intended to be used by other Micro:bit Educational Foundation projects that need to connect to a BBC micro:bit. +This is a JavaScript library for micro:bit connections in browsers via USB and Bluetooth. -The API is not stable and it's not yet recommended that third parties use this project unless they are happy to update usage as the API evolves. +This project is a work in progress. We are extracting WebUSB and Web Bluetooth code from the [micro:bit Python Editor](https://github.com/microbit-foundation/python-editor-v3/) and other projects. The API is not stable and it's not yet recommended that third parties use this project unless they are happy to update usage as the API evolves. -[Demo site](https://microbit-connection.pages.dev/) for this library. +[Demo page](https://microbit-connection.pages.dev/) for this library. [Alpha releases are now on NPM](https://www.npmjs.com/package/@microbit/microbit-connection). -[This Python Editor PR](https://github.com/microbit-foundation/python-editor-v3/pull/1190) tracks updating the micro:bit Python Editor to use this library. - [micro:bit CreateAI](https://github.com/microbit-foundation/ml-trainer/) is already using this library for WebUSB and Web Bluetooth. +[This Python Editor PR](https://github.com/microbit-foundation/python-editor-v3/pull/1190) tracks updating the micro:bit Python Editor to use this library. + ## Usage ### Flash a micro:bit From eff01dc281389b591642c358b90907cabb562e52 Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Wed, 29 Jan 2025 17:30:05 +0000 Subject: [PATCH 9/9] Another tweak --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 68a147c..b4af306 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # micro:bit connection library -[This documentation is best viewed on the documentation site](https://microbit-foundation.github.io/microbit-connection/). +[This documentation is best viewed on the documentation site rather than GitHub](https://microbit-foundation.github.io/microbit-connection/). This is a JavaScript library for micro:bit connections in browsers via USB and Bluetooth.