@qvac/sdk 0.6.1 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/LICENSE +1 -24
  2. package/NOTICE +632 -0
  3. package/README.md +2 -1
  4. package/dist/client/api/embed.js +1 -4
  5. package/dist/client/api/get-model-info.d.ts +10 -3
  6. package/dist/client/api/index.d.ts +2 -0
  7. package/dist/client/api/index.js +2 -0
  8. package/dist/client/api/invoke-plugin.d.ts +14 -0
  9. package/dist/client/api/invoke-plugin.js +38 -0
  10. package/dist/client/api/registry.d.ts +14 -0
  11. package/dist/client/api/registry.js +37 -0
  12. package/dist/client/api/transcribe.js +0 -4
  13. package/dist/client/api/unload-model.js +1 -1
  14. package/dist/client/config-loader/resolve-config.node.d.ts +3 -2
  15. package/dist/client/config-loader/resolve-config.node.js +31 -4
  16. package/dist/client/init-hooks.js +2 -1
  17. package/dist/client/rpc/bare-client.d.ts +2 -0
  18. package/dist/client/rpc/bare-client.js +48 -7
  19. package/dist/client/rpc/expo-device-info.d.ts +6 -0
  20. package/dist/client/rpc/expo-device-info.js +32 -0
  21. package/dist/client/rpc/expo-rpc-client.js +9 -32
  22. package/dist/client/rpc/node-rpc-client.d.ts +1 -1
  23. package/dist/client/rpc/node-rpc-client.js +201 -28
  24. package/dist/client/rpc/rpc-client.d.ts +1 -1
  25. package/dist/client/rpc/rpc-client.js +2 -2
  26. package/dist/constants/index.d.ts +1 -0
  27. package/dist/constants/index.js +1 -0
  28. package/dist/constants/registry.d.ts +2 -0
  29. package/dist/constants/registry.js +1 -0
  30. package/dist/examples/cache-management.js +2 -2
  31. package/dist/examples/config/plugins/plugins.config.d.ts +5 -0
  32. package/dist/examples/config/plugins/plugins.config.js +4 -0
  33. package/dist/examples/download-with-blind-relays.js +1 -1
  34. package/dist/examples/llamacpp-multimodal.js +3 -3
  35. package/dist/examples/llamacpp-native-tools.js +2 -2
  36. package/dist/examples/mcp-websearch.js +2 -2
  37. package/dist/examples/multi-model-demo.js +2 -2
  38. package/dist/examples/ocr-fasttext.js +4 -4
  39. package/dist/examples/parallel-download.js +2 -2
  40. package/dist/examples/plugins.d.ts +14 -0
  41. package/dist/examples/plugins.js +129 -0
  42. package/dist/examples/registry-query.d.ts +2 -0
  43. package/dist/examples/registry-query.js +87 -0
  44. package/dist/examples/translation/translation-bergamot-batch.js +2 -2
  45. package/dist/examples/translation/translation-bergamot.js +4 -4
  46. package/dist/examples/translation/translation-opus.js +2 -2
  47. package/dist/examples/translation/translation-stream.js +2 -2
  48. package/dist/examples/tts/chatterbox.d.ts +2 -0
  49. package/dist/examples/tts/chatterbox.js +59 -0
  50. package/dist/examples/tts/supertonic.d.ts +2 -0
  51. package/dist/examples/tts/supertonic.js +51 -0
  52. package/dist/examples/tts/utils.d.ts +17 -0
  53. package/dist/examples/tts/utils.js +93 -0
  54. package/dist/examples/whispercpp-filesystem.js +2 -3
  55. package/dist/examples/whispercpp-microphone-record.js +1 -2
  56. package/dist/examples/whispercpp-prompt.js +2 -3
  57. package/dist/expo/plugins/index.d.ts +3 -0
  58. package/dist/expo/plugins/index.js +3 -0
  59. package/dist/expo/plugins/resolve-sdk-package-dir.d.ts +15 -0
  60. package/dist/expo/plugins/resolve-sdk-package-dir.js +31 -0
  61. package/dist/expo/plugins/withAndroidArchitecture.d.ts +8 -0
  62. package/dist/expo/plugins/withAndroidArchitecture.js +52 -0
  63. package/dist/expo/plugins/withAndroidNdkVersion.d.ts +8 -0
  64. package/dist/expo/plugins/withAndroidNdkVersion.js +31 -0
  65. package/dist/expo/plugins/withDeviceInfo.d.ts +10 -0
  66. package/dist/expo/plugins/withDeviceInfo.js +48 -0
  67. package/dist/expo/plugins/withMobileBundle.d.ts +5 -2
  68. package/dist/expo/plugins/withMobileBundle.js +121 -65
  69. package/dist/expo/plugins/withQvacSDK.d.ts +4 -0
  70. package/dist/expo/plugins/withQvacSDK.js +26 -1
  71. package/dist/index.d.ts +4 -4
  72. package/dist/index.js +5 -5
  73. package/dist/models/{hyperdrive → registry}/index.js +1 -1
  74. package/dist/models/registry/models.d.ts +9056 -0
  75. package/dist/models/registry/models.js +9351 -0
  76. package/dist/models/update-models/codegen.d.ts +3 -0
  77. package/dist/models/update-models/codegen.js +135 -0
  78. package/dist/models/update-models/history.d.ts +13 -0
  79. package/dist/models/update-models/history.js +88 -0
  80. package/dist/models/update-models/index.d.ts +2 -0
  81. package/dist/models/update-models/index.js +124 -0
  82. package/dist/models/update-models/naming.d.ts +4 -0
  83. package/dist/models/update-models/naming.js +314 -0
  84. package/dist/models/update-models/processing.d.ts +8 -0
  85. package/dist/models/update-models/processing.js +67 -0
  86. package/dist/models/update-models/registry.d.ts +4 -0
  87. package/dist/models/update-models/registry.js +67 -0
  88. package/dist/models/update-models/shards.d.ts +4 -0
  89. package/dist/models/update-models/shards.js +57 -0
  90. package/dist/models/update-models/types.d.ts +60 -0
  91. package/dist/models/update-models/types.js +1 -0
  92. package/dist/models/update-models/utils.d.ts +3 -0
  93. package/dist/models/update-models/utils.js +21 -0
  94. package/dist/pear/pre.d.ts +18 -0
  95. package/dist/pear/pre.js +433 -0
  96. package/dist/schemas/common.d.ts +286 -32
  97. package/dist/schemas/common.js +12 -0
  98. package/dist/schemas/download-asset.d.ts +35 -11
  99. package/dist/schemas/download-asset.js +5 -1
  100. package/dist/schemas/engine-addon-map.d.ts +5 -0
  101. package/dist/schemas/engine-addon-map.js +49 -0
  102. package/dist/schemas/get-model-info.d.ts +32 -16
  103. package/dist/schemas/get-model-info.js +17 -8
  104. package/dist/schemas/index.d.ts +4 -1
  105. package/dist/schemas/index.js +4 -4
  106. package/dist/schemas/load-model.d.ts +2224 -900
  107. package/dist/schemas/load-model.js +130 -25
  108. package/dist/schemas/model-src-utils.d.ts +30 -12
  109. package/dist/schemas/model-src-utils.js +5 -2
  110. package/dist/schemas/model-types.d.ts +15 -4
  111. package/dist/schemas/model-types.js +21 -4
  112. package/dist/schemas/path-validation.d.ts +10 -0
  113. package/dist/schemas/path-validation.js +22 -0
  114. package/dist/schemas/plugin.d.ts +180 -0
  115. package/dist/schemas/plugin.js +132 -0
  116. package/dist/schemas/rag.d.ts +2 -2
  117. package/dist/schemas/rag.js +7 -3
  118. package/dist/schemas/registry.d.ts +338 -0
  119. package/dist/schemas/registry.js +91 -0
  120. package/dist/schemas/sdk-errors-client.d.ts +6 -6
  121. package/dist/schemas/sdk-errors-client.js +15 -15
  122. package/dist/schemas/sdk-errors-registry.d.ts +6 -0
  123. package/dist/schemas/sdk-errors-registry.js +8 -0
  124. package/dist/schemas/sdk-errors-server.d.ts +16 -2
  125. package/dist/schemas/sdk-errors-server.js +90 -10
  126. package/dist/schemas/text-to-speech.d.ts +670 -1
  127. package/dist/schemas/text-to-speech.js +51 -2
  128. package/dist/schemas/translate.d.ts +2 -2
  129. package/dist/scripts/run-security-tests-bare.d.ts +2 -0
  130. package/dist/scripts/run-security-tests-bare.js +78 -0
  131. package/dist/scripts/run-security-tests.d.ts +2 -0
  132. package/dist/scripts/run-security-tests.js +22 -0
  133. package/dist/server/bare/delegate-rpc-client.d.ts +6 -0
  134. package/dist/server/bare/delegate-rpc-client.js +136 -56
  135. package/dist/server/bare/{addons/llamacpp-embedding/handlers → ops}/embed.d.ts +1 -1
  136. package/dist/server/bare/{addons/llamacpp-embedding/handlers → ops}/embed.js +3 -3
  137. package/dist/server/bare/{addons/llamacpp-completion → ops}/kv-cache-utils.js +6 -6
  138. package/dist/server/bare/{addons → ops}/load-model.js +32 -42
  139. package/dist/server/bare/{addons/nmtcpp-translation/handlers → ops}/translate.d.ts +1 -1
  140. package/dist/server/bare/{addons/nmtcpp-translation/handlers → ops}/translate.js +5 -4
  141. package/dist/server/bare/plugins/index.d.ts +7 -0
  142. package/dist/server/bare/plugins/index.js +6 -0
  143. package/dist/server/bare/{addons/llamacpp-completion → plugins/llamacpp-completion/ops}/cache-logger.js +1 -1
  144. package/dist/server/bare/{addons/llamacpp-completion/handlers → plugins/llamacpp-completion/ops}/completion-stream.d.ts +1 -1
  145. package/dist/server/bare/{addons/llamacpp-completion/handlers → plugins/llamacpp-completion/ops}/completion-stream.js +2 -3
  146. package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +115 -0
  147. package/dist/server/bare/plugins/llamacpp-completion/plugin.js +142 -0
  148. package/dist/server/bare/plugins/llamacpp-embedding/plugin.d.ts +24 -0
  149. package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +73 -0
  150. package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +45 -0
  151. package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +97 -0
  152. package/dist/server/bare/{addons/onnx-ocr/handlers → plugins/onnx-ocr/ops}/ocr-stream.js +2 -1
  153. package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +38 -0
  154. package/dist/server/bare/{addons/onnx-ocr/create-model.js → plugins/onnx-ocr/plugin.js} +39 -2
  155. package/dist/server/bare/{addons/onnx-tts/handlers → plugins/onnx-tts/ops}/text-to-speech.js +23 -1
  156. package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +26 -0
  157. package/dist/server/bare/plugins/onnx-tts/plugin.js +162 -0
  158. package/dist/server/bare/plugins/onnx-tts/wav-helper.d.ts +14 -0
  159. package/dist/server/bare/plugins/onnx-tts/wav-helper.js +107 -0
  160. package/dist/server/bare/plugins/whispercpp-transcription/ops/transcribe-stream.d.ts +3 -0
  161. package/dist/server/bare/{addons/whispercpp-transcription/handlers → plugins/whispercpp-transcription/ops}/transcribe-stream.js +1 -2
  162. package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +31 -0
  163. package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +74 -0
  164. package/dist/server/bare/rag-hyperdb/handlers/ingest.js +1 -1
  165. package/dist/server/bare/rag-hyperdb/handlers/search.js +1 -1
  166. package/dist/server/bare/rag-hyperdb/rag-workspace-manager.js +2 -1
  167. package/dist/server/bare/registry/config-registry.js +1 -1
  168. package/dist/server/bare/registry/registry-client.d.ts +5 -0
  169. package/dist/server/bare/registry/registry-client.js +37 -0
  170. package/dist/server/env.d.ts +22 -0
  171. package/dist/server/env.js +57 -0
  172. package/dist/server/plugins/index.d.ts +2 -0
  173. package/dist/server/plugins/index.js +1 -0
  174. package/dist/server/plugins/registry.d.ts +9 -0
  175. package/dist/server/plugins/registry.js +75 -0
  176. package/dist/server/rpc/delegate-transport.d.ts +11 -0
  177. package/dist/server/rpc/delegate-transport.js +60 -0
  178. package/dist/server/rpc/handle-request.d.ts +0 -9
  179. package/dist/server/rpc/handle-request.js +13 -321
  180. package/dist/server/rpc/handler-registry.d.ts +3 -0
  181. package/dist/server/rpc/handler-registry.js +84 -0
  182. package/dist/server/rpc/handler-utils.d.ts +22 -0
  183. package/dist/server/rpc/handler-utils.js +87 -0
  184. package/dist/server/rpc/handlers/cancelHandler.js +1 -1
  185. package/dist/server/rpc/handlers/completion-stream-delegated.js +1 -1
  186. package/dist/server/rpc/handlers/completion-stream.js +2 -43
  187. package/dist/server/rpc/handlers/delete-cache.js +1 -1
  188. package/dist/server/rpc/handlers/embed.js +2 -21
  189. package/dist/server/rpc/handlers/get-model-info.js +19 -15
  190. package/dist/server/rpc/handlers/index.d.ts +9 -0
  191. package/dist/server/rpc/handlers/index.js +9 -0
  192. package/dist/server/rpc/handlers/load-model/download-manager.d.ts +1 -0
  193. package/dist/server/rpc/handlers/load-model/download-manager.js +3 -0
  194. package/dist/server/rpc/handlers/load-model/handler.js +47 -24
  195. package/dist/server/rpc/handlers/load-model/http.js +3 -2
  196. package/dist/server/rpc/handlers/load-model/hyperdrive.js +14 -10
  197. package/dist/server/rpc/handlers/load-model/registry.d.ts +10 -0
  198. package/dist/server/rpc/handlers/load-model/registry.js +571 -0
  199. package/dist/server/rpc/handlers/load-model/resolve.js +18 -5
  200. package/dist/server/rpc/handlers/load-model-delegated.js +4 -2
  201. package/dist/server/rpc/handlers/ocr-stream.js +2 -37
  202. package/dist/server/rpc/handlers/ping.d.ts +3 -0
  203. package/dist/server/rpc/handlers/ping.js +3 -0
  204. package/dist/server/rpc/handlers/plugin-dispatch.d.ts +15 -0
  205. package/dist/server/rpc/handlers/plugin-dispatch.js +54 -0
  206. package/dist/server/rpc/handlers/plugin-invoke.d.ts +4 -0
  207. package/dist/server/rpc/handlers/plugin-invoke.js +87 -0
  208. package/dist/server/rpc/handlers/registry.d.ts +5 -0
  209. package/dist/server/rpc/handlers/registry.js +157 -0
  210. package/dist/server/rpc/handlers/text-to-speech.js +2 -5
  211. package/dist/server/rpc/handlers/transcribe-stream.js +2 -30
  212. package/dist/server/rpc/handlers/translate.js +2 -42
  213. package/dist/server/rpc/handlers/unload-model.js +1 -1
  214. package/dist/server/rpc/index.d.ts +1 -1
  215. package/dist/server/utils/archive.d.ts +1 -0
  216. package/dist/server/utils/archive.js +10 -2
  217. package/dist/server/utils/cache.d.ts +5 -0
  218. package/dist/server/utils/cache.js +26 -2
  219. package/dist/server/utils/gguf-tensor-extractor.js +3 -3
  220. package/dist/server/utils/index.d.ts +1 -1
  221. package/dist/server/utils/index.js +1 -1
  222. package/dist/server/utils/path-security.d.ts +12 -0
  223. package/dist/server/utils/path-security.js +25 -0
  224. package/dist/server/utils/shard-utils.js +3 -3
  225. package/dist/server/worker-core.d.ts +6 -0
  226. package/dist/server/worker-core.js +88 -0
  227. package/dist/server/worker.d.ts +4 -5
  228. package/dist/server/worker.js +18 -116
  229. package/dist/utils/errors-client.d.ts +9 -6
  230. package/dist/utils/errors-client.js +19 -11
  231. package/dist/utils/errors-server.d.ts +44 -5
  232. package/dist/utils/errors-server.js +82 -9
  233. package/dist/utils/path-sanitize.d.ts +17 -0
  234. package/dist/utils/path-sanitize.js +54 -0
  235. package/expo/plugins/patches/android-link.mjs +63 -0
  236. package/expo/plugins/patches/ios-link.mjs +63 -0
  237. package/package.json +72 -10
  238. package/dist/examples/text-to-speech.d.ts +0 -3
  239. package/dist/examples/text-to-speech.js +0 -137
  240. package/dist/models/hyperdrive/models.d.ts +0 -4003
  241. package/dist/models/hyperdrive/models.js +0 -4282
  242. package/dist/server/bare/addons/index.d.ts +0 -4
  243. package/dist/server/bare/addons/index.js +0 -3
  244. package/dist/server/bare/addons/llamacpp-completion/create-model.d.ts +0 -8
  245. package/dist/server/bare/addons/llamacpp-completion/create-model.js +0 -43
  246. package/dist/server/bare/addons/llamacpp-completion/index.d.ts +0 -4
  247. package/dist/server/bare/addons/llamacpp-completion/index.js +0 -3
  248. package/dist/server/bare/addons/llamacpp-embedding/create-model.d.ts +0 -8
  249. package/dist/server/bare/addons/llamacpp-embedding/create-model.js +0 -38
  250. package/dist/server/bare/addons/llamacpp-embedding/index.d.ts +0 -3
  251. package/dist/server/bare/addons/llamacpp-embedding/index.js +0 -2
  252. package/dist/server/bare/addons/nmtcpp-translation/create-model.d.ts +0 -8
  253. package/dist/server/bare/addons/nmtcpp-translation/create-model.js +0 -52
  254. package/dist/server/bare/addons/nmtcpp-translation/index.d.ts +0 -3
  255. package/dist/server/bare/addons/nmtcpp-translation/index.js +0 -2
  256. package/dist/server/bare/addons/onnx-ocr/create-model.d.ts +0 -10
  257. package/dist/server/bare/addons/onnx-ocr/index.d.ts +0 -3
  258. package/dist/server/bare/addons/onnx-ocr/index.js +0 -2
  259. package/dist/server/bare/addons/onnx-tts/create-model.d.ts +0 -10
  260. package/dist/server/bare/addons/onnx-tts/create-model.js +0 -25
  261. package/dist/server/bare/addons/onnx-tts/index.d.ts +0 -3
  262. package/dist/server/bare/addons/onnx-tts/index.js +0 -2
  263. package/dist/server/bare/addons/whispercpp-transcription/create-model.d.ts +0 -10
  264. package/dist/server/bare/addons/whispercpp-transcription/create-model.js +0 -37
  265. package/dist/server/bare/addons/whispercpp-transcription/handlers/transcribe-stream.d.ts +0 -3
  266. package/dist/server/bare/addons/whispercpp-transcription/index.d.ts +0 -3
  267. package/dist/server/bare/addons/whispercpp-transcription/index.js +0 -2
  268. /package/dist/models/{hyperdrive → registry}/index.d.ts +0 -0
  269. /package/dist/server/bare/{addons → ops}/cancel.d.ts +0 -0
  270. /package/dist/server/bare/{addons → ops}/cancel.js +0 -0
  271. /package/dist/server/bare/{addons/llamacpp-completion → ops}/kv-cache-utils.d.ts +0 -0
  272. /package/dist/server/bare/{addons → ops}/load-model.d.ts +0 -0
  273. /package/dist/server/bare/{addons → ops}/unload-model.d.ts +0 -0
  274. /package/dist/server/bare/{addons → ops}/unload-model.js +0 -0
  275. /package/dist/server/bare/{addons/llamacpp-completion → plugins/llamacpp-completion/ops}/cache-logger.d.ts +0 -0
  276. /package/dist/server/bare/{addons/onnx-ocr/handlers → plugins/onnx-ocr/ops}/ocr-stream.d.ts +0 -0
  277. /package/dist/server/bare/{addons/onnx-tts/handlers → plugins/onnx-tts/ops}/text-to-speech.d.ts +0 -0
@@ -0,0 +1,87 @@
1
+ import { modelRegistryList, modelRegistrySearch, modelRegistryGetModel, ModelType, close, } from "@qvac/sdk";
2
+ try {
3
+ console.log("QVAC Model Registry Query Examples\n");
4
+ // List all available models
5
+ console.log("Listing all models in QVAC model registry...");
6
+ const allModels = await modelRegistryList();
7
+ console.log(` Found ${allModels.length} models in registry\n`);
8
+ // Show first 5 models as sample
9
+ console.log(" Sample models:");
10
+ allModels.slice(0, 5).forEach((model) => {
11
+ console.log(` - ${model.name} (${model.addon}, ${model.engine}, ${formatSize(model.expectedSize)})`);
12
+ });
13
+ console.log();
14
+ // Search with text filter
15
+ console.log('Searching for "whisper" models...');
16
+ const whisperModels = await modelRegistrySearch({ filter: "whisper" });
17
+ console.log(` Found ${whisperModels.length} whisper-related models\n`);
18
+ // Search by engine (using canonical ModelType enum)
19
+ console.log(`Searching by engine (${ModelType.llamacppEmbedding})...`);
20
+ const embedModels = await modelRegistrySearch({
21
+ engine: ModelType.llamacppEmbedding,
22
+ });
23
+ console.log(` Found ${embedModels.length} embedding models`);
24
+ embedModels.slice(0, 3).forEach((model) => {
25
+ console.log(` - ${model.name} (${model.quantization})`);
26
+ });
27
+ console.log();
28
+ // Search by quantization
29
+ console.log("Searching for Q4 quantized models...");
30
+ const q4Models = await modelRegistrySearch({ quantization: "q4" });
31
+ console.log(` Found ${q4Models.length} Q4 quantized models`);
32
+ q4Models.slice(0, 3).forEach((model) => {
33
+ console.log(` - ${model.name}`);
34
+ });
35
+ console.log();
36
+ // Search by addon/model type
37
+ console.log("Searching for transcription models...");
38
+ const transcriptionModels = await modelRegistrySearch({
39
+ addon: "whisper",
40
+ });
41
+ console.log(` Found ${transcriptionModels.length} transcription models`);
42
+ transcriptionModels.slice(0, 3).forEach((model) => {
43
+ console.log(` - ${model.name}`);
44
+ });
45
+ console.log();
46
+ // Combined search: engine + quantization
47
+ console.log("Searching for Q4 LLM models...");
48
+ const q4LlmModels = await modelRegistrySearch({
49
+ engine: ModelType.llamacppCompletion,
50
+ quantization: "q4",
51
+ });
52
+ console.log(` Found ${q4LlmModels.length} Q4 LLM models`);
53
+ q4LlmModels.slice(0, 3).forEach((model) => {
54
+ console.log(` - ${model.name} (${model.quantization})`);
55
+ });
56
+ console.log();
57
+ // Get specific model (if we have at least one model)
58
+ const sampleModel = allModels[0];
59
+ if (sampleModel) {
60
+ console.log(`Getting specific model: ${sampleModel.registrySource}/${sampleModel.registryPath}`);
61
+ const model = await modelRegistryGetModel(sampleModel.registryPath, sampleModel.registrySource);
62
+ console.log(" Model details:");
63
+ console.log(` - Name: ${model.name}`);
64
+ console.log(` - Addon: ${model.addon}`);
65
+ console.log(` - Engine: ${model.engine}`);
66
+ console.log(` - Quantization: ${model.quantization}`);
67
+ console.log(` - Expected size: ${formatSize(model.expectedSize)}`);
68
+ console.log(` - Checksum: ${model.sha256Checksum.slice(0, 16)}...`);
69
+ console.log();
70
+ }
71
+ console.log("QVAC model registry query examples completed successfully!");
72
+ void close();
73
+ process.exit(0);
74
+ }
75
+ catch (error) {
76
+ console.error("Error:", error);
77
+ process.exit(1);
78
+ }
79
+ function formatSize(bytes) {
80
+ if (bytes < 1024)
81
+ return `${bytes}B`;
82
+ if (bytes < 1024 * 1024)
83
+ return `${(bytes / 1024).toFixed(1)}KB`;
84
+ if (bytes < 1024 * 1024 * 1024)
85
+ return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
86
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)}GB`;
87
+ }
@@ -1,7 +1,7 @@
1
- import { loadModel, translate, unloadModel, BERGAMOT_ENFR } from "@qvac/sdk";
1
+ import { loadModel, translate, unloadModel, BERGAMOT_EN_FR } from "@qvac/sdk";
2
2
  try {
3
3
  const modelId = await loadModel({
4
- modelSrc: BERGAMOT_ENFR,
4
+ modelSrc: BERGAMOT_EN_FR,
5
5
  modelType: "nmt",
6
6
  modelConfig: {
7
7
  engine: "Bergamot",
@@ -1,11 +1,11 @@
1
- import { loadModel, translate, unloadModel, BERGAMOT_ENFR } from "@qvac/sdk";
1
+ import { loadModel, translate, unloadModel, BERGAMOT_EN_FR } from "@qvac/sdk";
2
2
  try {
3
- // Bergamot models automatically derive vocabulary files from the model source
4
- // when using pear:// URLs. You can still override them explicitly if needed:
3
+ // Bergamot models automatically derive vocabulary files from the model source.
4
+ // You can still override them explicitly if needed:
5
5
  // - srcVocabSrc: source vocabulary file (optional)
6
6
  // - dstVocabSrc: target vocabulary file (optional)
7
7
  const modelId = await loadModel({
8
- modelSrc: BERGAMOT_ENFR,
8
+ modelSrc: BERGAMOT_EN_FR,
9
9
  modelType: "nmt",
10
10
  modelConfig: {
11
11
  engine: "Bergamot",
@@ -1,7 +1,7 @@
1
- import { loadModel, translate, unloadModel, MARIAN_OPUS_EN_IT_Q0F32, } from "@qvac/sdk";
1
+ import { loadModel, translate, unloadModel, MARIAN_OPUS_EN_IT_Q4_0, } from "@qvac/sdk";
2
2
  try {
3
3
  const modelId = await loadModel({
4
- modelSrc: MARIAN_OPUS_EN_IT_Q0F32,
4
+ modelSrc: MARIAN_OPUS_EN_IT_Q4_0,
5
5
  modelType: "nmt",
6
6
  modelConfig: {
7
7
  engine: "Opus",
@@ -1,7 +1,7 @@
1
- import { loadModel, translate, MARIAN_OPUS_EN_IT_Q0F32, unloadModel, } from "@qvac/sdk";
1
+ import { loadModel, translate, unloadModel, MARIAN_OPUS_EN_IT_Q4_0, } from "@qvac/sdk";
2
2
  try {
3
3
  const modelId = await loadModel({
4
- modelSrc: MARIAN_OPUS_EN_IT_Q0F32,
4
+ modelSrc: MARIAN_OPUS_EN_IT_Q4_0,
5
5
  modelType: "nmt",
6
6
  modelConfig: {
7
7
  engine: "Opus",
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=chatterbox.d.ts.map
@@ -0,0 +1,59 @@
1
+ import { loadModel, textToSpeech, unloadModel, TTS_TOKENIZER_EN_CHATTERBOX, TTS_SPEECH_ENCODER_EN_CHATTERBOX_FP32, TTS_EMBED_TOKENS_EN_CHATTERBOX_FP32, TTS_CONDITIONAL_DECODER_EN_CHATTERBOX_FP32, TTS_LANGUAGE_MODEL_EN_CHATTERBOX_FP32, } from "@qvac/sdk";
2
+ import { createWav, playAudio, int16ArrayToBuffer, createWavHeader, } from "./utils.js";
3
+ // Chatterbox TTS: voice cloning with reference audio.
4
+ // Uses registry model constants - downloads automatically from QVAC Registry.
5
+ // Only reference audio WAV needs to be provided by the user.
6
+ // Usage: node chatterbox-filesystem.js <referenceAudioSrc>
7
+ const [referenceAudioSrc] = process.argv.slice(2);
8
+ if (!referenceAudioSrc) {
9
+ console.error("Usage: node chatterbox-filesystem.js <referenceAudioSrc>");
10
+ process.exit(1);
11
+ }
12
+ const CHATTERBOX_SAMPLE_RATE = 24000;
13
+ try {
14
+ const modelId = await loadModel({
15
+ modelSrc: TTS_TOKENIZER_EN_CHATTERBOX.src,
16
+ modelType: "tts",
17
+ modelConfig: {
18
+ ttsEngine: "chatterbox",
19
+ language: "en",
20
+ ttsTokenizerSrc: TTS_TOKENIZER_EN_CHATTERBOX.src,
21
+ ttsSpeechEncoderSrc: TTS_SPEECH_ENCODER_EN_CHATTERBOX_FP32.src,
22
+ ttsEmbedTokensSrc: TTS_EMBED_TOKENS_EN_CHATTERBOX_FP32.src,
23
+ ttsConditionalDecoderSrc: TTS_CONDITIONAL_DECODER_EN_CHATTERBOX_FP32.src,
24
+ ttsLanguageModelSrc: TTS_LANGUAGE_MODEL_EN_CHATTERBOX_FP32.src,
25
+ referenceAudioSrc,
26
+ },
27
+ onProgress: (progress) => {
28
+ console.log(progress);
29
+ },
30
+ });
31
+ console.log(`Model loaded: ${modelId}`);
32
+ console.log("🎵 Testing Text-to-Speech...");
33
+ const result = textToSpeech({
34
+ modelId,
35
+ text: `QVAC SDK is the canonical entry point to QVAC. Written in TypeScript, it provides all QVAC capabilities through a unified interface while also abstracting away the complexity of running your application in a JS environment other than Bare. Supported JS environments include Bare, Node.js, Expo and Bun.`,
36
+ inputType: "text",
37
+ stream: false,
38
+ });
39
+ const audioBuffer = await result.buffer;
40
+ console.log(`TTS complete. Total bytes: ${audioBuffer.length}`);
41
+ console.log("💾 Saving audio to file...");
42
+ createWav(audioBuffer, CHATTERBOX_SAMPLE_RATE, "tts-output.wav");
43
+ console.log("✅ Audio saved to tts-output.wav");
44
+ console.log("🔊 Playing audio...");
45
+ const audioData = int16ArrayToBuffer(audioBuffer);
46
+ const wavBuffer = Buffer.concat([
47
+ createWavHeader(audioData.length, CHATTERBOX_SAMPLE_RATE),
48
+ audioData,
49
+ ]);
50
+ playAudio(wavBuffer);
51
+ console.log("✅ Audio playback complete");
52
+ await unloadModel({ modelId });
53
+ console.log("Model unloaded");
54
+ process.exit(0);
55
+ }
56
+ catch (error) {
57
+ console.error("❌ Error:", error);
58
+ process.exit(1);
59
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=supertonic.d.ts.map
@@ -0,0 +1,51 @@
1
+ import { loadModel, textToSpeech, unloadModel, TTS_TOKENIZER_SUPERTONIC, TTS_TEXT_ENCODER_SUPERTONIC_FP32, TTS_LATENT_DENOISER_SUPERTONIC_FP32, TTS_VOICE_DECODER_SUPERTONIC_FP32, TTS_VOICE_STYLE_SUPERTONIC, } from "@qvac/sdk";
2
+ import { createWav, playAudio, int16ArrayToBuffer, createWavHeader, } from "./utils.js";
3
+ // Supertonic TTS: general-purpose, no voice cloning.
4
+ // Uses registry model constants - downloads automatically from QVAC Registry.
5
+ const SUPERTONIC_SAMPLE_RATE = 44100;
6
+ try {
7
+ const modelId = await loadModel({
8
+ modelSrc: TTS_TOKENIZER_SUPERTONIC.src,
9
+ modelType: "tts",
10
+ modelConfig: {
11
+ ttsEngine: "supertonic",
12
+ language: "en",
13
+ ttsTokenizerSrc: TTS_TOKENIZER_SUPERTONIC.src,
14
+ ttsTextEncoderSrc: TTS_TEXT_ENCODER_SUPERTONIC_FP32.src,
15
+ ttsLatentDenoiserSrc: TTS_LATENT_DENOISER_SUPERTONIC_FP32.src,
16
+ ttsVoiceDecoderSrc: TTS_VOICE_DECODER_SUPERTONIC_FP32.src,
17
+ ttsVoiceSrc: TTS_VOICE_STYLE_SUPERTONIC.src,
18
+ },
19
+ onProgress: (progress) => {
20
+ console.log(progress);
21
+ },
22
+ });
23
+ console.log(`Model loaded: ${modelId}`);
24
+ console.log("🎵 Testing Text-to-Speech...");
25
+ const result = textToSpeech({
26
+ modelId,
27
+ text: `QVAC SDK is the canonical entry point to QVAC. Written in TypeScript, it provides all QVAC capabilities through a unified interface while also abstracting away the complexity of running your application in a JS environment other than Bare. Supported JS environments include Bare, Node.js, Expo and Bun.`,
28
+ inputType: "text",
29
+ stream: false,
30
+ });
31
+ const audioBuffer = await result.buffer;
32
+ console.log(`TTS complete. Total samples: ${audioBuffer.length}`);
33
+ console.log("💾 Saving audio to file...");
34
+ createWav(audioBuffer, SUPERTONIC_SAMPLE_RATE, "supertonic-output.wav");
35
+ console.log("✅ Audio saved to supertonic-output.wav");
36
+ console.log("🔊 Playing audio...");
37
+ const audioData = int16ArrayToBuffer(audioBuffer);
38
+ const wavBuffer = Buffer.concat([
39
+ createWavHeader(audioData.length, SUPERTONIC_SAMPLE_RATE),
40
+ audioData,
41
+ ]);
42
+ playAudio(wavBuffer);
43
+ console.log("✅ Audio playback complete");
44
+ await unloadModel({ modelId });
45
+ console.log("Model unloaded");
46
+ process.exit(0);
47
+ }
48
+ catch (error) {
49
+ console.error("❌ Error:", error);
50
+ process.exit(1);
51
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Create WAV header for 16-bit PCM audio
3
+ */
4
+ export declare function createWavHeader(dataLength: number, sampleRate: number): Buffer;
5
+ /**
6
+ * Convert Int16Array to Buffer
7
+ */
8
+ export declare function int16ArrayToBuffer(samples: number[]): Buffer;
9
+ /**
10
+ * Create and save WAV file
11
+ */
12
+ export declare function createWav(audioBuffer: number[], sampleRate: number, filename: string): void;
13
+ /**
14
+ * Play audio using system audio players
15
+ */
16
+ export declare function playAudio(audioBuffer: Buffer): void;
17
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1,93 @@
1
+ import { writeFileSync, unlinkSync } from "fs";
2
+ import { spawnSync } from "child_process";
3
+ import { platform } from "os";
4
+ /**
5
+ * Create WAV header for 16-bit PCM audio
6
+ */
7
+ export function createWavHeader(dataLength, sampleRate) {
8
+ const header = Buffer.alloc(44);
9
+ // RIFF header
10
+ header.write("RIFF", 0);
11
+ header.writeUInt32LE(36 + dataLength, 4);
12
+ header.write("WAVE", 8);
13
+ // fmt chunk
14
+ header.write("fmt ", 12);
15
+ header.writeUInt32LE(16, 16); // fmt chunk size
16
+ header.writeUInt16LE(1, 20); // PCM format
17
+ header.writeUInt16LE(1, 22); // mono
18
+ header.writeUInt32LE(sampleRate, 24);
19
+ header.writeUInt32LE(sampleRate * 2, 28); // byte rate
20
+ header.writeUInt16LE(2, 32); // block align
21
+ header.writeUInt16LE(16, 34); // bits per sample
22
+ // data chunk
23
+ header.write("data", 36);
24
+ header.writeUInt32LE(dataLength, 40);
25
+ return header;
26
+ }
27
+ /**
28
+ * Convert Int16Array to Buffer
29
+ */
30
+ export function int16ArrayToBuffer(samples) {
31
+ const buffer = Buffer.alloc(samples.length * 2);
32
+ for (let i = 0; i < samples.length; i++) {
33
+ const value = Math.max(-32768, Math.min(32767, Math.round(samples[i] ?? 0)));
34
+ buffer.writeInt16LE(value, i * 2);
35
+ }
36
+ return buffer;
37
+ }
38
+ /**
39
+ * Create and save WAV file
40
+ */
41
+ export function createWav(audioBuffer, sampleRate, filename) {
42
+ const audioData = int16ArrayToBuffer(audioBuffer);
43
+ const wavHeader = createWavHeader(audioData.length, sampleRate);
44
+ const wavFile = Buffer.concat([wavHeader, audioData]);
45
+ writeFileSync(filename, wavFile);
46
+ console.log(`WAV file saved as: ${filename}`);
47
+ }
48
+ /**
49
+ * Play audio using system audio players
50
+ */
51
+ export function playAudio(audioBuffer) {
52
+ const currentPlatform = platform();
53
+ const tempFile = `/tmp/audio-${Date.now()}.wav`;
54
+ // Write audio buffer to temporary file
55
+ writeFileSync(tempFile, audioBuffer);
56
+ let audioPlayer;
57
+ let args;
58
+ switch (currentPlatform) {
59
+ case "darwin":
60
+ audioPlayer = "afplay";
61
+ args = [tempFile];
62
+ break;
63
+ case "linux":
64
+ audioPlayer = "aplay";
65
+ args = [tempFile];
66
+ break;
67
+ case "win32":
68
+ audioPlayer = "powershell";
69
+ args = [
70
+ "-Command",
71
+ `Add-Type -AssemblyName presentationCore; (New-Object Media.SoundPlayer).LoadStream([System.IO.File]::ReadAllBytes('${tempFile}')).PlaySync()`,
72
+ ];
73
+ break;
74
+ default:
75
+ audioPlayer = "aplay";
76
+ args = [tempFile];
77
+ }
78
+ const result = spawnSync(audioPlayer, args, {
79
+ stdio: ["inherit", "inherit", "inherit"],
80
+ });
81
+ try {
82
+ unlinkSync(tempFile);
83
+ }
84
+ catch {
85
+ // Ignore cleanup errors
86
+ }
87
+ if (result.error) {
88
+ throw new Error(`Audio player failed: ${result.error.message}`);
89
+ }
90
+ if (result.status !== 0) {
91
+ throw new Error(`Audio player exited with code ${result.status}`);
92
+ }
93
+ }
@@ -1,4 +1,4 @@
1
- import { loadModel, unloadModel, transcribe, WHISPER_TINY, VAD_SILERO_5_1_2, } from "@qvac/sdk";
1
+ import { loadModel, unloadModel, transcribe, WHISPER_TINY } from "@qvac/sdk";
2
2
  // Parse command line arguments
3
3
  const args = process.argv.slice(2);
4
4
  if (!args[0]) {
@@ -8,12 +8,11 @@ if (!args[0]) {
8
8
  const audioFilePath = args[0];
9
9
  try {
10
10
  console.log("🎤 Starting Whisper transcription example...");
11
- // Load the Whisper model with VAD
11
+ // Load the Whisper model
12
12
  console.log("📥 Loading Whisper model...");
13
13
  const modelId = await loadModel({
14
14
  modelSrc: WHISPER_TINY,
15
15
  modelType: "whisper",
16
- vadModelSrc: VAD_SILERO_5_1_2,
17
16
  modelConfig: {
18
17
  audio_format: "f32le",
19
18
  // Sampling strategy
@@ -1,4 +1,4 @@
1
- import { loadModel, unloadModel, transcribe, transcribeStream, WHISPER_TINY, VAD_SILERO_5_1_2, } from "@qvac/sdk";
1
+ import { loadModel, unloadModel, transcribe, transcribeStream, WHISPER_TINY, } from "@qvac/sdk";
2
2
  import { spawn, spawnSync } from "child_process";
3
3
  import * as readline from "readline";
4
4
  import { platform } from "os";
@@ -270,7 +270,6 @@ async function main() {
270
270
  modelId = await loadModel({
271
271
  modelSrc: WHISPER_TINY,
272
272
  modelType: "whisper",
273
- vadModelSrc: VAD_SILERO_5_1_2,
274
273
  modelConfig: {
275
274
  audio_format: "f32le",
276
275
  vad_params: {
@@ -1,12 +1,11 @@
1
- import { loadModel, unloadModel, transcribe, WHISPER_TINY, VAD_SILERO_5_1_2, } from "@qvac/sdk";
1
+ import { loadModel, unloadModel, transcribe, WHISPER_TINY } from "@qvac/sdk";
2
2
  try {
3
3
  console.log("🎤 Starting Whisper transcription with prompt example...");
4
- // Load the Whisper model with VAD
4
+ // Load the Whisper model
5
5
  console.log("📥 Loading Whisper model...");
6
6
  const modelId = await loadModel({
7
7
  modelSrc: WHISPER_TINY,
8
8
  modelType: "whisper",
9
- vadModelSrc: VAD_SILERO_5_1_2,
10
9
  modelConfig: {
11
10
  audio_format: "f32le",
12
11
  // Sampling strategy
@@ -1,3 +1,6 @@
1
+ export { default as withAndroidArchitecture } from "./withAndroidArchitecture";
2
+ export { default as withAndroidNdkVersion } from "./withAndroidNdkVersion";
3
+ export { default as withDeviceInfo } from "./withDeviceInfo";
1
4
  export { default as withMobileBundle } from "./withMobileBundle";
2
5
  export { default as withOpenCL } from "./withOpenCL";
3
6
  export { default as withQvacSDK } from "./withQvacSDK";
@@ -1,3 +1,6 @@
1
+ export { default as withAndroidArchitecture } from "./withAndroidArchitecture.js";
2
+ export { default as withAndroidNdkVersion } from "./withAndroidNdkVersion.js";
3
+ export { default as withDeviceInfo } from "./withDeviceInfo.js";
1
4
  export { default as withMobileBundle } from "./withMobileBundle.js";
2
5
  export { default as withOpenCL } from "./withOpenCL.js";
3
6
  export { default as withQvacSDK } from "./withQvacSDK.js";
@@ -0,0 +1,15 @@
1
+ declare const SDK_PACKAGE_NAMES: string[];
2
+ type SDKPackageInfo = {
3
+ dir: string;
4
+ name: string;
5
+ };
6
+ /**
7
+ * Resolves the installed SDK package directory from node_modules.
8
+ *
9
+ * Checks all known published package names and returns the one that exists.
10
+ * Throws if none found or if multiple are found (ambiguous installation).
11
+ */
12
+ declare function resolveSDKPackageDir(projectRoot: string): SDKPackageInfo;
13
+ export { resolveSDKPackageDir, SDK_PACKAGE_NAMES };
14
+ export type { SDKPackageInfo };
15
+ //# sourceMappingURL=resolve-sdk-package-dir.d.ts.map
@@ -0,0 +1,31 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { SDKNotFoundInNodeModulesError, MultipleSDKInstallationsError, } from "../../utils/errors-client.js";
4
+ const SDK_PACKAGE_NAMES = [
5
+ "@qvac/sdk",
6
+ "@tetherto/sdk-mono",
7
+ "@tetherto/sdk-dev",
8
+ ];
9
+ /**
10
+ * Resolves the installed SDK package directory from node_modules.
11
+ *
12
+ * Checks all known published package names and returns the one that exists.
13
+ * Throws if none found or if multiple are found (ambiguous installation).
14
+ */
15
+ function resolveSDKPackageDir(projectRoot) {
16
+ const found = [];
17
+ for (const name of SDK_PACKAGE_NAMES) {
18
+ const dir = path.join(projectRoot, "node_modules", name);
19
+ if (fs.existsSync(dir)) {
20
+ found.push({ name, dir });
21
+ }
22
+ }
23
+ if (found.length === 0) {
24
+ throw new SDKNotFoundInNodeModulesError();
25
+ }
26
+ if (found.length > 1) {
27
+ throw new MultipleSDKInstallationsError(found.map((f) => f.name).join(", "));
28
+ }
29
+ return found[0];
30
+ }
31
+ export { resolveSDKPackageDir, SDK_PACKAGE_NAMES };
@@ -0,0 +1,8 @@
1
+ import type { ExpoConfig } from "expo/config";
2
+ /**
3
+ * Expo plugin to configure Android architecture to arm64-v8a only.
4
+ * Reduces APK size by excluding other architectures (x86, x86_64, armeabi-v7a).
5
+ */
6
+ declare function withAndroidArchitecture(config: ExpoConfig): ExpoConfig;
7
+ export default withAndroidArchitecture;
8
+ //# sourceMappingURL=withAndroidArchitecture.d.ts.map
@@ -0,0 +1,52 @@
1
+ import configPlugins from "@expo/config-plugins";
2
+ const { withGradleProperties, withAppBuildGradle } = configPlugins;
3
+ const DEFAULT_ARCHITECTURES = ["arm64-v8a"];
4
+ /**
5
+ * Expo plugin to configure Android architecture to arm64-v8a only.
6
+ * Reduces APK size by excluding other architectures (x86, x86_64, armeabi-v7a).
7
+ */
8
+ function withAndroidArchitecture(config) {
9
+ const architectures = DEFAULT_ARCHITECTURES;
10
+ const architectureString = architectures.join(",");
11
+ const abiFiltersArray = architectures.map((arch) => `"${arch}"`).join(", ");
12
+ // Update gradle.properties to set reactNativeArchitectures
13
+ config = withGradleProperties(config, (config) => {
14
+ const propIndex = config.modResults.findIndex((item) => item.type === "property" && item.key === "reactNativeArchitectures");
15
+ if (propIndex >= 0) {
16
+ config.modResults.splice(propIndex, 1, {
17
+ type: "property",
18
+ key: "reactNativeArchitectures",
19
+ value: architectureString,
20
+ });
21
+ }
22
+ else {
23
+ config.modResults.push({
24
+ type: "property",
25
+ key: "reactNativeArchitectures",
26
+ value: architectureString,
27
+ });
28
+ }
29
+ return config;
30
+ });
31
+ // Update app/build.gradle to add ndk.abiFilters
32
+ config = withAppBuildGradle(config, (config) => {
33
+ let buildGradle = config.modResults.contents;
34
+ const ndkBlock = `\n ndk {\n abiFilters ${abiFiltersArray}\n }`;
35
+ if (!buildGradle.includes("ndk {")) {
36
+ const buildConfigRegex = /(buildConfigField\s+"String",\s+"REACT_NATIVE_RELEASE_LEVEL"[^\n]*\n)/;
37
+ if (buildConfigRegex.test(buildGradle)) {
38
+ buildGradle = buildGradle.replace(buildConfigRegex, `$1${ndkBlock}\n`);
39
+ }
40
+ }
41
+ else {
42
+ const ndkRegex = /ndk\s*\{[^}]*\}/s;
43
+ const newNdkBlock = `ndk {\n abiFilters ${abiFiltersArray}\n }`;
44
+ buildGradle = buildGradle.replace(ndkRegex, newNdkBlock);
45
+ }
46
+ config.modResults.contents = buildGradle;
47
+ return config;
48
+ });
49
+ console.log(`[withAndroidArchitecture] 🔧 QVAC: Set Android architectures to ${architectureString}`);
50
+ return config;
51
+ }
52
+ export default withAndroidArchitecture;
@@ -0,0 +1,8 @@
1
+ import type { ExpoConfig } from "expo/config";
2
+ /**
3
+ * Expo plugin to set NDK version in android/build.gradle.
4
+ * Ensures NDK 29 is used to match the addon build version.
5
+ */
6
+ declare function withAndroidNdkVersion(config: ExpoConfig): ExpoConfig;
7
+ export default withAndroidNdkVersion;
8
+ //# sourceMappingURL=withAndroidNdkVersion.d.ts.map
@@ -0,0 +1,31 @@
1
+ import configPlugins from "@expo/config-plugins";
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ const { withDangerousMod } = configPlugins;
5
+ const DEFAULT_NDK_VERSION = "29.0.14206865";
6
+ /**
7
+ * Expo plugin to set NDK version in android/build.gradle.
8
+ * Ensures NDK 29 is used to match the addon build version.
9
+ */
10
+ function withAndroidNdkVersion(config) {
11
+ const ndkVersion = DEFAULT_NDK_VERSION;
12
+ return withDangerousMod(config, [
13
+ "android",
14
+ function setNdkVersion(config) {
15
+ const buildGradlePath = path.join(config.modRequest.platformProjectRoot, "build.gradle");
16
+ if (fs.existsSync(buildGradlePath)) {
17
+ let buildGradle = fs.readFileSync(buildGradlePath, "utf8");
18
+ if (buildGradle.includes("ndkVersion")) {
19
+ buildGradle = buildGradle.replace(/ndkVersion\s*=\s*["'][^"']+["']/g, `ndkVersion = "${ndkVersion}"`);
20
+ }
21
+ else {
22
+ buildGradle = buildGradle.replace(/(buildscript\s*\{)/, `$1\n ext {\n ndkVersion = "${ndkVersion}"\n }`);
23
+ }
24
+ fs.writeFileSync(buildGradlePath, buildGradle);
25
+ console.log(`[withAndroidNdkVersion] 🔧 QVAC: Set Android NDK version to ${ndkVersion}`);
26
+ }
27
+ return config;
28
+ },
29
+ ]);
30
+ }
31
+ export default withAndroidNdkVersion;
@@ -0,0 +1,10 @@
1
+ import type { ExpoConfig } from "expo/config";
2
+ /**
3
+ * Expo plugin that stubs expo-device-info when expo-device is not a declared
4
+ * dependency of the consuming app. Expo autolinking resolves modules from
5
+ * package.json — if expo-device isn't listed there, the native module won't
6
+ * be linked and Metro may fail to resolve the JS import.
7
+ */
8
+ declare function withDeviceInfo(config: ExpoConfig): ExpoConfig;
9
+ export default withDeviceInfo;
10
+ //# sourceMappingURL=withDeviceInfo.d.ts.map
@@ -0,0 +1,48 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { resolveSDKPackageDir } from "./resolve-sdk-package-dir.js";
4
+ let didRun = false;
5
+ /**
6
+ * Expo plugin that stubs expo-device-info when expo-device is not a declared
7
+ * dependency of the consuming app. Expo autolinking resolves modules from
8
+ * package.json — if expo-device isn't listed there, the native module won't
9
+ * be linked and Metro may fail to resolve the JS import.
10
+ */
11
+ function withDeviceInfo(config) {
12
+ if (didRun) {
13
+ return config;
14
+ }
15
+ didRun = true;
16
+ const projectRoot = config._internal?.["projectRoot"];
17
+ if (!projectRoot) {
18
+ return config;
19
+ }
20
+ const { dir: qvacSdkPath } = resolveSDKPackageDir(projectRoot);
21
+ const appPackageJsonPath = path.join(projectRoot, "package.json");
22
+ let hasExpoDevice = false;
23
+ if (fs.existsSync(appPackageJsonPath)) {
24
+ const appPackageJson = JSON.parse(fs.readFileSync(appPackageJsonPath, "utf-8"));
25
+ hasExpoDevice =
26
+ "expo-device" in (appPackageJson.dependencies ?? {}) ||
27
+ "expo-device" in (appPackageJson.devDependencies ?? {});
28
+ }
29
+ if (!hasExpoDevice) {
30
+ const deviceInfoPath = path.join(qvacSdkPath, "dist", "client", "rpc", "expo-device-info.js");
31
+ if (fs.existsSync(deviceInfoPath)) {
32
+ fs.writeFileSync(deviceInfoPath, [
33
+ `"use strict";`,
34
+ `Object.defineProperty(exports, "__esModule", { value: true });`,
35
+ `async function getDeviceInfo() {`,
36
+ ` return { platform: undefined, deviceModel: undefined, deviceBrand: undefined };`,
37
+ `}`,
38
+ `exports.getDeviceInfo = getDeviceInfo;`,
39
+ ].join("\n"));
40
+ console.log("[withDeviceInfo] 🔧 QVAC: expo-device not in app dependencies, stubbed device info");
41
+ }
42
+ }
43
+ else {
44
+ console.log("[withDeviceInfo] 🔧 QVAC: expo-device in app dependencies, using expo-device info");
45
+ }
46
+ return config;
47
+ }
48
+ export default withDeviceInfo;