@neurosity/sdk 6.3.0 → 6.4.0-next.1
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/browser/neurosity.iife.js +1550 -1536
- package/dist/browser/neurosity.js +15 -15
- package/dist/browser/neurosity.js.map +1 -1
- package/dist/cjs/Neurosity.d.ts +5 -0
- package/dist/cjs/Neurosity.js +20 -6
- package/dist/cjs/api/bluetooth/BluetoothClient.d.ts +2 -0
- package/dist/cjs/api/bluetooth/BluetoothClient.js +35 -30
- package/dist/cjs/api/bluetooth/BluetoothTransport.d.ts +2 -2
- package/dist/cjs/api/bluetooth/react-native/ReactNativeTransport.d.ts +2 -3
- package/dist/cjs/api/bluetooth/react-native/ReactNativeTransport.js +37 -45
- package/dist/cjs/api/bluetooth/utils/osHasBluetoothSupport.d.ts +2 -2
- package/dist/cjs/api/bluetooth/utils/osHasBluetoothSupport.js +4 -2
- package/dist/cjs/api/bluetooth/web/WebBluetoothTransport.d.ts +2 -3
- package/dist/cjs/api/bluetooth/web/WebBluetoothTransport.js +35 -41
- package/dist/cjs/api/index.d.ts +3 -1
- package/dist/cjs/api/index.js +4 -0
- package/dist/electron/index.js +10 -10
- package/dist/electron/index.js.map +1 -1
- package/dist/esm/Neurosity.d.ts +5 -0
- package/dist/esm/Neurosity.js +20 -6
- package/dist/esm/api/bluetooth/BluetoothClient.d.ts +2 -0
- package/dist/esm/api/bluetooth/BluetoothClient.js +36 -31
- package/dist/esm/api/bluetooth/BluetoothTransport.d.ts +2 -2
- package/dist/esm/api/bluetooth/react-native/ReactNativeTransport.d.ts +2 -3
- package/dist/esm/api/bluetooth/react-native/ReactNativeTransport.js +33 -41
- package/dist/esm/api/bluetooth/utils/osHasBluetoothSupport.d.ts +2 -2
- package/dist/esm/api/bluetooth/utils/osHasBluetoothSupport.js +4 -2
- package/dist/esm/api/bluetooth/web/WebBluetoothTransport.d.ts +2 -3
- package/dist/esm/api/bluetooth/web/WebBluetoothTransport.js +33 -39
- package/dist/esm/api/index.d.ts +3 -1
- package/dist/esm/api/index.js +4 -0
- package/dist/esm/neurosity.mjs +1550 -1536
- package/dist/examples/neurosity.iife.js +1550 -1536
- package/dist/examples/neurosity.js +15 -15
- package/dist/examples/neurosity.mjs +1550 -1536
- package/package.json +1 -1
package/dist/cjs/Neurosity.d.ts
CHANGED
|
@@ -80,6 +80,11 @@ export declare class Neurosity {
|
|
|
80
80
|
* @hidden
|
|
81
81
|
*/
|
|
82
82
|
_initStreamingMode(streamingMode: STREAMING_MODE, hasBluetoothTransport: boolean): void;
|
|
83
|
+
/**
|
|
84
|
+
*
|
|
85
|
+
* @hidden
|
|
86
|
+
*/
|
|
87
|
+
_osHasBluetoothSupport(): Observable<any>;
|
|
83
88
|
/**
|
|
84
89
|
* Subscribe to the device's streaming state changes and the current strategy
|
|
85
90
|
*
|
package/dist/cjs/Neurosity.js
CHANGED
|
@@ -39,6 +39,7 @@ exports.Notion = exports.Neurosity = void 0;
|
|
|
39
39
|
const rxjs_1 = require("rxjs");
|
|
40
40
|
const rxjs_2 = require("rxjs");
|
|
41
41
|
const operators_1 = require("rxjs/operators");
|
|
42
|
+
const operators_2 = require("rxjs/operators");
|
|
42
43
|
const fast_deep_equal_1 = __importDefault(require("fast-deep-equal"));
|
|
43
44
|
const index_1 = require("./api/index");
|
|
44
45
|
const index_2 = require("./api/index");
|
|
@@ -99,6 +100,7 @@ class Neurosity {
|
|
|
99
100
|
if (!!bluetoothTransport) {
|
|
100
101
|
this.bluetoothClient = new bluetooth_1.BluetoothClient({
|
|
101
102
|
selectedDevice$: this.onDeviceChange(),
|
|
103
|
+
osHasBluetoothSupport$: this._osHasBluetoothSupport(),
|
|
102
104
|
createBluetoothToken: this.createBluetoothToken.bind(this),
|
|
103
105
|
transport: bluetoothTransport
|
|
104
106
|
});
|
|
@@ -129,6 +131,16 @@ class Neurosity {
|
|
|
129
131
|
this.streamingMode$.next(streamingMode);
|
|
130
132
|
}
|
|
131
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
*
|
|
136
|
+
* @hidden
|
|
137
|
+
*/
|
|
138
|
+
_osHasBluetoothSupport() {
|
|
139
|
+
return (0, rxjs_1.combineLatest)({
|
|
140
|
+
selectedDevice: this.onDeviceChange(),
|
|
141
|
+
osVersion: this.osVersion().pipe((0, operators_1.startWith)(null))
|
|
142
|
+
}).pipe((0, operators_1.map)(({ selectedDevice, osVersion }) => (0, bluetooth_1.osHasBluetoothSupport)(selectedDevice, osVersion)));
|
|
143
|
+
}
|
|
132
144
|
/**
|
|
133
145
|
* Subscribe to the device's streaming state changes and the current strategy
|
|
134
146
|
*
|
|
@@ -144,12 +156,14 @@ class Neurosity {
|
|
|
144
156
|
streamingState() {
|
|
145
157
|
const isWifiOnline = (state) => [status_1.STATUS.ONLINE, status_1.STATUS.UPDATING].includes(state);
|
|
146
158
|
return this.streamingMode$.pipe((0, operators_1.switchMap)((streamingMode) => {
|
|
147
|
-
return
|
|
148
|
-
|
|
159
|
+
return (0, rxjs_1.combineLatest)({
|
|
160
|
+
selectedDevice: this.onDeviceChange(),
|
|
161
|
+
osHasBluetoothSupport: this._osHasBluetoothSupport()
|
|
162
|
+
}).pipe((0, operators_1.switchMap)(({ selectedDevice, osHasBluetoothSupport }) => {
|
|
163
|
+
if (!selectedDevice) {
|
|
149
164
|
return rxjs_2.EMPTY;
|
|
150
165
|
}
|
|
151
|
-
const isUnableToUseBluetooth = this.isMissingBluetoothTransport ||
|
|
152
|
-
!(0, bluetooth_1.osHasBluetoothSupport)(selectDevice);
|
|
166
|
+
const isUnableToUseBluetooth = this.isMissingBluetoothTransport || !osHasBluetoothSupport;
|
|
153
167
|
if (isUnableToUseBluetooth) {
|
|
154
168
|
return this.cloudClient.status().pipe((0, operators_1.map)(({ state }) => ({
|
|
155
169
|
connected: isWifiOnline(state),
|
|
@@ -193,7 +207,7 @@ class Neurosity {
|
|
|
193
207
|
: streaming_1.STREAMING_TYPE.WIFI
|
|
194
208
|
};
|
|
195
209
|
}
|
|
196
|
-
}), (0,
|
|
210
|
+
}), (0, operators_2.distinctUntilChanged)((a, b) => (0, fast_deep_equal_1.default)(a, b)));
|
|
197
211
|
}));
|
|
198
212
|
}));
|
|
199
213
|
}
|
|
@@ -815,7 +829,7 @@ class Neurosity {
|
|
|
815
829
|
if (hasOAuthError) {
|
|
816
830
|
return (0, rxjs_1.throwError)(() => OAuthError);
|
|
817
831
|
}
|
|
818
|
-
return this.cloudClient.
|
|
832
|
+
return this.cloudClient.osVersion();
|
|
819
833
|
}
|
|
820
834
|
/**
|
|
821
835
|
* <StreamingModes wifi={true} bluetooth={true} />
|
|
@@ -16,12 +16,14 @@ declare type CreateBluetoothToken = () => Promise<string>;
|
|
|
16
16
|
declare type Options = {
|
|
17
17
|
transport: BluetoothTransport;
|
|
18
18
|
selectedDevice$: Observable<DeviceInfo>;
|
|
19
|
+
osHasBluetoothSupport$: Observable<boolean>;
|
|
19
20
|
createBluetoothToken: CreateBluetoothToken;
|
|
20
21
|
};
|
|
21
22
|
export declare class BluetoothClient {
|
|
22
23
|
transport: BluetoothTransport;
|
|
23
24
|
deviceInfo: DeviceInfo;
|
|
24
25
|
selectedDevice$: ReplaySubject<DeviceInfo>;
|
|
26
|
+
osHasBluetoothSupport$: ReplaySubject<boolean>;
|
|
25
27
|
isAuthenticated$: ReplaySubject<boolean>;
|
|
26
28
|
_focus$: Observable<any>;
|
|
27
29
|
_calm$: Observable<any>;
|
|
@@ -13,17 +13,16 @@ exports.BluetoothClient = void 0;
|
|
|
13
13
|
const rxjs_1 = require("rxjs");
|
|
14
14
|
const rxjs_2 = require("rxjs");
|
|
15
15
|
const operators_1 = require("rxjs/operators");
|
|
16
|
-
const operators_2 = require("rxjs/operators");
|
|
17
16
|
const WebBluetoothTransport_1 = require("./web/WebBluetoothTransport");
|
|
18
17
|
const ReactNativeTransport_1 = require("./react-native/ReactNativeTransport");
|
|
19
18
|
const csvBufferToEpoch_1 = require("./utils/csvBufferToEpoch");
|
|
20
19
|
const types_1 = require("./types");
|
|
21
|
-
const osHasBluetoothSupport_1 = require("./utils/osHasBluetoothSupport");
|
|
22
20
|
class BluetoothClient {
|
|
23
21
|
constructor(options) {
|
|
24
22
|
this.selectedDevice$ = new rxjs_2.ReplaySubject(1);
|
|
23
|
+
this.osHasBluetoothSupport$ = new rxjs_2.ReplaySubject(1);
|
|
25
24
|
this.isAuthenticated$ = new rxjs_2.ReplaySubject(1);
|
|
26
|
-
const { transport, selectedDevice$, createBluetoothToken } = options !== null && options !== void 0 ? options : {};
|
|
25
|
+
const { transport, selectedDevice$, osHasBluetoothSupport$, createBluetoothToken } = options !== null && options !== void 0 ? options : {};
|
|
27
26
|
if (!transport) {
|
|
28
27
|
throw new Error(`No bluetooth transport provided.`);
|
|
29
28
|
}
|
|
@@ -32,8 +31,15 @@ class BluetoothClient {
|
|
|
32
31
|
if (selectedDevice$) {
|
|
33
32
|
selectedDevice$.subscribe(this.selectedDevice$);
|
|
34
33
|
}
|
|
35
|
-
//
|
|
36
|
-
|
|
34
|
+
// Pass events to the internal osHasBluetoothSupport$ if osHasBluetoothSupport$ is passed via options
|
|
35
|
+
if (osHasBluetoothSupport$) {
|
|
36
|
+
osHasBluetoothSupport$.subscribe(this.osHasBluetoothSupport$);
|
|
37
|
+
}
|
|
38
|
+
this.osHasBluetoothSupport$
|
|
39
|
+
.pipe((0, operators_1.switchMap)((osHasBluetoothSupport) => osHasBluetoothSupport
|
|
40
|
+
? this.transport._autoConnect(this.selectedDevice$)
|
|
41
|
+
: rxjs_2.EMPTY))
|
|
42
|
+
.subscribe({
|
|
37
43
|
error: (error) => {
|
|
38
44
|
var _a;
|
|
39
45
|
this.transport.addLog(`Auto connect: error -> ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);
|
|
@@ -48,7 +54,11 @@ class BluetoothClient {
|
|
|
48
54
|
this.transport.addLog("Auto authentication not enabled");
|
|
49
55
|
}
|
|
50
56
|
// Auto manage action notifications
|
|
51
|
-
this.
|
|
57
|
+
this.osHasBluetoothSupport$
|
|
58
|
+
.pipe((0, operators_1.switchMap)((osHasBluetoothSupport) => osHasBluetoothSupport
|
|
59
|
+
? this.transport._autoToggleActionNotifications()
|
|
60
|
+
: rxjs_2.EMPTY))
|
|
61
|
+
.subscribe();
|
|
52
62
|
// Multicast metrics (share)
|
|
53
63
|
this._focus$ = this._subscribeWhileAuthenticated("focus");
|
|
54
64
|
this._calm$ = this._subscribeWhileAuthenticated("calm");
|
|
@@ -72,27 +82,24 @@ class BluetoothClient {
|
|
|
72
82
|
const reauthenticateInterval$ = (0, rxjs_1.timer)(0, REAUTHENTICATE_INTERVAL).pipe((0, operators_1.tap)(() => {
|
|
73
83
|
this.transport.addLog(`Auto authentication in progress...`);
|
|
74
84
|
}));
|
|
75
|
-
return this.
|
|
76
|
-
?
|
|
77
|
-
:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
})))));
|
|
85
|
+
return this.osHasBluetoothSupport$.pipe((0, operators_1.switchMap)((osHasBluetoothSupport) => osHasBluetoothSupport ? this.connection() : rxjs_2.EMPTY), (0, operators_1.switchMap)((connection) => connection === types_1.BLUETOOTH_CONNECTION.CONNECTED
|
|
86
|
+
? reauthenticateInterval$
|
|
87
|
+
: rxjs_2.EMPTY), (0, operators_1.switchMap)(() => __awaiter(this, void 0, void 0, function* () { return yield this.isAuthenticated(); })), (0, operators_1.tap)(([isAuthenticated]) => __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
if (!isAuthenticated) {
|
|
89
|
+
const token = yield createBluetoothToken();
|
|
90
|
+
yield this.authenticate(token);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
this.transport.addLog(`Already authenticated`);
|
|
94
|
+
}
|
|
95
|
+
})));
|
|
88
96
|
}
|
|
89
97
|
enableAutoConnect(autoConnect) {
|
|
90
98
|
this.transport.enableAutoConnect(autoConnect);
|
|
91
99
|
}
|
|
92
100
|
_hasBluetoothSupport() {
|
|
93
101
|
return __awaiter(this, void 0, void 0, function* () {
|
|
94
|
-
|
|
95
|
-
return (0, osHasBluetoothSupport_1.osHasBluetoothSupport)(selectedDevice);
|
|
102
|
+
return yield (0, rxjs_2.firstValueFrom)(this.osHasBluetoothSupport$);
|
|
96
103
|
});
|
|
97
104
|
}
|
|
98
105
|
authenticate(token) {
|
|
@@ -163,7 +170,7 @@ class BluetoothClient {
|
|
|
163
170
|
this.transport.addLog(errorMessage);
|
|
164
171
|
return Promise.reject(errorMessage);
|
|
165
172
|
}
|
|
166
|
-
const isAuthenticated = yield (0,
|
|
173
|
+
const isAuthenticated = yield (0, rxjs_2.firstValueFrom)(this.isAuthenticated$);
|
|
167
174
|
if (!isAuthenticated) {
|
|
168
175
|
const errorMessage = `Authentication required.`;
|
|
169
176
|
this.transport.addLog(errorMessage);
|
|
@@ -173,13 +180,11 @@ class BluetoothClient {
|
|
|
173
180
|
});
|
|
174
181
|
}
|
|
175
182
|
_subscribeWhileAuthenticated(characteristicName) {
|
|
176
|
-
return this.
|
|
177
|
-
?
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
})
|
|
182
|
-
: rxjs_2.EMPTY))), (0, operators_1.share)());
|
|
183
|
+
return this.osHasBluetoothSupport$.pipe((0, operators_1.switchMap)((osHasBluetoothSupport) => osHasBluetoothSupport ? this.isAuthenticated$ : rxjs_2.EMPTY), (0, operators_1.distinctUntilChanged)(), (0, operators_1.switchMap)((isAuthenticated) => isAuthenticated
|
|
184
|
+
? this.transport.subscribeToCharacteristic({
|
|
185
|
+
characteristicName
|
|
186
|
+
})
|
|
187
|
+
: rxjs_2.EMPTY), (0, operators_1.share)());
|
|
183
188
|
}
|
|
184
189
|
focus() {
|
|
185
190
|
return this._focus$;
|
|
@@ -220,7 +225,7 @@ class BluetoothClient {
|
|
|
220
225
|
}
|
|
221
226
|
getInfo() {
|
|
222
227
|
return __awaiter(this, void 0, void 0, function* () {
|
|
223
|
-
return yield this._withAuthentication(() => (0,
|
|
228
|
+
return yield this._withAuthentication(() => (0, rxjs_2.firstValueFrom)(this.transport.subscribeToCharacteristic({
|
|
224
229
|
characteristicName: "deviceInfo"
|
|
225
230
|
})));
|
|
226
231
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Observable, Subject } from "rxjs";
|
|
2
2
|
import { BLUETOOTH_CONNECTION, TRANSPORT_TYPE } from "./types";
|
|
3
3
|
import { Action } from "../../types/actions";
|
|
4
|
-
import { DeviceInfo } from "../../types/deviceInfo";
|
|
4
|
+
import { DeviceInfo, OSVersion } from "../../types/deviceInfo";
|
|
5
5
|
import { Peripheral } from "./react-native/types/BleManagerTypes";
|
|
6
6
|
export declare type DeviceNicknameOrPeripheral = string | Peripheral;
|
|
7
7
|
/**
|
|
@@ -10,7 +10,7 @@ export declare type DeviceNicknameOrPeripheral = string | Peripheral;
|
|
|
10
10
|
export interface BluetoothTransport {
|
|
11
11
|
type: TRANSPORT_TYPE;
|
|
12
12
|
connect(deviceNicknameORPeripheral?: DeviceNicknameOrPeripheral): Promise<void>;
|
|
13
|
-
_autoConnect(selectedDevice$: Observable<DeviceInfo>): Observable<void>;
|
|
13
|
+
_autoConnect(selectedDevice$: Observable<DeviceInfo>, osVersion: Observable<OSVersion>): Observable<void>;
|
|
14
14
|
disconnect(): Promise<void>;
|
|
15
15
|
connection(): Observable<BLUETOOTH_CONNECTION>;
|
|
16
16
|
requestDevice?(): any;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { BehaviorSubject, ReplaySubject } from "rxjs";
|
|
2
|
-
import { Observable } from "rxjs";
|
|
1
|
+
import { Observable, BehaviorSubject, ReplaySubject } from "rxjs";
|
|
3
2
|
import { BluetoothTransport } from "../BluetoothTransport";
|
|
4
3
|
import { ActionOptions, SubscribeOptions } from "../types";
|
|
5
4
|
import { TRANSPORT_TYPE, BLUETOOTH_CONNECTION } from "../types";
|
|
@@ -65,7 +64,7 @@ export declare class ReactNativeTransport implements BluetoothTransport {
|
|
|
65
64
|
writeCharacteristic(characteristicName: string, data: string): Promise<void>;
|
|
66
65
|
_addPendingAction(actionId: number): void;
|
|
67
66
|
_removePendingAction(actionId: number): void;
|
|
68
|
-
_autoToggleActionNotifications(
|
|
67
|
+
_autoToggleActionNotifications(): Observable<any>;
|
|
69
68
|
dispatchAction({ characteristicName, action }: ActionOptions): Promise<any>;
|
|
70
69
|
}
|
|
71
70
|
export {};
|
|
@@ -26,7 +26,6 @@ const constants_1 = require("../constants");
|
|
|
26
26
|
const constants_2 = require("../constants");
|
|
27
27
|
const constants_3 = require("../constants");
|
|
28
28
|
const constants_4 = require("../constants");
|
|
29
|
-
const osHasBluetoothSupport_1 = require("../utils/osHasBluetoothSupport");
|
|
30
29
|
const defaultOptions = {
|
|
31
30
|
autoConnect: true
|
|
32
31
|
};
|
|
@@ -107,13 +106,11 @@ class ReactNativeTransport {
|
|
|
107
106
|
_autoConnect(selectedDevice$) {
|
|
108
107
|
const selectedDeviceAfterDisconnect$ = this.onDisconnected$.pipe((0, operators_1.switchMap)(() => selectedDevice$));
|
|
109
108
|
return this._isAutoConnectEnabled$.pipe((0, operators_1.switchMap)((isAutoConnectEnabled) => isAutoConnectEnabled
|
|
110
|
-
? (0,
|
|
111
|
-
:
|
|
112
|
-
?
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return peripheralMatch ? (0, rxjs_1.of)(peripheralMatch) : rxjs_2.NEVER;
|
|
116
|
-
}), (0, operators_3.distinct)((peripheral) => peripheral.id), (0, operators_3.take)(1))), (0, operators_1.switchMap)((peripheral) => __awaiter(this, void 0, void 0, function* () {
|
|
109
|
+
? (0, rxjs_2.merge)(selectedDevice$, selectedDeviceAfterDisconnect$)
|
|
110
|
+
: rxjs_1.NEVER), (0, operators_1.switchMap)((selectedDevice) => this.scan().pipe((0, operators_1.switchMap)((peripherals) => {
|
|
111
|
+
const peripheralMatch = peripherals.find((peripheral) => peripheral.name === (selectedDevice === null || selectedDevice === void 0 ? void 0 : selectedDevice.deviceNickname));
|
|
112
|
+
return peripheralMatch ? (0, rxjs_2.of)(peripheralMatch) : rxjs_1.NEVER;
|
|
113
|
+
}), (0, operators_3.distinct)((peripheral) => peripheral.id), (0, operators_3.take)(1))), (0, operators_1.switchMap)((peripheral) => __awaiter(this, void 0, void 0, function* () {
|
|
117
114
|
return yield this.connect(peripheral);
|
|
118
115
|
})));
|
|
119
116
|
}
|
|
@@ -145,7 +142,7 @@ class ReactNativeTransport {
|
|
|
145
142
|
const serviceUUIDs = [ipk_1.BLUETOOTH_PRIMARY_SERVICE_UUID_STRING];
|
|
146
143
|
const allowDuplicates = true;
|
|
147
144
|
const scanOptions = {};
|
|
148
|
-
const scanOnce$ = new
|
|
145
|
+
const scanOnce$ = new rxjs_1.Observable((subscriber) => {
|
|
149
146
|
var _a;
|
|
150
147
|
try {
|
|
151
148
|
this.BleManager.scan(serviceUUIDs, seconds, allowDuplicates, scanOptions).then(() => {
|
|
@@ -163,7 +160,7 @@ class ReactNativeTransport {
|
|
|
163
160
|
});
|
|
164
161
|
const scan$ = once
|
|
165
162
|
? scanOnce$
|
|
166
|
-
: (0,
|
|
163
|
+
: (0, rxjs_2.timer)(0, RESCAN_INTERVAL).pipe((0, operators_1.switchMap)(() => scanOnce$));
|
|
167
164
|
const peripherals$ = scan$.pipe((0, operators_1.tap)(() => {
|
|
168
165
|
if (!skipConnectionUpdate) {
|
|
169
166
|
this.connection$.next(types_1.BLUETOOTH_CONNECTION.SCANNING);
|
|
@@ -261,7 +258,7 @@ class ReactNativeTransport {
|
|
|
261
258
|
return (_a = this.characteristicsByName) === null || _a === void 0 ? void 0 : _a[characteristicName];
|
|
262
259
|
}
|
|
263
260
|
subscribeToCharacteristic({ characteristicName, manageNotifications = true }) {
|
|
264
|
-
const getData = ({ peripheralId, serviceUUID, characteristicUUID }) => (0,
|
|
261
|
+
const getData = ({ peripheralId, serviceUUID, characteristicUUID }) => (0, rxjs_2.defer)(() => __awaiter(this, void 0, void 0, function* () {
|
|
265
262
|
var _a;
|
|
266
263
|
if (manageNotifications) {
|
|
267
264
|
try {
|
|
@@ -295,7 +292,7 @@ class ReactNativeTransport {
|
|
|
295
292
|
}));
|
|
296
293
|
return this.connection$.pipe((0, operators_1.switchMap)((connection) => connection === types_1.BLUETOOTH_CONNECTION.CONNECTED
|
|
297
294
|
? getData(this.getCharacteristicByName(characteristicName))
|
|
298
|
-
:
|
|
295
|
+
: rxjs_1.NEVER));
|
|
299
296
|
}
|
|
300
297
|
readCharacteristic(characteristicName, parse = false) {
|
|
301
298
|
var _a;
|
|
@@ -336,40 +333,35 @@ class ReactNativeTransport {
|
|
|
336
333
|
const actions = this.pendingActions$.getValue();
|
|
337
334
|
this.pendingActions$.next(actions.filter((id) => id !== actionId));
|
|
338
335
|
}
|
|
339
|
-
_autoToggleActionNotifications(
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
this.addLog(`Started notifications for [actions] characteristic`);
|
|
353
|
-
}
|
|
354
|
-
catch (error) {
|
|
355
|
-
this.addLog(`Attemped to start notifications for [actions] characteristic: ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);
|
|
356
|
-
}
|
|
336
|
+
_autoToggleActionNotifications() {
|
|
337
|
+
let started = false;
|
|
338
|
+
return this.connection$.asObservable().pipe((0, operators_1.switchMap)((connection) => connection === types_1.BLUETOOTH_CONNECTION.CONNECTED
|
|
339
|
+
? this.pendingActions$
|
|
340
|
+
: rxjs_1.NEVER), (0, operators_1.tap)((pendingActions) => __awaiter(this, void 0, void 0, function* () {
|
|
341
|
+
var _a, _b;
|
|
342
|
+
const { peripheralId, serviceUUID, characteristicUUID } = this.getCharacteristicByName("actions");
|
|
343
|
+
const hasPendingActions = !!pendingActions.length;
|
|
344
|
+
if (hasPendingActions && !started) {
|
|
345
|
+
started = true;
|
|
346
|
+
try {
|
|
347
|
+
yield this.BleManager.startNotification(peripheralId, serviceUUID, characteristicUUID);
|
|
348
|
+
this.addLog(`Started notifications for [actions] characteristic`);
|
|
357
349
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
try {
|
|
361
|
-
yield this.BleManager.stopNotification(peripheralId, serviceUUID, characteristicUUID);
|
|
362
|
-
this.addLog(`Stopped notifications for actions characteristic`);
|
|
363
|
-
}
|
|
364
|
-
catch (error) {
|
|
365
|
-
this.addLog(`Attemped to stop notifications for [actions] characteristic: ${(_b = error === null || error === void 0 ? void 0 : error.message) !== null && _b !== void 0 ? _b : error}`);
|
|
366
|
-
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
this.addLog(`Attemped to start notifications for [actions] characteristic: ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);
|
|
367
352
|
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
353
|
+
}
|
|
354
|
+
if (!hasPendingActions && started) {
|
|
355
|
+
started = false;
|
|
356
|
+
try {
|
|
357
|
+
yield this.BleManager.stopNotification(peripheralId, serviceUUID, characteristicUUID);
|
|
358
|
+
this.addLog(`Stopped notifications for actions characteristic`);
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
this.addLog(`Attemped to stop notifications for [actions] characteristic: ${(_b = error === null || error === void 0 ? void 0 : error.message) !== null && _b !== void 0 ? _b : error}`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
})));
|
|
373
365
|
}
|
|
374
366
|
dispatchAction({ characteristicName, action }) {
|
|
375
367
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -380,7 +372,7 @@ class ReactNativeTransport {
|
|
|
380
372
|
this.addLog(`Dispatched action with id ${actionId}`);
|
|
381
373
|
if (responseRequired && responseTimeout) {
|
|
382
374
|
this._addPendingAction(actionId);
|
|
383
|
-
const timeout = (0,
|
|
375
|
+
const timeout = (0, rxjs_2.timer)(responseTimeout).subscribe(() => {
|
|
384
376
|
this._removePendingAction(actionId);
|
|
385
377
|
reject(new Error(`Action with id ${actionId} timed out after ${responseTimeout}ms`));
|
|
386
378
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { DeviceInfo } from "../../../types/deviceInfo";
|
|
2
|
-
export declare function osHasBluetoothSupport(selectedDevice: DeviceInfo): any;
|
|
1
|
+
import { DeviceInfo, OSVersion } from "../../../types/deviceInfo";
|
|
2
|
+
export declare function osHasBluetoothSupport(selectedDevice: DeviceInfo, osVersion?: OSVersion): any;
|
|
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.osHasBluetoothSupport = void 0;
|
|
7
7
|
const gte_1 = __importDefault(require("semver/functions/gte"));
|
|
8
|
-
function osHasBluetoothSupport(selectedDevice) {
|
|
8
|
+
function osHasBluetoothSupport(selectedDevice, osVersion) {
|
|
9
9
|
if (!selectedDevice) {
|
|
10
10
|
return false;
|
|
11
11
|
}
|
|
@@ -18,6 +18,8 @@ function osHasBluetoothSupport(selectedDevice) {
|
|
|
18
18
|
if (isEmulator) {
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
// `osVersion` is updated in real time,
|
|
22
|
+
// unlike accessing via `selectedDevice.osVersion`
|
|
23
|
+
return (0, gte_1.default)(osVersion !== null && osVersion !== void 0 ? osVersion : selectedDevice.osVersion, "16.0.0");
|
|
22
24
|
}
|
|
23
25
|
exports.osHasBluetoothSupport = osHasBluetoothSupport;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/// <reference types="web-bluetooth" />
|
|
2
|
-
import { BehaviorSubject, ReplaySubject } from "rxjs";
|
|
3
|
-
import { Observable } from "rxjs";
|
|
2
|
+
import { Observable, BehaviorSubject, ReplaySubject } from "rxjs";
|
|
4
3
|
import { BluetoothTransport } from "../BluetoothTransport";
|
|
5
4
|
import { ActionOptions, SubscribeOptions } from "../types";
|
|
6
5
|
import { TRANSPORT_TYPE, BLUETOOTH_CONNECTION } from "../types";
|
|
@@ -48,7 +47,7 @@ export declare class WebBluetoothTransport implements BluetoothTransport {
|
|
|
48
47
|
writeCharacteristic(characteristicName: string, data: string): Promise<void>;
|
|
49
48
|
_addPendingAction(actionId: number): void;
|
|
50
49
|
_removePendingAction(actionId: number): void;
|
|
51
|
-
_autoToggleActionNotifications(
|
|
50
|
+
_autoToggleActionNotifications(): Observable<any>;
|
|
52
51
|
dispatchAction({ characteristicName, action }: ActionOptions): Promise<any>;
|
|
53
52
|
}
|
|
54
53
|
export {};
|
|
@@ -26,7 +26,6 @@ const encoding_1 = require("../utils/encoding");
|
|
|
26
26
|
const types_1 = require("../types");
|
|
27
27
|
const constants_1 = require("../constants");
|
|
28
28
|
const constants_2 = require("../constants");
|
|
29
|
-
const osHasBluetoothSupport_1 = require("../utils/osHasBluetoothSupport");
|
|
30
29
|
const defaultOptions = {
|
|
31
30
|
autoConnect: true
|
|
32
31
|
};
|
|
@@ -66,8 +65,8 @@ class WebBluetoothTransport {
|
|
|
66
65
|
}
|
|
67
66
|
_autoConnect(selectedDevice$) {
|
|
68
67
|
return this._isAutoConnectEnabled$.pipe((0, operators_1.switchMap)((isAutoConnectEnabled) => isAutoConnectEnabled
|
|
69
|
-
? (0,
|
|
70
|
-
: rxjs_2.NEVER), (0, operators_1.switchMap)((selectedDevice) =>
|
|
68
|
+
? (0, rxjs_2.merge)(selectedDevice$, this.onDisconnected$.pipe((0, operators_1.switchMap)(() => selectedDevice$)))
|
|
69
|
+
: rxjs_2.NEVER), (0, operators_1.switchMap)((selectedDevice) => __awaiter(this, void 0, void 0, function* () {
|
|
71
70
|
var _a;
|
|
72
71
|
const { deviceNickname } = selectedDevice;
|
|
73
72
|
if (this.isConnected()) {
|
|
@@ -213,7 +212,7 @@ class WebBluetoothTransport {
|
|
|
213
212
|
});
|
|
214
213
|
}
|
|
215
214
|
subscribeToCharacteristic({ characteristicName, manageNotifications = true }) {
|
|
216
|
-
const data$ = (0,
|
|
215
|
+
const data$ = (0, rxjs_2.defer)(() => this.getCharacteristicByName(characteristicName)).pipe((0, operators_1.switchMap)((characteristic) => __awaiter(this, void 0, void 0, function* () {
|
|
217
216
|
var _a;
|
|
218
217
|
if (this.isConnected() && manageNotifications) {
|
|
219
218
|
try {
|
|
@@ -307,43 +306,38 @@ class WebBluetoothTransport {
|
|
|
307
306
|
const actions = this.pendingActions$.getValue();
|
|
308
307
|
this.pendingActions$.next(actions.filter((id) => id !== actionId));
|
|
309
308
|
}
|
|
310
|
-
_autoToggleActionNotifications(
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
this.addLog(`Started notifications for [actions] characteristic`);
|
|
327
|
-
}
|
|
328
|
-
catch (error) {
|
|
329
|
-
this.addLog(`Attemped to start notifications for [actions] characteristic: ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);
|
|
330
|
-
}
|
|
309
|
+
_autoToggleActionNotifications() {
|
|
310
|
+
let actionsCharacteristic;
|
|
311
|
+
let started = false;
|
|
312
|
+
return this.connection$.asObservable().pipe((0, operators_1.switchMap)((connection) => connection === types_1.BLUETOOTH_CONNECTION.CONNECTED
|
|
313
|
+
? (0, rxjs_2.defer)(() => this.getCharacteristicByName("actions")).pipe((0, operators_1.switchMap)((characteristic) => {
|
|
314
|
+
actionsCharacteristic = characteristic;
|
|
315
|
+
return this.pendingActions$;
|
|
316
|
+
}))
|
|
317
|
+
: rxjs_2.NEVER), (0, operators_1.tap)((pendingActions) => __awaiter(this, void 0, void 0, function* () {
|
|
318
|
+
var _a, _b;
|
|
319
|
+
const hasPendingActions = !!pendingActions.length;
|
|
320
|
+
if (hasPendingActions && !started) {
|
|
321
|
+
started = true;
|
|
322
|
+
try {
|
|
323
|
+
yield actionsCharacteristic.startNotifications();
|
|
324
|
+
this.addLog(`Started notifications for [actions] characteristic`);
|
|
331
325
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
try {
|
|
335
|
-
yield actionsCharacteristic.stopNotifications();
|
|
336
|
-
this.addLog(`Stopped notifications for actions characteristic`);
|
|
337
|
-
}
|
|
338
|
-
catch (error) {
|
|
339
|
-
this.addLog(`Attemped to stop notifications for [actions] characteristic: ${(_b = error === null || error === void 0 ? void 0 : error.message) !== null && _b !== void 0 ? _b : error}`);
|
|
340
|
-
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
this.addLog(`Attemped to start notifications for [actions] characteristic: ${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);
|
|
341
328
|
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
329
|
+
}
|
|
330
|
+
if (!hasPendingActions && started) {
|
|
331
|
+
started = false;
|
|
332
|
+
try {
|
|
333
|
+
yield actionsCharacteristic.stopNotifications();
|
|
334
|
+
this.addLog(`Stopped notifications for actions characteristic`);
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
this.addLog(`Attemped to stop notifications for [actions] characteristic: ${(_b = error === null || error === void 0 ? void 0 : error.message) !== null && _b !== void 0 ? _b : error}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
})));
|
|
347
341
|
}
|
|
348
342
|
dispatchAction({ characteristicName, action }) {
|
|
349
343
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -360,7 +354,7 @@ class WebBluetoothTransport {
|
|
|
360
354
|
this.addLog(`Dispatched action with id ${actionId}`);
|
|
361
355
|
if (responseRequired && responseTimeout) {
|
|
362
356
|
this._addPendingAction(actionId);
|
|
363
|
-
const timeout = (0,
|
|
357
|
+
const timeout = (0, rxjs_2.timer)(responseTimeout).subscribe(() => {
|
|
364
358
|
this._removePendingAction(actionId);
|
|
365
359
|
reject(`Action with id ${actionId} timed out after ${responseTimeout}ms`);
|
|
366
360
|
});
|
|
@@ -406,7 +400,7 @@ function fromDOMEvent(target, eventName, beforeRemove) {
|
|
|
406
400
|
}));
|
|
407
401
|
}
|
|
408
402
|
function onAdvertisementReceived(device) {
|
|
409
|
-
return new
|
|
403
|
+
return new rxjs_1.Observable((subscriber) => {
|
|
410
404
|
const abortController = new AbortController();
|
|
411
405
|
const { signal } = abortController;
|
|
412
406
|
const listener = device.addEventListener("advertisementreceived", (advertisement) => {
|
package/dist/cjs/api/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { Credentials, CustomToken } from "../types/credentials";
|
|
|
11
11
|
import { EmailAndPassword } from "../types/credentials";
|
|
12
12
|
import { ChangeSettings } from "../types/settings";
|
|
13
13
|
import { DeviceStatus } from "../types/status";
|
|
14
|
-
import { DeviceInfo, DeviceSelector } from "../types/deviceInfo";
|
|
14
|
+
import { DeviceInfo, DeviceSelector, OSVersion } from "../types/deviceInfo";
|
|
15
15
|
import { UserClaims } from "../types/user";
|
|
16
16
|
import { OAuthRemoveResponse } from "../types/oauth";
|
|
17
17
|
import { Experiment } from "../types/experiment";
|
|
@@ -30,8 +30,10 @@ export declare class CloudClient implements Client {
|
|
|
30
30
|
protected timesync: Timesync;
|
|
31
31
|
protected subscriptionManager: SubscriptionManager;
|
|
32
32
|
protected status$: Observable<DeviceStatus>;
|
|
33
|
+
protected osVersion$: Observable<OSVersion>;
|
|
33
34
|
constructor(options: SDKOptions);
|
|
34
35
|
onDeviceChange(): Observable<DeviceInfo>;
|
|
36
|
+
osVersion(): Observable<OSVersion>;
|
|
35
37
|
private setAutoSelectedDevice;
|
|
36
38
|
get actions(): Actions;
|
|
37
39
|
dispatchAction(action: Action): Promise<any>;
|
package/dist/cjs/api/index.js
CHANGED
|
@@ -37,6 +37,7 @@ class CloudClient {
|
|
|
37
37
|
this.firebaseUser = new firebase_1.FirebaseUser(this.firebaseApp);
|
|
38
38
|
this._selectedDevice.next(undefined);
|
|
39
39
|
this.status$ = (0, heartbeat_1.heartbeatAwareStatus)(this.observeNamespace("status").pipe((0, operators_1.share)())).pipe((0, filterInternalKeys_1.filterInternalKeys)(), (0, operators_1.shareReplay)(1));
|
|
40
|
+
this.osVersion$ = this.observeNamespace("info/osVersion").pipe((0, operators_1.shareReplay)(1));
|
|
40
41
|
this.firebaseUser.onAuthStateChanged().subscribe((user) => {
|
|
41
42
|
this.user = user;
|
|
42
43
|
});
|
|
@@ -70,6 +71,9 @@ class CloudClient {
|
|
|
70
71
|
.asObservable()
|
|
71
72
|
.pipe((0, operators_1.filter)((value) => value !== undefined));
|
|
72
73
|
}
|
|
74
|
+
osVersion() {
|
|
75
|
+
return this.osVersion$;
|
|
76
|
+
}
|
|
73
77
|
// Automatically select device when user logs in
|
|
74
78
|
setAutoSelectedDevice() {
|
|
75
79
|
return __awaiter(this, void 0, void 0, function* () {
|