@bota.dev/react-native-app-sdk 2.0.0-beta.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/BotaDeviceSDK.podspec +55 -0
- package/LICENSE +21 -0
- package/README.md +101 -0
- package/android/build.gradle +76 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidDevices.kt +172 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidLifecycle.kt +100 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidLogs.kt +82 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidModels.kt +476 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidOTA.kt +58 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidRecordingUploads.kt +180 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidRecordings.kt +751 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidSecurity.kt +509 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidWiFi.kt +125 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKEncryptedUploadV2Materials.kt +46 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKModule.kt +723 -0
- package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKPackage.kt +33 -0
- package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidDevicesTest.kt +211 -0
- package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidLifecycleTest.kt +132 -0
- package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidLogsTest.kt +57 -0
- package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidOTATest.kt +75 -0
- package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidRecordingUploadsTest.kt +147 -0
- package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidRecordingsTest.kt +355 -0
- package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidSecurityTest.kt +523 -0
- package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidWiFiTest.kt +100 -0
- package/generated/codegen-contract.json +3593 -0
- package/ios/BotaDeviceSDK.mm +1300 -0
- package/ios/BotaDeviceSDKAppleBridge.swift +2260 -0
- package/ios/BotaDeviceSDKAppleDevices.swift +191 -0
- package/ios/BotaDeviceSDKAppleLifecycle.swift +167 -0
- package/ios/BotaDeviceSDKAppleLogs.swift +79 -0
- package/ios/BotaDeviceSDKAppleOTA.swift +73 -0
- package/ios/BotaDeviceSDKAppleRecordingUploads.swift +178 -0
- package/ios/BotaDeviceSDKAppleRecordings.swift +670 -0
- package/ios/BotaDeviceSDKAppleSecurity.swift +586 -0
- package/ios/BotaDeviceSDKAppleWiFi.swift +128 -0
- package/ios/BotaDeviceSDKEncryptedUploadV2Materials.swift +99 -0
- package/lib/commonjs/BotaClient.js +194 -0
- package/lib/commonjs/BotaClient.js.map +1 -0
- package/lib/commonjs/ble/constants.js +10 -0
- package/lib/commonjs/ble/constants.js.map +1 -0
- package/lib/commonjs/ble/deviceLogs.js +50 -0
- package/lib/commonjs/ble/deviceLogs.js.map +1 -0
- package/lib/commonjs/cache/DeviceStateCache.js +6 -0
- package/lib/commonjs/cache/DeviceStateCache.js.map +1 -0
- package/lib/commonjs/client.js +746 -0
- package/lib/commonjs/client.js.map +1 -0
- package/lib/commonjs/compatibility/runtime.js +44 -0
- package/lib/commonjs/compatibility/runtime.js.map +1 -0
- package/lib/commonjs/index.js +123 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/managers/DeviceManager.js +647 -0
- package/lib/commonjs/managers/DeviceManager.js.map +1 -0
- package/lib/commonjs/managers/OTAManager.js +140 -0
- package/lib/commonjs/managers/OTAManager.js.map +1 -0
- package/lib/commonjs/managers/RecordingManager.js +444 -0
- package/lib/commonjs/managers/RecordingManager.js.map +1 -0
- package/lib/commonjs/managers/StreamingSession.js +175 -0
- package/lib/commonjs/managers/StreamingSession.js.map +1 -0
- package/lib/commonjs/managers/types.js +6 -0
- package/lib/commonjs/managers/types.js.map +1 -0
- package/lib/commonjs/models/Device.js +2 -0
- package/lib/commonjs/models/Device.js.map +1 -0
- package/lib/commonjs/models/Recording.js +2 -0
- package/lib/commonjs/models/Recording.js.map +1 -0
- package/lib/commonjs/models/Status.js +6 -0
- package/lib/commonjs/models/Status.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/specs/NativeBotaDeviceSDK.js +9 -0
- package/lib/commonjs/specs/NativeBotaDeviceSDK.js.map +1 -0
- package/lib/commonjs/sync/syncStatus.js +178 -0
- package/lib/commonjs/sync/syncStatus.js.map +1 -0
- package/lib/commonjs/utils/errors.js +194 -0
- package/lib/commonjs/utils/errors.js.map +1 -0
- package/lib/commonjs/utils/logger.js +84 -0
- package/lib/commonjs/utils/logger.js.map +1 -0
- package/lib/module/BotaClient.js +189 -0
- package/lib/module/BotaClient.js.map +1 -0
- package/lib/module/ble/constants.js +6 -0
- package/lib/module/ble/constants.js.map +1 -0
- package/lib/module/ble/deviceLogs.js +45 -0
- package/lib/module/ble/deviceLogs.js.map +1 -0
- package/lib/module/cache/DeviceStateCache.js +4 -0
- package/lib/module/cache/DeviceStateCache.js.map +1 -0
- package/lib/module/client.js +740 -0
- package/lib/module/client.js.map +1 -0
- package/lib/module/compatibility/runtime.js +35 -0
- package/lib/module/compatibility/runtime.js.map +1 -0
- package/lib/module/index.js +17 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/managers/DeviceManager.js +641 -0
- package/lib/module/managers/DeviceManager.js.map +1 -0
- package/lib/module/managers/OTAManager.js +134 -0
- package/lib/module/managers/OTAManager.js.map +1 -0
- package/lib/module/managers/RecordingManager.js +438 -0
- package/lib/module/managers/RecordingManager.js.map +1 -0
- package/lib/module/managers/StreamingSession.js +168 -0
- package/lib/module/managers/StreamingSession.js.map +1 -0
- package/lib/module/managers/types.js +4 -0
- package/lib/module/managers/types.js.map +1 -0
- package/lib/module/models/Device.js +2 -0
- package/lib/module/models/Device.js.map +1 -0
- package/lib/module/models/Recording.js +2 -0
- package/lib/module/models/Recording.js.map +1 -0
- package/lib/module/models/Status.js +4 -0
- package/lib/module/models/Status.js.map +1 -0
- package/lib/module/specs/NativeBotaDeviceSDK.js +5 -0
- package/lib/module/specs/NativeBotaDeviceSDK.js.map +1 -0
- package/lib/module/sync/syncStatus.js +174 -0
- package/lib/module/sync/syncStatus.js.map +1 -0
- package/lib/module/utils/errors.js +183 -0
- package/lib/module/utils/errors.js.map +1 -0
- package/lib/module/utils/logger.js +80 -0
- package/lib/module/utils/logger.js.map +1 -0
- package/lib/typescript/BotaClient.d.ts +40 -0
- package/lib/typescript/BotaClient.d.ts.map +1 -0
- package/lib/typescript/ble/constants.d.ts +4 -0
- package/lib/typescript/ble/constants.d.ts.map +1 -0
- package/lib/typescript/ble/deviceLogs.d.ts +10 -0
- package/lib/typescript/ble/deviceLogs.d.ts.map +1 -0
- package/lib/typescript/cache/DeviceStateCache.d.ts +14 -0
- package/lib/typescript/cache/DeviceStateCache.d.ts.map +1 -0
- package/lib/typescript/client.d.ts +208 -0
- package/lib/typescript/client.d.ts.map +1 -0
- package/lib/typescript/compatibility/runtime.d.ts +11 -0
- package/lib/typescript/compatibility/runtime.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +19 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/managers/DeviceManager.d.ts +117 -0
- package/lib/typescript/managers/DeviceManager.d.ts.map +1 -0
- package/lib/typescript/managers/OTAManager.d.ts +25 -0
- package/lib/typescript/managers/OTAManager.d.ts.map +1 -0
- package/lib/typescript/managers/RecordingManager.d.ts +54 -0
- package/lib/typescript/managers/RecordingManager.d.ts.map +1 -0
- package/lib/typescript/managers/StreamingSession.d.ts +35 -0
- package/lib/typescript/managers/StreamingSession.d.ts.map +1 -0
- package/lib/typescript/managers/types.d.ts +19 -0
- package/lib/typescript/managers/types.d.ts.map +1 -0
- package/lib/typescript/models/Device.d.ts +392 -0
- package/lib/typescript/models/Device.d.ts.map +1 -0
- package/lib/typescript/models/Recording.d.ts +259 -0
- package/lib/typescript/models/Recording.d.ts.map +1 -0
- package/lib/typescript/models/Status.d.ts +106 -0
- package/lib/typescript/models/Status.d.ts.map +1 -0
- package/lib/typescript/specs/NativeBotaDeviceSDK.d.ts +393 -0
- package/lib/typescript/specs/NativeBotaDeviceSDK.d.ts.map +1 -0
- package/lib/typescript/sync/syncStatus.d.ts +123 -0
- package/lib/typescript/sync/syncStatus.d.ts.map +1 -0
- package/lib/typescript/utils/errors.d.ts +83 -0
- package/lib/typescript/utils/errors.d.ts.map +1 -0
- package/lib/typescript/utils/logger.d.ts +36 -0
- package/lib/typescript/utils/logger.d.ts.map +1 -0
- package/package.json +100 -0
- package/scripts/bota_device_sdk_spm_workaround.rb +53 -0
- package/src/BotaClient.ts +231 -0
- package/src/ble/constants.ts +3 -0
- package/src/ble/deviceLogs.ts +61 -0
- package/src/cache/DeviceStateCache.ts +20 -0
- package/src/client.ts +1410 -0
- package/src/compatibility/runtime.ts +55 -0
- package/src/index.ts +146 -0
- package/src/managers/DeviceManager.ts +927 -0
- package/src/managers/OTAManager.ts +195 -0
- package/src/managers/RecordingManager.ts +578 -0
- package/src/managers/StreamingSession.ts +212 -0
- package/src/managers/types.ts +36 -0
- package/src/models/Device.ts +484 -0
- package/src/models/Recording.ts +281 -0
- package/src/models/Status.ts +128 -0
- package/src/specs/NativeBotaDeviceSDK.ts +542 -0
- package/src/sync/syncStatus.ts +243 -0
- package/src/utils/errors.ts +327 -0
- package/src/utils/logger.ts +122 -0
|
@@ -0,0 +1,746 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createBotaDeviceSDK = exports.BotaNativeModuleError = void 0;
|
|
7
|
+
var _runtime = require("./compatibility/runtime");
|
|
8
|
+
class BotaNativeModuleError extends Error {
|
|
9
|
+
code = 'native_module_unavailable';
|
|
10
|
+
constructor() {
|
|
11
|
+
super('BotaDeviceSDK native module is unavailable. Rebuild the native application after installing the SDK.');
|
|
12
|
+
this.name = 'BotaNativeModuleError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.BotaNativeModuleError = BotaNativeModuleError;
|
|
16
|
+
const mapDiscoveredDevice = device => ({
|
|
17
|
+
id: device.id,
|
|
18
|
+
name: device.name ?? '',
|
|
19
|
+
deviceType: device.deviceType ?? 'bota_pin',
|
|
20
|
+
firmwareVersion: device.firmwareVersion ?? '',
|
|
21
|
+
macAddress: device.macAddress ?? null,
|
|
22
|
+
pairingState: device.pairingState ?? 'unpaired',
|
|
23
|
+
rssi: device.rssi,
|
|
24
|
+
discoveredAt: new Date(device.discoveredAtMs)
|
|
25
|
+
});
|
|
26
|
+
const toNativeDiscoveredDevice = device => ({
|
|
27
|
+
id: device.id,
|
|
28
|
+
name: device.name,
|
|
29
|
+
deviceType: device.deviceType,
|
|
30
|
+
firmwareVersion: device.firmwareVersion,
|
|
31
|
+
...(device.macAddress ? {
|
|
32
|
+
macAddress: device.macAddress
|
|
33
|
+
} : {}),
|
|
34
|
+
pairingState: device.pairingState,
|
|
35
|
+
rssi: device.rssi,
|
|
36
|
+
discoveredAtMs: device.discoveredAt.getTime()
|
|
37
|
+
});
|
|
38
|
+
const mapConnectedDevice = device => ({
|
|
39
|
+
...device,
|
|
40
|
+
deviceType: device.deviceType,
|
|
41
|
+
connectionState: device.connectionState
|
|
42
|
+
});
|
|
43
|
+
const toNativeConnectedDevice = device => ({
|
|
44
|
+
id: device.id,
|
|
45
|
+
serialNumber: device.serialNumber,
|
|
46
|
+
deviceType: device.deviceType,
|
|
47
|
+
firmwareVersion: device.firmwareVersion,
|
|
48
|
+
...(device.hardwareRevision === undefined ? {} : {
|
|
49
|
+
hardwareRevision: device.hardwareRevision
|
|
50
|
+
}),
|
|
51
|
+
isProvisioned: device.isProvisioned,
|
|
52
|
+
connectionState: device.connectionState,
|
|
53
|
+
mtu: device.mtu
|
|
54
|
+
});
|
|
55
|
+
const errorMessage = error => error instanceof Error ? error.message : String(error);
|
|
56
|
+
const createOpaqueId = () => 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, value => {
|
|
57
|
+
const random = Math.floor(Math.random() * 16);
|
|
58
|
+
const nibble = value === 'x' ? random : random & 0x3 | 0x8;
|
|
59
|
+
return nibble.toString(16);
|
|
60
|
+
});
|
|
61
|
+
const bytesToHex = value => Array.from(value, byte => byte.toString(16).padStart(2, '0')).join('');
|
|
62
|
+
const toNativeConnectionSettings = settings => ({
|
|
63
|
+
enabledConnections: settings.enabled_connections,
|
|
64
|
+
heartbeatEnabledConnections: settings.heartbeat_enabled_connections ?? {
|
|
65
|
+
wifi: true,
|
|
66
|
+
cellular: true
|
|
67
|
+
},
|
|
68
|
+
uploadNetworkPreference: settings.upload_network_preference,
|
|
69
|
+
powerManagement: {
|
|
70
|
+
wifiIdleTimeoutSeconds: settings.power_management?.wifi_idle_timeout_seconds ?? 180,
|
|
71
|
+
cellularIdleTimeoutSeconds: settings.power_management?.cellular_idle_timeout_seconds ?? 180
|
|
72
|
+
},
|
|
73
|
+
streamingEnabled: settings.streaming_enabled ?? true,
|
|
74
|
+
streamingFlushIntervalSeconds: settings.streaming_flush_interval_seconds ?? 60
|
|
75
|
+
});
|
|
76
|
+
const isConnectionType = value => value === 'wifi' || value === 'ble' || value === 'cellular';
|
|
77
|
+
const mapNativeConnectionSettings = settings => ({
|
|
78
|
+
enabled_connections: settings.enabledConnections,
|
|
79
|
+
heartbeat_enabled_connections: settings.heartbeatEnabledConnections,
|
|
80
|
+
upload_network_preference: settings.uploadNetworkPreference.filter(isConnectionType),
|
|
81
|
+
power_management: {
|
|
82
|
+
wifi_idle_timeout_seconds: settings.powerManagement.wifiIdleTimeoutSeconds,
|
|
83
|
+
cellular_idle_timeout_seconds: settings.powerManagement.cellularIdleTimeoutSeconds
|
|
84
|
+
},
|
|
85
|
+
streaming_enabled: settings.streamingEnabled,
|
|
86
|
+
streaming_flush_interval_seconds: settings.streamingFlushIntervalSeconds
|
|
87
|
+
});
|
|
88
|
+
const matchesScanOptions = (device, options) => {
|
|
89
|
+
if (options?.deviceTypes && !options.deviceTypes.includes(device.deviceType)) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (options?.pairingState && device.pairingState !== options.pairingState) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
if (options?.minRssi !== undefined && device.rssi < options.minRssi) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
return true;
|
|
99
|
+
};
|
|
100
|
+
const mapDeviceStatus = status => ({
|
|
101
|
+
batteryLevel: status.batteryLevel,
|
|
102
|
+
...(status.batteryMv === undefined ? {} : {
|
|
103
|
+
batteryMv: status.batteryMv
|
|
104
|
+
}),
|
|
105
|
+
storageTotalMb: status.storageTotalMb,
|
|
106
|
+
storageUsedMb: status.storageUsedMb,
|
|
107
|
+
state: status.state,
|
|
108
|
+
pendingRecordings: status.pendingRecordings,
|
|
109
|
+
lastTimeSyncAt: status.lastTimeSyncAtMs === undefined ? null : new Date(status.lastTimeSyncAtMs),
|
|
110
|
+
signalStrength: status.signalStrength,
|
|
111
|
+
flags: status.flags,
|
|
112
|
+
timestamp: status.timestamp,
|
|
113
|
+
lteStatus: status.lteStatus,
|
|
114
|
+
...(status.lteSignalQuality === undefined ? {} : {
|
|
115
|
+
lteSignalQuality: status.lteSignalQuality
|
|
116
|
+
}),
|
|
117
|
+
...(status.wifiStatus === undefined ? {} : {
|
|
118
|
+
wifiStatus: status.wifiStatus
|
|
119
|
+
}),
|
|
120
|
+
...(status.modemInfo === undefined ? {} : {
|
|
121
|
+
modemInfo: status.modemInfo
|
|
122
|
+
})
|
|
123
|
+
});
|
|
124
|
+
const mapRecording = recording => ({
|
|
125
|
+
uuid: recording.uuid,
|
|
126
|
+
startedAt: new Date(recording.startedAtMs),
|
|
127
|
+
durationMs: recording.durationMs,
|
|
128
|
+
fileSizeBytes: recording.fileSize,
|
|
129
|
+
codec: recording.codec,
|
|
130
|
+
isEncrypted: recording.isEncrypted
|
|
131
|
+
});
|
|
132
|
+
const toNativeRecording = recording => ({
|
|
133
|
+
uuid: recording.uuid,
|
|
134
|
+
startedAtMs: recording.startedAt.getTime(),
|
|
135
|
+
durationMs: recording.durationMs,
|
|
136
|
+
fileSize: recording.fileSizeBytes,
|
|
137
|
+
codec: recording.codec,
|
|
138
|
+
isEncrypted: recording.isEncrypted ?? false
|
|
139
|
+
});
|
|
140
|
+
const mapRecordingProgress = progress => ({
|
|
141
|
+
completedBytes: progress.completedUnits,
|
|
142
|
+
totalBytes: progress.totalUnits
|
|
143
|
+
});
|
|
144
|
+
const mapEncryptedUploadV2Progress = progress => ({
|
|
145
|
+
recordingUuid: progress.recordingUuid,
|
|
146
|
+
phase: progress.phase,
|
|
147
|
+
completedBytes: progress.completedBytes,
|
|
148
|
+
totalBytes: progress.totalBytes,
|
|
149
|
+
...(progress.checkpointRevision === undefined ? {} : {
|
|
150
|
+
checkpointRevision: progress.checkpointRevision
|
|
151
|
+
}),
|
|
152
|
+
...(progress.errorCode === undefined ? {} : {
|
|
153
|
+
errorCode: progress.errorCode
|
|
154
|
+
}),
|
|
155
|
+
...(progress.retryable === undefined ? {} : {
|
|
156
|
+
retryable: progress.retryable
|
|
157
|
+
}),
|
|
158
|
+
...(progress.protocolStatus === undefined ? {} : {
|
|
159
|
+
protocolStatus: progress.protocolStatus
|
|
160
|
+
})
|
|
161
|
+
});
|
|
162
|
+
const mapFirmwareProgress = progress => ({
|
|
163
|
+
phase: progress.phase,
|
|
164
|
+
completedBytes: progress.completedUnits,
|
|
165
|
+
totalBytes: progress.totalUnits
|
|
166
|
+
});
|
|
167
|
+
const isWiFiStatus = value => value === 'idle' || value === 'connecting' || value === 'connected' || value === 'failed' || value === 'disconnected';
|
|
168
|
+
const mapWiFiStatus = status => ({
|
|
169
|
+
status: isWiFiStatus(status.status) ? status.status : 'idle',
|
|
170
|
+
...(status.signalStrength === undefined ? {} : {
|
|
171
|
+
signalStrength: status.signalStrength
|
|
172
|
+
}),
|
|
173
|
+
...(status.ssid === undefined ? {} : {
|
|
174
|
+
ssid: status.ssid
|
|
175
|
+
}),
|
|
176
|
+
...(status.lastError === undefined ? {} : {
|
|
177
|
+
lastError: status.lastError
|
|
178
|
+
})
|
|
179
|
+
});
|
|
180
|
+
const mapRecordingControlResult = result => ({
|
|
181
|
+
success: result.success,
|
|
182
|
+
...(result.error === undefined ? {} : {
|
|
183
|
+
error: result.error
|
|
184
|
+
})
|
|
185
|
+
});
|
|
186
|
+
const mapRecordingState = state => ({
|
|
187
|
+
active: state.active,
|
|
188
|
+
...(state.recordingId === undefined ? {} : {
|
|
189
|
+
recordingId: state.recordingId
|
|
190
|
+
}),
|
|
191
|
+
initiatedBy: state.initiatedBy === 'remote' ? 'remote' : 'local'
|
|
192
|
+
});
|
|
193
|
+
const mapWiFiConfigResult = result => {
|
|
194
|
+
if (result.success) return {
|
|
195
|
+
success: true
|
|
196
|
+
};
|
|
197
|
+
switch (result.error) {
|
|
198
|
+
case 'invalid_grant':
|
|
199
|
+
case 'grant_expired':
|
|
200
|
+
case 'decryption_error':
|
|
201
|
+
case 'storage_error':
|
|
202
|
+
return {
|
|
203
|
+
success: false,
|
|
204
|
+
error: result.error
|
|
205
|
+
};
|
|
206
|
+
default:
|
|
207
|
+
return {
|
|
208
|
+
success: false,
|
|
209
|
+
error: 'unknown'
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const mapWiFiScanResult = result => ({
|
|
214
|
+
networks: result.networks.map(network => ({
|
|
215
|
+
...network
|
|
216
|
+
})),
|
|
217
|
+
currentSsid: result.currentSsid ?? null
|
|
218
|
+
});
|
|
219
|
+
const requiredUploadOwnershipField = (value, field) => {
|
|
220
|
+
if (value === undefined) {
|
|
221
|
+
throw new Error(`native upload ownership result is missing ${field}`);
|
|
222
|
+
}
|
|
223
|
+
return value;
|
|
224
|
+
};
|
|
225
|
+
const mapUploadOwnershipResult = result => {
|
|
226
|
+
switch (result.kind) {
|
|
227
|
+
case 'device_upload_completed':
|
|
228
|
+
return {
|
|
229
|
+
kind: 'device_upload_completed'
|
|
230
|
+
};
|
|
231
|
+
case 'device_upload_preserved':
|
|
232
|
+
return {
|
|
233
|
+
kind: 'device_upload_preserved',
|
|
234
|
+
uploadId: requiredUploadOwnershipField(result.uploadId, 'uploadId')
|
|
235
|
+
};
|
|
236
|
+
case 'bluetooth_fallback':
|
|
237
|
+
return {
|
|
238
|
+
kind: 'bluetooth_fallback',
|
|
239
|
+
recordingUuid: requiredUploadOwnershipField(result.recordingUuid, 'recordingUuid'),
|
|
240
|
+
uploadId: requiredUploadOwnershipField(result.uploadId, 'uploadId'),
|
|
241
|
+
destinationId: requiredUploadOwnershipField(result.destinationId, 'destinationId')
|
|
242
|
+
};
|
|
243
|
+
default:
|
|
244
|
+
throw new Error(`unsupported native upload ownership result: ${result.kind}`);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
const toNativeRecordingUploadRequest = task => ({
|
|
248
|
+
taskId: task.id,
|
|
249
|
+
recordingId: task.recordingId,
|
|
250
|
+
deviceId: task.deviceId,
|
|
251
|
+
localPath: task.localPath,
|
|
252
|
+
uploadUrl: task.uploadUrl,
|
|
253
|
+
...(task.uploadToken ? {
|
|
254
|
+
uploadToken: task.uploadToken
|
|
255
|
+
} : {}),
|
|
256
|
+
...(task.completeUrl ? {
|
|
257
|
+
completeUrl: task.completeUrl
|
|
258
|
+
} : {}),
|
|
259
|
+
...(task.contentType ? {
|
|
260
|
+
contentType: task.contentType
|
|
261
|
+
} : {}),
|
|
262
|
+
...(task.contentSha256 ? {
|
|
263
|
+
contentSha256: task.contentSha256
|
|
264
|
+
} : {}),
|
|
265
|
+
...(task.relay ? {
|
|
266
|
+
relayUrl: task.relay.url,
|
|
267
|
+
relayBearerToken: task.relay.bearerToken
|
|
268
|
+
} : {})
|
|
269
|
+
});
|
|
270
|
+
const parseUploadQueue = serialized => {
|
|
271
|
+
const value = JSON.parse(serialized || '[]');
|
|
272
|
+
if (!Array.isArray(value)) return [];
|
|
273
|
+
return value.map(task => {
|
|
274
|
+
const candidate = task;
|
|
275
|
+
return {
|
|
276
|
+
...candidate,
|
|
277
|
+
createdAt: new Date(candidate.createdAt),
|
|
278
|
+
updatedAt: new Date(candidate.updatedAt)
|
|
279
|
+
};
|
|
280
|
+
});
|
|
281
|
+
};
|
|
282
|
+
const createBotaDeviceSDK = nativeModule => {
|
|
283
|
+
const requireNativeModule = () => {
|
|
284
|
+
if (!nativeModule) throw new BotaNativeModuleError();
|
|
285
|
+
return nativeModule;
|
|
286
|
+
};
|
|
287
|
+
const devices = {
|
|
288
|
+
async startScan(options, onDevice) {
|
|
289
|
+
const module = requireNativeModule();
|
|
290
|
+
const subscription = module.onDeviceDiscovered(device => {
|
|
291
|
+
const discovered = mapDiscoveredDevice(device);
|
|
292
|
+
if (matchesScanOptions(discovered, options)) onDevice(discovered);
|
|
293
|
+
});
|
|
294
|
+
try {
|
|
295
|
+
await module.startScan(options?.timeout ?? 30_000, options?.allowDuplicates ?? false);
|
|
296
|
+
} catch (error) {
|
|
297
|
+
subscription.remove();
|
|
298
|
+
throw error;
|
|
299
|
+
}
|
|
300
|
+
return subscription;
|
|
301
|
+
},
|
|
302
|
+
async stopScan() {
|
|
303
|
+
await requireNativeModule().stopScan();
|
|
304
|
+
},
|
|
305
|
+
async connect(device) {
|
|
306
|
+
return mapConnectedDevice(await requireNativeModule().connectSelected(toNativeDiscoveredDevice(device)));
|
|
307
|
+
},
|
|
308
|
+
async reconnect(serialNumber, options = {}) {
|
|
309
|
+
return mapConnectedDevice(await requireNativeModule().reconnect(serialNumber, {
|
|
310
|
+
scanTimeoutMs: options.scanTimeout ?? 10_000,
|
|
311
|
+
connectionTimeoutMs: 10_000
|
|
312
|
+
}));
|
|
313
|
+
},
|
|
314
|
+
async disconnect() {
|
|
315
|
+
await requireNativeModule().disconnect();
|
|
316
|
+
},
|
|
317
|
+
async readStatus() {
|
|
318
|
+
return mapDeviceStatus(await requireNativeModule().readStatus());
|
|
319
|
+
},
|
|
320
|
+
async subscribeToStatus(onStatus) {
|
|
321
|
+
const module = requireNativeModule();
|
|
322
|
+
const eventSubscription = module.onDeviceStatusUpdated(status => {
|
|
323
|
+
onStatus(mapDeviceStatus(status));
|
|
324
|
+
});
|
|
325
|
+
try {
|
|
326
|
+
await module.startStatusUpdates();
|
|
327
|
+
} catch (error) {
|
|
328
|
+
eventSubscription.remove();
|
|
329
|
+
throw error;
|
|
330
|
+
}
|
|
331
|
+
let removed = false;
|
|
332
|
+
return {
|
|
333
|
+
async remove() {
|
|
334
|
+
if (removed) return;
|
|
335
|
+
removed = true;
|
|
336
|
+
eventSubscription.remove();
|
|
337
|
+
await module.stopStatusUpdates();
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
const provisioning = {
|
|
343
|
+
async provision(device, provider) {
|
|
344
|
+
const module = requireNativeModule();
|
|
345
|
+
const subscription = module.onProvisioningMaterialRequested(request => {
|
|
346
|
+
void (async () => {
|
|
347
|
+
try {
|
|
348
|
+
const material = await provider({
|
|
349
|
+
serialNumber: request.serialNumber,
|
|
350
|
+
nonce: request.nonce,
|
|
351
|
+
devicePublicKey: request.devicePublicKey
|
|
352
|
+
});
|
|
353
|
+
await module.resolveProvisioningMaterial(request.requestId, material);
|
|
354
|
+
} catch (error) {
|
|
355
|
+
await module.rejectApplicationMaterial(request.requestId, errorMessage(error));
|
|
356
|
+
}
|
|
357
|
+
})().catch(() => {});
|
|
358
|
+
});
|
|
359
|
+
try {
|
|
360
|
+
await module.provision(toNativeConnectedDevice(device));
|
|
361
|
+
} finally {
|
|
362
|
+
subscription.remove();
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
async deprovision(device, grantBlob) {
|
|
366
|
+
const result = await requireNativeModule().deprovision(toNativeConnectedDevice(device), grantBlob);
|
|
367
|
+
return result.error === undefined ? {
|
|
368
|
+
success: result.success
|
|
369
|
+
} : {
|
|
370
|
+
success: result.success,
|
|
371
|
+
error: result.error
|
|
372
|
+
};
|
|
373
|
+
},
|
|
374
|
+
async readConnectionSettings(device) {
|
|
375
|
+
return mapNativeConnectionSettings(await requireNativeModule().readConnectionSettings(toNativeConnectedDevice(device)));
|
|
376
|
+
},
|
|
377
|
+
async writeConnectionSettings(device, settings) {
|
|
378
|
+
await requireNativeModule().writeConnectionSettings(toNativeConnectedDevice(device), toNativeConnectionSettings(settings));
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
const controls = {
|
|
382
|
+
async isProvisioned(device) {
|
|
383
|
+
return requireNativeModule().isProvisioned(toNativeConnectedDevice(device));
|
|
384
|
+
},
|
|
385
|
+
async readPublicKey(device) {
|
|
386
|
+
return requireNativeModule().readPublicKey(toNativeConnectedDevice(device));
|
|
387
|
+
},
|
|
388
|
+
async readAuthNonce(device) {
|
|
389
|
+
return requireNativeModule().readAuthNonce(toNativeConnectedDevice(device));
|
|
390
|
+
},
|
|
391
|
+
async setApiEndpoint(device, environment) {
|
|
392
|
+
await requireNativeModule().setApiEndpoint(toNativeConnectedDevice(device), environment);
|
|
393
|
+
},
|
|
394
|
+
async deliverCertificate(device, certificatePem, privateKeyPem) {
|
|
395
|
+
await requireNativeModule().deliverCertificate(toNativeConnectedDevice(device), certificatePem, privateKeyPem);
|
|
396
|
+
},
|
|
397
|
+
async deliverBackendPublicKey(device, publicKey) {
|
|
398
|
+
await requireNativeModule().deliverBackendPublicKey(toNativeConnectedDevice(device), bytesToHex(publicKey));
|
|
399
|
+
},
|
|
400
|
+
async writeGrant(device, grantBlob) {
|
|
401
|
+
await requireNativeModule().writeGrant(toNativeConnectedDevice(device), grantBlob);
|
|
402
|
+
},
|
|
403
|
+
async syncTime(device) {
|
|
404
|
+
await requireNativeModule().syncTime(toNativeConnectedDevice(device));
|
|
405
|
+
},
|
|
406
|
+
async requestStartRecording(device, grantBlob) {
|
|
407
|
+
return mapRecordingControlResult(await requireNativeModule().requestStartRecording(toNativeConnectedDevice(device), grantBlob));
|
|
408
|
+
},
|
|
409
|
+
async requestStopRecording(device, grantBlob) {
|
|
410
|
+
return mapRecordingControlResult(await requireNativeModule().requestStopRecording(toNativeConnectedDevice(device), grantBlob));
|
|
411
|
+
},
|
|
412
|
+
async readRecordingState(device) {
|
|
413
|
+
return mapRecordingState(await requireNativeModule().readRecordingState(toNativeConnectedDevice(device)));
|
|
414
|
+
},
|
|
415
|
+
async subscribeToRecordingState(device, onState) {
|
|
416
|
+
const module = requireNativeModule();
|
|
417
|
+
const eventSubscription = module.onRecordingStateUpdated(state => {
|
|
418
|
+
onState(mapRecordingState(state));
|
|
419
|
+
});
|
|
420
|
+
try {
|
|
421
|
+
await module.startRecordingStateUpdates(toNativeConnectedDevice(device));
|
|
422
|
+
} catch (error) {
|
|
423
|
+
eventSubscription.remove();
|
|
424
|
+
throw error;
|
|
425
|
+
}
|
|
426
|
+
let removed = false;
|
|
427
|
+
return {
|
|
428
|
+
async remove() {
|
|
429
|
+
if (removed) return;
|
|
430
|
+
removed = true;
|
|
431
|
+
eventSubscription.remove();
|
|
432
|
+
await module.stopRecordingStateUpdates();
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
const factoryReset = {
|
|
438
|
+
async factoryReset(device, options, provider, persistResult) {
|
|
439
|
+
const module = requireNativeModule();
|
|
440
|
+
const grantSubscription = module.onFactoryResetGrantRequested(request => {
|
|
441
|
+
void (async () => {
|
|
442
|
+
try {
|
|
443
|
+
const grantBlob = await provider({
|
|
444
|
+
serialNumber: request.serialNumber,
|
|
445
|
+
nonce: request.nonce,
|
|
446
|
+
commandId: request.commandId,
|
|
447
|
+
bindingGeneration: request.bindingGeneration
|
|
448
|
+
});
|
|
449
|
+
await module.resolveFactoryResetGrant(request.requestId, grantBlob);
|
|
450
|
+
} catch (error) {
|
|
451
|
+
await module.rejectApplicationMaterial(request.requestId, errorMessage(error));
|
|
452
|
+
}
|
|
453
|
+
})().catch(() => {});
|
|
454
|
+
});
|
|
455
|
+
const persistenceSubscription = persistResult ? module.onFactoryResetResultPersistenceRequested(request => {
|
|
456
|
+
void (async () => {
|
|
457
|
+
try {
|
|
458
|
+
await persistResult({
|
|
459
|
+
success: true,
|
|
460
|
+
localRecordingsDeleted: request.localRecordingsDeleted
|
|
461
|
+
});
|
|
462
|
+
await module.resolveFactoryResetResultPersistence(request.requestId);
|
|
463
|
+
} catch (error) {
|
|
464
|
+
await module.rejectApplicationMaterial(request.requestId, errorMessage(error));
|
|
465
|
+
}
|
|
466
|
+
})().catch(() => {});
|
|
467
|
+
}) : null;
|
|
468
|
+
try {
|
|
469
|
+
return await module.factoryReset(toNativeConnectedDevice(device), options.commandId, options.bindingGeneration, persistResult !== undefined);
|
|
470
|
+
} finally {
|
|
471
|
+
grantSubscription.remove();
|
|
472
|
+
persistenceSubscription?.remove();
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
async resumePendingFactoryReset(device, currentBindingGeneration, persistResult) {
|
|
476
|
+
const module = requireNativeModule();
|
|
477
|
+
const subscription = persistResult ? module.onFactoryResetResultPersistenceRequested(request => {
|
|
478
|
+
void (async () => {
|
|
479
|
+
try {
|
|
480
|
+
await persistResult({
|
|
481
|
+
success: true,
|
|
482
|
+
localRecordingsDeleted: request.localRecordingsDeleted
|
|
483
|
+
});
|
|
484
|
+
await module.resolveFactoryResetResultPersistence(request.requestId);
|
|
485
|
+
} catch (error) {
|
|
486
|
+
await module.rejectApplicationMaterial(request.requestId, errorMessage(error));
|
|
487
|
+
}
|
|
488
|
+
})().catch(() => {});
|
|
489
|
+
}) : null;
|
|
490
|
+
try {
|
|
491
|
+
return await module.resumePendingFactoryReset(toNativeConnectedDevice(device), currentBindingGeneration, persistResult !== undefined);
|
|
492
|
+
} finally {
|
|
493
|
+
subscription?.remove();
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
const recordings = {
|
|
498
|
+
async listRecordings(device) {
|
|
499
|
+
const values = await requireNativeModule().listRecordings(toNativeConnectedDevice(device));
|
|
500
|
+
return values.map(mapRecording);
|
|
501
|
+
},
|
|
502
|
+
async syncRecording(device, recording, onProgress, sinkId) {
|
|
503
|
+
const module = requireNativeModule();
|
|
504
|
+
const subscription = module.onRecordingTransferProgress(progress => {
|
|
505
|
+
onProgress?.(mapRecordingProgress(progress));
|
|
506
|
+
});
|
|
507
|
+
try {
|
|
508
|
+
return await module.syncRecording(toNativeConnectedDevice(device), toNativeRecording(recording), sinkId ?? createOpaqueId());
|
|
509
|
+
} finally {
|
|
510
|
+
subscription.remove();
|
|
511
|
+
}
|
|
512
|
+
},
|
|
513
|
+
async syncEncryptedRecordingV2(device, recording, provider, onProgress) {
|
|
514
|
+
const module = requireNativeModule();
|
|
515
|
+
const operationId = createOpaqueId();
|
|
516
|
+
const profileSubscription = module.onEncryptedUploadV2ProfileRequested(request => {
|
|
517
|
+
if (request.operationId !== operationId) return;
|
|
518
|
+
void (async () => {
|
|
519
|
+
try {
|
|
520
|
+
const decision = await provider({
|
|
521
|
+
recording: request.recording,
|
|
522
|
+
capability: request.capability,
|
|
523
|
+
...(request.checkpoint === undefined ? {} : {
|
|
524
|
+
checkpoint: request.checkpoint
|
|
525
|
+
})
|
|
526
|
+
});
|
|
527
|
+
if (decision.profile !== 'encrypted_upload_v2') {
|
|
528
|
+
throw new Error('encrypted upload v2 requires an explicit v2 profile');
|
|
529
|
+
}
|
|
530
|
+
await module.resolveEncryptedUploadV2Profile(request.requestId, decision);
|
|
531
|
+
} catch (error) {
|
|
532
|
+
await module.rejectEncryptedUploadV2Profile(request.requestId, 'application_material_rejected');
|
|
533
|
+
}
|
|
534
|
+
})().catch(() => {});
|
|
535
|
+
});
|
|
536
|
+
const progressSubscription = module.onEncryptedUploadV2Progress(progress => {
|
|
537
|
+
if (progress.operationId !== operationId) return;
|
|
538
|
+
onProgress?.(mapEncryptedUploadV2Progress(progress));
|
|
539
|
+
});
|
|
540
|
+
try {
|
|
541
|
+
await module.syncEncryptedRecordingV2(toNativeConnectedDevice(device), recording, operationId);
|
|
542
|
+
} finally {
|
|
543
|
+
profileSubscription.remove();
|
|
544
|
+
progressSubscription.remove();
|
|
545
|
+
}
|
|
546
|
+
},
|
|
547
|
+
async uploadRecordingFile(task, onProgress) {
|
|
548
|
+
const module = requireNativeModule();
|
|
549
|
+
const subscription = module.onRecordingUploadProgress(progress => {
|
|
550
|
+
if (progress.taskId !== task.id) return;
|
|
551
|
+
onProgress?.({
|
|
552
|
+
completedBytes: progress.completedBytes,
|
|
553
|
+
totalBytes: progress.totalBytes
|
|
554
|
+
});
|
|
555
|
+
});
|
|
556
|
+
try {
|
|
557
|
+
await module.uploadRecordingFile(toNativeRecordingUploadRequest(task));
|
|
558
|
+
} finally {
|
|
559
|
+
subscription.remove();
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
async confirmRecording(device, recordingUuid) {
|
|
563
|
+
await requireNativeModule().confirmRecording(toNativeConnectedDevice(device), recordingUuid);
|
|
564
|
+
},
|
|
565
|
+
async cancelRecordingUpload(taskId) {
|
|
566
|
+
await requireNativeModule().cancelRecordingUpload(taskId);
|
|
567
|
+
},
|
|
568
|
+
async loadUploadQueue() {
|
|
569
|
+
return parseUploadQueue(await requireNativeModule().loadCompatibilityUploadQueue());
|
|
570
|
+
},
|
|
571
|
+
async saveUploadQueue(tasks) {
|
|
572
|
+
await requireNativeModule().saveCompatibilityUploadQueue(JSON.stringify(tasks));
|
|
573
|
+
},
|
|
574
|
+
async destroyCompatibilityOperations() {
|
|
575
|
+
await requireNativeModule().stopAllRecordingOperations();
|
|
576
|
+
},
|
|
577
|
+
async observeUploadOwnership(device, request, onProgress) {
|
|
578
|
+
const module = requireNativeModule();
|
|
579
|
+
const subscription = module.onUploadOwnershipProgress(progress => {
|
|
580
|
+
onProgress?.(mapRecordingProgress(progress));
|
|
581
|
+
});
|
|
582
|
+
try {
|
|
583
|
+
return mapUploadOwnershipResult(await module.observeUploadOwnership(toNativeConnectedDevice(device), request));
|
|
584
|
+
} finally {
|
|
585
|
+
subscription.remove();
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
const ota = {
|
|
590
|
+
async updateFirmware(device, image, onProgress) {
|
|
591
|
+
const module = requireNativeModule();
|
|
592
|
+
const subscription = module.onFirmwareUpdateProgress(progress => {
|
|
593
|
+
onProgress?.(mapFirmwareProgress(progress));
|
|
594
|
+
});
|
|
595
|
+
try {
|
|
596
|
+
await module.updateFirmware(toNativeConnectedDevice(device), {
|
|
597
|
+
version: image.version,
|
|
598
|
+
sizeUnits: image.sizeBytes,
|
|
599
|
+
crc32: image.crc32,
|
|
600
|
+
url: image.url
|
|
601
|
+
});
|
|
602
|
+
} finally {
|
|
603
|
+
subscription.remove();
|
|
604
|
+
}
|
|
605
|
+
},
|
|
606
|
+
async cancelFirmwareUpdate() {
|
|
607
|
+
await requireNativeModule().cancelFirmwareUpdate();
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
const streaming = {
|
|
611
|
+
async startStreaming(device, request, handlers) {
|
|
612
|
+
const module = requireNativeModule();
|
|
613
|
+
const progressSubscription = module.onStreamingProgress(progress => {
|
|
614
|
+
if (progress.sessionId !== request.sessionId) return;
|
|
615
|
+
handlers.onProgress({
|
|
616
|
+
state: progress.state,
|
|
617
|
+
bytesReceived: progress.bytesReceived,
|
|
618
|
+
chunksUploaded: progress.chunksUploaded
|
|
619
|
+
});
|
|
620
|
+
});
|
|
621
|
+
const destinationSubscription = module.onStreamingChunkDestinationRequested(nativeRequest => {
|
|
622
|
+
if (nativeRequest.sessionId !== request.sessionId) return;
|
|
623
|
+
void handlers.resolveChunkDestination({
|
|
624
|
+
sequence: nativeRequest.sequence,
|
|
625
|
+
encrypted: nativeRequest.encrypted
|
|
626
|
+
}).then(destination => module.resolveStreamingChunkDestination(nativeRequest.requestId, destination), error => module.rejectStreamingChunkDestination(nativeRequest.requestId, errorMessage(error))).catch(() => {});
|
|
627
|
+
});
|
|
628
|
+
const finalizeSubscription = module.onStreamingFinalizeRequested(nativeRequest => {
|
|
629
|
+
if (nativeRequest.sessionId !== request.sessionId) return;
|
|
630
|
+
void handlers.finalize({
|
|
631
|
+
totalChunks: nativeRequest.totalChunks,
|
|
632
|
+
durationMs: nativeRequest.durationMs,
|
|
633
|
+
fileSizeBytes: nativeRequest.fileSizeBytes,
|
|
634
|
+
encrypted: nativeRequest.encrypted
|
|
635
|
+
}).then(() => module.resolveStreamingFinalize(nativeRequest.requestId), error => module.rejectStreamingFinalize(nativeRequest.requestId, errorMessage(error))).catch(() => {});
|
|
636
|
+
});
|
|
637
|
+
try {
|
|
638
|
+
return await module.startStreaming(toNativeConnectedDevice(device), request);
|
|
639
|
+
} finally {
|
|
640
|
+
progressSubscription.remove();
|
|
641
|
+
destinationSubscription.remove();
|
|
642
|
+
finalizeSubscription.remove();
|
|
643
|
+
}
|
|
644
|
+
},
|
|
645
|
+
async abortStreaming(sessionId) {
|
|
646
|
+
await requireNativeModule().abortStreaming(sessionId);
|
|
647
|
+
}
|
|
648
|
+
};
|
|
649
|
+
const logs = {
|
|
650
|
+
async subscribe(device, onLine) {
|
|
651
|
+
const module = requireNativeModule();
|
|
652
|
+
const eventSubscription = module.onDeviceLog(line => {
|
|
653
|
+
onLine({
|
|
654
|
+
level: 'debug',
|
|
655
|
+
message: line.message,
|
|
656
|
+
isBacklog: line.isBacklog
|
|
657
|
+
});
|
|
658
|
+
});
|
|
659
|
+
try {
|
|
660
|
+
await module.startDeviceLogs(toNativeConnectedDevice(device));
|
|
661
|
+
} catch (error) {
|
|
662
|
+
eventSubscription.remove();
|
|
663
|
+
throw error;
|
|
664
|
+
}
|
|
665
|
+
let removed = false;
|
|
666
|
+
return {
|
|
667
|
+
async remove() {
|
|
668
|
+
if (removed) return;
|
|
669
|
+
removed = true;
|
|
670
|
+
eventSubscription.remove();
|
|
671
|
+
await module.stopDeviceLogs();
|
|
672
|
+
}
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
};
|
|
676
|
+
const wifi = {
|
|
677
|
+
async configure(device, credentials, grant) {
|
|
678
|
+
return mapWiFiConfigResult(await requireNativeModule().configureWiFi(toNativeConnectedDevice(device), credentials.ssid, credentials.password, grant.grantBlob));
|
|
679
|
+
},
|
|
680
|
+
async disconnect(device) {
|
|
681
|
+
return mapWiFiConfigResult(await requireNativeModule().disconnectWiFi(toNativeConnectedDevice(device)));
|
|
682
|
+
},
|
|
683
|
+
async readStatus(device) {
|
|
684
|
+
return mapWiFiStatus(await requireNativeModule().readWiFiStatus(toNativeConnectedDevice(device)));
|
|
685
|
+
},
|
|
686
|
+
async subscribeToStatus(device, onStatus) {
|
|
687
|
+
const module = requireNativeModule();
|
|
688
|
+
const eventSubscription = module.onWiFiStatusUpdated(status => {
|
|
689
|
+
onStatus(mapWiFiStatus(status));
|
|
690
|
+
});
|
|
691
|
+
try {
|
|
692
|
+
await module.startWiFiStatusUpdates(toNativeConnectedDevice(device));
|
|
693
|
+
} catch (error) {
|
|
694
|
+
eventSubscription.remove();
|
|
695
|
+
throw error;
|
|
696
|
+
}
|
|
697
|
+
let removed = false;
|
|
698
|
+
return {
|
|
699
|
+
async remove() {
|
|
700
|
+
if (removed) return;
|
|
701
|
+
removed = true;
|
|
702
|
+
eventSubscription.remove();
|
|
703
|
+
await module.stopWiFiStatusUpdates();
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
},
|
|
707
|
+
async scanNetworks(device) {
|
|
708
|
+
return mapWiFiScanResult(await requireNativeModule().scanWiFiNetworks(toNativeConnectedDevice(device)));
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
const client = {
|
|
712
|
+
controls,
|
|
713
|
+
devices,
|
|
714
|
+
factoryReset,
|
|
715
|
+
logs,
|
|
716
|
+
ota,
|
|
717
|
+
provisioning,
|
|
718
|
+
recordings,
|
|
719
|
+
streaming,
|
|
720
|
+
wifi,
|
|
721
|
+
async configure(configuration = {}) {
|
|
722
|
+
const nativeConfiguration = {
|
|
723
|
+
logLevel: configuration.logLevel ?? 'warn',
|
|
724
|
+
...(configuration.applicationSupportDirectory ? {
|
|
725
|
+
applicationSupportDirectory: configuration.applicationSupportDirectory
|
|
726
|
+
} : {})
|
|
727
|
+
};
|
|
728
|
+
await requireNativeModule().configure(nativeConfiguration);
|
|
729
|
+
},
|
|
730
|
+
async destroy() {
|
|
731
|
+
await requireNativeModule().destroy();
|
|
732
|
+
},
|
|
733
|
+
async getCapabilities() {
|
|
734
|
+
return requireNativeModule().getCapabilities();
|
|
735
|
+
},
|
|
736
|
+
async getState() {
|
|
737
|
+
return await requireNativeModule().getState();
|
|
738
|
+
}
|
|
739
|
+
};
|
|
740
|
+
nativeModule?.onDeviceDisconnected?.(event => {
|
|
741
|
+
(0, _runtime.reportCompatibilityDisconnection)(client, event.error ? new Error(event.error) : undefined);
|
|
742
|
+
});
|
|
743
|
+
return client;
|
|
744
|
+
};
|
|
745
|
+
exports.createBotaDeviceSDK = createBotaDeviceSDK;
|
|
746
|
+
//# sourceMappingURL=client.js.map
|