decibri 3.4.1 → 4.0.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/CHANGELOG.md +386 -0
- package/MIGRATION.md +151 -0
- package/README.md +206 -112
- package/examples/wav-capture.js +2 -2
- package/examples/websocket-stream.js +2 -2
- package/index.d.ts +1 -1
- package/index.js +52 -52
- package/package.json +9 -7
- package/src/browser/decibri-browser.js +37 -11
- package/src/browser/index.d.ts +28 -15
- package/src/browser/index.js +2 -2
- package/src/decibri-output.js +24 -29
- package/src/decibri.d.ts +81 -47
- package/src/decibri.js +106 -41
- package/src/errors.js +126 -23
package/src/errors.js
CHANGED
|
@@ -1,40 +1,143 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* decibri error classes.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* allowed range). Non-InvalidArg errors are passed through unchanged.
|
|
6
|
+
* A shallow set of catch-root classes that mirror the catch-roots the Python
|
|
7
|
+
* binding exposes (see bindings/python/python/decibri/exceptions.py), so
|
|
8
|
+
* `instanceof DecibriError` / `instanceof DeviceError` works the same way
|
|
9
|
+
* across bindings. Node idiom is shallow classes plus a stable `code` string,
|
|
10
|
+
* not a deep subclass tree: branch on `err.code` or on `instanceof`.
|
|
12
11
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
12
|
+
* DecibriError (base; extends Error)
|
|
13
|
+
* +- DeviceError (device enumeration / selection failures)
|
|
14
|
+
* +- OrtError (ONNX Runtime setup / inference failures)
|
|
15
|
+
* +- OrtPathError (a specific ORT library path could not be loaded)
|
|
17
16
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* Argument validation (bad sample rate, channels, frames, dtype, vad) keeps
|
|
18
|
+
* Node's built-in RangeError / TypeError, matching Node core; those are not
|
|
19
|
+
* decibri error classes by design.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
class DecibriError extends Error {
|
|
23
|
+
/**
|
|
24
|
+
* @param {string} message
|
|
25
|
+
* @param {string} [code] Stable string code for `err.code` branching.
|
|
26
|
+
*/
|
|
27
|
+
constructor(message, code) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = 'DecibriError';
|
|
30
|
+
this.code = code;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
class DeviceError extends DecibriError {
|
|
35
|
+
constructor(message, code) {
|
|
36
|
+
super(message, code);
|
|
37
|
+
this.name = 'DeviceError';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
class OrtError extends DecibriError {
|
|
42
|
+
constructor(message, code) {
|
|
43
|
+
super(message, code);
|
|
44
|
+
this.name = 'OrtError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
class OrtPathError extends OrtError {
|
|
49
|
+
constructor(message, code) {
|
|
50
|
+
super(message, code);
|
|
51
|
+
this.name = 'OrtPathError';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// ─── Native error classification ─────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
// The napi layer flattens every core DecibriError variant to a Status plus the
|
|
58
|
+
// variant's Display string (see bindings/node/src/lib.rs to_napi_error), so the
|
|
59
|
+
// message text is the only thing left to classify on. The prefixes below match
|
|
60
|
+
// the frozen core messages in crates/decibri/src/error.rs.
|
|
61
|
+
|
|
62
|
+
const DEVICE_CODES = [
|
|
63
|
+
['No microphone found matching', 'MICROPHONE_NOT_FOUND'],
|
|
64
|
+
['No speaker found matching', 'SPEAKER_NOT_FOUND'],
|
|
65
|
+
['Multiple devices match', 'MULTIPLE_DEVICES_MATCH'],
|
|
66
|
+
['No microphone found.', 'NO_MICROPHONE_FOUND'],
|
|
67
|
+
['No speaker found.', 'NO_SPEAKER_FOUND'],
|
|
68
|
+
['Selected device is not a valid microphone', 'NOT_AN_INPUT_DEVICE'],
|
|
69
|
+
['Failed to enumerate devices', 'DEVICE_ENUMERATION_FAILED'],
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
const ORT_CODES = [
|
|
73
|
+
['decibri: failed to initialize ONNX Runtime', 'ORT_INIT_FAILED'],
|
|
74
|
+
['Failed to load Silero VAD model from', 'VAD_MODEL_LOAD_FAILED'],
|
|
75
|
+
['Failed to create ort session builder', 'ORT_SESSION_BUILD_FAILED'],
|
|
76
|
+
['Failed to set ort threads', 'ORT_THREADS_CONFIG_FAILED'],
|
|
77
|
+
['Silero VAD inference failed', 'ORT_INFERENCE_FAILED'],
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Wrap an error thrown from a native DecibriBridge / DecibriOutputBridge call
|
|
82
|
+
* into the appropriate JS error: a built-in for argument validation, or a
|
|
83
|
+
* decibri catch-root class (with a `code`) for device and ONNX Runtime
|
|
84
|
+
* failures. The message is preserved verbatim.
|
|
85
|
+
*
|
|
86
|
+
* @param {Error} err Error thrown from a native constructor.
|
|
87
|
+
* @returns {Error} A RangeError, TypeError, or DecibriError subclass.
|
|
21
88
|
*/
|
|
22
89
|
function wrapNativeError(err) {
|
|
23
|
-
|
|
90
|
+
const msg = (err && err.message) || String(err);
|
|
24
91
|
|
|
25
|
-
|
|
26
|
-
|
|
92
|
+
// Argument validation stays as Node built-ins. `device index out of range`
|
|
93
|
+
// is kept here (RangeError) so the index error type is the same whether it
|
|
94
|
+
// is raised by the client-side bounds check or by the core.
|
|
95
|
+
if (
|
|
27
96
|
msg.startsWith('sample rate must be between') ||
|
|
28
97
|
msg.startsWith('channels must be between') ||
|
|
29
98
|
msg.startsWith('frames per buffer must be between') ||
|
|
30
99
|
msg.startsWith('Silero VAD only supports') ||
|
|
31
100
|
msg.startsWith('VAD threshold must be between') ||
|
|
32
|
-
msg.startsWith('device index out of range')
|
|
101
|
+
msg.startsWith('device index out of range')
|
|
102
|
+
) {
|
|
103
|
+
return new RangeError(msg);
|
|
104
|
+
}
|
|
105
|
+
if (
|
|
106
|
+
msg.startsWith("dtype must be 'int16' or 'float32'") ||
|
|
107
|
+
msg.startsWith("format must be 'int16' or 'float32'")
|
|
108
|
+
) {
|
|
109
|
+
return new TypeError(msg);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Device enumeration / selection failures.
|
|
113
|
+
for (const [prefix, code] of DEVICE_CODES) {
|
|
114
|
+
if (msg.startsWith(prefix)) return new DeviceError(msg, code);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ONNX Runtime: a bad library path is an OrtPathError (subclass of OrtError);
|
|
118
|
+
// OrtLoadFailed and OrtPathInvalid share this message prefix and the same
|
|
119
|
+
// user-facing meaning. Other ORT failures are OrtError.
|
|
120
|
+
if (msg.startsWith('decibri: failed to load ONNX Runtime from')) {
|
|
121
|
+
return new OrtPathError(msg, 'ORT_LOAD_FAILED');
|
|
122
|
+
}
|
|
123
|
+
for (const [prefix, code] of ORT_CODES) {
|
|
124
|
+
if (msg.startsWith(prefix)) return new OrtError(msg, code);
|
|
125
|
+
}
|
|
126
|
+
if (msg.startsWith('Failed to create') && msg.includes('tensor')) {
|
|
127
|
+
return new OrtError(msg, 'ORT_TENSOR_CREATE_FAILED');
|
|
128
|
+
}
|
|
129
|
+
if (msg.startsWith('Failed to extract') && msg.includes('tensor')) {
|
|
130
|
+
return new OrtError(msg, 'ORT_TENSOR_EXTRACT_FAILED');
|
|
131
|
+
}
|
|
33
132
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
wrapped.code = err.code;
|
|
37
|
-
return wrapped;
|
|
133
|
+
// Any other error from the native constructor is still a decibri error.
|
|
134
|
+
return new DecibriError(msg, 'DECIBRI_ERROR');
|
|
38
135
|
}
|
|
39
136
|
|
|
40
|
-
module.exports = {
|
|
137
|
+
module.exports = {
|
|
138
|
+
DecibriError,
|
|
139
|
+
DeviceError,
|
|
140
|
+
OrtError,
|
|
141
|
+
OrtPathError,
|
|
142
|
+
wrapNativeError,
|
|
143
|
+
};
|