@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,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recording-related type definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Audio codec type
|
|
7
|
+
*/
|
|
8
|
+
export type AudioCodec = 'pcm_16k' | 'pcm_8k' | 'opus_16k' | 'opus_8k';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Recording metadata from device
|
|
12
|
+
*/
|
|
13
|
+
export interface DeviceRecording {
|
|
14
|
+
/** Unique identifier on device (UUID) */
|
|
15
|
+
uuid: string;
|
|
16
|
+
/** Recording start timestamp */
|
|
17
|
+
startedAt: Date;
|
|
18
|
+
/** Duration in milliseconds */
|
|
19
|
+
durationMs: number;
|
|
20
|
+
/** File size in bytes */
|
|
21
|
+
fileSizeBytes: number;
|
|
22
|
+
/** Audio codec used */
|
|
23
|
+
codec: AudioCodec;
|
|
24
|
+
/** True if the file is stored encrypted at rest on the device (P4). False/undefined = legacy plaintext. */
|
|
25
|
+
isEncrypted?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Upload information provided by customer backend
|
|
30
|
+
* (obtained by calling customer's API, not Bota API directly)
|
|
31
|
+
*/
|
|
32
|
+
export interface UploadInfo {
|
|
33
|
+
/** Pre-signed S3 URL for upload */
|
|
34
|
+
uploadUrl: string;
|
|
35
|
+
/** Recording ID assigned by Bota API (rec_*) */
|
|
36
|
+
recordingId: string;
|
|
37
|
+
/** Upload token (up_*) for verification - optional if using custom completion flow */
|
|
38
|
+
uploadToken?: string;
|
|
39
|
+
/** URL to call when upload is complete - optional if using custom completion flow */
|
|
40
|
+
completeUrl?: string;
|
|
41
|
+
/** Expiration time of the upload URL */
|
|
42
|
+
expiresAt?: Date;
|
|
43
|
+
/** Content type for S3 upload (e.g., 'audio/opus', 'audio/wav') */
|
|
44
|
+
contentType?: string;
|
|
45
|
+
/** P10: when present AND the transferred audio bytes are BLE-e2e ciphertext
|
|
46
|
+
* (device encrypted before BLE relay), the SDK POSTs the raw bytes to this
|
|
47
|
+
* endpoint instead of the presigned S3 PUT. Backend decrypts server-side
|
|
48
|
+
* and writes plaintext to S3. Use the bind-time `cert`-flavored auth
|
|
49
|
+
* token (or any valid Bearer for the project). */
|
|
50
|
+
relay?: {
|
|
51
|
+
/** Full URL of `/v1/recordings/{id}/upload-relay` */
|
|
52
|
+
url: string;
|
|
53
|
+
/** Bearer token (typically sk_*, rk_*, or dtok_*) */
|
|
54
|
+
bearerToken: string;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Sync progress stages
|
|
60
|
+
*/
|
|
61
|
+
export type SyncStage =
|
|
62
|
+
| 'preparing'
|
|
63
|
+
| 'transferring'
|
|
64
|
+
| 'uploading'
|
|
65
|
+
| 'device_uploading'
|
|
66
|
+
| 'completing'
|
|
67
|
+
| 'completed'
|
|
68
|
+
| 'failed';
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Sync progress information
|
|
72
|
+
*/
|
|
73
|
+
export interface SyncProgress {
|
|
74
|
+
/** Current stage */
|
|
75
|
+
stage: SyncStage;
|
|
76
|
+
/** Progress within current stage (0.0 - 1.0) */
|
|
77
|
+
progress: number;
|
|
78
|
+
/** Bytes transferred so far (for transferring stage) */
|
|
79
|
+
bytesTransferred?: number;
|
|
80
|
+
/** Total bytes to transfer */
|
|
81
|
+
totalBytes?: number;
|
|
82
|
+
/** Bytes uploaded so far (for uploading stage) */
|
|
83
|
+
bytesUploaded?: number;
|
|
84
|
+
/** Recording ID (set when completed) */
|
|
85
|
+
recordingId?: string;
|
|
86
|
+
/** Error message (set when failed) */
|
|
87
|
+
error?: string;
|
|
88
|
+
/** P9.F2 BLE integrity hash. SHA-256 (64-char hex) the device computed over
|
|
89
|
+
* the SD-file bytes. Set on the `transferring` and `completed` stages when
|
|
90
|
+
* P9.F2+ firmware emitted a BOTA_PKT_TYPE_SHA256 packet after EOF. Forward
|
|
91
|
+
* to your backend's /upload-complete (or equivalent) so server-side stitch
|
|
92
|
+
* can verify integrity. Undefined on pre-P9.F2 firmware. */
|
|
93
|
+
contentSha256?: string;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Upload task status
|
|
98
|
+
*/
|
|
99
|
+
export type UploadTaskStatus = 'pending' | 'uploading' | 'completed' | 'failed';
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Upload task in the queue
|
|
103
|
+
*/
|
|
104
|
+
export interface UploadTask {
|
|
105
|
+
/** Unique task identifier */
|
|
106
|
+
id: string;
|
|
107
|
+
/** Recording ID from Bota API */
|
|
108
|
+
recordingId: string;
|
|
109
|
+
/** Device ID the recording came from */
|
|
110
|
+
deviceId: string;
|
|
111
|
+
/** Local file path */
|
|
112
|
+
localPath: string;
|
|
113
|
+
/** Pre-signed S3 upload URL */
|
|
114
|
+
uploadUrl: string;
|
|
115
|
+
/** Upload token - optional if using custom completion flow */
|
|
116
|
+
uploadToken?: string;
|
|
117
|
+
/** Complete URL to call after upload - optional if using custom completion flow */
|
|
118
|
+
completeUrl?: string;
|
|
119
|
+
/** Content type for S3 upload (e.g., 'audio/opus', 'audio/wav') */
|
|
120
|
+
contentType?: string;
|
|
121
|
+
/** P9.F2 BLE integrity hash. SHA-256 (64-char hex) the device computed over
|
|
122
|
+
* the SD-file bytes — forwarded to the host app's backend in the
|
|
123
|
+
* /upload-complete body so server-side stitch+SHA can verify integrity. */
|
|
124
|
+
contentSha256?: string;
|
|
125
|
+
/** P10: when set, the file at `localPath` is BLE-e2e ciphertext that must
|
|
126
|
+
* be POSTed to this relay endpoint (with the bearer token) instead of
|
|
127
|
+
* PUT to the presigned `uploadUrl`. The backend decrypts and writes
|
|
128
|
+
* plaintext to S3 on receipt. */
|
|
129
|
+
relay?: {
|
|
130
|
+
url: string;
|
|
131
|
+
bearerToken: string;
|
|
132
|
+
};
|
|
133
|
+
/** Current status */
|
|
134
|
+
status: UploadTaskStatus;
|
|
135
|
+
/** Number of retry attempts */
|
|
136
|
+
retryCount: number;
|
|
137
|
+
/** Error message if failed */
|
|
138
|
+
errorMessage?: string;
|
|
139
|
+
/** Task creation time */
|
|
140
|
+
createdAt: Date;
|
|
141
|
+
/** Last update time */
|
|
142
|
+
updatedAt: Date;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Transfer packet from device
|
|
147
|
+
*/
|
|
148
|
+
export interface TransferPacket {
|
|
149
|
+
/** Packet type. P10 adds:
|
|
150
|
+
* - 'e2e_start' session header (ephemeral_pk + salt)
|
|
151
|
+
* - 'encrypted_data' DATA with ciphertext + tag payload
|
|
152
|
+
* - 'encrypted_eof' EOF for an encrypted transfer (no CRC) */
|
|
153
|
+
type: 'data' | 'eof' | 'paused' | 'error' | 'sha256' | 'e2e_start' | 'encrypted_data' | 'encrypted_eof';
|
|
154
|
+
/** Sequence number */
|
|
155
|
+
sequenceNumber: number;
|
|
156
|
+
/** Audio data (for data packets) */
|
|
157
|
+
data?: Uint8Array;
|
|
158
|
+
/** CRC32 checksum (for EOF packets) */
|
|
159
|
+
checksum?: number;
|
|
160
|
+
/** Bytes sent so far (for paused packets — streaming mode) */
|
|
161
|
+
bytesSent?: number;
|
|
162
|
+
/** Error code (for error packets) */
|
|
163
|
+
errorCode?: number;
|
|
164
|
+
/** P10 e2e_start only: ephemeral X25519 pubkey (32 bytes). */
|
|
165
|
+
e2eEphemeralPk?: Uint8Array;
|
|
166
|
+
/** P10 e2e_start only: session salt (4 bytes) for per-chunk nonce. */
|
|
167
|
+
e2eSalt?: Uint8Array;
|
|
168
|
+
/** P10 encrypted_data only: full payload (ciphertext + 16-byte tag). */
|
|
169
|
+
e2eChunk?: Uint8Array;
|
|
170
|
+
/** P9.F2 sha256 only: device's SHA-256 over the SD-file bytes (32 raw bytes). */
|
|
171
|
+
sha256?: Uint8Array;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Options for startStreamingSync()
|
|
176
|
+
*/
|
|
177
|
+
export interface StreamingSyncOptions {
|
|
178
|
+
/**
|
|
179
|
+
* Size of each upload chunk in KB (64-1024).
|
|
180
|
+
* Smaller = more real-time (lower latency, higher HTTP overhead).
|
|
181
|
+
* Larger = less real-time (higher latency, lower overhead).
|
|
182
|
+
* Default: 256 (from device settings.upload.streaming_chunk_kb)
|
|
183
|
+
*/
|
|
184
|
+
chunkSizeKb?: number;
|
|
185
|
+
/**
|
|
186
|
+
* Time-based flush interval in milliseconds. Buffered data is uploaded
|
|
187
|
+
* as a partial chunk even if chunkSizeKb hasn't been reached yet.
|
|
188
|
+
* Mirrors firmware's streaming_flush_interval_seconds behaviour.
|
|
189
|
+
* 0 = disabled (flush on chunk full only). Default: 60000 (60s).
|
|
190
|
+
*/
|
|
191
|
+
flushIntervalMs?: number;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Streaming sync state
|
|
196
|
+
*/
|
|
197
|
+
export type StreamingState =
|
|
198
|
+
| 'idle'
|
|
199
|
+
| 'streaming' // Receiving live audio data from device
|
|
200
|
+
| 'paused' // Device caught up to recording write position, waiting
|
|
201
|
+
| 'uploading' // Uploading final chunks to S3
|
|
202
|
+
| 'completing' // Finalizing upload
|
|
203
|
+
| 'completed'
|
|
204
|
+
| 'disconnected' // Bluetooth dropped — falls back to batch sync later
|
|
205
|
+
| 'failed';
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Streaming sync progress event
|
|
209
|
+
*/
|
|
210
|
+
export interface StreamingSyncProgress {
|
|
211
|
+
/** Current streaming state */
|
|
212
|
+
state: StreamingState;
|
|
213
|
+
/** Bytes received from device so far */
|
|
214
|
+
bytesReceived: number;
|
|
215
|
+
/** Chunks uploaded to S3 so far */
|
|
216
|
+
chunksUploaded: number;
|
|
217
|
+
/** Recording ID from backend (set after first chunk upload) */
|
|
218
|
+
recordingId?: string;
|
|
219
|
+
/** Error message (if failed) */
|
|
220
|
+
error?: string;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Upload provider for streaming sync.
|
|
225
|
+
* Called by StreamingSession to create the backend record and upload chunks
|
|
226
|
+
* concurrently with Bluetooth transfer — same pattern as firmware WiFi/4G upload.
|
|
227
|
+
*/
|
|
228
|
+
export interface StreamingUploadProvider {
|
|
229
|
+
/**
|
|
230
|
+
* Create backend record at session start to obtain recordingId for chunk URLs.
|
|
231
|
+
*
|
|
232
|
+
* Optionally return `relay` info so the SDK can route P10 e2e-encrypted
|
|
233
|
+
* chunks (when the device delivers ciphertext) to the per-chunk streaming
|
|
234
|
+
* relay endpoints instead of trying to push them to S3 presigned URLs.
|
|
235
|
+
* Required when the project has a backend pubkey provisioned and the
|
|
236
|
+
* device emits encrypted streaming packets; without it, the SDK cannot
|
|
237
|
+
* deliver the recording.
|
|
238
|
+
*
|
|
239
|
+
* Per-chunk model (foundation for real-time downstream features):
|
|
240
|
+
* chunkUrl(seq) → POST [eph_pk||salt||ct+tag] for seq=0, [ct+tag] for seq>0
|
|
241
|
+
* finalizeUrl → POST { total_chunks, ... } once EOF received
|
|
242
|
+
*/
|
|
243
|
+
createRecording: (info: { startedAt: Date }) => Promise<{
|
|
244
|
+
recordingId: string;
|
|
245
|
+
relay?: {
|
|
246
|
+
/** Build the per-chunk POST URL for chunk `seq` (0-indexed). */
|
|
247
|
+
chunkUrl: (seq: number) => string;
|
|
248
|
+
/** POST URL for the finalize call after all chunks have been POSTed. */
|
|
249
|
+
finalizeUrl: string;
|
|
250
|
+
/** Bearer token used for both chunkUrl and finalizeUrl. */
|
|
251
|
+
bearerToken: string;
|
|
252
|
+
};
|
|
253
|
+
}>;
|
|
254
|
+
/** Get pre-signed S3 URL for a specific chunk (1-indexed) */
|
|
255
|
+
getChunkUrl: (recordingId: string, chunkIndex: number) => Promise<string>;
|
|
256
|
+
/** Finalize after all chunks uploaded — triggers backend stitching + transcription */
|
|
257
|
+
finalizeRecording: (recordingId: string, info: {
|
|
258
|
+
totalChunks: number;
|
|
259
|
+
durationMs?: number;
|
|
260
|
+
fileSizeBytes?: number;
|
|
261
|
+
}) => Promise<void>;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Streaming session — represents an active streaming sync of the current recording.
|
|
266
|
+
* Event-based because it's long-lived (entire recording duration).
|
|
267
|
+
*/
|
|
268
|
+
export interface StreamingSessionEvents {
|
|
269
|
+
/** Emitted when a new chunk of audio data is received */
|
|
270
|
+
chunk: (progress: StreamingSyncProgress) => void;
|
|
271
|
+
/** Emitted when device has caught up to recording write position */
|
|
272
|
+
paused: () => void;
|
|
273
|
+
/** Emitted when device resumes sending data after pause */
|
|
274
|
+
resumed: () => void;
|
|
275
|
+
/** Emitted when recording stops and all data has been uploaded */
|
|
276
|
+
completed: (result: { recordingId: string; totalBytes: number }) => void;
|
|
277
|
+
/** Emitted when Bluetooth disconnects — recording continues on device, batch sync later */
|
|
278
|
+
disconnected: () => void;
|
|
279
|
+
/** Emitted on error */
|
|
280
|
+
error: (err: Error) => void;
|
|
281
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status and configuration type definitions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { DeviceStatus, StorageInfo } from './Device';
|
|
6
|
+
import type { SyncProgress, UploadTask } from './Recording';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* SDK log level
|
|
10
|
+
*/
|
|
11
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* SDK configuration options
|
|
15
|
+
*/
|
|
16
|
+
export interface BotaConfig {
|
|
17
|
+
/** Environment for API endpoint (development, gamma, or production) */
|
|
18
|
+
environment?: 'development' | 'gamma' | 'production';
|
|
19
|
+
/** Enable background sync (default: true) */
|
|
20
|
+
backgroundSyncEnabled?: boolean;
|
|
21
|
+
/** Only upload on WiFi (default: false) */
|
|
22
|
+
wifiOnlyUpload?: boolean;
|
|
23
|
+
/** Logging level (default: 'warn') */
|
|
24
|
+
logLevel?: LogLevel;
|
|
25
|
+
/** Enable debug mode with verbose logging */
|
|
26
|
+
debug?: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* SDK state
|
|
31
|
+
*/
|
|
32
|
+
export type SdkState = 'uninitialized' | 'initializing' | 'ready' | 'error';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Bluetooth state
|
|
36
|
+
*/
|
|
37
|
+
export type BluetoothState =
|
|
38
|
+
| 'unknown'
|
|
39
|
+
| 'resetting'
|
|
40
|
+
| 'unsupported'
|
|
41
|
+
| 'unauthorized'
|
|
42
|
+
| 'poweredOff'
|
|
43
|
+
| 'poweredOn';
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* SDK status information
|
|
47
|
+
*/
|
|
48
|
+
export interface SdkStatus {
|
|
49
|
+
/** Current SDK state */
|
|
50
|
+
state: SdkState;
|
|
51
|
+
/** Bluetooth state */
|
|
52
|
+
bluetoothState: BluetoothState;
|
|
53
|
+
/** Whether Bluetooth is ready for operations */
|
|
54
|
+
isBluetoothReady: boolean;
|
|
55
|
+
/** Number of connected devices */
|
|
56
|
+
connectedDevicesCount: number;
|
|
57
|
+
/** Number of pending uploads in queue */
|
|
58
|
+
pendingUploadsCount: number;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Re-export for convenience
|
|
62
|
+
export type { DeviceStatus, StorageInfo, SyncProgress, UploadTask };
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Event types emitted by DeviceManager
|
|
66
|
+
*/
|
|
67
|
+
export interface DeviceManagerEvents {
|
|
68
|
+
/** Emitted when a device is discovered during scan */
|
|
69
|
+
deviceDiscovered: (device: import('./Device').DiscoveredDevice) => void;
|
|
70
|
+
/** Emitted when a device is connected */
|
|
71
|
+
deviceConnected: (device: import('./Device').ConnectedDevice) => void;
|
|
72
|
+
/** Emitted when a device is disconnected */
|
|
73
|
+
deviceDisconnected: (deviceId: string, error?: Error) => void;
|
|
74
|
+
/** Emitted when device status is updated */
|
|
75
|
+
deviceStatusUpdated: (
|
|
76
|
+
deviceId: string,
|
|
77
|
+
status: import('./Device').DeviceStatus
|
|
78
|
+
) => void;
|
|
79
|
+
/** Emitted when scan starts */
|
|
80
|
+
scanStarted: () => void;
|
|
81
|
+
/** Emitted when scan stops */
|
|
82
|
+
scanStopped: () => void;
|
|
83
|
+
/** Emitted on scan error */
|
|
84
|
+
scanError: (error: Error) => void;
|
|
85
|
+
/** Emitted on connection state change */
|
|
86
|
+
connectionStateChanged: (
|
|
87
|
+
deviceId: string,
|
|
88
|
+
state: import('./Device').ConnectionState
|
|
89
|
+
) => void;
|
|
90
|
+
/** Emitted when Bluetooth powers back on (off → on transition) */
|
|
91
|
+
bluetoothReady: () => void;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Event types emitted by RecordingManager
|
|
96
|
+
*/
|
|
97
|
+
export interface RecordingManagerEvents {
|
|
98
|
+
/** Emitted when sync starts for a recording */
|
|
99
|
+
syncStarted: (deviceRecordingUuid: string) => void;
|
|
100
|
+
/** Emitted on sync progress update */
|
|
101
|
+
syncProgress: (deviceRecordingUuid: string, progress: SyncProgress) => void;
|
|
102
|
+
/** Emitted when sync completes successfully */
|
|
103
|
+
syncCompleted: (deviceRecordingUuid: string, recordingId: string) => void;
|
|
104
|
+
/** Emitted when sync fails */
|
|
105
|
+
syncFailed: (deviceRecordingUuid: string, error: Error) => void;
|
|
106
|
+
/** Emitted when upload queue changes */
|
|
107
|
+
queueUpdated: (tasks: UploadTask[]) => void;
|
|
108
|
+
/** Emitted when an upload starts */
|
|
109
|
+
uploadStarted: (taskId: string) => void;
|
|
110
|
+
/** Emitted on upload progress */
|
|
111
|
+
uploadProgress: (taskId: string, progress: number) => void;
|
|
112
|
+
/** Emitted when an upload completes */
|
|
113
|
+
uploadCompleted: (taskId: string, recordingId: string) => void;
|
|
114
|
+
/** Emitted when an upload fails */
|
|
115
|
+
uploadFailed: (taskId: string, error: Error) => void;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Event types emitted by BotaClient
|
|
120
|
+
*/
|
|
121
|
+
export interface BotaClientEvents {
|
|
122
|
+
/** Emitted when SDK state changes */
|
|
123
|
+
stateChanged: (state: SdkState) => void;
|
|
124
|
+
/** Emitted when Bluetooth state changes */
|
|
125
|
+
bluetoothStateChanged: (state: BluetoothState) => void;
|
|
126
|
+
/** Emitted on SDK error */
|
|
127
|
+
error: (error: Error) => void;
|
|
128
|
+
}
|