@qvac/sdk 0.7.1 → 0.8.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 +57 -331
- package/README.md +2 -2
- package/bare-imports.json +9 -0
- package/dist/client/api/completion-stream.d.ts +2 -1
- package/dist/client/api/completion-stream.js +2 -1
- package/dist/client/api/download-asset.d.ts +3 -2
- package/dist/client/api/download-asset.js +4 -3
- package/dist/client/api/embed.d.ts +5 -2
- package/dist/client/api/embed.js +2 -2
- package/dist/client/api/get-model-info.d.ts +1 -1
- package/dist/client/api/invoke-plugin.d.ts +3 -2
- package/dist/client/api/invoke-plugin.js +4 -4
- package/dist/client/api/load-model.d.ts +12 -10
- package/dist/client/api/load-model.js +3 -3
- package/dist/client/api/rag.d.ts +10 -10
- package/dist/client/api/rag.js +21 -21
- package/dist/client/api/text-to-speech.d.ts +2 -2
- package/dist/client/api/text-to-speech.js +3 -3
- package/dist/client/api/transcribe.d.ts +5 -3
- package/dist/client/api/transcribe.js +6 -4
- package/dist/client/api/translate.d.ts +2 -2
- package/dist/client/api/translate.js +3 -3
- package/dist/client/rpc/node-rpc-client.d.ts +2 -7
- package/dist/client/rpc/node-rpc-client.js +2 -39
- package/dist/client/rpc/profiling/index.d.ts +2 -0
- package/dist/client/rpc/profiling/index.js +1 -0
- package/dist/client/rpc/profiling/profiler.d.ts +27 -0
- package/dist/client/rpc/profiling/profiler.js +139 -0
- package/dist/client/rpc/rpc-client.d.ts +2 -2
- package/dist/client/rpc/rpc-client.js +174 -12
- package/dist/examples/delegated-inference/consumer-profiled.d.ts +2 -0
- package/dist/examples/delegated-inference/consumer-profiled.js +67 -0
- package/dist/examples/llamacpp-multimodal.js +1 -1
- package/dist/examples/parallel-download.js +45 -13
- package/dist/examples/profiling/basic.d.ts +2 -0
- package/dist/examples/profiling/basic.js +71 -0
- package/dist/examples/profiling/per-call.d.ts +2 -0
- package/dist/examples/profiling/per-call.js +30 -0
- package/dist/examples/transcription/parakeet-ctc-filesystem.d.ts +2 -0
- package/dist/examples/transcription/parakeet-ctc-filesystem.js +40 -0
- package/dist/examples/transcription/parakeet-microphone-record.d.ts +2 -0
- package/dist/examples/transcription/parakeet-microphone-record.js +95 -0
- package/dist/examples/transcription/parakeet-sortformer.d.ts +2 -0
- package/dist/examples/transcription/parakeet-sortformer.js +115 -0
- package/dist/examples/transcription/parakeet-tdt-filesystem.d.ts +2 -0
- package/dist/examples/transcription/parakeet-tdt-filesystem.js +44 -0
- package/dist/examples/translation/translation-bergamot-pivot.d.ts +2 -0
- package/dist/examples/translation/translation-bergamot-pivot.js +73 -0
- package/dist/examples/translation/translation-llm-afriquegemma.d.ts +2 -0
- package/dist/examples/translation/translation-llm-afriquegemma.js +39 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -0
- package/dist/logging/index.d.ts +1 -1
- package/dist/logging/index.js +1 -1
- package/dist/logging/namespaces.d.ts +3 -9
- package/dist/logging/namespaces.js +2 -8
- package/dist/logging/registry.js +15 -1
- package/dist/models/registry/models.d.ts +1606 -245
- package/dist/models/registry/models.js +2127 -721
- package/dist/models/update-models/codegen.js +2 -2
- package/dist/models/update-models/history.d.ts +11 -0
- package/dist/models/update-models/history.js +24 -5
- package/dist/models/update-models/index.js +17 -16
- package/dist/models/update-models/naming.js +56 -0
- package/dist/profiling/aggregator.d.ts +15 -0
- package/dist/profiling/aggregator.js +100 -0
- package/dist/profiling/clock.d.ts +12 -0
- package/dist/profiling/clock.js +51 -0
- package/dist/profiling/controller.d.ts +33 -0
- package/dist/profiling/controller.js +123 -0
- package/dist/profiling/envelope.d.ts +10 -0
- package/dist/profiling/envelope.js +36 -0
- package/dist/profiling/events.d.ts +20 -0
- package/dist/profiling/events.js +37 -0
- package/dist/profiling/exporters.d.ts +10 -0
- package/dist/profiling/exporters.js +236 -0
- package/dist/profiling/index.d.ts +36 -0
- package/dist/profiling/index.js +31 -0
- package/dist/profiling/ring-buffer.d.ts +19 -0
- package/dist/profiling/ring-buffer.js +83 -0
- package/dist/profiling/types.d.ts +47 -0
- package/dist/profiling/types.js +1 -0
- package/dist/schemas/common.d.ts +1888 -133
- package/dist/schemas/common.js +2 -0
- package/dist/schemas/completion-stream.d.ts +31 -0
- package/dist/schemas/completion-stream.js +13 -0
- package/dist/schemas/download-asset.d.ts +14 -3
- package/dist/schemas/download-asset.js +3 -1
- package/dist/schemas/engine-addon-map.js +9 -6
- package/dist/schemas/get-model-info.d.ts +2 -0
- package/dist/schemas/get-model-info.js +1 -0
- package/dist/schemas/index.d.ts +2 -1
- package/dist/schemas/index.js +2 -1
- package/dist/schemas/llamacpp-config.d.ts +140 -14
- package/dist/schemas/llamacpp-config.js +11 -7
- package/dist/schemas/load-model.d.ts +9649 -2515
- package/dist/schemas/load-model.js +142 -182
- package/dist/schemas/model-src-utils.d.ts +10 -2
- package/dist/schemas/model-types.d.ts +19 -1
- package/dist/schemas/model-types.js +11 -0
- package/dist/schemas/ocr.d.ts +37 -0
- package/dist/schemas/ocr.js +5 -0
- package/dist/schemas/plugin.d.ts +51 -5
- package/dist/schemas/plugin.js +26 -0
- package/dist/schemas/profiling.d.ts +105 -0
- package/dist/schemas/profiling.js +66 -0
- package/dist/schemas/registry.d.ts +18 -0
- package/dist/schemas/registry.js +2 -0
- package/dist/schemas/reload-config.d.ts +126 -6
- package/dist/schemas/reload-config.js +1 -1
- package/dist/schemas/sdk-config.d.ts +2280 -24
- package/dist/schemas/sdk-config.js +6 -1
- package/dist/schemas/sdk-errors-client.d.ts +1 -0
- package/dist/schemas/sdk-errors-client.js +7 -0
- package/dist/schemas/sdk-errors-server.d.ts +3 -0
- package/dist/schemas/sdk-errors-server.js +15 -0
- package/dist/schemas/text-to-speech.d.ts +90 -68
- package/dist/schemas/text-to-speech.js +16 -33
- package/dist/schemas/transcription-config.d.ts +383 -0
- package/dist/schemas/{whispercpp-config.js → transcription-config.js} +29 -1
- package/dist/schemas/translation-config.d.ts +463 -8
- package/dist/schemas/translation-config.js +35 -2
- package/dist/server/bare/delegate-rpc-client.js +11 -1
- package/dist/server/bare/ops/load-model.d.ts +7 -1
- package/dist/server/bare/ops/load-model.js +41 -42
- package/dist/server/bare/ops/transcribe.d.ts +3 -0
- package/dist/server/bare/ops/transcribe.js +75 -0
- package/dist/server/bare/ops/translate.d.ts +2 -0
- package/dist/server/bare/ops/translate.js +12 -4
- package/dist/server/bare/plugins/index.d.ts +1 -0
- package/dist/server/bare/plugins/index.js +1 -0
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.d.ts +2 -1
- package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +8 -6
- package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +108 -3
- package/dist/server/bare/plugins/llamacpp-completion/plugin.js +19 -6
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.d.ts +32 -2
- package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +31 -17
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +325 -3
- package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +117 -10
- package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +50 -2
- package/dist/server/bare/plugins/onnx-ocr/plugin.js +46 -5
- package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +351 -4
- package/dist/server/bare/plugins/onnx-tts/plugin.js +81 -61
- package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +317 -0
- package/dist/server/bare/plugins/parakeet-transcription/plugin.js +154 -0
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +209 -3
- package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +21 -9
- package/dist/server/bare/rag-hyperdb/rag-workspace-manager.js +2 -2
- package/dist/server/bare/registry/model-config-utils.js +3 -1
- package/dist/server/bare/utils/audio-input.d.ts +10 -0
- package/dist/server/bare/utils/audio-input.js +33 -0
- package/dist/server/error-handlers.d.ts +3 -2
- package/dist/server/error-handlers.js +11 -8
- package/dist/server/plugins/registry.js +5 -1
- package/dist/server/rpc/delegate-transport.d.ts +11 -3
- package/dist/server/rpc/delegate-transport.js +158 -3
- package/dist/server/rpc/handle-request.js +43 -4
- package/dist/server/rpc/handler-registry.js +7 -1
- package/dist/server/rpc/handler-utils.d.ts +5 -4
- package/dist/server/rpc/handler-utils.js +72 -31
- package/dist/server/rpc/handlers/completion-stream-delegated.d.ts +3 -1
- package/dist/server/rpc/handlers/completion-stream-delegated.js +11 -2
- package/dist/server/rpc/handlers/download-asset.js +55 -3
- package/dist/server/rpc/handlers/load-model/download-stats.d.ts +6 -0
- package/dist/server/rpc/handlers/load-model/download-stats.js +87 -0
- package/dist/server/rpc/handlers/load-model/handler.js +108 -123
- package/dist/server/rpc/handlers/load-model/http.d.ts +2 -1
- package/dist/server/rpc/handlers/load-model/http.js +21 -5
- package/dist/server/rpc/handlers/load-model/hyperdrive.d.ts +2 -1
- package/dist/server/rpc/handlers/load-model/hyperdrive.js +19 -14
- package/dist/server/rpc/handlers/load-model/registry.d.ts +2 -1
- package/dist/server/rpc/handlers/load-model/registry.js +123 -130
- package/dist/server/rpc/handlers/load-model/resolve.d.ts +2 -0
- package/dist/server/rpc/handlers/load-model/resolve.js +55 -22
- package/dist/server/rpc/handlers/load-model/types.d.ts +29 -0
- package/dist/server/rpc/handlers/load-model/types.js +1 -0
- package/dist/server/rpc/handlers/load-model-delegated.d.ts +5 -1
- package/dist/server/rpc/handlers/load-model-delegated.js +35 -7
- package/dist/server/rpc/handlers/plugin-dispatch.js +15 -10
- package/dist/server/rpc/handlers/plugin-invoke.js +56 -51
- package/dist/server/rpc/handlers/rag.js +24 -0
- package/dist/server/rpc/handlers/unload-model-delegated.d.ts +3 -0
- package/dist/server/rpc/handlers/unload-model-delegated.js +32 -0
- package/dist/server/rpc/profiling/context.d.ts +18 -0
- package/dist/server/rpc/profiling/context.js +38 -0
- package/dist/server/rpc/profiling/delegation-profiler.d.ts +32 -0
- package/dist/server/rpc/profiling/delegation-profiler.js +154 -0
- package/dist/server/rpc/profiling/index.d.ts +5 -0
- package/dist/server/rpc/profiling/index.js +4 -0
- package/dist/server/rpc/profiling/operation-metrics.d.ts +25 -0
- package/dist/server/rpc/profiling/operation-metrics.js +199 -0
- package/dist/server/rpc/profiling/operation-wrappers.d.ts +18 -0
- package/dist/server/rpc/profiling/operation-wrappers.js +124 -0
- package/dist/server/rpc/profiling/profiler.d.ts +13 -0
- package/dist/server/rpc/profiling/profiler.js +97 -0
- package/dist/server/utils/cache.d.ts +2 -1
- package/dist/server/utils/cache.js +5 -1
- package/dist/server/utils/checksum.d.ts +2 -0
- package/dist/server/utils/checksum.js +7 -0
- package/dist/server/utils/formatting.d.ts +6 -0
- package/dist/server/utils/formatting.js +35 -0
- package/dist/server/worker.js +2 -1
- package/dist/utils/errors-client.d.ts +3 -0
- package/dist/utils/errors-client.js +6 -0
- package/dist/utils/errors-server.d.ts +9 -0
- package/dist/utils/errors-server.js +15 -0
- package/dist/utils/global-singleton.d.ts +2 -0
- package/dist/utils/global-singleton.js +10 -0
- package/package.json +13 -16
- package/dist/schemas/whispercpp-config.d.ts +0 -70
- package/dist/server/bare/plugins/whispercpp-transcription/ops/transcribe-stream.d.ts +0 -3
- package/dist/server/bare/plugins/whispercpp-transcription/ops/transcribe-stream.js +0 -81
- /package/dist/examples/{whispercpp-filesystem.d.ts → transcription/whispercpp-filesystem.d.ts} +0 -0
- /package/dist/examples/{whispercpp-filesystem.js → transcription/whispercpp-filesystem.js} +0 -0
- /package/dist/examples/{whispercpp-microphone-record.d.ts → transcription/whispercpp-microphone-record.d.ts} +0 -0
- /package/dist/examples/{whispercpp-microphone-record.js → transcription/whispercpp-microphone-record.js} +0 -0
- /package/dist/examples/{whispercpp-prompt.d.ts → transcription/whispercpp-prompt.d.ts} +0 -0
- /package/dist/examples/{whispercpp-prompt.js → transcription/whispercpp-prompt.js} +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { loadModel, unloadModel, transcribe, PARAKEET_CTC_FP32, PARAKEET_CTC_DATA_FP32, PARAKEET_CTC_TOKENIZER, } from "@qvac/sdk";
|
|
2
|
+
const args = process.argv.slice(2);
|
|
3
|
+
if (!args[0]) {
|
|
4
|
+
console.error("Usage: bun run examples/transcription/parakeet-ctc-filesystem.ts <wav-file> " +
|
|
5
|
+
"[model.onnx] [model.onnx_data] [tokenizer.json]");
|
|
6
|
+
console.error("\nIf model paths are omitted, defaults to registry models.");
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
const audioFilePath = args[0];
|
|
10
|
+
const parakeetCtcModelSrc = args[1] ?? PARAKEET_CTC_FP32;
|
|
11
|
+
const parakeetCtcModelDataSrc = args[2] ?? PARAKEET_CTC_DATA_FP32;
|
|
12
|
+
const parakeetTokenizerSrc = args[3] ?? PARAKEET_CTC_TOKENIZER;
|
|
13
|
+
try {
|
|
14
|
+
console.log("Loading Parakeet CTC model...");
|
|
15
|
+
const modelId = await loadModel({
|
|
16
|
+
modelSrc: parakeetCtcModelSrc,
|
|
17
|
+
modelType: "parakeet",
|
|
18
|
+
modelConfig: {
|
|
19
|
+
modelType: "ctc",
|
|
20
|
+
parakeetCtcModelSrc,
|
|
21
|
+
parakeetCtcModelDataSrc,
|
|
22
|
+
parakeetTokenizerSrc,
|
|
23
|
+
},
|
|
24
|
+
onProgress: (progress) => {
|
|
25
|
+
console.log(`Download progress: ${progress.percentage.toFixed(1)}%`);
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
console.log(`Parakeet CTC model loaded with ID: ${modelId}`);
|
|
29
|
+
console.log("Transcribing audio...");
|
|
30
|
+
const text = await transcribe({ modelId, audioChunk: audioFilePath });
|
|
31
|
+
console.log("Transcription result:");
|
|
32
|
+
console.log(text);
|
|
33
|
+
console.log("Unloading model...");
|
|
34
|
+
await unloadModel({ modelId });
|
|
35
|
+
console.log("Done");
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.error("Error:", error);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { loadModel, unloadModel, transcribeStream, PARAKEET_TDT_ENCODER_FP32, PARAKEET_TDT_ENCODER_DATA_FP32, PARAKEET_TDT_DECODER_FP32, PARAKEET_TDT_VOCAB, PARAKEET_TDT_PREPROCESSOR_FP32, } from "@qvac/sdk";
|
|
2
|
+
import { spawn, spawnSync } from "child_process";
|
|
3
|
+
import { platform } from "os";
|
|
4
|
+
function checkFFmpeg() {
|
|
5
|
+
const result = spawnSync("ffmpeg", ["-version"], { stdio: "ignore" });
|
|
6
|
+
if (result.error || result.status !== 0) {
|
|
7
|
+
throw new Error("FFmpeg is required but not found in PATH.");
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function getAudioDevice() {
|
|
11
|
+
switch (platform()) {
|
|
12
|
+
case "darwin":
|
|
13
|
+
return ":0";
|
|
14
|
+
case "linux":
|
|
15
|
+
return "default";
|
|
16
|
+
case "win32":
|
|
17
|
+
// Change as per your system
|
|
18
|
+
return "audio=@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\\wave_{58C07110-A4FD-4FF8-BA10-5A3C14389F71}";
|
|
19
|
+
default:
|
|
20
|
+
throw new Error(`Unsupported platform: ${platform()}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function getAudioInputArgs() {
|
|
24
|
+
switch (platform()) {
|
|
25
|
+
case "darwin":
|
|
26
|
+
return ["-f", "avfoundation", "-i", getAudioDevice()];
|
|
27
|
+
case "linux":
|
|
28
|
+
return ["-f", "pulse", "-i", getAudioDevice()];
|
|
29
|
+
case "win32":
|
|
30
|
+
return ["-f", "dshow", "-i", getAudioDevice()];
|
|
31
|
+
default:
|
|
32
|
+
throw new Error(`Unsupported platform: ${platform()}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
checkFFmpeg();
|
|
36
|
+
console.log("Loading Parakeet model...");
|
|
37
|
+
const modelId = await loadModel({
|
|
38
|
+
modelSrc: PARAKEET_TDT_ENCODER_FP32,
|
|
39
|
+
modelType: "parakeet",
|
|
40
|
+
modelConfig: {
|
|
41
|
+
parakeetEncoderSrc: PARAKEET_TDT_ENCODER_FP32,
|
|
42
|
+
parakeetEncoderDataSrc: PARAKEET_TDT_ENCODER_DATA_FP32,
|
|
43
|
+
parakeetDecoderSrc: PARAKEET_TDT_DECODER_FP32,
|
|
44
|
+
parakeetVocabSrc: PARAKEET_TDT_VOCAB,
|
|
45
|
+
parakeetPreprocessorSrc: PARAKEET_TDT_PREPROCESSOR_FP32,
|
|
46
|
+
},
|
|
47
|
+
onProgress: (p) => console.log(`Download: ${p.percentage.toFixed(1)}%`),
|
|
48
|
+
});
|
|
49
|
+
console.log("Model loaded. Speak into your microphone (Ctrl+C to stop):\n");
|
|
50
|
+
const ffmpeg = spawn("ffmpeg", [
|
|
51
|
+
...getAudioInputArgs(),
|
|
52
|
+
"-ar",
|
|
53
|
+
"16000",
|
|
54
|
+
"-ac",
|
|
55
|
+
"1",
|
|
56
|
+
"-sample_fmt",
|
|
57
|
+
"s16",
|
|
58
|
+
"-f",
|
|
59
|
+
"s16le",
|
|
60
|
+
"pipe:1",
|
|
61
|
+
], { stdio: ["ignore", "pipe", "ignore"] });
|
|
62
|
+
const CHUNK_SIZE = 96000; // ~3s of 16kHz 16-bit mono
|
|
63
|
+
let buffer = Buffer.alloc(0);
|
|
64
|
+
let processing = false;
|
|
65
|
+
ffmpeg.stdout.on("data", (chunk) => {
|
|
66
|
+
buffer = Buffer.concat([buffer, chunk]);
|
|
67
|
+
if (buffer.length >= CHUNK_SIZE && !processing) {
|
|
68
|
+
const audioChunk = buffer.subarray(0, CHUNK_SIZE);
|
|
69
|
+
buffer = buffer.subarray(CHUNK_SIZE);
|
|
70
|
+
processing = true;
|
|
71
|
+
void (async () => {
|
|
72
|
+
try {
|
|
73
|
+
for await (const text of transcribeStream({ modelId, audioChunk })) {
|
|
74
|
+
if (text.trim() && !text.includes("[No speech detected]")) {
|
|
75
|
+
process.stdout.write(text);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
console.error("Transcription error:", err instanceof Error ? err.message : err);
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
processing = false;
|
|
84
|
+
}
|
|
85
|
+
})();
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
async function cleanup() {
|
|
89
|
+
console.log("\n\nStopping...");
|
|
90
|
+
ffmpeg.kill();
|
|
91
|
+
await unloadModel({ modelId });
|
|
92
|
+
console.log("Done.");
|
|
93
|
+
}
|
|
94
|
+
process.on("SIGINT", () => void cleanup());
|
|
95
|
+
process.on("SIGTERM", () => void cleanup());
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { loadModel, unloadModel, transcribe, PARAKEET_TDT_ENCODER_FP32, PARAKEET_TDT_ENCODER_DATA_FP32, PARAKEET_TDT_DECODER_FP32, PARAKEET_TDT_VOCAB, PARAKEET_TDT_PREPROCESSOR_FP32, PARAKEET_SORTFORMER_FP32, } from "@qvac/sdk";
|
|
2
|
+
import { dirname, join } from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
import { readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
5
|
+
import { tmpdir } from "os";
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
const sortformerSrc = args[0] ?? PARAKEET_SORTFORMER_FP32;
|
|
9
|
+
const defaultAudioPath = join(__dirname, "..", "..", "..", "examples", "transcription", "audio", "diarization-sample-16k.wav");
|
|
10
|
+
const audioFilePath = args[1] ?? defaultAudioPath;
|
|
11
|
+
// ── Step 1: Diarize with Sortformer ──
|
|
12
|
+
const sfModelId = await loadModel({
|
|
13
|
+
modelSrc: sortformerSrc,
|
|
14
|
+
modelType: "parakeet",
|
|
15
|
+
modelConfig: {
|
|
16
|
+
modelType: "sortformer",
|
|
17
|
+
parakeetSortformerSrc: sortformerSrc,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
const diarization = await transcribe({
|
|
21
|
+
modelId: sfModelId,
|
|
22
|
+
audioChunk: audioFilePath,
|
|
23
|
+
});
|
|
24
|
+
await unloadModel({ modelId: sfModelId });
|
|
25
|
+
const segments = parseDiarization(diarization);
|
|
26
|
+
// ── Step 2: Transcribe each segment with TDT ──
|
|
27
|
+
const tdtModelId = await loadModel({
|
|
28
|
+
modelSrc: PARAKEET_TDT_ENCODER_FP32,
|
|
29
|
+
modelType: "parakeet",
|
|
30
|
+
modelConfig: {
|
|
31
|
+
parakeetEncoderSrc: PARAKEET_TDT_ENCODER_FP32,
|
|
32
|
+
parakeetEncoderDataSrc: PARAKEET_TDT_ENCODER_DATA_FP32,
|
|
33
|
+
parakeetDecoderSrc: PARAKEET_TDT_DECODER_FP32,
|
|
34
|
+
parakeetVocabSrc: PARAKEET_TDT_VOCAB,
|
|
35
|
+
parakeetPreprocessorSrc: PARAKEET_TDT_PREPROCESSOR_FP32,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
const pcm = readPcm(audioFilePath);
|
|
39
|
+
const sliceDir = join(tmpdir(), `qvac-diarize-${Date.now()}`);
|
|
40
|
+
mkdirSync(sliceDir, { recursive: true });
|
|
41
|
+
const results = [];
|
|
42
|
+
for (let i = 0; i < segments.length; i++) {
|
|
43
|
+
const seg = segments[i];
|
|
44
|
+
const slicePath = join(sliceDir, `seg-${i}.wav`);
|
|
45
|
+
if (!writeWavSlice(pcm, seg.start, seg.end, slicePath)) {
|
|
46
|
+
results.push({ ...seg, text: "[No speech detected]" });
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const text = await transcribe({ modelId: tdtModelId, audioChunk: slicePath });
|
|
50
|
+
results.push({ ...seg, text: text.trim() || "[No speech detected]" });
|
|
51
|
+
}
|
|
52
|
+
await unloadModel({ modelId: tdtModelId });
|
|
53
|
+
// ── Step 3: Merge consecutive same-speaker segments and print ──
|
|
54
|
+
const merged = mergeSpeakers(results);
|
|
55
|
+
console.log("\n=== DIARIZED TRANSCRIPTION ===");
|
|
56
|
+
console.log("=".repeat(60));
|
|
57
|
+
for (const entry of merged) {
|
|
58
|
+
console.log(`Speaker ${entry.speaker} (${entry.start.toFixed(2)}s - ${entry.end.toFixed(2)}s):`);
|
|
59
|
+
console.log(` ${entry.text}\n`);
|
|
60
|
+
}
|
|
61
|
+
console.log("=".repeat(60));
|
|
62
|
+
console.log("\nDone!");
|
|
63
|
+
// ── Helpers ──
|
|
64
|
+
function parseDiarization(text) {
|
|
65
|
+
const segs = [];
|
|
66
|
+
for (const line of text.split("\n")) {
|
|
67
|
+
const m = line.match(/Speaker (\d+): ([\d.]+)s - ([\d.]+)s/);
|
|
68
|
+
if (m)
|
|
69
|
+
segs.push({ speaker: +m[1], start: +m[2], end: +m[3] });
|
|
70
|
+
}
|
|
71
|
+
return segs.sort((a, b) => a.start - b.start);
|
|
72
|
+
}
|
|
73
|
+
function readPcm(wavPath) {
|
|
74
|
+
const buf = readFileSync(wavPath);
|
|
75
|
+
const dataOffset = buf.indexOf("data") + 4;
|
|
76
|
+
return buf.subarray(dataOffset + 4, dataOffset + 4 + buf.readUInt32LE(dataOffset));
|
|
77
|
+
}
|
|
78
|
+
function writeWavSlice(pcm, startSec, endSec, outPath) {
|
|
79
|
+
const SR = 16000;
|
|
80
|
+
const BPS = 2;
|
|
81
|
+
const startByte = Math.floor(startSec * SR) * BPS;
|
|
82
|
+
const endByte = Math.min(Math.ceil(endSec * SR) * BPS, pcm.length);
|
|
83
|
+
if (startByte >= endByte)
|
|
84
|
+
return false;
|
|
85
|
+
const slice = pcm.subarray(startByte, endByte);
|
|
86
|
+
const hdr = Buffer.alloc(44);
|
|
87
|
+
hdr.write("RIFF", 0);
|
|
88
|
+
hdr.writeUInt32LE(36 + slice.length, 4);
|
|
89
|
+
hdr.write("WAVEfmt ", 8);
|
|
90
|
+
hdr.writeUInt32LE(16, 16);
|
|
91
|
+
hdr.writeUInt16LE(1, 20);
|
|
92
|
+
hdr.writeUInt16LE(1, 22);
|
|
93
|
+
hdr.writeUInt32LE(SR, 24);
|
|
94
|
+
hdr.writeUInt32LE(SR * BPS, 28);
|
|
95
|
+
hdr.writeUInt16LE(BPS, 32);
|
|
96
|
+
hdr.writeUInt16LE(16, 34);
|
|
97
|
+
hdr.write("data", 36);
|
|
98
|
+
hdr.writeUInt32LE(slice.length, 40);
|
|
99
|
+
writeFileSync(outPath, Buffer.concat([hdr, slice]));
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
function mergeSpeakers(entries) {
|
|
103
|
+
const out = [];
|
|
104
|
+
for (const e of entries) {
|
|
105
|
+
const last = out[out.length - 1];
|
|
106
|
+
if (last && last.speaker === e.speaker) {
|
|
107
|
+
last.text += " " + e.text;
|
|
108
|
+
last.end = e.end;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
out.push({ ...e });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { loadModel, unloadModel, transcribe, PARAKEET_TDT_ENCODER_FP32, PARAKEET_TDT_ENCODER_DATA_FP32, PARAKEET_TDT_DECODER_FP32, PARAKEET_TDT_VOCAB, PARAKEET_TDT_PREPROCESSOR_FP32, } from "@qvac/sdk";
|
|
2
|
+
const args = process.argv.slice(2);
|
|
3
|
+
if (!args[0]) {
|
|
4
|
+
console.error("Usage: bun run examples/transcription/parakeet-tdt-filesystem.ts <wav-file-path> " +
|
|
5
|
+
"[encoder-onnx] [encoder-data] [decoder-onnx] [vocab-txt] [preprocessor-onnx]");
|
|
6
|
+
console.error("\nIf model paths are omitted, defaults to registry models.");
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
const audioFilePath = args[0];
|
|
10
|
+
const parakeetEncoderSrc = args[1] ?? PARAKEET_TDT_ENCODER_FP32;
|
|
11
|
+
const parakeetEncoderDataSrc = args[2] ?? PARAKEET_TDT_ENCODER_DATA_FP32;
|
|
12
|
+
const parakeetDecoderSrc = args[3] ?? PARAKEET_TDT_DECODER_FP32;
|
|
13
|
+
const parakeetVocabSrc = args[4] ?? PARAKEET_TDT_VOCAB;
|
|
14
|
+
const parakeetPreprocessorSrc = args[5] ?? PARAKEET_TDT_PREPROCESSOR_FP32;
|
|
15
|
+
try {
|
|
16
|
+
console.log("Starting Parakeet transcription example...");
|
|
17
|
+
console.log("Loading Parakeet model...");
|
|
18
|
+
const modelId = await loadModel({
|
|
19
|
+
modelSrc: parakeetEncoderSrc,
|
|
20
|
+
modelType: "parakeet",
|
|
21
|
+
modelConfig: {
|
|
22
|
+
parakeetEncoderSrc,
|
|
23
|
+
parakeetEncoderDataSrc,
|
|
24
|
+
parakeetDecoderSrc,
|
|
25
|
+
parakeetVocabSrc,
|
|
26
|
+
parakeetPreprocessorSrc,
|
|
27
|
+
},
|
|
28
|
+
onProgress: (progress) => {
|
|
29
|
+
console.log(`Download progress: ${progress.percentage.toFixed(1)}%`);
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
console.log(`Parakeet model loaded with ID: ${modelId}`);
|
|
33
|
+
console.log("Transcribing audio...");
|
|
34
|
+
const text = await transcribe({ modelId, audioChunk: audioFilePath });
|
|
35
|
+
console.log("Transcription result:");
|
|
36
|
+
console.log(text);
|
|
37
|
+
console.log("Unloading Parakeet model...");
|
|
38
|
+
await unloadModel({ modelId });
|
|
39
|
+
console.log("Parakeet model unloaded successfully");
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error("Error:", error);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { BERGAMOT_ES_EN, BERGAMOT_EN_IT, loadModel, translate, unloadModel } from "@qvac/sdk";
|
|
2
|
+
/**
|
|
3
|
+
* Example: Pivot Translation with Bergamot
|
|
4
|
+
*
|
|
5
|
+
* Demonstrates translating Spanish to Italian through English as a pivot language.
|
|
6
|
+
* This requires two models:
|
|
7
|
+
* 1. Spanish → English (primary model)
|
|
8
|
+
* 2. English → Italian (pivot model)
|
|
9
|
+
*
|
|
10
|
+
* The API structure follows the standard Bergamot model pattern:
|
|
11
|
+
* - modelSrc: Primary translation model
|
|
12
|
+
* - modelConfig: Configuration with Bergamot-specific settings
|
|
13
|
+
* - modelConfig.pivotModel: Configuration for the secondary model
|
|
14
|
+
*/
|
|
15
|
+
// Spanish to Italian via English pivot example
|
|
16
|
+
try {
|
|
17
|
+
// Load the primary model (Spanish → English) with pivot configuration
|
|
18
|
+
const modelId = await loadModel({
|
|
19
|
+
modelSrc: BERGAMOT_ES_EN, // Primary model: Spanish → English
|
|
20
|
+
modelType: "nmt",
|
|
21
|
+
modelConfig: {
|
|
22
|
+
engine: "Bergamot",
|
|
23
|
+
from: "es",
|
|
24
|
+
to: "it", // Final target language (SDK handles the pivot internally)
|
|
25
|
+
beamsize: 4,
|
|
26
|
+
normalize: 1,
|
|
27
|
+
temperature: 0.3,
|
|
28
|
+
topk: 100,
|
|
29
|
+
// Pivot model configuration (English → Italian)
|
|
30
|
+
pivotModel: {
|
|
31
|
+
modelSrc: BERGAMOT_EN_IT, // Source for English → Italian model
|
|
32
|
+
// Bergamot-specific generation parameters for pivot model
|
|
33
|
+
beamsize: 4,
|
|
34
|
+
temperature: 0.3,
|
|
35
|
+
topk: 100,
|
|
36
|
+
normalize: 1,
|
|
37
|
+
lengthpenalty: 1.2,
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
onProgress: (progress) => {
|
|
41
|
+
console.log(progress);
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
console.log(`✅ Pivot translation model loaded: ${modelId}`);
|
|
45
|
+
console.log(" Primary: Spanish → English");
|
|
46
|
+
console.log(" Pivot: English → Italian");
|
|
47
|
+
// Spanish text to translate
|
|
48
|
+
const spanishText = `Era una mañana soleada cuando María decidió visitar el mercado local.
|
|
49
|
+
Compró frutas frescas, verduras y flores para su casa.
|
|
50
|
+
El vendedor le recomendó las mejores manzanas de la temporada.`;
|
|
51
|
+
console.log("\n📝 Original Spanish text:");
|
|
52
|
+
console.log(spanishText);
|
|
53
|
+
// Translate Spanish → English → Italian
|
|
54
|
+
const result = translate({
|
|
55
|
+
modelId,
|
|
56
|
+
text: spanishText,
|
|
57
|
+
modelType: "nmt",
|
|
58
|
+
stream: false,
|
|
59
|
+
});
|
|
60
|
+
const italianText = await result.text;
|
|
61
|
+
console.log("\n🇮🇹 Translated to Italian (via English):");
|
|
62
|
+
console.log(italianText);
|
|
63
|
+
// Expected output (approximate):
|
|
64
|
+
// "Era una mattina di sole quando Maria decise di visitare il mercato locale.
|
|
65
|
+
// Ha comprato frutta fresca, verdura e fiori per la sua casa.
|
|
66
|
+
// Il venditore ha consigliato le migliori mele della stagione."
|
|
67
|
+
await unloadModel({ modelId });
|
|
68
|
+
console.log("\n✅ Model unloaded successfully");
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
console.error("❌ Error:", error);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { translate, loadModel, unloadModel, AFRICAN_4B_TRANSLATION_Q4_K_M, } from "@qvac/sdk";
|
|
2
|
+
try {
|
|
3
|
+
const modelId = await loadModel({
|
|
4
|
+
modelSrc: AFRICAN_4B_TRANSLATION_Q4_K_M,
|
|
5
|
+
modelType: "llm",
|
|
6
|
+
onProgress: (progress) => {
|
|
7
|
+
console.log(progress);
|
|
8
|
+
},
|
|
9
|
+
// IMPORTANT: these parameters are validated to be optimal
|
|
10
|
+
modelConfig: {
|
|
11
|
+
tools: true,
|
|
12
|
+
ctx_size: 2048,
|
|
13
|
+
top_k: 1,
|
|
14
|
+
top_p: 1,
|
|
15
|
+
temp: 0,
|
|
16
|
+
repeat_penalty: 1,
|
|
17
|
+
seed: 42,
|
|
18
|
+
predict: 256,
|
|
19
|
+
stop_sequences: ['\n']
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
// With explicit source language
|
|
23
|
+
const engText = "Hello, how are you today?";
|
|
24
|
+
const resultExplicit = translate({
|
|
25
|
+
modelId,
|
|
26
|
+
text: engText,
|
|
27
|
+
from: "en",
|
|
28
|
+
to: "swh_Latn",
|
|
29
|
+
modelType: "llm",
|
|
30
|
+
stream: false,
|
|
31
|
+
});
|
|
32
|
+
const translatedTextExplicit = await resultExplicit.text;
|
|
33
|
+
console.log(`Explicit source: ${engText} -> "${translatedTextExplicit}"`);
|
|
34
|
+
await unloadModel({ modelId, clearStorage: false });
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error("❌ Error:", error);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export { completion, deleteCache, loadModel, downloadAsset, ping, startQVACProvider, stopQVACProvider, unloadModel, transcribe, transcribeStream, embed, translate, cancel, ragChunk, ragIngest, ragSaveEmbeddings, ragSearch, ragDeleteEmbeddings, ragReindex, ragListWorkspaces, ragCloseWorkspace, ragDeleteWorkspace, textToSpeech, getModelInfo, loggingStream, ocr, invokePlugin, invokePluginStream, modelRegistryList, modelRegistrySearch, modelRegistryGetModel, type ModelRegistrySearchParams, } from "./client/api/index";
|
|
2
2
|
export { close } from "./client/index";
|
|
3
|
-
export { type ModelProgressUpdate, type LoadModelOptions, type DownloadAssetOptions, type Tool, type ToolCall, type ToolCallWithCall, type ToolCallError, type ToolCallEvent, type CompletionStats, VERBOSITY, type Attachment, type CompletionParams, type RagSearchResult, type RagSaveEmbeddingsResult, type RagReindexResult, type RagEmbeddedDoc, type RagDoc, type RagWorkspaceInfo, type RagCloseWorkspaceParams, type RagDeleteWorkspaceParams, type RagIngestStage, type RagReindexStage, type RagSaveStage, SDK_CLIENT_ERROR_CODES, SDK_SERVER_ERROR_CODES, type QvacConfig, type ModelInfo, type GetModelInfoParams, type LoadedInstance, type CacheFileInfo, toolSchema, type McpClient, type McpClientInput, type OCRClientParams, type OCRTextBlock, type OCROptions, definePlugin, defineHandler, type QvacPlugin, type CreateModelParams, type PluginModelResult, type ModelRegistryEntry, type ModelRegistryEntryAddon, PLUGIN_LLM, PLUGIN_EMBEDDING, PLUGIN_WHISPER, PLUGIN_NMT, PLUGIN_TTS, PLUGIN_OCR, SDK_DEFAULT_PLUGINS, type BuiltinPlugin, } from "./schemas/index";
|
|
3
|
+
export { type ModelProgressUpdate, type LoadModelOptions, type DownloadAssetOptions, type Tool, type ToolCall, type ToolCallWithCall, type ToolCallError, type ToolCallEvent, type CompletionStats, VERBOSITY, type Attachment, type CompletionParams, type RagSearchResult, type RagSaveEmbeddingsResult, type RagReindexResult, type RagEmbeddedDoc, type RagDoc, type RagWorkspaceInfo, type RagCloseWorkspaceParams, type RagDeleteWorkspaceParams, type RagIngestStage, type RagReindexStage, type RagSaveStage, SDK_CLIENT_ERROR_CODES, SDK_SERVER_ERROR_CODES, type QvacConfig, type ModelInfo, type GetModelInfoParams, type LoadedInstance, type CacheFileInfo, toolSchema, type McpClient, type McpClientInput, type OCRClientParams, type OCRTextBlock, type OCROptions, definePlugin, defineHandler, type QvacPlugin, type CreateModelParams, type PluginModelResult, type ModelRegistryEntry, type ModelRegistryEntryAddon, PLUGIN_LLM, PLUGIN_EMBEDDING, PLUGIN_WHISPER, PLUGIN_NMT, PLUGIN_TTS, PLUGIN_OCR, SDK_DEFAULT_PLUGINS, type BuiltinPlugin, type ProfilerMode, } from "./schemas/index";
|
|
4
4
|
export { type ToolInput, type ToolHandler } from "./utils/tool-helpers";
|
|
5
5
|
export { MODEL_TYPES, ModelType } from "./schemas/index";
|
|
6
6
|
export * from "./models/registry/index";
|
|
7
7
|
export { SUPPORTED_AUDIO_FORMATS } from "./constants/audio";
|
|
8
8
|
export { getLogger, SDK_LOG_ID } from "./logging/index";
|
|
9
9
|
export type { Logger, LogTransport, LoggerOptions } from "./logging/index";
|
|
10
|
+
export { profiler } from "./profiling/index";
|
|
11
|
+
export type { ProfilerRuntimeOptions, ProfilerExport } from "./profiling/index";
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -10,3 +10,5 @@ export * from "./models/registry/index.js";
|
|
|
10
10
|
export { SUPPORTED_AUDIO_FORMATS } from "./constants/audio.js";
|
|
11
11
|
// Logging exports
|
|
12
12
|
export { getLogger, SDK_LOG_ID } from "./logging/index.js";
|
|
13
|
+
// Profiler exports
|
|
14
|
+
export { profiler } from "./profiling/index.js";
|
package/dist/logging/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { createStreamLogger } from "./stream-logger";
|
|
|
4
4
|
export { getServerLogger } from "./server-logger";
|
|
5
5
|
export { getClientLogger } from "./client-logger";
|
|
6
6
|
export type { Logger, LoggerOptions, LogTransport } from "./types";
|
|
7
|
-
export {
|
|
7
|
+
export { RAG_NAMESPACE, SDK_LOG_ID, SDK_SERVER_NAMESPACE, type AddonNamespace, } from "./namespaces";
|
|
8
8
|
export { registerAddonLogger, unregisterAddonLogger, createAddonLoggerCallback, clearAllAddonLoggers, } from "./addon";
|
|
9
9
|
export { summarizeRequest } from "./utils";
|
|
10
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/logging/index.js
CHANGED
|
@@ -3,6 +3,6 @@ export { setGlobalLogLevel, setGlobalConsoleOutput, registerLogger, unregisterLo
|
|
|
3
3
|
export { createStreamLogger } from "./stream-logger.js";
|
|
4
4
|
export { getServerLogger } from "./server-logger.js";
|
|
5
5
|
export { getClientLogger } from "./client-logger.js";
|
|
6
|
-
export {
|
|
6
|
+
export { RAG_NAMESPACE, SDK_LOG_ID, SDK_SERVER_NAMESPACE, } from "./namespaces.js";
|
|
7
7
|
export { registerAddonLogger, unregisterAddonLogger, createAddonLoggerCallback, clearAllAddonLoggers, } from "./addon.js";
|
|
8
8
|
export { summarizeRequest } from "./utils.js";
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
readonly WHISPERCPP: "whispercpp";
|
|
5
|
-
readonly TTS: "tts";
|
|
6
|
-
readonly NMTCPP: "nmtcpp";
|
|
7
|
-
readonly RAG_HYPERDB: "rag:hyperdb";
|
|
8
|
-
};
|
|
9
|
-
export type AddonNamespace = (typeof ADDON_NAMESPACES)[keyof typeof ADDON_NAMESPACES];
|
|
1
|
+
import { type CanonicalModelType } from "../schemas/model-types";
|
|
2
|
+
export declare const RAG_NAMESPACE: "rag:hyperdb";
|
|
3
|
+
export type AddonNamespace = CanonicalModelType | typeof RAG_NAMESPACE;
|
|
10
4
|
export declare const SDK_LOG_ID = "__sdk__";
|
|
11
5
|
export declare const SDK_SERVER_NAMESPACE = "sdk:server";
|
|
12
6
|
//# sourceMappingURL=namespaces.d.ts.map
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
LLAMACPP_EMBED: "llamacpp:embed",
|
|
4
|
-
WHISPERCPP: "whispercpp",
|
|
5
|
-
TTS: "tts",
|
|
6
|
-
NMTCPP: "nmtcpp",
|
|
7
|
-
RAG_HYPERDB: "rag:hyperdb",
|
|
8
|
-
};
|
|
1
|
+
import {} from "../schemas/model-types.js";
|
|
2
|
+
export const RAG_NAMESPACE = "rag:hyperdb";
|
|
9
3
|
// Reserved ID for SDK server logs
|
|
10
4
|
export const SDK_LOG_ID = "__sdk__";
|
|
11
5
|
// Namespace for all SDK server logs
|
package/dist/logging/registry.js
CHANGED
|
@@ -23,25 +23,39 @@
|
|
|
23
23
|
* module evaluations and runtimes.
|
|
24
24
|
*/
|
|
25
25
|
const REGISTRY_KEY = Symbol.for("@qvac/sdk:logger-registry");
|
|
26
|
+
const GLOBAL_LEVEL_KEY = Symbol.for("@qvac/sdk:global-log-level");
|
|
27
|
+
const GLOBAL_CONSOLE_KEY = Symbol.for("@qvac/sdk:global-console-output");
|
|
28
|
+
function getGlobal() {
|
|
29
|
+
return globalThis;
|
|
30
|
+
}
|
|
26
31
|
function getRegistry() {
|
|
27
|
-
const global =
|
|
32
|
+
const global = getGlobal();
|
|
28
33
|
if (!global[REGISTRY_KEY]) {
|
|
29
34
|
global[REGISTRY_KEY] = new Set();
|
|
30
35
|
}
|
|
31
36
|
return global[REGISTRY_KEY];
|
|
32
37
|
}
|
|
33
38
|
export function registerLogger(logger) {
|
|
39
|
+
const global = getGlobal();
|
|
34
40
|
getRegistry().add(logger);
|
|
41
|
+
if (global[GLOBAL_LEVEL_KEY] !== undefined) {
|
|
42
|
+
logger.setLevel(global[GLOBAL_LEVEL_KEY]);
|
|
43
|
+
}
|
|
44
|
+
if (global[GLOBAL_CONSOLE_KEY] !== undefined) {
|
|
45
|
+
logger.setConsoleOutput(global[GLOBAL_CONSOLE_KEY]);
|
|
46
|
+
}
|
|
35
47
|
}
|
|
36
48
|
export function unregisterLogger(logger) {
|
|
37
49
|
getRegistry().delete(logger);
|
|
38
50
|
}
|
|
39
51
|
export function setGlobalLogLevel(level) {
|
|
52
|
+
getGlobal()[GLOBAL_LEVEL_KEY] = level;
|
|
40
53
|
for (const logger of getRegistry()) {
|
|
41
54
|
logger.setLevel(level);
|
|
42
55
|
}
|
|
43
56
|
}
|
|
44
57
|
export function setGlobalConsoleOutput(enabled) {
|
|
58
|
+
getGlobal()[GLOBAL_CONSOLE_KEY] = enabled;
|
|
45
59
|
for (const logger of getRegistry()) {
|
|
46
60
|
logger.setConsoleOutput(enabled);
|
|
47
61
|
}
|