@hangtime/grip-connect 0.5.11 → 0.6.0

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 (56) hide show
  1. package/README.md +12 -3
  2. package/deno.json +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.js +2 -1
  5. package/dist/interfaces/device/climbro.interface.d.ts +1 -1
  6. package/dist/interfaces/device/entralpi.interface.d.ts +1 -1
  7. package/dist/interfaces/device/forceboard.interface.d.ts +1 -1
  8. package/dist/interfaces/device/kilterboard.interface.d.ts +1 -1
  9. package/dist/interfaces/device/motherboard.interface.d.ts +2 -2
  10. package/dist/interfaces/device/mysmartboard.interface.d.ts +2 -2
  11. package/dist/interfaces/device/progressor.interface.d.ts +2 -2
  12. package/dist/interfaces/device/wh-c06.interface.d.ts +2 -2
  13. package/dist/interfaces/device.interface.d.ts +3 -3
  14. package/dist/models/base.model.d.ts +1 -1
  15. package/dist/models/device/climbro.model.d.ts +4 -3
  16. package/dist/models/device/climbro.model.js +3 -2
  17. package/dist/models/device/entralpi.model.d.ts +6 -2
  18. package/dist/models/device/entralpi.model.js +5 -1
  19. package/dist/models/device/forceboard.model.d.ts +4 -3
  20. package/dist/models/device/forceboard.model.js +3 -2
  21. package/dist/models/device/kilterboard.model.d.ts +4 -3
  22. package/dist/models/device/kilterboard.model.js +3 -2
  23. package/dist/models/device/motherboard.model.d.ts +4 -3
  24. package/dist/models/device/motherboard.model.js +3 -2
  25. package/dist/models/device/mysmartboard.model.d.ts +4 -3
  26. package/dist/models/device/mysmartboard.model.js +3 -2
  27. package/dist/models/device/progressor.model.d.ts +3 -3
  28. package/dist/models/device/progressor.model.js +4 -3
  29. package/dist/models/device/wh-c06.model.d.ts +6 -4
  30. package/dist/models/device/wh-c06.model.js +7 -4
  31. package/dist/models/device.model.d.ts +11 -5
  32. package/dist/models/device.model.js +18 -5
  33. package/dist/models/index.d.ts +8 -8
  34. package/dist/models/index.js +8 -9
  35. package/package.json +5 -2
  36. package/src/index.ts +3 -1
  37. package/src/interfaces/device/climbro.interface.ts +1 -1
  38. package/src/interfaces/device/entralpi.interface.ts +1 -1
  39. package/src/interfaces/device/forceboard.interface.ts +1 -1
  40. package/src/interfaces/device/kilterboard.interface.ts +1 -1
  41. package/src/interfaces/device/motherboard.interface.ts +2 -2
  42. package/src/interfaces/device/mysmartboard.interface.ts +2 -2
  43. package/src/interfaces/device/progressor.interface.ts +2 -2
  44. package/src/interfaces/device/wh-c06.interface.ts +2 -2
  45. package/src/interfaces/device.interface.ts +3 -3
  46. package/src/models/base.model.ts +1 -1
  47. package/src/models/device/climbro.model.ts +4 -3
  48. package/src/models/device/entralpi.model.ts +6 -2
  49. package/src/models/device/forceboard.model.ts +4 -3
  50. package/src/models/device/kilterboard.model.ts +4 -3
  51. package/src/models/device/motherboard.model.ts +5 -4
  52. package/src/models/device/mysmartboard.model.ts +4 -3
  53. package/src/models/device/progressor.model.ts +5 -4
  54. package/src/models/device/wh-c06.model.ts +10 -6
  55. package/src/models/device.model.ts +25 -9
  56. package/src/models/index.ts +8 -10
package/README.md CHANGED
@@ -35,13 +35,22 @@ Learn more: [Documentation](https://stevie-ray.github.io/hangtime-grip-connect/)
35
35
 
36
36
  ## Install
37
37
 
38
- This project can be found in the [NPM](https://www.npmjs.com/package/@hangtime/grip-connect) and
39
- [JSR](https://jsr.io/@hangtime/grip-connect) package registries.
38
+ This package is compatible with both Node.js and browser environments. It can be found in the
39
+ [NPM](https://www.npmjs.com/package/@hangtime/grip-connect) and [JSR](https://jsr.io/@hangtime/grip-connect) package
40
+ registries.
40
41
 
41
42
  ```sh [npm]
42
43
  $ npm install @hangtime/grip-connect
43
44
  ```
44
45
 
46
+ ```sh [yarn]
47
+ $ yarn add @hangtime/grip-connect
48
+ ```
49
+
50
+ ```sh [pnpm]
51
+ $ pnpm add @hangtime/grip-connect
52
+ ```
53
+
45
54
  ## Example usage (with a Motherboard)
46
55
 
47
56
  Simply importing the device you need from `@hangtime/grip-connect`.
@@ -115,7 +124,7 @@ document.querySelector("#motherboard").addEventListener("click", async () => {
115
124
  enable it at `chrome://flags/#enable-experimental-web-platform-features`.
116
125
  - ✅ [Kilter Board](https://stevie-ray.github.io/hangtime-grip-connect/devices/kilterboard.html)
117
126
  - ✅ [Entralpi](https://stevie-ray.github.io/hangtime-grip-connect/devices/entralpi.html) / Lefu / Unique CW275 Scale
118
- - ✅ [PitchSix Force Board](https://stevie-ray.github.io/hangtime-grip-connect/devices/forceboard.html)
127
+ - ✅ [PitchSix - Force Board](https://stevie-ray.github.io/hangtime-grip-connect/devices/forceboard.html)
119
128
  - ➡️ [Climbro](https://stevie-ray.github.io/hangtime-grip-connect/devices/climbro.html)
120
129
  - ➡️ [Smartboard Climbing - mySmartBoard](https://stevie-ray.github.io/hangtime-grip-connect/devices/mysmartboard.html)
121
130
 
package/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hangtime/grip-connect",
3
- "version": "0.5.11",
3
+ "version": "0.6.0",
4
4
  "license": "BSD-2-Clause",
5
5
  "exports": {
6
6
  ".": "./src/index.ts"
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { Climbro, Entralpi, ForceBoard, KilterBoard, Motherboard, mySmartBoard, Progressor, WHC06, } from "./models/index";
1
+ export { Climbro, Entralpi, ForceBoard, KilterBoard, Motherboard, mySmartBoard, Progressor, WHC06, } from "./models/index.js";
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
- export { Climbro, Entralpi, ForceBoard, KilterBoard, Motherboard, mySmartBoard, Progressor, WHC06, } from "./models/index";
1
+ // @ts-types="npm:@types/web-bluetooth@^0.0.20"
2
+ export { Climbro, Entralpi, ForceBoard, KilterBoard, Motherboard, mySmartBoard, Progressor, WHC06, } from "./models/index.js";
@@ -1,4 +1,4 @@
1
- import type { IDevice } from "../device.interface";
1
+ import type { IDevice } from "../device.interface.js";
2
2
  /**
3
3
  * Interface representing the Climbro device, extending the base Device interface.
4
4
  */
@@ -1,4 +1,4 @@
1
- import type { IDevice } from "../device.interface";
1
+ import type { IDevice } from "../device.interface.js";
2
2
  /**
3
3
  * Interface representing the Entralpi device, extending the base Device interface.
4
4
  */
@@ -1,4 +1,4 @@
1
- import type { IDevice } from "../device.interface";
1
+ import type { IDevice } from "../device.interface.js";
2
2
  /**
3
3
  * Interface representing the PitchSix ForceBoard device, extending the base Device interface.
4
4
  */
@@ -1,4 +1,4 @@
1
- import type { IDevice } from "../device.interface";
1
+ import type { IDevice } from "../device.interface.js";
2
2
  /**
3
3
  * Interface representing the KilterBoard device, extending the base Device interface.
4
4
  */
@@ -1,6 +1,6 @@
1
- import type { IDevice } from "../device.interface";
1
+ import type { IDevice } from "../device.interface.js";
2
2
  /**
3
- * Interface representing the Griptonite Motherboard device.
3
+ * Interface representing the Griptonite Motherboard device, extending the base Device interface.
4
4
  */
5
5
  export interface IMotherboard extends IDevice {
6
6
  /**
@@ -1,6 +1,6 @@
1
- import type { IDevice } from "../device.interface";
1
+ import type { IDevice } from "../device.interface.js";
2
2
  /**
3
- * Interface representing the mySmartBoard device, extending the base Device interface.
3
+ * Interface representing the Smartboard Climbing mySmartBoard device, extending the base Device interface.
4
4
  */
5
5
  export interface ImySmartBoard extends IDevice {
6
6
  }
@@ -1,6 +1,6 @@
1
- import type { IDevice } from "../device.interface";
1
+ import type { IDevice } from "../device.interface.js";
2
2
  /**
3
- * Interface representing the Tindeq Progressor device.
3
+ * Interface representing the Tindeq Progressor device, extending the base Device interface.
4
4
  */
5
5
  export interface IProgressor extends IDevice {
6
6
  /**
@@ -1,6 +1,6 @@
1
- import type { IDevice } from "../device.interface";
1
+ import type { IDevice } from "../device.interface.js";
2
2
  /**
3
- * Interface representing the Weiheng WH-C06 device.
3
+ * Interface representing the Weiheng WH-C06 device, extending the base Device interface.
4
4
  */
5
5
  export interface IWHC06 extends IDevice {
6
6
  }
@@ -1,6 +1,6 @@
1
- import type { IBase } from "./base.interface";
2
- import type { massObject } from "./callback.interface";
3
- import type { Commands } from "./command.interface";
1
+ import type { IBase } from "./base.interface.js";
2
+ import type { massObject } from "./callback.interface.js";
3
+ import type { Commands } from "./command.interface.js";
4
4
  /**
5
5
  * Represents a characteristic of a Bluetooth service.
6
6
  */
@@ -1,4 +1,4 @@
1
- import type { IBase } from "../interfaces/base.interface";
1
+ import type { IBase } from "../interfaces/base.interface.js";
2
2
  export declare abstract class BaseModel {
3
3
  id?: string;
4
4
  createdAt?: Date;
@@ -1,8 +1,9 @@
1
- import { Device } from "../device.model";
2
- import type { IClimbro } from "../../interfaces/device/climbro.interface";
1
+ import { Device } from "../device.model.js";
2
+ import type { IClimbro } from "../../interfaces/device/climbro.interface.js";
3
3
  /**
4
- * Represents a Climbro device
4
+ * Represents a Climbro device.
5
5
  * TODO: Add services, do you own a Climbro? Help us!
6
+ * {@link https://climbro.com/}
6
7
  */
7
8
  export declare class Climbro extends Device implements IClimbro {
8
9
  constructor();
@@ -1,7 +1,8 @@
1
- import { Device } from "../device.model";
1
+ import { Device } from "../device.model.js";
2
2
  /**
3
- * Represents a Climbro device
3
+ * Represents a Climbro device.
4
4
  * TODO: Add services, do you own a Climbro? Help us!
5
+ * {@link https://climbro.com/}
5
6
  */
6
7
  export class Climbro extends Device {
7
8
  constructor() {
@@ -1,5 +1,9 @@
1
- import { Device } from "../device.model";
2
- import type { IEntralpi } from "../../interfaces/device/entralpi.interface";
1
+ import { Device } from "../device.model.js";
2
+ import type { IEntralpi } from "../../interfaces/device/entralpi.interface.js";
3
+ /**
4
+ * Represents a Entralpi device.
5
+ * {@link https://entralpi.com}
6
+ */
3
7
  export declare class Entralpi extends Device implements IEntralpi {
4
8
  constructor();
5
9
  /**
@@ -1,4 +1,8 @@
1
- import { Device } from "../device.model";
1
+ import { Device } from "../device.model.js";
2
+ /**
3
+ * Represents a Entralpi device.
4
+ * {@link https://entralpi.com}
5
+ */
2
6
  export class Entralpi extends Device {
3
7
  constructor() {
4
8
  super({
@@ -1,7 +1,8 @@
1
- import { Device } from "../device.model";
2
- import type { IForceBoard } from "../../interfaces/device/forceboard.interface";
1
+ import { Device } from "../device.model.js";
2
+ import type { IForceBoard } from "../../interfaces/device/forceboard.interface.js";
3
3
  /**
4
- * Represents a PitchSix Force Board device
4
+ * Represents a PitchSix Force Board device.
5
+ * {@link https://pitchsix.com}
5
6
  */
6
7
  export declare class ForceBoard extends Device implements IForceBoard {
7
8
  constructor();
@@ -1,6 +1,7 @@
1
- import { Device } from "../device.model";
1
+ import { Device } from "../device.model.js";
2
2
  /**
3
- * Represents a PitchSix Force Board device
3
+ * Represents a PitchSix Force Board device.
4
+ * {@link https://pitchsix.com}
4
5
  */
5
6
  export class ForceBoard extends Device {
6
7
  constructor() {
@@ -1,5 +1,5 @@
1
- import { Device } from "../device.model";
2
- import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface";
1
+ import { Device } from "../device.model.js";
2
+ import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface.js";
3
3
  /**
4
4
  * For API level 2 and API level 3.
5
5
  * The first byte in the data is dependent on where the packet is in the message as a whole.
@@ -36,8 +36,9 @@ export declare const KilterBoardPlacementRoles: {
36
36
  screen_color: string;
37
37
  }[];
38
38
  /**
39
- * Represents a Aurora Climbing device
39
+ * Represents a Aurora Climbing device.
40
40
  * Kilter Board, Tension Board, Decoy Board, Touchstone Board, Grasshopper Board, Aurora Board, So iLL Board
41
+ * {@link https://auroraclimbing.com}
41
42
  */
42
43
  export declare class KilterBoard extends Device implements IKilterBoard {
43
44
  /**
@@ -1,4 +1,4 @@
1
- import { Device } from "../device.model";
1
+ import { Device } from "../device.model.js";
2
2
  /**
3
3
  * For API level 2 and API level 3.
4
4
  * The first byte in the data is dependent on where the packet is in the message as a whole.
@@ -65,8 +65,9 @@ export const KilterBoardPlacementRoles = [
65
65
  },
66
66
  ];
67
67
  /**
68
- * Represents a Aurora Climbing device
68
+ * Represents a Aurora Climbing device.
69
69
  * Kilter Board, Tension Board, Decoy Board, Touchstone Board, Grasshopper Board, Aurora Board, So iLL Board
70
+ * {@link https://auroraclimbing.com}
70
71
  */
71
72
  export class KilterBoard extends Device {
72
73
  /**
@@ -1,7 +1,8 @@
1
- import { Device } from "../device.model";
2
- import type { IMotherboard } from "../../interfaces/device/motherboard.interface";
1
+ import { Device } from "../device.model.js";
2
+ import type { IMotherboard } from "../../interfaces/device/motherboard.interface.js";
3
3
  /**
4
- * Represents a Griptonite Motherboard device
4
+ * Represents a Griptonite Motherboard device.
5
+ * {@link https://griptonite.io}
5
6
  */
6
7
  export declare class Motherboard extends Device implements IMotherboard {
7
8
  /**
@@ -1,6 +1,7 @@
1
- import { Device } from "../device.model";
1
+ import { Device } from "../device.model.js";
2
2
  /**
3
- * Represents a Griptonite Motherboard device
3
+ * Represents a Griptonite Motherboard device.
4
+ * {@link https://griptonite.io}
4
5
  */
5
6
  export class Motherboard extends Device {
6
7
  /**
@@ -1,8 +1,9 @@
1
- import { Device } from "../device.model";
2
- import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface";
1
+ import { Device } from "../device.model.js";
2
+ import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface.js";
3
3
  /**
4
- * Represents a mySmartBoard device
4
+ * Represents a Smartboard Climbing mySmartBoard device.
5
5
  * TODO: Add services, do you own a mySmartBoard? Help us!
6
+ * {@link https://www.smartboard-climbing.com}
6
7
  */
7
8
  export declare class mySmartBoard extends Device implements ImySmartBoard {
8
9
  constructor();
@@ -1,7 +1,8 @@
1
- import { Device } from "../device.model";
1
+ import { Device } from "../device.model.js";
2
2
  /**
3
- * Represents a mySmartBoard device
3
+ * Represents a Smartboard Climbing mySmartBoard device.
4
4
  * TODO: Add services, do you own a mySmartBoard? Help us!
5
+ * {@link https://www.smartboard-climbing.com}
5
6
  */
6
7
  export class mySmartBoard extends Device {
7
8
  constructor() {
@@ -1,7 +1,7 @@
1
- import { Device } from "../device.model";
2
- import type { IProgressor } from "../../interfaces/device/progressor.interface";
1
+ import { Device } from "../device.model.js";
2
+ import type { IProgressor } from "../../interfaces/device/progressor.interface.js";
3
3
  /**
4
- * Represents a Tindeq Progressor device
4
+ * Represents a Tindeq Progressor device.
5
5
  */
6
6
  export declare class Progressor extends Device implements IProgressor {
7
7
  constructor();
@@ -1,6 +1,7 @@
1
- import { Device } from "../device.model";
1
+ import { Device } from "../device.model.js";
2
2
  /**
3
- * Represents the possible responses of a Tindeq Progressor device.
3
+ * Represents a Tindeq Progressor device.
4
+ * {@link https://tindeq.com}
4
5
  */
5
6
  var ProgressorResponses;
6
7
  (function (ProgressorResponses) {
@@ -31,7 +32,7 @@ var ProgressorResponses;
31
32
  ProgressorResponses[ProgressorResponses["LOW_BATTERY_WARNING"] = 4] = "LOW_BATTERY_WARNING";
32
33
  })(ProgressorResponses || (ProgressorResponses = {}));
33
34
  /**
34
- * Represents a Tindeq Progressor device
35
+ * Represents a Tindeq Progressor device.
35
36
  */
36
37
  export class Progressor extends Device {
37
38
  constructor() {
@@ -1,8 +1,10 @@
1
- import { Device } from "../device.model";
2
- import type { IWHC06 } from "../../interfaces/device/wh-c06.interface";
1
+ import { Device } from "../device.model.js";
2
+ import type { IWHC06 } from "../../interfaces/device/wh-c06.interface.js";
3
3
  /**
4
- * Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device
5
- * Enable 'Experimental Web Platform features' Chrome Flags.
4
+ * Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device.
5
+ * To use this device enable: `chrome://flags/#enable-experimental-web-platform-features`.
6
+ * {@link https://googlechrome.github.io/samples/web-bluetooth/scan.html| Web Bluetooth}
7
+ * {@link https://weihengmanufacturer.com}
6
8
  */
7
9
  export declare class WHC06 extends Device implements IWHC06 {
8
10
  /**
@@ -1,7 +1,9 @@
1
- import { Device } from "../device.model";
1
+ import { Device } from "../device.model.js";
2
2
  /**
3
- * Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device
4
- * Enable 'Experimental Web Platform features' Chrome Flags.
3
+ * Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device.
4
+ * To use this device enable: `chrome://flags/#enable-experimental-web-platform-features`.
5
+ * {@link https://googlechrome.github.io/samples/web-bluetooth/scan.html| Web Bluetooth}
6
+ * {@link https://weihengmanufacturer.com}
5
7
  */
6
8
  export class WHC06 extends Device {
7
9
  /**
@@ -65,7 +67,8 @@ export class WHC06 extends Device {
65
67
  try {
66
68
  // Only data matching the optionalManufacturerData parameter to requestDevice is included in the advertisement event: https://github.com/WebBluetoothCG/web-bluetooth/issues/598
67
69
  const optionalManufacturerData = this.filters.flatMap((filter) => filter.manufacturerData?.map((data) => data.companyIdentifier) || []);
68
- this.bluetooth = await navigator.bluetooth.requestDevice({
70
+ const bluetooth = await this.getBluetooth();
71
+ this.bluetooth = await bluetooth.requestDevice({
69
72
  filters: this.filters,
70
73
  optionalManufacturerData,
71
74
  });
@@ -1,8 +1,8 @@
1
- import { BaseModel } from "./../models/base.model";
2
- import type { IDevice, Service } from "../interfaces/device.interface";
3
- import type { ActiveCallback, NotifyCallback, WriteCallback } from "../interfaces/callback.interface";
4
- import type { DownloadPacket } from "../interfaces/download.interface";
5
- import type { Commands } from "../interfaces/command.interface";
1
+ import { BaseModel } from "./../models/base.model.js";
2
+ import type { IDevice, Service } from "../interfaces/device.interface.js";
3
+ import type { ActiveCallback, NotifyCallback, WriteCallback } from "../interfaces/callback.interface.js";
4
+ import type { DownloadPacket } from "../interfaces/download.interface.js";
5
+ import type { Commands } from "../interfaces/command.interface.js";
6
6
  export declare abstract class Device extends BaseModel implements IDevice {
7
7
  /**
8
8
  * Filters to identify the device during Bluetooth scanning.
@@ -274,6 +274,12 @@ export declare abstract class Device extends BaseModel implements IDevice {
274
274
  * console.log(serviceUUIDs);
275
275
  */
276
276
  protected getAllServiceUUIDs: () => string[];
277
+ /**
278
+ * Attempt to use ES module import rather than require.
279
+ * This approach uses an async dynamic import for `webbluetooth`,
280
+ * so we can fallback if `navigator.bluetooth` is unavailable.
281
+ */
282
+ protected getBluetooth(): Promise<Bluetooth | import("webbluetooth").Bluetooth>;
277
283
  /**
278
284
  * Retrieves the characteristic from the device's service.
279
285
  * @param {string} serviceId - The UUID of the service.
@@ -1,4 +1,4 @@
1
- import { BaseModel } from "./../models/base.model";
1
+ import { BaseModel } from "./../models/base.model.js";
2
2
  export class Device extends BaseModel {
3
3
  /**
4
4
  * Filters to identify the device during Bluetooth scanning.
@@ -239,12 +239,10 @@ export class Device extends BaseModel {
239
239
  */
240
240
  connect = async (onSuccess = () => console.log("Connected successfully"), onError = (error) => console.error(error)) => {
241
241
  try {
242
- if (typeof navigator === "undefined" || !("bluetooth" in navigator)) {
243
- throw new Error("Web Bluetooth API not supported in this environment.");
244
- }
245
242
  // Request device and set up connection
246
243
  const deviceServices = this.getAllServiceUUIDs();
247
- this.bluetooth = await navigator.bluetooth.requestDevice({
244
+ const bluetooth = await this.getBluetooth();
245
+ this.bluetooth = await bluetooth.requestDevice({
248
246
  filters: this.filters,
249
247
  optionalServices: deviceServices,
250
248
  });
@@ -435,6 +433,21 @@ export class Device extends BaseModel {
435
433
  getAllServiceUUIDs = () => {
436
434
  return this.services.filter((service) => service?.uuid).map((service) => service.uuid);
437
435
  };
436
+ /**
437
+ * Attempt to use ES module import rather than require.
438
+ * This approach uses an async dynamic import for `webbluetooth`,
439
+ * so we can fallback if `navigator.bluetooth` is unavailable.
440
+ */
441
+ async getBluetooth() {
442
+ // If we're in a browser with real Web Bluetooth available:
443
+ if (typeof navigator !== "undefined" && "bluetooth" in navigator) {
444
+ return navigator.bluetooth;
445
+ }
446
+ // Otherwise, we're likely in Node or an environment without `navigator.bluetooth`.
447
+ // Use a dynamic import for the ESM version:
448
+ const { bluetooth } = await import("webbluetooth");
449
+ return bluetooth;
450
+ }
438
451
  /**
439
452
  * Retrieves the characteristic from the device's service.
440
453
  * @param {string} serviceId - The UUID of the service.
@@ -1,8 +1,8 @@
1
- export { Climbro } from "./device/climbro.model";
2
- export { Entralpi } from "./device/entralpi.model";
3
- export { ForceBoard } from "./device/forceboard.model";
4
- export { KilterBoard } from "./device/kilterboard.model";
5
- export { Motherboard } from "./device/motherboard.model";
6
- export { mySmartBoard } from "./device/mysmartboard.model";
7
- export { Progressor } from "./device/progressor.model";
8
- export { WHC06 } from "./device/wh-c06.model";
1
+ export { Climbro } from "./device/climbro.model.js";
2
+ export { Entralpi } from "./device/entralpi.model.js";
3
+ export { ForceBoard } from "./device/forceboard.model.js";
4
+ export { KilterBoard } from "./device/kilterboard.model.js";
5
+ export { Motherboard } from "./device/motherboard.model.js";
6
+ export { mySmartBoard } from "./device/mysmartboard.model.js";
7
+ export { Progressor } from "./device/progressor.model.js";
8
+ export { WHC06 } from "./device/wh-c06.model.js";
@@ -1,9 +1,8 @@
1
- // @ts-types="npm:@types/web-bluetooth@^0.0.20"
2
- export { Climbro } from "./device/climbro.model";
3
- export { Entralpi } from "./device/entralpi.model";
4
- export { ForceBoard } from "./device/forceboard.model";
5
- export { KilterBoard } from "./device/kilterboard.model";
6
- export { Motherboard } from "./device/motherboard.model";
7
- export { mySmartBoard } from "./device/mysmartboard.model";
8
- export { Progressor } from "./device/progressor.model";
9
- export { WHC06 } from "./device/wh-c06.model";
1
+ export { Climbro } from "./device/climbro.model.js";
2
+ export { Entralpi } from "./device/entralpi.model.js";
3
+ export { ForceBoard } from "./device/forceboard.model.js";
4
+ export { KilterBoard } from "./device/kilterboard.model.js";
5
+ export { Motherboard } from "./device/motherboard.model.js";
6
+ export { mySmartBoard } from "./device/mysmartboard.model.js";
7
+ export { Progressor } from "./device/progressor.model.js";
8
+ export { WHC06 } from "./device/wh-c06.model.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hangtime/grip-connect",
3
- "version": "0.5.11",
3
+ "version": "0.6.0",
4
4
  "description": "Griptonite Motherboard, Tindeq Progressor, PitchSix Force Board, WHC-06, Entralpi, Climbro, mySmartBoard: Web Bluetooth API Force-Sensing strength analysis for climbers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -33,5 +33,8 @@
33
33
  "bugs": {
34
34
  "url": "https://github.com/Stevie-Ray/hangtime-grip-connect/issues"
35
35
  },
36
- "homepage": "https://stevie-ray.github.io/hangtime-grip-connect/"
36
+ "homepage": "https://stevie-ray.github.io/hangtime-grip-connect/",
37
+ "dependencies": {
38
+ "webbluetooth": "^3.2.1"
39
+ }
37
40
  }
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ // @ts-types="npm:@types/web-bluetooth@^0.0.20"
2
+
1
3
  export {
2
4
  Climbro,
3
5
  Entralpi,
@@ -7,4 +9,4 @@ export {
7
9
  mySmartBoard,
8
10
  Progressor,
9
11
  WHC06,
10
- } from "./models/index"
12
+ } from "./models/index.js"
@@ -1,4 +1,4 @@
1
- import type { IDevice } from "../device.interface"
1
+ import type { IDevice } from "../device.interface.js"
2
2
  /**
3
3
  * Interface representing the Climbro device, extending the base Device interface.
4
4
  */
@@ -1,4 +1,4 @@
1
- import type { IDevice } from "../device.interface"
1
+ import type { IDevice } from "../device.interface.js"
2
2
 
3
3
  /**
4
4
  * Interface representing the Entralpi device, extending the base Device interface.
@@ -1,4 +1,4 @@
1
- import type { IDevice } from "../device.interface"
1
+ import type { IDevice } from "../device.interface.js"
2
2
 
3
3
  /**
4
4
  * Interface representing the PitchSix ForceBoard device, extending the base Device interface.
@@ -1,4 +1,4 @@
1
- import type { IDevice } from "../device.interface"
1
+ import type { IDevice } from "../device.interface.js"
2
2
  /**
3
3
  * Interface representing the KilterBoard device, extending the base Device interface.
4
4
  */
@@ -1,7 +1,7 @@
1
- import type { IDevice } from "../device.interface"
1
+ import type { IDevice } from "../device.interface.js"
2
2
 
3
3
  /**
4
- * Interface representing the Griptonite Motherboard device.
4
+ * Interface representing the Griptonite Motherboard device, extending the base Device interface.
5
5
  */
6
6
  export interface IMotherboard extends IDevice {
7
7
  /**
@@ -1,6 +1,6 @@
1
- import type { IDevice } from "../device.interface"
1
+ import type { IDevice } from "../device.interface.js"
2
2
  /**
3
- * Interface representing the mySmartBoard device, extending the base Device interface.
3
+ * Interface representing the Smartboard Climbing mySmartBoard device, extending the base Device interface.
4
4
  */
5
5
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
6
6
  export interface ImySmartBoard extends IDevice {}
@@ -1,7 +1,7 @@
1
- import type { IDevice } from "../device.interface"
1
+ import type { IDevice } from "../device.interface.js"
2
2
 
3
3
  /**
4
- * Interface representing the Tindeq Progressor device.
4
+ * Interface representing the Tindeq Progressor device, extending the base Device interface.
5
5
  */
6
6
  export interface IProgressor extends IDevice {
7
7
  /**
@@ -1,6 +1,6 @@
1
- import type { IDevice } from "../device.interface"
1
+ import type { IDevice } from "../device.interface.js"
2
2
  /**
3
- * Interface representing the Weiheng WH-C06 device.
3
+ * Interface representing the Weiheng WH-C06 device, extending the base Device interface.
4
4
  */
5
5
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
6
6
  export interface IWHC06 extends IDevice {}
@@ -1,6 +1,6 @@
1
- import type { IBase } from "./base.interface"
2
- import type { massObject } from "./callback.interface"
3
- import type { Commands } from "./command.interface"
1
+ import type { IBase } from "./base.interface.js"
2
+ import type { massObject } from "./callback.interface.js"
3
+ import type { Commands } from "./command.interface.js"
4
4
 
5
5
  /**
6
6
  * Represents a characteristic of a Bluetooth service.
@@ -1,4 +1,4 @@
1
- import type { IBase } from "../interfaces/base.interface"
1
+ import type { IBase } from "../interfaces/base.interface.js"
2
2
 
3
3
  export abstract class BaseModel {
4
4
  id?: string
@@ -1,9 +1,10 @@
1
- import { Device } from "../device.model"
2
- import type { IClimbro } from "../../interfaces/device/climbro.interface"
1
+ import { Device } from "../device.model.js"
2
+ import type { IClimbro } from "../../interfaces/device/climbro.interface.js"
3
3
 
4
4
  /**
5
- * Represents a Climbro device
5
+ * Represents a Climbro device.
6
6
  * TODO: Add services, do you own a Climbro? Help us!
7
+ * {@link https://climbro.com/}
7
8
  */
8
9
  export class Climbro extends Device implements IClimbro {
9
10
  constructor() {
@@ -1,6 +1,10 @@
1
- import { Device } from "../device.model"
2
- import type { IEntralpi } from "../../interfaces/device/entralpi.interface"
1
+ import { Device } from "../device.model.js"
2
+ import type { IEntralpi } from "../../interfaces/device/entralpi.interface.js"
3
3
 
4
+ /**
5
+ * Represents a Entralpi device.
6
+ * {@link https://entralpi.com}
7
+ */
4
8
  export class Entralpi extends Device implements IEntralpi {
5
9
  constructor() {
6
10
  super({
@@ -1,8 +1,9 @@
1
- import { Device } from "../device.model"
2
- import type { IForceBoard } from "../../interfaces/device/forceboard.interface"
1
+ import { Device } from "../device.model.js"
2
+ import type { IForceBoard } from "../../interfaces/device/forceboard.interface.js"
3
3
 
4
4
  /**
5
- * Represents a PitchSix Force Board device
5
+ * Represents a PitchSix Force Board device.
6
+ * {@link https://pitchsix.com}
6
7
  */
7
8
  export class ForceBoard extends Device implements IForceBoard {
8
9
  constructor() {
@@ -1,5 +1,5 @@
1
- import { Device } from "../device.model"
2
- import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface"
1
+ import { Device } from "../device.model.js"
2
+ import type { IKilterBoard } from "../../interfaces/device/kilterboard.interface.js"
3
3
 
4
4
  /**
5
5
  * For API level 2 and API level 3.
@@ -67,8 +67,9 @@ export const KilterBoardPlacementRoles = [
67
67
  ]
68
68
 
69
69
  /**
70
- * Represents a Aurora Climbing device
70
+ * Represents a Aurora Climbing device.
71
71
  * Kilter Board, Tension Board, Decoy Board, Touchstone Board, Grasshopper Board, Aurora Board, So iLL Board
72
+ * {@link https://auroraclimbing.com}
72
73
  */
73
74
  export class KilterBoard extends Device implements IKilterBoard {
74
75
  /**
@@ -1,9 +1,10 @@
1
- import { Device } from "../device.model"
2
- import type { IMotherboard } from "../../interfaces/device/motherboard.interface"
3
- import type { DownloadPacket } from "../../interfaces/download.interface"
1
+ import { Device } from "../device.model.js"
2
+ import type { IMotherboard } from "../../interfaces/device/motherboard.interface.js"
3
+ import type { DownloadPacket } from "../../interfaces/download.interface.js"
4
4
 
5
5
  /**
6
- * Represents a Griptonite Motherboard device
6
+ * Represents a Griptonite Motherboard device.
7
+ * {@link https://griptonite.io}
7
8
  */
8
9
  export class Motherboard extends Device implements IMotherboard {
9
10
  /**
@@ -1,9 +1,10 @@
1
- import { Device } from "../device.model"
2
- import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface"
1
+ import { Device } from "../device.model.js"
2
+ import type { ImySmartBoard } from "../../interfaces/device/mysmartboard.interface.js"
3
3
 
4
4
  /**
5
- * Represents a mySmartBoard device
5
+ * Represents a Smartboard Climbing mySmartBoard device.
6
6
  * TODO: Add services, do you own a mySmartBoard? Help us!
7
+ * {@link https://www.smartboard-climbing.com}
7
8
  */
8
9
  export class mySmartBoard extends Device implements ImySmartBoard {
9
10
  constructor() {
@@ -1,8 +1,9 @@
1
- import { Device } from "../device.model"
2
- import type { IProgressor } from "../../interfaces/device/progressor.interface"
1
+ import { Device } from "../device.model.js"
2
+ import type { IProgressor } from "../../interfaces/device/progressor.interface.js"
3
3
 
4
4
  /**
5
- * Represents the possible responses of a Tindeq Progressor device.
5
+ * Represents a Tindeq Progressor device.
6
+ * {@link https://tindeq.com}
6
7
  */
7
8
  enum ProgressorResponses {
8
9
  /**
@@ -37,7 +38,7 @@ enum ProgressorResponses {
37
38
  }
38
39
 
39
40
  /**
40
- * Represents a Tindeq Progressor device
41
+ * Represents a Tindeq Progressor device.
41
42
  */
42
43
  export class Progressor extends Device implements IProgressor {
43
44
  constructor() {
@@ -1,9 +1,11 @@
1
- import { Device } from "../device.model"
2
- import type { IWHC06 } from "../../interfaces/device/wh-c06.interface"
1
+ import { Device } from "../device.model.js"
2
+ import type { IWHC06 } from "../../interfaces/device/wh-c06.interface.js"
3
3
 
4
4
  /**
5
- * Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device
6
- * Enable 'Experimental Web Platform features' Chrome Flags.
5
+ * Represents a Weiheng - WH-C06 (or MAT Muscle Meter) device.
6
+ * To use this device enable: `chrome://flags/#enable-experimental-web-platform-features`.
7
+ * {@link https://googlechrome.github.io/samples/web-bluetooth/scan.html| Web Bluetooth}
8
+ * {@link https://weihengmanufacturer.com}
7
9
  */
8
10
  export class WHC06 extends Device implements IWHC06 {
9
11
  /**
@@ -29,7 +31,7 @@ export class WHC06 extends Device implements IWHC06 {
29
31
  * @type {number|null}
30
32
  * @private
31
33
  */
32
- private advertisementTimeout: number | null = null
34
+ private advertisementTimeout: ReturnType<typeof setTimeout> | null = null
33
35
 
34
36
  /**
35
37
  * The limit in seconds when timeout is triggered
@@ -78,7 +80,9 @@ export class WHC06 extends Device implements IWHC06 {
78
80
  (filter) => filter.manufacturerData?.map((data) => data.companyIdentifier) || [],
79
81
  )
80
82
 
81
- this.bluetooth = await navigator.bluetooth.requestDevice({
83
+ const bluetooth = await this.getBluetooth()
84
+
85
+ this.bluetooth = await bluetooth.requestDevice({
82
86
  filters: this.filters,
83
87
  optionalManufacturerData,
84
88
  })
@@ -1,8 +1,8 @@
1
- import { BaseModel } from "./../models/base.model"
2
- import type { IDevice, Service } from "../interfaces/device.interface"
3
- import type { ActiveCallback, massObject, NotifyCallback, WriteCallback } from "../interfaces/callback.interface"
4
- import type { DownloadPacket } from "../interfaces/download.interface"
5
- import type { Commands } from "../interfaces/command.interface"
1
+ import { BaseModel } from "./../models/base.model.js"
2
+ import type { IDevice, Service } from "../interfaces/device.interface.js"
3
+ import type { ActiveCallback, massObject, NotifyCallback, WriteCallback } from "../interfaces/callback.interface.js"
4
+ import type { DownloadPacket } from "../interfaces/download.interface.js"
5
+ import type { Commands } from "../interfaces/command.interface.js"
6
6
 
7
7
  export abstract class Device extends BaseModel implements IDevice {
8
8
  /**
@@ -275,13 +275,12 @@ export abstract class Device extends BaseModel implements IDevice {
275
275
  onError: (error: Error) => void = (error) => console.error(error),
276
276
  ): Promise<void> => {
277
277
  try {
278
- if (typeof navigator === "undefined" || !("bluetooth" in navigator)) {
279
- throw new Error("Web Bluetooth API not supported in this environment.")
280
- }
281
278
  // Request device and set up connection
282
279
  const deviceServices = this.getAllServiceUUIDs()
283
280
 
284
- this.bluetooth = await navigator.bluetooth.requestDevice({
281
+ const bluetooth = await this.getBluetooth()
282
+
283
+ this.bluetooth = await bluetooth.requestDevice({
285
284
  filters: this.filters,
286
285
  optionalServices: deviceServices,
287
286
  })
@@ -492,6 +491,23 @@ export abstract class Device extends BaseModel implements IDevice {
492
491
  return this.services.filter((service) => service?.uuid).map((service) => service.uuid)
493
492
  }
494
493
 
494
+ /**
495
+ * Attempt to use ES module import rather than require.
496
+ * This approach uses an async dynamic import for `webbluetooth`,
497
+ * so we can fallback if `navigator.bluetooth` is unavailable.
498
+ */
499
+ protected async getBluetooth() {
500
+ // If we're in a browser with real Web Bluetooth available:
501
+ if (typeof navigator !== "undefined" && "bluetooth" in navigator) {
502
+ return navigator.bluetooth
503
+ }
504
+
505
+ // Otherwise, we're likely in Node or an environment without `navigator.bluetooth`.
506
+ // Use a dynamic import for the ESM version:
507
+ const { bluetooth } = await import("webbluetooth")
508
+ return bluetooth
509
+ }
510
+
495
511
  /**
496
512
  * Retrieves the characteristic from the device's service.
497
513
  * @param {string} serviceId - The UUID of the service.
@@ -1,17 +1,15 @@
1
- // @ts-types="npm:@types/web-bluetooth@^0.0.20"
1
+ export { Climbro } from "./device/climbro.model.js"
2
2
 
3
- export { Climbro } from "./device/climbro.model"
3
+ export { Entralpi } from "./device/entralpi.model.js"
4
4
 
5
- export { Entralpi } from "./device/entralpi.model"
5
+ export { ForceBoard } from "./device/forceboard.model.js"
6
6
 
7
- export { ForceBoard } from "./device/forceboard.model"
7
+ export { KilterBoard } from "./device/kilterboard.model.js"
8
8
 
9
- export { KilterBoard } from "./device/kilterboard.model"
9
+ export { Motherboard } from "./device/motherboard.model.js"
10
10
 
11
- export { Motherboard } from "./device/motherboard.model"
11
+ export { mySmartBoard } from "./device/mysmartboard.model.js"
12
12
 
13
- export { mySmartBoard } from "./device/mysmartboard.model"
13
+ export { Progressor } from "./device/progressor.model.js"
14
14
 
15
- export { Progressor } from "./device/progressor.model"
16
-
17
- export { WHC06 } from "./device/wh-c06.model"
15
+ export { WHC06 } from "./device/wh-c06.model.js"