{"id":40824064,"url":"https://github.com/loopj/gbl-tools","last_synced_at":"2026-01-21T22:10:43.166Z","repository":{"id":311238055,"uuid":"1042991766","full_name":"loopj/gbl-tools","owner":"loopj","description":"JavaScript tools for parsing and uploading Gecko Bootloader images","archived":false,"fork":false,"pushed_at":"2025-08-23T06:18:19.000Z","size":22,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-24T09:20:36.710Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://loopj.com/gbl-tools/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/loopj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-22T23:41:36.000Z","updated_at":"2025-08-23T13:10:53.000Z","dependencies_parsed_at":"2025-08-24T09:45:39.661Z","dependency_job_id":null,"html_url":"https://github.com/loopj/gbl-tools","commit_stats":null,"previous_names":["loopj/gbl-tools.js","loopj/gbl-tools"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/loopj/gbl-tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopj%2Fgbl-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopj%2Fgbl-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopj%2Fgbl-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopj%2Fgbl-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loopj","download_url":"https://codeload.github.com/loopj/gbl-tools/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopj%2Fgbl-tools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28645179,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T21:29:11.980Z","status":"ssl_error","status_checked_at":"2026-01-21T21:24:31.872Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-21T22:10:42.357Z","updated_at":"2026-01-21T22:10:43.159Z","avatar_url":"https://github.com/loopj.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JavaScript Tools for Gecko Bootloader\n\nThis library provides tools for working with the Gecko Bootloader, including parsing GBL images and uploading firmware via the Web Bluetooth API.\n\n## Features\n\n- Pure JavaScript implementation, no dependencies.\n- GBL parsing support for both browser and Node.js environments.\n- Web Bluetooth client for the Gecko Bootloader BLE OTA protocol.\n- Easy-to-use CLI for quick GBL image analysis.\n\n## Demo\n\nCheck out the [live demo](https://loopj.com/gbl-tools/) of the Gecko Bootloader OTA upload client.\n\n## Installation\n\n### Browser\n\nTo use the library in a browser environment, you can import the module directly from the ESM CDN:\n\n```html\n\u003cscript type=\"module\"\u003e\n  import { GeckoBootloaderClient } from 'https://esm.sh/gbl-tools';\n\u003c/script\u003e\n```\n\n### Node.js\n\nTo install the package in a Node.js environment, you can use npm:\n\n```bash\nnpm install gbl-tools\n```\n\n## Parsing Gecko Bootloader (GBL) Images\n\n### Browser\n\n```js\nimport { GeckoBootloaderImage } from 'gecko-bootloader';\n\nconst fileInput = document.getElementById('file-input');\nfileInput.addEventListener('change', async (event) =\u003e {\n  // Read the file as an ArrayBuffer\n  const file = event.target.files[0];\n  const buffer = await file.arrayBuffer();\n\n  // Parse the GBL image\n  const gbl = new GeckoBootloaderImage(buffer);\n\n  // Check image is valid\n  const isValid = gbl.isValid();\n  console.log(`GBL image validity: ${isValid}`);\n\n  // Print the application version\n  const appVersion = gbl.application.version;\n  console.log(`Application version: ${appVersion}`);\n});\n```\n\n### Node.js\n\n```js\nimport { readFile } from 'node:fs/promises';\nimport { GeckoBootloaderImage } from 'gecko-bootloader';\n\n// Read a GBL file into a buffer\nconst buffer = await readFile('myfile.gbl');\n\n// Parse the GBL image\nconst gbl = new GeckoBootloaderImage(buffer.buffer);\n\n// Check image is valid\nconst isValid = gbl.isValid();\nconsole.log(`GBL image validity: ${isValid}`);\n\n// Print the application version\nconst appVersion = gbl.application.version;\nconsole.log(`Application version: ${appVersion}`);\n```\n\n### CLI\n\nYou can run the GBL parser from the command line without installing the package by using `npx`:\n\n```bash\nnpx -p gbl-tools gbl-parser myfile.gbl\n```\n\nAlternatively, you can install the package globally:\n\n```bash\nnpm install -g gbl-tools\ngbl-parser myfile.gbl\n```\n\n## Flashing firmware using the Gecko Bootloader BLE OTA protocol\n\nThe `GeckoBootloaderClient` class provides methods for interacting with a device running a Gecko Bootloader in AppLoader mode, or an application implementing the Gecko Bootloader OTA protocol, using the [Web Bluetooth API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API).\n\nThe Web Bluetooth API has very limited browser compatibility, so check [compatibility tables](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API#browser_compatibility) before use.\n\n### Connecting to a Device\n\n```js\nimport { GBL_OTA_SERVICE_UUID, GeckoBootloaderClient } from 'gecko-bootloader';\n\n// Prompt user to select a Bluetooth device\nlet device;\nconst connectButton = document.getElementById('connect-button');\nconnectButton.addEventListener('click', async () =\u003e {\n  device = await navigator.bluetooth.requestDevice({\n    filters: [{ services: [GBL_OTA_SERVICE_UUID] }]\n  });\n});\n\n// Create and connect the client\nconst client = new GeckoBootloaderClient(device);\nawait client.connect();\n\n// ...now we can call other methods on the client\n```\n\n### Flashing Firmware\n\n```js\n// Grab an ArrayBuffer from an HTML file input\nconst fileInput = document.getElementById('file-input');\nconst buffer = await fileInput.files[0].arrayBuffer();\n\n// Flash the firmware\nawait client.flashFirmware(buffer);\n```\n\n### Tracking Firmware Flashing Progress\n\nAn optional progress callback can be provided, which is called after each chunk of data is uploaded.\n\n```js\nfunction onProgress(progress) {\n  console.log(`Upload progress: ${progress}%`);\n}\n\nawait client.flashFirmware(buffer, { progress: onProgress });\n```\n\n### Aborting Firmware Flashing\n\nFlashing can be aborted using the `AbortController` pattern.\n\n```js\nconst controller = new AbortController();\n\ntry {\n  await client.flashFirmware(buffer, { signal: controller.signal });\n} catch (error) {\n  if (error.name === 'AbortError') {\n    console.log('Upload aborted by user');\n  } else {\n    console.error('Upload failed:', error);\n  }\n}\n\nconst cancelButton = document.getElementById('cancel-button');\ncancelButton.addEventListener('click', () =\u003e {\n  controller.abort();\n});\n```\n\n### Fetching Current Firmware Version\n\n```js\n// Grab the application version\nconst version = await client.getApplicationVersion();\nconsole.log(`Current firmware version: ${version}`);\n\n// If using semantic versioning\nconst semver = {\n  major: (version \u003e\u003e 24) \u0026 0xff,\n  minor: (version \u003e\u003e 16) \u0026 0xff,\n  patch: (version \u003e\u003e 8) \u0026 0xff,\n  build: version \u0026 0xff,\n};\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floopj%2Fgbl-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floopj%2Fgbl-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floopj%2Fgbl-tools/lists"}