@dg-kit/transport-webbluetooth 1.11.0 → 1.13.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.
- package/dist/aux-device-connect.d.ts +51 -0
- package/dist/aux-device-connect.d.ts.map +1 -0
- package/dist/aux-device-connect.js +106 -0
- package/dist/aux-device-connect.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/opossum-client.d.ts +37 -0
- package/dist/opossum-client.d.ts.map +1 -0
- package/dist/opossum-client.js +66 -0
- package/dist/opossum-client.js.map +1 -0
- package/dist/request-device-options.d.ts +18 -0
- package/dist/request-device-options.d.ts.map +1 -0
- package/dist/request-device-options.js +27 -0
- package/dist/request-device-options.js.map +1 -0
- package/dist/sensor-client.d.ts +52 -0
- package/dist/sensor-client.d.ts.map +1 -0
- package/dist/sensor-client.js +93 -0
- package/dist/sensor-client.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type BluetoothDeviceLike, type BluetoothRemoteGATTServerLike, type GattReadyRetryOptions, type NavigatorBluetoothLike, type RequestDeviceOptionsLike, type WebBluetoothConnectionContext } from '@dg-kit/protocol';
|
|
2
|
+
/** Minimal shape both `OpossumVibrateAdapter` and the sensor adapters satisfy. */
|
|
3
|
+
export interface ConnectableAdapter {
|
|
4
|
+
onConnected(context: WebBluetoothConnectionContext): Promise<void>;
|
|
5
|
+
onDisconnected(): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export interface AuxDeviceConnectOptions {
|
|
8
|
+
navigatorRef?: NavigatorBluetoothLike;
|
|
9
|
+
requestDeviceOptions: RequestDeviceOptionsLike;
|
|
10
|
+
/**
|
|
11
|
+
* Tuning for the GATT-not-ready retry wrapped around `adapter.onConnected()`
|
|
12
|
+
* — see `runWithGattReadyRetry`'s doc (`@dg-kit/protocol`). These three
|
|
13
|
+
* device kinds share the exact same GATT skeleton as Coyote, so they hit
|
|
14
|
+
* the identical "gatt.connect() resolves before service discovery"
|
|
15
|
+
* Web Bluetooth race. Defaults are fine for normal use; exposed mainly for
|
|
16
|
+
* tests.
|
|
17
|
+
*/
|
|
18
|
+
gattReadyRetryOptions?: GattReadyRetryOptions;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Opens the Bluetooth chooser scoped to `options.requestDeviceOptions`,
|
|
22
|
+
* connects GATT, and hands the connection to `adapter.onConnected()`.
|
|
23
|
+
* Mirrors `WebBluetoothDeviceClient.connect()`'s "replace the previous
|
|
24
|
+
* device only after the new one succeeds" ordering, minus the reconnect
|
|
25
|
+
* bookkeeping that client also carries.
|
|
26
|
+
*
|
|
27
|
+
* Returns the newly connected device; the caller is responsible for storing
|
|
28
|
+
* it and passing it back in on the next call (as `previousDevice`) and to
|
|
29
|
+
* `disconnectAuxDevice`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function connectAuxDevice(options: AuxDeviceConnectOptions, adapter: ConnectableAdapter, previousDevice: BluetoothDeviceLike | null, onGattDisconnected: (event: Event) => void): Promise<BluetoothDeviceLike>;
|
|
32
|
+
/**
|
|
33
|
+
* Attaches to an already-obtained `(device, server)` pair instead of
|
|
34
|
+
* running this helper's own `bluetooth.requestDevice()` chooser prompt —
|
|
35
|
+
* the aux-device counterpart to `WebBluetoothDeviceClient.connectDevice()`.
|
|
36
|
+
* Lets a caller that already ran ONE shared chooser scoped to every DG-Lab
|
|
37
|
+
* device kind (see `requestDgLabDevice()`) and identified the picked
|
|
38
|
+
* device's kind via `detectDeviceKind()` hand it straight to the matching
|
|
39
|
+
* client, instead of needing a second, kind-scoped chooser prompt.
|
|
40
|
+
* `gatt.connect()` must already have been called by the caller; this only
|
|
41
|
+
* runs the adapter handshake and the same replace-previous-device
|
|
42
|
+
* bookkeeping `connectAuxDevice()` does.
|
|
43
|
+
*/
|
|
44
|
+
export declare function attachAuxDevice(nextDevice: BluetoothDeviceLike, server: BluetoothRemoteGATTServerLike, adapter: ConnectableAdapter, previousDevice: BluetoothDeviceLike | null, onGattDisconnected: (event: Event) => void, gattReadyRetryOptions?: GattReadyRetryOptions): Promise<BluetoothDeviceLike>;
|
|
45
|
+
/**
|
|
46
|
+
* User-initiated disconnect: removes the listener BEFORE calling
|
|
47
|
+
* `gatt.disconnect()` so the resulting `gattserverdisconnected` event never
|
|
48
|
+
* reaches `onGattDisconnected` a second time.
|
|
49
|
+
*/
|
|
50
|
+
export declare function disconnectAuxDevice(device: BluetoothDeviceLike | null, adapter: ConnectableAdapter, onGattDisconnected: (event: Event) => void): Promise<void>;
|
|
51
|
+
//# sourceMappingURL=aux-device-connect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aux-device-connect.d.ts","sourceRoot":"","sources":["../src/aux-device-connect.ts"],"names":[],"mappings":"AAcA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,6BAA6B,EAClC,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,6BAA6B,EACnC,MAAM,kBAAkB,CAAC;AAE1B,kFAAkF;AAClF,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,OAAO,EAAE,6BAA6B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,uBAAuB;IACtC,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,oBAAoB,EAAE,wBAAwB,CAAC;IAC/C;;;;;;;OAOG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;CAC/C;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,uBAAuB,EAChC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,mBAAmB,GAAG,IAAI,EAC1C,kBAAkB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GACzC,OAAO,CAAC,mBAAmB,CAAC,CAgC9B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,mBAAmB,EAC/B,MAAM,EAAE,6BAA6B,EACrC,OAAO,EAAE,kBAAkB,EAC3B,cAAc,EAAE,mBAAmB,GAAG,IAAI,EAC1C,kBAAkB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EAC1C,qBAAqB,CAAC,EAAE,qBAAqB,GAC5C,OAAO,CAAC,mBAAmB,CAAC,CA8B9B;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,mBAAmB,GAAG,IAAI,EAClC,OAAO,EAAE,kBAAkB,EAC3B,kBAAkB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GACzC,OAAO,CAAC,IAAI,CAAC,CAQf"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared connect/disconnect bookkeeping for the three "auxiliary" device
|
|
3
|
+
* kinds (opossum, paw-prints, civet-edging), factored out so
|
|
4
|
+
* `WebBluetoothOpossumClient`/`WebBluetoothSensorClient` don't each
|
|
5
|
+
* reimplement the same requestDevice → gatt.connect → adapter.onConnected →
|
|
6
|
+
* listener-wiring dance.
|
|
7
|
+
*
|
|
8
|
+
* Deliberately does NOT replicate `WebBluetoothDeviceClient`'s
|
|
9
|
+
* `autoReconnect` option — none of the three new device kinds need it (see
|
|
10
|
+
* the `OpossumClient`/`SensorDeviceClient` contracts, which only require
|
|
11
|
+
* connect/disconnect/state, no reconnect semantics), and skipping it keeps
|
|
12
|
+
* this helper — and the two clients built on it — simple.
|
|
13
|
+
*/
|
|
14
|
+
import { getWebBluetoothAvailability } from './availability.js';
|
|
15
|
+
import { runWithGattReadyRetry, } from '@dg-kit/protocol';
|
|
16
|
+
/**
|
|
17
|
+
* Opens the Bluetooth chooser scoped to `options.requestDeviceOptions`,
|
|
18
|
+
* connects GATT, and hands the connection to `adapter.onConnected()`.
|
|
19
|
+
* Mirrors `WebBluetoothDeviceClient.connect()`'s "replace the previous
|
|
20
|
+
* device only after the new one succeeds" ordering, minus the reconnect
|
|
21
|
+
* bookkeeping that client also carries.
|
|
22
|
+
*
|
|
23
|
+
* Returns the newly connected device; the caller is responsible for storing
|
|
24
|
+
* it and passing it back in on the next call (as `previousDevice`) and to
|
|
25
|
+
* `disconnectAuxDevice`.
|
|
26
|
+
*/
|
|
27
|
+
export async function connectAuxDevice(options, adapter, previousDevice, onGattDisconnected) {
|
|
28
|
+
const nav = options.navigatorRef ??
|
|
29
|
+
(typeof navigator === 'undefined'
|
|
30
|
+
? undefined
|
|
31
|
+
: navigator);
|
|
32
|
+
const availability = getWebBluetoothAvailability(nav);
|
|
33
|
+
if (!availability.supported) {
|
|
34
|
+
throw new Error(availability.reason);
|
|
35
|
+
}
|
|
36
|
+
const bluetooth = nav?.bluetooth;
|
|
37
|
+
if (!bluetooth) {
|
|
38
|
+
throw new Error('当前环境不支持 Web Bluetooth');
|
|
39
|
+
}
|
|
40
|
+
const nextDevice = await bluetooth.requestDevice(options.requestDeviceOptions);
|
|
41
|
+
const gatt = nextDevice.gatt;
|
|
42
|
+
if (!gatt) {
|
|
43
|
+
throw new Error('所选蓝牙设备不支持 GATT');
|
|
44
|
+
}
|
|
45
|
+
const server = await gatt.connect();
|
|
46
|
+
return attachAuxDevice(nextDevice, server, adapter, previousDevice, onGattDisconnected, options.gattReadyRetryOptions);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Attaches to an already-obtained `(device, server)` pair instead of
|
|
50
|
+
* running this helper's own `bluetooth.requestDevice()` chooser prompt —
|
|
51
|
+
* the aux-device counterpart to `WebBluetoothDeviceClient.connectDevice()`.
|
|
52
|
+
* Lets a caller that already ran ONE shared chooser scoped to every DG-Lab
|
|
53
|
+
* device kind (see `requestDgLabDevice()`) and identified the picked
|
|
54
|
+
* device's kind via `detectDeviceKind()` hand it straight to the matching
|
|
55
|
+
* client, instead of needing a second, kind-scoped chooser prompt.
|
|
56
|
+
* `gatt.connect()` must already have been called by the caller; this only
|
|
57
|
+
* runs the adapter handshake and the same replace-previous-device
|
|
58
|
+
* bookkeeping `connectAuxDevice()` does.
|
|
59
|
+
*/
|
|
60
|
+
export async function attachAuxDevice(nextDevice, server, adapter, previousDevice, onGattDisconnected, gattReadyRetryOptions) {
|
|
61
|
+
const gatt = nextDevice.gatt;
|
|
62
|
+
const shouldReplacePrevious = !!previousDevice && previousDevice !== nextDevice;
|
|
63
|
+
if (shouldReplacePrevious) {
|
|
64
|
+
previousDevice.removeEventListener('gattserverdisconnected', onGattDisconnected);
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
await runWithGattReadyRetry(() => adapter.onConnected({ device: nextDevice, server }), gattReadyRetryOptions ?? {});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (shouldReplacePrevious && isGattConnected(previousDevice)) {
|
|
71
|
+
previousDevice.addEventListener('gattserverdisconnected', onGattDisconnected);
|
|
72
|
+
}
|
|
73
|
+
if (gatt?.connected) {
|
|
74
|
+
gatt.disconnect();
|
|
75
|
+
}
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
nextDevice.addEventListener('gattserverdisconnected', onGattDisconnected);
|
|
79
|
+
if (shouldReplacePrevious) {
|
|
80
|
+
disconnectDeviceGatt(previousDevice);
|
|
81
|
+
}
|
|
82
|
+
return nextDevice;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* User-initiated disconnect: removes the listener BEFORE calling
|
|
86
|
+
* `gatt.disconnect()` so the resulting `gattserverdisconnected` event never
|
|
87
|
+
* reaches `onGattDisconnected` a second time.
|
|
88
|
+
*/
|
|
89
|
+
export async function disconnectAuxDevice(device, adapter, onGattDisconnected) {
|
|
90
|
+
if (device) {
|
|
91
|
+
device.removeEventListener('gattserverdisconnected', onGattDisconnected);
|
|
92
|
+
if (device.gatt?.connected) {
|
|
93
|
+
device.gatt.disconnect();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
await adapter.onDisconnected();
|
|
97
|
+
}
|
|
98
|
+
function isGattConnected(device) {
|
|
99
|
+
return !!device?.gatt?.connected;
|
|
100
|
+
}
|
|
101
|
+
function disconnectDeviceGatt(device) {
|
|
102
|
+
if (!device?.gatt?.connected)
|
|
103
|
+
return;
|
|
104
|
+
device.gatt.disconnect();
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=aux-device-connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aux-device-connect.js","sourceRoot":"","sources":["../src/aux-device-connect.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export { getWebBluetoothAvailability } from './availability.js';
|
|
2
2
|
export { WebBluetoothDeviceClient, type WebBluetoothDeviceClientOptions, type ReconnectState, } from './client.js';
|
|
3
3
|
export { requestDgLabDevice, type RequestDgLabDeviceOptions, type RequestedDgLabDevice, } from './picker.js';
|
|
4
|
+
export { WebBluetoothOpossumClient, type WebBluetoothOpossumClientOptions, } from './opossum-client.js';
|
|
5
|
+
export { WebBluetoothSensorClient, WebBluetoothPawPrintsClient, WebBluetoothCivetEdgingClient, type WebBluetoothSensorClientOptions, type WebBluetoothAuxSensorClientOptions, } from './sensor-client.js';
|
|
6
|
+
export { connectAuxDevice, attachAuxDevice, disconnectAuxDevice, type ConnectableAdapter, type AuxDeviceConnectOptions, } from './aux-device-connect.js';
|
|
7
|
+
export { PAW_PRINTS_REQUEST_DEVICE_OPTIONS, CIVET_EDGING_REQUEST_DEVICE_OPTIONS, OPOSSUM_REQUEST_DEVICE_OPTIONS, } from './request-device-options.js';
|
|
4
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACL,wBAAwB,EACxB,KAAK,+BAA+B,EACpC,KAAK,cAAc,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACL,wBAAwB,EACxB,KAAK,+BAA+B,EACpC,KAAK,cAAc,GACpB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,EACzB,KAAK,gCAAgC,GACtC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,6BAA6B,EAC7B,KAAK,+BAA+B,EACpC,KAAK,kCAAkC,GACxC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,iCAAiC,EACjC,mCAAmC,EACnC,8BAA8B,GAC/B,MAAM,6BAA6B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export { getWebBluetoothAvailability } from './availability.js';
|
|
2
2
|
export { WebBluetoothDeviceClient, } from './client.js';
|
|
3
3
|
export { requestDgLabDevice, } from './picker.js';
|
|
4
|
+
export { WebBluetoothOpossumClient, } from './opossum-client.js';
|
|
5
|
+
export { WebBluetoothSensorClient, WebBluetoothPawPrintsClient, WebBluetoothCivetEdgingClient, } from './sensor-client.js';
|
|
6
|
+
export { connectAuxDevice, attachAuxDevice, disconnectAuxDevice, } from './aux-device-connect.js';
|
|
7
|
+
export { PAW_PRINTS_REQUEST_DEVICE_OPTIONS, CIVET_EDGING_REQUEST_DEVICE_OPTIONS, OPOSSUM_REQUEST_DEVICE_OPTIONS, } from './request-device-options.js';
|
|
4
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACL,wBAAwB,GAGzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,GAGnB,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACL,wBAAwB,GAGzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,GAGnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,yBAAyB,GAE1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,6BAA6B,GAG9B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,mBAAmB,GAGpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,iCAAiC,EACjC,mCAAmC,EACnC,8BAA8B,GAC/B,MAAM,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Bluetooth-backed `OpossumClient`. Wraps `OpossumVibrateAdapter` the
|
|
3
|
+
* same way `WebBluetoothDeviceClient` wraps `CoyoteProtocolAdapter` for
|
|
4
|
+
* Coyote, minus the auto-reconnect option (see `aux-device-connect.ts`'s
|
|
5
|
+
* doc comment for why that's intentionally out of scope here).
|
|
6
|
+
*/
|
|
7
|
+
import type { OpossumCommand } from '@dg-kit/core';
|
|
8
|
+
import { type OpossumClient, type OpossumCommandResult, type OpossumState } from '@dg-kit/protocol';
|
|
9
|
+
import type { BluetoothDeviceLike, BluetoothRemoteGATTServerLike, NavigatorBluetoothLike, RequestDeviceOptionsLike } from '@dg-kit/protocol';
|
|
10
|
+
export interface WebBluetoothOpossumClientOptions {
|
|
11
|
+
navigatorRef?: NavigatorBluetoothLike;
|
|
12
|
+
/** Overrides the default opossum-only scan filter — mainly for tests. */
|
|
13
|
+
requestDeviceOptions?: RequestDeviceOptionsLike;
|
|
14
|
+
}
|
|
15
|
+
export declare class WebBluetoothOpossumClient implements OpossumClient {
|
|
16
|
+
private readonly options;
|
|
17
|
+
private readonly adapter;
|
|
18
|
+
private readonly listeners;
|
|
19
|
+
private device;
|
|
20
|
+
constructor(options?: WebBluetoothOpossumClientOptions);
|
|
21
|
+
connect(): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Attach to an already-obtained `(device, server)` pair instead of
|
|
24
|
+
* running this client's own chooser prompt — see
|
|
25
|
+
* `aux-device-connect.ts`'s `attachAuxDevice()` doc comment.
|
|
26
|
+
*/
|
|
27
|
+
connectDevice(device: BluetoothDeviceLike, server: BluetoothRemoteGATTServerLike): Promise<void>;
|
|
28
|
+
disconnect(): Promise<void>;
|
|
29
|
+
getState(): Promise<OpossumState>;
|
|
30
|
+
execute(command: OpossumCommand): Promise<OpossumCommandResult>;
|
|
31
|
+
emergencyStop(): Promise<void>;
|
|
32
|
+
setIndicatorColor(color: number): Promise<void>;
|
|
33
|
+
onStateChanged(listener: (state: OpossumState) => void): () => void;
|
|
34
|
+
private readonly handleGattDisconnected;
|
|
35
|
+
private emit;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=opossum-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opossum-client.d.ts","sourceRoot":"","sources":["../src/opossum-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,mBAAmB,EACnB,6BAA6B,EAC7B,sBAAsB,EACtB,wBAAwB,EACzB,MAAM,kBAAkB,CAAC;AAI1B,MAAM,WAAW,gCAAgC;IAC/C,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,wBAAwB,CAAC;CACjD;AAED,qBAAa,yBAA0B,YAAW,aAAa;IAKjD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;IACtE,OAAO,CAAC,MAAM,CAAoC;gBAErB,OAAO,GAAE,gCAAqC;IAIrE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAY9B;;;;OAIG;IACG,aAAa,CACjB,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,IAAI,CAAC;IAUV,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,QAAQ,IAAI,OAAO,CAAC,YAAY,CAAC;IAIjC,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAK/D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOrD,cAAc,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,MAAM,IAAI;IAOnE,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAKrC;IAEF,OAAO,CAAC,IAAI;CAKb"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { OpossumVibrateAdapter, } from '@dg-kit/protocol';
|
|
2
|
+
import { attachAuxDevice, connectAuxDevice, disconnectAuxDevice } from './aux-device-connect.js';
|
|
3
|
+
import { OPOSSUM_REQUEST_DEVICE_OPTIONS } from './request-device-options.js';
|
|
4
|
+
export class WebBluetoothOpossumClient {
|
|
5
|
+
options;
|
|
6
|
+
adapter = new OpossumVibrateAdapter();
|
|
7
|
+
listeners = new Set();
|
|
8
|
+
device = null;
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
this.adapter.onStateChanged((state) => this.emit(state));
|
|
12
|
+
}
|
|
13
|
+
async connect() {
|
|
14
|
+
this.device = await connectAuxDevice({
|
|
15
|
+
navigatorRef: this.options.navigatorRef,
|
|
16
|
+
requestDeviceOptions: this.options.requestDeviceOptions ?? OPOSSUM_REQUEST_DEVICE_OPTIONS,
|
|
17
|
+
}, this.adapter, this.device, this.handleGattDisconnected);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Attach to an already-obtained `(device, server)` pair instead of
|
|
21
|
+
* running this client's own chooser prompt — see
|
|
22
|
+
* `aux-device-connect.ts`'s `attachAuxDevice()` doc comment.
|
|
23
|
+
*/
|
|
24
|
+
async connectDevice(device, server) {
|
|
25
|
+
this.device = await attachAuxDevice(device, server, this.adapter, this.device, this.handleGattDisconnected);
|
|
26
|
+
}
|
|
27
|
+
async disconnect() {
|
|
28
|
+
const device = this.device;
|
|
29
|
+
this.device = null;
|
|
30
|
+
await disconnectAuxDevice(device, this.adapter, this.handleGattDisconnected);
|
|
31
|
+
}
|
|
32
|
+
async getState() {
|
|
33
|
+
return this.adapter.getState();
|
|
34
|
+
}
|
|
35
|
+
async execute(command) {
|
|
36
|
+
const state = await this.adapter.execute(command);
|
|
37
|
+
return { state };
|
|
38
|
+
}
|
|
39
|
+
async emergencyStop() {
|
|
40
|
+
await this.adapter.emergencyStop();
|
|
41
|
+
}
|
|
42
|
+
async setIndicatorColor(color) {
|
|
43
|
+
// enableButtonReporting stays on — a purely cosmetic color change must
|
|
44
|
+
// not silently disable the button-press notifications a caller relies
|
|
45
|
+
// on, mirroring civet-edging's setIndicatorColor() doc comment.
|
|
46
|
+
await this.adapter.setLed(color, true);
|
|
47
|
+
}
|
|
48
|
+
onStateChanged(listener) {
|
|
49
|
+
this.listeners.add(listener);
|
|
50
|
+
return () => {
|
|
51
|
+
this.listeners.delete(listener);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
handleGattDisconnected = () => {
|
|
55
|
+
const device = this.device;
|
|
56
|
+
this.device = null;
|
|
57
|
+
device?.removeEventListener('gattserverdisconnected', this.handleGattDisconnected);
|
|
58
|
+
void this.adapter.onDisconnected();
|
|
59
|
+
};
|
|
60
|
+
emit(state) {
|
|
61
|
+
for (const listener of this.listeners) {
|
|
62
|
+
listener(state);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=opossum-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opossum-client.js","sourceRoot":"","sources":["../src/opossum-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type RequestDeviceOptionsLike } from '@dg-kit/protocol';
|
|
2
|
+
/**
|
|
3
|
+
* Per-kind Web Bluetooth scan filters for the three new 47L12x-family device
|
|
4
|
+
* kinds, each scoped to just that kind's name prefix.
|
|
5
|
+
*
|
|
6
|
+
* Deliberately narrower than `@dg-kit/protocol`'s `DG_LAB_REQUEST_DEVICE_OPTIONS`
|
|
7
|
+
* (which matches every known kind in a single picker). A caller giving each
|
|
8
|
+
* kind its own dedicated connect button should use these so the chooser it
|
|
9
|
+
* opens only ever lists devices of that one kind.
|
|
10
|
+
*
|
|
11
|
+
* All four 47L12x-family kinds (Coyote V3 included) share the identical
|
|
12
|
+
* primary/battery GATT services, so only the name-prefix filter differs
|
|
13
|
+
* between these three constants.
|
|
14
|
+
*/
|
|
15
|
+
export declare const PAW_PRINTS_REQUEST_DEVICE_OPTIONS: RequestDeviceOptionsLike;
|
|
16
|
+
export declare const CIVET_EDGING_REQUEST_DEVICE_OPTIONS: RequestDeviceOptionsLike;
|
|
17
|
+
export declare const OPOSSUM_REQUEST_DEVICE_OPTIONS: RequestDeviceOptionsLike;
|
|
18
|
+
//# sourceMappingURL=request-device-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-device-options.d.ts","sourceRoot":"","sources":["../src/request-device-options.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,wBAAwB,EAC9B,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iCAAiC,EAAE,wBAG/C,CAAC;AAEF,eAAO,MAAM,mCAAmC,EAAE,wBAGjD,CAAC;AAEF,eAAO,MAAM,8BAA8B,EAAE,wBAG5C,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { CIVET_DEVICE_NAME_PREFIX, OPOSSUM_DEVICE_NAME_PREFIX, PAW_PRINTS_DEVICE_NAME_PREFIX, V3_BATTERY_SERVICE, V3_PRIMARY_SERVICE, } from '@dg-kit/protocol';
|
|
2
|
+
/**
|
|
3
|
+
* Per-kind Web Bluetooth scan filters for the three new 47L12x-family device
|
|
4
|
+
* kinds, each scoped to just that kind's name prefix.
|
|
5
|
+
*
|
|
6
|
+
* Deliberately narrower than `@dg-kit/protocol`'s `DG_LAB_REQUEST_DEVICE_OPTIONS`
|
|
7
|
+
* (which matches every known kind in a single picker). A caller giving each
|
|
8
|
+
* kind its own dedicated connect button should use these so the chooser it
|
|
9
|
+
* opens only ever lists devices of that one kind.
|
|
10
|
+
*
|
|
11
|
+
* All four 47L12x-family kinds (Coyote V3 included) share the identical
|
|
12
|
+
* primary/battery GATT services, so only the name-prefix filter differs
|
|
13
|
+
* between these three constants.
|
|
14
|
+
*/
|
|
15
|
+
export const PAW_PRINTS_REQUEST_DEVICE_OPTIONS = {
|
|
16
|
+
filters: [{ namePrefix: PAW_PRINTS_DEVICE_NAME_PREFIX }],
|
|
17
|
+
optionalServices: [V3_PRIMARY_SERVICE, V3_BATTERY_SERVICE],
|
|
18
|
+
};
|
|
19
|
+
export const CIVET_EDGING_REQUEST_DEVICE_OPTIONS = {
|
|
20
|
+
filters: [{ namePrefix: CIVET_DEVICE_NAME_PREFIX }],
|
|
21
|
+
optionalServices: [V3_PRIMARY_SERVICE, V3_BATTERY_SERVICE],
|
|
22
|
+
};
|
|
23
|
+
export const OPOSSUM_REQUEST_DEVICE_OPTIONS = {
|
|
24
|
+
filters: [{ namePrefix: OPOSSUM_DEVICE_NAME_PREFIX }],
|
|
25
|
+
optionalServices: [V3_PRIMARY_SERVICE, V3_BATTERY_SERVICE],
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=request-device-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-device-options.js","sourceRoot":"","sources":["../src/request-device-options.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,6BAA6B,EAC7B,kBAAkB,EAClB,kBAAkB,GAEnB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAA6B;IACzE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,6BAA6B,EAAE,CAAC;IACxD,gBAAgB,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;CAC3D,CAAC;AAEF,MAAM,CAAC,MAAM,mCAAmC,GAA6B;IAC3E,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,wBAAwB,EAAE,CAAC;IACnD,gBAAgB,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;CAC3D,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAA6B;IACtE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,0BAA0B,EAAE,CAAC;IACrD,gBAAgB,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;CAC3D,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Bluetooth-backed `SensorDeviceClient<TReading>`. A single generic
|
|
3
|
+
* client wraps either of `@dg-kit/protocol`'s sensor adapters
|
|
4
|
+
* (`PawPrintsSensorAdapter`, `CivetPressureSensorAdapter`) — they share the
|
|
5
|
+
* exact same `WebBluetoothSensorAdapter<TReading>` shape
|
|
6
|
+
* (onConnected/onDisconnected/getState/subscribe/onStateChanged), only their
|
|
7
|
+
* LED-setting method name differs (`setLedSolid` vs `setIndicatorColor`),
|
|
8
|
+
* which is why `setIndicatorColor` is threaded in as a constructor callback
|
|
9
|
+
* rather than called directly on the adapter.
|
|
10
|
+
*/
|
|
11
|
+
import { type CivetPressureReading, type PawPrintsReading, type WebBluetoothSensorAdapter } from '@dg-kit/protocol';
|
|
12
|
+
import type { BluetoothDeviceLike, BluetoothRemoteGATTServerLike, NavigatorBluetoothLike, RequestDeviceOptionsLike } from '@dg-kit/protocol';
|
|
13
|
+
import type { SensorState } from '@dg-kit/core';
|
|
14
|
+
import type { SensorDeviceClient } from '@dg-kit/core';
|
|
15
|
+
export interface WebBluetoothSensorClientOptions<TReading> {
|
|
16
|
+
adapter: WebBluetoothSensorAdapter<TReading>;
|
|
17
|
+
requestDeviceOptions: RequestDeviceOptionsLike;
|
|
18
|
+
navigatorRef?: NavigatorBluetoothLike;
|
|
19
|
+
setIndicatorColor: (color: number) => Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export declare class WebBluetoothSensorClient<TReading> implements SensorDeviceClient<TReading> {
|
|
22
|
+
private readonly options;
|
|
23
|
+
private readonly listeners;
|
|
24
|
+
private device;
|
|
25
|
+
constructor(options: WebBluetoothSensorClientOptions<TReading>);
|
|
26
|
+
connect(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Attach to an already-obtained `(device, server)` pair instead of
|
|
29
|
+
* running this client's own chooser prompt — see
|
|
30
|
+
* `aux-device-connect.ts`'s `attachAuxDevice()` doc comment.
|
|
31
|
+
*/
|
|
32
|
+
connectDevice(device: BluetoothDeviceLike, server: BluetoothRemoteGATTServerLike): Promise<void>;
|
|
33
|
+
disconnect(): Promise<void>;
|
|
34
|
+
getState(): Promise<SensorState>;
|
|
35
|
+
subscribe(listener: (reading: TReading) => void): () => void;
|
|
36
|
+
onStateChanged(listener: (state: SensorState) => void): () => void;
|
|
37
|
+
setIndicatorColor(color: number): Promise<void>;
|
|
38
|
+
private readonly handleGattDisconnected;
|
|
39
|
+
private emit;
|
|
40
|
+
}
|
|
41
|
+
export interface WebBluetoothAuxSensorClientOptions {
|
|
42
|
+
navigatorRef?: NavigatorBluetoothLike;
|
|
43
|
+
/** Overrides the default kind-scoped scan filter — mainly for tests. */
|
|
44
|
+
requestDeviceOptions?: RequestDeviceOptionsLike;
|
|
45
|
+
}
|
|
46
|
+
export declare class WebBluetoothPawPrintsClient extends WebBluetoothSensorClient<PawPrintsReading> {
|
|
47
|
+
constructor(options?: WebBluetoothAuxSensorClientOptions);
|
|
48
|
+
}
|
|
49
|
+
export declare class WebBluetoothCivetEdgingClient extends WebBluetoothSensorClient<CivetPressureReading> {
|
|
50
|
+
constructor(options?: WebBluetoothAuxSensorClientOptions);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=sensor-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sensor-client.d.ts","sourceRoot":"","sources":["../src/sensor-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAC/B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,mBAAmB,EACnB,6BAA6B,EAC7B,sBAAsB,EACtB,wBAAwB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAOvD,MAAM,WAAW,+BAA+B,CAAC,QAAQ;IACvD,OAAO,EAAE,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IAC7C,oBAAoB,EAAE,wBAAwB,CAAC;IAC/C,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAED,qBAAa,wBAAwB,CAAC,QAAQ,CAAE,YAAW,kBAAkB,CAAC,QAAQ,CAAC;IAIzE,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2C;IACrE,OAAO,CAAC,MAAM,CAAoC;gBAErB,OAAO,EAAE,+BAA+B,CAAC,QAAQ,CAAC;IAIzE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAY9B;;;;OAIG;IACG,aAAa,CACjB,MAAM,EAAE,mBAAmB,EAC3B,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,IAAI,CAAC;IAUV,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B,QAAQ,IAAI,OAAO,CAAC,WAAW,CAAC;IAItC,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,QAAQ,KAAK,IAAI,GAAG,MAAM,IAAI;IAI5D,cAAc,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,MAAM,IAAI;IAO5D,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAKrC;IAEF,OAAO,CAAC,IAAI;CAKb;AAED,MAAM,WAAW,kCAAkC;IACjD,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,wEAAwE;IACxE,oBAAoB,CAAC,EAAE,wBAAwB,CAAC;CACjD;AAED,qBAAa,2BAA4B,SAAQ,wBAAwB,CAAC,gBAAgB,CAAC;gBAC7E,OAAO,GAAE,kCAAuC;CAU7D;AAED,qBAAa,6BAA8B,SAAQ,wBAAwB,CAAC,oBAAoB,CAAC;gBACnF,OAAO,GAAE,kCAAuC;CAW7D"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Bluetooth-backed `SensorDeviceClient<TReading>`. A single generic
|
|
3
|
+
* client wraps either of `@dg-kit/protocol`'s sensor adapters
|
|
4
|
+
* (`PawPrintsSensorAdapter`, `CivetPressureSensorAdapter`) — they share the
|
|
5
|
+
* exact same `WebBluetoothSensorAdapter<TReading>` shape
|
|
6
|
+
* (onConnected/onDisconnected/getState/subscribe/onStateChanged), only their
|
|
7
|
+
* LED-setting method name differs (`setLedSolid` vs `setIndicatorColor`),
|
|
8
|
+
* which is why `setIndicatorColor` is threaded in as a constructor callback
|
|
9
|
+
* rather than called directly on the adapter.
|
|
10
|
+
*/
|
|
11
|
+
import { CivetPressureSensorAdapter, PawPrintsSensorAdapter, } from '@dg-kit/protocol';
|
|
12
|
+
import { attachAuxDevice, connectAuxDevice, disconnectAuxDevice } from './aux-device-connect.js';
|
|
13
|
+
import { CIVET_EDGING_REQUEST_DEVICE_OPTIONS, PAW_PRINTS_REQUEST_DEVICE_OPTIONS, } from './request-device-options.js';
|
|
14
|
+
export class WebBluetoothSensorClient {
|
|
15
|
+
options;
|
|
16
|
+
listeners = new Set();
|
|
17
|
+
device = null;
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.options = options;
|
|
20
|
+
this.options.adapter.onStateChanged((state) => this.emit(state));
|
|
21
|
+
}
|
|
22
|
+
async connect() {
|
|
23
|
+
this.device = await connectAuxDevice({
|
|
24
|
+
navigatorRef: this.options.navigatorRef,
|
|
25
|
+
requestDeviceOptions: this.options.requestDeviceOptions,
|
|
26
|
+
}, this.options.adapter, this.device, this.handleGattDisconnected);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Attach to an already-obtained `(device, server)` pair instead of
|
|
30
|
+
* running this client's own chooser prompt — see
|
|
31
|
+
* `aux-device-connect.ts`'s `attachAuxDevice()` doc comment.
|
|
32
|
+
*/
|
|
33
|
+
async connectDevice(device, server) {
|
|
34
|
+
this.device = await attachAuxDevice(device, server, this.options.adapter, this.device, this.handleGattDisconnected);
|
|
35
|
+
}
|
|
36
|
+
async disconnect() {
|
|
37
|
+
const device = this.device;
|
|
38
|
+
this.device = null;
|
|
39
|
+
await disconnectAuxDevice(device, this.options.adapter, this.handleGattDisconnected);
|
|
40
|
+
}
|
|
41
|
+
async getState() {
|
|
42
|
+
return this.options.adapter.getState();
|
|
43
|
+
}
|
|
44
|
+
subscribe(listener) {
|
|
45
|
+
return this.options.adapter.subscribe(listener);
|
|
46
|
+
}
|
|
47
|
+
onStateChanged(listener) {
|
|
48
|
+
this.listeners.add(listener);
|
|
49
|
+
return () => {
|
|
50
|
+
this.listeners.delete(listener);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async setIndicatorColor(color) {
|
|
54
|
+
await this.options.setIndicatorColor(color);
|
|
55
|
+
}
|
|
56
|
+
handleGattDisconnected = () => {
|
|
57
|
+
const device = this.device;
|
|
58
|
+
this.device = null;
|
|
59
|
+
device?.removeEventListener('gattserverdisconnected', this.handleGattDisconnected);
|
|
60
|
+
void this.options.adapter.onDisconnected();
|
|
61
|
+
};
|
|
62
|
+
emit(state) {
|
|
63
|
+
for (const listener of this.listeners) {
|
|
64
|
+
listener(state);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export class WebBluetoothPawPrintsClient extends WebBluetoothSensorClient {
|
|
69
|
+
constructor(options = {}) {
|
|
70
|
+
const adapter = new PawPrintsSensorAdapter();
|
|
71
|
+
super({
|
|
72
|
+
adapter,
|
|
73
|
+
navigatorRef: options.navigatorRef,
|
|
74
|
+
requestDeviceOptions: options.requestDeviceOptions ?? PAW_PRINTS_REQUEST_DEVICE_OPTIONS,
|
|
75
|
+
// Paw-prints exposes a dedicated "set solid color" LED command.
|
|
76
|
+
setIndicatorColor: (color) => adapter.setLedSolid(color),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export class WebBluetoothCivetEdgingClient extends WebBluetoothSensorClient {
|
|
81
|
+
constructor(options = {}) {
|
|
82
|
+
const adapter = new CivetPressureSensorAdapter();
|
|
83
|
+
super({
|
|
84
|
+
adapter,
|
|
85
|
+
navigatorRef: options.navigatorRef,
|
|
86
|
+
requestDeviceOptions: options.requestDeviceOptions ?? CIVET_EDGING_REQUEST_DEVICE_OPTIONS,
|
|
87
|
+
// civet-edging has no standalone "set color" opcode — setIndicatorColor()
|
|
88
|
+
// re-sends the pressure-reporting packet with streaming state preserved.
|
|
89
|
+
setIndicatorColor: (color) => adapter.setIndicatorColor(color),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=sensor-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sensor-client.js","sourceRoot":"","sources":["../src/sensor-client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dg-kit/transport-webbluetooth",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"description": "Web Bluetooth DeviceClient for DG-Lab Coyote (browser-only)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "0xNullAI",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@dg-kit/core": "1.
|
|
31
|
-
"@dg-kit/protocol": "1.
|
|
30
|
+
"@dg-kit/core": "1.13.0",
|
|
31
|
+
"@dg-kit/protocol": "1.13.0"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
34
|
"build": "tsc -p tsconfig.json",
|