@qvac/registry-client 0.1.6 → 0.2.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/NOTICE CHANGED
@@ -1,4 +1,458 @@
1
1
  @qvac/registry-client
2
2
  Copyright 2026 Tether Data, S.A. de C.V.
3
3
 
4
- This product includes software developed by Tether Data, S.A. de C.V.
4
+ This product includes third-party components under their
5
+ respective licenses. @qvac/registry-client itself is licensed under
6
+ Apache-2.0; bundled dependencies are governed by the licenses
7
+ listed below.
8
+
9
+ =========================================================================
10
+ Required Attribution Notices
11
+ =========================================================================
12
+
13
+ Gemma is provided under and subject to the Gemma Terms of Use found
14
+ at ai.google.dev/gemma/terms
15
+
16
+ Additional requirements per Section 3.1:
17
+ Distribution must be accompanied by the Gemma Terms of Use.
18
+ Use is subject to the Gemma Prohibited Use Policy at
19
+ ai.google.dev/gemma/prohibited_use_policy
20
+
21
+ HAI-DEF is provided under and subject to the Health AI Developer
22
+ Foundations Terms of Use found at
23
+ https://developers.google.com/health-ai-developer-foundations/terms
24
+
25
+ Additional requirements per Section 3.1:
26
+ Distribution must be accompanied by the HAI-DEF Terms of Use.
27
+ Clinical use requires Health Regulatory Authorization from the
28
+ relevant authority (Section 3.1.3).
29
+ Use is subject to the HAI-DEF Prohibited Use Policy at
30
+ developers.google.com/health-ai-developer-foundations/prohibited-use-policy
31
+
32
+ Llama 3.2 is licensed under the Llama 3.2 Community License,
33
+ Copyright (c) Meta Platforms, Inc. All Rights Reserved.
34
+
35
+ Additional requirements per license Section 1.b.i:
36
+ Products or services distributing or containing Llama 3.2 materials
37
+ must prominently display "Built with Llama" on a related website,
38
+ user interface, blog post, about page, or product documentation.
39
+
40
+ =========================================================================
41
+ Third-Party Model Licenses
42
+ =========================================================================
43
+
44
+ --- apache-2.0 (Apache License 2.0) ---
45
+
46
+ de-tiny-ggml-model-f16
47
+ https://huggingface.co/primeline/whisper-tiny-german-1224
48
+ en-base-ggml-model-f16
49
+ https://huggingface.co/openai/whisper-base
50
+ fr-base-ggml-model-f16
51
+ https://huggingface.co/personalizedrefrigerator/whisper-base-fr
52
+ fr-tiny-ggml-model-f16
53
+ https://huggingface.co/JaepaX/whisper-tiny-fr
54
+ ggml-opus-ar-en
55
+ https://huggingface.co/Helsinki-NLP/opus-mt-ar-en
56
+ ggml-opus-de-en
57
+ https://huggingface.co/Helsinki-NLP/opus-mt-de-en
58
+ ggml-opus-de-fr
59
+ https://huggingface.co/Helsinki-NLP/opus-mt-de-fr
60
+ ggml-opus-en-ar
61
+ https://huggingface.co/Helsinki-NLP/opus-mt-en-ar
62
+ ggml-opus-en-es
63
+ https://huggingface.co/Helsinki-NLP/opus-mt-en-es
64
+ ggml-opus-en-fr
65
+ https://huggingface.co/Helsinki-NLP/opus-mt-en-fr
66
+ ggml-opus-en-it
67
+ https://huggingface.co/Helsinki-NLP/opus-mt-en-it
68
+ ggml-opus-en-ru
69
+ https://huggingface.co/Helsinki-NLP/opus-mt-en-ru
70
+ ggml-opus-en-zh
71
+ https://huggingface.co/Helsinki-NLP/opus-mt-en-zh
72
+ ggml-opus-es-en
73
+ https://huggingface.co/Helsinki-NLP/opus-mt-es-en
74
+ ggml-opus-es-fr
75
+ https://huggingface.co/Helsinki-NLP/opus-mt-es-fr
76
+ ggml-opus-fr-de
77
+ https://huggingface.co/Helsinki-NLP/opus-mt-fr-de
78
+ ggml-opus-fr-en
79
+ https://huggingface.co/Helsinki-NLP/opus-mt-fr-en
80
+ ggml-opus-fr-es
81
+ https://huggingface.co/Helsinki-NLP/opus-mt-fr-es
82
+ ggml-opus-it-en
83
+ https://huggingface.co/Helsinki-NLP/opus-mt-it-en
84
+ ggml-opus-ja-en
85
+ https://huggingface.co/Helsinki-NLP/opus-mt-ja-en
86
+ ggml-opus-mt-en-roa-f16
87
+ https://huggingface.co/Helsinki-NLP/opus-mt-en-roa
88
+ ggml-opus-mt-roa-en-f16
89
+ https://huggingface.co/Helsinki-NLP/opus-mt-roa-en
90
+ gpt-oss-20b-GGUF
91
+ https://huggingface.co/unsloth/gpt-oss-20b-GGUF
92
+ it-base-ggml-model-f16
93
+ https://huggingface.co/gustavv-andrzejewski/distil-whisper-base-it
94
+ it-tiny-ggml-model-f16
95
+ https://huggingface.co/luigisaetta/whisper-tiny-it
96
+ ja-base-ggml-model-f16
97
+ https://huggingface.co/bygreencn/whisper-base-ja
98
+ ja-tiny-ggml-model-f16
99
+ https://huggingface.co/CheeLi03/whisper-tiny-ja-puct-4k
100
+ laser-dolphin-mixtral-2x7b-dpo-GGUF
101
+ https://huggingface.co/jmb95/laser-dolphin-mixtral-2x7b-dpo-GGUF
102
+ Llama_3.2_1B_Intruct_Tool_Calling_V2-GGUF
103
+ https://huggingface.co/mav23/Llama_3.2_1B_Intruct_Tool_Calling_V2-GGUF
104
+ nb-tiny-ggml-model
105
+ https://huggingface.co/NbAiLab/nb-whisper-tiny
106
+ pt-base-ggml-model-f16
107
+ https://huggingface.co/mariana-coelho-9/whisper-base-pt
108
+ Qwen3-0.6B-GGUF
109
+ https://huggingface.co/unsloth/Qwen3-0.6B-GGUF
110
+ Qwen3-1.7B-GGUF
111
+ https://huggingface.co/unsloth/Qwen3-1.7B-GGUF
112
+ Qwen3-4B-Q4_0-00001-of-00005
113
+ https://huggingface.co/unsloth/Qwen3-4B-GGUF
114
+ Qwen3-4B-Q4_K_M
115
+ https://huggingface.co/Qwen/Qwen3-4B-GGUF
116
+ Qwen3-8B-GGUF
117
+ https://huggingface.co/Qwen/Qwen3-8B-GGUF
118
+ Qwen3-VL-2B-Instruct-GGUF
119
+ https://huggingface.co/Qwen/Qwen3-VL-2B-Instruct-GGUF
120
+ recognizer_latin
121
+ https://www.jaided.ai/easyocr/modelhub/
122
+ ru-base-ggml-model-f16
123
+ https://huggingface.co/CheeLi03/whisper-base-rus-8
124
+ ru-tiny-ggml-model-f16
125
+ https://huggingface.co/yaroslav0530/whisper-tiny-ru
126
+ salamandraTA-2B-instruct-GGUF
127
+ https://huggingface.co/BSC-LT/salamandraTA-2B-instruct-GGUF
128
+ SmolVLM2-500M-Video-Instruct-GGUF
129
+ https://huggingface.co/ggml-org/SmolVLM2-500M-Video-Instruct-GGUF
130
+
131
+ --- cc-by-4.0 (Creative Commons Attribution 4.0 International) ---
132
+
133
+ ggml-opus-en-de
134
+ https://huggingface.co/Helsinki-NLP/opus-mt-en-de
135
+ ggml-opus-en-pt
136
+ https://huggingface.co/Helsinki-NLP/opus-mt-tc-big-en-pt
137
+ ggml-opus-ru-en
138
+ https://huggingface.co/Helsinki-NLP/opus-mt-ru-en
139
+ ggml-opus-zh-en
140
+ https://huggingface.co/Helsinki-NLP/opus-mt-zh-en
141
+
142
+ --- gemma (Gemma Terms of Use) ---
143
+
144
+ embeddinggemma-300m-GGUF
145
+ https://huggingface.co/unsloth/embeddinggemma-300m-GGUF
146
+
147
+ --- health-ai-developer-foundations (HAI-DEF Terms of Use) ---
148
+
149
+ medgemma-4b-it-GGUF
150
+ https://huggingface.co/unsloth/medgemma-4b-it-GGUF
151
+
152
+ --- llama3.2 (Llama 3.2 Community License) ---
153
+
154
+ Llama-3.2-1B-Instruct-GGUF
155
+ https://huggingface.co/unsloth/Llama-3.2-1B-Instruct-GGUF
156
+ Llama-3.2-1B-Instruct-Q4_0-00001-of-00008
157
+ https://huggingface.co/bartowski/Llama-3.2-1B-Instruct-GGUF
158
+
159
+ --- mit (MIT License) ---
160
+
161
+ chatterbox-turbo-ONNX
162
+ https://huggingface.co/ResembleAI/chatterbox-turbo-ONNX
163
+ de-base-ggml-model-f16
164
+ https://huggingface.co/aware-ai/whisper-base-german
165
+ es-tiny-ggml-model-f16
166
+ https://huggingface.co/JaepaX/whisper-tiny-es
167
+ ggml-indictrans2-en-indic-1B-f16
168
+ https://huggingface.co/ai4bharat/indictrans2-en-indic-1B
169
+ ggml-indictrans2-en-indic-dist-200M-f16
170
+ https://huggingface.co/ai4bharat/indictrans2-en-indic-dist-200M
171
+ ggml-indictrans2-indic-en-1B-f16
172
+ https://huggingface.co/ai4bharat/indictrans2-indic-en-1B
173
+ ggml-indictrans2-indic-en-dist-200M-f16
174
+ https://huggingface.co/ai4bharat/indictrans2-indic-en-dist-200M
175
+ ggml-indictrans2-indic-indic-1B-f16
176
+ https://huggingface.co/ai4bharat/indictrans2-indic-indic-1B
177
+ ggml-indictrans2-indic-indic-dist-320M-f16
178
+ https://huggingface.co/ai4bharat/indictrans2-indic-indic-dist-320M
179
+ gte-large-gguf
180
+ https://huggingface.co/ChristianAzinn/gte-large-gguf
181
+ pt-tiny-ggml-model-f16
182
+ https://huggingface.co/DavyCosta701/whisper-tiny-pt-bpra
183
+ tiny_acft_q8_0
184
+ https://voiceinput.futo.org/VoiceInput/tiny_en_acft_q8_0.bin
185
+ whisper-vad
186
+ https://huggingface.co/ggml-org/whisper-vad
187
+ whisper.cpp
188
+ https://huggingface.co/ggerganov/whisper.cpp
189
+
190
+ --- mpl-2.0 (Mozilla Public License 2.0) ---
191
+
192
+ lex.50.50.aren.s2t
193
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/aren
194
+ lex.50.50.csen.s2t
195
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/csen
196
+ lex.50.50.enar.s2t
197
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/enar
198
+ lex.50.50.encs.s2t
199
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/encs
200
+ lex.50.50.enes.s2t
201
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/enes
202
+ lex.50.50.enfr.s2t
203
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/enfr
204
+ lex.50.50.enit.s2t
205
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/tiny/enit
206
+ lex.50.50.enja.s2t
207
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/enja
208
+ lex.50.50.enpt.s2t
209
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/enpt
210
+ lex.50.50.enru.s2t
211
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/enru
212
+ lex.50.50.enzh.s2t
213
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/enzh
214
+ lex.50.50.esen.s2t
215
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/tiny/esen
216
+ lex.50.50.fren.s2t
217
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/fren
218
+ lex.50.50.iten.s2t
219
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/iten
220
+ lex.50.50.jaen.s2t
221
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/jaen
222
+ lex.50.50.pten.s2t
223
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/pten
224
+ lex.50.50.ruen.s2t
225
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/tiny/ruen
226
+ lex.50.50.zhen.s2t
227
+ https://github.com/mozilla/firefox-translations-models/tree/main/models/base-memory/zhen
228
+
229
+ --- openrail ---
230
+
231
+ Supertonic-TTS-ONNX
232
+ https://huggingface.co/onnx-community/Supertonic-TTS-ONNX
233
+
234
+ =========================================================================
235
+ Modification Notice
236
+ =========================================================================
237
+
238
+ Models listed above may have been converted from original model
239
+ weights into optimized inference formats (GGUF, GGML, ONNX, or
240
+ Bergamot intgemm). These conversions involve format transformation
241
+ and/or weight quantization. No architectural changes were made to
242
+ the underlying models.
243
+
244
+ Source URLs for original weights are recorded in each model's
245
+ metadata entry within the registry.
246
+
247
+ =========================================================================
248
+ JavaScript Dependencies
249
+ =========================================================================
250
+
251
+ --- apache-2.0 (Apache License 2.0) ---
252
+
253
+ @hyperswarm/secret-stream@6.9.1
254
+ https://github.com/holepunchto/hyperswarm-secret-stream
255
+ @qvac/error@0.1.1
256
+ @qvac/registry-schema@0.1.1
257
+ adaptive-timeout@1.0.1
258
+ https://github.com/holepunchto/adaptive-timeout
259
+ b4a@1.7.3
260
+ https://github.com/holepunchto/b4a
261
+ bare-addon-resolve@1.9.7
262
+ https://github.com/holepunchto/bare-addon-resolve
263
+ bare-env@3.0.0
264
+ https://github.com/holepunchto/bare-env
265
+ bare-events@2.8.2
266
+ https://github.com/holepunchto/bare-events
267
+ bare-fs@4.5.4
268
+ https://github.com/holepunchto/bare-fs
269
+ bare-hrtime@2.1.1
270
+ https://github.com/holepunchto/bare-hrtime
271
+ bare-module-resolve@1.12.1
272
+ https://github.com/holepunchto/bare-module-resolve
273
+ bare-node-fs@1.0.2
274
+ https://github.com/holepunchto/bare-node
275
+ bare-node-os@1.0.1
276
+ https://github.com/holepunchto/bare-node
277
+ bare-node-path@1.0.1
278
+ https://github.com/holepunchto/bare-node
279
+ bare-node-process@1.0.1
280
+ https://github.com/holepunchto/bare-node
281
+ bare-os@3.6.2
282
+ https://github.com/holepunchto/bare-os
283
+ bare-path@3.0.0
284
+ https://github.com/holepunchto/bare-path
285
+ bare-pipe@4.1.3
286
+ https://github.com/holepunchto/bare-pipe
287
+ bare-process@4.2.2
288
+ https://github.com/holepunchto/bare-process
289
+ bare-semver@1.0.2
290
+ https://github.com/holepunchto/bare-semver
291
+ bare-signals@4.2.0
292
+ https://github.com/holepunchto/bare-signals
293
+ bare-stream@2.7.0
294
+ https://github.com/holepunchto/bare-stream
295
+ bare-tty@5.0.3
296
+ https://github.com/holepunchto/bare-tty
297
+ bare-url@2.3.2
298
+ https://github.com/holepunchto/bare-url
299
+ blind-relay@1.4.0
300
+ https://github.com/holepunchto/blind-relay
301
+ compact-encoding@2.18.0
302
+ https://github.com/compact-encoding/compact-encoding
303
+ device-file@2.3.1
304
+ https://github.com/holepunchto/device-file
305
+ events-universal@1.0.1
306
+ https://github.com/holepunchto/events-universal
307
+ fd-lock@2.1.1
308
+ https://github.com/holepunchto/fd-lock
309
+ fs-native-extensions@1.4.5
310
+ https://github.com/holepunchto/fs-native-extensions
311
+ hyperblobs@2.8.0
312
+ https://github.com/holepunchto/hyperblobs
313
+ hypercore-errors@1.5.0
314
+ https://github.com/holepunchto/hypercore-errors
315
+ hypercore-id-encoding@1.3.0
316
+ https://github.com/holepunchto/hypercore-id-encoding
317
+ hypercore-storage@2.4.1
318
+ hyperdb@4.22.3
319
+ https://github.com/holepunchto/hyperdb
320
+ hyperdispatch@1.4.4
321
+ https://github.com/holepunchto/hyperdispatch
322
+ hyperschema@1.19.0
323
+ https://github.com/holepunchto/hyperschema
324
+ index-encoder@3.4.0
325
+ https://github.com/holepunchto/index-encoder
326
+ noise-handshake@4.2.0
327
+ https://github.com/holepunchto/noise-handshake
328
+ paparam@1.10.0
329
+ https://github.com/holepunchto/paparam
330
+ quickbit-native@2.4.8
331
+ https://github.com/holepunchto/quickbit-native
332
+ rache@1.0.0
333
+ https://github.com/holepunchto/rache
334
+ refcounter@1.0.0
335
+ https://github.com/holepunchto/refcounter
336
+ require-addon@1.2.0
337
+ https://github.com/holepunchto/require-addon
338
+ resource-on-exit@1.0.0
339
+ https://github.com/holepunchto/bare-teardown
340
+ rocksdb-native@3.12.0
341
+ https://github.com/holepunchto/rocksdb-native
342
+ scope-lock@1.2.4
343
+ https://github.com/holepunchto/scope-lock
344
+ simdle-native@1.3.9
345
+ https://github.com/holepunchto/simdle-native
346
+ text-decoder@1.2.3
347
+ https://github.com/holepunchto/text-decoder
348
+ udx-native@1.19.2
349
+ https://github.com/holepunchto/udx-native
350
+ unslab@1.3.0
351
+ https://github.com/holepunchto/unslab
352
+ which-runtime@1.3.2
353
+ https://github.com/holepunchto/which-runtime
354
+
355
+ --- isc (ISC License) ---
356
+
357
+ bits-to-bytes@1.3.0
358
+ https://github.com/holepunchto/bits-to-bytes
359
+ compact-encoding-bitfield@1.0.0
360
+ https://github.com/compact-encoding/compact-encoding-bitfield
361
+ compact-encoding-net@1.2.0
362
+ https://github.com/compact-encoding/compact-encoding-net
363
+ nanoassert@2.0.0
364
+ https://github.com/emilbayes/nanoassert
365
+ noise-curve-ed@2.1.0
366
+ https://github.com/chm-diederichs/noise-curve-ed
367
+ quickbit-universal@2.2.0
368
+ https://github.com/holepunchto/quickbit-universal
369
+ simdle-universal@1.1.2
370
+ https://github.com/holepunchto/simdle-universal
371
+
372
+ --- mit (MIT License) ---
373
+
374
+ big-sparse-array@1.0.3
375
+ https://github.com/mafintosh/big-sparse-array
376
+ bogon@1.2.0
377
+ https://github.com/mafintosh/bogon
378
+ codecs@3.1.0
379
+ https://github.com/mafintosh/codecs
380
+ corestore@7.8.0
381
+ https://github.com/holepunchto/corestore
382
+ debounceify@1.1.0
383
+ https://github.com/mafintosh/debounceify
384
+ dht-rpc@6.24.2
385
+ https://github.com/mafintosh/dht-rpc
386
+ fast-fifo@1.3.2
387
+ https://github.com/mafintosh/fast-fifo
388
+ flat-tree@1.13.0
389
+ https://github.com/mafintosh/flat-tree
390
+ generate-object-property@2.0.0
391
+ https://github.com/mafintosh/generate-object-property
392
+ generate-string@1.0.1
393
+ https://github.com/mafintosh/generate-string
394
+ hyperbee@2.27.3
395
+ https://github.com/holepunchto/hyperbee
396
+ hypercore@11.24.0
397
+ https://github.com/holepunchto/hypercore
398
+ hypercore-crypto@3.6.1
399
+ https://github.com/mafintosh/hypercore-crypto
400
+ hyperdht@6.29.0
401
+ https://github.com/holepunchto/hyperdht
402
+ hyperswarm@4.16.0
403
+ https://github.com/holepunchto/hyperswarm
404
+ is-options@1.0.2
405
+ https://github.com/mafintosh/is-options
406
+ is-property@1.0.2
407
+ https://github.com/mikolalysenko/is-property
408
+ kademlia-routing-table@1.0.6
409
+ https://github.com/mafintosh/kademlia-routing-table
410
+ mutexify@1.4.0
411
+ https://github.com/mafintosh/mutexify
412
+ nat-sampler@1.0.1
413
+ https://github.com/mafintosh/nat-sampler
414
+ protocol-buffers-encodings@1.2.0
415
+ https://github.com/mafintosh/protocol-buffers-encodings
416
+ protomux@3.10.1
417
+ https://github.com/mafintosh/protomux
418
+ queue-tick@1.0.1
419
+ https://github.com/mafintosh/queue-tick
420
+ random-array-iterator@1.0.0
421
+ https://github.com/mafintosh/random-array-iterator
422
+ ready-resource@1.2.0
423
+ https://github.com/holepunchto/ready-resource
424
+ record-cache@1.2.0
425
+ https://github.com/mafintosh/record-cache
426
+ resolve-reject-promise@1.1.0
427
+ https://github.com/mafintosh/resolve-reject-promise
428
+ safety-catch@1.0.2
429
+ https://github.com/mafintosh/safety-catch
430
+ shuffled-priority-queue@2.1.0
431
+ https://github.com/mafintosh/shuffled-priority-queue
432
+ signal-promise@1.0.3
433
+ https://github.com/mafintosh/signal-promise
434
+ signed-varint@2.0.1
435
+ https://github.com/dominictarr/signed-varint
436
+ sodium-native@5.0.10
437
+ https://github.com/holepunchto/sodium-native
438
+ sodium-secretstream@1.2.0
439
+ https://github.com/mafintosh/sodium-secretstream
440
+ sodium-universal@5.0.1
441
+ https://github.com/holepunchto/sodium-universal
442
+ speedometer@1.1.0
443
+ https://github.com/mafintosh/speedometer
444
+ streamx@2.23.0
445
+ https://github.com/mafintosh/streamx
446
+ time-ordered-set@2.0.1
447
+ https://github.com/mafintosh/time-ordered-set
448
+ timeout-refresh@2.0.1
449
+ https://github.com/mafintosh/timeout-refresh
450
+ unordered-set@2.0.1
451
+ https://github.com/mafintosh/unordered-set
452
+ varint@5.0.0
453
+ https://github.com/chrisdickinson/varint
454
+ xache@1.2.1
455
+ https://github.com/mafintosh/xache
456
+ z32@1.1.0
457
+ https://github.com/mafintosh/z32
458
+
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @tetherto/qvac-lib-registry-client
1
+ # @qvac/registry-client
2
2
 
3
3
  Read-only client library for querying the QVAC Registry. It replicates the registry HyperDB via Hyperswarm and provides APIs for searching and retrieving model information.
4
4
 
@@ -13,7 +13,7 @@ Read-only client library for querying the QVAC Registry. It replicates the regis
13
13
  ## Installation
14
14
 
15
15
  ```bash
16
- npm install @tetherto/qvac-lib-registry-client
16
+ npm install @qvac/registry-client
17
17
  ```
18
18
 
19
19
  Ensure the registry core key is available via environment variables or provided via options.
@@ -24,7 +24,7 @@ Ensure the registry core key is available via environment variables or provided
24
24
 
25
25
  ```javascript
26
26
  'use strict'
27
- const { QVACRegistryClient } = require('@tetherto/qvac-lib-registry-client')
27
+ const { QVACRegistryClient } = require('@qvac/registry-client')
28
28
 
29
29
  async function main () {
30
30
  const client = new QVACRegistryClient({
@@ -106,18 +106,45 @@ const fs = require('fs')
106
106
  result.artifact.stream.pipe(fs.createWriteStream('./model.ggml'))
107
107
  ```
108
108
 
109
+ #### Direct Blob Download
110
+
111
+ - `downloadBlob(blobBinding, options)`: Downloads a blob directly using known blob coordinates, bypassing the metadata core lookup. Useful when `coreKey`, `blockOffset`, `blockLength`, and `byteLength` are already known (e.g., from a previous query or generated model constants).
112
+ - `blobBinding`: `{ coreKey, blockOffset, blockLength, byteOffset, byteLength }` — `coreKey` accepts Buffer, hex, or z-base-32 strings
113
+ - `options`:
114
+ - `timeout`: Download timeout in ms (default: 30000)
115
+ - `outputFile`: Optional file path to save directly to disk
116
+ - `onProgress`: Callback `({ downloaded, total, cachedBlocks, totalBlocks }) => void`
117
+ - `signal`: `AbortSignal` for cancellation
118
+ - Returns: `{ artifact: { path, totalSize } | { stream, totalSize } }`
119
+
120
+ This method only waits for the network layer (Corestore + Hyperswarm) — it does not wait for the metadata core to sync, making it faster for known blob coordinates.
121
+
122
+ ```javascript
123
+ const result = await client.downloadBlob({
124
+ coreKey: 'ey46cahego89xox118uhyryakz47bcs8bbxu97tnnpmuwmgi5wmo',
125
+ blockOffset: 0,
126
+ blockLength: 665,
127
+ byteOffset: 0,
128
+ byteLength: 43537433
129
+ }, {
130
+ outputFile: './downloaded/ggml-tiny-q8_0.bin',
131
+ timeout: 60000
132
+ })
133
+ console.log('Downloaded to:', result.artifact.path)
134
+ ```
135
+
109
136
  ## CLI
110
137
 
111
138
  The package includes a CLI for querying and downloading models from the registry.
112
139
 
113
140
  ### Install
114
141
 
115
- The package is hosted on GitHub Packages. Configure npm to use the GitHub registry for the `@tetherto` scope, then install globally:
142
+ The package is hosted on npm. Configure npm to use the registry for the `@qvac` scope, then install globally:
116
143
 
117
144
  ```bash
118
- echo "@tetherto:registry=https://npm.pkg.github.com" >> ~/.npmrc
119
- echo "//npm.pkg.github.com/:_authToken=YOUR_GITHUB_PAT" >> ~/.npmrc
120
- npm install -g @tetherto/registry-client-mono
145
+ echo "@qvac:registry=https://registry.npmjs.org" >> ~/.npmrc
146
+ echo "//registry.npmjs.org/:_authToken=YOUR_NPM_TOKEN" >> ~/.npmrc
147
+ npm install -g @qvac/registry-client
121
148
  ```
122
149
 
123
150
  Verify installation:
@@ -220,7 +247,8 @@ $ qvac-registry list --engine @qvac/transcription-whispercpp --json | jq '.[0].p
220
247
  See the `examples/` folder for complete working examples:
221
248
 
222
249
  - `example.js`: List models, query by engine/name/quantization, find shards
223
- - `download-model.js`: Download a single model to disk
250
+ - `download-model.js`: Download a single model to disk via metadata lookup
251
+ - `download-blob.js`: Download a blob directly using known blob coordinates
224
252
  - `download-all-models.js`: Download all models in the registry
225
253
 
226
254
  Run examples:
@@ -229,6 +257,7 @@ Run examples:
229
257
  cd client
230
258
  node examples/example.js
231
259
  node examples/download-model.js
260
+ node examples/download-blob.js
232
261
  node examples/download-all-models.js
233
262
  ```
234
263
 
@@ -271,8 +300,8 @@ The client uses custom error codes in the range 19001-20000. All errors extend `
271
300
  ### Error Handling Example
272
301
 
273
302
  ```javascript
274
- const { QVACRegistryClient } = require('@tetherto/qvac-lib-registry-client')
275
- const { QvacErrorRegistryClient } = require('@tetherto/qvac-lib-registry-client/utils/error')
303
+ const { QVACRegistryClient } = require('@qvac/registry-client')
304
+ const { QvacErrorRegistryClient } = require('@qvac/registry-client/utils/error')
276
305
 
277
306
  async function handleErrors () {
278
307
  const client = new QVACRegistryClient({
package/bin/cli.js CHANGED
@@ -4,7 +4,7 @@
4
4
  const { command, flag, arg, summary, header, footer, description } = require('paparam')
5
5
  const { QVACRegistryClient } = require('../index')
6
6
  const IdEnc = require('hypercore-id-encoding')
7
- const path = require('path')
7
+ const path = require('#path')
8
8
 
9
9
  const VERSION = require('../package.json').version
10
10
 
@@ -23,7 +23,7 @@ function createClient (parentFlags) {
23
23
  }
24
24
 
25
25
  function getRootFlags (cmd) {
26
- let current = cmd
26
+ let current = cmd.command || cmd
27
27
  while (current.parent) current = current.parent
28
28
  return current.flags || {}
29
29
  }
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export interface QVACBlobBinding {
2
- coreKey: Buffer
2
+ coreKey: Buffer | string
3
3
  blockOffset: number
4
4
  blockLength: number
5
5
  byteOffset: number
@@ -43,6 +43,17 @@ export interface QVACDownloadOptions {
43
43
  outputFile?: string
44
44
  }
45
45
 
46
+ export interface QVACBlobDownloadOptions {
47
+ timeout?: number
48
+ outputFile?: string
49
+ onProgress?: (progress: { downloaded: number, total: number, cachedBlocks: number, totalBlocks: number }) => void
50
+ signal?: AbortSignal
51
+ }
52
+
53
+ export interface QVACBlobDownloadResult {
54
+ artifact: QVACDownloadedArtifact & { totalSize: number }
55
+ }
56
+
46
57
  export interface QVACRegistryClientOptions {
47
58
  storage?: string
48
59
  registryCoreKey?: string
@@ -75,6 +86,7 @@ export class QVACRegistryClient {
75
86
 
76
87
  getModel (path: string, source: string): Promise<QVACModelEntry | null>
77
88
  downloadModel (path: string, source: string, options?: QVACDownloadOptions): Promise<QVACDownloadResult>
89
+ downloadBlob (blobBinding: QVACBlobBinding, options?: QVACBlobDownloadOptions): Promise<QVACBlobDownloadResult>
78
90
 
79
91
  findBy (params?: FindByParams): Promise<QVACModelEntry[]>
80
92
  findModels (query?: QVACModelQuery): Promise<QVACModelEntry[]>
package/lib/client.js CHANGED
@@ -9,8 +9,8 @@ const Corestore = require('corestore')
9
9
  const Hyperswarm = require('hyperswarm')
10
10
  const Hyperblobs = require('hyperblobs')
11
11
  const IdEnc = require('hypercore-id-encoding')
12
- const path = require('path')
13
- const fs = require('fs')
12
+ const path = require('#path')
13
+ const fs = require('#fs')
14
14
 
15
15
  class QVACRegistryClient extends ReadyResource {
16
16
  constructor (opts = {}) {
@@ -23,6 +23,7 @@ class QVACRegistryClient extends ReadyResource {
23
23
  this.corestore = null
24
24
  this.hyperswarm = null
25
25
  this._connectionHandler = null
26
+ this._metadataReady = null
26
27
 
27
28
  this.storage = this.registryConfig.getRegistryStorage(opts.storage)
28
29
  this.registryCoreKey = this.registryConfig.getRegistryCoreKey(opts.registryCoreKey)
@@ -38,11 +39,6 @@ class QVACRegistryClient extends ReadyResource {
38
39
  async _open () {
39
40
  this.logger.debug('_open called')
40
41
 
41
- if (!this.registryCoreKey) {
42
- this.logger.error('Missing registry core key for read mode')
43
- throw new QvacErrorRegistryClient({ code: ERR_CODES.FAILED_TO_CONNECT, adds: 'Missing registry core key. Set QVAC_REGISTRY_CORE_KEY environment variable.' })
44
- }
45
-
46
42
  this.logger.debug('Creating corestore for open')
47
43
  this.corestore = new Corestore(this.storage)
48
44
  await this.corestore.ready()
@@ -56,6 +52,15 @@ class QVACRegistryClient extends ReadyResource {
56
52
  }
57
53
  this.hyperswarm.on('connection', this._connectionHandler)
58
54
 
55
+ this._metadataReady = this._connectMetadataCore()
56
+ }
57
+
58
+ async _connectMetadataCore () {
59
+ if (!this.registryCoreKey) {
60
+ this.logger.error('Missing registry core key for read mode')
61
+ throw new QvacErrorRegistryClient({ code: ERR_CODES.FAILED_TO_CONNECT, adds: 'Missing registry core key. Set QVAC_REGISTRY_CORE_KEY environment variable.' })
62
+ }
63
+
59
64
  const viewKey = IdEnc.decode(this.registryCoreKey)
60
65
  const viewCore = this.corestore.get({ key: viewKey })
61
66
  await viewCore.ready()
@@ -65,28 +70,37 @@ class QVACRegistryClient extends ReadyResource {
65
70
  discoveryKey: IdEnc.normalize(viewCore.discoveryKey)
66
71
  })
67
72
 
73
+ const foundPeers = viewCore.findingPeers()
68
74
  this.hyperswarm.join(viewCore.discoveryKey, { client: true, server: false })
69
- await this.hyperswarm.flush()
75
+ this.hyperswarm.flush().then(() => foundPeers())
70
76
 
71
77
  this.logger.debug('Waiting for view core sync')
72
- await viewCore.update({ wait: true })
78
+ await viewCore.update()
73
79
 
74
80
  this.logger.debug('Creating RegistryDatabase from view core')
75
81
  this.db = new RegistryDatabase(viewCore, { extension: false })
76
82
  await this.db.ready()
77
83
 
78
- this.logger.debug('QVACRegistryClient ready', {
84
+ this.logger.debug('QVACRegistryClient metadata ready', {
79
85
  length: viewCore.length
80
86
  })
81
87
  }
82
88
 
89
+ async _ensureMetadata () {
90
+ await this.ready()
91
+ await this._metadataReady
92
+ if (!this.db) {
93
+ throw new QvacErrorRegistryClient({ code: ERR_CODES.FAILED_TO_CONNECT, adds: 'Registry database not available.' })
94
+ }
95
+ }
96
+
83
97
  async getModel (path, source) {
84
98
  this._validateString(path, 'path')
85
99
  this._validateString(source, 'source')
86
100
 
87
101
  try {
88
102
  this.logger.info('Getting model', { path, source })
89
- await this.ready()
103
+ await this._ensureMetadata()
90
104
 
91
105
  const result = await this.db.getModel(path, source)
92
106
  this.logger.debug('getModel result', { result })
@@ -98,7 +112,7 @@ class QVACRegistryClient extends ReadyResource {
98
112
  }
99
113
 
100
114
  async findModels (query = {}, opts = {}) {
101
- await this.ready()
115
+ await this._ensureMetadata()
102
116
  const { includeDeprecated = false } = opts
103
117
  this.logger.debug('findModels called', { query, includeDeprecated })
104
118
 
@@ -112,19 +126,19 @@ class QVACRegistryClient extends ReadyResource {
112
126
  }
113
127
 
114
128
  async findModelsByEngine (query = {}) {
115
- await this.ready()
129
+ await this._ensureMetadata()
116
130
  this.logger.debug('findModelsByEngine called', { query })
117
131
  return this.db.findModelsByEngine(query).toArray()
118
132
  }
119
133
 
120
134
  async findModelsByName (query = {}) {
121
- await this.ready()
135
+ await this._ensureMetadata()
122
136
  this.logger.debug('findModelsByName called', { query })
123
137
  return this.db.findModelsByName(query).toArray()
124
138
  }
125
139
 
126
140
  async findModelsByQuantization (query = {}) {
127
- await this.ready()
141
+ await this._ensureMetadata()
128
142
  this.logger.debug('findModelsByQuantization called', { query })
129
143
  return this.db.findModelsByQuantization(query).toArray()
130
144
  }
@@ -140,7 +154,7 @@ class QVACRegistryClient extends ReadyResource {
140
154
  * @returns {Promise<Array>} Array of matching models
141
155
  */
142
156
  async findBy (params = {}) {
143
- await this.ready()
157
+ await this._ensureMetadata()
144
158
  this.logger.debug('findBy called', { params })
145
159
  return this.db.findBy(params)
146
160
  }
@@ -169,9 +183,14 @@ class QVACRegistryClient extends ReadyResource {
169
183
  }
170
184
 
171
185
  async _getBlobsCore (blobsCoreKey) {
172
- const keyBuffer = Buffer.isBuffer(blobsCoreKey)
173
- ? blobsCoreKey
174
- : Buffer.from(blobsCoreKey.data || blobsCoreKey, 'hex')
186
+ let keyBuffer
187
+ if (Buffer.isBuffer(blobsCoreKey)) {
188
+ keyBuffer = blobsCoreKey
189
+ } else if (typeof blobsCoreKey === 'object' && blobsCoreKey.data) {
190
+ keyBuffer = Buffer.from(blobsCoreKey.data)
191
+ } else {
192
+ keyBuffer = IdEnc.decode(blobsCoreKey)
193
+ }
175
194
 
176
195
  this.logger.debug('Creating hyperblobs core', {
177
196
  blobCore: IdEnc.normalize(keyBuffer)
@@ -198,7 +217,7 @@ class QVACRegistryClient extends ReadyResource {
198
217
 
199
218
  try {
200
219
  this.logger.info('Downloading model', { path, source })
201
- await this.ready()
220
+ await this._ensureMetadata()
202
221
 
203
222
  const model = await this.getModel(path, source)
204
223
  if (!model) {
@@ -219,10 +238,11 @@ class QVACRegistryClient extends ReadyResource {
219
238
  discoveryKey: IdEnc.normalize(core.discoveryKey)
220
239
  })
221
240
 
241
+ const foundBlobPeers = core.findingPeers()
222
242
  this.hyperswarm.join(core.discoveryKey, { client: true, server: false })
223
- await this.hyperswarm.flush()
243
+ this.hyperswarm.flush().then(() => foundBlobPeers())
224
244
 
225
- await core.update({ wait: true })
245
+ await core.update()
226
246
  this.logger.debug('Blobs core updated')
227
247
 
228
248
  const totalSize = model.blobBinding.byteLength
@@ -290,6 +310,107 @@ class QVACRegistryClient extends ReadyResource {
290
310
  }
291
311
  }
292
312
 
313
+ async downloadBlob (blobBinding, options = {}) {
314
+ if (!blobBinding || !blobBinding.coreKey) {
315
+ throw new Error('Invalid blobBinding: coreKey is required')
316
+ }
317
+ if (typeof blobBinding.blockOffset !== 'number' ||
318
+ typeof blobBinding.blockLength !== 'number' ||
319
+ typeof blobBinding.byteLength !== 'number') {
320
+ throw new Error('Invalid blobBinding: blockOffset, blockLength, and byteLength are required numbers')
321
+ }
322
+
323
+ if (options && typeof options !== 'object') {
324
+ throw new Error(`Invalid options: ${typeof options}`)
325
+ }
326
+
327
+ let core, blobs
328
+
329
+ try {
330
+ this.logger.info('Downloading blob directly', {
331
+ coreKey: typeof blobBinding.coreKey === 'string' ? blobBinding.coreKey.slice(0, 12) + '...' : '(buffer)',
332
+ blockOffset: blobBinding.blockOffset,
333
+ blockLength: blobBinding.blockLength,
334
+ byteLength: blobBinding.byteLength
335
+ })
336
+
337
+ await this.ready()
338
+
339
+ const blobsCore = await this._getBlobsCore(blobBinding.coreKey)
340
+ core = blobsCore.core
341
+ blobs = blobsCore.blobs
342
+
343
+ this.logger.debug('Joining swarm for blobs core (direct)', {
344
+ discoveryKey: IdEnc.normalize(core.discoveryKey)
345
+ })
346
+
347
+ const foundBlobPeers = core.findingPeers()
348
+ this.hyperswarm.join(core.discoveryKey, { client: true, server: false })
349
+ this.hyperswarm.flush().then(() => foundBlobPeers())
350
+
351
+ await core.update()
352
+ this.logger.debug('Blobs core updated (direct)')
353
+
354
+ const pointer = {
355
+ blockOffset: blobBinding.blockOffset,
356
+ blockLength: blobBinding.blockLength,
357
+ byteOffset: blobBinding.byteOffset || 0,
358
+ byteLength: blobBinding.byteLength
359
+ }
360
+ const totalSize = blobBinding.byteLength
361
+
362
+ let artifact
363
+ if (options.outputFile) {
364
+ await this._streamBlobToFile(blobs, core, pointer, options.outputFile, options)
365
+ artifact = { path: options.outputFile, totalSize }
366
+
367
+ if (blobs) await blobs.close()
368
+ if (core) await core.close()
369
+ } else {
370
+ const stream = blobs.createReadStream(pointer, {
371
+ wait: true,
372
+ timeout: options.timeout || 30000
373
+ })
374
+ artifact = { stream, totalSize }
375
+
376
+ const cleanup = async () => {
377
+ if (blobs) {
378
+ try { await blobs.close() } catch (e) {
379
+ this.logger.warn('Error closing blob instance', { error: e.message })
380
+ }
381
+ }
382
+ if (core) {
383
+ try { await core.close() } catch (e) {
384
+ this.logger.warn('Error closing blob core', { error: e.message })
385
+ }
386
+ }
387
+ this.logger.debug('Blob resources closed after stream end')
388
+ }
389
+
390
+ stream.on('close', cleanup)
391
+ }
392
+
393
+ this.logger.info('Blob download complete (direct)')
394
+
395
+ return { artifact }
396
+ } catch (error) {
397
+ this.logger.error('Error downloading blob directly', error)
398
+
399
+ if (blobs) {
400
+ try { await blobs.close() } catch (e) {
401
+ this.logger.warn('Error closing blob instance on error', { error: e.message })
402
+ }
403
+ }
404
+ if (core) {
405
+ try { await core.close() } catch (e) {
406
+ this.logger.warn('Error closing blob core on error', { error: e.message })
407
+ }
408
+ }
409
+
410
+ throw error
411
+ }
412
+ }
413
+
293
414
  async _streamBlobToFile (blobs, core, blobPointer, filePath, options) {
294
415
  const { cachedBlocks, totalBlocks, totalBytes } = await this._checkBlobProgress(core, blobPointer)
295
416
 
@@ -368,6 +489,11 @@ class QVACRegistryClient extends ReadyResource {
368
489
  async _close () {
369
490
  this.logger.debug('_close called')
370
491
 
492
+ if (this._metadataReady) {
493
+ await this._metadataReady.catch(() => {})
494
+ this._metadataReady = null
495
+ }
496
+
371
497
  if (this.db) {
372
498
  this.logger.debug('Closing database')
373
499
  await this.db.close()
@@ -0,0 +1,3 @@
1
+ 'use strict'
2
+
3
+ module.exports = require('fs')
@@ -0,0 +1,3 @@
1
+ 'use strict'
2
+
3
+ module.exports = require('os')
@@ -0,0 +1,3 @@
1
+ 'use strict'
2
+
3
+ module.exports = require('path')
package/lib/config.js CHANGED
@@ -3,10 +3,10 @@
3
3
  const { getEnv } = require('../utils/env')
4
4
  const { ENV_KEYS } = require('@qvac/registry-schema')
5
5
  const Logger = require('./logger')
6
- const os = require('os')
7
- const path = require('path')
6
+ const os = require('#os')
7
+ const path = require('#path')
8
8
 
9
- const DEFAULT_REGISTRY_CORE_KEY = 'u6pq8h3kof7ck9g6kjusykfxaxqaqtnoydq15hhyuzrf55nt384y'
9
+ const DEFAULT_REGISTRY_CORE_KEY = 'uf1fm44uzockp6azhcdiqt1esjgm65fwtimsh946e8kwysdes9ko'
10
10
 
11
11
  class RegistryConfig {
12
12
  constructor (opts = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qvac/registry-client",
3
- "version": "0.1.6",
3
+ "version": "0.2.0",
4
4
  "description": "QVAC Registry client library for read-only queries via Hyperswarm",
5
5
  "license": "Apache-2.0",
6
6
  "type": "commonjs",
@@ -12,6 +12,20 @@
12
12
  ".": "./index.js",
13
13
  "./types": "./index.d.ts"
14
14
  },
15
+ "imports": {
16
+ "#os": {
17
+ "bare": "bare-os",
18
+ "default": "./lib/compat/os.js"
19
+ },
20
+ "#path": {
21
+ "bare": "bare-path",
22
+ "default": "./lib/compat/path.js"
23
+ },
24
+ "#fs": {
25
+ "bare": "bare-fs",
26
+ "default": "./lib/compat/fs.js"
27
+ }
28
+ },
15
29
  "files": [
16
30
  "index.js",
17
31
  "index.d.ts",
@@ -36,17 +50,14 @@
36
50
  "b4a": "^1.6.7",
37
51
  "bare-fs": "^4.5.2",
38
52
  "bare-os": "^3.6.2",
53
+ "bare-path": "^3.0.0",
39
54
  "bare-process": "^4.2.2",
40
55
  "corestore": "^7.4.5",
41
- "fs": "npm:bare-node-fs",
42
56
  "hyperblobs": "^2.8.0",
43
57
  "hypercore-id-encoding": "^1.3.0",
44
58
  "hyperdb": "^4.16.1",
45
59
  "hyperswarm": "^4.14.0",
46
- "os": "npm:bare-node-os",
47
60
  "paparam": "^1.10.0",
48
- "path": "npm:bare-node-path",
49
- "process": "npm:bare-node-process",
50
61
  "ready-resource": "^1.0.1"
51
62
  },
52
63
  "devDependencies": {