react-native-sherpa-onnx 0.2.0 → 0.3.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 (175) hide show
  1. package/README.md +232 -236
  2. package/SherpaOnnx.podspec +68 -64
  3. package/android/build.gradle +182 -192
  4. package/android/codegen.gradle +57 -0
  5. package/android/prebuilt-download.gradle +428 -0
  6. package/android/prebuilt-versions.gradle +43 -0
  7. package/android/proguard-rules.pro +10 -0
  8. package/android/src/main/assets/testModels/add_mul_add.onnx +28 -0
  9. package/android/src/main/assets/testModels/nnapi_internal_uint8_support.onnx +0 -0
  10. package/android/src/main/assets/testModels/qnn_multi_ctx_embed.onnx +0 -0
  11. package/android/src/main/cpp/CMakeLists.txt +166 -129
  12. package/android/src/main/cpp/CMakePresets.json +54 -0
  13. package/android/src/main/cpp/crypto/sha256.cpp +174 -0
  14. package/android/src/main/cpp/crypto/sha256.h +16 -0
  15. package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-helper.cpp +404 -0
  16. package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-helper.h +56 -0
  17. package/android/src/main/cpp/jni/archive/sherpa-onnx-archive-jni.cpp +181 -0
  18. package/android/src/main/cpp/jni/audio/sherpa-onnx-audio-convert-jni.cpp +888 -0
  19. package/{ios → android/src/main/cpp/jni/model_detect}/sherpa-onnx-common.h +18 -18
  20. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.cpp +86 -0
  21. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-detect-jni-common.h +20 -0
  22. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.cpp +423 -0
  23. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-helper.h +55 -0
  24. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-stt.cpp +399 -0
  25. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-model-detect-tts.cpp +238 -0
  26. package/{ios → android/src/main/cpp/jni/model_detect}/sherpa-onnx-model-detect.h +122 -89
  27. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-stt-wrapper.cpp +99 -0
  28. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-stt-wrapper.h +16 -0
  29. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-tts-wrapper.cpp +78 -0
  30. package/android/src/main/cpp/jni/model_detect/sherpa-onnx-tts-wrapper.h +16 -0
  31. package/android/src/main/cpp/jni/module/sherpa-onnx-module-jni.cpp +190 -0
  32. package/android/src/main/cpp/jni/tts/sherpa-onnx-tts-zipvoice-jni.cpp +301 -0
  33. package/android/src/main/java/com/sherpaonnx/SherpaOnnxArchiveHelper.kt +94 -0
  34. package/android/src/main/java/com/sherpaonnx/{SherpaOnnxCoreHelper.kt → SherpaOnnxAssetHelper.kt} +350 -236
  35. package/android/src/main/java/com/sherpaonnx/SherpaOnnxModule.kt +791 -483
  36. package/android/src/main/java/com/sherpaonnx/SherpaOnnxSttHelper.kt +699 -109
  37. package/android/src/main/java/com/sherpaonnx/SherpaOnnxTtsHelper.kt +1123 -668
  38. package/android/src/main/java/com/sherpaonnx/ZipvoiceTtsWrapper.kt +187 -0
  39. package/ios/SherpaOnnx+Assets.h +11 -0
  40. package/ios/SherpaOnnx+Assets.mm +325 -0
  41. package/ios/SherpaOnnx+STT.mm +455 -118
  42. package/ios/SherpaOnnx+TTS.mm +1101 -712
  43. package/ios/SherpaOnnx.h +17 -6
  44. package/ios/SherpaOnnx.mm +206 -311
  45. package/ios/SherpaOnnx.xcconfig +19 -19
  46. package/ios/SherpaOnnxCoreMLHelper.swift +24 -0
  47. package/ios/archive/sherpa-onnx-archive-helper.h +21 -0
  48. package/ios/archive/sherpa-onnx-archive-helper.mm +296 -0
  49. package/ios/libarchive_darwin_config.h +153 -0
  50. package/{android/src/main/cpp/jni → ios/model_detect}/sherpa-onnx-common.h +18 -18
  51. package/ios/model_detect/sherpa-onnx-model-detect-helper.h +49 -0
  52. package/ios/model_detect/sherpa-onnx-model-detect-helper.mm +210 -0
  53. package/ios/model_detect/sherpa-onnx-model-detect-stt.mm +344 -0
  54. package/ios/model_detect/sherpa-onnx-model-detect-tts.mm +201 -0
  55. package/{android/src/main/cpp/jni → ios/model_detect}/sherpa-onnx-model-detect.h +117 -89
  56. package/ios/scripts/patch-libarchive-includes.sh +61 -0
  57. package/ios/scripts/setup-ios-libarchive.sh +98 -0
  58. package/ios/stt/sherpa-onnx-stt-wrapper.h +129 -0
  59. package/ios/stt/sherpa-onnx-stt-wrapper.mm +523 -0
  60. package/ios/{sherpa-onnx-tts-wrapper.h → tts/sherpa-onnx-tts-wrapper.h} +90 -85
  61. package/ios/{sherpa-onnx-tts-wrapper.mm → tts/sherpa-onnx-tts-wrapper.mm} +376 -345
  62. package/lib/module/NativeSherpaOnnx.js +3 -0
  63. package/lib/module/NativeSherpaOnnx.js.map +1 -1
  64. package/lib/module/audio/index.js +22 -0
  65. package/lib/module/audio/index.js.map +1 -0
  66. package/lib/module/diarization/index.js +1 -1
  67. package/lib/module/diarization/index.js.map +1 -1
  68. package/lib/module/download/ModelDownloadManager.js +918 -0
  69. package/lib/module/download/ModelDownloadManager.js.map +1 -0
  70. package/lib/module/download/extractTarBz2.js +53 -0
  71. package/lib/module/download/extractTarBz2.js.map +1 -0
  72. package/lib/module/download/index.js +6 -0
  73. package/lib/module/download/index.js.map +1 -0
  74. package/lib/module/download/validation.js +178 -0
  75. package/lib/module/download/validation.js.map +1 -0
  76. package/lib/module/enhancement/index.js +1 -1
  77. package/lib/module/enhancement/index.js.map +1 -1
  78. package/lib/module/index.js +41 -3
  79. package/lib/module/index.js.map +1 -1
  80. package/lib/module/separation/index.js +1 -1
  81. package/lib/module/separation/index.js.map +1 -1
  82. package/lib/module/stt/index.js +127 -60
  83. package/lib/module/stt/index.js.map +1 -1
  84. package/lib/module/stt/sttModelLanguages.js +512 -0
  85. package/lib/module/stt/sttModelLanguages.js.map +1 -0
  86. package/lib/module/stt/types.js +53 -1
  87. package/lib/module/stt/types.js.map +1 -1
  88. package/lib/module/tts/index.js +216 -289
  89. package/lib/module/tts/index.js.map +1 -1
  90. package/lib/module/tts/types.js +86 -1
  91. package/lib/module/tts/types.js.map +1 -1
  92. package/lib/module/types.js.map +1 -1
  93. package/lib/module/utils.js +86 -73
  94. package/lib/module/utils.js.map +1 -1
  95. package/lib/module/vad/index.js +1 -1
  96. package/lib/module/vad/index.js.map +1 -1
  97. package/lib/typescript/src/NativeSherpaOnnx.d.ts +192 -38
  98. package/lib/typescript/src/NativeSherpaOnnx.d.ts.map +1 -1
  99. package/lib/typescript/src/audio/index.d.ts +13 -0
  100. package/lib/typescript/src/audio/index.d.ts.map +1 -0
  101. package/lib/typescript/src/diarization/index.d.ts +3 -2
  102. package/lib/typescript/src/diarization/index.d.ts.map +1 -1
  103. package/lib/typescript/src/download/ModelDownloadManager.d.ts +108 -0
  104. package/lib/typescript/src/download/ModelDownloadManager.d.ts.map +1 -0
  105. package/lib/typescript/src/download/extractTarBz2.d.ts +14 -0
  106. package/lib/typescript/src/download/extractTarBz2.d.ts.map +1 -0
  107. package/lib/typescript/src/download/index.d.ts +7 -0
  108. package/lib/typescript/src/download/index.d.ts.map +1 -0
  109. package/lib/typescript/src/download/validation.d.ts +57 -0
  110. package/lib/typescript/src/download/validation.d.ts.map +1 -0
  111. package/lib/typescript/src/enhancement/index.d.ts +3 -2
  112. package/lib/typescript/src/enhancement/index.d.ts.map +1 -1
  113. package/lib/typescript/src/index.d.ts +26 -2
  114. package/lib/typescript/src/index.d.ts.map +1 -1
  115. package/lib/typescript/src/separation/index.d.ts +3 -2
  116. package/lib/typescript/src/separation/index.d.ts.map +1 -1
  117. package/lib/typescript/src/stt/index.d.ts +31 -43
  118. package/lib/typescript/src/stt/index.d.ts.map +1 -1
  119. package/lib/typescript/src/stt/sttModelLanguages.d.ts +52 -0
  120. package/lib/typescript/src/stt/sttModelLanguages.d.ts.map +1 -0
  121. package/lib/typescript/src/stt/types.d.ts +196 -9
  122. package/lib/typescript/src/stt/types.d.ts.map +1 -1
  123. package/lib/typescript/src/tts/index.d.ts +25 -211
  124. package/lib/typescript/src/tts/index.d.ts.map +1 -1
  125. package/lib/typescript/src/tts/types.d.ts +148 -25
  126. package/lib/typescript/src/tts/types.d.ts.map +1 -1
  127. package/lib/typescript/src/types.d.ts +0 -32
  128. package/lib/typescript/src/types.d.ts.map +1 -1
  129. package/lib/typescript/src/utils.d.ts +28 -13
  130. package/lib/typescript/src/utils.d.ts.map +1 -1
  131. package/lib/typescript/src/vad/index.d.ts +3 -2
  132. package/lib/typescript/src/vad/index.d.ts.map +1 -1
  133. package/package.json +250 -222
  134. package/scripts/check-qnn-support.sh +78 -0
  135. package/scripts/setup-ios-framework.sh +379 -282
  136. package/src/NativeSherpaOnnx.ts +474 -251
  137. package/src/audio/index.ts +32 -0
  138. package/src/diarization/index.ts +4 -2
  139. package/src/download/ModelDownloadManager.ts +1325 -0
  140. package/src/download/extractTarBz2.ts +78 -0
  141. package/src/download/index.ts +43 -0
  142. package/src/download/validation.ts +279 -0
  143. package/src/enhancement/index.ts +4 -2
  144. package/src/index.tsx +78 -27
  145. package/src/separation/index.ts +4 -2
  146. package/src/stt/index.ts +249 -89
  147. package/src/stt/sttModelLanguages.ts +237 -0
  148. package/src/stt/types.ts +263 -9
  149. package/src/tts/index.ts +470 -458
  150. package/src/tts/types.ts +373 -218
  151. package/src/types.ts +0 -44
  152. package/src/utils.ts +145 -131
  153. package/src/vad/index.ts +4 -2
  154. package/third_party/ffmpeg_prebuilt/ANDROID_RELEASE_TAG +1 -0
  155. package/third_party/libarchive_prebuilt/ANDROID_RELEASE_TAG +1 -0
  156. package/third_party/libarchive_prebuilt/IOS_RELEASE_TAG +1 -0
  157. package/third_party/sherpa-onnx-prebuilt/ANDROID_RELEASE_TAG +1 -0
  158. package/third_party/sherpa-onnx-prebuilt/IOS_RELEASE_TAG +1 -0
  159. package/android/src/main/cpp/include/sherpa-onnx/c-api/c-api.h +0 -1918
  160. package/android/src/main/cpp/include/sherpa-onnx/c-api/cxx-api.h +0 -841
  161. package/android/src/main/cpp/jni/sherpa-onnx-model-detect.cpp +0 -541
  162. package/android/src/main/cpp/jni/sherpa-onnx-stt-jni.cpp +0 -336
  163. package/android/src/main/cpp/jni/sherpa-onnx-stt-wrapper.cpp +0 -222
  164. package/android/src/main/cpp/jni/sherpa-onnx-stt-wrapper.h +0 -68
  165. package/android/src/main/cpp/jni/sherpa-onnx-tts-jni.cpp +0 -823
  166. package/android/src/main/cpp/jni/sherpa-onnx-tts-wrapper.cpp +0 -387
  167. package/android/src/main/cpp/jni/sherpa-onnx-tts-wrapper.h +0 -147
  168. package/ios/Frameworks/sherpa_onnx.xcframework.zip +0 -0
  169. package/ios/include/sherpa-onnx/c-api/c-api.h +0 -1918
  170. package/ios/include/sherpa-onnx/c-api/cxx-api.h +0 -841
  171. package/ios/sherpa-onnx-model-detect.mm +0 -441
  172. package/ios/sherpa-onnx-stt-wrapper.h +0 -48
  173. package/ios/sherpa-onnx-stt-wrapper.mm +0 -201
  174. package/scripts/copy-headers.js +0 -184
  175. package/scripts/setup-assets.js +0 -323
@@ -0,0 +1,78 @@
1
+ import { DeviceEventEmitter } from 'react-native';
2
+ import SherpaOnnx from '../NativeSherpaOnnx';
3
+
4
+ export type ExtractProgressEvent = {
5
+ bytes: number;
6
+ totalBytes: number;
7
+ percent: number;
8
+ };
9
+
10
+ type ExtractResult = {
11
+ success: boolean;
12
+ path?: string;
13
+ sha256?: string;
14
+ reason?: string;
15
+ };
16
+
17
+ export async function extractTarBz2(
18
+ sourcePath: string,
19
+ targetPath: string,
20
+ force = true,
21
+ onProgress?: (event: ExtractProgressEvent) => void,
22
+ signal?: AbortSignal
23
+ ): Promise<ExtractResult> {
24
+ let subscription: { remove: () => void } | null = null;
25
+ let removeAbortListener: (() => void) | null = null;
26
+
27
+ if (signal?.aborted) {
28
+ const abortError = new Error('Extraction aborted');
29
+ abortError.name = 'AbortError';
30
+ throw abortError;
31
+ }
32
+
33
+ if (onProgress) {
34
+ subscription = DeviceEventEmitter.addListener(
35
+ 'extractTarBz2Progress',
36
+ (event: ExtractProgressEvent & { sourcePath?: string }) => {
37
+ // Only handle events for this extraction (fixes parallel extractions showing same %)
38
+ if (event.sourcePath != null && event.sourcePath !== sourcePath) {
39
+ return;
40
+ }
41
+ const safePercent = Math.max(0, Math.min(100, event.percent));
42
+ onProgress({ ...event, percent: safePercent });
43
+ }
44
+ );
45
+ }
46
+
47
+ if (signal) {
48
+ const onAbort = () => {
49
+ try {
50
+ SherpaOnnx.cancelExtractTarBz2();
51
+ } catch {
52
+ // Ignore cancel errors to avoid crashing on abort.
53
+ }
54
+ };
55
+ signal.addEventListener('abort', onAbort);
56
+ removeAbortListener = () => signal.removeEventListener('abort', onAbort);
57
+ }
58
+
59
+ try {
60
+ const result = await SherpaOnnx.extractTarBz2(
61
+ sourcePath,
62
+ targetPath,
63
+ force
64
+ );
65
+ if (!result.success) {
66
+ const message = result.reason || 'Extraction failed';
67
+ const error = new Error(message);
68
+ if (signal?.aborted || /cancel/i.test(message)) {
69
+ error.name = 'AbortError';
70
+ }
71
+ throw error;
72
+ }
73
+ return result;
74
+ } finally {
75
+ subscription?.remove();
76
+ removeAbortListener?.();
77
+ }
78
+ }
@@ -0,0 +1,43 @@
1
+ export { extractTarBz2 } from './extractTarBz2';
2
+ export type { ExtractProgressEvent } from './extractTarBz2';
3
+ export {
4
+ listModelsByCategory,
5
+ refreshModelsByCategory,
6
+ getModelsCacheStatusByCategory,
7
+ getModelByIdByCategory,
8
+ listDownloadedModelsByCategory,
9
+ isModelDownloadedByCategory,
10
+ getLocalModelPathByCategory,
11
+ downloadModelByCategory,
12
+ deleteModelByCategory,
13
+ clearModelCacheByCategory,
14
+ getDownloadStorageBase,
15
+ subscribeDownloadProgress,
16
+ subscribeModelsListUpdated,
17
+ updateModelLastUsed,
18
+ listDownloadedModelsWithMetadata,
19
+ cleanupLeastRecentlyUsed,
20
+ ModelCategory,
21
+ } from './ModelDownloadManager';
22
+ export type {
23
+ ModelMetaBase,
24
+ TtsModelMeta,
25
+ TtsModelType,
26
+ Quantization,
27
+ SizeTier,
28
+ DownloadProgress,
29
+ DownloadProgressListener,
30
+ ModelsListUpdatedListener,
31
+ DownloadResult,
32
+ ModelWithMetadata,
33
+ } from './ModelDownloadManager';
34
+ export {
35
+ validateChecksum,
36
+ validateExtractedFiles,
37
+ checkDiskSpace,
38
+ setExpectedFilesForCategory,
39
+ getExpectedFilesForCategory,
40
+ parseChecksumFile,
41
+ calculateFileChecksum,
42
+ } from './validation';
43
+ export type { ValidationError } from './validation';
@@ -0,0 +1,279 @@
1
+ import {
2
+ DocumentDirectoryPath,
3
+ stat,
4
+ exists,
5
+ readDir,
6
+ type ReadDirResItemT,
7
+ } from '@dr.pogodin/react-native-fs';
8
+ import SherpaOnnx from '../NativeSherpaOnnx';
9
+
10
+ export type ValidationError =
11
+ | 'CHECKSUM_MISMATCH'
12
+ | 'CHECKSUM_FAILED'
13
+ | 'MISSING_FILES'
14
+ | 'INSUFFICIENT_DISK_SPACE';
15
+
16
+ export class ValidationResult {
17
+ success: boolean;
18
+ error?: ValidationError;
19
+ message?: string;
20
+
21
+ constructor(success: boolean, error?: ValidationError, message?: string) {
22
+ this.success = success;
23
+ this.error = error;
24
+ this.message = message;
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Parse checksum.txt format into a Map of filename -> hash
30
+ * Expected format:
31
+ * filename\tsha256hash
32
+ * example:
33
+ * vits-vctk.tar.bz2 4f0a02db66914b3760b144cebc004e65dd4d1aeef43379f2b058849e74002490
34
+ */
35
+ export function parseChecksumFile(content: string): Map<string, string> {
36
+ const checksums = new Map<string, string>();
37
+ const lines = content.split('\n').filter((line) => line.trim());
38
+
39
+ for (const line of lines) {
40
+ const [filename, hash] = line.split(/\s+/);
41
+ if (filename && hash) {
42
+ checksums.set(filename.trim(), hash.trim());
43
+ }
44
+ }
45
+
46
+ return checksums;
47
+ }
48
+
49
+ /**
50
+ * Calculate SHA256 hash of a file in chunks to avoid OOM
51
+ * Reads file in 1MB chunks and processes them efficiently
52
+ */
53
+ export async function calculateFileChecksum(
54
+ filePath: string,
55
+ onProgress?: (
56
+ bytesProcessed: number,
57
+ totalBytes: number,
58
+ percent: number
59
+ ) => void
60
+ ): Promise<string> {
61
+ try {
62
+ const digest = await SherpaOnnx.computeFileSha256(filePath);
63
+ if (onProgress) {
64
+ const statResult = await stat(filePath);
65
+ const total = statResult.size;
66
+ onProgress(total, total, 100);
67
+ }
68
+ return digest.toLowerCase();
69
+ } catch (error) {
70
+ throw new Error(`Failed to calculate checksum: ${error}`);
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Validate checksum of downloaded file
76
+ */
77
+ export async function validateChecksum(
78
+ filePath: string,
79
+ expectedChecksum: string,
80
+ onProgress?: (
81
+ bytesProcessed: number,
82
+ totalBytes: number,
83
+ percent: number
84
+ ) => void
85
+ ): Promise<ValidationResult> {
86
+ try {
87
+ const actualChecksum = await calculateFileChecksum(filePath, onProgress);
88
+ // checksum comparison logged
89
+ if (actualChecksum.toLowerCase() !== expectedChecksum.toLowerCase()) {
90
+ return new ValidationResult(
91
+ false,
92
+ 'CHECKSUM_MISMATCH',
93
+ `Checksum mismatch: expected ${expectedChecksum}, got ${actualChecksum}`
94
+ );
95
+ }
96
+ return new ValidationResult(true);
97
+ } catch (error) {
98
+ return new ValidationResult(
99
+ false,
100
+ 'CHECKSUM_FAILED',
101
+ `Failed to validate checksum: ${error}`
102
+ );
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Validate that extraction was successful by checking:
108
+ * - Directory exists and is not empty
109
+ * - Contains at least some files (not just directories)
110
+ *
111
+ * The actual model validation (correct files for specific model type)
112
+ * is delegated to the native DetectSttModel / DetectTtsModel functions,
113
+ * so we don't need to check for specific filenames here.
114
+ */
115
+ export async function validateExtractedFiles(
116
+ modelDir: string,
117
+ _category: string
118
+ ): Promise<ValidationResult> {
119
+ try {
120
+ const dirExists = await exists(modelDir);
121
+ if (!dirExists) {
122
+ return new ValidationResult(
123
+ false,
124
+ 'MISSING_FILES',
125
+ `Model directory does not exist: ${modelDir}`
126
+ );
127
+ }
128
+
129
+ const isModelLikeFile = (name: string) => {
130
+ const lower = name.toLowerCase();
131
+ return (
132
+ lower.endsWith('.onnx') ||
133
+ lower.endsWith('.txt') ||
134
+ lower.endsWith('.bin') ||
135
+ lower.endsWith('.json')
136
+ );
137
+ };
138
+
139
+ const collectFilesRecursive = async (
140
+ dir: string,
141
+ depth = 0,
142
+ maxDepth = 4
143
+ ): Promise<ReadDirResItemT[]> => {
144
+ if (depth > maxDepth) return [];
145
+
146
+ const entries = await readDir(dir);
147
+ const files: ReadDirResItemT[] = [];
148
+
149
+ for (const entry of entries) {
150
+ if (entry.isDirectory()) {
151
+ const nested = await collectFilesRecursive(
152
+ entry.path,
153
+ depth + 1,
154
+ maxDepth
155
+ );
156
+ files.push(...nested);
157
+ } else {
158
+ files.push(entry);
159
+ }
160
+ }
161
+
162
+ return files;
163
+ };
164
+
165
+ const entries = await readDir(modelDir);
166
+ const actualFiles = entries.filter((entry) => !entry.isDirectory());
167
+ const subdirs = entries.filter((entry) => entry.isDirectory());
168
+
169
+ if (actualFiles.length === 0 && subdirs.length === 0) {
170
+ return new ValidationResult(
171
+ false,
172
+ 'MISSING_FILES',
173
+ `Extraction failed: directory is empty: ${modelDir}`
174
+ );
175
+ }
176
+
177
+ let hasModelLikeFiles = actualFiles.some((file) =>
178
+ isModelLikeFile(file.name)
179
+ );
180
+
181
+ if (!hasModelLikeFiles) {
182
+ const nestedFiles = await collectFilesRecursive(modelDir);
183
+ hasModelLikeFiles = nestedFiles.some((file) =>
184
+ isModelLikeFile(file.name)
185
+ );
186
+ }
187
+
188
+ if (!hasModelLikeFiles) {
189
+ return new ValidationResult(
190
+ false,
191
+ 'MISSING_FILES',
192
+ `Extraction may have failed: no model files (.onnx/.txt/.bin/.json) found under ${modelDir}`
193
+ );
194
+ }
195
+
196
+ return new ValidationResult(true);
197
+ } catch (error) {
198
+ return new ValidationResult(
199
+ false,
200
+ 'MISSING_FILES',
201
+ `Failed to validate extracted files: ${error}`
202
+ );
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Get available disk space (in bytes)
208
+ * This is a simplified version. For accurate values on Android/iOS, use native modules.
209
+ */
210
+ export async function getAvailableDiskSpace(): Promise<number> {
211
+ try {
212
+ // Try to get the document directory (simple check for availability)
213
+ const dirExists = await exists(DocumentDirectoryPath);
214
+ if (dirExists) {
215
+ // Default to 10GB for modern devices
216
+ // In production, integrate native disk space calculation
217
+ return 10 * 1024 * 1024 * 1024; // 10GB
218
+ }
219
+ } catch (error) {
220
+ console.warn('Failed to check disk space:', error);
221
+ }
222
+
223
+ // Fallback: return 10GB estimate for modern devices
224
+ return 10 * 1024 * 1024 * 1024;
225
+ }
226
+
227
+ /**
228
+ * Check if there's enough disk space for download
229
+ * Adds 20% buffer to the required size
230
+ */
231
+ export async function checkDiskSpace(
232
+ requiredBytes: number
233
+ ): Promise<ValidationResult> {
234
+ try {
235
+ const available = await getAvailableDiskSpace();
236
+ const buffer = requiredBytes * 0.2; // 20% safety buffer
237
+ const totalRequired = requiredBytes + buffer;
238
+
239
+ if (available < totalRequired) {
240
+ const availableGB = (available / (1024 * 1024 * 1024)).toFixed(2);
241
+ const requiredGB = (totalRequired / (1024 * 1024 * 1024)).toFixed(2);
242
+ return new ValidationResult(
243
+ false,
244
+ 'INSUFFICIENT_DISK_SPACE',
245
+ `Insufficient disk space. Available: ${availableGB}GB, Required: ${requiredGB}GB`
246
+ );
247
+ }
248
+
249
+ return new ValidationResult(true);
250
+ } catch (error) {
251
+ return new ValidationResult(
252
+ false,
253
+ 'INSUFFICIENT_DISK_SPACE',
254
+ `Failed to check disk space: ${error}`
255
+ );
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Update expected files configuration for a category
261
+ * DEPRECATED: The native DetectSttModel/DetectTtsModel functions handle model validation.
262
+ * This function is kept for backward compatibility but does nothing.
263
+ */
264
+ export function setExpectedFilesForCategory(
265
+ _category: string,
266
+ _files: string[]
267
+ ): void {
268
+ // No-op: validation is now handled by native detect functions
269
+ }
270
+
271
+ /**
272
+ * Get expected files for a category
273
+ * DEPRECATED: The native DetectSttModel/DetectTtsModel functions handle model validation.
274
+ * This function is kept for backward compatibility.
275
+ */
276
+ export function getExpectedFilesForCategory(_category: string): string[] {
277
+ // Return empty array: validation is now handled by native detect functions
278
+ return [];
279
+ }
@@ -10,16 +10,18 @@
10
10
  * // Future usage:
11
11
  * import { initializeEnhancement, enhanceAudio } from 'react-native-sherpa-onnx/enhancement';
12
12
  *
13
- * await initializeEnhancement({ modelPath: 'models/enhancement-model' });
13
+ * await initializeEnhancement({ modelPath: { type: 'auto', path: 'models/enhancement-model' } });
14
14
  * const enhancedPath = await enhanceAudio('path/to/noisy-audio.wav');
15
15
  * ```
16
16
  */
17
17
 
18
+ import type { ModelPathConfig } from '../types';
19
+
18
20
  /**
19
21
  * Enhancement initialization options (placeholder)
20
22
  */
21
23
  export interface EnhancementInitializeOptions {
22
- modelPath: string;
24
+ modelPath: ModelPathConfig;
23
25
  // Additional enhancement-specific options will be added here
24
26
  }
25
27
 
package/src/index.tsx CHANGED
@@ -1,27 +1,78 @@
1
- import SherpaOnnx from './NativeSherpaOnnx';
2
-
3
- // Export common types and utilities
4
- export type { InitializeOptions, ModelPathConfig, ModelType } from './types';
5
- export {
6
- assetModelPath,
7
- autoModelPath,
8
- fileModelPath,
9
- getDefaultModelPath,
10
- listAssetModels,
11
- resolveModelPath,
12
- } from './utils';
13
-
14
- // Note: Feature-specific exports are available via subpath imports:
15
- // - import { ... } from 'react-native-sherpa-onnx/stt'
16
- // - import { ... } from 'react-native-sherpa-onnx/tts'
17
- // - import { ... } from 'react-native-sherpa-onnx/vad' (planned)
18
- // - import { ... } from 'react-native-sherpa-onnx/diarization' (planned)
19
- // - import { ... } from 'react-native-sherpa-onnx/enhancement' (planned)
20
- // - import { ... } from 'react-native-sherpa-onnx/separation' (planned)
21
-
22
- /**
23
- * Test method to verify sherpa-onnx native library is loaded.
24
- */
25
- export function testSherpaInit(): Promise<string> {
26
- return SherpaOnnx.testSherpaInit();
27
- }
1
+ import SherpaOnnx from './NativeSherpaOnnx';
2
+ import type { AccelerationSupport } from './NativeSherpaOnnx';
3
+
4
+ // Export common types and utilities
5
+ export type { AccelerationSupport } from './NativeSherpaOnnx';
6
+ export type { ModelPathConfig } from './types';
7
+ export {
8
+ assetModelPath,
9
+ autoModelPath,
10
+ fileModelPath,
11
+ getAssetPackPath,
12
+ getDefaultModelPath,
13
+ getPlayAssetDeliveryModelsPath,
14
+ listAssetModels,
15
+ listModelsAtPath,
16
+ resolveModelPath,
17
+ } from './utils';
18
+
19
+ // Note: Feature-specific exports are available via subpath imports:
20
+ // - import { ... } from 'react-native-sherpa-onnx/stt'
21
+ // - import { ... } from 'react-native-sherpa-onnx/tts'
22
+ // - import { ... } from 'react-native-sherpa-onnx/download'
23
+ // - import { ... } from 'react-native-sherpa-onnx/vad' (planned)
24
+ // - import { ... } from 'react-native-sherpa-onnx/diarization' (planned)
25
+ // - import { ... } from 'react-native-sherpa-onnx/enhancement' (planned)
26
+ // - import { ... } from 'react-native-sherpa-onnx/separation' (planned)
27
+
28
+ /**
29
+ * Test method to verify sherpa-onnx native library is loaded.
30
+ */
31
+ export function testSherpaInit(): Promise<string> {
32
+ return SherpaOnnx.testSherpaInit();
33
+ }
34
+
35
+ /**
36
+ * QNN support (Android). Optional modelBase64 for canInit (session test); if omitted, SDK uses embedded test model.
37
+ */
38
+ export function getQnnSupport(
39
+ modelBase64?: string
40
+ ): Promise<AccelerationSupport> {
41
+ return SherpaOnnx.getQnnSupport(modelBase64);
42
+ }
43
+
44
+ /**
45
+ * Return the list of available ONNX Runtime execution providers
46
+ * (e.g. "CPU", "NNAPI", "QNN", "XNNPACK").
47
+ * Requires the ORT Java bridge from the onnxruntime AAR.
48
+ */
49
+ export function getAvailableProviders(): Promise<string[]> {
50
+ return SherpaOnnx.getAvailableProviders();
51
+ }
52
+
53
+ /**
54
+ * NNAPI support (Android). Optional modelBase64 for canInit (session test). On iOS returns all false.
55
+ */
56
+ export function getNnapiSupport(
57
+ modelBase64?: string
58
+ ): Promise<AccelerationSupport> {
59
+ return SherpaOnnx.getNnapiSupport(modelBase64);
60
+ }
61
+
62
+ /**
63
+ * XNNPACK support. hasAccelerator = true when providerCompiled (CPU-optimized). Optional modelBase64 for canInit. On iOS returns all false.
64
+ */
65
+ export function getXnnpackSupport(
66
+ modelBase64?: string
67
+ ): Promise<AccelerationSupport> {
68
+ return SherpaOnnx.getXnnpackSupport(modelBase64);
69
+ }
70
+
71
+ /**
72
+ * Core ML support (iOS). providerCompiled = true (Core ML on iOS 11+), hasAccelerator = Apple Neural Engine. Optional modelBase64 for canInit. On Android returns all false.
73
+ */
74
+ export function getCoreMlSupport(
75
+ modelBase64?: string
76
+ ): Promise<AccelerationSupport> {
77
+ return SherpaOnnx.getCoreMlSupport(modelBase64);
78
+ }
@@ -10,16 +10,18 @@
10
10
  * // Future usage:
11
11
  * import { initializeSeparation, separateSources } from 'react-native-sherpa-onnx/separation';
12
12
  *
13
- * await initializeSeparation({ modelPath: 'models/separation-model' });
13
+ * await initializeSeparation({ modelPath: { type: 'auto', path: 'models/separation-model' } });
14
14
  * const sources = await separateSources('path/to/mixed-audio.wav');
15
15
  * ```
16
16
  */
17
17
 
18
+ import type { ModelPathConfig } from '../types';
19
+
18
20
  /**
19
21
  * Separation initialization options (placeholder)
20
22
  */
21
23
  export interface SeparationInitializeOptions {
22
- modelPath: string;
24
+ modelPath: ModelPathConfig;
23
25
  // Additional separation-specific options will be added here
24
26
  }
25
27