@untemps/vocal 2.0.0-beta.17 → 2.0.0-beta.19
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 +14 -0
- package/README.md +34 -0
- package/dist/index.cjs +1 -1
- package/dist/index.es.js +4 -4
- package/package.json +3 -7
- package/dist/index.umd.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [2.0.0-beta.19](https://github.com/untemps/vocal/compare/v2.0.0-beta.18...v2.0.0-beta.19) (2026-05-17)
|
|
2
|
+
|
|
3
|
+
# [2.0.0-beta.18](https://github.com/untemps/vocal/compare/v2.0.0-beta.17...v2.0.0-beta.18) (2026-05-16)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### chore
|
|
7
|
+
|
|
8
|
+
* Remove UMD bundle from distribution ([#78](https://github.com/untemps/vocal/issues/78)) ([c0c819c](https://github.com/untemps/vocal/commit/c0c819c251cf4ee838463bf9dd6a960a70f6ad32))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### BREAKING CHANGES
|
|
12
|
+
|
|
13
|
+
* dist/index.umd.js is no longer published. Consumers loading via <script> tags or AMD loaders should use dist/index.es.js with a module-aware loader instead.
|
|
14
|
+
|
|
1
15
|
# [2.0.0-beta.17](https://github.com/untemps/vocal/compare/v2.0.0-beta.16...v2.0.0-beta.17) (2026-05-16)
|
|
2
16
|
|
|
3
17
|
|
package/README.md
CHANGED
|
@@ -108,6 +108,36 @@ vocal.start({ signal: controller.signal })
|
|
|
108
108
|
controller.abort()
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
+
### `stop()`
|
|
112
|
+
|
|
113
|
+
Stops recognition gracefully, allowing the current audio to be processed before disconnecting. Sets `isRecording` to `false`.
|
|
114
|
+
|
|
115
|
+
### `abort()`
|
|
116
|
+
|
|
117
|
+
Stops recognition immediately without processing pending audio. Sets `isRecording` to `false`.
|
|
118
|
+
|
|
119
|
+
### `addEventListener(eventType, callback)`
|
|
120
|
+
|
|
121
|
+
Registers a callback for the given event type. Multiple callbacks can be registered for the same type — they stack and all fire in registration order.
|
|
122
|
+
|
|
123
|
+
| Parameter | Type | Description |
|
|
124
|
+
| --------- | ------------------------------------------------- | ------------------------------------------ |
|
|
125
|
+
| eventType | `EventType` | One of the valid event type strings |
|
|
126
|
+
| callback | `ResultEventHandler \| ErrorEventHandler \| GenericEventHandler` | Callback invoked when the event fires |
|
|
127
|
+
|
|
128
|
+
Throws if `eventType` is not a valid `EventType`.
|
|
129
|
+
|
|
130
|
+
### `removeEventListener(eventType, callback?)`
|
|
131
|
+
|
|
132
|
+
Removes a listener for the given event type.
|
|
133
|
+
|
|
134
|
+
| Parameter | Type | Default | Description |
|
|
135
|
+
| --------- | ------------------------------------------------- | ----------- | ---------------------------------------------------- |
|
|
136
|
+
| eventType | `EventType` | | One of the valid event type strings |
|
|
137
|
+
| callback | `ResultEventHandler \| ErrorEventHandler \| GenericEventHandler` | `undefined` | Specific callback to remove. Omit to remove all listeners for this type |
|
|
138
|
+
|
|
139
|
+
Throws if `eventType` is not a valid `EventType`.
|
|
140
|
+
|
|
111
141
|
### `once(eventType, callback)`
|
|
112
142
|
|
|
113
143
|
Registers a one-shot listener that automatically unregisters itself after firing once.
|
|
@@ -124,3 +154,7 @@ vocal.once('result', (event, bestAlternative, alternatives) => {
|
|
|
124
154
|
})
|
|
125
155
|
```
|
|
126
156
|
|
|
157
|
+
### `cleanup()`
|
|
158
|
+
|
|
159
|
+
Stops recognition, removes all registered listeners, and releases the internal `SpeechRecognition` instance. The `Vocal` object cannot be reused after `cleanup()`.
|
|
160
|
+
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@untemps/user-permissions-utils`);var t=class t{static defaultOptions={grammars:null,lang:`en-US`,continuous:!1,interimResults:!1,maxAlternatives:1};static eventTypes={AUDIO_END:`audioend`,AUDIO_START:`audiostart`,END:`end`,ERROR:`error`,NO_MATCH:`nomatch`,RESULT:`result`,SOUND_END:`soundend`,SOUND_START:`soundstart`,SPEECH_END:`speechend`,SPEECH_START:`speechstart`,START:`start`};static get isSupported(){return!!t._resolveSpeechRecognition()&&!!(0,e.isNavigatorPermissionsSupported)()&&!!(0,e.isNavigatorMediaDevicesSupported)()}static set isSupported(e){throw Error(`You cannot set isSupported directly.`)}_instance=null;_listeners=
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@untemps/user-permissions-utils`);var t=class t{static defaultOptions={grammars:null,lang:`en-US`,continuous:!1,interimResults:!1,maxAlternatives:1};static eventTypes={AUDIO_END:`audioend`,AUDIO_START:`audiostart`,END:`end`,ERROR:`error`,NO_MATCH:`nomatch`,RESULT:`result`,SOUND_END:`soundend`,SOUND_START:`soundstart`,SPEECH_END:`speechend`,SPEECH_START:`speechstart`,START:`start`};static get isSupported(){return!!t._resolveSpeechRecognition()&&!!(0,e.isNavigatorPermissionsSupported)()&&!!(0,e.isNavigatorMediaDevicesSupported)()}static set isSupported(e){throw Error(`You cannot set isSupported directly.`)}_instance=null;_listeners={};_isRecording=!1;_onEnd=()=>{this._isRecording=!1};constructor(e){let n=t._resolveSpeechRecognition();if(!n)throw new DOMException(`SpeechRecognition not supported`,`NOT_SUPPORTED_ERR`);this._instance=new n;let{grammars:r,...i}={...t.defaultOptions,...e??{}},a=this._instance;if(Object.assign(a,i),r)a.grammars=r;else{let e=t._resolveSpeechGrammarList();a.grammars=e?new e:null}this._instance.addEventListener(`end`,this._onEnd)}get isRecording(){return this._isRecording}set isRecording(e){throw Error(`You cannot set isRecording directly.`)}async start({signal:t}={}){if(this._instance)try{if(!await(0,e.getUserMediaStream)(`microphone`,{audio:!0},{signal:t}))throw Error(`Unable to retrieve the stream from media device`);this._instance.start(),this._isRecording=!0}catch(e){if(e instanceof Error&&e.name===`AbortError`)return this;throw e}return this}stop(){return this._instance&&(this._instance.stop(),this._isRecording=!1),this}abort(){return this._instance&&(this._instance.abort(),this._isRecording=!1),this}addEventListener(e,n){if(!this._includesEventType(e))throw Error(this._unknownEventTypeMessage(e));if(this._instance){let r=r=>{let i=[];if(e===t.eventTypes.RESULT){let e=r;if(e.results?.length>0&&e.resultIndex<e.results.length){let t=Array.from(e.results[e.resultIndex]),n=t.reduce((e,t)=>(t.confidence??0)>(e.confidence??0)?t:e);i.push(n.transcript,t.map(e=>e.transcript))}}n.call(this,r,...i)};this._instance.addEventListener(e,r),this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push({callback:n,handler:r})}return this}removeEventListener(e,t){if(!this._includesEventType(e))throw Error(this._unknownEventTypeMessage(e));let n=this._instance;if(n&&this._listeners[e])if(t!==void 0){let r=this._listeners[e].findIndex(e=>e.callback===t);r!==-1&&(n.removeEventListener(e,this._listeners[e][r].handler),this._listeners[e].splice(r,1),this._listeners[e].length===0&&delete this._listeners[e])}else this._listeners[e].forEach(({handler:t})=>n.removeEventListener(e,t)),delete this._listeners[e];return this}once(e,t){let n=(...r)=>{t.call(this,...r),this.removeEventListener(e,n)};return this.addEventListener(e,n)}cleanup(){return this.stop(),Object.keys(this._listeners).forEach(e=>this.removeEventListener(e)),this._instance?.removeEventListener(`end`,this._onEnd),this._instance=null,this}_includesEventType(e){return Object.values(t.eventTypes).includes(e)}_unknownEventTypeMessage(e){return`Unknown event type "${e}". Valid types are: ${Object.values(t.eventTypes).join(`, `)}.`}static _resolveSpeechRecognition(){if(!(typeof window>`u`))return window.SpeechRecognition??window.webkitSpeechRecognition??window.mozSpeechRecognition??window.msSpeechRecognition}static _resolveSpeechGrammarList(){return window.SpeechGrammarList??window.webkitSpeechGrammarList??window.mozSpeechGrammarList??window.msSpeechGrammarList}};exports.Vocal=t;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.es.js
CHANGED
|
@@ -28,7 +28,7 @@ var r = class r {
|
|
|
28
28
|
throw Error("You cannot set isSupported directly.");
|
|
29
29
|
}
|
|
30
30
|
_instance = null;
|
|
31
|
-
_listeners =
|
|
31
|
+
_listeners = {};
|
|
32
32
|
_isRecording = !1;
|
|
33
33
|
_onEnd = () => {
|
|
34
34
|
this._isRecording = !1;
|
|
@@ -36,7 +36,7 @@ var r = class r {
|
|
|
36
36
|
constructor(e) {
|
|
37
37
|
let t = r._resolveSpeechRecognition();
|
|
38
38
|
if (!t) throw new DOMException("SpeechRecognition not supported", "NOT_SUPPORTED_ERR");
|
|
39
|
-
this._instance = new t()
|
|
39
|
+
this._instance = new t();
|
|
40
40
|
let { grammars: n, ...i } = {
|
|
41
41
|
...r.defaultOptions,
|
|
42
42
|
...e ?? {}
|
|
@@ -72,7 +72,7 @@ var r = class r {
|
|
|
72
72
|
}
|
|
73
73
|
addEventListener(e, t) {
|
|
74
74
|
if (!this._includesEventType(e)) throw Error(this._unknownEventTypeMessage(e));
|
|
75
|
-
if (this._instance
|
|
75
|
+
if (this._instance) {
|
|
76
76
|
let n = (n) => {
|
|
77
77
|
let i = [];
|
|
78
78
|
if (e === r.eventTypes.RESULT) {
|
|
@@ -94,7 +94,7 @@ var r = class r {
|
|
|
94
94
|
removeEventListener(e, t) {
|
|
95
95
|
if (!this._includesEventType(e)) throw Error(this._unknownEventTypeMessage(e));
|
|
96
96
|
let n = this._instance;
|
|
97
|
-
if (n && this._listeners
|
|
97
|
+
if (n && this._listeners[e]) if (t !== void 0) {
|
|
98
98
|
let r = this._listeners[e].findIndex((e) => e.callback === t);
|
|
99
99
|
r !== -1 && (n.removeEventListener(e, this._listeners[e][r].handler), this._listeners[e].splice(r, 1), this._listeners[e].length === 0 && delete this._listeners[e]);
|
|
100
100
|
} else this._listeners[e].forEach(({ handler: t }) => n.removeEventListener(e, t)), delete this._listeners[e];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@untemps/vocal",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.19",
|
|
4
4
|
"description": "Class wrapped around the SpeechRecognition Web API",
|
|
5
5
|
"repository": "git@github.com:untemps/vocal.git",
|
|
6
6
|
"keywords": [
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"files": [
|
|
24
24
|
"dist/index.cjs",
|
|
25
25
|
"dist/index.es.js",
|
|
26
|
-
"dist/index.umd.js",
|
|
27
26
|
"dist/index.d.ts",
|
|
28
27
|
"CHANGELOG.md"
|
|
29
28
|
],
|
|
@@ -61,7 +60,7 @@
|
|
|
61
60
|
"vitest": "^4.1.5"
|
|
62
61
|
},
|
|
63
62
|
"dependencies": {
|
|
64
|
-
"@untemps/user-permissions-utils": "^1.3.
|
|
63
|
+
"@untemps/user-permissions-utils": "^1.3.3"
|
|
65
64
|
},
|
|
66
65
|
"release": {
|
|
67
66
|
"branches": [
|
|
@@ -98,10 +97,6 @@
|
|
|
98
97
|
{
|
|
99
98
|
"path": "dist/index.es.js",
|
|
100
99
|
"label": "ES distribution"
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
"path": "dist/index.umd.js",
|
|
104
|
-
"label": "UMD distribution"
|
|
105
100
|
}
|
|
106
101
|
]
|
|
107
102
|
}
|
|
@@ -109,6 +104,7 @@
|
|
|
109
104
|
]
|
|
110
105
|
},
|
|
111
106
|
"scripts": {
|
|
107
|
+
"dev": "vite demo --config demo/vite.config.js",
|
|
112
108
|
"test": "vitest",
|
|
113
109
|
"test:ci": "vitest run --coverage",
|
|
114
110
|
"build": "vite build",
|
package/dist/index.umd.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`@untemps/user-permissions-utils`)):typeof define==`function`&&define.amd?define([`exports`,`@untemps/user-permissions-utils`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.Vocal={},e.UserPermissionsUtils))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`}),e.Vocal=class e{static defaultOptions={grammars:null,lang:`en-US`,continuous:!1,interimResults:!1,maxAlternatives:1};static eventTypes={AUDIO_END:`audioend`,AUDIO_START:`audiostart`,END:`end`,ERROR:`error`,NO_MATCH:`nomatch`,RESULT:`result`,SOUND_END:`soundend`,SOUND_START:`soundstart`,SPEECH_END:`speechend`,SPEECH_START:`speechstart`,START:`start`};static get isSupported(){return!!e._resolveSpeechRecognition()&&!!(0,t.isNavigatorPermissionsSupported)()&&!!(0,t.isNavigatorMediaDevicesSupported)()}static set isSupported(e){throw Error(`You cannot set isSupported directly.`)}_instance=null;_listeners=null;_isRecording=!1;_onEnd=()=>{this._isRecording=!1};constructor(t){let n=e._resolveSpeechRecognition();if(!n)throw new DOMException(`SpeechRecognition not supported`,`NOT_SUPPORTED_ERR`);this._instance=new n,this._listeners={};let{grammars:r,...i}={...e.defaultOptions,...t??{}},a=this._instance;if(Object.assign(a,i),r)a.grammars=r;else{let t=e._resolveSpeechGrammarList();a.grammars=t?new t:null}this._instance.addEventListener(`end`,this._onEnd)}get isRecording(){return this._isRecording}set isRecording(e){throw Error(`You cannot set isRecording directly.`)}async start({signal:e}={}){if(this._instance)try{if(!await(0,t.getUserMediaStream)(`microphone`,{audio:!0},{signal:e}))throw Error(`Unable to retrieve the stream from media device`);this._instance.start(),this._isRecording=!0}catch(e){if(e instanceof Error&&e.name===`AbortError`)return this;throw e}return this}stop(){return this._instance&&(this._instance.stop(),this._isRecording=!1),this}abort(){return this._instance&&(this._instance.abort(),this._isRecording=!1),this}addEventListener(t,n){if(!this._includesEventType(t))throw Error(this._unknownEventTypeMessage(t));if(this._instance&&this._listeners){let r=r=>{let i=[];if(t===e.eventTypes.RESULT){let e=r;if(e.results?.length>0&&e.resultIndex<e.results.length){let t=Array.from(e.results[e.resultIndex]),n=t.reduce((e,t)=>(t.confidence??0)>(e.confidence??0)?t:e);i.push(n.transcript,t.map(e=>e.transcript))}}n.call(this,r,...i)};this._instance.addEventListener(t,r),this._listeners[t]||(this._listeners[t]=[]),this._listeners[t].push({callback:n,handler:r})}return this}removeEventListener(e,t){if(!this._includesEventType(e))throw Error(this._unknownEventTypeMessage(e));let n=this._instance;if(n&&this._listeners&&this._listeners[e])if(t!==void 0){let r=this._listeners[e].findIndex(e=>e.callback===t);r!==-1&&(n.removeEventListener(e,this._listeners[e][r].handler),this._listeners[e].splice(r,1),this._listeners[e].length===0&&delete this._listeners[e])}else this._listeners[e].forEach(({handler:t})=>n.removeEventListener(e,t)),delete this._listeners[e];return this}once(e,t){let n=(...r)=>{t.call(this,...r),this.removeEventListener(e,n)};return this.addEventListener(e,n)}cleanup(){return this.stop(),Object.keys(this._listeners).forEach(e=>this.removeEventListener(e)),this._instance?.removeEventListener(`end`,this._onEnd),this._instance=null,this}_includesEventType(t){return Object.values(e.eventTypes).includes(t)}_unknownEventTypeMessage(t){return`Unknown event type "${t}". Valid types are: ${Object.values(e.eventTypes).join(`, `)}.`}static _resolveSpeechRecognition(){if(!(typeof window>`u`))return window.SpeechRecognition??window.webkitSpeechRecognition??window.mozSpeechRecognition??window.msSpeechRecognition}static _resolveSpeechGrammarList(){return window.SpeechGrammarList??window.webkitSpeechGrammarList??window.mozSpeechGrammarList??window.msSpeechGrammarList}}});
|
|
2
|
-
//# sourceMappingURL=index.umd.js.map
|