refactor: switch to using Bun (#718)
This commit is contained in:
@@ -1,16 +1,14 @@
|
||||
{
|
||||
"name": "@meshtastic/transport-web-bluetooth",
|
||||
"version": "0.1.2",
|
||||
"description": "A transport layer for Meshtastic applications using Web Bluetooth.",
|
||||
"exports": {
|
||||
".": "./mod.ts"
|
||||
},
|
||||
"imports": {
|
||||
"@types/web-bluetooth": "npm:@types/web-bluetooth@^0.0.20"
|
||||
},
|
||||
"compilerOptions": {
|
||||
"types": [
|
||||
"@types/web-bluetooth"
|
||||
]
|
||||
}
|
||||
"name": "@meshtastic/transport-web-bluetooth",
|
||||
"version": "0.1.2",
|
||||
"description": "A transport layer for Meshtastic applications using Web Bluetooth.",
|
||||
"exports": {
|
||||
".": "./mod.ts"
|
||||
},
|
||||
"imports": {
|
||||
"@types/web-bluetooth": "npm:@types/web-bluetooth@^0.0.20"
|
||||
},
|
||||
"compilerOptions": {
|
||||
"types": ["@types/web-bluetooth"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,134 +1,133 @@
|
||||
import type { Types } from "@meshtastic/core";
|
||||
|
||||
export class TransportWebBluetooth implements Types.Transport {
|
||||
private _toDevice: WritableStream<Uint8Array>;
|
||||
private _fromDevice: ReadableStream<Types.DeviceOutput>;
|
||||
private _fromDeviceController?: ReadableStreamDefaultController<
|
||||
Types.DeviceOutput
|
||||
>;
|
||||
private _isFirstWrite = true;
|
||||
private _toDevice: WritableStream<Uint8Array>;
|
||||
private _fromDevice: ReadableStream<Types.DeviceOutput>;
|
||||
private _fromDeviceController?: ReadableStreamDefaultController<Types.DeviceOutput>;
|
||||
private _isFirstWrite = true;
|
||||
|
||||
private toRadioCharacteristic: BluetoothRemoteGATTCharacteristic;
|
||||
private fromRadioCharacteristic: BluetoothRemoteGATTCharacteristic;
|
||||
private fromNumCharacteristic: BluetoothRemoteGATTCharacteristic;
|
||||
private toRadioCharacteristic: BluetoothRemoteGATTCharacteristic;
|
||||
private fromRadioCharacteristic: BluetoothRemoteGATTCharacteristic;
|
||||
private fromNumCharacteristic: BluetoothRemoteGATTCharacteristic;
|
||||
|
||||
static ToRadioUuid = "f75c76d2-129e-4dad-a1dd-7866124401e7";
|
||||
static FromRadioUuid = "2c55e69e-4993-11ed-b878-0242ac120002";
|
||||
static FromNumUuid = "ed9da18c-a800-4f66-a670-aa7547e34453";
|
||||
static ServiceUuid = "6ba1b218-15a8-461f-9fa8-5dcae273eafd";
|
||||
static ToRadioUuid = "f75c76d2-129e-4dad-a1dd-7866124401e7";
|
||||
static FromRadioUuid = "2c55e69e-4993-11ed-b878-0242ac120002";
|
||||
static FromNumUuid = "ed9da18c-a800-4f66-a670-aa7547e34453";
|
||||
static ServiceUuid = "6ba1b218-15a8-461f-9fa8-5dcae273eafd";
|
||||
|
||||
public static async create(): Promise<TransportWebBluetooth> {
|
||||
const device = await navigator.bluetooth.requestDevice({
|
||||
filters: [{ services: [this.ServiceUuid] }],
|
||||
});
|
||||
return await this.prepareConnection(device);
|
||||
}
|
||||
public static async create(): Promise<TransportWebBluetooth> {
|
||||
const device = await navigator.bluetooth.requestDevice({
|
||||
filters: [{ services: [this.ServiceUuid] }],
|
||||
});
|
||||
return await this.prepareConnection(device);
|
||||
}
|
||||
|
||||
public static async createFromDevice(
|
||||
device: BluetoothDevice,
|
||||
): Promise<TransportWebBluetooth> {
|
||||
return await this.prepareConnection(device);
|
||||
}
|
||||
public static async createFromDevice(
|
||||
device: BluetoothDevice,
|
||||
): Promise<TransportWebBluetooth> {
|
||||
return await this.prepareConnection(device);
|
||||
}
|
||||
|
||||
public static async prepareConnection(
|
||||
device: BluetoothDevice,
|
||||
): Promise<TransportWebBluetooth> {
|
||||
const gattServer = await device.gatt?.connect();
|
||||
public static async prepareConnection(
|
||||
device: BluetoothDevice,
|
||||
): Promise<TransportWebBluetooth> {
|
||||
const gattServer = await device.gatt?.connect();
|
||||
|
||||
if (!gattServer) {
|
||||
throw new Error("Failed to connect to GATT server");
|
||||
}
|
||||
if (!gattServer) {
|
||||
throw new Error("Failed to connect to GATT server");
|
||||
}
|
||||
|
||||
const service = await gattServer.getPrimaryService(this.ServiceUuid);
|
||||
const service = await gattServer.getPrimaryService(this.ServiceUuid);
|
||||
|
||||
const toRadioCharacteristic = await service.getCharacteristic(
|
||||
this.ToRadioUuid,
|
||||
);
|
||||
const fromRadioCharacteristic = await service.getCharacteristic(
|
||||
this.FromRadioUuid,
|
||||
);
|
||||
const fromNumCharacteristic = await service.getCharacteristic(
|
||||
this.FromNumUuid,
|
||||
);
|
||||
const toRadioCharacteristic = await service.getCharacteristic(
|
||||
this.ToRadioUuid,
|
||||
);
|
||||
const fromRadioCharacteristic = await service.getCharacteristic(
|
||||
this.FromRadioUuid,
|
||||
);
|
||||
const fromNumCharacteristic = await service.getCharacteristic(
|
||||
this.FromNumUuid,
|
||||
);
|
||||
|
||||
if (
|
||||
!toRadioCharacteristic || !fromRadioCharacteristic ||
|
||||
!fromNumCharacteristic
|
||||
) {
|
||||
throw new Error("Failed to find required characteristics");
|
||||
}
|
||||
if (
|
||||
!toRadioCharacteristic ||
|
||||
!fromRadioCharacteristic ||
|
||||
!fromNumCharacteristic
|
||||
) {
|
||||
throw new Error("Failed to find required characteristics");
|
||||
}
|
||||
|
||||
console.log("Connected to device", device.name);
|
||||
console.log("Connected to device", device.name);
|
||||
|
||||
return new TransportWebBluetooth(
|
||||
toRadioCharacteristic,
|
||||
fromRadioCharacteristic,
|
||||
fromNumCharacteristic,
|
||||
);
|
||||
}
|
||||
return new TransportWebBluetooth(
|
||||
toRadioCharacteristic,
|
||||
fromRadioCharacteristic,
|
||||
fromNumCharacteristic,
|
||||
);
|
||||
}
|
||||
|
||||
constructor(
|
||||
toRadioCharacteristic: BluetoothRemoteGATTCharacteristic,
|
||||
fromRadioCharacteristic: BluetoothRemoteGATTCharacteristic,
|
||||
fromNumCharacteristic: BluetoothRemoteGATTCharacteristic,
|
||||
) {
|
||||
this.toRadioCharacteristic = toRadioCharacteristic;
|
||||
this.fromRadioCharacteristic = fromRadioCharacteristic;
|
||||
this.fromNumCharacteristic = fromNumCharacteristic;
|
||||
constructor(
|
||||
toRadioCharacteristic: BluetoothRemoteGATTCharacteristic,
|
||||
fromRadioCharacteristic: BluetoothRemoteGATTCharacteristic,
|
||||
fromNumCharacteristic: BluetoothRemoteGATTCharacteristic,
|
||||
) {
|
||||
this.toRadioCharacteristic = toRadioCharacteristic;
|
||||
this.fromRadioCharacteristic = fromRadioCharacteristic;
|
||||
this.fromNumCharacteristic = fromNumCharacteristic;
|
||||
|
||||
this._fromDevice = new ReadableStream({
|
||||
start: (ctrl) => {
|
||||
this._fromDeviceController = ctrl;
|
||||
},
|
||||
});
|
||||
this._fromDevice = new ReadableStream({
|
||||
start: (ctrl) => {
|
||||
this._fromDeviceController = ctrl;
|
||||
},
|
||||
});
|
||||
|
||||
this._toDevice = new WritableStream({
|
||||
write: async (chunk) => {
|
||||
await this.toRadioCharacteristic.writeValue(chunk);
|
||||
this._toDevice = new WritableStream({
|
||||
write: async (chunk) => {
|
||||
await this.toRadioCharacteristic.writeValue(chunk);
|
||||
|
||||
if (this._isFirstWrite && this._fromDeviceController) {
|
||||
this._isFirstWrite = false;
|
||||
setTimeout(() => {
|
||||
this.readFromRadio(this._fromDeviceController!);
|
||||
}, 50);
|
||||
}
|
||||
},
|
||||
});
|
||||
if (this._isFirstWrite && this._fromDeviceController) {
|
||||
this._isFirstWrite = false;
|
||||
setTimeout(() => {
|
||||
this.readFromRadio(this._fromDeviceController!);
|
||||
}, 50);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
this.fromNumCharacteristic.addEventListener(
|
||||
"characteristicvaluechanged",
|
||||
() => {
|
||||
if (this._fromDeviceController) {
|
||||
this.readFromRadio(this._fromDeviceController);
|
||||
}
|
||||
},
|
||||
);
|
||||
this.fromNumCharacteristic.addEventListener(
|
||||
"characteristicvaluechanged",
|
||||
() => {
|
||||
if (this._fromDeviceController) {
|
||||
this.readFromRadio(this._fromDeviceController);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
this.fromNumCharacteristic.startNotifications();
|
||||
}
|
||||
this.fromNumCharacteristic.startNotifications();
|
||||
}
|
||||
|
||||
get toDevice(): WritableStream<Uint8Array> {
|
||||
return this._toDevice;
|
||||
}
|
||||
get toDevice(): WritableStream<Uint8Array> {
|
||||
return this._toDevice;
|
||||
}
|
||||
|
||||
get fromDevice(): ReadableStream<Types.DeviceOutput> {
|
||||
return this._fromDevice;
|
||||
}
|
||||
get fromDevice(): ReadableStream<Types.DeviceOutput> {
|
||||
return this._fromDevice;
|
||||
}
|
||||
|
||||
protected async readFromRadio(
|
||||
controller: ReadableStreamDefaultController<Types.DeviceOutput>,
|
||||
): Promise<void> {
|
||||
let hasMoreData = true;
|
||||
while (hasMoreData && this.fromRadioCharacteristic) {
|
||||
const value = await this.fromRadioCharacteristic.readValue();
|
||||
if (value.byteLength === 0) {
|
||||
hasMoreData = false;
|
||||
continue;
|
||||
}
|
||||
controller.enqueue({
|
||||
type: "packet",
|
||||
data: new Uint8Array(value.buffer),
|
||||
});
|
||||
}
|
||||
}
|
||||
protected async readFromRadio(
|
||||
controller: ReadableStreamDefaultController<Types.DeviceOutput>,
|
||||
): Promise<void> {
|
||||
let hasMoreData = true;
|
||||
while (hasMoreData && this.fromRadioCharacteristic) {
|
||||
const value = await this.fromRadioCharacteristic.readValue();
|
||||
if (value.byteLength === 0) {
|
||||
hasMoreData = false;
|
||||
continue;
|
||||
}
|
||||
controller.enqueue({
|
||||
type: "packet",
|
||||
data: new Uint8Array(value.buffer),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user