@untemps/vocal 2.0.0-beta.22 → 2.0.0-beta.23

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,10 @@
1
+ # [2.0.0-beta.23](https://github.com/untemps/vocal/compare/v2.0.0-beta.22...v2.0.0-beta.23) (2026-05-22)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * Suppress intermediate result events in continuous mode ([#90](https://github.com/untemps/vocal/issues/90)) ([4f62153](https://github.com/untemps/vocal/commit/4f621534a242d00b8d1131cdfb868bf08597c964))
7
+
1
8
  # [2.0.0-beta.22](https://github.com/untemps/vocal/compare/v2.0.0-beta.21...v2.0.0-beta.22) (2026-05-22)
2
9
 
3
10
 
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={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`},n=1e3,r=new Set([`not-allowed`,`service-not-allowed`,`audio-capture`]),i={grammars:null,lang:`en-US`,continuous:!1,interimResults:!1,maxAlternatives:1},a=()=>{if(!(typeof window>`u`))return window.SpeechRecognition??window.webkitSpeechRecognition??window.mozSpeechRecognition??window.msSpeechRecognition},o=()=>window.SpeechGrammarList??window.webkitSpeechGrammarList??window.mozSpeechGrammarList??window.msSpeechGrammarList,s=e=>e.reduce((e,t)=>(t.confidence??0)>(e.confidence??0)?t:e),c=e=>Object.values(t).includes(e),l=e=>`Unknown event type "${e}". Valid types are: ${Object.values(t).join(`, `)}.`,u=()=>!!a()&&!!(0,e.isNavigatorPermissionsSupported)()&&!!(0,e.isNavigatorMediaDevicesSupported)(),d=u=>{let d=a();if(!d)throw new DOMException(`SpeechRecognition not supported`,`NOT_SUPPORTED_ERR`);let f=new d,p={},m=!1,h=!1,g=0,_=null,v=!1,y=[],b={...i,...u??{}};if(f.lang=b.lang,f.continuous=b.continuous,f.interimResults=b.interimResults,f.maxAlternatives=b.maxAlternatives,b.grammars)f.grammars=b.grammars;else{let e=o();f.grammars=e?new e:null}let x=()=>{_!==null&&(clearTimeout(_),_=null),v=!1},S=()=>!!f&&!h&&f.continuous,C=()=>{_=null;try{f.start(),g=Date.now()}catch{v=!1,m=!1}},w=()=>{let e=y;if(y=[],e.length===0||!p[t.RESULT]?.length)return;let n=e.join(` `).trim(),r=Object.assign([{transcript:n,confidence:1}],{isFinal:!0}),i=Object.assign(new Event(t.RESULT),{resultIndex:0,results:[r]});[...p[t.RESULT]].forEach(({handler:e})=>e(i))},T=[[t.END,e=>{if(S()){let t=Math.max(0,n-(Date.now()-g));v=!0,_=setTimeout(C,t),e.stopImmediatePropagation();return}m=!1}],[t.START,e=>{v&&(e.stopImmediatePropagation(),queueMicrotask(()=>{v=!1}))}],[t.ERROR,e=>{r.has(e.error)&&(h=!0,x(),m=!1)}],[t.RESULT,e=>{let t=e,n=t.results?.[t.resultIndex];n?.isFinal&&y.push(s(Array.from(n)).transcript)}]];T.forEach(([e,t])=>f.addEventListener(e,t));let E=async({signal:t}={})=>{if(f)try{let n=await(0,e.getUserMediaStream)(`microphone`,{audio:!0},{signal:t});if(t?.aborted)return;if(!n)throw Error(`Unable to retrieve the stream from media device`);h=!1,y=[],f.start(),m=!0,g=Date.now()}catch(e){if(e instanceof Error&&e.name===`AbortError`)return;throw e}},D=()=>{f&&(h=!0,x(),w(),f.stop(),m=!1)},O=()=>{f&&(h=!0,x(),f.abort(),m=!1,y=[])},k=(e,n)=>{if(!c(e))throw Error(l(e));if(!f)return;let r=r=>{if(v&&(e===t.END||e===t.START))return;if(e!==t.RESULT){n(r);return}let i=r;if(!(i.results?.length>0)||i.resultIndex>=i.results.length){n(r);return}let a=Array.from(i.results[i.resultIndex]);n(r,s(a).transcript,a.map(e=>e.transcript))};f.addEventListener(e,r),p[e]||(p[e]=[]),p[e].push({callback:n,handler:r})},A=(e,t)=>{if(!c(e))throw Error(l(e));if(!(!f||!p[e]))if(t!==void 0){let n=p[e].findIndex(e=>e.callback===t);n!==-1&&(f.removeEventListener(e,p[e][n].handler),p[e].splice(n,1),p[e].length===0&&delete p[e])}else p[e].forEach(({handler:t})=>f.removeEventListener(e,t)),delete p[e]};return{get isRecording(){return m},start:E,stop:D,abort:O,on:k,off:A,cleanup:()=>{D(),Object.keys(p).forEach(e=>A(e)),T.forEach(([e,t])=>f?.removeEventListener(e,t)),f=null}}};exports.createVocal=d,exports.eventTypes=t,exports.isSupported=u;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@untemps/user-permissions-utils`);var t={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`},n=1e3,r=new Set([`not-allowed`,`service-not-allowed`,`audio-capture`]),i={grammars:null,lang:`en-US`,continuous:!1,interimResults:!1,maxAlternatives:1},a=()=>{if(!(typeof window>`u`))return window.SpeechRecognition??window.webkitSpeechRecognition??window.mozSpeechRecognition??window.msSpeechRecognition},o=()=>window.SpeechGrammarList??window.webkitSpeechGrammarList??window.mozSpeechGrammarList??window.msSpeechGrammarList,s=e=>e.reduce((e,t)=>(t.confidence??0)>(e.confidence??0)?t:e),c=e=>Object.values(t).includes(e),l=e=>`Unknown event type "${e}". Valid types are: ${Object.values(t).join(`, `)}.`,u=()=>!!a()&&!!(0,e.isNavigatorPermissionsSupported)()&&!!(0,e.isNavigatorMediaDevicesSupported)(),d=u=>{let d=a();if(!d)throw new DOMException(`SpeechRecognition not supported`,`NOT_SUPPORTED_ERR`);let f=new d,p={},m=!1,h=!1,g=0,_=null,v=!1,y=!1,b=[],x={...i,...u??{}};if(f.lang=x.lang,f.continuous=x.continuous,f.interimResults=x.interimResults,f.maxAlternatives=x.maxAlternatives,x.grammars)f.grammars=x.grammars;else{let e=o();f.grammars=e?new e:null}let S=()=>{_!==null&&(clearTimeout(_),_=null),v=!1},C=()=>!!f&&!h&&f.continuous,w=()=>{_=null;try{f.start(),g=Date.now()}catch{v=!1,m=!1}},T=()=>{let e=b;if(b=[],e.length===0||!p[t.RESULT]?.length)return;let n=e.join(` `).trim(),r=Object.assign([{transcript:n,confidence:1}],{isFinal:!0}),i=Object.assign(new Event(t.RESULT),{resultIndex:0,results:[r]});y=!0;try{[...p[t.RESULT]].forEach(({handler:e})=>e(i))}finally{y=!1}},E=[[t.END,e=>{if(C()){let t=Math.max(0,n-(Date.now()-g));v=!0,_=setTimeout(w,t),e.stopImmediatePropagation();return}T(),m=!1}],[t.START,e=>{v&&(e.stopImmediatePropagation(),queueMicrotask(()=>{v=!1}))}],[t.ERROR,e=>{r.has(e.error)&&(h=!0,S(),m=!1)}],[t.RESULT,e=>{if(!x.continuous)return;let t=e,n=t.results?.[t.resultIndex];n?.isFinal&&b.push(s(Array.from(n)).transcript)}]];E.forEach(([e,t])=>f.addEventListener(e,t));let D=async({signal:t}={})=>{if(f)try{let n=await(0,e.getUserMediaStream)(`microphone`,{audio:!0},{signal:t});if(t?.aborted)return;if(!n)throw Error(`Unable to retrieve the stream from media device`);h=!1,b=[],f.start(),m=!0,g=Date.now()}catch(e){if(e instanceof Error&&e.name===`AbortError`)return;throw e}},O=()=>{f&&(h=!0,S(),f.stop(),m=!1)},k=()=>{f&&(h=!0,S(),b=[],f.abort(),m=!1)},A=(e,n)=>{if(!c(e))throw Error(l(e));if(!f)return;let r=r=>{if(v&&(e===t.END||e===t.START))return;if(e!==t.RESULT){n(r);return}let i=r;if(!(i.results?.length>0)||i.resultIndex>=i.results.length){n(r);return}let a=i.results[i.resultIndex];if(x.continuous&&!y&&a.isFinal)return;let o=Array.from(a);n(r,s(o).transcript,o.map(e=>e.transcript))};f.addEventListener(e,r),p[e]||(p[e]=[]),p[e].push({callback:n,handler:r})},j=(e,t)=>{if(!c(e))throw Error(l(e));if(!(!f||!p[e]))if(t!==void 0){let n=p[e].findIndex(e=>e.callback===t);n!==-1&&(f.removeEventListener(e,p[e][n].handler),p[e].splice(n,1),p[e].length===0&&delete p[e])}else p[e].forEach(({handler:t})=>f.removeEventListener(e,t)),delete p[e]};return{get isRecording(){return m},start:D,stop:O,abort:k,on:A,off:j,cleanup:()=>{O(),Object.keys(p).forEach(e=>j(e)),E.forEach(([e,t])=>f?.removeEventListener(e,t)),f=null}}};exports.createVocal=d,exports.eventTypes=t,exports.isSupported=u;
2
2
  //# sourceMappingURL=index.cjs.map
package/dist/index.es.js CHANGED
@@ -27,27 +27,27 @@ var r = {
27
27
  }, c = () => window.SpeechGrammarList ?? window.webkitSpeechGrammarList ?? window.mozSpeechGrammarList ?? window.msSpeechGrammarList, l = (e) => e.reduce((e, t) => (t.confidence ?? 0) > (e.confidence ?? 0) ? t : e), u = (e) => Object.values(r).includes(e), d = (e) => `Unknown event type "${e}". Valid types are: ${Object.values(r).join(", ")}.`, f = () => !!s() && !!n() && !!t(), p = (t) => {
28
28
  let n = s();
29
29
  if (!n) throw new DOMException("SpeechRecognition not supported", "NOT_SUPPORTED_ERR");
30
- let f = new n(), p = {}, m = !1, h = !1, g = 0, _ = null, v = !1, y = [], b = {
30
+ let f = new n(), p = {}, m = !1, h = !1, g = 0, _ = null, v = !1, y = !1, b = [], x = {
31
31
  ...o,
32
32
  ...t ?? {}
33
33
  };
34
- if (f.lang = b.lang, f.continuous = b.continuous, f.interimResults = b.interimResults, f.maxAlternatives = b.maxAlternatives, b.grammars) f.grammars = b.grammars;
34
+ if (f.lang = x.lang, f.continuous = x.continuous, f.interimResults = x.interimResults, f.maxAlternatives = x.maxAlternatives, x.grammars) f.grammars = x.grammars;
35
35
  else {
36
36
  let e = c();
37
37
  f.grammars = e ? new e() : null;
38
38
  }
39
- let x = () => {
39
+ let S = () => {
40
40
  _ !== null && (clearTimeout(_), _ = null), v = !1;
41
- }, S = () => !!f && !h && f.continuous, C = () => {
41
+ }, C = () => !!f && !h && f.continuous, w = () => {
42
42
  _ = null;
43
43
  try {
44
44
  f.start(), g = Date.now();
45
45
  } catch {
46
46
  v = !1, m = !1;
47
47
  }
48
- }, w = () => {
49
- let e = y;
50
- if (y = [], e.length === 0 || !p[r.RESULT]?.length) return;
48
+ }, T = () => {
49
+ let e = b;
50
+ if (b = [], e.length === 0 || !p[r.RESULT]?.length) return;
51
51
  let t = e.join(" ").trim(), n = Object.assign([{
52
52
  transcript: t,
53
53
  confidence: 1
@@ -55,15 +55,20 @@ var r = {
55
55
  resultIndex: 0,
56
56
  results: [n]
57
57
  });
58
- [...p[r.RESULT]].forEach(({ handler: e }) => e(i));
59
- }, T = [
58
+ y = !0;
59
+ try {
60
+ [...p[r.RESULT]].forEach(({ handler: e }) => e(i));
61
+ } finally {
62
+ y = !1;
63
+ }
64
+ }, E = [
60
65
  [r.END, (e) => {
61
- if (S()) {
66
+ if (C()) {
62
67
  let t = Math.max(0, i - (Date.now() - g));
63
- v = !0, _ = setTimeout(C, t), e.stopImmediatePropagation();
68
+ v = !0, _ = setTimeout(w, t), e.stopImmediatePropagation();
64
69
  return;
65
70
  }
66
- m = !1;
71
+ T(), m = !1;
67
72
  }],
68
73
  [r.START, (e) => {
69
74
  v && (e.stopImmediatePropagation(), queueMicrotask(() => {
@@ -71,29 +76,30 @@ var r = {
71
76
  }));
72
77
  }],
73
78
  [r.ERROR, (e) => {
74
- a.has(e.error) && (h = !0, x(), m = !1);
79
+ a.has(e.error) && (h = !0, S(), m = !1);
75
80
  }],
76
81
  [r.RESULT, (e) => {
82
+ if (!x.continuous) return;
77
83
  let t = e, n = t.results?.[t.resultIndex];
78
- n?.isFinal && y.push(l(Array.from(n)).transcript);
84
+ n?.isFinal && b.push(l(Array.from(n)).transcript);
79
85
  }]
80
86
  ];
81
- T.forEach(([e, t]) => f.addEventListener(e, t));
82
- let E = async ({ signal: t } = {}) => {
87
+ E.forEach(([e, t]) => f.addEventListener(e, t));
88
+ let D = async ({ signal: t } = {}) => {
83
89
  if (f) try {
84
90
  let n = await e("microphone", { audio: !0 }, { signal: t });
85
91
  if (t?.aborted) return;
86
92
  if (!n) throw Error("Unable to retrieve the stream from media device");
87
- h = !1, y = [], f.start(), m = !0, g = Date.now();
93
+ h = !1, b = [], f.start(), m = !0, g = Date.now();
88
94
  } catch (e) {
89
95
  if (e instanceof Error && e.name === "AbortError") return;
90
96
  throw e;
91
97
  }
92
- }, D = () => {
93
- f && (h = !0, x(), w(), f.stop(), m = !1);
94
98
  }, O = () => {
95
- f && (h = !0, x(), f.abort(), m = !1, y = []);
96
- }, k = (e, t) => {
99
+ f && (h = !0, S(), f.stop(), m = !1);
100
+ }, k = () => {
101
+ f && (h = !0, S(), b = [], f.abort(), m = !1);
102
+ }, A = (e, t) => {
97
103
  if (!u(e)) throw Error(d(e));
98
104
  if (!f) return;
99
105
  let n = (n) => {
@@ -107,14 +113,16 @@ var r = {
107
113
  t(n);
108
114
  return;
109
115
  }
110
- let a = Array.from(i.results[i.resultIndex]);
111
- t(n, l(a).transcript, a.map((e) => e.transcript));
116
+ let a = i.results[i.resultIndex];
117
+ if (x.continuous && !y && a.isFinal) return;
118
+ let o = Array.from(a);
119
+ t(n, l(o).transcript, o.map((e) => e.transcript));
112
120
  };
113
121
  f.addEventListener(e, n), p[e] || (p[e] = []), p[e].push({
114
122
  callback: t,
115
123
  handler: n
116
124
  });
117
- }, A = (e, t) => {
125
+ }, j = (e, t) => {
118
126
  if (!u(e)) throw Error(d(e));
119
127
  if (!(!f || !p[e])) if (t !== void 0) {
120
128
  let n = p[e].findIndex((e) => e.callback === t);
@@ -125,13 +133,13 @@ var r = {
125
133
  get isRecording() {
126
134
  return m;
127
135
  },
128
- start: E,
129
- stop: D,
130
- abort: O,
131
- on: k,
132
- off: A,
136
+ start: D,
137
+ stop: O,
138
+ abort: k,
139
+ on: A,
140
+ off: j,
133
141
  cleanup: () => {
134
- D(), Object.keys(p).forEach((e) => A(e)), T.forEach(([e, t]) => f?.removeEventListener(e, t)), f = null;
142
+ O(), Object.keys(p).forEach((e) => j(e)), E.forEach(([e, t]) => f?.removeEventListener(e, t)), f = null;
135
143
  }
136
144
  };
137
145
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@untemps/vocal",
3
- "version": "2.0.0-beta.22",
3
+ "version": "2.0.0-beta.23",
4
4
  "description": "Class wrapped around the SpeechRecognition Web API",
5
5
  "repository": "git@github.com:untemps/vocal.git",
6
6
  "keywords": [