@untemps/vocal 2.0.0-beta.3 → 2.0.0-beta.4

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 CHANGED
@@ -1,3 +1,16 @@
1
+ # [2.0.0-beta.4](https://github.com/untemps/vocal/compare/v2.0.0-beta.3...v2.0.0-beta.4) (2026-05-16)
2
+
3
+
4
+ ### Features
5
+
6
+ * start() rejects on error instead of always resolving ([#43](https://github.com/untemps/vocal/issues/43)) ([4414f11](https://github.com/untemps/vocal/commit/4414f11608e795b94845d06e6be53e8e5a76e022))
7
+
8
+
9
+ ### BREAKING CHANGES
10
+
11
+ * start(): no longer resolves when the microphone stream fails. Callers who did not handle rejections will receive an UnhandledPromiseRejection.
12
+ Migration: wrap await vocal.start() in try/catch, or use .catch().
13
+
1
14
  # [2.0.0-beta.3](https://github.com/untemps/vocal/compare/v2.0.0-beta.2...v2.0.0-beta.3) (2026-05-15)
2
15
 
3
16
 
package/README.md CHANGED
@@ -36,8 +36,12 @@ vocal.addEventListener('speechend', (event) => console.log('Vocal stops recordin
36
36
  vocal.addEventListener('result', (event, transcript, alternatives) => console.log('Vocal catches a result:', transcript, alternatives))
37
37
  vocal.addEventListener('error', (error) => { throw error })
38
38
 
39
- // Start recording
40
- vocal.start()
39
+ // Start recording — rejects on error
40
+ try {
41
+ await vocal.start()
42
+ } catch (error) {
43
+ // handle error
44
+ }
41
45
 
42
46
  // Stop/Pause recording
43
47
  vocal.stop()
package/dist/index.es.js CHANGED
@@ -65,8 +65,7 @@ var r = class r {
65
65
  this._instance.start(), this._isRecording = !0;
66
66
  } catch (e) {
67
67
  if (e instanceof Error && e.name === "AbortError") return this;
68
- let t = this._listeners?.error;
69
- t && t(e);
68
+ throw e;
70
69
  }
71
70
  return this;
72
71
  }
package/dist/index.js 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=null;_isRecording=!1;constructor(e){let n=t._resolveSpeechRecognition();if(!n)throw new DOMException(`SpeechRecognition not supported`,`NOT_SUPPORTED_ERR`);this._instance=new n,this._listeners={};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._isRecording=!1})}get instance(){return this._instance}set instance(e){throw Error(`You cannot set instance directly.`)}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;let t=this._listeners?.error;t&&t(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._instance&&this._listeners&&this._includesEventType(e)){this._listeners[e]&&this.removeEventListener(e);let r=r=>{let i=[];if(e===t.eventTypes.RESULT){let e=r;if(e.results?.length>0){let t=Array.from(e.results[0],e=>e.transcript);i.push(t[0],t)}}n.apply(this,[r,...i])};this._instance.addEventListener(e,r),this._listeners[e]=r}return this}removeEventListener(e){if(this._instance&&this._listeners){let t=this._listeners[e];this._instance.removeEventListener(e,t),delete this._listeners[e]}return this}cleanup(){return this.stop(),Object.keys(this._listeners).forEach(e=>this.removeEventListener(e)),this._instance=null,this}_includesEventType(e){return Object.values(t.eventTypes).includes(e)}static _resolveSpeechRecognition(){return window.SpeechRecognition??window.webkitSpeechRecognition??window.mozSpeechRecognition??window.msSpeechRecognition}static _resolveSpeechGrammarList(){return window.SpeechGrammarList??window.webkitSpeechGrammarList??window.mozSpeechGrammarList??window.msSpeechGrammarList}};exports.Vocal=t;
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=null;_isRecording=!1;constructor(e){let n=t._resolveSpeechRecognition();if(!n)throw new DOMException(`SpeechRecognition not supported`,`NOT_SUPPORTED_ERR`);this._instance=new n,this._listeners={};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._isRecording=!1})}get instance(){return this._instance}set instance(e){throw Error(`You cannot set instance directly.`)}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._instance&&this._listeners&&this._includesEventType(e)){this._listeners[e]&&this.removeEventListener(e);let r=r=>{let i=[];if(e===t.eventTypes.RESULT){let e=r;if(e.results?.length>0){let t=Array.from(e.results[0],e=>e.transcript);i.push(t[0],t)}}n.apply(this,[r,...i])};this._instance.addEventListener(e,r),this._listeners[e]=r}return this}removeEventListener(e){if(this._instance&&this._listeners){let t=this._listeners[e];this._instance.removeEventListener(e,t),delete this._listeners[e]}return this}cleanup(){return this.stop(),Object.keys(this._listeners).forEach(e=>this.removeEventListener(e)),this._instance=null,this}_includesEventType(e){return Object.values(t.eventTypes).includes(e)}static _resolveSpeechRecognition(){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.js.map
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
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;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._isRecording=!1})}get instance(){return this._instance}set instance(e){throw Error(`You cannot set instance directly.`)}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;let t=this._listeners?.error;t&&t(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._instance&&this._listeners&&this._includesEventType(t)){this._listeners[t]&&this.removeEventListener(t);let r=r=>{let i=[];if(t===e.eventTypes.RESULT){let e=r;if(e.results?.length>0){let t=Array.from(e.results[0],e=>e.transcript);i.push(t[0],t)}}n.apply(this,[r,...i])};this._instance.addEventListener(t,r),this._listeners[t]=r}return this}removeEventListener(e){if(this._instance&&this._listeners){let t=this._listeners[e];this._instance.removeEventListener(e,t),delete this._listeners[e]}return this}cleanup(){return this.stop(),Object.keys(this._listeners).forEach(e=>this.removeEventListener(e)),this._instance=null,this}_includesEventType(t){return Object.values(e.eventTypes).includes(t)}static _resolveSpeechRecognition(){return window.SpeechRecognition??window.webkitSpeechRecognition??window.mozSpeechRecognition??window.msSpeechRecognition}static _resolveSpeechGrammarList(){return window.SpeechGrammarList??window.webkitSpeechGrammarList??window.mozSpeechGrammarList??window.msSpeechGrammarList}}});
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;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._isRecording=!1})}get instance(){return this._instance}set instance(e){throw Error(`You cannot set instance directly.`)}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._instance&&this._listeners&&this._includesEventType(t)){this._listeners[t]&&this.removeEventListener(t);let r=r=>{let i=[];if(t===e.eventTypes.RESULT){let e=r;if(e.results?.length>0){let t=Array.from(e.results[0],e=>e.transcript);i.push(t[0],t)}}n.apply(this,[r,...i])};this._instance.addEventListener(t,r),this._listeners[t]=r}return this}removeEventListener(e){if(this._instance&&this._listeners){let t=this._listeners[e];this._instance.removeEventListener(e,t),delete this._listeners[e]}return this}cleanup(){return this.stop(),Object.keys(this._listeners).forEach(e=>this.removeEventListener(e)),this._instance=null,this}_includesEventType(t){return Object.values(e.eventTypes).includes(t)}static _resolveSpeechRecognition(){return window.SpeechRecognition??window.webkitSpeechRecognition??window.mozSpeechRecognition??window.msSpeechRecognition}static _resolveSpeechGrammarList(){return window.SpeechGrammarList??window.webkitSpeechGrammarList??window.mozSpeechGrammarList??window.msSpeechGrammarList}}});
2
2
  //# sourceMappingURL=index.umd.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@untemps/vocal",
3
- "version": "2.0.0-beta.3",
3
+ "version": "2.0.0-beta.4",
4
4
  "description": "Class wrapped around the SpeechRecognition Web API",
5
5
  "repository": "git@github.com:untemps/vocal.git",
6
6
  "keywords": [