@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.
Files changed (173) hide show
  1. package/BotaDeviceSDK.podspec +55 -0
  2. package/LICENSE +21 -0
  3. package/README.md +101 -0
  4. package/android/build.gradle +76 -0
  5. package/android/src/main/AndroidManifest.xml +1 -0
  6. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidDevices.kt +172 -0
  7. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidLifecycle.kt +100 -0
  8. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidLogs.kt +82 -0
  9. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidModels.kt +476 -0
  10. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidOTA.kt +58 -0
  11. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidRecordingUploads.kt +180 -0
  12. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidRecordings.kt +751 -0
  13. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidSecurity.kt +509 -0
  14. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidWiFi.kt +125 -0
  15. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKEncryptedUploadV2Materials.kt +46 -0
  16. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKModule.kt +723 -0
  17. package/android/src/main/java/dev/bota/sdk/reactnative/BotaDeviceSDKPackage.kt +33 -0
  18. package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidDevicesTest.kt +211 -0
  19. package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidLifecycleTest.kt +132 -0
  20. package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidLogsTest.kt +57 -0
  21. package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidOTATest.kt +75 -0
  22. package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidRecordingUploadsTest.kt +147 -0
  23. package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidRecordingsTest.kt +355 -0
  24. package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidSecurityTest.kt +523 -0
  25. package/android/src/test/java/dev/bota/sdk/reactnative/BotaDeviceSDKAndroidWiFiTest.kt +100 -0
  26. package/generated/codegen-contract.json +3593 -0
  27. package/ios/BotaDeviceSDK.mm +1300 -0
  28. package/ios/BotaDeviceSDKAppleBridge.swift +2260 -0
  29. package/ios/BotaDeviceSDKAppleDevices.swift +191 -0
  30. package/ios/BotaDeviceSDKAppleLifecycle.swift +167 -0
  31. package/ios/BotaDeviceSDKAppleLogs.swift +79 -0
  32. package/ios/BotaDeviceSDKAppleOTA.swift +73 -0
  33. package/ios/BotaDeviceSDKAppleRecordingUploads.swift +178 -0
  34. package/ios/BotaDeviceSDKAppleRecordings.swift +670 -0
  35. package/ios/BotaDeviceSDKAppleSecurity.swift +586 -0
  36. package/ios/BotaDeviceSDKAppleWiFi.swift +128 -0
  37. package/ios/BotaDeviceSDKEncryptedUploadV2Materials.swift +99 -0
  38. package/lib/commonjs/BotaClient.js +194 -0
  39. package/lib/commonjs/BotaClient.js.map +1 -0
  40. package/lib/commonjs/ble/constants.js +10 -0
  41. package/lib/commonjs/ble/constants.js.map +1 -0
  42. package/lib/commonjs/ble/deviceLogs.js +50 -0
  43. package/lib/commonjs/ble/deviceLogs.js.map +1 -0
  44. package/lib/commonjs/cache/DeviceStateCache.js +6 -0
  45. package/lib/commonjs/cache/DeviceStateCache.js.map +1 -0
  46. package/lib/commonjs/client.js +746 -0
  47. package/lib/commonjs/client.js.map +1 -0
  48. package/lib/commonjs/compatibility/runtime.js +44 -0
  49. package/lib/commonjs/compatibility/runtime.js.map +1 -0
  50. package/lib/commonjs/index.js +123 -0
  51. package/lib/commonjs/index.js.map +1 -0
  52. package/lib/commonjs/managers/DeviceManager.js +647 -0
  53. package/lib/commonjs/managers/DeviceManager.js.map +1 -0
  54. package/lib/commonjs/managers/OTAManager.js +140 -0
  55. package/lib/commonjs/managers/OTAManager.js.map +1 -0
  56. package/lib/commonjs/managers/RecordingManager.js +444 -0
  57. package/lib/commonjs/managers/RecordingManager.js.map +1 -0
  58. package/lib/commonjs/managers/StreamingSession.js +175 -0
  59. package/lib/commonjs/managers/StreamingSession.js.map +1 -0
  60. package/lib/commonjs/managers/types.js +6 -0
  61. package/lib/commonjs/managers/types.js.map +1 -0
  62. package/lib/commonjs/models/Device.js +2 -0
  63. package/lib/commonjs/models/Device.js.map +1 -0
  64. package/lib/commonjs/models/Recording.js +2 -0
  65. package/lib/commonjs/models/Recording.js.map +1 -0
  66. package/lib/commonjs/models/Status.js +6 -0
  67. package/lib/commonjs/models/Status.js.map +1 -0
  68. package/lib/commonjs/package.json +1 -0
  69. package/lib/commonjs/specs/NativeBotaDeviceSDK.js +9 -0
  70. package/lib/commonjs/specs/NativeBotaDeviceSDK.js.map +1 -0
  71. package/lib/commonjs/sync/syncStatus.js +178 -0
  72. package/lib/commonjs/sync/syncStatus.js.map +1 -0
  73. package/lib/commonjs/utils/errors.js +194 -0
  74. package/lib/commonjs/utils/errors.js.map +1 -0
  75. package/lib/commonjs/utils/logger.js +84 -0
  76. package/lib/commonjs/utils/logger.js.map +1 -0
  77. package/lib/module/BotaClient.js +189 -0
  78. package/lib/module/BotaClient.js.map +1 -0
  79. package/lib/module/ble/constants.js +6 -0
  80. package/lib/module/ble/constants.js.map +1 -0
  81. package/lib/module/ble/deviceLogs.js +45 -0
  82. package/lib/module/ble/deviceLogs.js.map +1 -0
  83. package/lib/module/cache/DeviceStateCache.js +4 -0
  84. package/lib/module/cache/DeviceStateCache.js.map +1 -0
  85. package/lib/module/client.js +740 -0
  86. package/lib/module/client.js.map +1 -0
  87. package/lib/module/compatibility/runtime.js +35 -0
  88. package/lib/module/compatibility/runtime.js.map +1 -0
  89. package/lib/module/index.js +17 -0
  90. package/lib/module/index.js.map +1 -0
  91. package/lib/module/managers/DeviceManager.js +641 -0
  92. package/lib/module/managers/DeviceManager.js.map +1 -0
  93. package/lib/module/managers/OTAManager.js +134 -0
  94. package/lib/module/managers/OTAManager.js.map +1 -0
  95. package/lib/module/managers/RecordingManager.js +438 -0
  96. package/lib/module/managers/RecordingManager.js.map +1 -0
  97. package/lib/module/managers/StreamingSession.js +168 -0
  98. package/lib/module/managers/StreamingSession.js.map +1 -0
  99. package/lib/module/managers/types.js +4 -0
  100. package/lib/module/managers/types.js.map +1 -0
  101. package/lib/module/models/Device.js +2 -0
  102. package/lib/module/models/Device.js.map +1 -0
  103. package/lib/module/models/Recording.js +2 -0
  104. package/lib/module/models/Recording.js.map +1 -0
  105. package/lib/module/models/Status.js +4 -0
  106. package/lib/module/models/Status.js.map +1 -0
  107. package/lib/module/specs/NativeBotaDeviceSDK.js +5 -0
  108. package/lib/module/specs/NativeBotaDeviceSDK.js.map +1 -0
  109. package/lib/module/sync/syncStatus.js +174 -0
  110. package/lib/module/sync/syncStatus.js.map +1 -0
  111. package/lib/module/utils/errors.js +183 -0
  112. package/lib/module/utils/errors.js.map +1 -0
  113. package/lib/module/utils/logger.js +80 -0
  114. package/lib/module/utils/logger.js.map +1 -0
  115. package/lib/typescript/BotaClient.d.ts +40 -0
  116. package/lib/typescript/BotaClient.d.ts.map +1 -0
  117. package/lib/typescript/ble/constants.d.ts +4 -0
  118. package/lib/typescript/ble/constants.d.ts.map +1 -0
  119. package/lib/typescript/ble/deviceLogs.d.ts +10 -0
  120. package/lib/typescript/ble/deviceLogs.d.ts.map +1 -0
  121. package/lib/typescript/cache/DeviceStateCache.d.ts +14 -0
  122. package/lib/typescript/cache/DeviceStateCache.d.ts.map +1 -0
  123. package/lib/typescript/client.d.ts +208 -0
  124. package/lib/typescript/client.d.ts.map +1 -0
  125. package/lib/typescript/compatibility/runtime.d.ts +11 -0
  126. package/lib/typescript/compatibility/runtime.d.ts.map +1 -0
  127. package/lib/typescript/index.d.ts +19 -0
  128. package/lib/typescript/index.d.ts.map +1 -0
  129. package/lib/typescript/managers/DeviceManager.d.ts +117 -0
  130. package/lib/typescript/managers/DeviceManager.d.ts.map +1 -0
  131. package/lib/typescript/managers/OTAManager.d.ts +25 -0
  132. package/lib/typescript/managers/OTAManager.d.ts.map +1 -0
  133. package/lib/typescript/managers/RecordingManager.d.ts +54 -0
  134. package/lib/typescript/managers/RecordingManager.d.ts.map +1 -0
  135. package/lib/typescript/managers/StreamingSession.d.ts +35 -0
  136. package/lib/typescript/managers/StreamingSession.d.ts.map +1 -0
  137. package/lib/typescript/managers/types.d.ts +19 -0
  138. package/lib/typescript/managers/types.d.ts.map +1 -0
  139. package/lib/typescript/models/Device.d.ts +392 -0
  140. package/lib/typescript/models/Device.d.ts.map +1 -0
  141. package/lib/typescript/models/Recording.d.ts +259 -0
  142. package/lib/typescript/models/Recording.d.ts.map +1 -0
  143. package/lib/typescript/models/Status.d.ts +106 -0
  144. package/lib/typescript/models/Status.d.ts.map +1 -0
  145. package/lib/typescript/specs/NativeBotaDeviceSDK.d.ts +393 -0
  146. package/lib/typescript/specs/NativeBotaDeviceSDK.d.ts.map +1 -0
  147. package/lib/typescript/sync/syncStatus.d.ts +123 -0
  148. package/lib/typescript/sync/syncStatus.d.ts.map +1 -0
  149. package/lib/typescript/utils/errors.d.ts +83 -0
  150. package/lib/typescript/utils/errors.d.ts.map +1 -0
  151. package/lib/typescript/utils/logger.d.ts +36 -0
  152. package/lib/typescript/utils/logger.d.ts.map +1 -0
  153. package/package.json +100 -0
  154. package/scripts/bota_device_sdk_spm_workaround.rb +53 -0
  155. package/src/BotaClient.ts +231 -0
  156. package/src/ble/constants.ts +3 -0
  157. package/src/ble/deviceLogs.ts +61 -0
  158. package/src/cache/DeviceStateCache.ts +20 -0
  159. package/src/client.ts +1410 -0
  160. package/src/compatibility/runtime.ts +55 -0
  161. package/src/index.ts +146 -0
  162. package/src/managers/DeviceManager.ts +927 -0
  163. package/src/managers/OTAManager.ts +195 -0
  164. package/src/managers/RecordingManager.ts +578 -0
  165. package/src/managers/StreamingSession.ts +212 -0
  166. package/src/managers/types.ts +36 -0
  167. package/src/models/Device.ts +484 -0
  168. package/src/models/Recording.ts +281 -0
  169. package/src/models/Status.ts +128 -0
  170. package/src/specs/NativeBotaDeviceSDK.ts +542 -0
  171. package/src/sync/syncStatus.ts +243 -0
  172. package/src/utils/errors.ts +327 -0
  173. package/src/utils/logger.ts +122 -0
@@ -0,0 +1,195 @@
1
+ import EventEmitter from 'eventemitter3';
2
+
3
+ import { getCompatibilityClient } from '../compatibility/runtime';
4
+ import type { ConnectedDevice } from '../models/Device';
5
+ import type { DeviceManager } from './DeviceManager';
6
+ import type {
7
+ FirmwareDownloadProgressCallback,
8
+ FirmwareInfo,
9
+ OtaProgress,
10
+ OtaStage,
11
+ } from './types';
12
+
13
+ interface OTAManagerEvents {
14
+ updateAvailable: (firmware: FirmwareInfo) => void;
15
+ progress: (deviceId: string, progress: OtaProgress) => void;
16
+ completed: (deviceId: string, version: string) => void;
17
+ failed: (deviceId: string, error: Error) => void;
18
+ }
19
+
20
+ interface FirmwareDownloadProgressEvent {
21
+ loaded: number;
22
+ total: number;
23
+ lengthComputable: boolean;
24
+ }
25
+
26
+ interface FirmwareDownloadRequest {
27
+ status: number;
28
+ response: unknown;
29
+ responseType: string;
30
+ onprogress: ((event: FirmwareDownloadProgressEvent) => void) | null;
31
+ onload: (() => void) | null;
32
+ onerror: (() => void) | null;
33
+ onabort: (() => void) | null;
34
+ open(method: string, url: string): void;
35
+ send(): void;
36
+ }
37
+
38
+ type FirmwareDownloadRequestConstructor = new () => FirmwareDownloadRequest;
39
+
40
+ const stageForNativePhase = (phase: string): OtaStage => {
41
+ switch (phase) {
42
+ case 'downloading':
43
+ return 'downloading';
44
+ case 'awaiting_device':
45
+ return 'preparing';
46
+ case 'transferring':
47
+ return 'updating';
48
+ case 'verifying':
49
+ return 'verifying';
50
+ case 'rebooting':
51
+ case 'reconnecting':
52
+ return 'restarting';
53
+ case 'complete':
54
+ return 'completed';
55
+ default:
56
+ throw new Error(`Unknown firmware update phase: ${phase}`);
57
+ }
58
+ };
59
+
60
+ export class OTAManager extends EventEmitter<OTAManagerEvents> {
61
+ private readonly client = getCompatibilityClient();
62
+ private destroyed = false;
63
+
64
+ constructor(
65
+ private readonly deviceManager: DeviceManager,
66
+ private readonly firmwareCdnUrl = 'https://cdn.bota.dev/firmware'
67
+ ) {
68
+ super();
69
+ }
70
+
71
+ async checkForUpdate(device: ConnectedDevice): Promise<FirmwareInfo | null> {
72
+ this.assertAlive();
73
+ this.emit('progress', device.id, { stage: 'checking', progress: 0 });
74
+ const response = await fetch(
75
+ `${this.firmwareCdnUrl}/latest?device_type=${device.deviceType}&current=${device.firmwareVersion}`
76
+ );
77
+ if (!response.ok) {
78
+ if (response.status === 404) return null;
79
+ throw new Error(`Failed to check for updates: ${response.status}`);
80
+ }
81
+ const firmware = (await response.json()) as FirmwareInfo;
82
+ if (!this.isNewerVersion(firmware.version, device.firmwareVersion)) return null;
83
+ this.emit('updateAvailable', firmware);
84
+ return firmware;
85
+ }
86
+
87
+ async downloadFirmware(
88
+ firmware: FirmwareInfo,
89
+ onProgress?: FirmwareDownloadProgressCallback
90
+ ): Promise<ArrayBuffer> {
91
+ this.assertAlive();
92
+ return new Promise<ArrayBuffer>((resolve, reject) => {
93
+ const Request = (globalThis as unknown as {
94
+ XMLHttpRequest?: FirmwareDownloadRequestConstructor;
95
+ }).XMLHttpRequest;
96
+ if (!Request) {
97
+ reject(new Error('Failed to download firmware: XMLHttpRequest is unavailable'));
98
+ return;
99
+ }
100
+ const request = new Request();
101
+ request.open('GET', firmware.url);
102
+ request.responseType = 'arraybuffer';
103
+ request.onprogress = (event) => {
104
+ const total = event.lengthComputable && event.total > 0
105
+ ? event.total
106
+ : firmware.size;
107
+ onProgress?.(event.loaded, total);
108
+ };
109
+ request.onload = () => {
110
+ if (request.status < 200 || request.status >= 300) {
111
+ reject(new Error(`Failed to download firmware: ${request.status}`));
112
+ } else if (!(request.response instanceof ArrayBuffer)) {
113
+ reject(new Error('Failed to download firmware: empty response'));
114
+ } else {
115
+ resolve(request.response);
116
+ }
117
+ };
118
+ request.onerror = () =>
119
+ reject(new Error('Failed to download firmware: network error'));
120
+ request.onabort = () =>
121
+ reject(new Error('Failed to download firmware: request aborted'));
122
+ request.send();
123
+ });
124
+ }
125
+
126
+ async performUpdate(
127
+ device: ConnectedDevice,
128
+ firmware: FirmwareInfo,
129
+ grantBlob?: string
130
+ ): Promise<void> {
131
+ this.assertAlive();
132
+ try {
133
+ if (grantBlob) await this.deviceManager.writeGrant(device, grantBlob);
134
+ await this.client.ota.updateFirmware(
135
+ device,
136
+ {
137
+ version: firmware.version,
138
+ sizeBytes: firmware.size,
139
+ crc32: 0,
140
+ url: firmware.url,
141
+ },
142
+ (nativeProgress) => {
143
+ if (this.destroyed) return;
144
+ const total = nativeProgress.totalBytes;
145
+ const progress: OtaProgress = {
146
+ stage: stageForNativePhase(nativeProgress.phase),
147
+ progress: total > 0
148
+ ? Math.min(nativeProgress.completedBytes / total, 1)
149
+ : 0,
150
+ };
151
+ if (nativeProgress.phase === 'downloading') {
152
+ progress.bytesTransferred = nativeProgress.completedBytes;
153
+ progress.totalBytes = total;
154
+ }
155
+ this.emit('progress', device.id, progress);
156
+ }
157
+ );
158
+ if (!this.destroyed) this.emit('completed', device.id, firmware.version);
159
+ } catch (error) {
160
+ const failure = error instanceof Error ? error : new Error(String(error));
161
+ if (!this.destroyed) {
162
+ this.emit('progress', device.id, {
163
+ stage: 'failed',
164
+ progress: 0,
165
+ error: failure.message,
166
+ });
167
+ this.emit('failed', device.id, failure);
168
+ }
169
+ throw error;
170
+ }
171
+ }
172
+
173
+ destroy(): void {
174
+ if (this.destroyed) return;
175
+ this.destroyed = true;
176
+ this.removeAllListeners();
177
+ void this.client.ota.cancelFirmwareUpdate();
178
+ }
179
+
180
+ private isNewerVersion(newVersion: string, currentVersion: string): boolean {
181
+ const newParts = newVersion.split('.').map((part) => Number.parseInt(part, 10) || 0);
182
+ const currentParts = currentVersion.split('.').map((part) => Number.parseInt(part, 10) || 0);
183
+ for (let index = 0; index < Math.max(newParts.length, currentParts.length); index += 1) {
184
+ const next = newParts[index] ?? 0;
185
+ const current = currentParts[index] ?? 0;
186
+ if (next > current) return true;
187
+ if (next < current) return false;
188
+ }
189
+ return false;
190
+ }
191
+
192
+ private assertAlive(): void {
193
+ if (this.destroyed) throw new Error('OTAManager has been destroyed');
194
+ }
195
+ }